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