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 ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr )
1879  {
1880  SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pAnchoredObj);
1881  OSL_ENSURE( !pFly->IsFlyInContentFrame(), "FlyInCnt at Page?" );
1882  const SwFormatVertOrient &rVert =
1883  pFly->GetFormat()->GetVertOrient();
1884  // When do we have to invalidate?
1885  // If a frame is aligned on a PageTextArea and the header
1886  // changes a TOP, MIDDLE or NONE aligned frame needs to
1887  // recalculate it's position; if the footer changes a BOTTOM
1888  // or MIDDLE aligned frame needs to recalculate it's
1889  // position.
1890  if( ( rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
1891  rVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) &&
1892  ((IsHeaderFrame() && rVert.GetVertOrient()!=text::VertOrientation::BOTTOM) ||
1893  (IsFooterFrame() && rVert.GetVertOrient()!=text::VertOrientation::NONE &&
1894  rVert.GetVertOrient() != text::VertOrientation::TOP)) )
1895  {
1896  pFly->InvalidatePos_();
1897  pFly->Invalidate_();
1898  }
1899  }
1900  }
1901  }
1902  }
1903  return (nBrowseAdd + nReal + nAdd);
1904 }
1905 
1908 {
1909  // default behaviour is to perform no additional action
1910 }
1911 
1914 {
1915  // default behaviour is to allow invalidation
1916  return true;
1917 }
1918 
1920 {
1922  {
1923  setFrameAreaSizeValid(false);
1924 
1925  if ( IsFlyFrame() )
1926  static_cast<SwFlyFrame*>(this)->Invalidate_();
1927  else
1928  InvalidatePage();
1929 
1930  // OD 2004-05-19 #i28701#
1932  }
1933 }
1934 
1936 {
1938  {
1939  setFramePrintAreaValid(false);
1940 
1941  if ( IsFlyFrame() )
1942  static_cast<SwFlyFrame*>(this)->Invalidate_();
1943  else
1944  InvalidatePage();
1945 
1946  // OD 2004-05-19 #i28701#
1948  }
1949 }
1950 
1952 {
1953  if ( !InvalidationAllowed( INVALID_POS ) )
1954  return;
1955 
1957 
1958  if ( IsFlyFrame() )
1959  {
1960  static_cast<SwFlyFrame*>(this)->Invalidate_();
1961  }
1962  else
1963  {
1964  InvalidatePage();
1965  }
1966 
1967  // OD 2004-05-19 #i28701#
1969 }
1970 
1972 {
1974  {
1975  mbValidLineNum = false;
1976  OSL_ENSURE( IsTextFrame(), "line numbers are implemented for text only" );
1977  InvalidatePage();
1978 
1979  // OD 2004-05-19 #i28701#
1981  }
1982 }
1983 
1985 {
1986  const SwFormatFrameSize &rFormatSize = GetAttrSet()->GetFrameSize();
1987  if ( SwFrameSize::Variable == rFormatSize.GetHeightSizeType() ||
1988  SwFrameSize::Minimum == rFormatSize.GetHeightSizeType())
1989  {
1990  mbFixSize = false;
1992  {
1993  SwFrame *pFrame = static_cast<SwLayoutFrame*>(this)->Lower();
1994  while ( pFrame )
1995  { pFrame->InvalidateSize_();
1996  pFrame->InvalidatePrt_();
1997  pFrame = pFrame->GetNext();
1998  }
1999  SwContentFrame *pCnt = static_cast<SwLayoutFrame*>(this)->ContainsContent();
2000  // #i36991# - be save.
2001  // E.g., a row can contain *no* content.
2002  if ( pCnt )
2003  {
2004  pCnt->InvalidatePage();
2005  do
2006  {
2008  pCnt->InvalidateSize_();
2009  pCnt = pCnt->GetNextContentFrame();
2010  } while ( static_cast<SwLayoutFrame*>(this)->IsAnLower( pCnt ) );
2011  }
2012  }
2013  }
2014  else if ( rFormatSize.GetHeightSizeType() == SwFrameSize::Fixed )
2015  {
2016  if( IsVertical() )
2017  ChgSize( Size( rFormatSize.GetWidth(), getFrameArea().Height()));
2018  else
2019  ChgSize( Size( getFrameArea().Width(), rFormatSize.GetHeight()));
2020  }
2021 }
2022 
2023 void SwFrame::ValidateThisAndAllLowers( const sal_uInt16 nStage )
2024 {
2025  // Stage 0: Only validate frames. Do not process any objects.
2026  // Stage 1: Only validate fly frames and all of their contents.
2027  // Stage 2: Validate all.
2028 
2029  const bool bOnlyObject = 1 == nStage;
2030  const bool bIncludeObjects = 1 <= nStage;
2031 
2032  if ( !bOnlyObject || dynamic_cast< const SwFlyFrame *>( this ) != nullptr )
2033  {
2034  setFrameAreaSizeValid(true);
2035  setFramePrintAreaValid(true);
2037  }
2038 
2039  if ( bIncludeObjects )
2040  {
2041  const SwSortedObjs* pObjs = GetDrawObjs();
2042  if ( pObjs )
2043  {
2044  const size_t nCnt = pObjs->size();
2045  for ( size_t i = 0; i < nCnt; ++i )
2046  {
2047  SwAnchoredObject* pAnchObj = (*pObjs)[i];
2048  if ( dynamic_cast< const SwFlyFrame *>( pAnchObj ) != nullptr )
2049  static_cast<SwFlyFrame*>(pAnchObj)->ValidateThisAndAllLowers( 2 );
2050  else if ( dynamic_cast< const SwAnchoredDrawObject *>( pAnchObj ) != nullptr )
2051  static_cast<SwAnchoredDrawObject*>(pAnchObj)->ValidateThis();
2052  }
2053  }
2054  }
2055 
2056  if ( IsLayoutFrame() )
2057  {
2058  SwFrame* pLower = static_cast<SwLayoutFrame*>(this)->Lower();
2059  while ( pLower )
2060  {
2061  pLower->ValidateThisAndAllLowers( nStage );
2062  pLower = pLower->GetNext();
2063  }
2064  }
2065 }
2066 
2067 SwTwips SwContentFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo )
2068 {
2069  SwRectFnSet aRectFnSet(this);
2070 
2071  SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
2072  if( nFrameHeight > 0 &&
2073  nDist > (LONG_MAX - nFrameHeight ) )
2074  nDist = LONG_MAX - nFrameHeight;
2075 
2076  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
2077  const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2079  if (bBrowse)
2080  nTmpType |= SwFrameType::Body;
2081  if( !(GetUpper()->GetType() & nTmpType) && GetUpper()->HasFixSize() )
2082  {
2083  if ( !bTst )
2084  {
2085  {
2087  aRectFnSet.SetHeight( aFrm, nFrameHeight + nDist );
2088 
2089  if( IsVertical() && !IsVertLR() )
2090  {
2091  aFrm.Pos().AdjustX( -nDist );
2092  }
2093  }
2094 
2095  if ( GetNext() )
2096  {
2097  GetNext()->InvalidatePos();
2098  }
2099  // #i28701# - Due to the new object positioning the
2100  // frame on the next page/column can flow backward (e.g. it was moved forward
2101  // due to the positioning of its objects ). Thus, invalivate this next frame,
2102  // if document compatibility option 'Consider wrapping style influence on
2103  // object positioning' is ON.
2104  else if ( GetUpper()->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) )
2105  {
2107  }
2108  }
2109  return 0;
2110  }
2111 
2112  SwTwips nReal = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea());
2113  SwFrame *pFrame = GetUpper()->Lower();
2114  while( pFrame && nReal > 0 )
2115  { nReal -= aRectFnSet.GetHeight(pFrame->getFrameArea());
2116  pFrame = pFrame->GetNext();
2117  }
2118 
2119  if ( !bTst )
2120  {
2121  //Contents are always resized to the wished value.
2122  long nOld = aRectFnSet.GetHeight(getFrameArea());
2123 
2124  {
2126 
2127  aRectFnSet.SetHeight( aFrm, nOld + nDist );
2128 
2129  if( IsVertical()&& !IsVertLR() )
2130  {
2131  aFrm.Pos().AdjustX( -nDist );
2132  }
2133  }
2134 
2135  SwTabFrame *pTab = (nOld && IsInTab()) ? FindTabFrame() : nullptr;
2136  if (pTab)
2137  {
2138  if ( pTab->GetTable()->GetHTMLTableLayout() &&
2139  !pTab->IsJoinLocked() &&
2140  !pTab->GetFormat()->GetDoc()->GetDocShell()->IsReadOnly() )
2141  {
2142  pTab->InvalidatePos();
2143  pTab->SetResizeHTMLTable();
2144  }
2145  }
2146  }
2147 
2148  //Only grow Upper if necessary.
2149  if ( nReal < nDist )
2150  {
2151  if( GetUpper() )
2152  {
2153  if( bTst || !GetUpper()->IsFooterFrame() )
2154  nReal = GetUpper()->Grow( nDist - std::max<long>(nReal, 0),
2155  bTst, bInfo );
2156  else
2157  {
2158  nReal = 0;
2159  GetUpper()->InvalidateSize();
2160  }
2161  }
2162  else
2163  nReal = 0;
2164  }
2165  else
2166  nReal = nDist;
2167 
2168  // #i28701# - Due to the new object positioning the
2169  // frame on the next page/column can flow backward (e.g. it was moved forward
2170  // due to the positioning of its objects ). Thus, invalivate this next frame,
2171  // if document compatibility option 'Consider wrapping style influence on
2172  // object positioning' is ON.
2173  if ( !bTst )
2174  {
2175  if ( GetNext() )
2176  {
2177  GetNext()->InvalidatePos();
2178  }
2179  else if ( GetUpper()->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) )
2180  {
2182  }
2183  }
2184 
2185  return nReal;
2186 }
2187 
2188 SwTwips SwContentFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo )
2189 {
2190  SwRectFnSet aRectFnSet(this);
2191  OSL_ENSURE( nDist >= 0, "nDist < 0" );
2192  OSL_ENSURE( nDist <= aRectFnSet.GetHeight(getFrameArea()),
2193  "nDist > than current size." );
2194 
2195  if ( !bTst )
2196  {
2197  SwTwips nRstHeight;
2198  if( GetUpper() )
2199  nRstHeight = aRectFnSet.BottomDist( getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper()) );
2200  else
2201  nRstHeight = 0;
2202  if( nRstHeight < 0 )
2203  {
2204  SwTwips nNextHeight = 0;
2205  if( GetUpper()->IsSctFrame() && nDist > LONG_MAX/2 )
2206  {
2207  SwFrame *pNxt = GetNext();
2208  while( pNxt )
2209  {
2210  nNextHeight += aRectFnSet.GetHeight(pNxt->getFrameArea());
2211  pNxt = pNxt->GetNext();
2212  }
2213  }
2214  nRstHeight = nDist + nRstHeight - nNextHeight;
2215  }
2216  else
2217  {
2218  nRstHeight = nDist;
2219  }
2220 
2221  {
2223  aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) - nDist );
2224 
2225  if( IsVertical() && !IsVertLR() )
2226  {
2227  aFrm.Pos().AdjustX(nDist );
2228  }
2229  }
2230 
2231  nDist = nRstHeight;
2232  SwTabFrame *pTab = IsInTab() ? FindTabFrame() : nullptr;
2233  if (pTab)
2234  {
2235  if ( pTab->GetTable()->GetHTMLTableLayout() &&
2236  !pTab->IsJoinLocked() &&
2237  !pTab->GetFormat()->GetDoc()->GetDocShell()->IsReadOnly() )
2238  {
2239  pTab->InvalidatePos();
2240  pTab->SetResizeHTMLTable();
2241  }
2242  }
2243  }
2244 
2245  SwTwips nReal;
2246  if( GetUpper() && nDist > 0 )
2247  {
2248  if( bTst || !GetUpper()->IsFooterFrame() )
2249  nReal = GetUpper()->Shrink( nDist, bTst, bInfo );
2250  else
2251  {
2252  nReal = 0;
2253 
2254  // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you,
2255  // if there are any objects anchored inside your content, which
2256  // overlap with the shrinking frame.
2257  // This may lead to a footer frame that is too big, but this is better
2258  // than looping.
2259  // #109722# : The fix for #108745# was too strict.
2260 
2261  bool bInvalidate = true;
2262  const SwRect aRect( getFrameArea() );
2263  const SwPageFrame* pPage = FindPageFrame();
2264  const SwSortedObjs* pSorted = pPage ? pPage->GetSortedObjs() : nullptr;
2265  if( pSorted )
2266  {
2267  for (SwAnchoredObject* pAnchoredObj : *pSorted)
2268  {
2269  const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );
2270 
2271  if( aBound.Left() > aRect.Right() )
2272  continue;
2273 
2274  if( aBound.IsOver( aRect ) )
2275  {
2276  const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat();
2277  if( css::text::WrapTextMode_THROUGH != rFormat.GetSurround().GetSurround() )
2278  {
2279  const SwFrame* pAnchor = pAnchoredObj->GetAnchorFrame();
2280  if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() )
2281  {
2282  bInvalidate = false;
2283  break;
2284  }
2285  }
2286  }
2287  }
2288  }
2289 
2290  if ( bInvalidate )
2291  GetUpper()->InvalidateSize();
2292  }
2293  }
2294  else
2295  nReal = 0;
2296 
2297  if ( !bTst )
2298  {
2299  //The position of the next Frame changes for sure.
2301 
2302  //If I don't have a successor I have to do the retouch by myself.
2303  if ( !GetNext() )
2304  SetRetouche();
2305  }
2306  return nReal;
2307 }
2308 
2309 void SwContentFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
2310 {
2311  sal_uInt8 nInvFlags = 0;
2312 
2313  if( pNew && RES_ATTRSET_CHG == pNew->Which() && pOld )
2314  {
2315  SfxItemIter aNIter( *static_cast<const SwAttrSetChg*>(pNew)->GetChgSet() );
2316  SfxItemIter aOIter( *static_cast<const SwAttrSetChg*>(pOld)->GetChgSet() );
2317  const SfxPoolItem* pNItem = aNIter.GetCurItem();
2318  const SfxPoolItem* pOItem = aOIter.GetCurItem();
2319  SwAttrSetChg aOldSet( *static_cast<const SwAttrSetChg*>(pOld) );
2320  SwAttrSetChg aNewSet( *static_cast<const SwAttrSetChg*>(pNew) );
2321  do
2322  {
2323  UpdateAttr_(pOItem, pNItem, nInvFlags, &aOldSet, &aNewSet);
2324  pNItem = aNIter.NextItem();
2325  pOItem = aOIter.NextItem();
2326  } while (pNItem);
2327  if ( aOldSet.Count() || aNewSet.Count() )
2328  SwFrame::Modify( &aOldSet, &aNewSet );
2329  }
2330  else
2331  UpdateAttr_( pOld, pNew, nInvFlags );
2332 
2333  if ( nInvFlags == 0 )
2334  return;
2335 
2336  SwPageFrame *pPage = FindPageFrame();
2337  InvalidatePage( pPage );
2338  if ( nInvFlags & 0x01 )
2339  SetCompletePaint();
2340  if ( nInvFlags & 0x02 )
2341  InvalidatePos_();
2342  if ( nInvFlags & 0x04 )
2343  InvalidateSize_();
2344  if ( nInvFlags & 0x88 )
2345  {
2346  if( IsInSct() && !GetPrev() )
2347  {
2348  SwSectionFrame *pSect = FindSctFrame();
2349  if( pSect->ContainsAny() == this )
2350  {
2351  pSect->InvalidatePrt_();
2352  pSect->InvalidatePage( pPage );
2353  }
2354  }
2355  InvalidatePrt_();
2356  }
2357  SwFrame* pNextFrame = GetIndNext();
2358  if ( pNextFrame && nInvFlags & 0x10)
2359  {
2360  pNextFrame->InvalidatePrt_();
2361  pNextFrame->InvalidatePage( pPage );
2362  }
2363  if ( pNextFrame && nInvFlags & 0x80 )
2364  {
2365  pNextFrame->SetCompletePaint();
2366  }
2367  if ( nInvFlags & 0x20 )
2368  {
2369  SwFrame* pPrevFrame = GetPrev();
2370  if ( pPrevFrame )
2371  {
2372  pPrevFrame->InvalidatePrt_();
2373  pPrevFrame->InvalidatePage( pPage );
2374  }
2375  }
2376  if ( nInvFlags & 0x40 )
2378 
2379 }
2380 
2381 void SwContentFrame::UpdateAttr_( const SfxPoolItem* pOld, const SfxPoolItem* pNew,
2382  sal_uInt8 &rInvFlags,
2383  SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
2384 {
2385  bool bClear = true;
2386  sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
2387  switch ( nWhich )
2388  {
2389  case RES_FMT_CHG:
2390  rInvFlags = 0xFF;
2391  [[fallthrough]];
2392 
2393  case RES_PAGEDESC: //attribute changes (on/off)
2394  if ( IsInDocBody() && !IsInTab() )
2395  {
2396  rInvFlags |= 0x02;
2397  SwPageFrame *pPage = FindPageFrame();
2398  if ( !GetPrev() )
2399  CheckPageDescs( pPage );
2400  if (GetPageDescItem().GetNumOffset())
2401  static_cast<SwRootFrame*>(pPage->GetUpper())->SetVirtPageNum( true );
2402  SwDocPosUpdate aMsgHint( pPage->getFrameArea().Top() );
2403  pPage->GetFormat()->GetDoc()->getIDocumentFieldsAccess().UpdatePageFields( &aMsgHint );
2404  }
2405  break;
2406 
2407  case RES_UL_SPACE:
2408  {
2409  // OD 2004-02-18 #106629# - correction
2410  // Invalidation of the printing area of next frame, not only
2411  // for footnote content.
2412  if ( !GetIndNext() )
2413  {
2414  SwFrame* pNxt = FindNext();
2415  if ( pNxt )
2416  {
2417  SwPageFrame* pPg = pNxt->FindPageFrame();
2418  pNxt->InvalidatePage( pPg );
2419  pNxt->InvalidatePrt_();
2420  if( pNxt->IsSctFrame() )
2421  {
2422  SwFrame* pCnt = static_cast<SwSectionFrame*>(pNxt)->ContainsAny();
2423  if( pCnt )
2424  {
2425  pCnt->InvalidatePrt_();
2426  pCnt->InvalidatePage( pPg );
2427  }
2428  }
2429  pNxt->SetCompletePaint();
2430  }
2431  }
2432  // OD 2004-03-17 #i11860#
2433  if ( GetIndNext() &&
2434  !GetUpper()->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::USE_FORMER_OBJECT_POS) )
2435  {
2436  // OD 2004-07-01 #i28701# - use new method <InvalidateObjs(..)>
2438  }
2439  Prepare( PrepareHint::ULSpaceChanged ); //TextFrame has to correct line spacing.
2440  rInvFlags |= 0x80;
2441  [[fallthrough]];
2442  }
2443  case RES_LR_SPACE:
2444  case RES_BOX:
2445  case RES_SHADOW:
2447  SwFrame::Modify( pOld, pNew );
2448  rInvFlags |= 0x30;
2449  break;
2450 
2451  case RES_BREAK:
2452  {
2453  rInvFlags |= 0x42;
2457  {
2458  rInvFlags |= 0x1;
2459  SwFrame* pNxt = FindNext();
2460  if( pNxt )
2461  {
2462  SwPageFrame* pPg = pNxt->FindPageFrame();
2463  pNxt->InvalidatePage( pPg );
2464  pNxt->InvalidatePrt_();
2465  if( pNxt->IsSctFrame() )
2466  {
2467  SwFrame* pCnt = static_cast<SwSectionFrame*>(pNxt)->ContainsAny();
2468  if( pCnt )
2469  {
2470  pCnt->InvalidatePrt_();
2471  pCnt->InvalidatePage( pPg );
2472  }
2473  }
2474  pNxt->SetCompletePaint();
2475  }
2476  }
2477  }
2478  break;
2479 
2480  // OD 2004-02-26 #i25029#
2482  {
2483  rInvFlags |= 0x01;
2484  if ( IsTextFrame() )
2485  {
2487  }
2488  if ( !GetIndNext() && IsInTab() && IsInSplitTableRow() )
2489  {
2491  }
2492  }
2493  break;
2494 
2495  case RES_PARATR_TABSTOP:
2496  case RES_CHRATR_SHADOWED:
2497  case RES_CHRATR_AUTOKERN:
2498  case RES_CHRATR_UNDERLINE:
2499  case RES_CHRATR_OVERLINE:
2500  case RES_CHRATR_KERNING:
2501  case RES_CHRATR_FONT:
2502  case RES_CHRATR_FONTSIZE:
2503  case RES_CHRATR_ESCAPEMENT:
2504  case RES_CHRATR_CONTOUR:
2505  case RES_PARATR_NUMRULE:
2506  rInvFlags |= 0x01;
2507  break;
2508 
2509  case RES_FRM_SIZE:
2510  rInvFlags |= 0x01;
2511  [[fallthrough]];
2512 
2513  default:
2514  bClear = false;
2515  }
2516  if ( bClear )
2517  {
2518  if ( pOldSet || pNewSet )
2519  {
2520  if ( pOldSet )
2521  pOldSet->ClearItem( nWhich );
2522  if ( pNewSet )
2523  pNewSet->ClearItem( nWhich );
2524  }
2525  else
2526  SwFrame::Modify( pOld, pNew );
2527  }
2528 }
2529 
2531  : SwFrame(pFormat, pSib)
2532  , m_pLower(nullptr)
2533 {
2534  const SwFormatFrameSize &rFormatSize = pFormat->GetFrameSize();
2535  if ( rFormatSize.GetHeightSizeType() == SwFrameSize::Fixed )
2536  mbFixSize = true;
2537 }
2538 
2539 // #i28701#
2540 
2542 {
2543  const SwFrame* pCnt = Lower();
2544  if (!pCnt)
2545  return 0;
2546 
2547  SwRectFnSet aRectFnSet(this);
2548  SwTwips nRet = 0;
2549  if( pCnt->IsColumnFrame() || pCnt->IsCellFrame() )
2550  {
2551  do
2552  {
2553  SwTwips nTmp = static_cast<const SwLayoutFrame*>(pCnt)->InnerHeight();
2554  if( pCnt->isFramePrintAreaValid() )
2555  nTmp += aRectFnSet.GetHeight(pCnt->getFrameArea()) -
2556  aRectFnSet.GetHeight(pCnt->getFramePrintArea());
2557  if( nRet < nTmp )
2558  nRet = nTmp;
2559  pCnt = pCnt->GetNext();
2560  } while ( pCnt );
2561  }
2562  else
2563  {
2564  do
2565  {
2566  nRet += aRectFnSet.GetHeight(pCnt->getFrameArea());
2567  if( pCnt->IsContentFrame() && static_cast<const SwTextFrame*>(pCnt)->IsUndersized() )
2568  nRet += static_cast<const SwTextFrame*>(pCnt)->GetParHeight() -
2569  aRectFnSet.GetHeight(pCnt->getFramePrintArea());
2570  if( pCnt->IsLayoutFrame() && !pCnt->IsTabFrame() )
2571  nRet += static_cast<const SwLayoutFrame*>(pCnt)->InnerHeight() -
2572  aRectFnSet.GetHeight(pCnt->getFramePrintArea());
2573  pCnt = pCnt->GetNext();
2574  } while( pCnt );
2575 
2576  }
2577  return nRet;
2578 }
2579 
2580 SwTwips SwLayoutFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo )
2581 {
2582  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
2583  const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2585  if (bBrowse)
2586  nTmpType |= SwFrameType::Body;
2587  if( !(GetType() & nTmpType) && HasFixSize() )
2588  return 0;
2589 
2590  SwRectFnSet aRectFnSet(this);
2591  const SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
2592  const SwTwips nFramePos = getFrameArea().Pos().X();
2593 
2594  if ( nFrameHeight > 0 && nDist > (LONG_MAX - nFrameHeight) )
2595  nDist = LONG_MAX - nFrameHeight;
2596 
2597  SwTwips nMin = 0;
2598  if ( GetUpper() && !IsCellFrame() )
2599  {
2600  SwFrame *pFrame = GetUpper()->Lower();
2601  while( pFrame )
2602  { nMin += aRectFnSet.GetHeight(pFrame->getFrameArea());
2603  pFrame = pFrame->GetNext();
2604  }
2605  nMin = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) - nMin;
2606  if ( nMin < 0 )
2607  nMin = 0;
2608  }
2609 
2610  SwRect aOldFrame( getFrameArea() );
2611  bool bMoveAccFrame = false;
2612 
2613  bool bChgPos = IsVertical();
2614  if ( !bTst )
2615  {
2617  aRectFnSet.SetHeight( aFrm, nFrameHeight + nDist );
2618 
2619  if( bChgPos && !IsVertLR() )
2620  {
2621  aFrm.Pos().AdjustX( -nDist );
2622  }
2623 
2624  bMoveAccFrame = true;
2625  }
2626 
2627  SwTwips nReal = nDist - nMin;
2628  if ( nReal > 0 )
2629  {
2630  if ( GetUpper() )
2631  { // AdjustNeighbourhood now only for the columns (but not in frames)
2633  static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment()
2635  if( SwNeighbourAdjust::OnlyAdjust == nAdjust )
2636  nReal = AdjustNeighbourhood( nReal, bTst );
2637  else
2638  {
2639  if( SwNeighbourAdjust::AdjustGrow == nAdjust )
2640  nReal += AdjustNeighbourhood( nReal, bTst );
2641 
2642  SwTwips nGrow = 0;
2643  if( 0 < nReal )
2644  {
2645  SwFrame* pToGrow = GetUpper();
2646  // NEW TABLES
2647  // A cell with a row span of > 1 is allowed to grow the
2648  // line containing the end of the row span if it is
2649  // located in the same table frame:
2650  const SwCellFrame* pThisCell = dynamic_cast<const SwCellFrame*>(this);
2651  if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2652  {
2653  SwCellFrame& rEndCell = const_cast<SwCellFrame&>(pThisCell->FindStartEndOfRowSpanCell( false ));
2654  if ( -1 == rEndCell.GetTabBox()->getRowSpan() )
2655  pToGrow = rEndCell.GetUpper();
2656  else
2657  pToGrow = nullptr;
2658  }
2659 
2660  nGrow = pToGrow ? pToGrow->Grow( nReal, bTst, bInfo ) : 0;
2661  }
2662 
2663  if( SwNeighbourAdjust::GrowAdjust == nAdjust && nGrow < nReal )
2664  nReal = o3tl::saturating_add(nReal, AdjustNeighbourhood( nReal - nGrow, bTst ));
2665 
2666  if ( IsFootnoteFrame() && (nGrow != nReal) && GetNext() )
2667  {
2668  //Footnotes can replace their successor.
2669  SwTwips nSpace = bTst ? 0 : -nDist;
2670  const SwFrame *pFrame = GetUpper()->Lower();
2671  do
2672  { nSpace += aRectFnSet.GetHeight(pFrame->getFrameArea());
2673  pFrame = pFrame->GetNext();
2674  } while ( pFrame != GetNext() );
2675  nSpace = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) -nSpace;
2676  if ( nSpace < 0 )
2677  nSpace = 0;
2678  nSpace += nGrow;
2679  if ( nReal > nSpace )
2680  nReal = nSpace;
2681  if ( nReal && !bTst )
2682  static_cast<SwFootnoteFrame*>(this)->InvalidateNxtFootnoteCnts( FindPageFrame() );
2683  }
2684  else
2685  nReal = nGrow;
2686  }
2687  }
2688  else
2689  nReal = 0;
2690 
2691  nReal += nMin;
2692  }
2693  else
2694  nReal = nDist;
2695 
2696  if ( !bTst )
2697  {
2698  if( nReal != nDist &&
2699  // NEW TABLES
2700  ( !IsCellFrame() || static_cast<SwCellFrame*>(this)->GetLayoutRowSpan() > 1 ) )
2701  {
2703  aRectFnSet.SetHeight( aFrm, nFrameHeight + nReal );
2704 
2705  if( bChgPos && !IsVertLR() )
2706  {
2707  aFrm.Pos().setX( nFramePos - nReal );
2708  }
2709 
2710  bMoveAccFrame = true;
2711  }
2712 
2713  if ( nReal )
2714  {
2715  SwPageFrame *pPage = FindPageFrame();
2716  if ( GetNext() )
2717  {
2718  GetNext()->InvalidatePos_();
2719  if ( GetNext()->IsContentFrame() )
2720  GetNext()->InvalidatePage( pPage );
2721  }
2722  if ( !IsPageBodyFrame() )
2723  {
2724  InvalidateAll_();
2725  InvalidatePage( pPage );
2726  }
2728  NotifyLowerObjs();
2729 
2730  if( IsCellFrame() )
2731  InvaPercentLowers( nReal );
2732 
2733  std::unique_ptr<SvxBrushItem> aBack(GetFormat()->makeBackgroundBrushItem());
2734  const SvxGraphicPosition ePos = aBack ? aBack->GetGraphicPos() : GPOS_NONE;
2735  if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
2736  SetCompletePaint();
2737  }
2738  }
2739 
2740  if( bMoveAccFrame && IsAccessibleFrame() )
2741  {
2742  SwRootFrame *pRootFrame = getRootFrame();
2743  if( pRootFrame && pRootFrame->IsAnyShellAccessible() &&
2744  pRootFrame->GetCurrShell() )
2745  {
2746  pRootFrame->GetCurrShell()->Imp()->MoveAccessibleFrame( this, aOldFrame );
2747  }
2748  }
2749  return nReal;
2750 }
2751 
2752 SwTwips SwLayoutFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo )
2753 {
2754  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
2755  const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
2757  if (bBrowse)
2758  nTmpType |= SwFrameType::Body;
2759 
2760  if (pSh && pSh->GetViewOptions()->IsWhitespaceHidden())
2761  {
2762  if (IsBodyFrame())
2763  {
2764  // Whitespace is hidden and this body frame will not shrink, as it
2765  // has a fix size.
2766  // Invalidate the page frame size, so in case the reason for the
2767  // shrink was that there is more whitespace on this page, the size
2768  // without whitespace will be recalculated correctly.
2769  SwPageFrame* pPageFrame = FindPageFrame();
2770  pPageFrame->InvalidateSize();
2771  }
2772  }
2773 
2774  if( !(GetType() & nTmpType) && HasFixSize() )
2775  return 0;
2776 
2777  OSL_ENSURE( nDist >= 0, "nDist < 0" );
2778  SwRectFnSet aRectFnSet(this);
2779  SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
2780  if ( nDist > nFrameHeight )
2781  nDist = nFrameHeight;
2782 
2783  SwTwips nMin = 0;
2784  bool bChgPos = IsVertical();
2785  if ( Lower() )
2786  {
2787  if( !Lower()->IsNeighbourFrame() )
2788  { const SwFrame *pFrame = Lower();
2789  const long nTmp = aRectFnSet.GetHeight(getFramePrintArea());
2790  while( pFrame && nMin < nTmp )
2791  { nMin += aRectFnSet.GetHeight(pFrame->getFrameArea());
2792  pFrame = pFrame->GetNext();
2793  }
2794  }
2795  }
2796  SwTwips nReal = nDist;
2797  SwTwips nMinDiff = aRectFnSet.GetHeight(getFramePrintArea()) - nMin;
2798  if( nReal > nMinDiff )
2799  nReal = nMinDiff;
2800  if( nReal <= 0 )
2801  return nDist;
2802 
2803  SwRect aOldFrame( getFrameArea() );
2804  bool bMoveAccFrame = false;
2805 
2806  SwTwips nRealDist = nReal;
2807  if ( !bTst )
2808  {
2810  aRectFnSet.SetHeight( aFrm, nFrameHeight - nReal );
2811 
2812  if( bChgPos && !IsVertLR() )
2813  {
2814  aFrm.Pos().AdjustX(nReal );
2815  }
2816 
2817  bMoveAccFrame = true;
2818  }
2819 
2821  static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment()
2823 
2824  // AdjustNeighbourhood also in columns (but not in frames)
2825  if( SwNeighbourAdjust::OnlyAdjust == nAdjust )
2826  {
2827  if ( IsPageBodyFrame() && !bBrowse )
2828  nReal = nDist;
2829  else
2830  { nReal = AdjustNeighbourhood( -nReal, bTst );
2831  nReal *= -1;
2832  if ( !bTst && IsBodyFrame() && nReal < nRealDist )
2833  {
2835  aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) + nRealDist - nReal );
2836 
2837  if( bChgPos && !IsVertLR() )
2838  {
2839  aFrm.Pos().AdjustX(nRealDist - nReal );
2840  }
2841 
2842  OSL_ENSURE( !IsAccessibleFrame(), "bMoveAccFrame has to be set!" );
2843  }
2844  }
2845  }
2846  else if( IsColumnFrame() || IsColBodyFrame() )
2847  {
2848  SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo );
2849  if ( nTmp != nReal )
2850  {
2852  aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) + nReal - nTmp );
2853 
2854  if( bChgPos && !IsVertLR() )
2855  {
2856  aFrm.Pos().AdjustX(nTmp - nReal );
2857  }
2858 
2859  OSL_ENSURE( !IsAccessibleFrame(), "bMoveAccFrame has to be set!" );
2860  nReal = nTmp;
2861  }
2862  }
2863  else
2864  {
2865  SwTwips nShrink = nReal;
2866  SwFrame* pToShrink = GetUpper();
2867  const SwCellFrame* pThisCell = dynamic_cast<const SwCellFrame*>(this);
2868  // NEW TABLES
2869  if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
2870  {
2871  SwCellFrame& rEndCell = const_cast<SwCellFrame&>(pThisCell->FindStartEndOfRowSpanCell( false ));
2872  pToShrink = rEndCell.GetUpper();
2873  }
2874 
2875  nReal = pToShrink ? pToShrink->Shrink( nShrink, bTst, bInfo ) : 0;
2876  if( ( SwNeighbourAdjust::GrowAdjust == nAdjust || SwNeighbourAdjust::AdjustGrow == nAdjust )
2877  && nReal < nShrink )
2878  AdjustNeighbourhood( nReal - nShrink );
2879  }
2880 
2881  if( bMoveAccFrame && IsAccessibleFrame() )
2882  {
2883  SwRootFrame *pRootFrame = getRootFrame();
2884  if( pRootFrame && pRootFrame->IsAnyShellAccessible() &&
2885  pRootFrame->GetCurrShell() )
2886  {
2887  pRootFrame->GetCurrShell()->Imp()->MoveAccessibleFrame( this, aOldFrame );
2888  }
2889  }
2890  if ( !bTst && (IsCellFrame() || IsColumnFrame() ? nReal : nRealDist) )
2891  {
2892  SwPageFrame *pPage = FindPageFrame();
2893  if ( GetNext() )
2894  {
2895  GetNext()->InvalidatePos_();
2896  if ( GetNext()->IsContentFrame() )
2897  GetNext()->InvalidatePage( pPage );
2898  if ( IsTabFrame() )
2899  static_cast<SwTabFrame*>(this)->SetComplete();
2900  }
2901  else
2902  { if ( IsRetoucheFrame() )
2903  SetRetouche();
2904  if ( IsTabFrame() )
2905  {
2906  static_cast<SwTabFrame*>(this)->SetComplete();
2907  if ( Lower() ) // Can also be in the Join and be empty!
2909  }
2910  }
2911  if ( !IsBodyFrame() )
2912  {
2913  InvalidateAll_();
2914  InvalidatePage( pPage );
2915  bool bCompletePaint = true;
2916  const SwFrameFormat* pFormat = GetFormat();
2917  if (pFormat)
2918  {
2919  std::unique_ptr<SvxBrushItem> aBack(pFormat->makeBackgroundBrushItem());
2920  const SvxGraphicPosition ePos = aBack ? aBack->GetGraphicPos() : GPOS_NONE;
2921  if ( GPOS_NONE == ePos || GPOS_TILED == ePos )
2922  bCompletePaint = false;
2923  }
2924  if (bCompletePaint)
2925  SetCompletePaint();
2926  }
2927 
2929  NotifyLowerObjs();
2930 
2931  if( IsCellFrame() )
2932  InvaPercentLowers( nReal );
2933 
2934  SwContentFrame *pCnt;
2935  if( IsFootnoteFrame() && !static_cast<SwFootnoteFrame*>(this)->GetAttr()->GetFootnote().IsEndNote() &&
2936  ( GetFormat()->GetDoc()->GetFootnoteInfo().m_ePos != FTNPOS_CHAPTER ||
2937  ( IsInSct() && FindSctFrame()->IsFootnoteAtEnd() ) ) &&
2938  nullptr != (pCnt = static_cast<SwFootnoteFrame*>(this)->GetRefFromAttr() ) )
2939  {
2940  if ( pCnt->IsFollow() )
2941  { // If we are in another column/page than the frame with the
2942  // reference, we don't need to invalidate its master.
2943  SwFrame *pTmp = pCnt->FindFootnoteBossFrame(true) == FindFootnoteBossFrame(true)
2944  ? &pCnt->FindMaster()->GetFrame() : pCnt;
2946  pTmp->InvalidateSize();
2947  }
2948  else
2949  pCnt->InvalidatePos();
2950  }
2951  }
2952  return nReal;
2953 }
2954 
2961 void SwLayoutFrame::ChgLowersProp( const Size& rOldSize )
2962 {
2963  // no change of lower properties for root frame or if no lower exists.
2964  if ( IsRootFrame() || !Lower() )
2965  return;
2966 
2967  // declare and init <SwFrame* pLowerFrame> with first lower
2968  SwFrame *pLowerFrame = Lower();
2969 
2970  // declare and init const booleans <bHeightChgd> and <bWidthChg>
2971  const bool bHeightChgd = rOldSize.Height() != getFramePrintArea().Height();
2972  const bool bWidthChgd = rOldSize.Width() != getFramePrintArea().Width();
2973 
2974  SwRectFnSet aRectFnSet(this);
2975 
2976  // This shortcut basically tries to handle only lower frames that
2977  // are affected by the size change. Otherwise much more lower frames
2978  // are invalidated.
2979  if ( !( aRectFnSet.IsVert() ? bHeightChgd : bWidthChgd ) &&
2980  ! Lower()->IsColumnFrame() &&
2981  ( ( IsBodyFrame() && IsInDocBody() && ( !IsInSct() || !FindSctFrame()->IsColLocked() ) ) ||
2982  // #i10826# Section frames without columns should not
2983  // invalidate all lowers!
2984  IsSctFrame() ) )
2985  {
2986  // Determine page frame the body frame resp. the section frame belongs to.
2987  SwPageFrame *pPage = FindPageFrame();
2988  // Determine last lower by traveling through them using <GetNext()>.
2989  // During travel check each section frame, if it will be sized to
2990  // maximum. If Yes, invalidate size of section frame and set
2991  // corresponding flags at the page.
2992  do
2993  {
2994  if( pLowerFrame->IsSctFrame() && static_cast<SwSectionFrame*>(pLowerFrame)->ToMaximize_() )
2995  {
2996  pLowerFrame->InvalidateSize_();
2997  pLowerFrame->InvalidatePage( pPage );
2998  }
2999  if( pLowerFrame->GetNext() )
3000  pLowerFrame = pLowerFrame->GetNext();
3001  else
3002  break;
3003  } while( true );
3004  // If found last lower is a section frame containing no section
3005  // (section frame isn't valid and will be deleted in the future),
3006  // travel backwards.
3007  while( pLowerFrame->IsSctFrame() && !static_cast<SwSectionFrame*>(pLowerFrame)->GetSection() &&
3008  pLowerFrame->GetPrev() )
3009  pLowerFrame = pLowerFrame->GetPrev();
3010  // If found last lower is a section frame, set <pLowerFrame> to its last
3011  // content, if the section frame is valid and is not sized to maximum.
3012  // Otherwise set <pLowerFrame> to NULL - In this case body frame only
3013  // contains invalid section frames.
3014  if( pLowerFrame->IsSctFrame() )
3015  pLowerFrame = static_cast<SwSectionFrame*>(pLowerFrame)->GetSection() &&
3016  !static_cast<SwSectionFrame*>(pLowerFrame)->ToMaximize( false ) ?
3017  static_cast<SwSectionFrame*>(pLowerFrame)->FindLastContent() : nullptr;
3018 
3019  // continue with found last lower, probably the last content of a section
3020  if ( pLowerFrame )
3021  {
3022  // If <pLowerFrame> is in a table frame, set <pLowerFrame> to this table
3023  // frame and continue.
3024  if ( pLowerFrame->IsInTab() )
3025  {
3026  // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrame> to
3027  // its table frame - check, if the table frame is also a lower
3028  // of the body frame, in order to assure that <pLowerFrame> is not
3029  // set to a frame, which is an *upper* of the body frame.
3030  SwFrame* pTableFrame = pLowerFrame->FindTabFrame();
3031  if ( IsAnLower( pTableFrame ) )
3032  {
3033  pLowerFrame = pTableFrame;
3034  }
3035  }
3036  // Check, if variable size of body frame resp. section frame has grown
3037  // OD 28.10.2002 #97265# - correct check, if variable size has grown.
3038  SwTwips nOldHeight = aRectFnSet.IsVert() ? rOldSize.Width() : rOldSize.Height();
3039  if( nOldHeight < aRectFnSet.GetHeight(getFramePrintArea()) )
3040  {
3041  // If variable size of body|section frame has grown, only found
3042  // last lower and the position of the its next have to be invalidated.
3043  pLowerFrame->InvalidateAll_();
3044  pLowerFrame->InvalidatePage( pPage );
3045  if( !pLowerFrame->IsFlowFrame() ||
3046  !SwFlowFrame::CastFlowFrame( pLowerFrame )->HasFollow() )
3047  pLowerFrame->InvalidateNextPos( true );
3048  if ( pLowerFrame->IsTextFrame() )
3049  static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::AdjustSizeWithoutFormatting );
3050  }
3051  else
3052  {
3053  // variable size of body|section frame has shrunk. Thus,
3054  // invalidate all lowers not matching the new body|section size
3055  // and the dedicated new last lower.
3056  if( aRectFnSet.IsVert() )
3057  {
3058  SwTwips nBot = getFrameArea().Left() + getFramePrintArea().Left();
3059  while ( pLowerFrame && pLowerFrame->GetPrev() && pLowerFrame->getFrameArea().Left() < nBot )
3060  {
3061  pLowerFrame->InvalidateAll_();
3062  pLowerFrame->InvalidatePage( pPage );
3063  pLowerFrame = pLowerFrame->GetPrev();
3064  }
3065  }
3066  else
3067  {
3068  SwTwips nBot = getFrameArea().Top() + getFramePrintArea().Bottom();
3069  while ( pLowerFrame && pLowerFrame->GetPrev() && pLowerFrame->getFrameArea().Top() > nBot )
3070  {
3071  pLowerFrame->InvalidateAll_();
3072  pLowerFrame->InvalidatePage( pPage );
3073  pLowerFrame = pLowerFrame->GetPrev();
3074  }
3075  }
3076  if ( pLowerFrame )
3077  {
3078  pLowerFrame->InvalidateSize_();
3079  pLowerFrame->InvalidatePage( pPage );
3080  if ( pLowerFrame->IsTextFrame() )
3081  static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::AdjustSizeWithoutFormatting );
3082  }
3083  }
3084  // #i41694# - improvement by removing duplicates
3085  if ( pLowerFrame )
3086  {
3087  if ( pLowerFrame->IsInSct() )
3088  {
3089  // #i41694# - follow-up of issue #i10826#
3090  // No invalidation of section frame, if it's the this.
3091  SwFrame* pSectFrame = pLowerFrame->FindSctFrame();
3092  if( pSectFrame != this && IsAnLower( pSectFrame ) )
3093  {
3094  pSectFrame->InvalidateSize_();
3095  pSectFrame->InvalidatePage( pPage );
3096  }
3097  }
3098  }
3099  }
3100  return;
3101  } // end of { special case }
3102 
3103  // Invalidate page for content only once.
3104  bool bInvaPageForContent = true;
3105 
3106  // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame
3107  // adjustment, if fixed/variable size has changed.
3108  bool bFixChgd, bVarChgd;
3109  if( aRectFnSet.IsVert() == pLowerFrame->IsNeighbourFrame() )
3110  {
3111  bFixChgd = bWidthChgd;
3112  bVarChgd = bHeightChgd;
3113  }
3114  else
3115  {
3116  bFixChgd = bHeightChgd;
3117  bVarChgd = bWidthChgd;
3118  }
3119 
3120  // Declare const unsigned short <nFixWidth> and init it this frame types
3121  // which has fixed width in vertical respectively horizontal layout.
3122  // In vertical layout these are neighbour frames (cell and column frames),
3123  // header frames and footer frames.
3124  // In horizontal layout these are all frames, which aren't neighbour frames.
3125  const SwFrameType nFixWidth = aRectFnSet.IsVert() ? (FRM_NEIGHBOUR | FRM_HEADFOOT)
3127 
3128  // Declare const unsigned short <nFixHeight> and init it this frame types
3129  // which has fixed height in vertical respectively horizontal layout.
3130  // In vertical layout these are all frames, which aren't neighbour frames,
3131  // header frames, footer frames, body frames or foot note container frames.
3132  // In horizontal layout these are neighbour frames.
3133  const SwFrameType nFixHeight = aRectFnSet.IsVert() ? ~SwFrameType(FRM_NEIGHBOUR | FRM_HEADFOOT | FRM_BODYFTNC)
3134  : FRM_NEIGHBOUR;
3135 
3136  // Travel through all lowers using <GetNext()>
3137  while ( pLowerFrame )
3138  {
3139  if ( pLowerFrame->IsTextFrame() )
3140  {
3141  // Text frames will only be invalidated - prepare invalidation
3142  if ( bFixChgd )
3143  static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::FixSizeChanged );
3144  if ( bVarChgd )
3145  static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::AdjustSizeWithoutFormatting );
3146  }
3147  else
3148  {
3149  // If lower isn't a table, row, cell or section frame, adjust its
3150  // frame size.
3151  const SwFrameType nLowerType = pLowerFrame->GetType();
3153  {
3154  if ( bWidthChgd )
3155  {
3156  if( nLowerType & nFixWidth )
3157  {
3158  // Considering previous conditions:
3159  // In vertical layout set width of column, header and
3160  // footer frames to its upper width.
3161  // In horizontal layout set width of header, footer,
3162  // foot note container, foot note, body and no-text
3163  // frames to its upper width.
3165  aFrm.Width( getFramePrintArea().Width() );
3166  }
3167  else if( rOldSize.Width() && !pLowerFrame->IsFootnoteFrame() )
3168  {
3169  // Adjust frame width proportional, if lower isn't a
3170  // foot note frame and condition <nLowerType & nFixWidth>
3171  // isn't true.
3172  // Considering previous conditions:
3173  // In vertical layout these are foot note container,
3174  // body and no-text frames.
3175  // In horizontal layout these are column and no-text frames.
3176  // OD 24.10.2002 #97265# - <double> calculation
3177  // Perform <double> calculation of new width, if
3178  // one of the coefficients is greater than 50000
3179  SwTwips nNewWidth;
3180  if ( (pLowerFrame->getFrameArea().Width() > 50000) ||
3181  (getFramePrintArea().Width() > 50000) )
3182  {
3183  double nNewWidthTmp =
3184  ( double(pLowerFrame->getFrameArea().Width())
3185  * double(getFramePrintArea().Width()) )
3186  / double(rOldSize.Width());
3187  nNewWidth = SwTwips(nNewWidthTmp);
3188  }
3189  else
3190  {
3191  nNewWidth =
3192  (pLowerFrame->getFrameArea().Width() * getFramePrintArea().Width()) / rOldSize.Width();
3193  }
3194 
3196  aFrm.Width( nNewWidth );
3197  }
3198  }
3199  if ( bHeightChgd )
3200  {
3201  if( nLowerType & nFixHeight )
3202  {
3203  // Considering previous conditions:
3204  // In vertical layout set height of foot note and
3205  // no-text frames to its upper height.
3206  // In horizontal layout set height of column frames
3207  // to its upper height.
3209  aFrm.Height( getFramePrintArea().Height() );
3210  }
3211  // OD 01.10.2002 #102211#
3212  // add conditions <!pLowerFrame->IsHeaderFrame()> and
3213  // <!pLowerFrame->IsFooterFrame()> in order to avoid that
3214  // the <Grow> of header or footer are overwritten.
3215  // NOTE: Height of header/footer frame is determined by contents.
3216  else if ( rOldSize.Height() &&
3217  !pLowerFrame->IsFootnoteFrame() &&
3218  !pLowerFrame->IsHeaderFrame() &&
3219  !pLowerFrame->IsFooterFrame()
3220  )
3221  {
3222  // Adjust frame height proportional, if lower isn't a
3223  // foot note, a header or a footer frame and
3224  // condition <nLowerType & nFixHeight> isn't true.
3225  // Considering previous conditions:
3226  // In vertical layout these are column, foot note container,
3227  // body and no-text frames.
3228  // In horizontal layout these are column, foot note
3229  // container, body and no-text frames.
3230 
3231  // OD 29.10.2002 #97265# - special case for page lowers
3232  // The page lowers that have to be adjusted on page height
3233  // change are the body frame and the foot note container
3234  // frame.
3235  // In vertical layout the height of both is directly
3236  // adjusted to the page height change.
3237  // In horizontal layout the height of the body frame is
3238  // directly adjusted to the page height change and the
3239  // foot note frame height isn't touched, because its
3240  // determined by its content.
3241  // OD 31.03.2003 #108446# - apply special case for page
3242  // lowers - see description above - also for section columns.
3243  if ( IsPageFrame() ||
3244  ( IsColumnFrame() && IsInSct() )
3245  )
3246  {
3247  OSL_ENSURE( pLowerFrame->IsBodyFrame() || pLowerFrame->IsFootnoteContFrame(),
3248  "ChgLowersProp - only for body or foot note container" );
3249  if ( pLowerFrame->IsBodyFrame() || pLowerFrame->IsFootnoteContFrame() )
3250  {
3251  if ( IsVertical() || pLowerFrame->IsBodyFrame() )
3252  {
3253  SwTwips nNewHeight =
3254  pLowerFrame->getFrameArea().Height() +
3255  ( getFramePrintArea().Height() - rOldSize.Height() );
3256  if ( nNewHeight < 0)
3257  {
3258  // OD 01.04.2003 #108446# - adjust assertion condition and text
3259  OSL_ENSURE( !( IsPageFrame() &&
3260  (pLowerFrame->getFrameArea().Height()>0) &&
3261  (pLowerFrame->isFrameAreaDefinitionValid()) ),
3262  "ChgLowersProg - negative height for lower.");
3263  nNewHeight = 0;
3264  }
3265 
3267  aFrm.Height( nNewHeight );
3268  }
3269  }
3270  }
3271  else
3272  {
3273  SwTwips nNewHeight;
3274  // OD 24.10.2002 #97265# - <double> calculation
3275  // Perform <double> calculation of new height, if
3276  // one of the coefficients is greater than 50000
3277  if ( (pLowerFrame->getFrameArea().Height() > 50000) ||
3278  (getFramePrintArea().Height() > 50000) )
3279  {
3280  double nNewHeightTmp =
3281  ( double(pLowerFrame->getFrameArea().Height())
3282  * double(getFramePrintArea().Height()) )
3283  / double(rOldSize.Height());
3284  nNewHeight = SwTwips(nNewHeightTmp);
3285  }
3286  else
3287  {
3288  nNewHeight = ( pLowerFrame->getFrameArea().Height()
3289  * getFramePrintArea().Height() ) / rOldSize.Height();
3290  }
3291  if( !pLowerFrame->GetNext() )
3292  {
3293  SwTwips nSum = getFramePrintArea().Height();
3294  SwFrame* pTmp = Lower();
3295  while( pTmp->GetNext() )
3296  {
3297  if( !pTmp->IsFootnoteContFrame() || !pTmp->IsVertical() )
3298  nSum -= pTmp->getFrameArea().Height();
3299  pTmp = pTmp->GetNext();
3300  }
3301  if( nSum - nNewHeight == 1 &&
3302  nSum == pLowerFrame->getFrameArea().Height() )
3303  nNewHeight = nSum;
3304  }
3305 
3307  aFrm.Height( nNewHeight );
3308  }
3309  }
3310  }
3311  }
3312  } // end of else { NOT text frame }
3313 
3314  pLowerFrame->InvalidateAll_();
3315  if ( bInvaPageForContent && pLowerFrame->IsContentFrame() )
3316  {
3317  pLowerFrame->InvalidatePage();
3318  bInvaPageForContent = false;
3319  }
3320 
3321  if ( !pLowerFrame->GetNext() && pLowerFrame->IsRetoucheFrame() )
3322  {
3323  //If a growth took place and the subordinate elements can retouch
3324  //itself (currently Tabs, Sections and Content) we trigger it.
3325  if ( rOldSize.Height() < getFramePrintArea().SSize().Height() ||
3326  rOldSize.Width() < getFramePrintArea().SSize().Width() )
3327  pLowerFrame->SetRetouche();
3328  }
3329  pLowerFrame = pLowerFrame->GetNext();
3330  }
3331 
3332  // Finally adjust the columns if width is set to auto
3333  // Possible optimization: execute this code earlier in this function and
3334  // return???
3335  if ( !(( (aRectFnSet.IsVert() && bHeightChgd) || (! aRectFnSet.IsVert() && bWidthChgd) ) &&
3336  Lower()->IsColumnFrame()) )
3337  return;
3338 
3339  // get column attribute
3340  const SwFormatCol* pColAttr = nullptr;
3341  if ( IsPageBodyFrame() )
3342  {
3343  OSL_ENSURE( GetUpper()->IsPageFrame(), "Upper is not page frame" );
3344  pColAttr = &GetUpper()->GetFormat()->GetCol();
3345  }
3346  else
3347  {
3348  OSL_ENSURE( IsFlyFrame() || IsSctFrame(), "Columns not in fly or section" );
3349  pColAttr = &GetFormat()->GetCol();
3350  }
3351 
3352  if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 )
3353  AdjustColumns( pColAttr, false );
3354 }
3355 
3360 void SwLayoutFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorderAttrs *pAttrs )
3361 {
3362  OSL_ENSURE( pAttrs, "LayoutFrame::Format, pAttrs is 0." );
3363 
3365  return;
3366 
3367  bool bHideWhitespace = false;
3368  if (IsPageFrame())
3369  {
3370  SwViewShell* pShell = getRootFrame()->GetCurrShell();
3371  if (pShell && pShell->GetViewOptions()->IsWhitespaceHidden())
3372  {
3373  // This is needed so that no space is reserved for the margin on
3374  // the last page of the document. Other pages would have no margin
3375  // set even without this, as their frame height is the content
3376  // height already.
3377  bHideWhitespace = true;
3378  }
3379  }
3380 
3381  const sal_uInt16 nLeft = static_cast<sal_uInt16>(pAttrs->CalcLeft(this));
3382  const sal_uInt16 nUpper = bHideWhitespace ? 0 : pAttrs->CalcTop();
3383 
3384  const sal_uInt16 nRight = static_cast<sal_uInt16>(pAttrs->CalcRight(this));
3385  const sal_uInt16 nLower = bHideWhitespace ? 0 : pAttrs->CalcBottom();
3386 
3387  const bool bVert = IsVertical() && !IsPageFrame();
3388  SwRectFn fnRect = bVert ? ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
3389  if ( !isFramePrintAreaValid() )
3390  {
3391  setFramePrintAreaValid(true);
3392  (this->*fnRect->fnSetXMargins)( nLeft, nRight );
3393  (this->*fnRect->fnSetYMargins)( nUpper, nLower );
3394  }
3395 
3396  if ( isFrameAreaSizeValid() )
3397  return;
3398 
3399  if ( !HasFixSize() )
3400  {
3401  const SwTwips nBorder = nUpper + nLower;
3402  const SwFormatFrameSize &rSz = GetFormat()->GetFrameSize();
3403  SwTwips nMinHeight = rSz.GetHeightSizeType() == SwFrameSize::Minimum ? rSz.GetHeight() : 0;
3404  do
3405  {
3406  setFrameAreaSizeValid(true);
3407 
3408  //The size in VarSize is calculated using the content plus the
3409  // borders.
3410  SwTwips nRemaining = 0;
3411  SwFrame *pFrame = Lower();
3412  while ( pFrame )
3413  { nRemaining += (pFrame->getFrameArea().*fnRect->fnGetHeight)();
3414  if( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsUndersized() )
3415  // This TextFrame would like to be a bit bigger
3416  nRemaining += static_cast<SwTextFrame*>(pFrame)->GetParHeight()
3417  - (pFrame->getFramePrintArea().*fnRect->fnGetHeight)();
3418  else if( pFrame->IsSctFrame() && static_cast<SwSectionFrame*>(pFrame)->IsUndersized() )
3419  nRemaining += static_cast<SwSectionFrame*>(pFrame)->Undersize();
3420  pFrame = pFrame->GetNext();
3421  }
3422  nRemaining += nBorder;
3423  nRemaining = std::max( nRemaining, nMinHeight );
3424  const SwTwips nDiff = nRemaining-(getFrameArea().*fnRect->fnGetHeight)();
3425  const long nOldLeft = (getFrameArea().*fnRect->fnGetLeft)();
3426  const long nOldTop = (getFrameArea().*fnRect->fnGetTop)();
3427  if ( nDiff )
3428  {
3429  if ( nDiff > 0 )
3430  Grow( nDiff );
3431  else
3432  Shrink( -nDiff );
3433  //Updates the positions using the fast channel.
3434  MakePos();
3435  }
3436  //Don't exceed the bottom edge of the Upper.
3437  if ( GetUpper() && (getFrameArea().*fnRect->fnGetHeight)() )
3438  {
3439  const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
3440  if( (this->*fnRect->fnSetLimit)( nLimit ) &&
3441  nOldLeft == (getFrameArea().*fnRect->fnGetLeft)() &&
3442  nOldTop == (getFrameArea().*fnRect->fnGetTop)() )
3443  {
3444  setFrameAreaSizeValid(true);
3445  setFramePrintAreaValid(true);
3446  }
3447  }
3448  } while ( !isFrameAreaSizeValid() );
3449  }
3450  else if (GetType() & FRM_HEADFOOT)
3451  {
3452  do
3453  { if ( getFrameArea().Height() != pAttrs->GetSize().Height() )
3454  {
3455  ChgSize( Size( getFrameArea().Width(), pAttrs->GetSize().Height()));
3456  }
3457 
3458  setFrameAreaSizeValid(true);
3459  MakePos();
3460  } while ( !isFrameAreaSizeValid() );
3461  }
3462  else
3463  {
3464  setFrameAreaSizeValid(true);
3465  }
3466 
3467  // While updating the size, PrtArea might be invalidated.
3468  if (!isFramePrintAreaValid())
3469  {
3470  setFramePrintAreaValid(true);
3471  (this->*fnRect->fnSetXMargins)(nLeft, nRight);
3472  (this->*fnRect->fnSetYMargins)(nUpper, nLower);
3473  }
3474 }
3475 
3476 static void InvaPercentFlys( SwFrame *pFrame, SwTwips nDiff )
3477 {
3478  OSL_ENSURE( pFrame->GetDrawObjs(), "Can't find any Objects" );
3479  for (SwAnchoredObject* pAnchoredObj : *pFrame->GetDrawObjs())
3480  {
3481  if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr )
3482  {
3483  SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pAnchoredObj);
3484  const SwFormatFrameSize &rSz = pFly->GetFormat()->GetFrameSize();
3485  if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3486  {
3487  bool bNotify = true;
3488  // If we've a fly with more than 90% relative height...
3489  if( rSz.GetHeightPercent() > 90 && pFly->GetAnchorFrame() &&
3490  rSz.GetHeightPercent() != SwFormatFrameSize::SYNCED && nDiff )
3491  {
3492  const SwFrame *pRel = pFly->IsFlyLayFrame() ? pFly->GetAnchorFrame():
3493  pFly->GetAnchorFrame()->GetUpper();
3494  // ... and we have already more than 90% height and we
3495  // not allow the text to go through...
3496  // then a notification could cause an endless loop, e.g.
3497  // 100% height and no text wrap inside a cell of a table.
3498  if( pFly->getFrameArea().Height()*10 >
3499  ( nDiff + pRel->getFramePrintArea().Height() )*9 &&
3500  pFly->GetFormat()->GetSurround().GetSurround() !=
3501  css::text::WrapTextMode_THROUGH )
3502  bNotify = false;
3503  }
3504  if( bNotify )
3505  pFly->InvalidateSize();
3506  }
3507  }
3508  }
3509 }
3510 
3512 {
3513  if ( GetDrawObjs() )
3514  ::InvaPercentFlys( this, nDiff );
3515 
3516  SwFrame *pFrame = ContainsContent();
3517  if ( !pFrame )
3518  return;
3519 
3520  do
3521  {
3522  if ( pFrame->IsInTab() && !IsTabFrame() )
3523  {
3524  SwFrame *pTmp = pFrame->FindTabFrame();
3525  OSL_ENSURE( pTmp, "Where's my TabFrame?" );
3526  if( IsAnLower( pTmp ) )
3527  pFrame = pTmp;
3528  }
3529 
3530  if ( pFrame->IsTabFrame() )
3531  {
3532  const SwFormatFrameSize &rSz = static_cast<SwLayoutFrame*>(pFrame)->GetFormat()->GetFrameSize();
3533  if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
3534  pFrame->InvalidatePrt();
3535  }
3536  else if ( pFrame->GetDrawObjs() )
3537  ::InvaPercentFlys( pFrame, nDiff );
3538  pFrame = pFrame->FindNextCnt();
3539  } while ( pFrame && IsAnLower( pFrame ) ) ;
3540 }
3541 
3543 {
3544  long nRet = rSz.GetWidth(),
3545  nPercent = rSz.GetWidthPercent();
3546 
3547  if ( nPercent )
3548  {
3549  const SwFrame *pRel = GetUpper();
3550  long nRel = LONG_MAX;
3551  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
3552  const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
3553  if( pRel->IsPageBodyFrame() && pSh && bBrowseMode && pSh->VisArea().Width() )
3554  {
3555  nRel = pSh->GetBrowseWidth();
3556  long nDiff = nRel - pRel->getFramePrintArea().Width();
3557  if ( nDiff > 0 )
3558  nRel -= nDiff;
3559  }
3560  nRel = std::min( nRel, pRel->getFramePrintArea().Width() );
3561  nRet = nRel * nPercent / 100;
3562  }
3563  return nRet;
3564 }
3565 
3566 // Local helpers for SwLayoutFrame::FormatWidthCols()
3567 
3568 static long lcl_CalcMinColDiff( SwLayoutFrame *pLayFrame )
3569 {
3570  long nDiff = 0, nFirstDiff = 0;
3571  SwLayoutFrame *pCol = static_cast<SwLayoutFrame*>(pLayFrame->Lower());
3572  OSL_ENSURE( pCol, "Where's the columnframe?" );
3573  SwFrame *pFrame = pCol->Lower();
3574  do
3575  {
3576  if( pFrame && pFrame->IsBodyFrame() )
3577  pFrame = static_cast<SwBodyFrame*>(pFrame)->Lower();
3578  if ( pFrame && pFrame->IsTextFrame() )
3579  {
3580  const long nTmp = static_cast<SwTextFrame*>(pFrame)->FirstLineHeight();
3581  if ( nTmp != USHRT_MAX )
3582  {
3583  if ( pCol == pLayFrame->Lower() )
3584  nFirstDiff = nTmp;
3585  else
3586  nDiff = nDiff ? std::min( nDiff, nTmp ) : nTmp;
3587  }
3588  }
3589  //Skip empty columns!
3590  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3591  while ( pCol && nullptr == (pFrame = pCol->Lower()) )
3592  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3593 
3594  } while ( pFrame && pCol );
3595 
3596  return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240;
3597 }
3598 
3600 {
3601  SwFrame *pFrame = pLay->ContainsContent();
3602  while ( pFrame )
3603  {
3604  if ( pFrame->IsInTab() )
3605  pFrame = pFrame->FindTabFrame();
3606 
3607  if ( pFrame->GetDrawObjs() )
3608  {
3609  const size_t nCnt = pFrame->GetDrawObjs()->size();
3610  for ( size_t i = 0; i < nCnt; ++i )
3611  {
3612  SwAnchoredObject* pAnchoredObj = (*pFrame->GetDrawObjs())[i];
3613  if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr )
3614  {
3615  SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pAnchoredObj);
3616  if ( pFly->IsHeightClipped() &&
3617  ( !pFly->IsFlyFreeFrame() || pFly->GetPageFrame() ) )
3618  return true;
3619  }
3620  }
3621  }
3622  pFrame = pFrame->FindNextCnt();
3623  }
3624  return false;
3625 }
3626 
3628  const SwTwips nBorder, const SwTwips nMinHeight )
3629 {
3630  //If there are columns involved, the size is adjusted using the last column.
3631  //1. Format content.
3632  //2. Calculate height of the last column: if it's too big, the Fly has to
3633  // grow. The amount by which the Fly grows is not the amount of the
3634  // overhang because we have to act on the assumption that some text flows
3635  // back which will generate some more space.
3636  // The amount which we grow by equals the overhang
3637  // divided by the amount of columns or the overhang itself if it's smaller
3638  // than the amount of columns.
3639  //3. Go back to 1. until everything is stable.
3640 
3641  const SwFormatCol &rCol = rAttrs.GetAttrSet().GetCol();
3642  const sal_uInt16 nNumCols = rCol.GetNumCols();
3643 
3644  bool bEnd = false;
3645  bool bBackLock = false;
3647  SwViewShellImp *pImp = pSh ? pSh->Imp() : nullptr;
3648  vcl::RenderContext* pRenderContext = pSh ? pSh->GetOut() : nullptr;
3649  {
3650  // Underlying algorithm
3651  // We try to find the optimal height for the column.
3652  // nMinimum starts with the passed minimum height and is then remembered
3653  // as the maximum height on which column content still juts out of a
3654  // column.
3655  // nMaximum starts with LONG_MAX and is then remembered as the minimum
3656  // width on which the content fitted.
3657  // In column based sections nMaximum starts at the maximum value which
3658  // the surrounding defines, this can certainly be a value on which
3659  // content still juts out.
3660  // The columns are formatted. If content still juts out, nMinimum is
3661  // adjusted accordingly, then we grow, at least by uMinDiff but not
3662  // over a certain nMaximum. If no content juts out but there is still
3663  // some space left in the column, shrinking is done accordingly, at
3664  // least by nMindIff but not below the nMinimum.
3665  // Cancel as soon as no content juts out and the difference from minimum
3666  // to maximum is less than MinDiff or the maximum which was defined by
3667  // the surrounding is reached even if some content still juts out.
3668 
3669  // Criticism of this implementation
3670  // 1. Theoretically situations are possible in which the content fits in
3671  // a lower height but not in a higher height. To ensure that the code
3672  // handles such situations the code contains a few checks concerning
3673  // minimum and maximum which probably are never triggered.
3674  // 2. We use the same nMinDiff for shrinking and growing, but nMinDiff
3675  // is more or less the smallest first line height and doesn't seem ideal
3676  // as minimum value.
3677 
3678  long nMinimum = nMinHeight;
3679  long nMaximum;
3680  bool bNoBalance = false;
3681  SwRectFnSet aRectFnSet(this);
3682  if( IsSctFrame() )
3683  {
3684  nMaximum = aRectFnSet.GetHeight(getFrameArea()) - nBorder +
3685  aRectFnSet.BottomDist(getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper()));
3686  nMaximum += GetUpper()->Grow( LONG_MAX, true );
3687  if( nMaximum < nMinimum )
3688  {
3689  if( nMaximum < 0 )
3690  nMinimum = nMaximum = 0;
3691  else
3692  nMinimum = nMaximum;
3693  }
3694  if( nMaximum > BROWSE_HEIGHT )
3695  nMaximum = BROWSE_HEIGHT;
3696 
3697  bNoBalance = static_cast<SwSectionFrame*>(this)->GetSection()->GetFormat()->
3698  GetBalancedColumns().GetValue();
3699  SwFrame* pAny = ContainsAny();
3700  if( bNoBalance ||
3701  ( !aRectFnSet.GetHeight(getFrameArea()) && pAny ) )
3702  {
3703  long nTop = aRectFnSet.GetTopMargin(*this);
3704  // #i23129# - correction
3705  // to the calculated maximum height.
3706  {
3708  aRectFnSet.AddBottom( aFrm, nMaximum - aRectFnSet.GetHeight(getFrameArea()) );
3709  }
3710 
3711  if( nTop > nMaximum )
3712  nTop = nMaximum;
3713  aRectFnSet.SetYMargins( *this, nTop, 0 );
3714  }
3715  if( !pAny && !static_cast<SwSectionFrame*>(this)->IsFootnoteLock() )
3716  {
3717  SwFootnoteContFrame* pFootnoteCont = static_cast<SwSectionFrame*>(this)->ContainsFootnoteCont();
3718  if( pFootnoteCont )
3719  {
3720  SwFrame* pFootnoteAny = pFootnoteCont->ContainsAny();
3721  if( pFootnoteAny && pFootnoteAny->isFrameAreaDefinitionValid() )
3722  {
3723  bBackLock = true;
3724  static_cast<SwSectionFrame*>(this)->SetFootnoteLock( true );
3725  }
3726  }
3727  }
3728  }
3729  else
3730  nMaximum = LONG_MAX;
3731 
3732  // #i3317# - reset temporarily consideration
3733  // of wrapping style influence
3734  SwPageFrame* pPageFrame = FindPageFrame();
3735  SwSortedObjs* pObjs = pPageFrame ? pPageFrame->GetSortedObjs() : nullptr;
3736  if ( pObjs )
3737  {
3738  for (SwAnchoredObject* pAnchoredObj : *pObjs)
3739  {
3740  if ( IsAnLower( pAnchoredObj->GetAnchorFrame() ) )
3741  {
3742  pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3743  }
3744  }
3745  }
3746  do
3747  {
3748  //Could take a while therefore check for Waitcrsr here.
3749  if ( pImp )
3750  pImp->CheckWaitCursor();
3751 
3752  setFrameAreaSizeValid(true);
3753  //First format the column as this will relieve the stack a bit.
3754  //Also set width and height of the column (if they are wrong)
3755  //while we are at it.
3756  SwLayoutFrame *pCol = static_cast<SwLayoutFrame*>(Lower());
3757 
3758  // #i27399#
3759  // Simply setting the column width based on the values returned by
3760  // CalcColWidth does not work for automatic column width.
3761  AdjustColumns( &rCol, false );
3762 
3763  for ( sal_uInt16 i = 0; i < nNumCols; ++i )
3764  {
3765  pCol->Calc(pRenderContext);
3766  // ColumnFrames have a BodyFrame now, which needs to be calculated
3767  pCol->Lower()->Calc(pRenderContext);
3768  if( pCol->Lower()->GetNext() )
3769  pCol->Lower()->GetNext()->Calc(pRenderContext); // SwFootnoteCont
3770  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3771  }
3772 
3773  ::CalcContent( this );
3774 
3775  pCol = static_cast<SwLayoutFrame*>(Lower());
3776  OSL_ENSURE( pCol && pCol->GetNext(), ":-( column making holidays?");
3777  // set bMinDiff if no empty columns exist
3778  bool bMinDiff = true;
3779  // OD 28.03.2003 #108446# - check for all column content and all columns
3780  while ( bMinDiff && pCol )
3781  {
3782  bMinDiff = nullptr != pCol->ContainsContent();
3783  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3784  }
3785  pCol = static_cast<SwLayoutFrame*>(Lower());
3786  // OD 28.03.2003 #108446# - initialize local variable
3787  SwTwips nDiff = 0;
3788  SwTwips nMaxFree = 0;
3789  SwTwips nAllFree = LONG_MAX;
3790  // set bFoundLower if there is at least one non-empty column
3791  bool bFoundLower = false;
3792  while( pCol )
3793  {
3794  SwLayoutFrame* pLay = static_cast<SwLayoutFrame*>(pCol->Lower());
3795  SwTwips nInnerHeight = aRectFnSet.GetHeight(pLay->getFrameArea()) -
3796  aRectFnSet.GetHeight(pLay->getFramePrintArea());
3797  if( pLay->Lower() )
3798  {
3799  bFoundLower = true;
3800  nInnerHeight += pLay->InnerHeight();
3801  }
3802  else if( nInnerHeight < 0 )
3803  nInnerHeight = 0;
3804 
3805  if( pLay->GetNext() )
3806  {
3807  bFoundLower = true;
3808  pLay = static_cast<SwLayoutFrame*>(pLay->GetNext());
3809  OSL_ENSURE( pLay->IsFootnoteContFrame(),"FootnoteContainer expected" );
3810  nInnerHeight += pLay->InnerHeight();
3811  nInnerHeight += aRectFnSet.GetHeight(pLay->getFrameArea()) -
3812  aRectFnSet.GetHeight(pLay->getFramePrintArea());
3813  }
3814  nInnerHeight -= aRectFnSet.GetHeight(pCol->getFramePrintArea());
3815  if( nInnerHeight > nDiff )
3816  {
3817  nDiff = nInnerHeight;
3818  nAllFree = 0;
3819  }
3820  else
3821  {
3822  if( nMaxFree < -nInnerHeight )
3823  nMaxFree = -nInnerHeight;
3824  if( nAllFree > -nInnerHeight )
3825  nAllFree = -nInnerHeight;
3826  }
3827  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3828  }
3829 
3830  if ( bFoundLower || ( IsSctFrame() && static_cast<SwSectionFrame*>(this)->HasFollow() ) )
3831  {
3832  SwTwips nMinDiff = ::lcl_CalcMinColDiff( this );
3833  // Here we decide if growing is needed - this is the case, if
3834  // column content (nDiff) or a Fly juts over.
3835  // In sections with columns we take into account to set the size
3836  // when having a non-empty Follow.
3837  if ( nDiff || ::lcl_IsFlyHeightClipped( this ) ||
3838  ( IsSctFrame() && static_cast<SwSectionFrame*>(this)->CalcMinDiff( nMinDiff ) ) )
3839  {
3840  long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
3841  // The minimum must not be smaller than our PrtHeight as
3842  // long as something juts over.
3843  if( nMinimum < nPrtHeight )
3844  nMinimum = nPrtHeight;
3845  // The maximum must not be smaller than PrtHeight if
3846  // something still juts over.
3847  if( nMaximum < nPrtHeight )
3848  nMaximum = nPrtHeight; // Robust, but will this ever happen?
3849  if( !nDiff ) // If only Flys jut over, we grow by nMinDiff
3850  nDiff = nMinDiff;
3851  // If we should grow more than by nMinDiff we split it over
3852  // the columns
3853  if ( std::abs(nDiff - nMinDiff) > nNumCols && nDiff > static_cast<long>(nNumCols) )
3854  nDiff /= nNumCols;
3855 
3856  if ( bMinDiff )
3857  { // If no empty column exists, we want to grow at least
3858  // by nMinDiff. Special case: If we are smaller than the
3859  // minimal FrameHeight and PrtHeight is smaller than
3860  // nMindiff we grow in a way that PrtHeight is exactly
3861  // nMinDiff afterwards.
3862  long nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
3863  if ( nFrameHeight > nMinHeight || nPrtHeight >= nMinDiff )
3864  nDiff = std::max( nDiff, nMinDiff );
3865  else if( nDiff < nMinDiff )
3866  nDiff = nMinDiff - nPrtHeight + 1;
3867  }
3868  // nMaximum has a size which fits the content or the
3869  // requested value from the surrounding therefore we don't
3870  // need to exceed this value.
3871  if( nDiff + nPrtHeight > nMaximum )
3872  nDiff = nMaximum - nPrtHeight;
3873  }
3874  else if( nMaximum > nMinimum ) // We fit, do we still have some margin?
3875  {
3876  long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
3877  if ( nMaximum < nPrtHeight )
3878  nDiff = nMaximum - nPrtHeight; // We grew over a working
3879  // height and shrink back to it, but will this ever
3880  // happen?
3881  else
3882  { // We have a new maximum, a size which fits for the content.
3883  nMaximum = nPrtHeight;
3884  // If the margin in the column is bigger than nMinDiff
3885  // and we therefore drop under the minimum, we deflate
3886  // a bit.
3887  if ( !bNoBalance &&
3888  // #i23129# - <nMinDiff> can be
3889  // big, because of an object at the beginning of
3890  // a column. Thus, decrease optimization here.
3891  //nMaxFree >= nMinDiff &&
3892  nMaxFree > 0 &&
3893  ( !nAllFree ||
3894  nMinimum < nPrtHeight - nMinDiff ) )
3895  {
3896  nMaxFree /= nNumCols; // disperse over the columns
3897  nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // min nMinDiff
3898  if( nPrtHeight + nDiff <= nMinimum ) // below the minimum?
3899  nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3900  }
3901  else if( nAllFree )
3902  {
3903  nDiff = -nAllFree;
3904  if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum?
3905  nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
3906  }
3907  }
3908  }
3909  if( nDiff ) // now we shrink or grow...
3910  {
3911  Size aOldSz( getFramePrintArea().SSize() );
3912  long nTop = aRectFnSet.GetTopMargin(*this);
3913  nDiff = aRectFnSet.GetHeight(getFramePrintArea()) + nDiff + nBorder - aRectFnSet.GetHeight(getFrameArea());
3914 
3915  {
3917  aRectFnSet.AddBottom( aFrm, nDiff );
3918  }
3919 
3920  // #i68520#
3921  SwFlyFrame *pFlyFrame = dynamic_cast<SwFlyFrame*>(this);
3922  if (pFlyFrame)
3923  {
3924  pFlyFrame->InvalidateObjRectWithSpaces();
3925  }
3926  aRectFnSet.SetYMargins( *this, nTop, nBorder - nTop );
3927  ChgLowersProp( aOldSz );
3928  NotifyLowerObjs();
3929 
3930  // #i3317# - reset temporarily consideration
3931  // of wrapping style influence
3932  SwPageFrame* pTmpPageFrame = FindPageFrame();
3933  SwSortedObjs* pTmpObjs = pTmpPageFrame ? pTmpPageFrame->GetSortedObjs() : nullptr;
3934  if ( pTmpObjs )
3935  {
3936  for (SwAnchoredObject* pAnchoredObj : *pTmpObjs)
3937  {
3938  if ( IsAnLower( pAnchoredObj->GetAnchorFrame() ) )
3939  {
3940  pAnchoredObj->SetTmpConsiderWrapInfluence( false );
3941  }
3942  }
3943  }
3944  //Invalidate suitable to nicely balance the Frames.
3945  //- Every first one after the second column gets a
3946  // InvalidatePos();
3947  pCol = static_cast<SwLayoutFrame*>(Lower()->GetNext());
3948  while ( pCol )
3949  {
3950  SwFrame *pLow = pCol->Lower();
3951  if ( pLow )
3952  pLow->InvalidatePos_();
3953  pCol = static_cast<SwLayoutFrame*>(pCol->GetNext());
3954  }
3955  if( IsSctFrame() && static_cast<SwSectionFrame*>(this)->HasFollow() )
3956  {
3957  // If we created a Follow, we need to give its content
3958  // the opportunity to flow back inside the CalcContent
3959  SwContentFrame* pTmpContent =
3960  static_cast<SwSectionFrame*>(this)->GetFollow()->ContainsContent();
3961  if( pTmpContent )
3962  pTmpContent->InvalidatePos_();
3963  }
3964  }
3965  else
3966  bEnd = true;
3967  }
3968  else
3969  bEnd = true;
3970 
3971  } while ( !bEnd || !isFrameAreaSizeValid() );
3972  }
3973  // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set
3974  // 2nd parameter to <true>.
3975  ::CalcContent( this, true );
3976  if( IsSctFrame() )
3977  {
3978  // OD 14.03.2003 #i11760# - adjust 2nd parameter - sal_True --> true
3979  ::CalcContent( this, true );
3980  if( bBackLock )
3981  static_cast<SwSectionFrame*>(this)->SetFootnoteLock( false );
3982  }
3983 }
3984 
3986 {
3987  SwSectionFrame* pSect = pCnt->FindSctFrame();
3988  // If our ContentFrame is placed inside a table or a footnote, only sections
3989  // which are also placed inside are meant.
3990  // Exception: If a table is directly passed.
3991  if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) ||
3992  ( pCnt->IsInFootnote() && !pSect->IsInFootnote() ) ) && !pCnt->IsTabFrame() )
3993  return nullptr;
3994  if( nInv & SwInvalidateFlags::Size )
3995  pSect->InvalidateSize_();
3996  if( nInv & SwInvalidateFlags::Pos )
3997  pSect->InvalidatePos_();
3998  if( nInv & SwInvalidateFlags::PrtArea )
3999  pSect->InvalidatePrt_();
4000  SwFlowFrame *pFoll = pSect->GetFollow();
4001  // Temporary separation from follow
4002  pSect->SetFollow( nullptr );
4003  SwContentFrame* pRet = pSect->FindLastContent();
4004  pSect->SetFollow( pFoll );
4005  return pRet;
4006 }
4007 
4009 {
4010  if( ( nInv & SwInvalidateFlags::Section ) && pTable->IsInSct() )
4011  lcl_InvalidateSection( pTable, nInv );
4012  if( nInv & SwInvalidateFlags::Size )
4013  pTable->InvalidateSize_();
4014  if( nInv & SwInvalidateFlags::Pos )
4015  pTable->InvalidatePos_();
4016  if( nInv & SwInvalidateFlags::PrtArea )
4017  pTable->InvalidatePrt_();
4018  return pTable->FindLastContent();
4019 }
4020 
4021 static void lcl_InvalidateAllContent( SwContentFrame *pCnt, SwInvalidateFlags nInv );
4022 
4024 {
4025  SwContentFrame *pLastTabCnt = nullptr;
4026  SwContentFrame *pLastSctCnt = nullptr;
4027  while ( pCnt )
4028  {
4029  if( nInv & SwInvalidateFlags::Section )
4030  {
4031  if( pCnt->IsInSct() )
4032  {
4033  // See above at tables
4034  if( !pLastSctCnt )
4035  pLastSctCnt = lcl_InvalidateSection( pCnt, nInv );
4036  if( pLastSctCnt == pCnt )
4037  pLastSctCnt = nullptr;
4038  }
4039 #if OSL_DEBUG_LEVEL > 0
4040  else
4041  OSL_ENSURE( !pLastSctCnt, "Where's the last SctContent?" );
4042 #endif
4043  }
4044  if( nInv & SwInvalidateFlags::Table )
4045  {
4046  if( pCnt->IsInTab() )
4047  {
4048  // To not call FindTabFrame() for each ContentFrame of a table and
4049  // then invalidate the table, we remember the last ContentFrame of
4050  // the table and ignore IsInTab() until we are past it.
4051  // When entering the table, LastSctCnt is set to null, so
4052  // sections inside the table are correctly invalidated.
4053  // If the table itself is in a section the
4054  // invalidation is done three times, which is acceptable.
4055  if( !pLastTabCnt )
4056  {
4057  pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrame(), nInv );
4058  pLastSctCnt = nullptr;
4059  }
4060  if( pLastTabCnt == pCnt )
4061  {
4062  pLastTabCnt = nullptr;
4063  pLastSctCnt = nullptr;
4064  }
4065  }
4066 #if OSL_DEBUG_LEVEL > 0
4067  else
4068  OSL_ENSURE( !pLastTabCnt, "Where's the last TabContent?" );
4069 #endif
4070  }
4071 
4072  if( nInv & SwInvalidateFlags::Size )
4073  pCnt->Prepare( PrepareHint::Clear, nullptr, false );
4074  if( nInv & SwInvalidateFlags::Pos )
4075  pCnt->InvalidatePos_();
4076  if( nInv & SwInvalidateFlags::PrtArea )
4077  pCnt->InvalidatePrt_();
4078  if ( nInv & SwInvalidateFlags::LineNum )
4079  pCnt->InvalidateLineNum();
4080  if ( pCnt->GetDrawObjs() )
4081  lcl_InvalidateAllContent( pCnt, nInv );
4082  pCnt = pCnt->GetNextContentFrame();
4083  }
4084 }
4085 
4087 {
4088  SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
4089  for (SwAnchoredObject* pAnchoredObj : rObjs)
4090  {
4091  if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr )
4092  {
4093  SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pAnchoredObj);
4094  if ( pFly->IsFlyInContentFrame() )
4095  {
4096  ::lcl_InvalidateContent( pFly->ContainsContent(), nInv );
4097  if( nInv & SwInvalidateFlags::Direction )
4098  pFly->CheckDirChange();
4099  }
4100  }
4101  }
4102 }
4103 
4105 {
4106  // First process all page bound FlyFrames.
4107  SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower());
4108  while( pPage )
4109  {
4110  pPage->InvalidateFlyLayout();
4111  pPage->InvalidateFlyContent();
4112  pPage->InvalidateFlyInCnt();
4113  pPage->InvalidateLayout();
4114  pPage->InvalidateContent();
4115  pPage->InvalidatePage( pPage ); // So even the Turbo disappears if applicable
4116 
4117  if ( pPage->GetSortedObjs() )
4118  {
4119  const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
4120  for (SwAnchoredObject* pAnchoredObj : rObjs)
4121  {
4122  if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr )
4123  {
4124  SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pAnchoredObj);
4125  ::lcl_InvalidateContent( pFly->ContainsContent(), nInv );
4126  if ( nInv & SwInvalidateFlags::Direction )
4127  pFly->CheckDirChange();
4128  }
4129  }
4130  }
4131  if( nInv & SwInvalidateFlags::Direction )
4132  pPage->CheckDirChange();
4133  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
4134  }
4135 
4136  //Invalidate the whole document content and the character bound Flys here.
4138 
4139  if( nInv & SwInvalidateFlags::PrtArea )
4140  {
4142  if( pSh )
4143  pSh->InvalidateWindows( getFrameArea() );
4144  }
4145 }
4146 
4152 {
4153  const SwPageFrame* pPageFrame = static_cast<const SwPageFrame*>(Lower());
4154  while( pPageFrame )
4155  {
4156  pPageFrame->InvalidateFlyLayout();
4157 
4158  if ( pPageFrame->GetSortedObjs() )
4159  {
4160  const SwSortedObjs& rObjs = *(pPageFrame->GetSortedObjs());
4161  for (SwAnchoredObject* pAnchoredObj : rObjs)
4162  {
4163  const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat().GetAnchor();
4164  if ((rAnch.GetAnchorId() != RndStdIds::FLY_AT_PARA) &&
4165  (rAnch.GetAnchorId() != RndStdIds::FLY_AT_CHAR))
4166  {
4167  // only to paragraph and to character anchored objects are considered.
4168  continue;
4169  }
4170  // #i28701# - special invalidation for anchored
4171  // objects, whose wrapping style influence has to be considered.
4172  if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
4173  pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence();
4174  else
4175  pAnchoredObj->InvalidateObjPos();
4176  }
4177  }
4178 
4179  pPageFrame = static_cast<const SwPageFrame*>(pPageFrame->GetNext());
4180  }
4181 }
4182 
4184  SwTextFrame & rFrame, SwTextNode & rTextNode,
4185  std::set<sal_uLong> *const pSkipped,
4186  SwFrameFormats & rTable,
4187  SwPageFrame *const pPage,
4188  SwTextNode const*const pNode,
4189  std::vector<sw::Extent>::const_iterator & rIterFirst,
4190  std::vector<sw::Extent>::const_iterator const& rIterEnd,
4191  SwTextNode const*const pFirstNode, SwTextNode const*const pLastNode)
4192 {
4193  if (pNode == &rTextNode)
4194  { // remove existing hidden at-char anchored flys
4195  RemoveHiddenObjsOfNode(rTextNode, &rIterFirst, &rIterEnd, pFirstNode, pLastNode);
4196  }
4197  else if (rTextNode.GetIndex() < pNode->GetIndex())
4198  {
4199  // pNode's frame has been deleted by CheckParaRedlineMerge()
4200  AppendObjsOfNode(&rTable,
4201  pNode->GetIndex(), &rFrame, pPage, rTextNode.GetDoc(),
4202  &rIterFirst, &rIterEnd, pFirstNode, pLastNode);
4203  if (pSkipped)
4204  {
4205  // if a fly has been added by AppendObjsOfNode, it must be skipped; if not, then it doesn't matter if it's skipped or not because it has no frames and because of that it would be skipped anyway
4206  if (auto const pFlys = pNode->GetAnchoredFlys())
4207  {
4208  for (auto const pFly : *pFlys)
4209  {
4210  if (pFly->Which() != RES_DRAWFRMFMT)
4211  {
4212  pSkipped->insert(pFly->GetContent().GetContentIdx()->GetIndex());
4213  }
4214  }
4215  }
4216  }
4217  }
4218 }
4219 
4220 namespace sw {
4221 
4226  SwTextFrame & rFrame, SwTextNode & rTextNode,
4227  std::set<sal_uLong> *const pSkipped)
4228 {
4229  auto const pMerged(rFrame.GetMergedPara());
4230  if (!pMerged
4231  // do this only *once*, for the *last* frame
4232  // otherwise AppendObj would create multiple frames for fly-frames!
4233  || rFrame.GetFollow())
4234  return;
4235 
4236  assert(pMerged->pFirstNode->GetIndex() <= rTextNode.GetIndex()
4237  && rTextNode.GetIndex() <= pMerged->pLastNode->GetIndex());
4238  // add visible flys in non-first node to merged frame
4239  // (hidden flys remain and are deleted via DelFrames())
4240  SwFrameFormats& rTable(*rTextNode.GetDoc()->GetSpzFrameFormats());
4241  SwPageFrame *const pPage(rFrame.FindPageFrame());
4242  std::vector<sw::Extent>::const_iterator iterFirst(pMerged->extents.begin());
4243  std::vector<sw::Extent>::const_iterator iter(iterFirst);
4244  SwTextNode const* pNode(pMerged->pFirstNode);
4245  for ( ; ; ++iter)
4246  {
4247  if (iter == pMerged->extents.end()
4248  || iter->pNode != pNode)
4249  {
4250  AddRemoveFlysForNode(rFrame, rTextNode, pSkipped, rTable, pPage,
4251  pNode, iterFirst, iter,
4252  pMerged->pFirstNode, pMerged->pLastNode);
4253  sal_uLong const until = iter == pMerged->extents.end()
4254  ? pMerged->pLastNode->GetIndex() + 1
4255  : iter->pNode->GetIndex();
4256  for (sal_uLong i = pNode->GetIndex() + 1; i < until; ++i)
4257  {
4258  // let's show at-para flys on nodes that contain start/end of
4259  // redline too, even if there's no text there
4260  SwNode const*const pTmp(pNode->GetNodes()[i]);
4261  if (pTmp->GetRedlineMergeFlag() == SwNode::Merge::NonFirst)
4262  {
4263  AddRemoveFlysForNode(rFrame, rTextNode, pSkipped,
4264  rTable, pPage, pTmp->GetTextNode(), iter, iter,
4265  pMerged->pFirstNode, pMerged->pLastNode);
4266  }
4267  }
4268  if (iter == pMerged->extents.end())
4269  {
4270  break;
4271  }
4272  pNode = iter->pNode;
4273  iterFirst = iter;
4274  }
4275  }
4276 }
4277 
4278 } // namespace sw
4279 
4280 static void UnHideRedlines(SwRootFrame & rLayout,
4281  SwNodes & rNodes, SwNode const& rEndOfSectionNode,
4282  std::set<sal_uLong> *const pSkipped)
4283 {
4284  assert(rEndOfSectionNode.IsEndNode());
4285  assert(rNodes[rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1]->IsCreateFrameWhenHidingRedlines()); // first node is never hidden
4286  for (sal_uLong i = rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1;
4287  i < rEndOfSectionNode.GetIndex(); ++i)
4288  {
4289  SwNode & rNode(*rNodes[i]);
4290  if (rNode.IsTextNode()) // only text nodes are 1st node of a merge
4291  {
4292  SwTextNode & rTextNode(*rNode.GetTextNode());
4294  std::vector<SwTextFrame*> frames;
4295  for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
4296  {
4297  if (pFrame->getRootFrame() == &rLayout)
4298  {
4299  if (pFrame->IsFollow())
4300  {
4301  frames.push_back(pFrame);
4302  } // when hiding, the loop must remove the anchored flys
4303  else // *before* resetting SetMergedPara anywhere - else
4304  { // the fly deletion code will access multiple of the
4305  // frames with inconsistent MergedPara and assert
4306  frames.insert(frames.begin(), pFrame);
4307  }
4308  }
4309  }
4310  // this messes with pRegisteredIn so do it outside SwIterator
4312  for (SwTextFrame * pFrame : frames)
4313  {
4314  if (rLayout.IsHideRedlines())
4315  {
4316  assert(!pFrame->GetMergedPara() ||
4318  if (rNode.IsCreateFrameWhenHidingRedlines())
4319  {
4320  {
4321  auto pMerged(CheckParaRedlineMerge(*pFrame,
4322  rTextNode, eMode));
4323  pFrame->SetMergedPara(std::move(pMerged));
4324  }
4325  auto const pMerged(pFrame->GetMergedPara());
4326  if (pMerged)
4327  {
4328  // invalidate SwInvalidateFlags::Size
4329  pFrame->Prepare(PrepareHint::Clear, nullptr, false);
4330  pFrame->InvalidatePage();
4331  if (auto const pObjs = pFrame->GetDrawObjs())
4332  { // also invalidate position of existing flys
4333  // because they may need to be moved
4334  for (auto const pObject : *pObjs)
4335  {
4336  pObject->InvalidateObjPos();
4337  }
4338  }
4339  }
4340  sw::AddRemoveFlysAnchoredToFrameStartingAtNode(*pFrame, rTextNode, pSkipped);
4341  // only *first* frame of node gets Existing because it
4342  eMode = sw::FrameMode::New; // is not idempotent!
4343  }
4344  }
4345  else
4346  {
4347  if (auto const& pMergedPara = pFrame->GetMergedPara())
4348  {
4349  // invalidate SwInvalidateFlags::Size
4350  pFrame->Prepare(PrepareHint::Clear, nullptr, false);
4351  pFrame->InvalidatePage();
4352  if (auto const pObjs = pFrame->GetDrawObjs())
4353  { // also invalidate position of existing flys
4354  for (auto const pObject : *pObjs)
4355  {
4356  pObject->InvalidateObjPos();
4357  }
4358  }
4359  // SwFlyAtContentFrame::Modify() always appends to
4360  // the master frame, so do the same here.
4361  // (RemoveFootnotesForNode must be called at least once)
4362  if (!pFrame->IsFollow())
4363  {
4364  // the new text frames don't exist yet, so at this point
4365  // we can only delete the footnote frames so they don't
4366  // point to the merged SwTextFrame any more...
4367  assert(&rTextNode == pMergedPara->pFirstNode);
4368  // iterate over nodes, not extents: if a node has
4369  // no extents now but did have extents initially,
4370  // its flys need their frames deleted too!
4371  for (sal_uLong j = rTextNode.GetIndex() + 1;
4372  j <= pMergedPara->pLastNode->GetIndex(); ++j)
4373  {
4374  SwNode *const pNode(rTextNode.GetNodes()[j]);
4375  assert(!pNode->IsEndNode());
4376  if (pNode->IsStartNode())
4377  {
4378  j = pNode->EndOfSectionIndex();
4379  }
4380  else if (pNode->IsTextNode())
4381  {
4382  sw::RemoveFootnotesForNode(rLayout, *pNode->GetTextNode(), nullptr);
4383  // similarly, remove the anchored flys
4384  if (auto const pFlys = pNode->GetAnchoredFlys())
4385  {
4386  for (SwFrameFormat * pFormat : *pFlys)
4387  {
4388  pFormat->DelFrames(/*&rLayout*/);
4389  }
4390  }
4391  }
4392  }
4393  // rely on AppendAllObjs call at the end to add
4394  // all flys in first node that are hidden
4395  }
4396  pFrame->SetMergedPara(nullptr);
4397  }
4398  }
4399  pFrame->Broadcast(SfxHint()); // notify SwAccessibleParagraph
4400  }
4401  // all nodes, not just merged ones! it may be in the same list as
4402  if (rTextNode.IsNumbered(nullptr)) // a preceding merged one...
4403  { // notify frames so they reformat numbering portions
4404  rTextNode.NumRuleChgd();
4405  }
4406  }
4407  else if (rNode.IsTableNode() && rLayout.IsHideRedlines())
4408  {
4409  SwPosition const tmp(rNode);
4410  SwRangeRedline const*const pRedline(
4411  rLayout.GetFormat()->GetDoc()->getIDocumentRedlineAccess().GetRedline(tmp, nullptr));
4412  // pathology: redline that starts on a TableNode; cannot
4413  // be created in UI but by import filters...
4414  if (pRedline
4415  && pRedline->GetType() == RedlineType::Delete
4416  && &pRedline->Start()->nNode.GetNode() == &rNode)
4417  {
4418  for (sal_uLong j = rNode.GetIndex(); j <= rNode.EndOfSectionIndex(); ++j)
4419  {
4420  rNode.GetNodes()[j]->SetRedlineMergeFlag(SwNode::Merge::Hidden);
4421  }
4422  rNode.GetTableNode()->DelFrames(&rLayout);
4423  }
4424  }
4425  if (!rNode.IsCreateFrameWhenHidingRedlines())
4426  {
4427  if (rLayout.IsHideRedlines())
4428  {
4429  if (rNode.IsContentNode())
4430  {
4431  // note: nothing to do here, already done
4432 #ifndef NDEBUG
4433  auto const pFrame(static_cast<SwContentNode&>(rNode).getLayoutFrame(&rLayout));
4434  assert(!pFrame || static_cast<SwTextFrame*>(pFrame)->GetMergedPara()->pFirstNode != &rNode);
4435 #endif
4436  }
4437  }
4438  else
4439  {
4440  assert(!rNode.IsContentNode() || !rNode.GetContentNode()->getLayoutFrame(&rLayout));
4441  sal_uLong j = i + 1;
4442  for ( ; j < rEndOfSectionNode.GetIndex(); ++j)
4443  {
4444  if (rNodes[j]->IsCreateFrameWhenHidingRedlines())
4445  {
4446  break;
4447  }
4448  }
4449  // call MakeFrames once, because sections/tables
4450  // InsertCnt_ also checks for hidden sections
4451  SwNodeIndex const start(rNodes, i);
4452  SwNodeIndex const end(rNodes, j);
4454  bDontCreateObjects = true; // suppress here, to be called once
4455  ::MakeFrames(rLayout.GetFormat()->GetDoc(), start, end);
4456  bDontCreateObjects = false;
4457  i = j - 1; // will be incremented again
4458  }
4459  }
4460  }
4461 }
4462 
4463 static void UnHideRedlinesExtras(SwRootFrame & rLayout,
4464  SwNodes & rNodes, SwNode const& rEndOfExtraSectionNode,
4465  std::set<sal_uLong> *const pSkipped)
4466 {
4467  assert(rEndOfExtraSectionNode.IsEndNode());
4468  for (sal_uLong i = rEndOfExtraSectionNode.StartOfSectionNode()->GetIndex()
4469  + 1; i < rEndOfExtraSectionNode.GetIndex(); ++i)
4470  {
4471  SwNode const& rStartNode(*rNodes[i]);
4472  assert(rStartNode.IsStartNode());
4474  SwNode const& rEndNode(*rStartNode.EndOfSectionNode());
4475  bool bSkip(pSkipped && pSkipped->find(i) != pSkipped->end());
4476  i = rEndNode.GetIndex();
4477  for (sal_uLong j = rStartNode.GetIndex() + 1; j < i; ++j)
4478  {
4479  // note: SwStartNode has no way to access the frames, so check
4480  // whether the first content-node inside the section has frames
4481  SwNode const& rNode(*rNodes[j]);
4482  if (rNode.IsSectionNode() &&
4483  static_cast<SwSectionNode const&>(rNode).GetSection().IsHiddenFlag())
4484  { // skip hidden sections - they can be inserted in fly-frames :(
4485  j = rNode.EndOfSectionNode()->GetIndex();
4486  continue;
4487  }
4488  if (rNode.IsContentNode())
4489  {
4490  SwContentNode const& rCNode(static_cast<SwContentNode const&>(rNode));
4491  if (!rCNode.getLayoutFrame(&rLayout))
4492  { // ignore footnote/fly/header/footer with no layout frame
4493  bSkip = true; // they will be created from scratch later if needed
4494  }
4495  break;
4496  }
4497  }
4498  if (!bSkip)
4499  {
4500  UnHideRedlines(rLayout, rNodes, rEndNode, pSkipped);
4501  }
4502  }
4503 }
4504 
4505 void SwRootFrame::SetHideRedlines(bool const bHideRedlines)
4506 {
4507  if (bHideRedlines == mbHideRedlines)
4508  {
4509  return;
4510  }
4511  mbHideRedlines = bHideRedlines;
4512  assert(GetCurrShell()->ActionPend()); // tdf#125754 avoid recursive layout
4513  SwDoc & rDoc(*GetFormat()->GetDoc());
4514  // don't do early return if there are no redlines:
4515  // Show->Hide must init hidden number trees
4516  // Hide->Show may be called after all redlines have been deleted but there
4517  // may still be MergedParas because those aren't deleted yet...
4518 #if 0
4519  if (!bHideRedlines
4521  {
4522  return;
4523  }
4524 #endif
4525  // Hide->Show: clear MergedPara, create frames
4526  // Show->Hide: call CheckParaRedlineMerge, delete frames
4527  // Traverse the document via the nodes-array; traversing via the layout
4528  // wouldn't find the nodes that don't have frames in the ->Show case.
4529  // In-order traversal of each nodes array section should init the flags
4530  // in nodes before they are iterated.
4531  // Actual creation of frames should be done with existing functions
4532  // if possible, particularly InsertCnt_() or its wrapper ::MakeFrames().
4533  SwNodes /*const*/& rNodes(rDoc.GetNodes());
4534  // Flys/footnotes: must iterate and find all the ones that already exist
4535  // with frames and have redlines inside them; if any don't have frames at
4536  // all, they will be created (if necessary) from scratch and completely by
4537  // MakeFrames().
4538  //
4539  // Flys before footnotes: because footnotes may contain flys but not
4540  // vice-versa; alas flys may contain flys, so we skip some of them
4541  // if they have already been created from scratch via their anchor flys.
4542  std::set<sal_uLong> skippedFlys;
4543  UnHideRedlinesExtras(*this, rNodes, rNodes.GetEndOfAutotext(),
4544  // when un-hiding, delay all fly frame creation to AppendAllObjs below
4545  IsHideRedlines() ? &skippedFlys : nullptr);
4546  // Footnotes are created automatically (after invalidation etc.) by
4547  // ConnectFootnote(), but need to be deleted manually. Footnotes do not
4548  // occur in flys or headers/footers.
4549  UnHideRedlinesExtras(*this, rNodes, rNodes.GetEndOfInserts(), nullptr);
4550  UnHideRedlines(*this, rNodes, rNodes.GetEndOfContent(), nullptr);
4551 
4552  if (!IsHideRedlines())
4553  { // create all previously hidden flys at once:
4554  // * Flys on first node of pre-existing merged frames that are hidden
4555  // (in delete redline), to be added to the existing frame
4556  // * Flys on non-first (hidden/merged) nodes of pre-existing merged
4557  // frames, to be added to the new frame of their node
4558  // * Flys anchored in other flys that are hidden
4559  AppendAllObjs(rDoc.GetSpzFrameFormats(), this);
4560  }
4561 
4562  for (auto const pRedline : rDoc.getIDocumentRedlineAccess().GetRedlineTable())
4563  { // DELETE are handled by the code above; for other types, need to
4564  // trigger repaint of text frames to add/remove the redline color font
4565  if (pRedline->GetType() != RedlineType::Delete)
4566  {
4567  pRedline->InvalidateRange(SwRangeRedline::Invalidation::Add);
4568  }
4569  }
4570 
4571  SwFootnoteIdxs & rFootnotes(rDoc.GetFootnoteIdxs());
4572  if (rDoc.GetFootnoteInfo().m_eNum == FTNNUM_CHAPTER)
4573  {
4574  // sadly determining which node is outline node requires hidden layout
4575  rFootnotes.UpdateAllFootnote();
4576  }
4577  // invalidate all footnotes to reformat their numbers
4578  for (SwTextFootnote *const pFootnote : rFootnotes)
4579  {
4580  SwFormatFootnote const& rFootnote(pFootnote->GetFootnote());
4581  if (rFootnote.GetNumber() != rFootnote.GetNumberRLHidden()
4582  && rFootnote.GetNumStr().isEmpty())
4583  {
4584  pFootnote->InvalidateNumberInLayout();
4585  }
4586  }
4587  // update various fields to re-expand them with the new layout
4589  auto const pAuthType(rIDFA.GetFieldType(
4590  SwFieldIds::TableOfAuthorities, OUString(), false));
4591  if (pAuthType) // created on demand...
4592  { // calling DelSequenceArray() should be unnecessary here since the
4593  // sequence doesn't depend on frames
4594  pAuthType->UpdateFields();
4595  }
4596  rIDFA.GetFieldType(SwFieldIds::RefPageGet, OUString(), false)->UpdateFields();
4597  rIDFA.GetSysFieldType(SwFieldIds::Chapter)->UpdateFields();
4598  rIDFA.UpdateExpFields(nullptr, false);
4599  rIDFA.UpdateRefFields();
4600 
4601  // update SwPostItMgr / notes in the margin
4602  // note: as long as all shells share layout, broadcast to all shells!
4603  rDoc.GetDocShell()->Broadcast( SwFormatFieldHint(nullptr, bHideRedlines
4606 
4607 
4608 // InvalidateAllContent(SwInvalidateFlags::Size); // ??? TODO what to invalidate? this is the big hammer
4609 }
4610 
4611 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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:339
long Width() const
#define FRM_NEIGHBOUR
Definition: frame.hxx:104
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:547
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
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:282
constexpr TypedWhichId< SwHeaderAndFooterEatSpacingItem > RES_HEADER_FOOTER_EAT_SPACING(121)
bool IsFlyLayFrame() const
Definition: flyfrm.hxx:195
void Add(SwClient *pDepend)
Definition: calbck.cxx:217
bool IsFollow() const
Definition: flowfrm.hxx:166
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:2807
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:644
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:3360
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:183
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:1003
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:4104
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 SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:106
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:1919
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:3627
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:1190
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:1913
void InvalidatePos()
Definition: frame.hxx:1021
SwRectGet fnGetHeight
Definition: frame.hxx:1274
void Invalidate_(SwPageFrame const *pPage=nullptr)
Definition: fly.cxx:1029
#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:2530
void ImplInvalidatePrt()
Definition: wsfrm.cxx:1935
long CalcRight(const SwFrame *pCaller) const
Definition: frmtool.cxx:2210
virtual const SwFormatPageDesc & GetPageDescItem() const
Definition: findfrm.cxx:659
SwFrame(SwModify *, SwFrame *)
Definition: wsfrm.cxx:290
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2639
static long lcl_CalcMinColDiff(SwLayoutFrame *pLayFrame)
Definition: wsfrm.cxx:3568
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:1998
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:4008
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:356
void SetRetouche() const
Definition: frame.hxx:981
long CalcLeft(const SwFrame *pCaller) const
Definition: frmtool.cxx:2258
GPOS_TILED
void InvalidateObjs(const bool _bNoInvaOfAsCharAnchoredObjs=true)
Definition: fly.cxx:2284
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:2961
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:782
SwTwips Shrink_(SwTwips, bool bTst)
Definition: fly.cxx:1949
long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1388
SwTableNode * GetTableNode()
Definition: node.hxx:599
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:454
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:624
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:288
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:4225
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:1929
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:4505
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:4183
virtual SwTwips GrowFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: wsfrm.cxx:2067
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:3481
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1085
bool IsContentNode() const
Definition: node.hxx:628
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:1354
virtual SwTwips GrowFrame(SwTwips, bool bTst=false, bool bInfo=false)=0
SwTwips Grow_(SwTwips, bool bTst)
Definition: fly.cxx:1869
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:200
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
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:2541
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:4086
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:3599
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:3476
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:615
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 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
SwDoc * GetDoc()
Definition: node.hxx:702
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:3542
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:396
bool mbDerivedR2L
Definition: frame.hxx:401
Marks a node in the document model.
Definition: ndindex.hxx:31
bool IsEndNode() const
Definition: node.hxx:632
bool isIdentity() const
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
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:757
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:4151
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:677
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
void Bottom(const long nBottom)
Definition: swrect.hxx:209