LibreOffice Module sw (master)  1
wsfrm.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <hints.hxx>
21 #include <osl/diagnose.h>
22 #include <o3tl/safeint.hxx>
23 #include <svl/itemiter.hxx>
24 #include <editeng/brushitem.hxx>
25 #include <fmtornt.hxx>
26 #include <pagefrm.hxx>
27 #include <section.hxx>
28 #include <rootfrm.hxx>
29 #include <anchoreddrawobject.hxx>
30 #include <fmtanchr.hxx>
31 #include <viewimp.hxx>
32 #include <viewopt.hxx>
36 #include <redline.hxx>
37 #include <docsh.hxx>
38 #include <ftninfo.hxx>
39 #include <ftnidx.hxx>
40 #include <fmtclbl.hxx>
41 #include <fmtfsize.hxx>
42 #include <fmtpdsc.hxx>
43 #include <txtftn.hxx>
44 #include <fmtftn.hxx>
45 #include <fmtsrnd.hxx>
46 #include <fmtcntnt.hxx>
47 #include <ftnfrm.hxx>
48 #include <tabfrm.hxx>
49 #include <rowfrm.hxx>
50 #include <flyfrm.hxx>
51 #include <sectfrm.hxx>
52 #include <fmtclds.hxx>
53 #include <txtfrm.hxx>
54 #include <bodyfrm.hxx>
55 #include <cellfrm.hxx>
56 #include <dbg_lay.hxx>
57 #include <editeng/frmdiritem.hxx>
58 #include <sortedobjs.hxx>
59 #include <frmatr.hxx>
60 #include <frmtool.hxx>
61 #include <layact.hxx>
62 #include <ndtxt.hxx>
63 #include <swtable.hxx>
64 #include <tblsel.hxx>
65 
66 // RotateFlyFrame3
68 
69 using namespace ::com::sun::star;
70 
72 : mbFrameAreaPositionValid(false),
73  mbFrameAreaSizeValid(false),
74  mbFramePrintAreaValid(false),
75  mnFrameId(SwFrameAreaDefinition::snLastFrameId++)
76 {
77 }
78 
80 {
81 }
82 
84 {
85  if(mbFrameAreaPositionValid != bNew)
86  {
88  }
89 }
90 
92 {
93  if(mbFrameAreaSizeValid != bNew)
94  {
95  mbFrameAreaSizeValid = bNew;
96  }
97 }
98 
100 {
101  if(mbFramePrintAreaValid != bNew)
102  {
103  mbFramePrintAreaValid = bNew;
104  }
105 }
106 
108 {
109  if(mrTarget.maFrameArea != *this)
110  {
111  mrTarget.maFrameArea = *this;
112  }
113 }
114 
116 {
117  if(mrTarget.maFramePrintArea != *this)
118  {
119  mrTarget.maFramePrintArea = *this;
120  }
121 }
122 
123 // RotateFlyFrame3 - Support for Transformations
125 {
126  // default implementation hands out FrameArea (outer frame)
127  const SwRect& rFrameArea(getFrameArea());
128 
130  rFrameArea.Width(), rFrameArea.Height(),
131  rFrameArea.Left(), rFrameArea.Top());
132 }
133 
135 {
136  // default implementation hands out FramePrintArea (outer frame)
137  // Take into account that FramePrintArea is relative to FrameArea
138  const SwRect& rFrameArea(getFrameArea());
139  const SwRect& rFramePrintArea(getFramePrintArea());
140 
142  rFramePrintArea.Width(), rFramePrintArea.Height(),
143  rFramePrintArea.Left() + rFrameArea.Left(),
144  rFramePrintArea.Top() + rFrameArea.Top());
145 }
146 
148 {
149  // RotateFlyFrame3: default is to change the FrameArea, FramePrintArea needs no
150  // change since it is relative to FrameArea
152 
153  if (aFrm.Pos().X() != FAR_AWAY)
154  {
155  aFrm.Pos().AdjustX(rOffset.X() );
156  }
157 
158  if (aFrm.Pos().Y() != FAR_AWAY)
159  {
160  aFrm.Pos().AdjustY(rOffset.Y() );
161  }
162 }
163 
165 {
166  const basegfx::B2DHomMatrix& rSource(getLocalFrameAreaTransformation());
167 
168  if(rSource.isIdentity())
169  {
170  return mrSwFrameAreaDefinition.getFrameArea();
171  }
172  else
173  {
174  basegfx::B2DVector aScale, aTranslate;
175  double fRotate, fShearX;
176  rSource.decompose(aScale, aTranslate, fRotate, fShearX);
177  const basegfx::B2DPoint aCenter(rSource * basegfx::B2DPoint(0.5, 0.5));
178  const basegfx::B2DVector aAbsScale(basegfx::absolute(aScale));
179 
180  return SwRect(
181  basegfx::fround(aCenter.getX() - (0.5 * aAbsScale.getX())),
182  basegfx::fround(aCenter.getY() - (0.5 * aAbsScale.getY())),
183  basegfx::fround(aAbsScale.getX()),
184  basegfx::fround(aAbsScale.getY()));
185  }
186 }
187 
189 {
190  const basegfx::B2DHomMatrix& rSource(getLocalFramePrintAreaTransformation());
191 
192  if(rSource.isIdentity())
193  {
194  return mrSwFrameAreaDefinition.getFramePrintArea();
195  }
196  else
197  {
198  basegfx::B2DVector aScale, aTranslate;
199  double fRotate, fShearX;
200  rSource.decompose(aScale, aTranslate, fRotate, fShearX);
201  const basegfx::B2DPoint aCenter(rSource * basegfx::B2DPoint(0.5, 0.5));
202  const basegfx::B2DVector aAbsScale(basegfx::absolute(aScale));
203  const SwRect aUntransformedFrameArea(getUntransformedFrameArea());
204 
205  return SwRect(
206  basegfx::fround(aCenter.getX() - (0.5 * aAbsScale.getX())) - aUntransformedFrameArea.Left(),
207  basegfx::fround(aCenter.getY() - (0.5 * aAbsScale.getY())) - aUntransformedFrameArea.Top(),
208  basegfx::fround(aAbsScale.getX()),
209  basegfx::fround(aAbsScale.getY()));
210  }
211 }
212 
214  double fRotation,
215  const basegfx::B2DPoint& rCenter)
216 {
217  const basegfx::B2DHomMatrix aRotateAroundCenter(
219  rCenter.getX(),
220  rCenter.getY(),
221  fRotation));
222  const SwRect& rFrameArea(mrSwFrameAreaDefinition.getFrameArea());
223  const SwRect& rFramePrintArea(mrSwFrameAreaDefinition.getFramePrintArea());
224 
225  maFrameAreaTransformation = aRotateAroundCenter * basegfx::utils::createScaleTranslateB2DHomMatrix(
226  rFrameArea.Width(), rFrameArea.Height(),
227  rFrameArea.Left(), rFrameArea.Top());
228  maFramePrintAreaTransformation = aRotateAroundCenter * basegfx::utils::createScaleTranslateB2DHomMatrix(
229  rFramePrintArea.Width(), rFramePrintArea.Height(),
230  rFramePrintArea.Left() + rFrameArea.Left(), rFramePrintArea.Top() + rFrameArea.Top());
231 }
232 
234 {
235  if(!getLocalFrameAreaTransformation().isIdentity())
236  {
237  basegfx::B2DRange aRangeFrameArea(0.0, 0.0, 1.0, 1.0);
238  aRangeFrameArea.transform(getLocalFrameAreaTransformation());
239  const SwRect aNewFrm(
240  basegfx::fround(aRangeFrameArea.getMinX()), basegfx::fround(aRangeFrameArea.getMinY()),
241  basegfx::fround(aRangeFrameArea.getWidth()), basegfx::fround(aRangeFrameArea.getHeight()));
242 
243  if(aNewFrm != mrSwFrameAreaDefinition.getFrameArea())
244  {
245  SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(mrSwFrameAreaDefinition);
246  aFrm.setSwRect(aNewFrm);
247  }
248  }
249 
250  if(getLocalFramePrintAreaTransformation().isIdentity())
251  return;
252 
253  basegfx::B2DRange aRangeFramePrintArea(0.0, 0.0, 1.0, 1.0);
254  aRangeFramePrintArea.transform(getLocalFramePrintAreaTransformation());
255  const SwRect aNewPrt(
256  basegfx::fround(aRangeFramePrintArea.getMinX()) - mrSwFrameAreaDefinition.getFrameArea().Left(),
257  basegfx::fround(aRangeFramePrintArea.getMinY()) - mrSwFrameAreaDefinition.getFrameArea().Top(),
258  basegfx::fround(aRangeFramePrintArea.getWidth()),
259  basegfx::fround(aRangeFramePrintArea.getHeight()));
260 
261  if(aNewPrt != mrSwFrameAreaDefinition.getFramePrintArea())
262  {
263  SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(mrSwFrameAreaDefinition);
264  aPrt.setSwRect(aNewPrt);
265  }
266 }
267 
269 {
270  // This can be done fully based on the Transformations currently
271  // set, so use this. Only needed when transformation *is* used
272  if(!getLocalFrameAreaTransformation().isIdentity())
273  {
274  SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(mrSwFrameAreaDefinition);
275  aFrm.setSwRect(getUntransformedFrameArea());
276  }
277 
278  if(!getLocalFramePrintAreaTransformation().isIdentity())
279  {
280  SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(mrSwFrameAreaDefinition);
281  aPrt.setSwRect(getUntransformedFramePrintArea());
282  }
283 }
284 
285 // transform by given B2DHomMatrix
287 {
288  maFrameAreaTransformation *= aTransform;
289  maFramePrintAreaTransformation *= aTransform;
290 }
291 
293 : SwClient( pMod ),
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." );
323 }
324 
326 {
328 }
329 
330 bool SwFrame::KnowsFormat( const SwFormat& rFormat ) const
331 {
332  return GetRegisteredIn() == &rFormat;
333 }
334 
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 
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::SwClientNotify(const SwModify&, const SfxHint& rHint)
475 {
476  if (rHint.GetId() != SfxHintId::SwLegacyModify)
477  return;
478  auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
480 
481  if(pLegacy->m_pOld && pLegacy->m_pNew && RES_ATTRSET_CHG == pLegacy->m_pNew->Which())
482  {
483  SfxItemIter aNIter(*static_cast<const SwAttrSetChg*>(pLegacy->m_pNew)->GetChgSet());
484  SfxItemIter aOIter(*static_cast<const SwAttrSetChg*>(pLegacy->m_pOld)->GetChgSet());
485  const SfxPoolItem* pNItem = aNIter.GetCurItem();
486  const SfxPoolItem* pOItem = aOIter.GetCurItem();
487  do
488  {
489  UpdateAttrFrame(pOItem, pNItem, eInvFlags);
490  pNItem = aNIter.NextItem();
491  pOItem = aOIter.NextItem();
492  } while (pNItem);
493  }
494  else
495  UpdateAttrFrame(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
496 
497  if(eInvFlags == SwFrameInvFlags::NONE)
498  return;
499 
500  SwPageFrame* pPage = FindPageFrame();
501  InvalidatePage(pPage);
502  if(eInvFlags & SwFrameInvFlags::InvalidatePrt)
503  {
504  InvalidatePrt_();
505  if(!GetPrev() && IsTabFrame() && IsInSct())
507  }
508  if(eInvFlags & SwFrameInvFlags::InvalidateSize)
509  InvalidateSize_();
510  if(eInvFlags & SwFrameInvFlags::InvalidatePos)
511  InvalidatePos_();
512  if(eInvFlags & SwFrameInvFlags::SetCompletePaint)
514  SwFrame *pNxt;
516  && nullptr != (pNxt = GetNext()))
517  {
518  pNxt->InvalidatePage(pPage);
519  if(eInvFlags & SwFrameInvFlags::NextInvalidatePos)
520  pNxt->InvalidatePos_();
522  pNxt->SetCompletePaint();
523  }
524 }
525 
526 void SwFrame::UpdateAttrFrame( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
527  SwFrameInvFlags &rInvFlags )
528 {
529  sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
530  switch( nWhich )
531  {
532  case RES_BOX:
533  case RES_SHADOW:
535  [[fallthrough]];
536  case RES_LR_SPACE:
537  case RES_UL_SPACE:
538  case RES_RTL_GUTTER:
541  break;
542 
545  break;
546 
547  case RES_BACKGROUND:
550  break;
551 
552  case RES_KEEP:
553  rInvFlags |= SwFrameInvFlags::InvalidatePos;
554  break;
555 
556  case RES_FRM_SIZE:
560  break;
561 
562  case RES_FMT_CHG:
565  break;
566 
567  case RES_ROW_SPLIT:
568  {
569  if ( IsRowFrame() )
570  {
571  bool bInFollowFlowRow = nullptr != IsInFollowFlowRow();
572  if ( bInFollowFlowRow || nullptr != IsInSplitTableRow() )
573  {
574  SwTabFrame* pTab = FindTabFrame();
575  if ( bInFollowFlowRow )
576  pTab = pTab->FindMaster();
577  pTab->SetRemoveFollowFlowLinePending( true );
578  }
579  }
580  break;
581  }
582  case RES_COL:
583  OSL_FAIL( "Columns for new FrameType?" );
584  break;
585 
586  default:
587  // the new FillStyle has to do the same as previous RES_BACKGROUND
588  if(nWhich >= XATTR_FILL_FIRST && nWhich <= XATTR_FILL_LAST)
589  {
590  rInvFlags
592  }
593  /* do Nothing */;
594  }
595 }
596 
597 bool SwFrame::Prepare( const PrepareHint, const void *, bool )
598 {
599  /* Do nothing */
600  return false;
601 }
602 
607 void SwFrame::InvalidatePage( const SwPageFrame *pPage ) const
608 {
609  if ( !pPage )
610  {
611  pPage = FindPageFrame();
612  // #i28701# - for at-character and as-character
613  // anchored Writer fly frames additionally invalidate also page frame
614  // its 'anchor character' is on.
615  if ( pPage && pPage->GetUpper() && IsFlyFrame() )
616  {
617  const SwFlyFrame* pFlyFrame = static_cast<const SwFlyFrame*>(this);
618  if ( pFlyFrame->IsAutoPos() || pFlyFrame->IsFlyInContentFrame() )
619  {
620  // #i33751#, #i34060# - method <GetPageFrameOfAnchor()>
621  // is replaced by method <FindPageFrameOfAnchor()>. It's return value
622  // have to be checked.
623  SwPageFrame* pPageFrameOfAnchor =
624  const_cast<SwFlyFrame*>(pFlyFrame)->FindPageFrameOfAnchor();
625  if ( pPageFrameOfAnchor && pPageFrameOfAnchor != pPage )
626  {
627  InvalidatePage( pPageFrameOfAnchor );
628  }
629  }
630  }
631  }
632 
633  if ( !(pPage && pPage->GetUpper()) )
634  return;
635 
636  if ( pPage->GetFormat()->GetDoc()->IsInDtor() )
637  return;
638 
639  SwRootFrame *pRoot = const_cast<SwRootFrame*>(static_cast<const SwRootFrame*>(pPage->GetUpper()));
640  const SwFlyFrame *pFly = FindFlyFrame();
641  if ( IsContentFrame() )
642  {
643  if ( pRoot->IsTurboAllowed() )
644  {
645  // If a ContentFrame wants to register for a second time, make it a TurboAction.
646  if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() )
647  pRoot->SetTurbo( static_cast<const SwContentFrame*>(this) );
648  else
649  {
650  pRoot->DisallowTurbo();
651  //The page of the Turbo could be a different one then mine,
652  //therefore we have to invalidate it.
653  const SwFrame *pTmp = pRoot->GetTurbo();
654  pRoot->ResetTurbo();
655  pTmp->InvalidatePage();
656  }
657  }
658  if ( !pRoot->GetTurbo() )
659  {
660  if ( pFly )
661  { if( !pFly->IsLocked() )
662  {
663  if ( pFly->IsFlyInContentFrame() )
664  { pPage->InvalidateFlyInCnt();
665  pFly->GetAnchorFrame()->InvalidatePage();
666  }
667  else
668  pPage->InvalidateFlyContent();
669  }
670  }
671  else
672  pPage->InvalidateContent();
673  }
674  }
675  else
676  {
677  pRoot->DisallowTurbo();
678  if ( pFly )
679  {
680  if ( !pFly->IsLocked() )
681  {
682  if ( pFly->IsFlyInContentFrame() )
683  {
684  pPage->InvalidateFlyInCnt();
685  pFly->GetAnchorFrame()->InvalidatePage();
686  }
687  else
688  pPage->InvalidateFlyLayout();
689  }
690  }
691  else
692  pPage->InvalidateLayout();
693 
694  if ( pRoot->GetTurbo() )
695  { const SwFrame *pTmp = pRoot->GetTurbo();
696  pRoot->ResetTurbo();
697  pTmp->InvalidatePage();
698  }
699  }
700  pRoot->SetIdleFlags();
701 
702  if (!IsTextFrame())
703  return;
704 
705  SwTextFrame const*const pText(static_cast<SwTextFrame const*>(this));
706  if (sw::MergedPara const*const pMergedPara = pText->GetMergedPara())
707  {
708  SwTextNode const* pNode(nullptr);
709  for (auto const& e : pMergedPara->extents)
710  {
711  if (e.pNode != pNode)
712  {
713  pNode = e.pNode;
714  if (pNode->IsGrammarCheckDirty())
715  {
716  pRoot->SetNeedGrammarCheck( true );
717  break;
718  }
719  }
720  }
721  }
722  else
723  {
724  if (pText->GetTextNodeFirst()->IsGrammarCheckDirty())
725  {
726  pRoot->SetNeedGrammarCheck( true );
727  }
728  }
729 }
730 
731 Size SwFrame::ChgSize( const Size& aNewSize )
732 {
733  mbFixSize = true;
734  const Size aOldSize( getFrameArea().SSize() );
735  if ( aNewSize == aOldSize )
736  return aOldSize;
737 
738  if ( GetUpper() )
739  {
740  bool bNeighb = IsNeighbourFrame();
741  SwRectFn fnRect = IsVertical() == bNeighb ? fnRectHori : ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert );
742  SwRect aNew( Point(0,0), aNewSize );
743 
744  {
746  (aFrm.*fnRect->fnSetWidth)( (aNew.*fnRect->fnGetWidth)() );
747  }
748 
749  tools::Long nNew = (aNew.*fnRect->fnGetHeight)();
750  tools::Long nDiff = nNew - (getFrameArea().*fnRect->fnGetHeight)();
751 
752  if( nDiff )
753  {
754  if ( GetUpper()->IsFootnoteBossFrame() && HasFixSize() &&
756  static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment() )
757  {
758  {
760  (aFrm.*fnRect->fnSetHeight)( nNew );
761  }
762 
763  SwTwips nReal = static_cast<SwLayoutFrame*>(this)->AdjustNeighbourhood(nDiff);
764 
765  if ( nReal != nDiff )
766  {
768  (aFrm.*fnRect->fnSetHeight)( nNew - nDiff + nReal );
769  }
770  }
771  else
772  {
773  // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames
774  // NOTE: neighbour frames are cell and column frames.
775  if ( !bNeighb )
776  {
777  if ( nDiff > 0 )
778  Grow( nDiff );
779  else
780  Shrink( -nDiff );
781 
782  if ( GetUpper() && (getFrameArea().*fnRect->fnGetHeight)() != nNew )
783  {
785  }
786  }
787 
788  // Even if grow/shrink did not yet set the desired width, for
789  // example when called by ChgColumns to set the column width, we
790  // set the right width now.
792  (aFrm.*fnRect->fnSetHeight)( nNew );
793  }
794  }
795  }
796  else
797  {
799  aFrm.SSize( aNewSize );
800  }
801 
802  if ( getFrameArea().SSize() != aOldSize )
803  {
804  SwPageFrame *pPage = FindPageFrame();
805  if ( GetNext() )
806  {
807  GetNext()->InvalidatePos_();
808  GetNext()->InvalidatePage( pPage );
809  }
810  if( IsLayoutFrame() )
811  {
812  if( IsRightToLeft() )
813  InvalidatePos_();
814  if( static_cast<SwLayoutFrame*>(this)->Lower() )
815  static_cast<SwLayoutFrame*>(this)->Lower()->InvalidateSize_();
816  }
817  InvalidatePrt_();
818  InvalidateSize_();
819  InvalidatePage( pPage );
820  }
821 
822  return getFrameArea().SSize();
823 }
824 
830 void SwFrame::InsertBefore( SwLayoutFrame* pParent, SwFrame* pBehind )
831 {
832  OSL_ENSURE( pParent, "No parent for insert." );
833  OSL_ENSURE( (!pBehind || pParent == pBehind->GetUpper()),
834  "Frame tree is inconsistent." );
835 
836  mpUpper = pParent;
837  mpNext = pBehind;
838  if( pBehind )
839  { //Insert before pBehind.
840  mpPrev = pBehind->mpPrev;
841  if( nullptr != mpPrev )
842  mpPrev->mpNext = this;
843  else
844  mpUpper->m_pLower = this;
845  pBehind->mpPrev = this;
846  }
847  else
848  { //Insert at the end, or as first node in the sub tree
849  mpPrev = mpUpper->Lower();
850  if ( mpPrev )
851  {
852  while( mpPrev->mpNext )
853  mpPrev = mpPrev->mpNext;
854  mpPrev->mpNext = this;
855  }
856  else
857  mpUpper->m_pLower = this;
858  }
859 }
860 
866 void SwFrame::InsertBehind( SwLayoutFrame *pParent, SwFrame *pBefore )
867 {
868  OSL_ENSURE( pParent, "No Parent for Insert." );
869  OSL_ENSURE( (!pBefore || pParent == pBefore->GetUpper()),
870  "Frame tree is inconsistent." );
871 
872  mpUpper = pParent;
873  mpPrev = pBefore;
874  if ( pBefore )
875  {
876  //Insert after pBefore
877  mpNext = pBefore->mpNext;
878  if ( nullptr != mpNext )
879  mpNext->mpPrev = this;
880  pBefore->mpNext = this;
881  }
882  else
883  {
884  //Insert at the beginning of the chain
885  mpNext = pParent->Lower();
886  if ( pParent->Lower() )
887  pParent->Lower()->mpPrev = this;
888  pParent->m_pLower = this;
889  }
890 }
891 
905 bool SwFrame::InsertGroupBefore( SwFrame* pParent, SwFrame* pBehind, SwFrame* pSct )
906 {
907  OSL_ENSURE( pParent, "No parent for insert." );
908  OSL_ENSURE( (!pBehind || ( (pBehind && (pParent == pBehind->GetUpper()))
909  || ((pParent->IsSctFrame() && pBehind->GetUpper()->IsColBodyFrame())) ) ),
910  "Frame tree inconsistent." );
911  if( pSct )
912  {
913  mpUpper = pParent->GetUpper();
914  SwFrame *pLast = this;
915  while( pLast->GetNext() )
916  {
917  pLast = pLast->GetNext();
918  pLast->mpUpper = GetUpper();
919  }
920  if( pBehind )
921  {
922  pLast->mpNext = pSct;
923  pSct->mpPrev = pLast;
924  pSct->mpNext = pParent->GetNext();
925  }
926  else
927  {
928  pLast->mpNext = pParent->GetNext();
929  if( pLast->GetNext() )
930  pLast->GetNext()->mpPrev = pLast;
931  }
932  pParent->mpNext = this;
933  mpPrev = pParent;
934  if( pSct->GetNext() )
935  pSct->GetNext()->mpPrev = pSct;
936  while( pLast->GetNext() )
937  {
938  pLast = pLast->GetNext();
939  pLast->mpUpper = GetUpper();
940  }
941  if( pBehind )
942  { // Insert before pBehind.
943  if( pBehind->GetPrev() )
944  pBehind->GetPrev()->mpNext = nullptr;
945  else
946  pBehind->GetUpper()->m_pLower = nullptr;
947  pBehind->mpPrev = nullptr;
948  SwLayoutFrame* pTmp = static_cast<SwLayoutFrame*>(pSct);
949  if( pTmp->Lower() )
950  {
951  OSL_ENSURE( pTmp->Lower()->IsColumnFrame(), "InsertGrp: Used SectionFrame" );
952  pTmp = static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(pTmp->Lower())->Lower());
953  OSL_ENSURE( pTmp, "InsertGrp: Missing ColBody" );
954  }
955  pBehind->mpUpper = pTmp;
956  pBehind->GetUpper()->m_pLower = pBehind;
957  pLast = pBehind->GetNext();
958  while ( pLast )
959  {
960  pLast->mpUpper = pBehind->GetUpper();
961  pLast = pLast->GetNext();
962  }
963  }
964  else
965  {
966  OSL_ENSURE( pSct->IsSctFrame(), "InsertGroup: For SectionFrames only" );
967  SwFrame::DestroyFrame(pSct);
968  return false;
969  }
970  }
971  else
972  {
973  mpUpper = static_cast<SwLayoutFrame*>(pParent);
974  SwFrame *pLast = this;
975  while( pLast->GetNext() )
976  {
977  pLast = pLast->GetNext();
978  pLast->mpUpper = GetUpper();
979  }
980  pLast->mpNext = pBehind;
981  if( pBehind )
982  { // Insert before pBehind.
983  mpPrev = pBehind->mpPrev;
984  if( nullptr != mpPrev )
985  mpPrev->mpNext = this;
986  else
987  mpUpper->m_pLower = this;
988  pBehind->mpPrev = pLast;
989  }
990  else
991  {
992  //Insert at the end, or ... the first node in the subtree
993  mpPrev = mpUpper->Lower();
994  if ( mpPrev )
995  {
996  while( mpPrev->mpNext )
997  mpPrev = mpPrev->mpNext;
998  mpPrev->mpNext = this;
999  }
1000  else
1001  mpUpper->m_pLower = this;
1002  }
1003  }
1004  return true;
1005 }
1006 
1008 {
1009  OSL_ENSURE( mpUpper, "Remove without upper?" );
1010 
1011  if (mpPrev)
1012  // one out of the middle is removed
1013  mpPrev->mpNext = mpNext;
1014  else if (mpUpper)
1015  { // the first in a list is removed //TODO
1016  OSL_ENSURE( mpUpper->m_pLower == this, "Layout is inconsistent." );
1017  mpUpper->m_pLower = mpNext;
1018  }
1019  if( mpNext )
1020  mpNext->mpPrev = mpPrev;
1021 
1022  // Remove link
1023  mpNext = mpPrev = nullptr;
1024  mpUpper = nullptr;
1025 }
1026 
1027 void SwContentFrame::Paste( SwFrame* pParent, SwFrame* pSibling)
1028 {
1029  OSL_ENSURE( pParent, "No parent for pasting." );
1030  OSL_ENSURE( pParent->IsLayoutFrame(), "Parent is ContentFrame." );
1031  OSL_ENSURE( pParent != this, "I'm the parent." );
1032  OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
1033  OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
1034  "I'm still registered somewhere" );
1035  OSL_ENSURE( !pSibling || pSibling->IsFlowFrame(),
1036  "<SwContentFrame::Paste(..)> - sibling not of expected type." );
1037 
1038  //Insert in the tree.
1039  InsertBefore( static_cast<SwLayoutFrame*>(pParent), pSibling );
1040 
1041  SwPageFrame *pPage = FindPageFrame();
1042  InvalidateAll_();
1043  InvalidatePage( pPage );
1044 
1045  if( pPage )
1046  {
1047  pPage->InvalidateSpelling();
1048  pPage->InvalidateSmartTags();
1049  pPage->InvalidateAutoCompleteWords();
1050  pPage->InvalidateWordCount();
1051  }
1052 
1053  if ( GetNext() )
1054  {
1055  SwFrame* pNxt = GetNext();
1056  pNxt->InvalidatePrt_();
1057  pNxt->InvalidatePos_();
1058  pNxt->InvalidatePage( pPage );
1059  if( pNxt->IsSctFrame() )
1060  pNxt = static_cast<SwSectionFrame*>(pNxt)->ContainsContent();
1061  if( pNxt && pNxt->IsTextFrame() && pNxt->IsInFootnote() )
1062  pNxt->Prepare( PrepareHint::FootnoteInvalidation, nullptr, false );
1063  }
1064 
1065  if ( getFrameArea().Height() )
1066  pParent->Grow( getFrameArea().Height() );
1067 
1068  if ( getFrameArea().Width() != pParent->getFramePrintArea().Width() )
1070 
1071  if ( GetPrev() )
1072  {
1073  if ( IsFollow() )
1074  //I'm a direct follower of my master now
1075  static_cast<SwContentFrame*>(GetPrev())->Prepare( PrepareHint::FollowFollows );
1076  else
1077  {
1078  if ( GetPrev()->getFrameArea().Height() !=
1080  {
1081  // Take the border into account?
1082  GetPrev()->InvalidatePrt_();
1083  }
1084  // OD 18.02.2003 #104989# - force complete paint of previous frame,
1085  // if frame is inserted at the end of a section frame, in order to
1086  // get subsidiary lines repainted for the section.
1087  if ( pParent->IsSctFrame() && !GetNext() )
1088  {
1089  // force complete paint of previous frame, if new inserted frame
1090  // in the section is the last one.
1092  }
1093  GetPrev()->InvalidatePage( pPage );
1094  }
1095  }
1096  if ( IsInFootnote() )
1097  {
1098  SwFrame* pFrame = GetIndPrev();
1099  if( pFrame && pFrame->IsSctFrame() )
1100  pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
1101  if( pFrame )
1102  pFrame->Prepare( PrepareHint::QuoVadis, nullptr, false );
1103  if( !GetNext() )
1104  {
1105  pFrame = FindFootnoteFrame()->GetNext();
1106  if( pFrame && nullptr != (pFrame=static_cast<SwLayoutFrame*>(pFrame)->ContainsAny()) )
1107  pFrame->InvalidatePrt_();
1108  }
1109  }
1110 
1112  SwFrame *pNxt = FindNextCnt();
1113  if ( !pNxt )
1114  return;
1115 
1116  while ( pNxt && pNxt->IsInTab() )
1117  {
1118  pNxt = pNxt->FindTabFrame();
1119  if( nullptr != pNxt )
1120  pNxt = pNxt->FindNextCnt();
1121  }
1122  if ( pNxt )
1123  {
1124  pNxt->InvalidateLineNum_();
1125  if ( pNxt != GetNext() )
1126  pNxt->InvalidatePage();
1127  }
1128 }
1129 
1131 {
1132  OSL_ENSURE( GetUpper(), "Cut without Upper()." );
1133 
1134  SwPageFrame *pPage = FindPageFrame();
1135  InvalidatePage( pPage );
1136  SwFrame *pFrame = GetIndPrev();
1137  if( pFrame )
1138  {
1139  if( pFrame->IsSctFrame() )
1140  pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
1141  if ( pFrame && pFrame->IsContentFrame() )
1142  {
1143  pFrame->InvalidatePrt_();
1144  if( IsInFootnote() )
1145  pFrame->Prepare( PrepareHint::QuoVadis, nullptr, false );
1146  }
1147  // #i26250# - invalidate printing area of previous
1148  // table frame.
1149  else if ( pFrame && pFrame->IsTabFrame() )
1150  {
1151  pFrame->InvalidatePrt();
1152  }
1153  }
1154 
1155  SwFrame *pNxt = FindNextCnt();
1156  if ( pNxt )
1157  {
1158  while ( pNxt && pNxt->IsInTab() )
1159  {
1160  pNxt = pNxt->FindTabFrame();
1161  if( nullptr != pNxt )
1162  pNxt = pNxt->FindNextCnt();
1163  }
1164  if ( pNxt )
1165  {
1166  pNxt->InvalidateLineNum_();
1167  if ( pNxt != GetNext() )
1168  pNxt->InvalidatePage();
1169  }
1170  }
1171 
1172  SwTabFrame* pMasterTab(nullptr);
1173  pFrame = GetIndNext();
1174  if( pFrame )
1175  {
1176  // The old follow may have calculated a gap to the predecessor which
1177  // now becomes obsolete or different as it becomes the first one itself
1178  pFrame->InvalidatePrt_();
1179  pFrame->InvalidatePos_();
1180  pFrame->InvalidatePage( pPage );
1181  if( pFrame->IsSctFrame() )
1182  {
1183  pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
1184  if( pFrame )
1185  {
1186  pFrame->InvalidatePrt_();
1187  pFrame->InvalidatePos_();
1188  pFrame->InvalidatePage( pPage );
1189  }
1190  }
1191  if( pFrame && IsInFootnote() )
1192  pFrame->Prepare( PrepareHint::ErgoSum, nullptr, false );
1193  if( IsInSct() && !GetPrev() )
1194  {
1195  SwSectionFrame* pSct = FindSctFrame();
1196  if( !pSct->IsFollow() )
1197  {
1198  pSct->InvalidatePrt_();
1199  pSct->InvalidatePage( pPage );
1200  }
1201  }
1202  }
1203  else
1204  {
1206  //Someone needs to do the retouching: predecessor or upper
1207  pFrame = GetPrev();
1208  if ( nullptr != pFrame )
1209  { pFrame->SetRetouche();
1211  pFrame->InvalidatePos_();
1212  pFrame->InvalidatePage( pPage );
1213  }
1214  // If I'm (was) the only ContentFrame in my upper, it has to do the
1215  // retouching. Also, perhaps a page became empty.
1216  else
1217  { SwRootFrame *pRoot = getRootFrame();
1218  if ( pRoot )
1219  {
1220  pRoot->SetSuperfluous();
1221  // RemoveSuperfluous can only remove empty pages at the end;
1222  // find if there are pages without content following pPage
1223  // and if so request a call to CheckPageDescs()
1224  SwPageFrame const* pNext(pPage);
1225  if (pRoot->GetCurrShell()->Imp()->IsAction())
1226  {
1227  while ((pNext = static_cast<SwPageFrame const*>(pNext->GetNext())))
1228  {
1229  if (!sw::IsPageFrameEmpty(*pNext) && !pNext->IsFootnotePage())
1230  {
1231  pRoot->GetCurrShell()->Imp()->GetLayAction().SetCheckPageNum(pPage->GetPhyPageNum());
1232  break;
1233  }
1234  }
1235  }
1237  GetUpper()->InvalidatePage( pPage );
1238  }
1239  if( IsInSct() )
1240  {
1241  SwSectionFrame* pSct = FindSctFrame();
1242  if( !pSct->IsFollow() )
1243  {
1244  pSct->InvalidatePrt_();
1245  pSct->InvalidatePage( pPage );
1246  }
1247  }
1248  // #i52253# The master table should take care
1249  // of removing the follow flow line.
1250  if ( IsInTab() )
1251  {
1252  SwTabFrame* pThisTab = FindTabFrame();
1253  if (pThisTab && pThisTab->IsFollow())
1254  {
1255  pMasterTab = pThisTab->FindMaster();
1256  }
1257  }
1258  }
1259  }
1260  //Remove first, then shrink the upper.
1261  SwLayoutFrame *pUp = GetUpper();
1262  RemoveFromLayout();
1263  if ( !pUp )
1264  {
1265  assert(!pMasterTab);
1266  return;
1267  }
1268 
1269  if (pMasterTab
1270  && !pMasterTab->GetFollow()->GetFirstNonHeadlineRow()->ContainsContent())
1271  { // only do this if there's no content in other cells of the row!
1272  pMasterTab->InvalidatePos_();
1273  pMasterTab->SetRemoveFollowFlowLinePending(true);
1274  }
1275 
1276  SwSectionFrame *pSct = nullptr;
1277  if ( !pUp->Lower() &&
1278  ( ( pUp->IsFootnoteFrame() && !pUp->IsColLocked() ) ||
1279  ( pUp->IsInSct() &&
1280  // #i29438#
1281  // We have to consider the case that the section may be "empty"
1282  // except from a temporary empty table frame.
1283  // This can happen due to the new cell split feature.
1284  !pUp->IsCellFrame() &&
1285  // #126020# - adjust check for empty section
1286  // #130797# - correct fix #126020#
1287  !(pSct = pUp->FindSctFrame())->ContainsContent() &&
1288  !pSct->ContainsAny( true ) ) ) )
1289  {
1290  if ( pUp->GetUpper() )
1291  {
1292 
1293  // prevent delete of <ColLocked> footnote frame
1294  if ( pUp->IsFootnoteFrame() && !pUp->IsColLocked())
1295  {
1296  if( pUp->GetNext() && !pUp->GetPrev() )
1297  {
1298  SwFrame* pTmp = static_cast<SwLayoutFrame*>(pUp->GetNext())->ContainsAny();
1299  if( pTmp )
1300  pTmp->InvalidatePrt_();
1301  }
1302  if (!pUp->IsDeleteForbidden())
1303  {
1304  pUp->Cut();
1305  SwFrame::DestroyFrame(pUp);
1306  }
1307  }
1308  else
1309  {
1310 
1311  if ( pSct->IsColLocked() || !pSct->IsInFootnote() ||
1312  ( pUp->IsFootnoteFrame() && pUp->IsColLocked() ) )
1313  {
1314  pSct->DelEmpty( false );
1315  // If a locked section may not be deleted then at least
1316  // its size became invalid after removing its last
1317  // content.
1318  pSct->InvalidateSize_();
1319  }
1320  else
1321  {
1322  pSct->DelEmpty( true );
1323  SwFrame::DestroyFrame(pSct);
1324  }
1325  }
1326  }
1327  }
1328  else
1329  {
1330  SwRectFnSet aRectFnSet(this);
1331  tools::Long nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
1332  if( nFrameHeight )
1333  pUp->Shrink( nFrameHeight );
1334  }
1335 }
1336 
1337 void SwLayoutFrame::Paste( SwFrame* pParent, SwFrame* pSibling)
1338 {
1339  OSL_ENSURE( pParent, "No parent for pasting." );
1340  OSL_ENSURE( pParent->IsLayoutFrame(), "Parent is ContentFrame." );
1341  OSL_ENSURE( pParent != this, "I'm the parent oneself." );
1342  OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
1343  OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
1344  "I'm still registered somewhere." );
1345 
1346  //Insert in the tree.
1347  InsertBefore( static_cast<SwLayoutFrame*>(pParent), pSibling );
1348 
1349  // OD 24.10.2002 #103517# - correct setting of variable <fnRect>
1350  // <fnRect> is used for the following:
1351  // (1) To invalidate the frame's size, if its size, which has to be the
1352  // same as its upper/parent, differs from its upper's/parent's.
1353  // (2) To adjust/grow the frame's upper/parent, if it has a dimension in its
1354  // size, which is not determined by its upper/parent.
1355  // Which size is which depends on the frame type and the layout direction
1356  // (vertical or horizontal).
1357  // There are the following cases:
1358  // (A) Header and footer frames both in vertical and in horizontal layout
1359  // have to size the width to the upper/parent. A dimension in the height
1360  // has to cause an adjustment/grow of the upper/parent.
1361  // --> <fnRect> = fnRectHori
1362  // (B) Cell and column frames in vertical layout, the width has to be the
1363  // same as upper/parent and a dimension in height causes adjustment/grow
1364  // of the upper/parent.
1365  // --> <fnRect> = fnRectHori
1366  // in horizontal layout the other way around
1367  // --> <fnRect> = fnRectVert
1368  // (C) Other frames in vertical layout, the height has to be the
1369  // same as upper/parent and a dimension in width causes adjustment/grow
1370  // of the upper/parent.
1371  // --> <fnRect> = fnRectVert
1372  // in horizontal layout the other way around
1373  // --> <fnRect> = fnRectHori
1374  //SwRectFn fnRect = IsVertical() ? fnRectHori : fnRectVert;
1375  SwRectFn fnRect;
1376  if ( IsHeaderFrame() || IsFooterFrame() )
1377  fnRect = fnRectHori;
1378  else if ( IsCellFrame() || IsColumnFrame() )
1380  else
1382 
1383  if( (getFrameArea().*fnRect->fnGetWidth)() != (pParent->getFramePrintArea().*fnRect->fnGetWidth)())
1384  InvalidateSize_();
1385  InvalidatePos_();
1386  const SwPageFrame *pPage = FindPageFrame();
1387  InvalidatePage( pPage );
1388  if( !IsColumnFrame() )
1389  {
1390  SwFrame *pFrame = GetIndNext();
1391  if( nullptr != pFrame )
1392  {
1393  pFrame->InvalidatePos_();
1394  if( IsInFootnote() )
1395  {
1396  if( pFrame->IsSctFrame() )
1397  pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
1398  if( pFrame )
1399  pFrame->Prepare( PrepareHint::ErgoSum, nullptr, false );
1400  }
1401  }
1402  if ( IsInFootnote() && nullptr != ( pFrame = GetIndPrev() ) )
1403  {
1404  if( pFrame->IsSctFrame() )
1405  pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
1406  if( pFrame )
1407  pFrame->Prepare( PrepareHint::QuoVadis, nullptr, false );
1408  }
1409  }
1410 
1411  if( !(getFrameArea().*fnRect->fnGetHeight)() )
1412  return;
1413 
1414  // AdjustNeighbourhood is now also called in columns which are not
1415  // placed inside a frame
1417  static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment()
1419  SwTwips nGrow = (getFrameArea().*fnRect->fnGetHeight)();
1420  if( SwNeighbourAdjust::OnlyAdjust == nAdjust )
1421  AdjustNeighbourhood( nGrow );
1422  else
1423  {
1424  SwTwips nReal = 0;
1425  if( SwNeighbourAdjust::AdjustGrow == nAdjust )
1426  nReal = AdjustNeighbourhood( nGrow );
1427  if( nReal < nGrow )
1428  nReal += pParent->Grow( nGrow - nReal );
1429  if( SwNeighbourAdjust::GrowAdjust == nAdjust && nReal < nGrow )
1430  AdjustNeighbourhood( nGrow - nReal );
1431  }
1432 }
1433 
1435 {
1436  if ( GetNext() )
1437  GetNext()->InvalidatePos_();
1438 
1439  SwRectFnSet aRectFnSet(this);
1440  SwTwips nShrink = aRectFnSet.GetHeight(getFrameArea());
1441 
1442  // Remove first, then shrink upper.
1443  SwLayoutFrame *pUp = GetUpper();
1444 
1445  // AdjustNeighbourhood is now also called in columns which are not
1446  // placed inside a frame.
1447 
1448  // Remove must not be called before an AdjustNeighbourhood, but it has to
1449  // be called before the upper-shrink-call, if the upper-shrink takes care
1450  // of its content.
1451  if ( pUp && nShrink )
1452  {
1453  if( pUp->IsFootnoteBossFrame() )
1454  {
1455  SwNeighbourAdjust nAdjust= static_cast<SwFootnoteBossFrame*>(pUp)->NeighbourhoodAdjustment();
1456  if( SwNeighbourAdjust::OnlyAdjust == nAdjust )
1457  AdjustNeighbourhood( -nShrink );
1458  else
1459  {
1460  SwTwips nReal = 0;
1461  if( SwNeighbourAdjust::AdjustGrow == nAdjust )
1462  nReal = -AdjustNeighbourhood( -nShrink );
1463  if( nReal < nShrink )
1464  {
1465  const SwTwips nOldHeight = aRectFnSet.GetHeight(getFrameArea());
1466 
1467  // seems as if this needs to be forwarded to the SwFrame already here,
1468  // changing to zero seems temporary anyways
1469  {
1471  aRectFnSet.SetHeight( aFrm, 0 );
1472  }
1473 
1474  nReal += pUp->Shrink( nShrink - nReal );
1475 
1476  {
1478  aRectFnSet.SetHeight( aFrm, nOldHeight );
1479  }
1480  }
1481 
1482  if( SwNeighbourAdjust::GrowAdjust == nAdjust && nReal < nShrink )
1483  AdjustNeighbourhood( nReal - nShrink );
1484  }
1485  RemoveFromLayout();
1486  }
1487  else
1488  {
1489  RemoveFromLayout();
1490  pUp->Shrink( nShrink );
1491  }
1492  }
1493  else
1494  RemoveFromLayout();
1495 
1496  if( pUp && !pUp->Lower() )
1497  {
1498  pUp->SetCompletePaint();
1499  pUp->InvalidatePage();
1500  }
1501 }
1502 
1503 SwTwips SwFrame::Grow( SwTwips nDist, bool bTst, bool bInfo )
1504 {
1505  OSL_ENSURE( nDist >= 0, "Negative growth?" );
1506 
1507  PROTOCOL_ENTER( this, bTst ? PROT::GrowTest : PROT::Grow, DbgAction::NONE, &nDist )
1508 
1509  if ( nDist )
1510  {
1511  SwRectFnSet aRectFnSet(this);
1512 
1513  SwTwips nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
1514  if( nPrtHeight > 0 && nDist > (LONG_MAX - nPrtHeight) )
1515  nDist = LONG_MAX - nPrtHeight;
1516 
1517  if ( IsFlyFrame() )
1518  return static_cast<SwFlyFrame*>(this)->Grow_( nDist, bTst );
1519  else if( IsSctFrame() )
1520  return static_cast<SwSectionFrame*>(this)->Grow_( nDist, bTst );
1521  else
1522  {
1523  if (IsCellFrame())
1524  {
1525  const SwCellFrame* pThisCell = static_cast<const SwCellFrame*>(this);
1526  const SwTabFrame* pTab = FindTabFrame();
1527 
1528  // NEW TABLES
1529  if ( pTab->IsVertical() != IsVertical() ||
1530  pThisCell->GetLayoutRowSpan() < 1 )
1531  return 0;
1532  }
1533  const SwTwips nReal = GrowFrame( nDist, bTst, bInfo );
1534  if( !bTst )
1535  {
1536  nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
1537 
1539  aRectFnSet.SetHeight( aPrt, nPrtHeight + ( IsContentFrame() ? nDist : nReal ) );
1540  }
1541  return nReal;
1542  }
1543  }
1544  return 0;
1545 }
1546 
1547 SwTwips SwFrame::Shrink( SwTwips nDist, bool bTst, bool bInfo )
1548 {
1549  OSL_ENSURE( nDist >= 0, "Negative reduction?" );
1550 
1551  PROTOCOL_ENTER( this, bTst ? PROT::ShrinkTest : PROT::Shrink, DbgAction::NONE, &nDist )
1552 
1553  if ( nDist )
1554  {
1555  if ( IsFlyFrame() )
1556  return static_cast<SwFlyFrame*>(this)->Shrink_( nDist, bTst );
1557  else if( IsSctFrame() )
1558  return static_cast<SwSectionFrame*>(this)->Shrink_( nDist, bTst );
1559  else
1560  {
1561  if (IsCellFrame())
1562  {
1563  const SwCellFrame* pThisCell = static_cast<const SwCellFrame*>(this);
1564  const SwTabFrame* pTab = FindTabFrame();
1565 
1566  // NEW TABLES
1567  if ( (pTab && pTab->IsVertical() != IsVertical()) ||
1568  pThisCell->GetLayoutRowSpan() < 1 )
1569  return 0;
1570  }
1571  SwRectFnSet aRectFnSet(this);
1572  SwTwips nReal = aRectFnSet.GetHeight(getFrameArea());
1573  ShrinkFrame( nDist, bTst, bInfo );
1574  nReal -= aRectFnSet.GetHeight(getFrameArea());
1575  if( !bTst )
1576  {
1577  const SwTwips nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
1579  aRectFnSet.SetHeight( aPrt, nPrtHeight - ( IsContentFrame() ? nDist : nReal ) );
1580  }
1581  return nReal;
1582  }
1583  }
1584  return 0;
1585 }
1586 
1608 {
1609  PROTOCOL_ENTER( this, PROT::AdjustN, DbgAction::NONE, &nDiff );
1610 
1611  if ( !nDiff || !GetUpper()->IsFootnoteBossFrame() ) // only inside pages/columns
1612  return 0;
1613 
1614  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
1615  const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1616 
1617  //The (Page-)Body only changes in BrowseMode, but only if it does not
1618  //contain columns.
1619  if ( IsPageBodyFrame() && (!bBrowse ||
1620  (static_cast<SwLayoutFrame*>(this)->Lower() &&
1621  static_cast<SwLayoutFrame*>(this)->Lower()->IsColumnFrame())) )
1622  return 0;
1623 
1624  //In BrowseView mode the PageFrame can handle some of the requests.
1625  tools::Long nBrowseAdd = 0;
1626  if ( bBrowse && GetUpper()->IsPageFrame() ) // only (Page-)BodyFrames
1627  {
1628  SwViewShell *pViewShell = getRootFrame()->GetCurrShell();
1629  SwLayoutFrame *pUp = GetUpper();
1630  tools::Long nChg;
1631  const tools::Long nUpPrtBottom = pUp->getFrameArea().Height() -
1632  pUp->getFramePrintArea().Height() - pUp->getFramePrintArea().Top();
1633  SwRect aInva( pUp->getFrameArea() );
1634  if ( pViewShell )
1635  {
1636  aInva.Pos().setX( pViewShell->VisArea().Left() );
1637  aInva.Width( pViewShell->VisArea().Width() );
1638  }
1639  if ( nDiff > 0 )
1640  {
1641  nChg = BROWSE_HEIGHT - pUp->getFrameArea().Height();
1642  nChg = std::min( nDiff, SwTwips(nChg) );
1643 
1644  if ( !IsBodyFrame() )
1645  {
1646  SetCompletePaint();
1647  if ( !pViewShell || pViewShell->VisArea().Height() >= pUp->getFrameArea().Height() )
1648  {
1649  //First minimize Body, it will grow again later.
1650  SwFrame *pBody = static_cast<SwFootnoteBossFrame*>(pUp)->FindBodyCont();
1651  const tools::Long nTmp = nChg - pBody->getFramePrintArea().Height();
1652  if ( !bTst )
1653  {
1654  {
1656  aFrm.Height(std::max( tools::Long(0), aFrm.Height() - nChg ));
1657  }
1658 
1659  pBody->InvalidatePrt_();
1660  pBody->InvalidateSize_();
1661  if ( pBody->GetNext() )
1662  pBody->GetNext()->InvalidatePos_();
1663  if ( !IsHeaderFrame() )
1664  pBody->SetCompletePaint();
1665  }
1666  nChg = nTmp <= 0 ? 0 : nTmp;
1667  }
1668  }
1669 
1670  const tools::Long nTmp = nUpPrtBottom + 20;
1671  aInva.Top( aInva.Bottom() - nTmp );
1672  aInva.Height( nChg + nTmp );
1673  }
1674  else
1675  {
1676  //The page can shrink to 0. The first page keeps the same size like
1677  //VisArea.
1678  nChg = nDiff;
1679  tools::Long nInvaAdd = 0;
1680  if ( pViewShell && !pUp->GetPrev() &&
1681  pUp->getFrameArea().Height() + nDiff < pViewShell->VisArea().Height() )
1682  {
1683  // This means that we have to invalidate adequately.
1684  nChg = pViewShell->VisArea().Height() - pUp->getFrameArea().Height();
1685  nInvaAdd = -(nDiff - nChg);
1686  }
1687 
1688  //Invalidate including bottom border.
1689  tools::Long nBorder = nUpPrtBottom + 20;
1690  nBorder -= nChg;
1691  aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) );
1692  if ( !IsBodyFrame() )
1693  {
1694  SetCompletePaint();
1695  if ( !IsHeaderFrame() )
1696  static_cast<SwFootnoteBossFrame*>(pUp)->FindBodyCont()->SetCompletePaint();
1697  }
1698  //Invalidate the page because of the frames. Thereby the page becomes
1699  //the right size again if a frame didn't fit. This only works
1700  //randomly for paragraph bound frames otherwise (NotifyFlys).
1701  pUp->InvalidateSize();
1702  }
1703  if ( !bTst )
1704  {
1705  //Independent from nChg
1706  if ( pViewShell && aInva.HasArea() && pUp->GetUpper() )
1707  pViewShell->InvalidateWindows( aInva );
1708  }
1709  if ( !bTst && nChg )
1710  {
1711  {
1713  aFrm.AddHeight(nChg );
1714  }
1715 
1716  {
1718  aPrt.AddHeight(nChg );
1719  }
1720 
1721  if ( pViewShell )
1722  pViewShell->Imp()->SetFirstVisPageInvalid();
1723 
1724  if ( GetNext() )
1725  GetNext()->InvalidatePos_();
1726 
1727  //Trigger a repaint if necessary.
1728  std::unique_ptr<SvxBrushItem> aBack(pUp->GetFormat()->makeBackgroundBrushItem());
1729  const SvxGraphicPosition ePos = aBack ? aBack->GetGraphicPos() : GPOS_NONE;
1730  if ( ePos != GPOS_NONE && ePos != GPOS_TILED )
1731  pViewShell->InvalidateWindows( pUp->getFrameArea() );
1732 
1733  if ( pUp->GetUpper() )
1734  {
1735  if ( pUp->GetNext() )
1736  pUp->GetNext()->InvalidatePos();
1737 
1738  //Sad but true: during notify on ViewImp a Calc on the page and
1739  //its Lower may be called. The values should not be changed
1740  //because the caller takes care of the adjustment of Frame and
1741  //Prt.
1742  const tools::Long nOldFrameHeight = getFrameArea().Height();
1743  const tools::Long nOldPrtHeight = getFramePrintArea().Height();
1744  const bool bOldComplete = IsCompletePaint();
1745 
1746  if ( IsBodyFrame() )
1747  {
1749  aPrt.Height( nOldFrameHeight );
1750  }
1751 
1752  if ( pUp->GetUpper() )
1753  {
1754  static_cast<SwRootFrame*>(pUp->GetUpper())->CheckViewLayout( nullptr, nullptr );
1755  }
1756 
1758  aFrm.Height( nOldFrameHeight );
1759 
1761  aPrt.Height( nOldPrtHeight );
1762 
1763  mbCompletePaint = bOldComplete;
1764  }
1765  if ( !IsBodyFrame() )
1766  pUp->InvalidateSize_();
1767  InvalidatePage( static_cast<SwPageFrame*>(pUp) );
1768  }
1769  nDiff -= nChg;
1770  if ( !nDiff )
1771  return nChg;
1772  else
1773  nBrowseAdd = nChg;
1774  }
1775 
1776  const SwFootnoteBossFrame *pBoss = static_cast<SwFootnoteBossFrame*>(GetUpper());
1777 
1778  SwTwips nReal = 0,
1779  nAdd = 0;
1780  SwFrame *pFrame = nullptr;
1781  SwRectFnSet aRectFnSet(this);
1782 
1783  if( IsBodyFrame() )
1784  {
1785  if( IsInSct() )
1786  {
1787  SwSectionFrame *pSect = FindSctFrame();
1788  if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() &&
1790  {
1791  SwFootnoteContFrame* pCont = static_cast<SwFootnoteContFrame*>(GetNext());
1792  SwTwips nMinH = 0;
1793  SwFootnoteFrame* pFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower());
1794  bool bFootnote = false;
1795  while( pFootnote )
1796  {
1797  if( !pFootnote->GetAttr()->GetFootnote().IsEndNote() )
1798  {
1799  nMinH += aRectFnSet.GetHeight(pFootnote->getFrameArea());
1800  bFootnote = true;
1801  }
1802  pFootnote = static_cast<SwFootnoteFrame*>(pFootnote->GetNext());
1803  }
1804  if( bFootnote )
1805  nMinH += aRectFnSet.GetTop(pCont->getFramePrintArea());
1806  nReal = aRectFnSet.GetHeight(pCont->getFrameArea()) - nMinH;
1807  if( nReal > nDiff )
1808  nReal = nDiff;
1809  if( nReal > 0 )
1810  pFrame = GetNext();
1811  else
1812  nReal = 0;
1813  }
1814  if( !bTst && !pSect->IsColLocked() )
1815  pSect->InvalidateSize();
1816  }
1817  if( !pFrame )
1818  return nBrowseAdd;
1819  }
1820  else
1821  {
1822  const bool bFootnotePage = pBoss->IsPageFrame() && static_cast<const SwPageFrame*>(pBoss)->IsFootnotePage();
1823  if ( bFootnotePage && !IsFootnoteContFrame() )
1824  pFrame = const_cast<SwFrame*>(static_cast<SwFrame const *>(pBoss->FindFootnoteCont()));
1825  if ( !pFrame )
1826  pFrame = const_cast<SwFrame*>(static_cast<SwFrame const *>(pBoss->FindBodyCont()));
1827 
1828  if ( !pFrame )
1829  return 0;
1830 
1831  //If not one is found, everything else is solved.
1832  nReal = aRectFnSet.GetHeight(pFrame->getFrameArea());
1833  if( nReal > nDiff )
1834  nReal = nDiff;
1835  if( !bFootnotePage )
1836  {
1837  //Respect the minimal boundary!
1838  if( nReal )
1839  {
1840  const SwTwips nMax = pBoss->GetVarSpace();
1841  if ( nReal > nMax )
1842  nReal = nMax;
1843  }
1844  if( !IsFootnoteContFrame() && nDiff > nReal &&
1845  pFrame->GetNext() && pFrame->GetNext()->IsFootnoteContFrame()
1846  && ( pFrame->GetNext()->IsVertical() == IsVertical() )
1847  )
1848  {
1849  //If the Body doesn't return enough, we look for a footnote, if
1850  //there is one, we steal there accordingly.
1851  const SwTwips nAddMax = aRectFnSet.GetHeight(pFrame->GetNext()->getFrameArea());
1852  nAdd = nDiff - nReal;
1853  if ( nAdd > nAddMax )
1854  nAdd = nAddMax;
1855  if ( !bTst )
1856  {
1857  {
1859  aRectFnSet.SetHeight(aFrm, nAddMax-nAdd);
1860 
1861  if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
1862  {
1863  aFrm.Pos().AdjustX(nAdd );
1864  }
1865  }
1866 
1867  pFrame->GetNext()->InvalidatePrt();
1868 
1869  if ( pFrame->GetNext()->GetNext() )
1870  {
1871  pFrame->GetNext()->GetNext()->InvalidatePos_();
1872  }
1873  }
1874  }
1875  }
1876  }
1877 
1878  if ( !bTst && nReal )
1879  {
1880  SwTwips nTmp = aRectFnSet.GetHeight(pFrame->getFrameArea());
1881 
1882  {
1884  aRectFnSet.SetHeight( aFrm, nTmp - nReal );
1885 
1886  if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
1887  {
1888  aFrm.Pos().AdjustX(nReal );
1889  }
1890  }
1891 
1892  pFrame->InvalidatePrt();
1893 
1894  if ( pFrame->GetNext() )
1895  pFrame->GetNext()->InvalidatePos_();
1896 
1897  if( nReal < 0 && pFrame->IsInSct() )
1898  {
1899  SwLayoutFrame* pUp = pFrame->GetUpper();
1900  if( pUp && nullptr != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrame() &&
1901  !pUp->IsColLocked() )
1902  pUp->InvalidateSize();
1903  }
1904  if( ( IsHeaderFrame() || IsFooterFrame() ) && pBoss->GetDrawObjs() )
1905  {
1906  const SwSortedObjs &rObjs = *pBoss->GetDrawObjs();
1907  OSL_ENSURE( pBoss->IsPageFrame(), "Header/Footer out of page?" );
1908  for (SwAnchoredObject* pAnchoredObj : rObjs)
1909  {
1910  if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
1911  {
1912  OSL_ENSURE( !pFly->IsFlyInContentFrame(), "FlyInCnt at Page?" );
1913  const SwFormatVertOrient &rVert =
1914  pFly->GetFormat()->GetVertOrient();
1915  // When do we have to invalidate?
1916  // If a frame is aligned on a PageTextArea and the header
1917  // changes a TOP, MIDDLE or NONE aligned frame needs to
1918  // recalculate it's position; if the footer changes a BOTTOM
1919  // or MIDDLE aligned frame needs to recalculate it's
1920  // position.
1921  if( ( rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
1922  rVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) &&
1923  ((IsHeaderFrame() && rVert.GetVertOrient()!=text::VertOrientation::BOTTOM) ||
1924  (IsFooterFrame() && rVert.GetVertOrient()!=text::VertOrientation::NONE &&
1925  rVert.GetVertOrient() != text::VertOrientation::TOP)) )
1926  {
1927  pFly->InvalidatePos_();
1928  pFly->Invalidate_();
1929  }
1930  }
1931  }
1932  }
1933  }
1934  return (nBrowseAdd + nReal + nAdd);
1935 }
1936 
1939 {
1940  // default behaviour is to perform no additional action
1941 }
1942 
1945 {
1946  // default behaviour is to allow invalidation
1947  return true;
1948 }
1949 
1951 {
1953  {
1954  setFrameAreaSizeValid(false);
1955 
1956  if ( IsFlyFrame() )
1957  static_cast<SwFlyFrame*>(this)->Invalidate_();
1958  else
1959  InvalidatePage();
1960 
1961  // OD 2004-05-19 #i28701#
1963  }
1964 }
1965 
1967 {
1969  {
1970  setFramePrintAreaValid(false);
1971 
1972  if ( IsFlyFrame() )
1973  static_cast<SwFlyFrame*>(this)->Invalidate_();
1974  else
1975  InvalidatePage();
1976 
1977  // OD 2004-05-19 #i28701#
1979  }
1980 }
1981 
1983 {
1984  if ( !InvalidationAllowed( INVALID_POS ) )
1985  return;
1986 
1988 
1989  if ( IsFlyFrame() )
1990  {
1991  static_cast<SwFlyFrame*>(this)->Invalidate_();
1992  }
1993  else
1994  {
1995  InvalidatePage();
1996  }
1997 
1998  // OD 2004-05-19 #i28701#
2000 }
2001 
2003 {
2005  {
2006  mbValidLineNum = false;
2007  OSL_ENSURE( IsTextFrame(), "line numbers are implemented for text only" );
2008  InvalidatePage();
2009 
2010  // OD 2004-05-19 #i28701#
2012  }
2013 }
2014 
2016 {
2017  const SwFormatFrameSize &rFormatSize = GetAttrSet()->GetFrameSize();
2018  if ( SwFrameSize::Variable == rFormatSize.GetHeightSizeType() ||
2019  SwFrameSize::Minimum == rFormatSize.GetHeightSizeType())
2020  {
2021  mbFixSize = false;
2023  {
2024  SwFrame *pFrame = static_cast<SwLayoutFrame*>(this)->Lower();
2025  while ( pFrame )
2026  { pFrame->InvalidateSize_();
2027  pFrame->InvalidatePrt_();
2028  pFrame = pFrame->GetNext();
2029  }
2030  SwContentFrame *pCnt = static_cast<SwLayoutFrame*>(this)->ContainsContent();
2031  // #i36991# - be save.
2032  // E.g., a row can contain *no* content.
2033  if ( pCnt )
2034  {
2035  pCnt->InvalidatePage();
2036  do
2037  {
2039  pCnt->InvalidateSize_();
2040  pCnt = pCnt->GetNextContentFrame();
2041  } while ( static_cast<SwLayoutFrame*>(this)->IsAnLower( pCnt ) );
2042  }
2043  }
2044  }
2045  else if ( rFormatSize.GetHeightSizeType() == SwFrameSize::Fixed )
2046  {
2047  if( IsVertical() )
2048  ChgSize( Size( rFormatSize.GetWidth(), getFrameArea().Height()));
2049  else
2050  ChgSize( Size( getFrameArea().Width(), rFormatSize.GetHeight()));
2051  }
2052 }
2053 
2054 void SwFrame::ValidateThisAndAllLowers( const sal_uInt16 nStage )
2055 {
2056  // Stage 0: Only validate frames. Do not process any objects.
2057  // Stage 1: Only validate fly frames and all of their contents.
2058  // Stage 2: Validate all.
2059 
2060  const bool bOnlyObject = 1 == nStage;
2061  const bool bIncludeObjects = 1 <= nStage;
2062 
2063  if ( !bOnlyObject || IsFlyFrame() )
2064  {
2065  setFrameAreaSizeValid(true);
2066  setFramePrintAreaValid(true);
2068  }
2069 
2070  if ( bIncludeObjects )
2071  {
2072  const SwSortedObjs* pObjs = GetDrawObjs();
2073  if ( pObjs )
2074  {
2075  const size_t nCnt = pObjs->size();
2076  for ( size_t i = 0; i < nCnt; ++i )
2077  {
2078  SwAnchoredObject* pAnchObj = (*pObjs)[i];
2079  if ( auto pFlyFrame = pAnchObj->DynCastFlyFrame() )
2080  pFlyFrame->ValidateThisAndAllLowers( 2 );
2081  else if ( auto pAnchoredDrawObj = dynamic_cast<SwAnchoredDrawObject *>( pAnchObj ) )
2082  pAnchoredDrawObj->ValidateThis();
2083  }
2084  }
2085  }
2086 
2087  if ( IsLayoutFrame() )
2088  {
2089  SwFrame* pLower = static_cast<SwLayoutFrame*>(this)->Lower();
2090  while ( pLower )
2091  {
2092  pLower->ValidateThisAndAllLowers( nStage );
2093  pLower = pLower->GetNext();
2094  }
2095  }
2096 }
2097 
2098 SwTwips SwContentFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo )
2099 {
2100  SwRectFnSet aRectFnSet(this);
2101 
2102  SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
2103  if( nFrameHeight > 0 &&
2104  nDist > (LONG_MAX - nFrameHeight ) )
2105  nDist = LONG_MAX - nFrameHeight;
2106 
2107  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
2108  const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2110  if (bBrowse)
2111  nTmpType |= SwFrameType::Body;
2112  if( !(GetUpper()->GetType() & nTmpType) && GetUpper()->HasFixSize() )
2113  {
2114  if ( !bTst )
2115  {
2116  {
2118  aRectFnSet.SetHeight( aFrm, nFrameHeight + nDist );
2119 
2120  if( IsVertical() && !IsVertLR() )
2121  {
2122  aFrm.Pos().AdjustX( -nDist );
2123  }
2124  }
2125 
2126  if ( GetNext() )
2127  {
2128  GetNext()->InvalidatePos();
2129  }
2130  // #i28701# - Due to the new object positioning the
2131  // frame on the next page/column can flow backward (e.g. it was moved forward
2132  // due to the positioning of its objects ). Thus, invalivate this next frame,
2133  // if document compatibility option 'Consider wrapping style influence on
2134  // object positioning' is ON.
2135  else if ( GetUpper()->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) )
2136  {
2138  }
2139  }
2140  return 0;
2141  }
2142 
2143  SwTwips nReal = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea());
2144  SwFrame *pFrame = GetUpper()->Lower();
2145  while( pFrame && nReal > 0 )
2146  { nReal -= aRectFnSet.GetHeight(pFrame->getFrameArea());
2147  pFrame = pFrame->GetNext();
2148  }
2149 
2150  if ( !bTst )
2151  {
2152  //Contents are always resized to the wished value.
2153  tools::Long nOld = aRectFnSet.GetHeight(getFrameArea());
2154 
2155  {
2157 
2158  aRectFnSet.SetHeight( aFrm, nOld + nDist );
2159 
2160  if( IsVertical()&& !IsVertLR() )
2161  {
2162  aFrm.Pos().AdjustX( -nDist );
2163  }
2164  }
2165 
2166  SwTabFrame *pTab = (nOld && IsInTab()) ? FindTabFrame() : nullptr;
2167  if (pTab)
2168  {
2169  if ( pTab->GetTable()->GetHTMLTableLayout() &&
2170  !pTab->IsJoinLocked() &&
2171  !pTab->GetFormat()->GetDoc()->GetDocShell()->IsReadOnly() )
2172  {
2173  pTab->InvalidatePos();
2174  pTab->SetResizeHTMLTable();
2175  }
2176  }
2177  }
2178 
2179  //Only grow Upper if necessary.
2180  if ( nReal < nDist )
2181  {
2182  if( GetUpper() )
2183  {
2184  if( bTst || !GetUpper()->IsFooterFrame() )
2185  nReal = GetUpper()->Grow( nDist - std::max<tools::Long>(nReal, 0),
2186  bTst, bInfo );
2187  else
2188  {
2189  nReal = 0;
2190  GetUpper()->InvalidateSize();
2191  }
2192  }
2193  else
2194  nReal = 0;
2195  }
2196  else
2197  nReal = nDist;
2198 
2199  // #i28701# - Due to the new object positioning the
2200  // frame on the next page/column can flow backward (e.g. it was moved forward
2201  // due to the positioning of its objects ). Thus, invalivate this next frame,
2202  // if document compatibility option 'Consider wrapping style influence on
2203  // object positioning' is ON.
2204  if ( !bTst )
2205  {
2206  if ( GetNext() )
2207  {
2208  GetNext()->InvalidatePos();
2209  }
2210  else if ( GetUpper()->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) )
2211  {
2213  }
2214  }
2215 
2216  return nReal;
2217 }
2218 
2219 SwTwips SwContentFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo )
2220 {
2221  SwRectFnSet aRectFnSet(this);
2222  OSL_ENSURE( nDist >= 0, "nDist < 0" );
2223  OSL_ENSURE( nDist <= aRectFnSet.GetHeight(getFrameArea()),
2224  "nDist > than current size." );
2225 
2226  if ( !bTst )
2227  {
2228  SwTwips nRstHeight;
2229  if( GetUpper() )
2230  nRstHeight = aRectFnSet.BottomDist( getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper()) );
2231  else
2232  nRstHeight = 0;
2233  if( nRstHeight < 0 )
2234  {
2235  SwTwips nNextHeight = 0;
2236  if( GetUpper()->IsSctFrame() && nDist > LONG_MAX/2 )
2237  {
2238  SwFrame *pNxt = GetNext();
2239  while( pNxt )
2240  {
2241  nNextHeight += aRectFnSet.GetHeight(pNxt->getFrameArea());
2242  pNxt = pNxt->GetNext();
2243  }
2244  }
2245  nRstHeight = nDist + nRstHeight - nNextHeight;
2246  }
2247  else
2248  {
2249  nRstHeight = nDist;
2250  }
2251 
2252  {
2254  aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) - nDist );
2255 
2256  if( IsVertical() && !IsVertLR() )
2257  {
2258  aFrm.Pos().AdjustX(nDist );
2259  }
2260  }
2261 
2262  nDist = nRstHeight;
2263  SwTabFrame *pTab = IsInTab() ? FindTabFrame() : nullptr;
2264  if (pTab)
2265  {
2266  if ( pTab->GetTable()->GetHTMLTableLayout() &&
2267  !pTab->IsJoinLocked() &&
2268  !pTab->GetFormat()->GetDoc()->GetDocShell()->IsReadOnly() )
2269  {
2270  pTab->InvalidatePos();
2271  pTab->SetResizeHTMLTable();
2272  }
2273  }
2274  }
2275 
2276  SwTwips nReal;
2277  if( GetUpper() && nDist > 0 )
2278  {
2279  if( bTst || !GetUpper()->IsFooterFrame() )
2280  nReal = GetUpper()->Shrink( nDist, bTst, bInfo );
2281  else
2282  {
2283  nReal = 0;
2284 
2285  // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you,
2286  // if there are any objects anchored inside your content, which
2287  // overlap with the shrinking frame.
2288  // This may lead to a footer frame that is too big, but this is better
2289  // than looping.
2290  // #109722# : The fix for #108745# was too strict.
2291 
2292  bool bInvalidate = true;
2293  const SwRect aRect( getFrameArea() );
2294  const SwPageFrame* pPage = FindPageFrame();
2295  const SwSortedObjs* pSorted = pPage ? pPage->GetSortedObjs() : nullptr;
2296  if( pSorted )
2297  {
2298  for (SwAnchoredObject* pAnchoredObj : *pSorted)
2299  {
2300  const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
2301 
2302  if( aBound.Left() > aRect.Right() )
2303  continue;
2304 
2305  if( aBound.Overlaps( aRect ) )
2306  {
2307  const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat();
2308  if( css::text::WrapTextMode_THROUGH != rFormat.GetSurround().GetSurround() )
2309  {
2310  const SwFrame* pAnchor = pAnchoredObj->GetAnchorFrame();
2311  if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() )
2312  {
2313  bInvalidate = false;
2314  break;
2315  }
2316  }
2317  }
2318  }
2319  }
2320 
2321  if ( bInvalidate )
2322  GetUpper()->InvalidateSize();
2323  }
2324  }
2325  else
2326  nReal = 0;
2327 
2328  if ( !bTst )
2329  {
2330  //The position of the next Frame changes for sure.
2332 
2333  //If I don't have a successor I have to do the retouch by myself.
2334  if ( !GetNext() )
2335  SetRetouche();
2336  }
2337  return nReal;
2338 }
2339 
2340 void SwContentFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
2341 {
2342  if (rHint.GetId() != SfxHintId::SwLegacyModify)
2343  return;
2344  auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
2346  if(pLegacy->m_pNew && RES_ATTRSET_CHG == pLegacy->m_pNew->Which() && pLegacy->m_pOld)
2347  {
2348  auto& rOldSetChg = *static_cast<const SwAttrSetChg*>(pLegacy->m_pOld);
2349  auto& rNewSetChg = *static_cast<const SwAttrSetChg*>(pLegacy->m_pNew);
2350  SfxItemIter aOIter(*rOldSetChg.GetChgSet());
2351  SfxItemIter aNIter(*rNewSetChg.GetChgSet());
2352  const SfxPoolItem* pNItem = aNIter.GetCurItem();
2353  const SfxPoolItem* pOItem = aOIter.GetCurItem();
2354  SwAttrSetChg aOldSet(rOldSetChg);
2355  SwAttrSetChg aNewSet(rNewSetChg);
2356  do
2357  {
2358  UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
2359  pNItem = aNIter.NextItem();
2360  pOItem = aOIter.NextItem();
2361  } while(pNItem);
2362  if(aOldSet.Count() || aNewSet.Count())
2363  SwFrame::SwClientNotify(rMod, sw::LegacyModifyHint(&aOldSet, &aNewSet));
2364  }
2365  else
2366  UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
2367 
2368  if(eInvFlags == SwContentFrameInvFlags::NONE)
2369  return;
2370 
2371  SwPageFrame* pPage = FindPageFrame();
2372  InvalidatePage(pPage);
2374  SetCompletePaint();
2376  InvalidatePos_();
2378  InvalidateSize_();
2380  {
2381  if(IsInSct() && !GetPrev())
2382  {
2383  SwSectionFrame* pSect = FindSctFrame();
2384  if(pSect->ContainsAny() == this)
2385  {
2386  pSect->InvalidatePrt_();
2387  pSect->InvalidatePage(pPage);
2388  }
2389  }
2390  InvalidatePrt_();
2391  }
2392  SwFrame* pNextFrame = GetIndNext();
2393  if(pNextFrame && eInvFlags & SwContentFrameInvFlags::InvalidateNextPrt)
2394  {
2395  pNextFrame->InvalidatePrt_();
2396  pNextFrame->InvalidatePage(pPage);
2397  }
2398  if(pNextFrame && eInvFlags & SwContentFrameInvFlags::SetNextCompletePaint)
2399  {
2400  pNextFrame->SetCompletePaint();
2401  }
2403  {
2404  SwFrame* pPrevFrame = GetPrev();
2405  if(pPrevFrame)
2406  {
2407  pPrevFrame->InvalidatePrt_();
2408  pPrevFrame->InvalidatePage(pPage);
2409  }
2410  }
2413 }
2414 
2415 void SwContentFrame::UpdateAttr_( const SfxPoolItem* pOld, const SfxPoolItem* pNew,
2416  SwContentFrameInvFlags &rInvFlags,
2417  SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
2418 {
2419  bool bClear = true;
2420  sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
2421  switch ( nWhich )
2422  {
2423  case RES_FMT_CHG:
2432  [[fallthrough]];
2433 
2434  case RES_PAGEDESC: //attribute changes (on/off)
2435  if ( IsInDocBody() && !IsInTab() )
2436  {
2438  SwPageFrame *pPage = FindPageFrame();
2439  if ( !GetPrev() )
2440  CheckPageDescs( pPage );
2441  if (GetPageDescItem().GetNumOffset())
2442  static_cast<SwRootFrame*>(pPage->GetUpper())->SetVirtPageNum( true );
2443  SwDocPosUpdate aMsgHint( pPage->getFrameArea().Top() );
2444  pPage->GetFormat()->GetDoc()->getIDocumentFieldsAccess().UpdatePageFields( &aMsgHint );
2445  }
2446  break;
2447 
2448  case RES_UL_SPACE:
2449  {
2450  // OD 2004-02-18 #106629# - correction
2451  // Invalidation of the printing area of next frame, not only
2452  // for footnote content.
2453  if ( !GetIndNext() )
2454  {
2455  SwFrame* pNxt = FindNext();
2456  if ( pNxt )
2457  {
2458  SwPageFrame* pPg = pNxt->FindPageFrame();
2459  pNxt->InvalidatePage( pPg );
2460  pNxt->InvalidatePrt_();
2461  if( pNxt->IsSctFrame() )
2462  {
2463  SwFrame* pCnt = static_cast<SwSectionFrame*>(pNxt)->ContainsAny();
2464  if( pCnt )
2465  {
2466  pCnt->InvalidatePrt_();
2467  pCnt->InvalidatePage( pPg );
2468  }
2469  }
2470  pNxt->SetCompletePaint();
2471  }
2472  }
2473  // OD 2004-03-17 #i11860#
2474  if ( GetIndNext() &&
2475  !GetUpper()->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::USE_FORMER_OBJECT_POS) )
2476  {
2477  // OD 2004-07-01 #i28701# - use new method <InvalidateObjs(..)>
2479  }
2480  Prepare( PrepareHint::ULSpaceChanged ); //TextFrame has to correct line spacing.
2482  [[fallthrough]];
2483  }
2484  case RES_LR_SPACE:
2485  case RES_BOX:
2486  case RES_SHADOW:
2487  {
2489  SwModify aMod;
2490  SwFrame::SwClientNotify(aMod, sw::LegacyModifyHint(pOld, pNew));
2492  break;
2493  }
2494  case RES_BREAK:
2495  {
2500  {
2502  SwFrame* pNxt = FindNext();
2503  if( pNxt )
2504  {
2505  SwPageFrame* pPg = pNxt->FindPageFrame();
2506  pNxt->InvalidatePage( pPg );
2507  pNxt->InvalidatePrt_();
2508  if( pNxt->IsSctFrame() )
2509  {
2510  SwFrame* pCnt = static_cast<SwSectionFrame*>(pNxt)->ContainsAny();
2511  if( pCnt )
2512  {
2513  pCnt->InvalidatePrt_();
2514  pCnt->InvalidatePage( pPg );
2515  }
2516  }
2517  pNxt->SetCompletePaint();
2518  }
2519  }
2520  }
2521  break;
2522 
2523  // OD 2004-02-26 #i25029#
2525  {
2527  if ( IsTextFrame() )
2528  {
2530  }
2531  if ( !GetIndNext() && IsInTab() && IsInSplitTableRow() )
2532  {
2534  }
2535  }
2536  break;
2537 
2538  case RES_PARATR_TABSTOP:
2539  case RES_CHRATR_SHADOWED:
2540  case RES_CHRATR_AUTOKERN:
2541  case RES_CHRATR_UNDERLINE:
2542  case RES_CHRATR_OVERLINE:
2543  case RES_CHRATR_KERNING:
2544  case RES_CHRATR_FONT:
2545  case RES_CHRATR_FONTSIZE:
2546  case RES_CHRATR_ESCAPEMENT:
2547  case RES_CHRATR_CONTOUR:
2548  case RES_PARATR_NUMRULE:
2550  break;
2551 
2552  case RES_FRM_SIZE:
2554  [[fallthrough]];
2555 
2556  default:
2557  bClear = false;
2558  }
2559  if ( !bClear )
2560  return;
2561 
2562  if ( pOldSet || pNewSet )
2563  {
2564  if ( pOldSet )
2565  pOldSet->ClearItem( nWhich );
2566  if ( pNewSet )
2567  pNewSet->ClearItem( nWhich );
2568  }
2569  else
2570  {
2571  SwModify aMod;
2572  SwFrame::SwClientNotify(aMod, sw::LegacyModifyHint(pOld, pNew));
2573  }
2574 }
2575 
2577  : SwFrame(pFormat, pSib)
2578  , m_pLower(nullptr)
2579 {
2580  const SwFormatFrameSize &rFormatSize = pFormat->GetFrameSize();
2581  if ( rFormatSize.GetHeightSizeType() == SwFrameSize::Fixed )
2582  mbFixSize = true;
2583 }
2584 
2585 // #i28701#
2586 
2588 {
2589  const SwFrame* pCnt = Lower();
2590  if (!pCnt)
2591  return 0;
2592 
2593  SwRectFnSet aRectFnSet(this);
2594  SwTwips nRet = 0;
2595  if( pCnt->IsColumnFrame() || pCnt->IsCellFrame() )
2596  {
2597  do
2598  {
2599  SwTwips nTmp = static_cast<const SwLayoutFrame*>(pCnt)->InnerHeight();
2600  if( pCnt->isFramePrintAreaValid() )
2601  nTmp += aRectFnSet.GetHeight(pCnt->getFrameArea()) -
2602  aRectFnSet.GetHeight(pCnt->getFramePrintArea());
2603  if( nRet < nTmp )
2604  nRet = nTmp;
2605  pCnt = pCnt->GetNext();
2606  } while ( pCnt );
2607  }
2608  else
2609  {
2610  do
2611  {
2612  nRet += aRectFnSet.GetHeight(pCnt->getFrameArea());
2613  if( pCnt->IsContentFrame() && static_cast<const SwTextFrame*>(pCnt)->IsUndersized() )
2614  nRet += static_cast<const SwTextFrame*>(pCnt)->GetParHeight() -
2615  aRectFnSet.GetHeight(pCnt->getFramePrintArea());
2616  if( pCnt->IsLayoutFrame() && !pCnt->IsTabFrame() )
2617  nRet += static_cast<const SwLayoutFrame*>(pCnt)->InnerHeight() -
2618  aRectFnSet.GetHeight(pCnt->getFramePrintArea());
2619  pCnt = pCnt->GetNext();
2620  } while( pCnt );
2621 
2622  }
2623  return nRet;
2624 }
2625 
2626 SwTwips SwLayoutFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo )
2627 {
2628  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
2629  const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2631  if (bBrowse)
2632  nTmpType |= SwFrameType::Body;
2633  if( !(GetType() & nTmpType) && HasFixSize() )
2634  return 0;
2635 
2636  SwRectFnSet aRectFnSet(this);
2637  const SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
2638  const SwTwips nFramePos = getFrameArea().Pos().X();
2639 
2640  if ( nFrameHeight > 0 && nDist > (LONG_MAX - nFrameHeight) )
2641  nDist = LONG_MAX - nFrameHeight;
2642 
2643  SwTwips nMin = 0;
2644  if ( GetUpper() && !IsCellFrame() )
2645  {
2646  SwFrame *pFrame = GetUpper()->Lower();
2647  while( pFrame )
2648  { nMin += aRectFnSet.GetHeight(pFrame->getFrameArea());
2649  pFrame = pFrame->GetNext();
2650  }
2651  nMin = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) - nMin;
2652  if ( nMin < 0 )
2653  nMin = 0;
2654  }
2655 
2656  SwRect aOldFrame( getFrameArea() );
2657  bool bMoveAccFrame = false;
2658 
2659  bool bChgPos = IsVertical();
2660  if ( !bTst )
2661  {
2663  aRectFnSet.SetHeight( aFrm, nFrameHeight + nDist );
2664 
2665  if( bChgPos && !IsVertLR() )
2666  {
2667  aFrm.Pos().AdjustX( -nDist );
2668  }
2669 
2670  bMoveAccFrame = true;
2671  }
2672 
2673  SwTwips nReal = nDist - nMin;
2674  if ( nReal > 0 )
2675  {
2676  if ( GetUpper() )
2677  { // AdjustNeighbourhood now only for the columns (but not in frames)
2679  static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment()
2681  if( SwNeighbourAdjust::OnlyAdjust == nAdjust )
2682  nReal = AdjustNeighbourhood( nReal, bTst );
2683  else
2684  {
2685  if( SwNeighbourAdjust::AdjustGrow == nAdjust )
2686  nReal += AdjustNeighbourhood( nReal, bTst );
2687 
2688  SwTwips nGrow = 0;
2689  if( 0 < nReal )
2690  {
2691  SwFrame* pToGrow = GetUpper();
2692  // NEW TABLES
2693  // A cell with a row span of > 1 is allowed to grow the
2694  // line containing the end of the row span if it is
2695  // located in the same table frame:
2696  if (IsCellFrame())
2697  {
2698  const SwCellFrame* pThisCell = static_cast<const SwCellFrame*>(this);
2699  if ( pThisCell->GetLayoutRowSpan() > 1 )
2700  {
2701  SwCellFrame& rEndCell = const_cast<SwCellFrame&>(pThisCell->FindStartEndOfRowSpanCell( false ));
2702  if ( -1 == rEndCell.GetTabBox()->getRowSpan() )
2703  pToGrow = rEndCell.GetUpper();
2704  else
2705  pToGrow = nullptr;
2706  }
2707  }
2708  nGrow = pToGrow ? pToGrow->Grow( nReal, bTst, bInfo ) : 0;
2709  }
2710 
2711  if( SwNeighbourAdjust::GrowAdjust == nAdjust && nGrow < nReal )
2712  nReal = o3tl::saturating_add(nReal, AdjustNeighbourhood( nReal - nGrow, bTst ));
2713 
2714  if ( IsFootnoteFrame() && (nGrow != nReal) && GetNext() )
2715  {
2716  //Footnotes can replace their successor.
2717  SwTwips nSpace = bTst ? 0 : -nDist;
2718  const SwFrame *pFrame = GetUpper()->Lower();
2719  do
2720  { nSpace += aRectFnSet.GetHeight(pFrame->getFrameArea());
2721  pFrame = pFrame->GetNext();
2722  } while ( pFrame != GetNext() );
2723  nSpace = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) -nSpace;
2724  if ( nSpace < 0 )
2725  nSpace = 0;
2726  nSpace += nGrow;
2727  if ( nReal > nSpace )
2728  nReal = nSpace;
2729  if ( nReal && !bTst )
2730  static_cast<SwFootnoteFrame*>(this)->InvalidateNxtFootnoteCnts( FindPageFrame() );
2731  }
2732  else
2733  nReal = nGrow;
2734  }
2735  }
2736  else
2737  nReal = 0;
2738 
2739  nReal += nMin;
2740  }
2741  else
2742  nReal = nDist;
2743 
2744  if ( !bTst )
2745  {
2746  if( nReal != nDist &&
2747  // NEW TABLES
2748  ( !IsCellFrame() || static_cast<SwCellFrame*>(this)->GetLayoutRowSpan() > 1 ) )
2749  {
2751  aRectFnSet.SetHeight( aFrm, nFrameHeight + nReal );
2752 
2753  if( bChgPos && !IsVertLR() )
2754  {
2755  aFrm.Pos().setX( nFramePos - nReal );
2756  }
2757 
2758  bMoveAccFrame = true;
2759  }
2760 
2761  if ( nReal )
2762  {
2763  SwPageFrame *pPage = FindPageFrame();
2764  if ( GetNext() )
2765  {
2766  GetNext()->InvalidatePos_();
2767  if ( GetNext()->IsContentFrame() )
2768  GetNext()->InvalidatePage( pPage );
2769  }
2770  if ( !IsPageBodyFrame() )
2771  {
2772  InvalidateAll_();
2773  InvalidatePage( pPage );
2774  }
2776  NotifyLowerObjs();
2777 
2778  if( IsCellFrame() )
2779  InvaPercentLowers( nReal );
2780 
2781  std::unique_ptr<SvxBrushItem> aBack(GetFormat()->makeBackgroundBrushItem());
2782  const SvxGraphicPosition ePos = aBack ? aBack->GetGraphicPos() : GPOS_NONE;
2783  if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
2784  SetCompletePaint();
2785  }
2786  }
2787 
2788  if( bMoveAccFrame && IsAccessibleFrame() )
2789  {
2790  SwRootFrame *pRootFrame = getRootFrame();
2791  if( pRootFrame && pRootFrame->IsAnyShellAccessible() &&
2792  pRootFrame->GetCurrShell() )
2793  {
2794  pRootFrame->GetCurrShell()->Imp()->MoveAccessibleFrame( this, aOldFrame );
2795  }
2796  }
2797  return nReal;
2798 }
2799 
2800 SwTwips SwLayoutFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo )
2801 {
2802  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
2803  const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2805  if (bBrowse)
2806  nTmpType |= SwFrameType::Body;
2807 
2808  if (pSh && pSh->GetViewOptions()->IsWhitespaceHidden())
2809  {
2810  if (IsBodyFrame())
2811  {
2812  // Whitespace is hidden and this body frame will not shrink, as it
2813  // has a fix size.
2814  // Invalidate the page frame size, so in case the reason for the
2815  // shrink was that there is more whitespace on this page, the size
2816  // without whitespace will be recalculated correctly.
2817  SwPageFrame* pPageFrame = FindPageFrame();
2818  pPageFrame->InvalidateSize();
2819  }
2820  }
2821 
2822  if( !(GetType() & nTmpType) && HasFixSize() )
2823  return 0;
2824 
2825  OSL_ENSURE( nDist >= 0, "nDist < 0" );
2826  SwRectFnSet aRectFnSet(this);
2827  SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
2828  if ( nDist > nFrameHeight )
2829  nDist = nFrameHeight;
2830 
2831  SwTwips nMin = 0;
2832  bool bChgPos = IsVertical();
2833  if ( Lower() )
2834  {
2835  if( !Lower()->IsNeighbourFrame() )
2836  { const SwFrame *pFrame = Lower();
2837  const tools::Long nTmp = aRectFnSet.GetHeight(getFramePrintArea());
2838  while( pFrame && nMin < nTmp )
2839  { nMin += aRectFnSet.GetHeight(pFrame->getFrameArea());
2840  pFrame = pFrame->GetNext();
2841  }
2842  }
2843  }
2844  SwTwips nReal = nDist;
2845  SwTwips nMinDiff = aRectFnSet.GetHeight(getFramePrintArea()) - nMin;
2846  if( nReal > nMinDiff )
2847  nReal = nMinDiff;
2848  if( nReal <= 0 )
2849  return nDist;
2850 
2851  SwRect aOldFrame( getFrameArea() );
2852  bool bMoveAccFrame = false;
2853 
2854  SwTwips nRealDist = nReal;
2855  if ( !bTst )
2856  {
2858  aRectFnSet.SetHeight( aFrm, nFrameHeight - nReal );
2859 
2860  if( bChgPos && !IsVertLR() )
2861  {
2862  aFrm.Pos().AdjustX(nReal );
2863  }
2864 
2865  bMoveAccFrame = true;
2866  }
2867 
2869  static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment()
2871 
2872  // AdjustNeighbourhood also in columns (but not in frames)
2873  if( SwNeighbourAdjust::OnlyAdjust == nAdjust )
2874  {
2875  if ( IsPageBodyFrame() && !bBrowse )
2876  nReal = nDist;
2877  else
2878  { nReal = AdjustNeighbourhood( -nReal, bTst );
2879  nReal *= -1;
2880  if ( !bTst && IsBodyFrame() && nReal < nRealDist )
2881  {
2883  aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) + nRealDist - nReal );
2884 
2885  if( bChgPos && !IsVertLR() )
2886  {
2887  aFrm.Pos().AdjustX(nRealDist - nReal );
2888  }
2889 
2890  OSL_ENSURE( !IsAccessibleFrame(), "bMoveAccFrame has to be set!" );
2891  }
2892  }
2893  }
2894  else if( IsColumnFrame() || IsColBodyFrame() )
2895  {
2896  SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo );
2897  if ( nTmp != nReal )
2898  {
2900  aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) + nReal - nTmp );
2901 
2902  if( bChgPos && !IsVertLR() )
2903  {
2904  aFrm.Pos().AdjustX(nTmp - nReal );
2905  }
2906 
2907  OSL_ENSURE( !IsAccessibleFrame(), "bMoveAccFrame has to be set!" );
2908  nReal = nTmp;
2909  }
2910  }
2911  else
2912  {
2913  SwTwips nShrink = nReal;
2914  SwFrame* pToShrink = GetUpper();
2915  // NEW TABLES
2916  if ( IsCellFrame() )
2917  {
2918  const SwCellFrame* pThisCell = static_cast<const SwCellFrame*>(this);
2919  if ( pThisCell->GetLayoutRowSpan() > 1 )
2920  {
2921  SwCellFrame& rEndCell = const_cast<SwCellFrame&>(pThisCell->FindStartEndOfRowSpanCell( false ));
2922  pToShrink = rEndCell.GetUpper();
2923  }
2924  }
2925 
2926  nReal = pToShrink ? pToShrink->Shrink( nShrink, bTst, bInfo ) : 0;
2927  if( ( SwNeighbourAdjust::GrowAdjust == nAdjust || SwNeighbourAdjust::AdjustGrow == nAdjust )
2928  && nReal < nShrink )
2929  AdjustNeighbourhood( nReal - nShrink );
2930  }
2931 
2932  if( bMoveAccFrame && IsAccessibleFrame() )
2933  {
2934  SwRootFrame *pRootFrame = getRootFrame();
2935  if( pRootFrame && pRootFrame->IsAnyShellAccessible() &&
2936  pRootFrame->GetCurrShell() )
2937  {
2938  pRootFrame->GetCurrShell()->Imp()->MoveAccessibleFrame( this, aOldFrame );
2939  }
2940  }
2941  if ( !bTst && (IsCellFrame() || IsColumnFrame() ? nReal : nRealDist) )
2942  {
2943  SwPageFrame *pPage = FindPageFrame();
2944  if ( GetNext() )
2945  {
2946  GetNext()->InvalidatePos_();
2947  if ( GetNext()->IsContentFrame() )
2948  GetNext()->InvalidatePage( pPage );
2949  if ( IsTabFrame() )
2950  static_cast<SwTabFrame*>(this)->SetComplete();
2951  }
2952  else
2953  { if ( IsRetoucheFrame() )
2954  SetRetouche();
2955  if ( IsTabFrame() )
2956  {
2957  static_cast<SwTabFrame*>(this)->SetComplete();
2958  if ( Lower() ) // Can also be in the Join and be empty!
2960  }
2961  }
2962  if ( !IsBodyFrame() )
2963  {
2964  InvalidateAll_();
2965  InvalidatePage( pPage );
2966  bool bCompletePaint = true;
2967  const SwFrameFormat* pFormat = GetFormat();
2968  if (pFormat)
2969  {
2970  std::unique_ptr<SvxBrushItem> aBack(pFormat->makeBackgroundBrushItem());
2971  const SvxGraphicPosition ePos = aBack ? aBack->GetGraphicPos() : GPOS_NONE;
2972  if ( GPOS_NONE == ePos || GPOS_TILED == ePos )
2973  bCompletePaint = false;
2974  }
2975  if (bCompletePaint)
2976  SetCompletePaint();
2977  }
2978 
2980  NotifyLowerObjs();
2981 
2982  if( IsCellFrame() )
2983  InvaPercentLowers( nReal );
2984 
2985  SwContentFrame *pCnt;
2986  if( IsFootnoteFrame() && !static_cast<SwFootnoteFrame*>(this)->GetAttr()->GetFootnote().IsEndNote() &&
2987  ( GetFormat()->GetDoc()->GetFootnoteInfo().m_ePos != FTNPOS_CHAPTER ||
2988  ( IsInSct() && FindSctFrame()->IsFootnoteAtEnd() ) ) &&
2989  nullptr != (pCnt = static_cast<SwFootnoteFrame*>(this)->GetRefFromAttr() ) )
2990  {
2991  if ( pCnt->IsFollow() )
2992  { // If we are in another column/page than the frame with the
2993  // reference, we don't need to invalidate its master.
2994  SwFrame *pTmp = pCnt->FindFootnoteBossFrame(true) == FindFootnoteBossFrame(true)
2995  ? &pCnt->FindMaster()->GetFrame() : pCnt;
2997  pTmp->InvalidateSize();
2998  }
2999  else
3000  pCnt->InvalidatePos();
3001  }
3002  }
3003  return nReal;
3004 }
3005 
3012 void SwLayoutFrame::ChgLowersProp( const Size& rOldSize )
3013 {
3014  // no change of lower properties for root frame or if no lower exists.
3015  if ( IsRootFrame() || !Lower() )
3016  return;
3017 
3018  // declare and init <SwFrame* pLowerFrame> with first lower
3019  SwFrame *pLowerFrame = Lower();
3020 
3021  // declare and init const booleans <bHeightChgd> and <bWidthChg>
3022  const bool bHeightChgd = rOldSize.Height() != getFramePrintArea().Height();
3023  const bool bWidthChgd = rOldSize.Width() != getFramePrintArea().Width();
3024 
3025  SwRectFnSet aRectFnSet(this);
3026 
3027  // This shortcut basically tries to handle only lower frames that
3028  // are affected by the size change. Otherwise much more lower frames
3029  // are invalidated.
3030  if ( !( aRectFnSet.IsVert() ? bHeightChgd : bWidthChgd ) &&
3031  ! Lower()->IsColumnFrame() &&
3032  ( ( IsBodyFrame() && IsInDocBody() && ( !IsInSct() || !FindSctFrame()->IsColLocked() ) ) ||
3033  // #i10826# Section frames without columns should not
3034  // invalidate all lowers!
3035  IsSctFrame() ) )
3036  {
3037  // Determine page frame the body frame resp. the section frame belongs to.
3038  SwPageFrame *pPage = FindPageFrame();
3039  // Determine last lower by traveling through them using <GetNext()>.
3040  // During travel check each section frame, if it will be sized to
3041  // maximum. If Yes, invalidate size of section frame and set
3042  // corresponding flags at the page.
3043  do
3044  {
3045  if( pLowerFrame->IsSctFrame() && static_cast<SwSectionFrame*>(pLowerFrame)->ToMaximize_() )
3046  {
3047  pLowerFrame->InvalidateSize_();
3048  pLowerFrame->InvalidatePage( pPage );
3049  }
3050  if( pLowerFrame->GetNext() )
3051  pLowerFrame = pLowerFrame->GetNext();
3052  else
3053  break;
3054  } while( true );
3055  // If found last lower is a section frame containing no section
3056  // (section frame isn't valid and will be deleted in the future),
3057  // travel backwards.
3058  while( pLowerFrame->IsSctFrame() && !static_cast<SwSectionFrame*>(pLowerFrame)->GetSection() &&
3059  pLowerFrame->GetPrev() )
3060  pLowerFrame = pLowerFrame->GetPrev();
3061  // If found last lower is a section frame, set <pLowerFrame> to its last
3062  // content, if the section frame is valid and is not sized to maximum.
3063  // Otherwise set <pLowerFrame> to NULL - In this case body frame only
3064  // contains invalid section frames.
3065  if( pLowerFrame->IsSctFrame() )
3066  pLowerFrame = static_cast<SwSectionFrame*>(pLowerFrame)->GetSection() &&
3067  !static_cast<SwSectionFrame*>(pLowerFrame)->ToMaximize( false ) ?
3068  static_cast<SwSectionFrame*>(pLowerFrame)->FindLastContent() : nullptr;
3069 
3070  // continue with found last lower, probably the last content of a section
3071  if ( pLowerFrame )
3072  {
3073  // If <pLowerFrame> is in a table frame, set <pLowerFrame> to this table
3074  // frame and continue.
3075  if ( pLowerFrame->IsInTab() )
3076  {
3077  // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrame> to
3078  // its table frame - check, if the table frame is also a lower
3079  // of the body frame, in order to assure that <pLowerFrame> is not
3080  // set to a frame, which is an *upper* of the body frame.
3081  SwFrame* pTableFrame = pLowerFrame->FindTabFrame();
3082  if ( IsAnLower( pTableFrame ) )
3083  {
3084  pLowerFrame = pTableFrame;
3085  }
3086  }
3087  // Check, if variable size of body frame resp. section frame has grown
3088  // OD 28.10.2002 #97265# - correct check, if variable size has grown.
3089  SwTwips nOldHeight = aRectFnSet.IsVert() ? rOldSize.Width() : rOldSize.Height();
3090  if( nOldHeight < aRectFnSet.GetHeight(getFramePrintArea()) )
3091  {
3092  // If variable size of body|section frame has grown, only found
3093  // last lower and the position of the its next have to be invalidated.
3094  pLowerFrame->InvalidateAll_();
3095  pLowerFrame->InvalidatePage( pPage );
3096  if( !pLowerFrame->IsFlowFrame() ||
3097  !SwFlowFrame::CastFlowFrame( pLowerFrame )->HasFollow() )
3098  pLowerFrame->InvalidateNextPos( true );
3099  if ( pLowerFrame->IsTextFrame() )
3100  static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::AdjustSizeWithoutFormatting );
3101  }
3102  else
3103  {
3104  // variable size of body|section frame has shrunk. Thus,
3105  // invalidate all lowers not matching the new body|section size
3106  // and the dedicated new last lower.
3107  if( aRectFnSet.IsVert() )
3108  {
3109  SwTwips nBot = getFrameArea().Left() + getFramePrintArea().Left();
3110  while ( pLowerFrame && pLowerFrame->GetPrev() && pLowerFrame->getFrameArea().Left() < nBot )
3111  {
3112  pLowerFrame->InvalidateAll_();
3113  pLowerFrame->InvalidatePage( pPage );
3114  pLowerFrame = pLowerFrame->GetPrev();
3115  }
3116  }
3117  else
3118  {
3119  SwTwips nBot = getFrameArea().Top() + getFramePrintArea().Bottom();
3120  while ( pLowerFrame && pLowerFrame->GetPrev() && pLowerFrame->getFrameArea().Top() > nBot )
3121  {
3122  pLowerFrame->InvalidateAll_();
3123  pLowerFrame->InvalidatePage( pPage );
3124  pLowerFrame = pLowerFrame->GetPrev();
3125  }
3126  }
3127  if ( pLowerFrame )
3128  {
3129  pLowerFrame->InvalidateSize_();
3130  pLowerFrame->InvalidatePage( pPage );
3131  if ( pLowerFrame->IsTextFrame() )
3132  static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::AdjustSizeWithoutFormatting );
3133  }
3134  }
3135  // #i41694# - improvement by removing duplicates
3136  if ( pLowerFrame )
3137  {
3138  if ( pLowerFrame->IsInSct() )
3139  {
3140  // #i41694# - follow-up of issue #i10826#
3141  // No invalidation of section frame, if it's the this.
3142  SwFrame* pSectFrame = pLowerFrame->FindSctFrame();
3143  if( pSectFrame != this && IsAnLower( pSectFrame ) )
3144  {
3145  pSectFrame->InvalidateSize_();
3146  pSectFrame->InvalidatePage( pPage );
3147  }
3148  }
3149  }
3150  }
3151  return;
3152  } // end of { special case }
3153 
3154  // Invalidate page for content only once.
3155  bool bInvaPageForContent = true;
3156 
3157  // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame
3158  // adjustment, if fixed/variable size has changed.
3159  bool bFixChgd, bVarChgd;
3160  if( aRectFnSet.IsVert() == pLowerFrame->IsNeighbourFrame() )
3161  {
3162  bFixChgd = bWidthChgd;
3163  bVarChgd = bHeightChgd;
3164  }
3165  else
3166  {
3167  bFixChgd = bHeightChgd;
3168  bVarChgd = bWidthChgd;
3169  }
3170 
3171  // Declare const unsigned short <nFixWidth> and init it this frame types
3172  // which has fixed width in vertical respectively horizontal layout.
3173  // In vertical layout these are neighbour frames (cell and column frames),
3174  // header frames and footer frames.
3175  // In horizontal layout these are all frames, which aren't neighbour frames.
3176  const SwFrameType nFixWidth = aRectFnSet.IsVert() ? (FRM_NEIGHBOUR | FRM_HEADFOOT)
3178 
3179  // Declare const unsigned short <nFixHeight> and init it this frame types
3180  // which has fixed height in vertical respectively horizontal layout.
3181  // In vertical layout these are all frames, which aren't neighbour frames,
3182  // header frames, footer frames, body frames or foot note container frames.
3183  // In horizontal layout these are neighbour frames.
3184  const SwFrameType nFixHeight = aRectFnSet.IsVert() ? ~SwFrameType(FRM_NEIGHBOUR | FRM_HEADFOOT | FRM_BODYFTNC)
3185  : FRM_NEIGHBOUR;
3186 
3187  // Travel through all lowers using <GetNext()>
3188  while ( pLowerFrame )
3189  {
3190  if ( pLowerFrame->IsTextFrame() )
3191  {
3192  // Text frames will only be invalidated - prepare invalidation
3193  if ( bFixChgd )
3194  static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::FixSizeChanged );
3195  if ( bVarChgd )
3196  static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::AdjustSizeWithoutFormatting );
3197  }
3198  else
3199  {
3200  // If lower isn't a table, row, cell or section frame, adjust its
3201  // frame size.
3202  const SwFrameType nLowerType = pLowerFrame->GetType();
3204  {
3205  if ( bWidthChgd )
3206  {
3207  if( nLowerType & nFixWidth )
3208  {
3209  // Considering previous conditions:
3210  // In vertical layout set width of column, header and
3211  // footer frames to its upper width.
3212  // In horizontal layout set width of header, footer,
3213  // foot note container, foot note, body and no-text
3214  // frames to its upper width.
3216  aFrm.Width( getFramePrintArea().Width() );
3217  }
3218  else if( rOldSize.Width() && !pLowerFrame->IsFootnoteFrame() )
3219  {
3220  // Adjust frame width proportional, if lower isn't a
3221  // foot note frame and condition <nLowerType & nFixWidth>
3222  // isn't true.
3223  // Considering previous conditions:
3224  // In vertical layout these are foot note container,
3225  // body and no-text frames.
3226  // In horizontal layout these are column and no-text frames.
3227  // OD 24.10.2002 #97265# - <double> calculation
3228  // Perform <double> calculation of new width, if
3229  // one of the coefficients is greater than 50000
3230  SwTwips nNewWidth;
3231  if ( (pLowerFrame->getFrameArea().Width() > 50000) ||
3232  (getFramePrintArea().Width() > 50000) )
3233  {
3234  double nNewWidthTmp =
3235  ( double(pLowerFrame->getFrameArea().Width())
3236  * double(getFramePrintArea().Width()) )
3237  / double(rOldSize.Width());
3238  nNewWidth = SwTwips(nNewWidthTmp);
3239  }
3240  else
3241  {
3242  nNewWidth =
3243  (pLowerFrame->getFrameArea().Width() * getFramePrintArea().Width()) / rOldSize.Width();
3244  }
3245 
3247  aFrm.Width( nNewWidth );
3248  }
3249  }
3250  if ( bHeightChgd )
3251  {
3252  if( nLowerType & nFixHeight )
3253  {
3254  // Considering previous conditions:
3255  // In vertical layout set height of foot note and
3256  // no-text frames to its upper height.
3257  // In horizontal layout set height of column frames
3258  // to its upper height.
3260  aFrm.Height( getFramePrintArea().Height() );
3261  }
3262  // OD 01.10.2002 #102211#
3263  // add conditions <!pLowerFrame->IsHeaderFrame()> and
3264  // <!pLowerFrame->IsFooterFrame()> in order to avoid that
3265  // the <Grow> of header or footer are overwritten.
3266  // NOTE: Height of header/footer frame is determined by contents.
3267  else if ( rOldSize.Height() &&
3268  !pLowerFrame->IsFootnoteFrame() &&
3269  !pLowerFrame->IsHeaderFrame() &&
3270  !pLowerFrame->IsFooterFrame()
3271  )
3272  {
3273  // Adjust frame height proportional, if lower isn't a
3274  // foot note, a header or a footer frame and
3275  // condition <nLowerType & nFixHeight> isn't true.
3276  // Considering previous conditions:
3277  // In vertical layout these are column, foot note container,
3278  // body and no-text frames.
3279  // In horizontal layout these are column, foot note
3280  // container, body and no-text frames.
3281 
3282  // OD 29.10.2002 #97265# - special case for page lowers
3283  // The page lowers that have to be adjusted on page height
3284  // change are the body frame and the foot note container
3285  // frame.
3286  // In vertical layout the height of both is directly
3287  // adjusted to the page height change.
3288  // In horizontal layout the height of the body frame is
3289  // directly adjusted to the page height change and the
3290  // foot note frame height isn't touched, because its
3291  // determined by its content.
3292  // OD 31.03.2003 #108446# - apply special case for page
3293  // lowers - see description above - also for section columns.
3294  if ( IsPageFrame() ||
3295  ( IsColumnFrame() && IsInSct() )
3296  )
3297  {
3298  OSL_ENSURE( pLowerFrame->IsBodyFrame() || pLowerFrame->IsFootnoteContFrame(),
3299  "ChgLowersProp - only for body or foot note container" );
3300  if ( pLowerFrame->IsBodyFrame() || pLowerFrame->IsFootnoteContFrame() )
3301  {
3302  if ( IsVertical() || pLowerFrame->IsBodyFrame() )
3303  {
3304  SwTwips nNewHeight =
3305  pLowerFrame->getFrameArea().Height() +
3306  ( getFramePrintArea().Height() - rOldSize.Height() );
3307  if ( nNewHeight < 0)
3308  {
3309  // OD 01.04.2003 #108446# - adjust assertion condition and text
3310  OSL_ENSURE( !( IsPageFrame() &&
3311  (pLowerFrame->getFrameArea().Height()>0) &&
3312  (pLowerFrame->isFrameAreaDefinitionValid()) ),
3313  "ChgLowersProg - negative height for lower.");
3314  nNewHeight = 0;
3315  }
3316 
3318  aFrm.Height( nNewHeight );
3319  }
3320  }
3321  }
3322  else
3323  {
3324  SwTwips nNewHeight;
3325  // OD 24.10.2002 #97265# - <double> calculation
3326  // Perform <double> calculation of new height, if
3327  // one of the coefficients is greater than 50000
3328  if ( (pLowerFrame->getFrameArea().Height() > 50000) ||
3329  (getFramePrintArea().Height() > 50000) )
3330  {
3331  double nNewHeightTmp =
3332  ( double(pLowerFrame->getFrameArea().Height())
3333  * double(getFramePrintArea().Height()) )
3334  / double(rOldSize.Height());
3335  nNewHeight = SwTwips(nNewHeightTmp);
3336  }
3337  else
3338  {
3339  nNewHeight = ( pLowerFrame->getFrameArea().Height()
3340  * getFramePrintArea().Height() ) / rOldSize.Height();
3341  }
3342  if( !pLowerFrame->GetNext() )
3343  {
3344  SwTwips nSum = getFramePrintArea().Height();
3345  SwFrame* pTmp = Lower();
3346  while( pTmp->GetNext() )
3347  {
3348  if( !pTmp->IsFootnoteContFrame() || !pTmp->IsVertical() )
3349  nSum -= pTmp->getFrameArea().Height();
3350  pTmp = pTmp->GetNext();
3351  }
3352  if( nSum - nNewHeight == 1 &&
3353  nSum == pLowerFrame->getFrameArea().Height() )
3354  nNewHeight = nSum;
3355  }
3356 
3358  aFrm.Height( nNewHeight );
3359  }
3360  }
3361  }
3362  }
3363  } // end of else { NOT text frame }
3364 
3365  pLowerFrame->InvalidateAll_();
3366  if ( bInvaPageForContent && pLowerFrame->IsContentFrame() )
3367  {
3368  pLowerFrame->InvalidatePage();
3369  bInvaPageForContent = false;
3370  }
3371 
3372  if ( !pLowerFrame->GetNext() && pLowerFrame->IsRetoucheFrame() )
3373  {
3374  //If a growth took place and the subordinate elements can retouch
3375  //itself (currently Tabs, Sections and Content) we trigger it.
3376  if ( rOldSize.Height() < getFramePrintArea().SSize().Height() ||
3377  rOldSize.Width() < getFramePrintArea().SSize().Width() )
3378  pLowerFrame->SetRetouche();
3379  }
3380  pLowerFrame = pLowerFrame->GetNext();
3381  }
3382 
3383  // Finally adjust the columns if width is set to auto
3384  // Possible optimization: execute this code earlier in this function and
3385  // return???
3386  if ( !(( (aRectFnSet.IsVert() && bHeightChgd) || (! aRectFnSet.IsVert() && bWidthChgd) ) &&
3387  Lower()->IsColumnFrame()) )
3388  return;
3389 
3390  // get column attribute
3391  const SwFormatCol* pColAttr = nullptr;
3392  if ( IsPageBodyFrame() )
3393  {
3394  OSL_ENSURE( GetUpper()->IsPageFrame(), "Upper is not page frame" );
3395  pColAttr = &GetUpper()->GetFormat()->GetCol();
3396  }
3397  else
3398  {
3399  OSL_ENSURE( IsFlyFrame() || IsSctFrame(), "Columns not in fly or section" );
3400  pColAttr = &GetFormat()->GetCol();
3401  }
3402 
3403  if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 )
3404  AdjustColumns( pColAttr, false );
3405 }
3406 
3411 void SwLayoutFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorderAttrs *pAttrs )
3412 {
3413  OSL_ENSURE( pAttrs, "LayoutFrame::Format, pAttrs is 0." );
3414 
3416  return;
3417 
3418  bool bHideWhitespace = false;
3419  if (IsPageFrame())
3420  {
3421  SwViewShell* pShell = getRootFrame()->GetCurrShell();
3422  if (pShell && pShell->GetViewOptions()->IsWhitespaceHidden())
3423  {
3424  // This is needed so that no space is reserved for the margin on
3425  // the last page of the document. Other pages would have no margin
3426  // set even without this, as their frame height is the content
3427  // height already.
3428  bHideWhitespace = true;
3429  }
3430  }
3431 
3432  const sal_uInt16 nLeft = o3tl::narrowing<sal_uInt16>(pAttrs->CalcLeft(this));
3433  const sal_uInt16 nUpper = bHideWhitespace ? 0 : pAttrs->CalcTop();
3434 
3435  const sal_uInt16 nRight = o3tl::narrowing<sal_uInt16>(pAttrs->CalcRight(this));
3436  const sal_uInt16 nLower = bHideWhitespace ? 0 : pAttrs->CalcBottom();
3437 
3438  const bool bVert = IsVertical() && !IsPageFrame();
3439  SwRectFn fnRect = bVert ? ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
3440  if ( !isFramePrintAreaValid() )
3441  {
3442  setFramePrintAreaValid(true);
3443  (this->*fnRect->fnSetXMargins)( nLeft, nRight );
3444  (this->*fnRect->fnSetYMargins)( nUpper, nLower );
3445  }
3446 
3447  if ( isFrameAreaSizeValid() )
3448  return;
3449 
3450  if ( !HasFixSize() )
3451  {
3452  const SwTwips nBorder = nUpper + nLower;
3453  const SwFormatFrameSize &rSz = GetFormat()->GetFrameSize();
3454  SwTwips nMinHeight = rSz.GetHeightSizeType() == SwFrameSize::Minimum ? rSz.GetHeight() : 0;
3455  do
3456  {
3457  setFrameAreaSizeValid(true);
3458 
3459  //The size in VarSize is calculated using the content plus the
3460  // borders.
3461  SwTwips nRemaining = 0;
3462  SwFrame *pFrame = Lower();
3463  while ( pFrame )
3464  { nRemaining += (pFrame->getFrameArea().*fnRect->fnGetHeight)();
3465  if( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsUndersized() )
3466  // This TextFrame would like to be a bit bigger
3467  nRemaining += static_cast<SwTextFrame*>(pFrame)->GetParHeight()
3468  - (pFrame->getFramePrintArea().*fnRect->fnGetHeight)();
3469  else if( pFrame->IsSctFrame() && static_cast<SwSectionFrame*>(pFrame)->IsUndersized() )
3470  nRemaining += static_cast<SwSectionFrame*>(pFrame)->Undersize();
3471  pFrame = pFrame->GetNext();
3472  }
3473  nRemaining += nBorder;
3474  nRemaining = std::max( nRemaining, nMinHeight );
3475  const SwTwips nDiff = nRemaining-(getFrameArea().*fnRect->fnGetHeight)();
3476  const tools::Long nOldLeft = (getFrameArea().*fnRect->fnGetLeft)();
3477  const tools::Long nOldTop = (getFrameArea().*fnRect->fnGetTop)();
3478  if ( nDiff )
3479  {
3480  if ( nDiff > 0 )
3481  Grow( nDiff );
3482  else
3483  Shrink( -nDiff );
3484  //Updates the positions using the fast channel.
3485  MakePos();
3486  }
3487  //Don't exceed the bottom edge of the Upper.
3488  if ( GetUpper() && (getFrameArea().*fnRect->fnGetHeight)() )
3489  {
3490  const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
3491  if( (this->*fnRect->fnSetLimit)( nLimit ) &&
3492  nOldLeft == (getFrameArea().*fnRect->fnGetLeft)() &&
3493  nOldTop == (getFrameArea().*fnRect->fnGetTop)() )
3494  {
3495  setFrameAreaSizeValid(true);
3496  setFramePrintAreaValid(true);
3497  }
3498  }
3499  } while ( !isFrameAreaSizeValid() );
3500  }
3501  else if (GetType() & FRM_HEADFOOT)
3502  {
3503  do
3504  { if ( getFrameArea().Height() != pAttrs->GetSize().Height() )
3505  {
3506  ChgSize( Size( getFrameArea().Width(), pAttrs->GetSize().Height()));
3507  }
3508 
3509  setFrameAreaSizeValid(true);
3510  MakePos();
3511  } while ( !isFrameAreaSizeValid() );
3512  }
3513  else
3514  {
3515  setFrameAreaSizeValid(true);
3516  }
3517 
3518  // While updating the size, PrtArea might be invalidated.
3519  if (!isFramePrintAreaValid())
3520  {
3521  setFramePrintAreaValid(true);
3522  (this->*fnRect->fnSetXMargins)(nLeft, nRight);
3523  (this->*fnRect->fnSetYMargins)(nUpper, nLower);
3524  }
3525 }
3526 
3527 static void InvaPercentFlys( SwFrame *pFrame, SwTwips nDiff )
3528 {
3529  OSL_ENSURE( pFrame->GetDrawObjs(), "Can't find any Objects" );
3530  for (SwAnchoredObject* pAnchoredObj : *pFrame->GetDrawObjs())
3531  {
3532  if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
3533  {
3534  const SwFormatFrameSize &rSz = pFly->GetFormat()->GetFrameSize();
3535  if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3536  {
3537  bool bNotify = true;
3538  // If we've a fly with more than 90% relative height...
3539  if( rSz.GetHeightPercent() > 90 && pFly->GetAnchorFrame() &&
3540  rSz.GetHeightPercent() != SwFormatFrameSize::SYNCED && nDiff )
3541  {
3542  const SwFrame *pRel = pFly->IsFlyLayFrame() ? pFly->GetAnchorFrame():
3543  pFly->GetAnchorFrame()->GetUpper();
3544  // ... and we have already more than 90% height and we
3545  // not allow the text to go through...
3546  // then a notification could cause an endless loop, e.g.
3547  // 100% height and no text wrap inside a cell of a table.
3548  if( pFly->getFrameArea().Height()*10 >
3549  ( nDiff + pRel->getFramePrintArea().Height() )*9 &&
3550  pFly->GetFormat()->GetSurround().GetSurround() !=
3551  css::text::WrapTextMode_THROUGH )
3552  bNotify = false;
3553  }
3554  if( bNotify )
3555  pFly->InvalidateSize();
3556  }
3557  }
3558  }
3559 }
3560 
3562 {
3563  if ( GetDrawObjs() )
3564  ::InvaPercentFlys( this, nDiff );
3565 
3566  SwFrame *pFrame = ContainsContent();
3567  if ( !pFrame )
3568  return;
3569 
3570  do
3571  {
3572  if ( pFrame->IsInTab() && !IsTabFrame() )
3573  {
3574  SwFrame *pTmp = pFrame->FindTabFrame();
3575  OSL_ENSURE( pTmp, "Where's my TabFrame?" );
3576  if( IsAnLower( pTmp ) )
3577  pFrame = pTmp;
3578  }
3579 
3580  if ( pFrame->IsTabFrame() )
3581  {
3582  const SwFormatFrameSize &rSz = static_cast<SwLayoutFrame*>(pFrame)->GetFormat()->GetFrameSize();
3583  if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3584  pFrame->InvalidatePrt();
3585  }
3586  else if ( pFrame->GetDrawObjs() )
3587  ::InvaPercentFlys( pFrame, nDiff );
3588  pFrame = pFrame->FindNextCnt();
3589  } while ( pFrame && IsAnLower( pFrame ) ) ;
3590 }
3591 
3593 {
3594  tools::Long nRet = rSz.GetWidth(),
3595  nPercent = rSz.GetWidthPercent();
3596 
3597  if ( nPercent )
3598  {
3599  const SwFrame *pRel = GetUpper();
3600  tools::Long nRel = LONG_MAX;
3601  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
3602  const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
3603  if( pRel->IsPageBodyFrame() && pSh && bBrowseMode && pSh->VisArea().Width() )
3604  {
3605  nRel = pSh->GetBrowseWidth();
3606  tools::Long nDiff = nRel - pRel->getFramePrintArea().Width();
3607  if ( nDiff > 0 )
3608  nRel -= nDiff;
3609  }
3610  nRel = std::min( nRel, pRel->getFramePrintArea().Width() );
3611  nRet = nRel * nPercent / 100;
3612  }
3613  return nRet;
3614 }
3615 
3616 // Local helpers for SwLayoutFrame::FormatWidthCols()
3617 
3619 {
3620  tools::Long nDiff = 0, nFirstDiff = 0;
3621  SwLayoutFrame *pCol = static_cast<SwLayoutFrame*>(pLayFrame->Lower());
3622  OSL_ENSURE( pCol, "Where's the columnframe?" );
3623  SwFrame *pFrame = pCol->Lower();
3624  do
3625  {
3626  if( pFrame && pFrame->IsBodyFrame() )
3627  pFrame = static_cast<SwBodyFrame*>(pFrame)->Lower();
3628  if ( pFrame && pFrame->IsTextFrame() )
3629  {
3630  const tools::Long nTmp = static_cast<SwTextFrame*>(pFrame)->FirstLineHeight();
3631  if ( nTmp != USHRT_MAX )
3632  {
3633  if ( pCol == pLayFrame->Lower() )
3634  nFirstDiff = nTmp;
3635  else
3636  nDiff = nDiff ? std::min( nDiff, nTmp ) : nTmp;
3637  }
3638  }
3639  //Skip empty columns!
3640  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3641  while ( pCol && nullptr == (pFrame = pCol->Lower()) )
3642  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3643 
3644  } while ( pFrame && pCol );
3645 
3646  return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240;
3647 }
3648 
3650 {
3651  SwFrame *pFrame = pLay->ContainsContent();
3652  while ( pFrame )
3653  {
3654  if ( pFrame->IsInTab() )
3655  pFrame = pFrame->FindTabFrame();
3656 
3657  if ( pFrame->GetDrawObjs() )
3658  {
3659  const size_t nCnt = pFrame->GetDrawObjs()->size();
3660  for ( size_t i = 0; i < nCnt; ++i )
3661  {
3662  SwAnchoredObject* pAnchoredObj = (*pFrame->GetDrawObjs())[i];
3663  if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
3664  {
3665  if ( pFly->IsHeightClipped() &&
3666  ( !pFly->IsFlyFreeFrame() || pFly->GetPageFrame() ) )
3667  return true;
3668  }
3669  }
3670  }
3671  pFrame = pFrame->FindNextCnt();
3672  }
3673  return false;
3674 }
3675 
3677  const SwTwips nBorder, const SwTwips nMinHeight )
3678 {
3679  //If there are columns involved, the size is adjusted using the last column.
3680  //1. Format content.
3681  //2. Calculate height of the last column: if it's too big, the Fly has to
3682  // grow. The amount by which the Fly grows is not the amount of the
3683  // overhang because we have to act on the assumption that some text flows
3684  // back which will generate some more space.
3685  // The amount which we grow by equals the overhang
3686  // divided by the amount of columns or the overhang itself if it's smaller
3687  // than the amount of columns.
3688  //3. Go back to 1. until everything is stable.
3689 
3690  const SwFormatCol &rCol = rAttrs.GetAttrSet().GetCol();
3691  const sal_uInt16 nNumCols = rCol.GetNumCols();
3692 
3693  bool bEnd = false;
3694  bool bBackLock = false;
3696  SwViewShellImp *pImp = pSh ? pSh->Imp() : nullptr;
3697  vcl::RenderContext* pRenderContext = pSh ? pSh->GetOut() : nullptr;
3698  {
3699  // Underlying algorithm
3700  // We try to find the optimal height for the column.
3701  // nMinimum starts with the passed minimum height and is then remembered
3702  // as the maximum height on which column content still juts out of a
3703  // column.
3704  // nMaximum starts with LONG_MAX and is then remembered as the minimum
3705  // width on which the content fitted.
3706  // In column based sections nMaximum starts at the maximum value which
3707  // the surrounding defines, this can certainly be a value on which
3708  // content still juts out.
3709  // The columns are formatted. If content still juts out, nMinimum is
3710  // adjusted accordingly, then we grow, at least by uMinDiff but not
3711  // over a certain nMaximum. If no content juts out but there is still
3712  // some space left in the column, shrinking is done accordingly, at
3713  // least by nMindIff but not below the nMinimum.
3714  // Cancel as soon as no content juts out and the difference from minimum
3715  // to maximum is less than MinDiff or the maximum which was defined by
3716  // the surrounding is reached even if some content still juts out.
3717 
3718  // Criticism of this implementation
3719  // 1. Theoretically situations are possible in which the content fits in
3720  // a lower height but not in a higher height. To ensure that the code
3721  // handles such situations the code contains a few checks concerning
3722  // minimum and maximum which probably are never triggered.
3723  // 2. We use the same nMinDiff for shrinking and growing, but nMinDiff
3724  // is more or less the smallest first line height and doesn't seem ideal
3725  // as minimum value.
3726 
3727  tools::Long nMinimum = nMinHeight;
3728  tools::Long nMaximum;
3729  bool bNoBalance = false;
3730  SwRectFnSet aRectFnSet(this);
3731  if( IsSctFrame() )
3732  {
3733  nMaximum = aRectFnSet.GetHeight(getFrameArea()) - nBorder +
3734  aRectFnSet.BottomDist(getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper()));
3735  nMaximum += GetUpper()->Grow( LONG_MAX, true );
3736  if( nMaximum < nMinimum )
3737  {
3738  if( nMaximum < 0 )
3739  nMinimum = nMaximum = 0;
3740  else
3741  nMinimum = nMaximum;
3742  }
3743  if( nMaximum > BROWSE_HEIGHT )
3744  nMaximum = BROWSE_HEIGHT;
3745 
3746  bNoBalance = static_cast<SwSectionFrame*>(this)->GetSection()->GetFormat()->
3747  GetBalancedColumns().GetValue();
3748  SwFrame* pAny = ContainsAny();
3749  if( bNoBalance ||
3750  ( !aRectFnSet.GetHeight(getFrameArea()) && pAny ) )
3751  {
3752  tools::Long nTop = aRectFnSet.GetTopMargin(*this);
3753  // #i23129# - correction
3754  // to the calculated maximum height.
3755  {
3757  aRectFnSet.AddBottom( aFrm, nMaximum - aRectFnSet.GetHeight(getFrameArea()) );
3758  }
3759 
3760  if( nTop > nMaximum )
3761  nTop = nMaximum;
3762  aRectFnSet.SetYMargins( *this, nTop, 0 );
3763  }
3764  if( !pAny && !static_cast<SwSectionFrame*>(this)->IsFootnoteLock() )
3765  {
3766  SwFootnoteContFrame* pFootnoteCont = static_cast<SwSectionFrame*>(this)->ContainsFootnoteCont();
3767  if( pFootnoteCont )
3768  {
3769  SwFrame* pFootnoteAny = pFootnoteCont->ContainsAny();
3770  if( pFootnoteAny && pFootnoteAny->isFrameAreaDefinitionValid() )
3771  {
3772  bBackLock = true;
3773  static_cast<SwSectionFrame*>(this)->SetFootnoteLock( true );
3774  }
3775  }
3776  }
3777  }
3778  else
3779  nMaximum = LONG_MAX;
3780 
3781  // #i3317# - reset temporarily consideration
3782  // of wrapping style influence
3783  SwPageFrame* pPageFrame = FindPageFrame();
3784  SwSortedObjs* pObjs = pPageFrame ? pPageFrame->GetSortedObjs() : nullptr;
3785  if ( pObjs )
3786  {
3787  for (SwAnchoredObject* pAnchoredObj : *pObjs)
3788  {
3789  if ( IsAnLower( pAnchoredObj->GetAnchorFrame() ) )
3790  {
3791  pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3792  }
3793  }
3794  }
3795  do
3796  {
3797  //Could take a while therefore check for Waitcrsr here.
3798  if ( pImp )
3799  pImp->CheckWaitCursor();
3800 
3801  setFrameAreaSizeValid(true);
3802  //First format the column as this will relieve the stack a bit.
3803  //Also set width and height of the column (if they are wrong)
3804  //while we are at it.
3805  SwLayoutFrame *pCol = static_cast<SwLayoutFrame*>(Lower());
3806 
3807  // #i27399#
3808  // Simply setting the column width based on the values returned by
3809  // CalcColWidth does not work for automatic column width.
3810  AdjustColumns( &rCol, false );
3811 
3812  for ( sal_uInt16 i = 0; i < nNumCols; ++i )
3813  {
3814  pCol->Calc(pRenderContext);
3815  // ColumnFrames have a BodyFrame now, which needs to be calculated
3816  pCol->Lower()->Calc(pRenderContext);
3817  if( pCol->Lower()->GetNext() )
3818  pCol->Lower()->GetNext()->Calc(pRenderContext); // SwFootnoteCont
3819  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3820  }
3821 
3822  ::CalcContent( this );
3823 
3824  pCol = static_cast<SwLayoutFrame*>(Lower());
3825  OSL_ENSURE( pCol && pCol->GetNext(), ":-( column making holidays?");
3826  // set bMinDiff if no empty columns exist
3827  bool bMinDiff = true;
3828  // OD 28.03.2003 #108446# - check for all column content and all columns
3829  while ( bMinDiff && pCol )
3830  {
3831  bMinDiff = nullptr != pCol->ContainsContent();
3832  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3833  }
3834  pCol = static_cast<SwLayoutFrame*>(Lower());
3835  // OD 28.03.2003 #108446# - initialize local variable
3836  SwTwips nDiff = 0;
3837  SwTwips nMaxFree = 0;
3838  SwTwips nAllFree = LONG_MAX;
3839  // set bFoundLower if there is at least one non-empty column
3840  bool bFoundLower = false;
3841  while( pCol )
3842  {
3843  SwLayoutFrame* pLay = static_cast<SwLayoutFrame*>(pCol->Lower());
3844  SwTwips nInnerHeight = aRectFnSet.GetHeight(pLay->getFrameArea()) -
3845  aRectFnSet.GetHeight(pLay->getFramePrintArea());
3846  if( pLay->Lower() )
3847  {
3848  bFoundLower = true;
3849  nInnerHeight += pLay->InnerHeight();
3850  }
3851  else if( nInnerHeight < 0 )
3852  nInnerHeight = 0;
3853 
3854  if( pLay->GetNext() )
3855  {
3856  bFoundLower = true;
3857  pLay = static_cast<SwLayoutFrame*>(pLay->GetNext());
3858  OSL_ENSURE( pLay->IsFootnoteContFrame(),"FootnoteContainer expected" );
3859  nInnerHeight += pLay->InnerHeight();
3860  nInnerHeight += aRectFnSet.GetHeight(pLay->getFrameArea()) -
3861  aRectFnSet.GetHeight(pLay->getFramePrintArea());
3862  }
3863  nInnerHeight -= aRectFnSet.GetHeight(pCol->getFramePrintArea());
3864  if( nInnerHeight > nDiff )
3865  {
3866  nDiff = nInnerHeight;
3867  nAllFree = 0;
3868  }
3869  else
3870  {
3871  if( nMaxFree < -nInnerHeight )
3872  nMaxFree = -nInnerHeight;
3873  if( nAllFree > -nInnerHeight )
3874  nAllFree = -nInnerHeight;
3875  }
3876  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3877  }
3878 
3879  if ( bFoundLower || ( IsSctFrame() && static_cast<SwSectionFrame*>(this)->HasFollow() ) )
3880  {
3881  SwTwips nMinDiff = ::lcl_CalcMinColDiff( this );
3882  // Here we decide if growing is needed - this is the case, if
3883  // column content (nDiff) or a Fly juts over.
3884  // In sections with columns we take into account to set the size
3885  // when having a non-empty Follow.
3886  if ( nDiff || ::lcl_IsFlyHeightClipped( this ) ||
3887  ( IsSctFrame() && static_cast<SwSectionFrame*>(this)->CalcMinDiff( nMinDiff ) ) )
3888  {
3889  tools::Long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
3890  // The minimum must not be smaller than our PrtHeight as
3891  // long as something juts over.
3892  if( nMinimum < nPrtHeight )
3893  nMinimum = nPrtHeight;
3894  // The maximum must not be smaller than PrtHeight if
3895  // something still juts over.
3896  if( nMaximum < nPrtHeight )
3897  nMaximum = nPrtHeight; // Robust, but will this ever happen?
3898  if( !nDiff ) // If only Flys jut over, we grow by nMinDiff
3899  nDiff = nMinDiff;
3900  // If we should grow more than by nMinDiff we split it over
3901  // the columns
3902  if ( std::abs(nDiff - nMinDiff) > nNumCols && nDiff > static_cast<tools::Long>(nNumCols) )
3903  nDiff /= nNumCols;
3904 
3905  if ( bMinDiff )
3906  { // If no empty column exists, we want to grow at least
3907  // by nMinDiff. Special case: If we are smaller than the
3908  // minimal FrameHeight and PrtHeight is smaller than
3909  // nMindiff we grow in a way that PrtHeight is exactly
3910  // nMinDiff afterwards.
3911  tools::Long nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
3912  if ( nFrameHeight > nMinHeight || nPrtHeight >= nMinDiff )
3913  nDiff = std::max( nDiff, nMinDiff );
3914  else if( nDiff < nMinDiff )
3915  nDiff = nMinDiff - nPrtHeight + 1;
3916  }
3917  // nMaximum has a size which fits the content or the
3918  // requested value from the surrounding therefore we don't
3919  // need to exceed this value.
3920  if( nDiff + nPrtHeight > nMaximum )
3921  nDiff = nMaximum - nPrtHeight;
3922  }
3923  else if( nMaximum > nMinimum ) // We fit, do we still have some margin?
3924  {
3925  tools::Long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
3926  if ( nMaximum < nPrtHeight )
3927  nDiff = nMaximum - nPrtHeight; // We grew over a working
3928  // height and shrink back to it, but will this ever
3929  // happen?
3930  else
3931  { // We have a new maximum, a size which fits for the content.
3932  nMaximum = nPrtHeight;
3933  // If the margin in the column is bigger than nMinDiff
3934  // and we therefore drop under the minimum, we deflate
3935  // a bit.
3936  if ( !bNoBalance &&
3937  // #i23129# - <nMinDiff> can be
3938  // big, because of an object at the beginning of
3939  // a column. Thus, decrease optimization here.
3940  //nMaxFree >= nMinDiff &&
3941  nMaxFree > 0 &&
3942  ( !nAllFree ||
3943  nMinimum < nPrtHeight - nMinDiff ) )
3944  {
3945  nMaxFree /= nNumCols; // disperse over the columns
3946  nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // min nMinDiff
3947  if( nPrtHeight + nDiff <= nMinimum ) // below the minimum?
3948  nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3949  }
3950  else if( nAllFree )
3951  {
3952  nDiff = -nAllFree;
3953  if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum?
3954  nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3955  }
3956  }
3957  }
3958  if( nDiff ) // now we shrink or grow...
3959  {
3960  Size aOldSz( getFramePrintArea().SSize() );
3961  tools::Long nTop = aRectFnSet.GetTopMargin(*this);
3962  nDiff = aRectFnSet.GetHeight(getFramePrintArea()) + nDiff + nBorder - aRectFnSet.GetHeight(getFrameArea());
3963 
3964  {
3966  aRectFnSet.AddBottom( aFrm, nDiff );
3967  }
3968 
3969  // #i68520#
3970  SwFlyFrame *pFlyFrame = IsFlyFrame() ? static_cast<SwFlyFrame*>(this) : nullptr;
3971  if (pFlyFrame)
3972  {
3973  pFlyFrame->InvalidateObjRectWithSpaces();
3974  }
3975  aRectFnSet.SetYMargins( *this, nTop, nBorder - nTop );
3976  ChgLowersProp( aOldSz );
3977  NotifyLowerObjs();
3978 
3979  // #i3317# - reset temporarily consideration
3980  // of wrapping style influence
3981  SwPageFrame* pTmpPageFrame = FindPageFrame();
3982  SwSortedObjs* pTmpObjs = pTmpPageFrame ? pTmpPageFrame->GetSortedObjs() : nullptr;
3983  if ( pTmpObjs )
3984  {
3985  for (SwAnchoredObject* pAnchoredObj : *pTmpObjs)
3986  {
3987  if ( IsAnLower( pAnchoredObj->GetAnchorFrame() ) )
3988  {
3989  pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3990  }
3991  }
3992  }
3993  //Invalidate suitable to nicely balance the Frames.
3994  //- Every first one after the second column gets a
3995  // InvalidatePos();
3996  pCol = static_cast<SwLayoutFrame*>(Lower()->GetNext());
3997  while ( pCol )
3998  {
3999  SwFrame *pLow = pCol->Lower();
4000  if ( pLow )
4001  pLow->InvalidatePos_();
4002  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
4003  }
4004  if( IsSctFrame() && static_cast<SwSectionFrame*>(this)->HasFollow() )
4005  {
4006  // If we created a Follow, we need to give its content
4007  // the opportunity to flow back inside the CalcContent
4008  SwContentFrame* pTmpContent =
4009  static_cast<SwSectionFrame*>(this)->GetFollow()->ContainsContent();
4010  if( pTmpContent )
4011  pTmpContent->InvalidatePos_();
4012  }
4013  }
4014  else
4015  bEnd = true;
4016  }
4017  else
4018  bEnd = true;
4019 
4020  } while ( !bEnd || !isFrameAreaSizeValid() );
4021  }
4022  // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set
4023  // 2nd parameter to <true>.
4024  ::CalcContent( this, true );
4025  if( IsSctFrame() )
4026  {
4027  // OD 14.03.2003 #i11760# - adjust 2nd parameter - sal_True --> true
4028  ::CalcContent( this, true );
4029  if( bBackLock )
4030  static_cast<SwSectionFrame*>(this)->SetFootnoteLock( false );
4031  }
4032 }
4033 
4035 {
4036  SwSectionFrame* pSect = pCnt->FindSctFrame();
4037  // If our ContentFrame is placed inside a table or a footnote, only sections
4038  // which are also placed inside are meant.
4039  // Exception: If a table is directly passed.
4040  if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) ||
4041  ( pCnt->IsInFootnote() && !pSect->IsInFootnote() ) ) && !pCnt->IsTabFrame() )
4042  return nullptr;
4043  if( nInv & SwInvalidateFlags::Size )
4044  pSect->InvalidateSize_();
4045  if( nInv & SwInvalidateFlags::Pos )
4046  pSect->InvalidatePos_();
4047  if( nInv & SwInvalidateFlags::PrtArea )
4048  pSect->InvalidatePrt_();
4049  SwFlowFrame *pFoll = pSect->GetFollow();
4050  // Temporary separation from follow
4051  pSect->SetFollow( nullptr );
4052  SwContentFrame* pRet = pSect->FindLastContent();
4053  pSect->SetFollow( pFoll );
4054  return pRet;
4055 }
4056 
4058 {
4059  if( ( nInv & SwInvalidateFlags::Section ) && pTable->IsInSct() )
4060  lcl_InvalidateSection( pTable, nInv );
4061  if( nInv & SwInvalidateFlags::Size )
4062  pTable->InvalidateSize_();
4063  if( nInv & SwInvalidateFlags::Pos )
4064  pTable->InvalidatePos_();
4065  if( nInv & SwInvalidateFlags::PrtArea )
4066  pTable->InvalidatePrt_();
4067  return pTable->FindLastContent();
4068 }
4069 
4070 static void lcl_InvalidateAllContent( SwContentFrame *pCnt, SwInvalidateFlags nInv );
4071 
4073 {
4074  SwContentFrame *pLastTabCnt = nullptr;
4075  SwContentFrame *pLastSctCnt = nullptr;
4076  while ( pCnt )
4077  {
4078  if( nInv & SwInvalidateFlags::Section )
4079  {
4080  if( pCnt->IsInSct() )
4081  {
4082  // See above at tables
4083  if( !pLastSctCnt )
4084  pLastSctCnt = lcl_InvalidateSection( pCnt, nInv );
4085  if( pLastSctCnt == pCnt )
4086  pLastSctCnt = nullptr;
4087  }
4088 #if OSL_DEBUG_LEVEL > 0
4089  else
4090  OSL_ENSURE( !pLastSctCnt, "Where's the last SctContent?" );
4091 #endif
4092  }
4093  if( nInv & SwInvalidateFlags::Table )
4094  {
4095  if( pCnt->IsInTab() )
4096  {
4097  // To not call FindTabFrame() for each ContentFrame of a table and
4098  // then invalidate the table, we remember the last ContentFrame of
4099  // the table and ignore IsInTab() until we are past it.
4100  // When entering the table, LastSctCnt is set to null, so
4101  // sections inside the table are correctly invalidated.
4102  // If the table itself is in a section the
4103  // invalidation is done three times, which is acceptable.
4104  if( !pLastTabCnt )
4105  {
4106  pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrame(), nInv );
4107  pLastSctCnt = nullptr;
4108  }
4109  if( pLastTabCnt == pCnt )
4110  {
4111  pLastTabCnt = nullptr;
4112  pLastSctCnt = nullptr;
4113  }
4114  }
4115 #if OSL_DEBUG_LEVEL > 0
4116  else
4117  OSL_ENSURE( !pLastTabCnt, "Where's the last TabContent?" );
4118 #endif
4119  }
4120 
4121  if( nInv & SwInvalidateFlags::Size )
4122  pCnt->Prepare( PrepareHint::Clear, nullptr, false );
4123  if( nInv & SwInvalidateFlags::Pos )
4124  pCnt->InvalidatePos_();
4125  if( nInv & SwInvalidateFlags::PrtArea )
4126  pCnt->InvalidatePrt_();
4127  if ( nInv & SwInvalidateFlags::LineNum )
4128  pCnt->InvalidateLineNum();
4129  if ( pCnt->GetDrawObjs() )
4130  lcl_InvalidateAllContent( pCnt, nInv );
4131  pCnt = pCnt->GetNextContentFrame();
4132  }
4133 }
4134 
4136 {
4137  SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
4138  for (SwAnchoredObject* pAnchoredObj : rObjs)
4139  {
4140  if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
4141  {
4142  if ( pFly->IsFlyInContentFrame() )
4143  {
4144  ::lcl_InvalidateContent( pFly->ContainsContent(), nInv );
4145  if( nInv & SwInvalidateFlags::Direction )
4146  pFly->CheckDirChange();
4147  }
4148  }
4149  }
4150 }
4151 
4153 {
4154  // First process all page bound FlyFrames.
4155  SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower());
4156  while( pPage )
4157  {
4158  pPage->InvalidateFlyLayout();
4159  pPage->InvalidateFlyContent();
4160  pPage->InvalidateFlyInCnt();
4161  pPage->InvalidateLayout();
4162  pPage->InvalidateContent();
4163  pPage->InvalidatePage( pPage ); // So even the Turbo disappears if applicable
4164 
4165  if ( pPage->GetSortedObjs() )
4166  {
4167  const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
4168  for (SwAnchoredObject* pAnchoredObj : rObjs)
4169  {
4170  if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
4171  {
4172  ::lcl_InvalidateContent( pFly->ContainsContent(), nInv );
4173  if ( nInv & SwInvalidateFlags::Direction )
4174  pFly->CheckDirChange();
4175  }
4176  }
4177  }
4178  if( nInv & SwInvalidateFlags::Direction )
4179  pPage->CheckDirChange();
4180  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
4181  }
4182 
4183  //Invalidate the whole document content and the character bound Flys here.
4185 
4186  if( nInv & SwInvalidateFlags::PrtArea )
4187  {
4189  if( pSh )
4190  pSh->InvalidateWindows( getFrameArea() );
4191  }
4192 }
4193 
4199 {
4200  const SwPageFrame* pPageFrame = static_cast<const SwPageFrame*>(Lower());
4201  while( pPageFrame )
4202  {
4203  pPageFrame->InvalidateFlyLayout();
4204 
4205  if ( pPageFrame->GetSortedObjs() )
4206  {
4207  const SwSortedObjs& rObjs = *(pPageFrame->GetSortedObjs());
4208  for (SwAnchoredObject* pAnchoredObj : rObjs)
4209  {
4210  const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat().GetAnchor();
4211  if ((rAnch.GetAnchorId() != RndStdIds::FLY_AT_PARA) &&
4212  (rAnch.GetAnchorId() != RndStdIds::FLY_AT_CHAR))
4213  {
4214  // only to paragraph and to character anchored objects are considered.
4215  continue;
4216  }
4217  // #i28701# - special invalidation for anchored
4218  // objects, whose wrapping style influence has to be considered.
4219  if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
4220  pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence();
4221  else
4222  pAnchoredObj->InvalidateObjPos();
4223  }
4224  }
4225 
4226  pPageFrame = static_cast<const SwPageFrame*>(pPageFrame->GetNext());
4227  }
4228 }
4229 
4231  SwTextFrame & rFrame, SwTextNode & rTextNode,
4232  std::set<sal_uLong> *const pSkipped,
4233  SwFrameFormats & rTable,
4234  SwPageFrame *const pPage,
4235  SwTextNode const*const pNode,
4236  std::vector<sw::Extent>::const_iterator & rIterFirst,
4237  std::vector<sw::Extent>::const_iterator const& rIterEnd,
4238  SwTextNode const*const pFirstNode, SwTextNode const*const pLastNode)
4239 {
4240  if (pNode == &rTextNode)
4241  { // remove existing hidden at-char anchored flys
4242  RemoveHiddenObjsOfNode(rTextNode, &rIterFirst, &rIterEnd, pFirstNode, pLastNode);
4243  }
4244  else if (rTextNode.GetIndex() < pNode->GetIndex())
4245  {
4246  // pNode's frame has been deleted by CheckParaRedlineMerge()
4247  AppendObjsOfNode(&rTable,
4248  pNode->GetIndex(), &rFrame, pPage, &rTextNode.GetDoc(),
4249  &rIterFirst, &rIterEnd, pFirstNode, pLastNode);
4250  if (pSkipped)
4251  {
4252  // 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
4253  for (auto const pFly : pNode->GetAnchoredFlys())
4254  {
4255  if (pFly->Which() != RES_DRAWFRMFMT)
4256  {
4257  pSkipped->insert(pFly->GetContent().GetContentIdx()->GetIndex());
4258  }
4259  }
4260  }
4261  }
4262 }
4263 
4264 namespace sw {
4265 
4270  SwTextFrame & rFrame, SwTextNode & rTextNode,
4271  std::set<sal_uLong> *const pSkipped)
4272 {
4273  auto const pMerged(rFrame.GetMergedPara());
4274  if (!pMerged
4275  // do this only *once*, for the *last* frame
4276  // otherwise AppendObj would create multiple frames for fly-frames!
4277  || rFrame.GetFollow())
4278  return;
4279 
4280  assert(pMerged->pFirstNode->GetIndex() <= rTextNode.GetIndex()
4281  && rTextNode.GetIndex() <= pMerged->pLastNode->GetIndex());
4282  // add visible flys in non-first node to merged frame
4283  // (hidden flys remain and are deleted via DelFrames())
4284  SwFrameFormats& rTable(*rTextNode.GetDoc().GetSpzFrameFormats());
4285  SwPageFrame *const pPage(rFrame.FindPageFrame());
4286  std::vector<sw::Extent>::const_iterator iterFirst(pMerged->extents.begin());
4287  std::vector<sw::Extent>::const_iterator iter(iterFirst);
4288  SwTextNode const* pNode(pMerged->pFirstNode);
4289  for ( ; ; ++iter)
4290  {
4291  if (iter == pMerged->extents.end()
4292  || iter->pNode != pNode)
4293  {
4294  AddRemoveFlysForNode(rFrame, rTextNode, pSkipped, rTable, pPage,
4295  pNode, iterFirst, iter,
4296  pMerged->pFirstNode, pMerged->pLastNode);
4297  sal_uLong const until = iter == pMerged->extents.end()
4298  ? pMerged->pLastNode->GetIndex() + 1
4299  : iter->pNode->GetIndex();
4300  for (sal_uLong i = pNode->GetIndex() + 1; i < until; ++i)
4301  {
4302  // let's show at-para flys on nodes that contain start/end of
4303  // redline too, even if there's no text there
4304  SwNode const*const pTmp(pNode->GetNodes()[i]);
4305  if (pTmp->GetRedlineMergeFlag() == SwNode::Merge::NonFirst)
4306  {
4307  AddRemoveFlysForNode(rFrame, rTextNode, pSkipped,
4308  rTable, pPage, pTmp->GetTextNode(), iter, iter,
4309  pMerged->pFirstNode, pMerged->pLastNode);
4310  }
4311  }
4312  if (iter == pMerged->extents.end())
4313  {
4314  break;
4315  }
4316  pNode = iter->pNode;
4317  iterFirst = iter;
4318  }
4319  }
4320 }
4321 
4322 } // namespace sw
4323 
4324 static void UnHideRedlines(SwRootFrame & rLayout,
4325  SwNodes & rNodes, SwNode const& rEndOfSectionNode,
4326  std::set<sal_uLong> *const pSkipped)
4327 {
4328  assert(rEndOfSectionNode.IsEndNode());
4329  assert(rNodes[rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1]->IsCreateFrameWhenHidingRedlines()); // first node is never hidden
4330  for (sal_uLong i = rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1;
4331  i < rEndOfSectionNode.GetIndex(); ++i)
4332  {
4333  SwNode & rNode(*rNodes[i]);
4334  if (rNode.IsTextNode()) // only text nodes are 1st node of a merge
4335  {
4336  SwTextNode & rTextNode(*rNode.GetTextNode());
4338  std::vector<SwTextFrame*> frames;
4339  for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
4340  {
4341  if (pFrame->getRootFrame() == &rLayout)
4342  {
4343  if (pFrame->IsFollow())
4344  {
4345  frames.push_back(pFrame);
4346  } // when hiding, the loop must remove the anchored flys
4347  else // *before* resetting SetMergedPara anywhere - else
4348  { // the fly deletion code will access multiple of the
4349  // frames with inconsistent MergedPara and assert
4350  frames.insert(frames.begin(), pFrame);
4351  }
4352  }
4353  }
4354  // this messes with pRegisteredIn so do it outside SwIterator
4356  for (SwTextFrame * pFrame : frames)
4357  {
4358  if (rLayout.HasMergedParas())
4359  {
4360  assert(!pFrame->GetMergedPara() ||
4362  // FIXME: skip this assert in tables with deleted rows
4363  pFrame->IsInTab());
4364  if (rNode.IsCreateFrameWhenHidingRedlines())
4365  {
4366  {
4367  auto pMerged(CheckParaRedlineMerge(*pFrame,
4368  rTextNode, eMode));
4369  pFrame->SetMergedPara(std::move(pMerged));
4370  }
4371  auto const pMerged(pFrame->GetMergedPara());
4372  if (pMerged)
4373  {
4374  // invalidate SwInvalidateFlags::Size
4375  pFrame->Prepare(PrepareHint::Clear, nullptr, false);
4376  pFrame->InvalidatePage();
4377  if (auto const pObjs = pFrame->GetDrawObjs())
4378  { // also invalidate position of existing flys
4379  // because they may need to be moved
4380  for (auto const pObject : *pObjs)
4381  {
4382  pObject->InvalidateObjPos();
4383  }
4384  }
4385  }
4386  sw::AddRemoveFlysAnchoredToFrameStartingAtNode(*pFrame, rTextNode, pSkipped);
4387  // only *first* frame of node gets Existing because it
4388  eMode = sw::FrameMode::New; // is not idempotent!
4389  }
4390  }
4391  else
4392  {
4393  if (auto const& pMergedPara = pFrame->GetMergedPara())
4394  {
4395  // invalidate SwInvalidateFlags::Size
4396  pFrame->Prepare(PrepareHint::Clear, nullptr, false);
4397  pFrame->InvalidatePage();
4398  if (auto const pObjs = pFrame->GetDrawObjs())
4399  { // also invalidate position of existing flys
4400  for (auto const pObject : *pObjs)
4401  {
4402  pObject->InvalidateObjPos();
4403  }
4404  }
4405  // SwFlyAtContentFrame::SwClientNotify() always appends to
4406  // the master frame, so do the same here.
4407  // (RemoveFootnotesForNode must be called at least once)
4408  if (!pFrame->IsFollow())
4409  {
4410  // the new text frames don't exist yet, so at this point
4411  // we can only delete the footnote frames so they don't
4412  // point to the merged SwTextFrame any more...
4413  assert(&rTextNode == pMergedPara->pFirstNode);
4414  // iterate over nodes, not extents: if a node has
4415  // no extents now but did have extents initially,
4416  // its flys need their frames deleted too!
4417  for (sal_uLong j = rTextNode.GetIndex() + 1;
4418  j <= pMergedPara->pLastNode->GetIndex(); ++j)
4419  {
4420  SwNode *const pNode(rTextNode.GetNodes()[j]);
4421  assert(!pNode->IsEndNode());
4422  if (pNode->IsStartNode())
4423  {
4424  j = pNode->EndOfSectionIndex();
4425  }
4426  else if (pNode->IsTextNode())
4427  {
4428  sw::RemoveFootnotesForNode(rLayout, *pNode->GetTextNode(), nullptr);
4429  // similarly, remove the anchored flys
4430  for (SwFrameFormat * pFormat : pNode->GetAnchoredFlys())
4431  {
4432  pFormat->DelFrames(/*&rLayout*/);
4433  }
4434  }
4435  }
4436  // rely on AppendAllObjs call at the end to add
4437  // all flys in first node that are hidden
4438  }
4439  pFrame->SetMergedPara(nullptr);
4440  }
4441  }
4442  pFrame->Broadcast(SfxHint()); // notify SwAccessibleParagraph
4443  }
4444  // all nodes, not just merged ones! it may be in the same list as
4445  if (rTextNode.IsNumbered(nullptr)) // a preceding merged one...
4446  { // notify frames so they reformat numbering portions
4447  rTextNode.NumRuleChgd();
4448  }
4449  }
4450  else if (rNode.IsTableNode() && rLayout.IsHideRedlines())
4451  {
4452  SwTableNode * pTableNd = rNode.GetTableNode();
4453  SwPosition const tmp(rNode);
4454  SwRangeRedline const*const pRedline(
4455  rLayout.GetFormat()->GetDoc()->getIDocumentRedlineAccess().GetRedline(tmp, nullptr));
4456  // pathology: redline that starts on a TableNode; cannot
4457  // be created in UI but by import filters...
4458  if (pRedline
4459  && pRedline->GetType() == RedlineType::Delete
4460  && &pRedline->Start()->nNode.GetNode() == &rNode)
4461  {
4462  for (sal_uLong j = rNode.GetIndex(); j <= rNode.EndOfSectionIndex(); ++j)
4463  {
4464  rNode.GetNodes()[j]->SetRedlineMergeFlag(SwNode::Merge::Hidden);
4465  }
4466  pTableNd->DelFrames(&rLayout);
4467  }
4468  else if ( pTableNd->GetTable().HasDeletedRow() )
4469  {
4470  pTableNd->DelFrames(&rLayout);
4471  if ( !pTableNd->GetTable().IsDeleted() )
4472  {
4473  SwNodeIndex aIdx( *pTableNd->EndOfSectionNode(), 1 );
4474  pTableNd->MakeOwnFrames(&aIdx);
4475  }
4476  }
4477  }
4478  else if (rNode.IsTableNode() && !rLayout.IsHideRedlines() &&
4479  rNode.GetTableNode()->GetTable().HasDeletedRow() )
4480  {
4481  SwTableNode * pTableNd = rNode.GetTableNode();
4482  pTableNd->DelFrames(&rLayout);
4483  SwNodeIndex aIdx( *pTableNd->EndOfSectionNode(), 1 );
4484  pTableNd->MakeOwnFrames(&aIdx);
4485  }
4486 
4487  if (!rNode.IsCreateFrameWhenHidingRedlines())
4488  {
4489  if (rLayout.HasMergedParas())
4490  {
4491  if (rNode.IsContentNode())
4492  {
4493  // note: nothing to do here, already done
4494 #ifndef NDEBUG
4495  auto const pFrame(static_cast<SwContentNode&>(rNode).getLayoutFrame(&rLayout));
4496  assert(!pFrame || static_cast<SwTextFrame*>(pFrame)->GetMergedPara()->pFirstNode != &rNode);
4497 #endif
4498  }
4499  }
4500  else
4501  {
4502  assert(!rNode.IsContentNode() || !rNode.GetContentNode()->getLayoutFrame(&rLayout) ||
4503  // FIXME: skip this assert in tables with deleted rows
4504  rNode.GetContentNode()->getLayoutFrame(&rLayout)->IsInTab());
4505  sal_uLong j = i + 1;
4506  for ( ; j < rEndOfSectionNode.GetIndex(); ++j)
4507  {
4508  if (rNodes[j]->IsCreateFrameWhenHidingRedlines())
4509  {
4510  break;
4511  }
4512  }
4513  // call MakeFrames once, because sections/tables
4514  // InsertCnt_ also checks for hidden sections
4515  SwNodeIndex const start(rNodes, i);
4516  SwNodeIndex const end(rNodes, j);
4517  {
4518  sw::FlyCreationSuppressor aSuppressor(false);
4519  ::MakeFrames(rLayout.GetFormat()->GetDoc(), start, end);
4520  }
4521  i = j - 1; // will be incremented again
4522  }
4523  }
4524  }
4525 }
4526 
4527 static void UnHideRedlinesExtras(SwRootFrame & rLayout,
4528  SwNodes & rNodes, SwNode const& rEndOfExtraSectionNode,
4529  std::set<sal_uLong> *const pSkipped)
4530 {
4531  assert(rEndOfExtraSectionNode.IsEndNode());
4532  for (sal_uLong i = rEndOfExtraSectionNode.StartOfSectionNode()->GetIndex()
4533  + 1; i < rEndOfExtraSectionNode.GetIndex(); ++i)
4534  {
4535  SwNode const& rStartNode(*rNodes[i]);
4536  assert(rStartNode.IsStartNode());
4537  assert(rStartNode.GetRedlineMergeFlag() == SwNode::Merge::None);
4538  SwNode const& rEndNode(*rStartNode.EndOfSectionNode());
4539  bool bSkip(pSkipped && pSkipped->find(i) != pSkipped->end());
4540  i = rEndNode.GetIndex();
4541  for (sal_uLong j = rStartNode.GetIndex() + 1; j < i; ++j)
4542  {
4543  // note: SwStartNode has no way to access the frames, so check
4544  // whether the first content-node inside the section has frames
4545  SwNode const& rNode(*rNodes[j]);
4546  if (rNode.IsSectionNode() &&
4547  static_cast<SwSectionNode const&>(rNode).GetSection().IsHiddenFlag())
4548  { // skip hidden sections - they can be inserted in fly-frames :(
4549  j = rNode.EndOfSectionNode()->GetIndex();
4550  continue;
4551  }
4552  if (rNode.IsContentNode())
4553  {
4554  SwContentNode const& rCNode(static_cast<SwContentNode const&>(rNode));
4555  if (!rCNode.getLayoutFrame(&rLayout))
4556  { // ignore footnote/fly/header/footer with no layout frame
4557  bSkip = true; // they will be created from scratch later if needed
4558  }
4559  break;
4560  }
4561  }
4562  if (!bSkip)
4563  {
4564  UnHideRedlines(rLayout, rNodes, rEndNode, pSkipped);
4565  }
4566  }
4567 }
4568 
4569 static void UnHide(SwRootFrame & rLayout)
4570 {
4571  assert(rLayout.GetCurrShell()->ActionPend()); // tdf#125754 avoid recursive layout
4572  SwDoc & rDoc(*rLayout.GetFormat()->GetDoc());
4573  // don't do early return if there are no redlines:
4574  // Show->Hide must init hidden number trees
4575  // Hide->Show may be called after all redlines have been deleted but there
4576  // may still be MergedParas because those aren't deleted yet...
4577 #if 0
4578  if (!bHideRedlines
4579  && rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty())
4580  {
4581  return;
4582  }
4583 #endif
4584  // Hide->Show: clear MergedPara, create frames
4585  // Show->Hide: call CheckParaRedlineMerge, delete frames
4586  // Traverse the document via the nodes-array; traversing via the layout
4587  // wouldn't find the nodes that don't have frames in the ->Show case.
4588  // In-order traversal of each nodes array section should init the flags
4589  // in nodes before they are iterated.
4590  // Actual creation of frames should be done with existing functions
4591  // if possible, particularly InsertCnt_() or its wrapper ::MakeFrames().
4592  SwNodes /*const*/& rNodes(rDoc.GetNodes());
4593  // Flys/footnotes: must iterate and find all the ones that already exist
4594  // with frames and have redlines inside them; if any don't have frames at
4595  // all, they will be created (if necessary) from scratch and completely by
4596  // MakeFrames().
4597  //
4598  // Flys before footnotes: because footnotes may contain flys but not
4599  // vice-versa; alas flys may contain flys, so we skip some of them
4600  // if they have already been created from scratch via their anchor flys.
4601  std::set<sal_uLong> skippedFlys;
4602  UnHideRedlinesExtras(rLayout, rNodes, rNodes.GetEndOfAutotext(),
4603  // when un-hiding, delay all fly frame creation to AppendAllObjs below
4604  rLayout.HasMergedParas() ? &skippedFlys : nullptr);
4605  // Footnotes are created automatically (after invalidation etc.) by
4606  // ConnectFootnote(), but need to be deleted manually. Footnotes do not
4607  // occur in flys or headers/footers.
4608  UnHideRedlinesExtras(rLayout, rNodes, rNodes.GetEndOfInserts(), nullptr);
4609  UnHideRedlines(rLayout, rNodes, rNodes.GetEndOfContent(), nullptr);
4610 
4611  if (!rLayout.HasMergedParas())
4612  { // create all previously hidden flys at once:
4613  // * Flys on first node of pre-existing merged frames that are hidden
4614  // (in delete redline), to be added to the existing frame
4615  // * Flys on non-first (hidden/merged) nodes of pre-existing merged
4616  // frames, to be added to the new frame of their node
4617  // * Flys anchored in other flys that are hidden
4618  AppendAllObjs(rDoc.GetSpzFrameFormats(), &rLayout);
4619  }
4620 
4621  const bool bIsShowChangesInMargin = rLayout.GetCurrShell()->GetViewOptions()->IsShowChangesInMargin();
4622  for (auto const pRedline : rDoc.getIDocumentRedlineAccess().GetRedlineTable())
4623  { // DELETE are handled by the code above; for other types, need to
4624  // trigger repaint of text frames to add/remove the redline color font
4625  // (handle deletions showed in margin also here)
4626  if (bIsShowChangesInMargin || pRedline->GetType() != RedlineType::Delete)
4627  {
4628  pRedline->InvalidateRange(SwRangeRedline::Invalidation::Add);
4629  }
4630  }
4631 
4632  SwFootnoteIdxs & rFootnotes(rDoc.GetFootnoteIdxs());
4633  if (rDoc.GetFootnoteInfo().m_eNum == FTNNUM_CHAPTER)
4634  {
4635  // sadly determining which node is outline node requires hidden layout
4636  rFootnotes.UpdateAllFootnote();
4637  }
4638  // invalidate all footnotes to reformat their numbers
4639  for (SwTextFootnote *const pFootnote : rFootnotes)
4640  {
4641  SwFormatFootnote const& rFootnote(pFootnote->GetFootnote());
4642  if (rFootnote.GetNumber() != rFootnote.GetNumberRLHidden()
4643  && rFootnote.GetNumStr().isEmpty())
4644  {
4645  pFootnote->InvalidateNumberInLayout();
4646  }
4647  }
4648  // update various fields to re-expand them with the new layout
4649  IDocumentFieldsAccess & rIDFA(rDoc.getIDocumentFieldsAccess());
4650  auto const pAuthType(rIDFA.GetFieldType(
4651  SwFieldIds::TableOfAuthorities, OUString(), false));
4652  if (pAuthType) // created on demand...
4653  { // calling DelSequenceArray() should be unnecessary here since the
4654  // sequence doesn't depend on frames
4655  pAuthType->UpdateFields();
4656  }
4657  rIDFA.GetFieldType(SwFieldIds::RefPageGet, OUString(), false)->UpdateFields();
4658  rIDFA.GetSysFieldType(SwFieldIds::Chapter)->UpdateFields();
4659  rIDFA.UpdateExpFields(nullptr, false);
4660  rIDFA.UpdateRefFields();
4661 
4662  // update SwPostItMgr / notes in the margin
4663  // note: as long as all shells share layout, broadcast to all shells!
4664  rDoc.GetDocShell()->Broadcast( SwFormatFieldHint(nullptr, rLayout.HasMergedParas()
4667 
4668 
4669 // InvalidateAllContent(SwInvalidateFlags::Size); // ??? TODO what to invalidate? this is the big hammer
4670 }
4671 
4672 void SwRootFrame::SetHideRedlines(bool const bHideRedlines)
4673 {
4674  if (bHideRedlines == mbHideRedlines)
4675  {
4676  return;
4677  }
4678  // TODO: remove temporary ShowBoth
4680  if (HasMergedParas())
4681  {
4683  mbHideRedlines = false;
4684  UnHide(*this);
4685  }
4686  if (bHideRedlines || eMode != m_FieldmarkMode)
4687  {
4688  m_FieldmarkMode = eMode;
4689  mbHideRedlines = bHideRedlines;
4690  UnHide(*this);
4691  }
4692 }
4693 
4695 {
4696  if (eMode == m_FieldmarkMode)
4697  {
4698  return;
4699  }
4700  // TODO: remove temporary ShowBoth
4701  bool const isHideRedlines(mbHideRedlines);
4702  if (HasMergedParas())
4703  {
4704  mbHideRedlines = false;
4706  UnHide(*this);
4707  }
4708  if (eMode != sw::FieldmarkMode::ShowBoth || isHideRedlines)
4709  {
4710  mbHideRedlines = isHideRedlines;
4711  m_FieldmarkMode = eMode;
4712  UnHide(*this);
4713  }
4714 }
4715 
4716 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void InsertBefore(SwLayoutFrame *pParent, SwFrame *pBehind)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:830
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:207
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:338
#define FRM_NEIGHBOUR
Definition: frame.hxx:107
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:548
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:683
void transform(const basegfx::B2DHomMatrix &aTransform)
Definition: wsfrm.cxx:286
virtual void CheckDirection(bool bVert) override
Definition: wsfrm.cxx:406
Base class of the Writer layout elements.
Definition: frame.hxx:315
double getY() const
Base class that provides the general functionalities for frames that are allowed at page breaks (flow...
Definition: flowfrm.hxx:58
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:158
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
tools::Long GetWidth() const
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(93)
SwFrameGet fnGetPrtBottom
Definition: frame.hxx:1325
sal_uLong GetIndex() const
Definition: node.hxx:291
void Right(const tools::Long nRight)
Definition: swrect.hxx:199
constexpr TypedWhichId< SwHeaderAndFooterEatSpacingItem > RES_HEADER_FOOTER_EAT_SPACING(121)
void Add(SwClient *pDepend)
Definition: calbck.cxx:173
bool IsFollow() const
Definition: flowfrm.hxx:166
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:2877
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:565
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:168
Marks a position in the document model.
Definition: pam.hxx:35
void RegisterToFormat(SwFormat &rFormat)
Definition: wsfrm.cxx:335
constexpr TypedWhichId< SvxTabStopItem > RES_PARATR_TABSTOP(68)
SwFrame * mpNext
Definition: frame.hxx:339
SwFrame * mpPrev
Definition: frame.hxx:340
bool IsSectionNode() const
Definition: node.hxx:645
bool IsEndnAtEnd() const
Definition: sectfrm.hxx:157
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:115
constexpr TypedWhichId< SvxEscapementItem > RES_CHRATR_ESCAPEMENT(6)
bool IsInDocBody() const
Definition: frame.hxx:944
bool IsRootFrame() const
Definition: frame.hxx:1175
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1503
bool mbValidLineNum
Definition: frame.hxx:428
bool IsInSct() const
Definition: frame.hxx:968
bool IsOrtho() const
Definition: fmtclds.hxx:121
double getHeight() const
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
"Formats" the Frame; Frame and PrtArea.
Definition: wsfrm.cxx:3411
tools::Long BottomDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1415
SwRect getUntransformedFramePrintArea() const
Definition: wsfrm.cxx:188
bool IsAnyShellAccessible() const
Definition: rootfrm.hxx:390
void DelFrames(SwRootFrame const *pLayout=nullptr)
Method deletes all views of document for the node.
Definition: ndtbl.cxx:2446
SwViewShellImp * Imp()
Definition: viewsh.hxx:182
void DelEmpty(bool bRemove)
Definition: sectfrm.cxx:186
bool mbInvalidVert
Definition: frame.hxx:421
B2DTuple absolute(const B2DTuple &rTup)
static void CheckPageDescs(SwPageFrame *pStart, bool bNotifyFields=true, SwPageFrame **ppPrev=nullptr)
Check all pages (starting from the given one) if they use the appropriate frame format.
Definition: pagechg.cxx:1056
SwDocShell * GetDocShell()
Definition: doc.hxx:1352
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(162)
std::string GetValue
bool IsColLocked() const
Definition: frame.hxx:887
void InvalidateAllContent(SwInvalidateFlags nInvalidate)
Invalidate all Content, Size or PrtArea.
Definition: wsfrm.cxx:4152
constexpr TypedWhichId< SwFormatCol > RES_COL(109)
bool mbFrameAreaPositionValid
Definition: frame.hxx:147
virtual void UpdatePageFields(SfxPoolItem *)=0
constexpr TypedWhichId< SvxFormatKeepItem > RES_KEEP(110)
const SwTable * GetTable() const
Definition: tabfrm.hxx:158
void Left(const tools::Long nLeft)
Definition: swrect.hxx:194
GPOS_NONE
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
void SetCompletePaint() const
Definition: frame.hxx:995
void ImplInvalidateSize()
Definition: wsfrm.cxx:1950
bool IsInFootnote() const
Definition: frame.hxx:950
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:597
void FormatWidthCols(const SwBorderAttrs &, const SwTwips nBorder, const SwTwips nMinHeight)
Called by Format for Frames and Areas with columns.
Definition: wsfrm.cxx:3676
SwFrameType GetType() const
Definition: frame.hxx:520
virtual basegfx::B2DHomMatrix getFramePrintAreaTransformation() const
Definition: wsfrm.cxx:134
void SetNeedGrammarCheck(bool bVal)
Definition: rootfrm.hxx:263
void setSwRect(const SwRect &rNew)
Definition: frame.hxx:199
sal_uIntPtr sal_uLong
long Long
constexpr TypedWhichId< SwNumRuleItem > RES_PARATR_NUMRULE(72)
const SwRect & getFramePrintArea() const
Definition: frame.hxx:181
void InvalidateLineNum_()
Definition: frame.hxx:796
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_FONTSIZE(8)
virtual void CheckDirection(bool bVert) override
Definition: wsfrm.cxx:448
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:46
tools::Long CalcRight(const SwFrame *pCaller) const
Definition: frmtool.cxx:2271
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:450
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1213
void InvalidateSize_()
Definition: frame.hxx:772
Definition: doc.hxx:188
bool HasFollow() const
Definition: flowfrm.hxx:165
static void UnHide(SwRootFrame &rLayout)
Definition: wsfrm.cxx:4569
bool KnowsFormat(const SwFormat &rFormat) const
Definition: wsfrm.cxx:330
virtual bool InvalidationAllowed(const InvalidationType _nInvalid) const
method to determine, if an invalidation is allowed.
Definition: wsfrm.cxx:1944
void InvalidatePos()
Definition: frame.hxx:1044
SwRectGet fnGetHeight
Definition: frame.hxx:1297
#define FRM_BODYFTNC
Definition: frame.hxx:110
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
constexpr TypedWhichId< SvxUnderlineItem > RES_CHRATR_UNDERLINE(14)
constexpr TypedWhichId< SvxAutoKernItem > RES_CHRATR_AUTOKERN(17)
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: wsfrm.cxx:1337
void SetTurbo(const SwContentFrame *pContent)
Definition: rootfrm.hxx:351
SvxFrameDirection
bool IsVert() const
Definition: frame.hxx:1368
SwRectGet fnGetWidth
Definition: frame.hxx:1296
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:384
void Pos(const Point &rNew)
Definition: swrect.hxx:168
SwFrameAreaDefinition & mrTarget
Definition: frame.hxx:191
bool IsEndNote() const
Definition: fmtftn.hxx:71
const SwCellFrame & FindStartEndOfRowSpanCell(bool bStart) const
Definition: findfrm.cxx:1684
Dialog to specify the properties of date form field.
SwFrame * FindNext()
Definition: frame.hxx:1142
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1788
bool IsCellFrame() const
Definition: frame.hxx:1227
bool IsFootnotePage() const
Foot note interface.
Definition: pagefrm.hxx:199
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
SwLayoutFrame(SwFrameFormat *, SwFrame *)
Definition: wsfrm.cxx:2576
void ImplInvalidatePrt()
Definition: wsfrm.cxx:1966
virtual const SwFormatPageDesc & GetPageDescItem() const
Definition: findfrm.cxx:662
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2703
bool mbVertLR
Definition: frame.hxx:425
EmbeddedObjectRef * pObject
void AddBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1395
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const
Definition: wsfrm.cxx:124
void SetResizeHTMLTable()
Definition: tabfrm.hxx:169
css::chart::ChartAxisLabelPosition ePos
void InvalidateFlyInCnt() const
Definition: pagefrm.hxx:372
bool IsFootnoteFrame() const
Definition: frame.hxx:1203
None
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
sal_Int32 GetBrowseWidth() const
Definition: viewsh.cxx:1996
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:744
SfxHintId GetId() const
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:172
Value in Var-direction gives minimum (can be exceeded but not be less).
static bool bFootnote
Definition: insfnote.cxx:33
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: wsfrm.cxx:2340
static SwContentFrame * lcl_InvalidateTable(SwTabFrame *pTable, SwInvalidateFlags nInv)
Definition: wsfrm.cxx:4057
void UpdateAttrFrame(const SfxPoolItem *, const SfxPoolItem *, SwFrameInvFlags &)
Definition: wsfrm.cxx:526
void CheckDirChange()
checks the layout direction and invalidates the lower frames recursively, if necessary.
Definition: ssfrm.cxx:192
bool IsVertLRBT() const
Definition: frame.hxx:984
FieldmarkMode
Definition: rootfrm.hxx:50
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:204
sal_Int32 getRowSpan() const
Definition: swtable.cxx:76
bool IsTurboAllowed() const
Definition: rootfrm.hxx:350
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1378
constexpr tools::Long Width() const
bool mbVertLRBT
Definition: frame.hxx:426
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:357
void SetRetouche() const
Definition: frame.hxx:1004
SwFrame(sw::BroadcastingModify *, SwFrame *)
Definition: wsfrm.cxx:292
GPOS_TILED
void InvalidateObjs(const bool _bNoInvaOfAsCharAnchoredObjs=true)
Definition: fly.cxx:2345
bool IsFlyFrame() const
Definition: frame.hxx:1211
void InvalidateNextPrtArea()
method to invalidate printing area of next frame #i11859#
Definition: findfrm.cxx:1282
void ChgLowersProp(const Size &rOldSize)
Change size of lowers proportionally.
Definition: wsfrm.cxx:3012
wrapper class for the positioning of Writer fly frames and drawing objects
void SetFirstVisPageInvalid()
Definition: viewimp.hxx:146
std::unique_ptr< SvxBrushItem > makeBackgroundBrushItem(bool=true) const
Definition: format.cxx:742
SwTwips Shrink_(SwTwips, bool bTst)
Definition: fly.cxx:2010
SwTableNode * GetTableNode()
Definition: node.hxx:600
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(159)
double getWidth() const
const SwTableBox * GetTabBox() const
Definition: cellfrm.hxx:52
void restoreFrameAreas()
Definition: wsfrm.cxx:268
const SwRect & getFrameArea() const
Definition: frame.hxx:180
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1026
bool getBrowseMode() const
Definition: viewopt.hxx:472
BASEGFX_DLLPUBLIC void transform(const B2DHomMatrix &rMatrix)
virtual Size ChgSize(const Size &aNewSize)
Definition: wsfrm.cxx:731
EdgeEntry * mpNext
bool IsInTab() const
Definition: frame.hxx:956
std::unique_ptr< sw::MergedPara > CheckParaRedlineMerge(SwTextFrame &rFrame, SwTextNode &rTextNode, FrameMode eMode)
Definition: redlnitr.cxx:205
constexpr TypedWhichId< SfxBoolItem > RES_RTL_GUTTER(132)
const SwRowFrame * IsInSplitTableRow() const
Definition: findfrm.cxx:1755
bool IsTextFrame() const
Definition: frame.hxx:1235
void InvalidateFlyContent() const
Definition: pagefrm.hxx:368
SwRectFn fnRectVertL2R
Definition: newfrm.cxx:288
void SetSuperfluous()
Remove superfluous Pages.
Definition: rootfrm.hxx:302
bool IsStartNode() const
Definition: node.hxx:625
SwInvalidateFlags
Definition: rootfrm.hxx:53
void Width(tools::Long nNew)
Definition: swrect.hxx:186
void setFramePrintAreaValid(bool bNew)
Definition: wsfrm.cxx:99
void AddRemoveFlysAnchoredToFrameStartingAtNode(SwTextFrame &rFrame, SwTextNode &rTextNode, std::set< sal_uLong > *pSkipped)
rTextNode is the first one of the "new" merge - if rTextNode isn't the same as MergedPara::pFirstNode...
Definition: wsfrm.cxx:4269
SwContentFrameInvFlags
Definition: cntfrm.hxx:36
Mode eMode
B2DHomMatrix createScaleTranslateB2DHomMatrix(double fScaleX, double fScaleY, double fTranslateX, double fTranslateY)
const SwTable & GetTable() const
Definition: node.hxx:499
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
std::vector< SwFrameFormat * > const & GetAnchoredFlys() const
Definition: node.hxx:297
bool IsPageBodyFrame() const
Definition: layfrm.hxx:214
virtual void CheckDirection(bool bVert) override
Definition: wsfrm.cxx:466
Describes parts of multiple text nodes, which will form a text frame, even when redlines are hidden a...
Definition: txtfrm.hxx:956
SwFrameInvFlags
Definition: frame.hxx:293
bool IsSctFrame() const
Definition: frame.hxx:1215
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1112
void CheckWaitCursor()
If an Action is running we ask it to check whether it's time to enable the WaitCursor.
Definition: viewimp.cxx:135
SwFrameSet fnSetXMargins
Definition: frame.hxx:1322
bool IsFlyInContentFrame() const
Definition: flyfrm.hxx:215
bool IsFlowFrame() const
Definition: frame.hxx:1243
void SetIdleFlags()
Definition: rootfrm.hxx:249
SwRectFn fnRectHori
Definition: newfrm.cxx:286
B2IRange fround(const B2DRange &rRange)
void InvalidateLayout() const
Definition: pagefrm.hxx:376
virtual ~SwFrameAreaDefinition()
Definition: wsfrm.cxx:79
void MakeFrames(SwDoc *pDoc, const SwNodeIndex &rSttIdx, const SwNodeIndex &rEndIdx)
Definition: frmtool.cxx:1978
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:855
tools::Long GetLayoutRowSpan() const
Definition: tabfrm.cxx:5588
Specific frame formats (frames, DrawObjects).
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:677
static sal_uInt8 nFramePos
Definition: basesh.cxx:113
void InvalidateContent() const
Definition: pagefrm.hxx:380
const SwFrame & GetFrame() const
Definition: flowfrm.hxx:151
Base class for various Writer styles.
Definition: format.hxx:46
constexpr TypedWhichId< SwFormatRowSplit > RES_ROW_SPLIT(122)
void SetHideRedlines(bool)
Definition: wsfrm.cxx:4672
static void AddRemoveFlysForNode(SwTextFrame &rFrame, SwTextNode &rTextNode, std::set< sal_uLong > *const pSkipped, SwFrameFormats &rTable, SwPageFrame *const pPage, SwTextNode const *const pNode, std::vector< sw::Extent >::const_iterator &rIterFirst, std::vector< sw::Extent >::const_iterator const &rIterEnd, SwTextNode const *const pFirstNode, SwTextNode const *const pLastNode)
Definition: wsfrm.cxx:4230
virtual SwTwips GrowFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: wsfrm.cxx:2098
bool IsColumnFrame() const
Definition: frame.hxx:1183
SwRectFn fnRectVertL2RB2T
Definition: newfrm.cxx:289
void ResetTurbo()
Definition: rootfrm.hxx:352
SwContentFrame * FindLastContent()
Definition: tabfrm.cxx:3563
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1108
bool IsContentNode() const
Definition: node.hxx:629
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:457
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1305
void InvalidateAutoCompleteWords() const
Definition: pagefrm.hxx:393
void CalcContent(SwLayoutFrame *pLay, bool bNoColl=false)
Definition: fly.cxx:1411
virtual SwTwips GrowFrame(SwTwips, bool bTst=false, bool bInfo=false)=0
bool IsDeleted() const
Definition: swtable.cxx:1581
SwTwips Grow_(SwTwips, bool bTst)
Definition: fly.cxx:1930
void SetDirFlags(bool bVert)
Updates the vertical or the righttoleft-flags.
Definition: findfrm.cxx:1467
Style of a layout element.
Definition: frmfmt.hxx:59
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:165
PrepareHint
Definition: swtypes.hxx:194
bool IsContentFrame() const
Definition: frame.hxx:1231
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:774
void InvalidateLineNum()
Definition: frame.hxx:1051
SwFrame * GetIndPrev() const
Definition: frame.hxx:725
constexpr TypedWhichId< SfxBoolItem > RES_BACKGROUND_FULL_SIZE(131)
void InvalidatePrt()
Definition: frame.hxx:1037
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:132
void InvalidateSpelling() const
Definition: pagefrm.hxx:384
void SetRemoveFollowFlowLinePending(bool bNew)
Definition: tabfrm.hxx:184
int i
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1411
void MoveAccessibleFrame(const SwFrame *pFrame, const SwRect &rOldFrame)
Definition: viewimp.hxx:290
const SwRect & VisArea() const
Definition: viewsh.cxx:568
#define FRM_HEADFOOT
Definition: frame.hxx:109
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:132
SwDoc & GetDoc()
Definition: node.hxx:212
SwTwips InnerHeight() const
InnerHeight returns the height of the content and may be bigger or less than the PrtArea-Height of th...
Definition: wsfrm.cxx:2587
SwFrameType
Definition: frame.hxx:75
SwFrame * GetIndNext()
Definition: frame.hxx:728
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
static void lcl_InvalidateAllContent(SwContentFrame *pCnt, SwInvalidateFlags nInv)
Definition: wsfrm.cxx:4135
const SwSectionFrame * GetFollow() const
Definition: sectfrm.hxx:169
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
size_t size() const
Definition: sortedobjs.cxx:43
tools::Long CalcLeft(const SwFrame *pCaller) const
Definition: frmtool.cxx:2333
SwPageFrame * FindPageFrame()
Definition: frame.hxx:681
static bool lcl_IsFlyHeightClipped(SwLayoutFrame *pLay)
Definition: wsfrm.cxx:3649
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:888
SwFrame * m_pLower
Definition: layfrm.hxx:53
Document fields related interfaces.
virtual void Cut() override
Definition: wsfrm.cxx:1434
static void InvaPercentFlys(SwFrame *pFrame, SwTwips nDiff)
Definition: wsfrm.cxx:3527
bool IsCompletePaint() const
Definition: frame.hxx:602
const SwFrame * Lower() const
Definition: layfrm.hxx:101
bool ActionPend() const
Definition: viewsh.hxx:196
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:191
SwTwips AdjustNeighbourhood(SwTwips nDiff, bool bTst=false)
Adjust surrounding neighbourhood after insertion.
Definition: wsfrm.cxx:1607
SwContentNode * GetContentNode()
Definition: node.hxx:616
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: wsfrm.cxx:474
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the