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