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