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