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