LibreOffice Module sw (master)  1
flowfrm.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 <memory>
21 #include <sal/config.h>
22 #include <sal/log.hxx>
23 #include <svx/svdobj.hxx>
24 
25 #include <anchoredobject.hxx>
26 #include <bodyfrm.hxx>
27 #include <swtable.hxx>
28 #include <rootfrm.hxx>
29 #include <pagefrm.hxx>
30 #include <viewimp.hxx>
31 #include <viewopt.hxx>
32 #include <frmatr.hxx>
33 #include <frmtool.hxx>
36 #include <editeng/keepitem.hxx>
37 #include <fmtanchr.hxx>
38 #include <fmtsrnd.hxx>
39 #include <fmtpdsc.hxx>
40 #include <editeng/ulspitem.hxx>
41 #include <tgrditem.hxx>
42 #include <txtftn.hxx>
43 #include <fmtftn.hxx>
44 #include <editeng/pgrditem.hxx>
45 #include <paratr.hxx>
46 #include <ftnfrm.hxx>
47 #include <txtfrm.hxx>
48 #include <notxtfrm.hxx>
49 #include <tabfrm.hxx>
50 #include <rowfrm.hxx>
51 #include <pagedesc.hxx>
52 #include <layact.hxx>
53 #include <flyfrm.hxx>
54 #include <sectfrm.hxx>
55 #include <section.hxx>
56 #include <dbg_lay.hxx>
57 #include <lineinfo.hxx>
58 #include <fmtclbl.hxx>
59 #include <sortedobjs.hxx>
60 #include <layouter.hxx>
61 #include <fmtfollowtextflow.hxx>
62 #include <calbck.hxx>
65 #include <pam.hxx>
66 #include <ndtxt.hxx>
67 
68 bool SwFlowFrame::m_bMoveBwdJump = false;
69 
71  m_rThis( rFrame ),
72  m_pFollow( nullptr ),
73  m_pPrecede( nullptr ),
74  m_bLockJoin( false ),
75  m_bUndersized( false ),
76  m_bFlyLock( false )
77 {}
78 
80 {
81  if (m_pFollow)
82  {
83  m_pFollow->m_pPrecede = nullptr;
84  }
85  if (m_pPrecede)
86  {
87  m_pPrecede->m_pFollow = nullptr;
88  }
89 }
90 
91 void SwFlowFrame::SetFollow(SwFlowFrame *const pFollow)
92 {
93  if (m_pFollow)
94  {
95  assert(this == m_pFollow->m_pPrecede);
96  m_pFollow->m_pPrecede = nullptr;
97  }
98  m_pFollow = pFollow;
99  if (m_pFollow != nullptr)
100  {
101  if (m_pFollow->m_pPrecede) // re-chaining pFollow?
102  {
104  m_pFollow->m_pPrecede->m_pFollow = nullptr;
105  }
106  m_pFollow->m_pPrecede = this;
107  }
108 }
109 
112 {
113  const SwFlowFrame* pFrame = GetFollow();
114  while( pFrame )
115  {
116  if( pFrame->IsJoinLocked() )
117  return true;
118  pFrame = pFrame->GetFollow();
119  }
120  return false;
121 }
122 
123 bool SwFlowFrame::IsKeepFwdMoveAllowed( bool bIgnoreMyOwnKeepValue )
124 {
125  // If all the predecessors up to the first of the chain have
126  // the 'keep' attribute set, and the first of the chain's
127  // IsFwdMoveAllowed returns false, then we're not allowed to move.
128  SwFrame *pFrame = &m_rThis;
129  if ( !pFrame->IsInFootnote() ) {
130  if ( bIgnoreMyOwnKeepValue && pFrame->GetIndPrev() )
131  pFrame = pFrame->GetIndPrev();
132  do
133  { if ( pFrame->GetAttrSet()->GetKeep().GetValue() )
134  pFrame = pFrame->GetIndPrev();
135  else
136  return true;
137  } while ( pFrame );
138  }
139  //See IsFwdMoveAllowed()
140  bool bRet = false;
141  if ( pFrame && pFrame->GetIndPrev() )
142  bRet = true;
143  return bRet;
144 }
145 
147 {
148  // Kick off the "last" predecessor with a 'keep' attribute, because
149  // it's possible for the whole troop to move back.
150  SwFrame *pPre = m_rThis.GetIndPrev();
151  assert(pPre);
152  if( pPre->IsSctFrame() )
153  {
154  SwFrame *pLast = static_cast<SwSectionFrame*>(pPre)->FindLastContent();
155  if( pLast && pLast->FindSctFrame() == pPre )
156  pPre = pLast;
157  else
158  return;
159  }
160  SwFrame* pTmp;
161  bool bKeep;
162  while ( (bKeep = pPre->GetAttrSet()->GetKeep().GetValue()) &&
163  nullptr != ( pTmp = pPre->GetIndPrev() ) )
164  {
165  if( pTmp->IsSctFrame() )
166  {
167  SwFrame *pLast = static_cast<SwSectionFrame*>(pTmp)->FindLastContent();
168  if( pLast && pLast->FindSctFrame() == pTmp )
169  pTmp = pLast;
170  else
171  break;
172  }
173  pPre = pTmp;
174  }
175  if ( bKeep )
176  pPre->InvalidatePos();
177 }
178 
180  SvxFormatBreakItem const& rBreak,
181  bool const bCheckIfLastRowShouldKeep) const
182 {
183  // 1. The keep attribute is ignored inside footnotes
184  // 2. For compatibility reasons, the keep attribute is
185  // ignored for frames inside table cells
186  // 3. If bBreakCheck is set to true, this function only checks
187  // if there are any break after attributes set at rAttrs
188  // or break before attributes set for the next content (or next table)
189  bool bKeep = bCheckIfLastRowShouldKeep ||
190  ( !m_rThis.IsInFootnote() &&
191  ( !m_rThis.IsInTab() || m_rThis.IsTabFrame() ) &&
192  rKeep.GetValue() );
193 
194  OSL_ENSURE( !bCheckIfLastRowShouldKeep || m_rThis.IsTabFrame(),
195  "IsKeep with bCheckIfLastRowShouldKeep should only be used for tabfrms" );
196 
197  // Ignore keep attribute if there are break situations:
198  if ( bKeep )
199  {
200  switch (rBreak.GetBreak())
201  {
202  case SvxBreak::ColumnAfter:
203  case SvxBreak::ColumnBoth:
204  case SvxBreak::PageAfter:
205  case SvxBreak::PageBoth:
206  {
207  bKeep = false;
208  break;
209  }
210  default: break;
211  }
212  if ( bKeep )
213  {
214  SwFrame *pNxt;
215  if( nullptr != (pNxt = m_rThis.FindNextCnt()) &&
216  (!m_pFollow || pNxt != &m_pFollow->GetFrame()))
217  {
218  // The last row of a table only keeps with the next content
219  // it they are in the same section:
220  if ( bCheckIfLastRowShouldKeep )
221  {
222  const SwSection* pThisSection = nullptr;
223  const SwSection* pNextSection = nullptr;
224  const SwSectionFrame* pThisSectionFrame = m_rThis.FindSctFrame();
225  const SwSectionFrame* pNextSectionFrame = pNxt->FindSctFrame();
226 
227  if ( pThisSectionFrame )
228  pThisSection = pThisSectionFrame->GetSection();
229 
230  if ( pNextSectionFrame )
231  pNextSection = pNextSectionFrame->GetSection();
232 
233  if ( pThisSection != pNextSection )
234  bKeep = false;
235  }
236 
237  if ( bKeep )
238  {
239  SvxFormatBreakItem const* pBreak;
240  SwFormatPageDesc const* pPageDesc;
241  SwTabFrame* pTab = pNxt->IsInTab() ? pNxt->FindTabFrame() : nullptr;
242  if (pTab && (!m_rThis.IsInTab() || m_rThis.FindTabFrame() != pTab))
243  {
244  const SwAttrSet *const pSet = &pTab->GetFormat()->GetAttrSet();
245  pBreak = &pSet->GetBreak();
246  pPageDesc = &pSet->GetPageDesc();
247  }
248  else
249  {
250  pBreak = &pNxt->GetBreakItem();
251  pPageDesc = &pNxt->GetPageDescItem();
252  }
253 
254  if (pPageDesc->GetPageDesc())
255  bKeep = false;
256  else switch (pBreak->GetBreak())
257  {
258  case SvxBreak::ColumnBefore:
259  case SvxBreak::ColumnBoth:
260  case SvxBreak::PageBefore:
261  case SvxBreak::PageBoth:
262  bKeep = false;
263  break;
264  default: break;
265  }
266  }
267  }
268  }
269  }
270  return bKeep;
271 }
272 
274 {
275  // The return value helps deciding whether we need to flow back (3),
276  // or whether we can use the good old WouldFit (0, 1), or if
277  // it's reasonable to relocate and test-format (2).
278 
279  // Bit 1 in this case means that there are objects anchored to myself,
280  // bit 2 means that I have to evade other objects.
281 
282  // If a SurroundObj that desires to be wrapped around overlaps with the
283  // Rect, it's required to flow (because we can't guess the relationships).
284  // However it's possible for a test formatting to happen.
285  // If the SurroundObj is a Fly and I'm a Lower, or the Fly is a Lower of
286  // mine, then it doesn't matter.
287  // If the SurroundObj is anchored in a character bound Fly, and I'm not
288  // a Lower of that character bound Fly myself, then the Fly doesn't matter.
289 
290  // #32639# If the object is anchored with me, i can ignore it, because
291  // it's likely that it will follow me with the flow. A test formatting is
292  // not allowed in that case, however!
293  sal_uInt8 nRet = 0;
294  SwFlowFrame *pTmp = this;
295  do
296  { // If there are objects hanging either on me or on a follow, we can't
297  // do a test formatting, because paragraph bound objects wouldn't
298  // be properly considered, and character bound objects shouldn't
299  // be test formatted at all.
300  if( pTmp->GetFrame().GetDrawObjs() )
301  nRet = 1;
302  pTmp = pTmp->GetFollow();
303  } while ( !nRet && pTmp );
304  const SwSortedObjs *pObjs = pPage ? pPage->GetSortedObjs() : nullptr;
305  if (pObjs)
306  {
307  // #i28701# - new type <SwSortedObjs>
308  const SwSortedObjs &rObjs = *pObjs;
309  sal_uLong nIndex = ULONG_MAX;
310  for ( size_t i = 0; nRet < 3 && i < rObjs.size(); ++i )
311  {
312  // #i28701# - consider changed type of
313  // <SwSortedObjs> entries.
314  SwAnchoredObject* pObj = rObjs[i];
315  const SwFrameFormat& rFormat = pObj->GetFrameFormat();
316  const SwRect aRect( pObj->GetObjRect() );
317  if ( aRect.IsOver( rRect ) &&
318  rFormat.GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH )
319  {
320  if( m_rThis.IsLayoutFrame() && //Fly Lower of This?
321  Is_Lower_Of( &m_rThis, pObj->GetDrawObj() ) )
322  continue;
323  if( auto pFly = dynamic_cast<const SwFlyFrame*>(pObj) )
324  {
325  if ( pFly->IsAnLower( &m_rThis ) )//This Lower of Fly?
326  continue;
327  }
328 
329  const SwFrame* pAnchor = pObj->GetAnchorFrame();
330  if ( pAnchor == &m_rThis )
331  {
332  nRet |= 1;
333  continue;
334  }
335 
336  // Don't do this if the object is anchored behind me in the text
337  // flow, because then I wouldn't evade it.
338  if ( ::IsFrameInSameContext( pAnchor, &m_rThis ) )
339  {
340  if ( rFormat.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA )
341  {
342  // The index of the other one can be retrieved using the anchor attribute.
343  sal_uLong nTmpIndex = rFormat.GetAnchor().GetContentAnchor()->nNode.GetIndex();
344  // Now we're going to check whether the current paragraph before
345  // the anchor of the displacing object sits in the text. If this
346  // is the case, we don't try to evade it.
347  // The index is being determined via SwFormatAnchor, because it's
348  // getting quite expensive otherwise.
349  if( ULONG_MAX == nIndex )
350  {
351  const SwNode *pNode;
352  if (m_rThis.IsTextFrame())
353  pNode = static_cast<SwTextFrame&>(m_rThis).GetTextNodeFirst();
354  else if (m_rThis.IsNoTextFrame())
355  pNode = static_cast<SwNoTextFrame&>(m_rThis).GetNode();
356  else if( m_rThis.IsSctFrame() )
357  pNode = static_cast<SwSectionFormat*>(static_cast<SwSectionFrame&>(m_rThis).
358  GetFormat())->GetSectionNode();
359  else
360  {
361  assert(!m_rThis.IsContentFrame());
362  OSL_ENSURE( m_rThis.IsTabFrame(), "new FowFrame?" );
363  pNode = static_cast<SwTabFrame&>(m_rThis).GetTable()->
364  GetTabSortBoxes()[0]->GetSttNd()->FindTableNode();
365  }
366  nIndex = pNode->GetIndex();
367  }
368  if (nIndex < nTmpIndex &&
369  (!m_rThis.IsTextFrame() ||
370  !FrameContainsNode(static_cast<SwTextFrame&>(m_rThis), nTmpIndex)))
371  {
372  continue;
373  }
374  }
375  }
376  else
377  continue;
378 
379  nRet |= 2;
380  }
381  }
382  }
383  return nRet;
384 }
385 
389 {
390  // Cut the Start and all the neighbours; they are chained together and
391  // a handle to the first one is returned. Residuals are invalidated
392  // as appropriate.
393 
394  SwLayoutFrame *pLay = pStart->GetUpper();
395  if ( pLay->IsInFootnote() )
396  pLay = pLay->FindFootnoteFrame();
397 
398  // #i58846#
399  // <pPrepare( PREP_QUOVADIS )> only for frames in footnotes
400  if( pStart->IsInFootnote() )
401  {
402  SwFrame* pTmp = pStart->GetIndPrev();
403  if( pTmp )
404  pTmp->Prepare( PREP_QUOVADIS );
405  }
406 
407  // Just cut quickly and take care that we don't cause problems with the
408  // left-behinds. The pointers of the chain being cut can point who-knows where.
409  if ( pStart == pStart->GetUpper()->Lower() )
410  pStart->GetUpper()->m_pLower = nullptr;
411  if ( pStart->GetPrev() )
412  {
413  pStart->GetPrev()->mpNext = nullptr;
414  pStart->mpPrev = nullptr;
415  }
416 
417  if ( pLay->IsFootnoteFrame() )
418  {
419  if ( !pLay->Lower() && !pLay->IsColLocked() &&
420  !static_cast<SwFootnoteFrame*>(pLay)->IsBackMoveLocked() )
421  {
422  // tdf#101821 don't delete it while iterating over it
423  if (!pLay->IsDeleteForbidden())
424  {
425  pLay->Cut();
426  SwFrame::DestroyFrame(pLay);
427  }
428  // else: assume there is code on the stack to clean up empty
429  // footnote frames
430  // (don't go into the else branch below, it produces a disconnected
431  // footnote with null upper that can be returned by
432  // SwFootnoteBossFrame::FindFootnote() causing null pointer deref
433  // in SwTextFrame::ConnectFootnote()
434  }
435  else
436  {
437  bool bUnlock = !static_cast<SwFootnoteFrame*>(pLay)->IsBackMoveLocked();
438  static_cast<SwFootnoteFrame*>(pLay)->LockBackMove();
439  pLay->InvalidateSize();
440  pLay->Calc(pLay->getRootFrame()->GetCurrShell()->GetOut());
441  SwContentFrame *pCnt = pLay->ContainsContent();
442  while ( pCnt && pLay->IsAnLower( pCnt ) )
443  {
444  // It's possible for the ContentFrame to be locked, and we don't want
445  // to end up in an endless page migration, so we're not even
446  // going to call Calc!
447  OSL_ENSURE( pCnt->IsTextFrame(), "The Graphic has landed." );
448  if ( static_cast<SwTextFrame*>(pCnt)->IsLocked() ||
449  static_cast<SwTextFrame*>(pCnt)->GetFollow() == pStart )
450  break;
451  pCnt->Calc(pCnt->getRootFrame()->GetCurrShell()->GetOut());
452  pCnt = pCnt->GetNextContentFrame();
453  }
454  if( bUnlock )
455  static_cast<SwFootnoteFrame*>(pLay)->UnlockBackMove();
456  }
457  pLay = nullptr;
458  }
459  return pLay;
460 }
461 
464 bool SwFlowFrame::PasteTree( SwFrame *pStart, SwLayoutFrame *pParent, SwFrame *pSibling,
465  SwFrame *pOldParent )
466 {
467  // returns true if there's a LayoutFrame in the chain.
468  bool bRet = false;
469 
470  // The chain beginning with pStart is inserted before pSibling
471  // under the parent. We take care to invalidate as required.
472 
473  // I'm receiving a finished chain. We need to update the pointers for
474  // the beginning of the chain, then all the uppers and finally the end.
475  // On the way there, we invalidate as required.
476  if ( pSibling )
477  {
478  if ( nullptr != (pStart->mpPrev = pSibling->GetPrev()) )
479  pStart->GetPrev()->mpNext = pStart;
480  else
481  pParent->m_pLower = pStart;
482  pSibling->InvalidatePos_();
483  pSibling->InvalidatePrt_();
484  }
485  else
486  {
487  if ( nullptr == (pStart->mpPrev = pParent->Lower()) )
488  pParent->m_pLower = pStart;
489  else
490  //Modified for #i100782#,04/03/2009
491  //If the pParent has more than 1 child nodes, former design will
492  //ignore them directly without any collection work. It will make some
493  //dangling pointers. This lead the crash...
494  //The new design will find the last child of pParent in loop way, and
495  //add the pStart after the last child.
496  // pParent->Lower()->pNext = pStart;
497  {
498  SwFrame* pTemp = pParent->m_pLower;
499  while (pTemp)
500  {
501  if (pTemp->mpNext)
502  pTemp = pTemp->mpNext;
503  else
504  {
505  pStart->mpPrev = pTemp;
506  pTemp->mpNext = pStart;
507  break;
508  }
509  }
510  }
511  //End modification for #i100782#,04/03/2009
512 
513  // #i27145#
514  if ( pParent->IsSctFrame() )
515  {
516  // We have no sibling because pParent is a section frame and
517  // has just been created to contain some content. The printing
518  // area of the frame behind pParent has to be invalidated, so
519  // that the correct distance between pParent and the next frame
520  // can be calculated.
521  pParent->InvalidateNextPrtArea();
522  }
523  }
524  SwFrame *pFloat = pStart;
525  SwFrame *pLst = nullptr;
526  SwRectFnSet aRectFnSet(pParent);
527  SwTwips nGrowVal = 0;
528  do
529  { pFloat->mpUpper = pParent;
530  pFloat->InvalidateAll_();
531  pFloat->CheckDirChange();
532 
533  // I'm a friend of the TextFrame and thus am allowed to do many things.
534  // The CacheIdx idea seems to be a bit risky!
535  if ( pFloat->IsTextFrame() )
536  {
537  if ( static_cast<SwTextFrame*>(pFloat)->GetCacheIdx() != USHRT_MAX )
538  static_cast<SwTextFrame*>(pFloat)->Init(); // I'm his friend.
539  }
540  else
541  bRet = true;
542 
543  nGrowVal += aRectFnSet.GetHeight(pFloat->getFrameArea());
544  if ( pFloat->GetNext() )
545  pFloat = pFloat->GetNext();
546  else
547  {
548  pLst = pFloat;
549  pFloat = nullptr;
550  }
551  } while ( pFloat );
552 
553  if ( pSibling )
554  {
555  pLst->mpNext = pSibling;
556  pSibling->mpPrev = pLst;
557  if( pSibling->IsInFootnote() )
558  {
559  if( pSibling->IsSctFrame() )
560  pSibling = static_cast<SwSectionFrame*>(pSibling)->ContainsAny();
561  if( pSibling )
562  pSibling->Prepare( PREP_ERGOSUM );
563  }
564  }
565  if ( nGrowVal )
566  {
567  if ( pOldParent && pOldParent->IsBodyFrame() ) // For variable page height while browsing
568  pOldParent->Shrink( nGrowVal );
569  pParent->Grow( nGrowVal );
570  }
571 
572  if ( pParent->IsFootnoteFrame() )
573  static_cast<SwFootnoteFrame*>(pParent)->InvalidateNxtFootnoteCnts( pParent->FindPageFrame() );
574  return bRet;
575 }
576 
577 void SwFlowFrame::MoveSubTree( SwLayoutFrame* pParent, SwFrame* pSibling )
578 {
579  OSL_ENSURE( pParent, "No parent given." );
580  OSL_ENSURE( m_rThis.GetUpper(), "Where are we coming from?" );
581 
582  // Be economical with notifications if an action is running.
584  const SwViewShellImp *pImp = pSh ? pSh->Imp() : nullptr;
585  const bool bComplete = pImp && pImp->IsAction() && pImp->GetLayAction().IsComplete();
586 
587  if ( !bComplete )
588  {
589  SwFrame *pPre = m_rThis.GetIndPrev();
590  if ( pPre )
591  {
592  pPre->SetRetouche();
593  // #115759# - follow-up of #i26250#
594  // invalidate printing area of previous frame, if it's in a table
595  if ( pPre->GetUpper()->IsInTab() )
596  {
597  pPre->InvalidatePrt_();
598  }
599  pPre->InvalidatePage();
600  }
601  else
602  {
605  }
606  }
607 
608  SwPageFrame *pOldPage = m_rThis.FindPageFrame();
609 
610  SwLayoutFrame *pOldParent;
611  bool bInvaLay;
612 
613  {
614  //JoinLock pParent for the lifetime of the Cut/Paste call to avoid
615  //SwSectionFrame::MergeNext removing the pParent we're trying to reparent
616  //into
617  FlowFrameJoinLockGuard aJoinGuard(pParent);
618  SwFrameDeleteGuard aDeleteGuard(pParent);
619  pOldParent = CutTree( &m_rThis );
620  bInvaLay = PasteTree( &m_rThis, pParent, pSibling, pOldParent );
621  }
622 
623  // If, by cutting & pasting, an empty SectionFrame came into existence, it should
624  // disappear automatically.
625  SwSectionFrame *pSct;
626  // #126020# - adjust check for empty section
627  // #130797# - correct fix #126020#
628  if ( pOldParent && !pOldParent->Lower() &&
629  ( pOldParent->IsInSct() &&
630  !(pSct = pOldParent->FindSctFrame())->ContainsContent() &&
631  !pSct->ContainsAny( true ) ) )
632  {
633  pSct->DelEmpty( false );
634  }
635 
636  // If we're in a column section, we'd rather not call Calc "from below"
637  if( !m_rThis.IsInSct() &&
638  ( !m_rThis.IsInTab() || ( m_rThis.IsTabFrame() && !m_rThis.GetUpper()->IsInTab() ) ) )
640  else if( m_rThis.GetUpper()->IsSctFrame() )
641  {
642  SwSectionFrame* pTmpSct = static_cast<SwSectionFrame*>(m_rThis.GetUpper());
643  bool bOld = pTmpSct->IsContentLocked();
644  pTmpSct->SetContentLock( true );
645  pTmpSct->Calc(m_rThis.getRootFrame()->GetCurrShell()->GetOut());
646  if( !bOld )
647  pTmpSct->SetContentLock( false );
648  }
649  SwPageFrame *pPage = m_rThis.FindPageFrame();
650 
651  if ( pOldPage != pPage )
652  {
653  m_rThis.InvalidatePage( pPage );
654  if ( m_rThis.IsLayoutFrame() )
655  {
656  SwContentFrame *pCnt = static_cast<SwLayoutFrame*>(&m_rThis)->ContainsContent();
657  if ( pCnt )
658  pCnt->InvalidatePage( pPage );
659  }
660  else if ( pSh && pSh->GetDoc()->GetLineNumberInfo().IsRestartEachPage()
661  && pPage->FindFirstBodyContent() == &m_rThis )
662  {
664  }
665  }
666  if ( bInvaLay || (pSibling && pSibling->IsLayoutFrame()) )
667  m_rThis.GetUpper()->InvalidatePage( pPage );
668 }
669 
670 bool SwFlowFrame::IsAnFollow( const SwFlowFrame *pAssumed ) const
671 {
672  const SwFlowFrame *pFoll = this;
673  do
674  { if ( pAssumed == pFoll )
675  return true;
676  pFoll = pFoll->GetFollow();
677  } while ( pFoll );
678  return false;
679 }
680 
682 {
683  OSL_ENSURE( IsFollow(), "SwContentFrame::FindMaster(): !IsFollow" );
684 
685  const SwContentFrame* pPrec = static_cast<const SwContentFrame*>(SwFlowFrame::GetPrecede());
686 
687  if ( pPrec && pPrec->HasFollow() && pPrec->GetFollow() == this )
688  {
689  OSL_ENSURE( pPrec->IsTextFrame(), "NoTextFrame with follow found" );
690  return const_cast<SwTextFrame*>(static_cast< const SwTextFrame* >(pPrec));
691  }
692 
693  OSL_FAIL( "Follow is lost in Space." );
694  return nullptr;
695 }
696 
698 {
699  OSL_ENSURE( IsFollow(), "SwSectionFrame::FindMaster(): !IsFollow" );
700 
701  if (!m_pSection)
702  return nullptr;
703 
705  SwSectionFrame* pSect = aIter.First();
706  while ( pSect )
707  {
708  if (pSect->GetFollow() == this)
709  return pSect;
710  pSect = aIter.Next();
711  }
712 
713  OSL_FAIL( "Follow is lost in Space." );
714  return nullptr;
715 }
716 
717 SwTabFrame* SwTabFrame::FindMaster( bool bFirstMaster ) const
718 {
719  OSL_ENSURE( IsFollow(), "SwTabFrame::FindMaster(): !IsFollow" );
720 
721  SwIterator<SwTabFrame,SwFormat> aIter( *GetTable()->GetFrameFormat() );
722  SwTabFrame* pTab = aIter.First();
723  while ( pTab )
724  {
725  if ( bFirstMaster )
726  {
727  // Optimization. This makes code like this obsolete:
728  // while ( pTab->IsFollow() )
729  // pTab = pTab->FindMaster();
730 
731  if ( !pTab->IsFollow() )
732  {
733  SwTabFrame* pNxt = pTab;
734  while ( pNxt )
735  {
736  if ( pNxt->GetFollow() == this )
737  return pTab;
738  pNxt = pNxt->GetFollow();
739  }
740  }
741  }
742  else
743  {
744  if ( pTab->GetFollow() == this )
745  return pTab;
746  }
747 
748  pTab = aIter.Next();
749  }
750 
751  OSL_FAIL( "Follow is lost in Space." );
752  return nullptr;
753 }
754 
759 const SwLayoutFrame *SwFrame::GetLeaf( MakePageType eMakePage, bool bFwd,
760  const SwFrame *pAnch ) const
761 {
762  // No flow, no joy...
763  if ( !(IsInDocBody() || IsInFootnote() || IsInFly()) )
764  return nullptr;
765 
766  const SwFrame *pLeaf = this;
767  bool bFound = false;
768 
769  do
770  { pLeaf = const_cast<SwFrame*>(pLeaf)->GetLeaf( eMakePage, bFwd );
771 
772  if ( pLeaf &&
773  (!IsLayoutFrame() || !static_cast<const SwLayoutFrame*>(this)->IsAnLower( pLeaf )))
774  {
775  if ( pAnch->IsInDocBody() == pLeaf->IsInDocBody() &&
776  pAnch->IsInFootnote() == pLeaf->IsInFootnote() )
777  {
778  bFound = true;
779  }
780  }
781  } while ( !bFound && pLeaf );
782 
783  return static_cast<const SwLayoutFrame*>(pLeaf);
784 }
785 
787 {
788  if ( IsInFootnote() )
789  return bFwd ? GetNextFootnoteLeaf( eMakePage ) : GetPrevFootnoteLeaf( eMakePage );
790 
791  // #i53323#
792  // A frame could be inside a table AND inside a section.
793  // Thus, it has to be determined, which is the first parent.
794  bool bInTab( IsInTab() );
795  bool bInSct( IsInSct() );
796  if ( bInTab && bInSct )
797  {
798  const SwFrame* pUpperFrame( GetUpper() );
799  while ( pUpperFrame )
800  {
801  if ( pUpperFrame->IsTabFrame() )
802  {
803  // the table is the first.
804  bInSct = false;
805  break;
806  }
807  else if ( pUpperFrame->IsSctFrame() )
808  {
809  // the section is the first.
810  bInTab = false;
811  break;
812  }
813 
814  pUpperFrame = pUpperFrame->GetUpper();
815  }
816  }
817 
818  if ( bInTab && ( !IsTabFrame() || GetUpper()->IsCellFrame() ) ) // TABLE IN TABLE
819  return bFwd ? GetNextCellLeaf() : GetPrevCellLeaf();
820 
821  if ( bInSct )
822  return bFwd ? GetNextSctLeaf( eMakePage ) : GetPrevSctLeaf();
823 
824  return bFwd ? GetNextLeaf( eMakePage ) : GetPrevLeaf();
825 }
826 
828 {
829  // Now it's getting a bit complicated:
830 
831  // Maybe I'm bringing a Pagedesc myself; in that case,
832  // the pagedesc of the next page needs to correspond.
833  // Otherwise, I'll have to dig a bit deeper to see where
834  // the following Pagedesc is coming from.
835  // If the following page itself tells me that it's pagedesc
836  // is wrong, I can happily exchange it.
837  // If the page however thinks that it's pagedesc is correct,
838  // this doesn't mean it's useful to me:
839  // If the first BodyContent asks for a PageDesc or a PageBreak,
840  // I'll have to insert a new page - except the desired page is
841  // the correct one.
842  // If I inserted a new page, the problems only get started:
843  // because then it's likely for the next page to have been
844  // wrong and having been swapped because of that.
845  // This in turn means that I have a new (and correct) page,
846  // but the conditions to swap still apply.
847  // Way out of the situation: Try to preliminarily insert a
848  // new page once (empty pages are already inserted by InsertPage()
849  // if required)
850 
851  //My Pagedesc doesn't count if I'm a follow!
852  const SwPageDesc *pDesc = nullptr;
853  int nTmp = 0;
854  SwFlowFrame *pFlow = SwFlowFrame::CastFlowFrame( this );
855  if ( !pFlow || !pFlow->IsFollow() )
856  {
857  const SwFormatPageDesc &rFormatDesc = GetPageDescItem();
858  pDesc = rFormatDesc.GetPageDesc();
859  if( pDesc )
860  {
861  if( !pDesc->GetRightFormat() )
862  nTmp = 2;
863  else if( !pDesc->GetLeftFormat() )
864  nTmp = 1;
865  else if( rFormatDesc.GetNumOffset() )
866  nTmp = rFormatDesc.GetNumOffset().get();
867  }
868  }
869 
870  // Does the Content bring a Pagedesc or do we need the
871  // virtual page number of the new layout leaf?
872  // PageDesc isn't allowed with Follows
873  const bool bOdd = nTmp ? (nTmp % 2) !=0 : pNew->OnRightPage();
874  if ( !pDesc )
875  pDesc = pNew->FindPageDesc();
876 
877  bool bFirst = pNew->OnFirstPage();
878 
879  const SwFlowFrame *pNewFlow = pNew->FindFirstBodyContent();
880  // Did we find ourselves?
881  if( pNewFlow == pFlow )
882  pNewFlow = nullptr;
883  if ( pNewFlow && pNewFlow->GetFrame().IsInTab() )
884  pNewFlow = pNewFlow->GetFrame().FindTabFrame();
885  const SwPageDesc *pNewDesc= ( pNewFlow && !pNewFlow->IsFollow() )
886  ? pNewFlow->GetFrame().GetPageDescItem().GetPageDesc()
887  : nullptr;
888 
889  SAL_INFO( "sw.pageframe", "WrongPageDesc p: " << pNew << " phys: " << pNew->GetPhyPageNum() );
890  SAL_INFO( "sw.pageframe", "WrongPageDesc " << pNew->GetPageDesc() << " " << pDesc );
891  SAL_INFO( "sw.pageframe", "WrongPageDesc odd: " << bOdd
892  << " first: " << bFirst << " " << pNew->GetFormat() << " == "
893  << (bOdd ? pDesc->GetRightFormat(bFirst) : pDesc->GetLeftFormat(bFirst)) << " "
894  << (bOdd ? pDesc->GetLeftFormat(bFirst) : pDesc->GetRightFormat(bFirst)) );
895 
896  return (pNew->GetPageDesc() != pDesc) // own desc ?
897  || (pNew->GetFormat() !=
898  (bOdd ? pDesc->GetRightFormat(bFirst) : pDesc->GetLeftFormat(bFirst)))
899  || (pNewDesc && pNewDesc == pDesc);
900 }
901 
904 {
905  OSL_ENSURE( !IsInFootnote(), "GetNextLeaf(), don't call me for Footnote." );
906  OSL_ENSURE( !IsInSct(), "GetNextLeaf(), don't call me for Sections." );
907 
908  const bool bBody = IsInDocBody(); // If I'm coming from the DocBody,
909  // I want to end up in the body.
910 
911  // It doesn't make sense to insert pages, as we only want to search the
912  // chain.
913  if( IsInFly() )
914  eMakePage = MAKEPAGE_NONE;
915 
916  // For tables, we just take the big leap. A simple GetNext would
917  // iterate through the first cells and, in turn, all other cells.
918  SwLayoutFrame *pLayLeaf = nullptr;
919  if ( IsTabFrame() )
920  {
921  SwFrame *const pTmp = static_cast<SwTabFrame*>(this)->FindLastContentOrTable();
922  if ( pTmp )
923  pLayLeaf = pTmp->GetUpper();
924  }
925  if ( !pLayLeaf )
926  pLayLeaf = GetNextLayoutLeaf();
927 
928  SwLayoutFrame *pOldLayLeaf = nullptr; // Make sure that we don't have to
929  // start searching from top when we
930  // have a freshly created page.
931  bool bNewPg = false; // Only insert a new page once.
932 
933  while ( true )
934  {
935  if ( pLayLeaf )
936  {
937  // There's yet another LayoutFrame. Let's see if it's ready to host
938  // me as well.
939  // It only needs to be of the same kind like my starting point
940  // (DocBody or Footnote respectively)
941  if ( pLayLeaf->FindPageFrame()->IsFootnotePage() )
942  { // If I ended up at the end note pages, we're done.
943  pLayLeaf = nullptr;
944  continue;
945  }
946  if ( (bBody && !pLayLeaf->IsInDocBody()) || pLayLeaf->IsInTab()
947  || pLayLeaf->IsInSct() )
948  {
949  // They don't want me! Try again
950  pOldLayLeaf = pLayLeaf;
951  pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
952  continue;
953  }
954 
955  // I'm wanted, therefore I'm done. However, it may still be that,
956  // during a page break, the page type isn't the desired one. In that
957  // case we have to insert a page of the correct type.
958 
959  if( !IsFlowFrame() && ( eMakePage == MAKEPAGE_NONE ||
960  eMakePage==MAKEPAGE_APPEND || eMakePage==MAKEPAGE_NOSECTION ) )
961  return pLayLeaf;
962 
963  SwPageFrame *pNew = pLayLeaf->FindPageFrame();
964  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
965  // #111704# The pagedesc check does not make sense for frames in fly frames
966  if ( pNew != FindPageFrame() && !bNewPg && !IsInFly() &&
967  // #i46683#
968  // Do not consider page descriptions in browse mode (since
969  // MoveBwd ignored them)
970  !(pSh && pSh->GetViewOptions()->getBrowseMode() ) )
971  {
972  if( WrongPageDesc( pNew ) )
973  {
974  SwFootnoteContFrame *pCont = pNew->FindFootnoteCont();
975  if( pCont )
976  {
977  // If the reference of the first footnote of this page
978  // lies before the page, we'd rather not insert a new page.
979  // (Bug #55620#)
980  SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower());
981  if( pFootnote && pFootnote->GetRef() )
982  {
983  const sal_uInt16 nRefNum = pNew->GetPhyPageNum();
984  if( pFootnote->GetRef()->GetPhyPageNum() < nRefNum )
985  break;
986  }
987  }
988  //Gotcha! The following page is wrong, therefore we need to
989  //insert a new one.
990  if ( eMakePage == MAKEPAGE_INSERT )
991  {
992  bNewPg = true;
993 
994  SwPageFrame *pPg = pOldLayLeaf ?
995  pOldLayLeaf->FindPageFrame() : nullptr;
996  if ( pPg && pPg->IsEmptyPage() )
997  // Don't insert behind. Insert before the EmptyPage.
998  pPg = static_cast<SwPageFrame*>(pPg->GetPrev());
999 
1000  if ( !pPg || pPg == pNew )
1001  pPg = FindPageFrame();
1002 
1003  InsertPage( pPg, false );
1004  pLayLeaf = GetNextLayoutLeaf();
1005  pOldLayLeaf = nullptr;
1006  continue;
1007  }
1008  else
1009  pLayLeaf = nullptr;
1010  }
1011  }
1012  break;
1013  }
1014  else
1015  {
1016  // There's no other matching LayoutFrame, so we have to insert
1017  // a new page.
1018  if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
1019  {
1020  InsertPage(
1021  pOldLayLeaf ? pOldLayLeaf->FindPageFrame() : FindPageFrame(),
1022  false );
1023 
1024  // And again from the start.
1025  pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
1026  }
1027  else
1028  break;
1029  }
1030  }
1031  return pLayLeaf;
1032 }
1033 
1036 {
1037  OSL_ENSURE( !IsInFootnote(), "GetPrevLeaf(), don't call me for Footnote." );
1038 
1039  const bool bBody = IsInDocBody(); // If I'm coming from the DocBody,
1040  // I want to end up in the body.
1041  const bool bFly = IsInFly();
1042 
1043  SwLayoutFrame *pLayLeaf = GetPrevLayoutLeaf();
1044  SwLayoutFrame *pPrevLeaf = nullptr;
1045 
1046  while ( pLayLeaf )
1047  {
1048  if ( pLayLeaf->IsInTab() || // Never go into tables.
1049  pLayLeaf->IsInSct() ) // Same goes for sections!
1050  pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1051  else if ( bBody && pLayLeaf->IsInDocBody() )
1052  {
1053  if ( pLayLeaf->Lower() )
1054  break;
1055  pPrevLeaf = pLayLeaf;
1056  pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1057  if ( pLayLeaf )
1059  }
1060  else if ( bFly )
1061  break; //Contents in Flys should accept any layout leaf.
1062  else
1063  pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
1064  }
1065  return pLayLeaf ? pLayLeaf : pPrevLeaf;
1066 }
1067 
1069 {
1070  // true: The FlowFrame must respect the a border of the predecessor, also needs
1071  // to insert a break if required.
1072 
1074  const SwViewShell *pSh = m_rThis.getRootFrame()->GetCurrShell();
1075  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
1076  return false;
1077 
1078  SwFrame *pPre = m_rThis.FindPrev();
1079 
1080  if ( pPre && pPre->GetDrawObjs() )
1081  {
1082  OSL_ENSURE( SwFlowFrame::CastFlowFrame( pPre ), "new flowfrm?" );
1083  if( SwFlowFrame::CastFlowFrame( pPre )->IsAnFollow( this ) )
1084  return false;
1085  SwLayoutFrame* pPreUp = pPre->GetUpper();
1086  // If the upper is a SectionFrame, or a column of a SectionFrame, we're
1087  // allowed to protrude out of it. However, we need to respect the
1088  // Upper of the SectionFrame.
1089  if( pPreUp->IsInSct() )
1090  {
1091  if( pPreUp->IsSctFrame() )
1092  pPreUp = pPreUp->GetUpper();
1093  else if( pPreUp->IsColBodyFrame() &&
1094  pPreUp->GetUpper()->GetUpper()->IsSctFrame() )
1095  pPreUp = pPreUp->GetUpper()->GetUpper()->GetUpper();
1096  }
1097  // #i26945# - re-factoring
1098  // use <GetVertPosOrientFrame()> to determine, if object has followed the
1099  // text flow to the next layout frame
1100  for (SwAnchoredObject* pObj : *pPre->GetDrawObjs())
1101  {
1102  // #i28701# - consider changed type of
1103  // <SwSortedObjs> entries.
1104  // OD 2004-01-20 #110582# - do not consider hidden objects
1105  // #i26945# - do not consider object, which
1106  // doesn't follow the text flow.
1107  if ( pObj->GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId(
1108  pObj->GetDrawObj()->GetLayer() ) &&
1109  pObj->GetFrameFormat().GetFollowTextFlow().GetValue() )
1110  {
1111  const SwLayoutFrame* pVertPosOrientFrame = pObj->GetVertPosOrientFrame();
1112  if ( pVertPosOrientFrame &&
1113  pPreUp != pVertPosOrientFrame &&
1114  !pPreUp->IsAnLower( pVertPosOrientFrame ) )
1115  {
1116  return true;
1117  }
1118  }
1119  }
1120  }
1121  return false;
1122 }
1123 
1139 bool SwFlowFrame::IsPageBreak( bool bAct ) const
1140 {
1141  if ( !IsFollow() && m_rThis.IsInDocBody() &&
1142  ( !m_rThis.IsInTab() || ( m_rThis.IsTabFrame() && !m_rThis.GetUpper()->IsInTab() ) ) ) // i66968
1143  {
1144  const SwViewShell *pSh = m_rThis.getRootFrame()->GetCurrShell();
1145  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
1146  return false;
1147 
1148  // Determine predecessor
1149  const SwFrame *pPrev = m_rThis.FindPrev();
1150  while ( pPrev && ( !pPrev->IsInDocBody() ||
1151  ( pPrev->IsTextFrame() && static_cast<const SwTextFrame*>(pPrev)->IsHiddenNow() ) ) )
1152  pPrev = pPrev->FindPrev();
1153 
1154  if ( pPrev )
1155  {
1156  OSL_ENSURE( pPrev->IsInDocBody(), "IsPageBreak: Not in DocBody?" );
1157  if ( bAct )
1158  { if ( m_rThis.FindPageFrame() == pPrev->FindPageFrame() )
1159  return false;
1160  }
1161  else
1162  { if ( m_rThis.FindPageFrame() != pPrev->FindPageFrame() )
1163  return false;
1164  }
1165 
1166  //for compatibility, also break at column break if no columns exist
1168  const bool bTreatSingleColumnBreakAsPageBreak = rIDSA.get(DocumentSettingId::TREAT_SINGLE_COLUMN_BREAK_AS_PAGE_BREAK);
1169  const SvxBreak eBreak = m_rThis.GetBreakItem().GetBreak();
1170  if ( eBreak == SvxBreak::PageBefore ||
1171  eBreak == SvxBreak::PageBoth ||
1172  ( bTreatSingleColumnBreakAsPageBreak && eBreak == SvxBreak::ColumnBefore && !m_rThis.FindColFrame() ))
1173  return true;
1174  else
1175  {
1176  const SvxBreak &ePrB = pPrev->GetBreakItem().GetBreak();
1177  if ( ePrB == SvxBreak::PageAfter ||
1178  ePrB == SvxBreak::PageBoth ||
1180  {
1181  return true;
1182  }
1183  }
1184  }
1185  }
1186  return false;
1187 }
1188 
1202 bool SwFlowFrame::IsColBreak( bool bAct ) const
1203 {
1204  if ( !IsFollow() && (m_rThis.IsMoveable() || bAct) )
1205  {
1206  const SwFrame *pCol = m_rThis.FindColFrame();
1207  if ( pCol )
1208  {
1209  // Determine predecessor
1210  const SwFrame *pPrev = m_rThis.FindPrev();
1211  while( pPrev && ( ( !pPrev->IsInDocBody() && !m_rThis.IsInFly() && !m_rThis.FindFooterOrHeader() ) ||
1212  ( pPrev->IsTextFrame() && static_cast<const SwTextFrame*>(pPrev)->IsHiddenNow() ) ) )
1213  pPrev = pPrev->FindPrev();
1214 
1215  if ( pPrev )
1216  {
1217  if ( bAct )
1218  { if ( pCol == pPrev->FindColFrame() )
1219  return false;
1220  }
1221  else
1222  { if ( pCol != pPrev->FindColFrame() )
1223  return false;
1224  }
1225 
1226  const SvxBreak eBreak = m_rThis.GetBreakItem().GetBreak();
1227  if ( eBreak == SvxBreak::ColumnBefore ||
1228  eBreak == SvxBreak::ColumnBoth )
1229  return true;
1230  else
1231  {
1232  const SvxBreak &ePrB = pPrev->GetBreakItem().GetBreak();
1233  if ( ePrB == SvxBreak::ColumnAfter ||
1234  ePrB == SvxBreak::ColumnBoth )
1235  return true;
1236  }
1237  }
1238  }
1239  }
1240  return false;
1241 }
1242 
1243 bool SwFlowFrame::HasParaSpaceAtPages( bool bSct ) const
1244 {
1245  if( m_rThis.IsInSct() )
1246  {
1247  const SwFrame* pTmp = m_rThis.GetUpper();
1248  while( pTmp )
1249  {
1250  if( pTmp->IsCellFrame() || pTmp->IsFlyFrame() ||
1251  pTmp->IsFooterFrame() || pTmp->IsHeaderFrame() ||
1252  ( pTmp->IsFootnoteFrame() && !static_cast<const SwFootnoteFrame*>(pTmp)->GetMaster() ) )
1253  return true;
1254  if( pTmp->IsPageFrame() )
1255  return !pTmp->GetPrev() || IsPageBreak(true);
1256  if( pTmp->IsColumnFrame() && pTmp->GetPrev() )
1257  return IsColBreak( true );
1258  if( pTmp->IsSctFrame() && ( !bSct || pTmp->GetPrev() ) )
1259  return false;
1260  pTmp = pTmp->GetUpper();
1261  }
1262  OSL_FAIL( "HasParaSpaceAtPages: Where's my page?" );
1263  return false;
1264  }
1265  if( !m_rThis.IsInDocBody() || ( m_rThis.IsInTab() && !m_rThis.IsTabFrame()) ||
1266  IsPageBreak( true ) || ( m_rThis.FindColFrame() && IsColBreak( true ) ) )
1267  return true;
1268  const SwFrame* pTmp = m_rThis.FindColFrame();
1269  if( pTmp )
1270  {
1271  if( pTmp->GetPrev() )
1272  return false;
1273  }
1274  else
1275  pTmp = &m_rThis;
1276  pTmp = pTmp->FindPageFrame();
1277  return pTmp && !pTmp->GetPrev();
1278 }
1279 
1285 const SwFrame* SwFlowFrame::GetPrevFrameForUpperSpaceCalc_( const SwFrame* _pProposedPrevFrame ) const
1286 {
1287  const SwFrame* pPrevFrame = _pProposedPrevFrame
1288  ? _pProposedPrevFrame
1289  : m_rThis.GetPrev();
1290 
1291  // Skip hidden paragraphs and empty sections
1292  while ( pPrevFrame &&
1293  ( ( pPrevFrame->IsTextFrame() &&
1294  static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) ||
1295  ( pPrevFrame->IsSctFrame() &&
1296  !static_cast<const SwSectionFrame*>(pPrevFrame)->GetSection() ) ) )
1297  {
1298  pPrevFrame = pPrevFrame->GetPrev();
1299  }
1300 
1301  // Special case: no direct previous frame is found but frame is in footnote
1302  // Search for a previous frame in previous footnote,
1303  // if frame isn't in a section, which is also in the footnote
1304  if ( !pPrevFrame && m_rThis.IsInFootnote() &&
1305  ( m_rThis.IsSctFrame() ||
1307  {
1308  const SwFootnoteFrame* pPrevFootnoteFrame =
1309  static_cast<const SwFootnoteFrame*>(m_rThis.FindFootnoteFrame()->GetPrev());
1310  if ( pPrevFootnoteFrame )
1311  {
1312  pPrevFrame = pPrevFootnoteFrame->GetLastLower();
1313 
1314  // Skip hidden paragraphs and empty sections
1315  while ( pPrevFrame &&
1316  ( ( pPrevFrame->IsTextFrame() &&
1317  static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) ||
1318  ( pPrevFrame->IsSctFrame() &&
1319  !static_cast<const SwSectionFrame*>(pPrevFrame)->GetSection() ) ) )
1320  {
1321  pPrevFrame = pPrevFrame->GetPrev();
1322  }
1323  }
1324  }
1325  // Special case: found previous frame is a section
1326  // Search for the last content in the section
1327  if( pPrevFrame && pPrevFrame->IsSctFrame() )
1328  {
1329  const SwSectionFrame* pPrevSectFrame =
1330  static_cast<const SwSectionFrame*>(pPrevFrame);
1331  pPrevFrame = pPrevSectFrame->FindLastContent();
1332  // If the last content is in a table _inside_ the section,
1333  // take the table herself.
1334  // OD 2004-02-18 #106629# - correction:
1335  // Check directly, if table is inside table, instead of indirectly
1336  // by checking, if section isn't inside a table
1337  if ( pPrevFrame && pPrevFrame->IsInTab() )
1338  {
1339  const SwTabFrame* pTableFrame = pPrevFrame->FindTabFrame();
1340  if ( pPrevSectFrame->IsAnLower( pTableFrame ) )
1341  {
1342  pPrevFrame = pTableFrame;
1343  }
1344  }
1345  // OD 2004-02-18 #106629# correction: skip hidden text frames
1346  while ( pPrevFrame &&
1347  pPrevFrame->IsTextFrame() &&
1348  static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() )
1349  {
1350  pPrevFrame = pPrevFrame->GetPrev();
1351  }
1352  }
1353 
1354  return pPrevFrame;
1355 }
1356 
1358 static bool lcl_IdenticalStyles(const SwFrame* pPrevFrame, const SwFrame* pFrame)
1359 {
1360  SwTextFormatColl *pPrevFormatColl = nullptr;
1361  if (pPrevFrame && pPrevFrame->IsTextFrame())
1362  {
1363  const SwTextFrame *pTextFrame = static_cast< const SwTextFrame * >( pPrevFrame );
1364  pPrevFormatColl = dynamic_cast<SwTextFormatColl*>(
1365  pTextFrame->GetTextNodeForParaProps()->GetFormatColl());
1366  }
1367 
1368  bool bIdenticalStyles = false;
1369  if (pFrame && pFrame->IsTextFrame())
1370  {
1371  const SwTextFrame *pTextFrame = static_cast< const SwTextFrame * >( pFrame );
1372  SwTextFormatColl *const pFormatColl = dynamic_cast<SwTextFormatColl*>(
1373  pTextFrame->GetTextNodeForParaProps()->GetFormatColl());
1374  bIdenticalStyles = pPrevFormatColl == pFormatColl;
1375  }
1376  return bIdenticalStyles;
1377 }
1378 
1379 static bool lcl_getContextualSpacing(const SwFrame* pPrevFrame)
1380 {
1381  bool bRet;
1382  auto pAccess = std::make_unique<SwBorderAttrAccess>(SwFrame::GetCache(), pPrevFrame);
1383  const SwBorderAttrs *pAttrs = pAccess->Get();
1384 
1385  bRet = pAttrs->GetULSpace().GetContext();
1386 
1387  return bRet;
1388 }
1389 
1390 // OD 2004-03-12 #i11860# - add 3rd parameter <_bConsiderGrid>
1392  const SwFrame* pPr,
1393  const bool _bConsiderGrid ) const
1394 {
1395  // OD 2004-03-10 #i11860# - use new method <GetPrevFrameForUpperSpaceCalc(..)>
1396  const SwFrame* pPrevFrame = GetPrevFrameForUpperSpaceCalc_( pPr );
1397 
1398  std::unique_ptr<SwBorderAttrAccess> pAccess;
1399  SwFrame* pOwn;
1400  if( !pAttrs )
1401  {
1402  if( m_rThis.IsSctFrame() )
1403  {
1404  SwSectionFrame* pFoll = &static_cast<SwSectionFrame&>(m_rThis);
1405  do
1406  pOwn = pFoll->ContainsAny();
1407  while( !pOwn && nullptr != ( pFoll = pFoll->GetFollow() ) );
1408  if( !pOwn )
1409  return 0;
1410  }
1411  else
1412  pOwn = &m_rThis;
1413  pAccess = std::make_unique<SwBorderAttrAccess>(SwFrame::GetCache(), pOwn);
1414  pAttrs = pAccess->Get();
1415  }
1416  else
1417  {
1418  pOwn = &m_rThis;
1419  }
1420  SwTwips nUpper = 0;
1421  // OD 06.01.2004 #i11859#
1422  {
1424  if( pPrevFrame )
1425  {
1426  const bool bUseFormerLineSpacing = rIDSA.get(DocumentSettingId::OLD_LINE_SPACING);
1427  const bool bContextualSpacing = pAttrs->GetULSpace().GetContext()
1428  && lcl_getContextualSpacing(pPrevFrame)
1429  && lcl_IdenticalStyles(pPrevFrame, &m_rThis);
1430 
1431  // OD 2004-03-10 #i11860# - use new method to determine needed spacing
1432  // values of found previous frame and use these values.
1433  SwTwips nPrevLowerSpace = 0;
1434  SwTwips nPrevLineSpacing = 0;
1435  // #i102458#
1436  bool bPrevLineSpacingPorportional = false;
1437  GetSpacingValuesOfFrame( (*pPrevFrame),
1438  nPrevLowerSpace, nPrevLineSpacing,
1439  bPrevLineSpacingPorportional );
1441  {
1442  nUpper = bContextualSpacing ? 0 : nPrevLowerSpace + pAttrs->GetULSpace().GetUpper();
1443  SwTwips nAdd = nPrevLineSpacing;
1444  // OD 07.01.2004 #i11859# - consideration of the line spacing
1445  // for the upper spacing of a text frame
1446  if ( bUseFormerLineSpacing )
1447  {
1448  // former consideration
1449  if ( pOwn->IsTextFrame() )
1450  {
1451  nAdd = std::max( nAdd, static_cast<SwTextFrame*>(pOwn)->GetLineSpace() );
1452  }
1453  nUpper += nAdd;
1454  }
1455  else
1456  {
1457  // new consideration:
1458  // Only the proportional line spacing of the previous
1459  // text frame is considered for the upper spacing and
1460  // the line spacing values are add up instead of
1461  // building its maximum.
1462  if ( pOwn->IsTextFrame() )
1463  {
1464  // #i102458#
1465  // Correction:
1466  // A proportional line spacing of the previous text frame
1467  // is added up to an own leading line spacing.
1468  // Otherwise, the maximum of the leading line spacing
1469  // of the previous text frame and the own leading line
1470  // spacing is built.
1471  if ( bPrevLineSpacingPorportional )
1472  {
1473  nAdd += static_cast<SwTextFrame*>(pOwn)->GetLineSpace( true );
1474  }
1475  else
1476  {
1477  nAdd = std::max( nAdd, static_cast<SwTextFrame*>(pOwn)->GetLineSpace( true ) );
1478  }
1479  }
1480  nUpper += nAdd;
1481  }
1482  }
1483  else
1484  {
1485  nUpper = bContextualSpacing ? 0 : std::max(static_cast<long>(nPrevLowerSpace),
1486  static_cast<long>(pAttrs->GetULSpace().GetUpper()) );
1487  // OD 07.01.2004 #i11859# - consideration of the line spacing
1488  // for the upper spacing of a text frame
1489  if ( bUseFormerLineSpacing )
1490  {
1491  // former consideration
1492  if ( pOwn->IsTextFrame() )
1493  nUpper = std::max( nUpper, static_cast<SwTextFrame*>(pOwn)->GetLineSpace() );
1494  if ( nPrevLineSpacing != 0 )
1495  {
1496  nUpper = std::max( nUpper, nPrevLineSpacing );
1497  }
1498  }
1499  else
1500  {
1501  // new consideration:
1502  // Only the proportional line spacing of the previous
1503  // text frame is considered for the upper spacing and
1504  // the line spacing values are add up and added to
1505  // the paragraph spacing instead of building the
1506  // maximum of the line spacings and the paragraph spacing.
1507  SwTwips nAdd = nPrevLineSpacing;
1508  if ( pOwn->IsTextFrame() )
1509  {
1510  // #i102458#
1511  // Correction:
1512  // A proportional line spacing of the previous text frame
1513  // is added up to an own leading line spacing.
1514  // Otherwise, the maximum of the leading line spacing
1515  // of the previous text frame and the own leading line
1516  // spacing is built.
1517  if ( bPrevLineSpacingPorportional )
1518  {
1519  nAdd += static_cast<SwTextFrame*>(pOwn)->GetLineSpace( true );
1520  }
1521  else
1522  {
1523  nAdd = std::max( nAdd, static_cast<SwTextFrame*>(pOwn)->GetLineSpace( true ) );
1524  }
1525  }
1526  nUpper += nAdd;
1527  }
1528  }
1529  }
1532  {
1533  nUpper = pAttrs->GetULSpace().GetUpper();
1534  }
1535  }
1536 
1537  // OD 2004-02-26 #i25029# - pass previous frame <pPrevFrame>
1538  // to method <GetTopLine(..)>, if parameter <pPr> is set.
1539  // Note: parameter <pPr> is set, if method is called from <SwTextFrame::WouldFit(..)>
1540  nUpper += pAttrs->GetTopLine( m_rThis, (pPr ? pPrevFrame : nullptr) );
1541 
1542  // OD 2004-03-12 #i11860# - consider value of new parameter <_bConsiderGrid>
1543  // and use new method <GetUpperSpaceAmountConsideredForPageGrid(..)>
1544 
1545  //consider grid in square page mode
1546  if ( _bConsiderGrid && m_rThis.GetUpper()->GetFormat()->GetDoc()->IsSquaredPageMode() )
1547  {
1548  nUpper += GetUpperSpaceAmountConsideredForPageGrid_( nUpper );
1549  }
1550  return nUpper;
1551 }
1552 
1560  const SwTwips _nUpperSpaceWithoutGrid ) const
1561 {
1562  SwTwips nUpperSpaceAmountConsideredForPageGrid = 0;
1563 
1564  if ( m_rThis.IsInDocBody() && m_rThis.GetAttrSet()->GetParaGrid().GetValue() )
1565  {
1566  const SwPageFrame* pPageFrame = m_rThis.FindPageFrame();
1567  SwTextGridItem const*const pGrid(GetGridItem(pPageFrame));
1568  if( pGrid )
1569  {
1570  const SwFrame* pBodyFrame = pPageFrame->FindBodyCont();
1571  if ( pBodyFrame )
1572  {
1573  const long nGridLineHeight =
1574  pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
1575 
1576  SwRectFnSet aRectFnSet(&m_rThis);
1577  const SwTwips nBodyPrtTop = aRectFnSet.GetPrtTop(*pBodyFrame);
1578  const SwTwips nProposedPrtTop =
1579  aRectFnSet.YInc( aRectFnSet.GetTop(m_rThis.getFrameArea()),
1580  _nUpperSpaceWithoutGrid );
1581 
1582  const SwTwips nSpaceAbovePrtTop =
1583  aRectFnSet.YDiff( nProposedPrtTop, nBodyPrtTop );
1584  const SwTwips nSpaceOfCompleteLinesAbove =
1585  nGridLineHeight * ( nSpaceAbovePrtTop / nGridLineHeight );
1586  SwTwips nNewPrtTop =
1587  aRectFnSet.YInc( nBodyPrtTop, nSpaceOfCompleteLinesAbove );
1588  if ( aRectFnSet.YDiff( nProposedPrtTop, nNewPrtTop ) > 0 )
1589  {
1590  nNewPrtTop = aRectFnSet.YInc( nNewPrtTop, nGridLineHeight );
1591  }
1592 
1593  const SwTwips nNewUpperSpace =
1594  aRectFnSet.YDiff( nNewPrtTop,
1595  aRectFnSet.GetTop(m_rThis.getFrameArea()) );
1596 
1597  nUpperSpaceAmountConsideredForPageGrid =
1598  nNewUpperSpace - _nUpperSpaceWithoutGrid;
1599 
1600  OSL_ENSURE( nUpperSpaceAmountConsideredForPageGrid >= 0,
1601  "<SwFlowFrame::GetUpperSpaceAmountConsideredForPageGrid(..)> - negative space considered for page grid!" );
1602  }
1603  }
1604  }
1605  return nUpperSpaceAmountConsideredForPageGrid;
1606 }
1607 
1614 {
1615  SwTwips nUpperSpaceAmountOfPrevFrame = 0;
1616 
1617  const SwFrame* pPrevFrame = GetPrevFrameForUpperSpaceCalc_();
1618  if ( pPrevFrame )
1619  {
1620  SwTwips nPrevLowerSpace = 0;
1621  SwTwips nPrevLineSpacing = 0;
1622  // #i102458#
1623  bool bDummy = false;
1624  GetSpacingValuesOfFrame( (*pPrevFrame), nPrevLowerSpace, nPrevLineSpacing, bDummy );
1625  if ( nPrevLowerSpace > 0 || nPrevLineSpacing > 0 )
1626  {
1628  if ( rIDSA.get(DocumentSettingId::PARA_SPACE_MAX) ||
1630  {
1631  nUpperSpaceAmountOfPrevFrame = nPrevLowerSpace + nPrevLineSpacing;
1632  }
1633  else
1634  {
1635  nUpperSpaceAmountOfPrevFrame = std::max( nPrevLowerSpace, nPrevLineSpacing );
1636  }
1637  }
1638  }
1639 
1640  return nUpperSpaceAmountOfPrevFrame;
1641 }
1642 
1650 {
1651  SwTwips nUpperSpaceAmountConsideredForPrevFrameAndPageGrid = 0;
1652 
1654  {
1655  nUpperSpaceAmountConsideredForPrevFrameAndPageGrid =
1658  ? GetUpperSpaceAmountConsideredForPageGrid_( CalcUpperSpace( nullptr, nullptr, false ) )
1659  : 0 );
1660  }
1661 
1662  return nUpperSpaceAmountConsideredForPrevFrameAndPageGrid;
1663 }
1664 
1670 {
1671  SwTwips nLowerSpace = 0;
1672 
1673  std::unique_ptr<SwBorderAttrAccess> pAttrAccess;
1674  if ( !_pAttrs )
1675  {
1676  pAttrAccess = std::make_unique<SwBorderAttrAccess>(SwFrame::GetCache(), &m_rThis);
1677  _pAttrs = pAttrAccess->Get();
1678  }
1679 
1680  bool bCommonBorder = true;
1681  if ( m_rThis.IsInSct() && m_rThis.GetUpper()->IsColBodyFrame() )
1682  {
1683  const SwSectionFrame* pSectFrame = m_rThis.FindSctFrame();
1684  bCommonBorder = pSectFrame->GetFormat()->GetBalancedColumns().GetValue();
1685  }
1686  nLowerSpace = bCommonBorder ?
1687  _pAttrs->GetBottomLine( m_rThis ) :
1688  _pAttrs->CalcBottomLine();
1689 
1690  // #i26250#
1691  // - correct consideration of table frames
1692  // - use new method <CalcAddLowerSpaceAsLastInTableCell(..)>
1693  if ( ( ( m_rThis.IsTabFrame() && m_rThis.GetUpper()->IsInTab() ) ||
1694  // #115759# - no lower spacing, if frame has a follow
1695  ( m_rThis.IsInTab() && !GetFollow() ) ) &&
1696  !m_rThis.GetIndNext() )
1697  {
1698  nLowerSpace += CalcAddLowerSpaceAsLastInTableCell( _pAttrs );
1699  }
1700 
1701  return nLowerSpace;
1702 }
1703 
1710  const SwBorderAttrs* _pAttrs ) const
1711 {
1712  SwTwips nAdditionalLowerSpace = 0;
1713 
1715  {
1716  const SwFrame* pFrame = &m_rThis;
1717  if ( pFrame->IsSctFrame() )
1718  {
1719  const SwSectionFrame* pSectFrame = static_cast<const SwSectionFrame*>(pFrame);
1720  pFrame = pSectFrame->FindLastContent();
1721  if ( pFrame && pFrame->IsInTab() )
1722  {
1723  const SwTabFrame* pTableFrame = pFrame->FindTabFrame();
1724  if ( pSectFrame->IsAnLower( pTableFrame ) )
1725  {
1726  pFrame = pTableFrame;
1727  }
1728  }
1729  }
1730 
1731  std::unique_ptr<SwBorderAttrAccess> pAttrAccess;
1732  if (pFrame && (!_pAttrs || pFrame != &m_rThis))
1733  {
1734  pAttrAccess = std::make_unique<SwBorderAttrAccess>(SwFrame::GetCache(), pFrame);
1735  _pAttrs = pAttrAccess->Get();
1736  }
1737 
1738  if (_pAttrs)
1739  nAdditionalLowerSpace += _pAttrs->GetULSpace().GetLower();
1740  }
1741 
1742  return nAdditionalLowerSpace;
1743 }
1744 
1746 bool SwFlowFrame::CheckMoveFwd( bool& rbMakePage, bool bKeep, bool bIgnoreMyOwnKeepValue )
1747 {
1748  const SwFrame* pNxt = m_rThis.GetIndNext();
1749 
1750  if ( bKeep &&
1751  ( !pNxt || ( pNxt->IsTextFrame() && static_cast<const SwTextFrame*>(pNxt)->IsEmptyMaster() ) ) &&
1752  ( nullptr != (pNxt = m_rThis.FindNext()) ) && IsKeepFwdMoveAllowed(bIgnoreMyOwnKeepValue) )
1753  {
1754  if( pNxt->IsSctFrame() )
1755  { // Don't get fooled by empty SectionFrames
1756  const SwFrame* pTmp = nullptr;
1757  while( pNxt && pNxt->IsSctFrame() &&
1758  ( !static_cast<const SwSectionFrame*>(pNxt)->GetSection() ||
1759  nullptr == ( pTmp = static_cast<const SwSectionFrame*>(pNxt)->ContainsAny() ) ) )
1760  {
1761  pNxt = pNxt->FindNext();
1762  pTmp = nullptr;
1763  }
1764  if( pTmp )
1765  pNxt = pTmp; // the content of the next notempty sectionfrm
1766  }
1767  if( pNxt && pNxt->isFrameAreaPositionValid() )
1768  {
1769  bool bMove = false;
1770  const SwSectionFrame *pSct = m_rThis.FindSctFrame();
1771  if( pSct && !pSct->isFrameAreaSizeValid() )
1772  {
1773  const SwSectionFrame* pNxtSct = pNxt->FindSctFrame();
1774  if( pNxtSct && pSct->IsAnFollow( pNxtSct ) )
1775  bMove = true;
1776  }
1777  else
1778  bMove = true;
1779  if( bMove )
1780  {
1781  //Keep together with the following frame
1782  MoveFwd( rbMakePage, false );
1783  return true;
1784  }
1785  }
1786  }
1787 
1788  bool bMovedFwd = false;
1789 
1790  if ( m_rThis.GetIndPrev() )
1791  {
1792  if ( IsPrevObjMove() ) // Should we care about objects of the Prev?
1793  {
1794  bMovedFwd = true;
1795  if ( !MoveFwd( rbMakePage, false ) )
1796  rbMakePage = false;
1797  }
1798  else
1799  {
1800  if ( IsPageBreak( false ) )
1801  {
1802  while ( MoveFwd( rbMakePage, true ) )
1803  /* do nothing */;
1804  rbMakePage = false;
1805  bMovedFwd = true;
1806  }
1807  else if ( IsColBreak ( false ) )
1808  {
1809  const SwPageFrame *pPage = m_rThis.FindPageFrame();
1810  SwFrame *pCol = m_rThis.FindColFrame();
1811  do
1812  { MoveFwd( rbMakePage, false );
1813  SwFrame *pTmp = m_rThis.FindColFrame();
1814  if( pTmp != pCol )
1815  {
1816  bMovedFwd = true;
1817  pCol = pTmp;
1818  }
1819  else
1820  break;
1821  } while ( IsColBreak( false ) );
1822  if ( pPage != m_rThis.FindPageFrame() )
1823  rbMakePage = false;
1824  }
1825  }
1826  }
1827  return bMovedFwd;
1828 }
1829 
1831 {
1832  return m_rThis.IsTabFrame() || m_rThis.IsInTab();
1833 }
1834 
1836 bool SwFlowFrame::MoveFwd( bool bMakePage, bool bPageBreak, bool bMoveAlways )
1837 {
1840  if (m_rThis.IsInFootnote())
1841  {
1842  assert(!ForbiddenForFootnoteCntFwd()); // prevented by IsMoveable()
1843  if (!m_rThis.IsContentFrame() || !pOldBoss)
1844  {
1845  SAL_WARN("sw.core", "Tables in footnotes are not truly supported");
1846  return false;
1847  }
1848  return static_cast<SwContentFrame&>(m_rThis).MoveFootnoteCntFwd( bMakePage, pOldBoss );
1849  }
1850 
1851  if( !IsFwdMoveAllowed() && !bMoveAlways )
1852  {
1853  bool bNoFwd = true;
1854  if( m_rThis.IsInSct() )
1855  {
1857  bNoFwd = !pBoss->IsInSct() || ( !pBoss->Lower()->GetNext() &&
1858  !pBoss->GetPrev() );
1859  }
1860 
1861  // Allow the MoveFwd even if we do not have an IndPrev in these cases:
1862  if ( m_rThis.IsInTab() &&
1863  ( !m_rThis.IsTabFrame() ||
1864  ( m_rThis.GetUpper()->IsInTab() &&
1866  nullptr != m_rThis.GetNextCellLeaf() )
1867  {
1868  bNoFwd = false;
1869  }
1870 
1871  if( bNoFwd )
1872  {
1873  // It's allowed to move PageBreaks if the Frame isn't the first
1874  // one on the page.
1875  if ( !bPageBreak )
1876  return false;
1877 
1878  const SwFrame *pCol = m_rThis.FindColFrame();
1879  if ( !pCol || !pCol->GetPrev() )
1880  return false;
1881  }
1882  }
1883 
1884  std::unique_ptr<SwFrameDeleteGuard> xDeleteGuard(bMakePage ? new SwFrameDeleteGuard(pOldBoss) : nullptr);
1885 
1886  bool bSamePage = true;
1887  SwLayoutFrame *pNewUpper =
1888  m_rThis.GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, true );
1889 
1890  if ( pNewUpper )
1891  {
1893  SwPageFrame *pOldPage = pOldBoss->FindPageFrame();
1894  // We move ourself and all the direct successors before the
1895  // first ContentFrame below the new Upper.
1896 
1897  // If our NewUpper lies in a SectionFrame, we need to make sure
1898  // that it won't destroy itself in Calc.
1899  SwSectionFrame* pSect = pNewUpper->FindSctFrame();
1900  if( pSect )
1901  {
1902  // If we only switch column within our SectionFrame, we better don't
1903  // call Calc, as this would format the SectionFrame, which in turn would
1904  // call us again, etc.
1905  if( pSect != m_rThis.FindSctFrame() )
1906  {
1907  bool bUnlock = !pSect->IsColLocked();
1908  pSect->ColLock();
1909  pNewUpper->Calc(m_rThis.getRootFrame()->GetCurrShell()->GetOut());
1910  if( bUnlock )
1911  pSect->ColUnlock();
1912  }
1913  }
1914  // Do not calculate split cell frames.
1915  else if ( !pNewUpper->IsCellFrame() || pNewUpper->Lower() )
1916  pNewUpper->Calc(m_rThis.getRootFrame()->GetCurrShell()->GetOut());
1917 
1918  SwFootnoteBossFrame *pNewBoss = pNewUpper->FindFootnoteBossFrame();
1919  bool bBossChg = pNewBoss != pOldBoss;
1920  pNewBoss = pNewBoss->FindFootnoteBossFrame( true );
1921  pOldBoss = pOldBoss->FindFootnoteBossFrame( true );
1922  SwPageFrame* pNewPage = pOldPage;
1923 
1924  xDeleteGuard.reset();
1925 
1926  // First, we move the footnotes.
1927  bool bFootnoteMoved = false;
1928 
1929  // #i26831#
1930  // If pSect has just been created, the printing area of pSect has
1931  // been calculated based on the first content of its follow.
1932  // In this case we prefer to call a SimpleFormat for this new
1933  // section after we inserted the contents. Otherwise the section
1934  // frame will invalidate its lowers, if its printing area changes
1935  // in SwSectionFrame::Format, which can cause loops.
1936  const bool bForceSimpleFormat = pSect && pSect->HasFollow() &&
1937  !pSect->ContainsAny();
1938 
1939  if ( pNewBoss != pOldBoss )
1940  {
1941  pNewPage = pNewBoss->FindPageFrame();
1942  bSamePage = pNewPage == pOldPage;
1943  // Set deadline, so the footnotes don't think up
1944  // silly things...
1945  SwRectFnSet aRectFnSet(pOldBoss);
1946  SwSaveFootnoteHeight aHeight( pOldBoss,
1947  aRectFnSet.GetBottom(pOldBoss->getFrameArea()) );
1948  SwContentFrame* pStart = m_rThis.IsContentFrame() ?
1949  static_cast<SwContentFrame*>(&m_rThis) : static_cast<SwLayoutFrame&>(m_rThis).ContainsContent();
1950  OSL_ENSURE( pStart || ( m_rThis.IsTabFrame() && !static_cast<SwTabFrame&>(m_rThis).Lower() ),
1951  "MoveFwd: Missing Content" );
1952  SwLayoutFrame* pBody = pStart ? ( pStart->IsTextFrame() ?
1953  const_cast<SwBodyFrame *>(static_cast<SwTextFrame*>(pStart)->FindBodyFrame()) : nullptr ) : nullptr;
1954  if( pBody )
1955  bFootnoteMoved = pBody->MoveLowerFootnotes( pStart, pOldBoss, pNewBoss,
1956  false);
1957  }
1958  // It's possible when dealing with SectionFrames that we have been moved
1959  // by pNewUpper->Calc(), for instance into the pNewUpper.
1960  // MoveSubTree or PasteTree respectively is not prepared to handle such a
1961  // situation.
1962  if( pNewUpper != m_rThis.GetUpper() )
1963  {
1964  // #i27145#
1965  SwSectionFrame* pOldSct = nullptr;
1966  if ( m_rThis.GetUpper()->IsSctFrame() )
1967  {
1968  pOldSct = static_cast<SwSectionFrame*>(m_rThis.GetUpper());
1969  }
1970 
1971  MoveSubTree( pNewUpper, pNewUpper->Lower() );
1972 
1973  // #i27145#
1974  if ( pOldSct && pOldSct->GetSection() )
1975  {
1976  // Prevent loops by setting the new height at
1977  // the section frame if footnotes have been moved.
1978  // Otherwise the call of SwLayNotify::~SwLayNotify() for
1979  // the (invalid) section frame will invalidate the first
1980  // lower of its follow, because it grows due to the removed
1981  // footnotes.
1982  // Note: If pOldSct has become empty during MoveSubTree, it
1983  // has already been scheduled for removal. No SimpleFormat
1984  // for these.
1985  pOldSct->SimpleFormat();
1986  }
1987 
1988  // #i26831#
1989  if ( bForceSimpleFormat )
1990  {
1991  pSect->SimpleFormat();
1992  }
1993 
1994  if ( bFootnoteMoved && !bSamePage )
1995  {
1996  pOldPage->UpdateFootnoteNum();
1997  pNewPage->UpdateFootnoteNum();
1998  }
1999 
2000  if( bBossChg )
2001  {
2002  m_rThis.Prepare( PREP_BOSS_CHGD, nullptr, false );
2003  if( !bSamePage )
2004  {
2006  if ( pSh && !pSh->Imp()->IsUpdateExpFields() )
2007  pSh->GetDoc()->getIDocumentFieldsAccess().SetNewFieldLst(true); // Will be done by CalcLayout() later on!
2008 
2009  pNewPage->InvalidateSpelling();
2010  pNewPage->InvalidateSmartTags();
2011  pNewPage->InvalidateAutoCompleteWords();
2012  pNewPage->InvalidateWordCount();
2013  }
2014  }
2015  }
2016  // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
2017  const SwViewShell *pSh = m_rThis.getRootFrame()->GetCurrShell();
2018 
2019  if ( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) )
2020  {
2021  // #i106452#
2022  // check page description not only in situation with sections.
2023  if ( !bSamePage &&
2025  pOldPage->GetPageDesc()->GetFollow() != pNewPage->GetPageDesc() ) )
2026  {
2027  SwFrame::CheckPageDescs( pNewPage, false );
2028  }
2029  }
2030  }
2031  return bSamePage;
2032 }
2033 
2039 bool SwFlowFrame::MoveBwd( bool &rbReformat )
2040 {
2041  SwFlowFrame::SetMoveBwdJump( false );
2042 
2043  SwFootnoteFrame* pFootnote = m_rThis.FindFootnoteFrame();
2044  if ( pFootnote && pFootnote->IsBackMoveLocked() )
2045  return false;
2046 
2047  // #115759# - text frames, which are directly inside
2048  // tables aren't allowed to move backward.
2049  if ( m_rThis.IsTextFrame() && m_rThis.IsInTab() )
2050  {
2051  const SwLayoutFrame* pUpperFrame = m_rThis.GetUpper();
2052  while ( pUpperFrame )
2053  {
2054  if ( pUpperFrame->IsTabFrame() || pUpperFrame->IsRowFrame() )
2055  {
2056  return false;
2057  }
2058  // If the text frame is a follow-section-in-table, that can move
2059  // backward as well.
2060  bool bIsFollowSection = pUpperFrame->IsSctFrame() && static_cast<const SwSectionFrame*>(pUpperFrame)->GetPrecede();
2061 
2062  // If the text frame is a follow-in-table, that can move
2063  // backward as well.
2064  bool bIsFollow = const_cast<SwLayoutFrame*>(pUpperFrame)->GetPrevCellLeaf();
2065 
2066  if ( ( pUpperFrame->IsColumnFrame() && pUpperFrame->IsInSct() ) || bIsFollowSection || bIsFollow )
2067  {
2068  break;
2069  }
2070  pUpperFrame = pUpperFrame->GetUpper();
2071  }
2072  }
2073 
2075  if (!pOldBoss)
2076  return false;
2077 
2078  SwPageFrame * const pOldPage = pOldBoss->FindPageFrame();
2079  SwLayoutFrame *pNewUpper = nullptr;
2080  bool bCheckPageDescs = false;
2081  bool bCheckPageDescOfNextPage = false;
2082 
2083  if ( pFootnote )
2084  {
2085  // If the footnote already sits on the same page/column as the reference,
2086  // we can't flow back. The breaks don't need to be checked for footnotes.
2087 
2088  // #i37084# FindLastContent does not necessarily
2089  // have to have a result != 0
2090  SwFrame* pRef = nullptr;
2091  const bool bEndnote = pFootnote->GetAttr()->GetFootnote().IsEndNote();
2092  const IDocumentSettingAccess& rSettings
2093  = pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
2094  if( bEndnote && pFootnote->IsInSct() )
2095  {
2096  SwSectionFrame* pSect = pFootnote->FindSctFrame();
2097  if( pSect->IsEndnAtEnd() )
2098  // Endnotes at the end of the section.
2099  pRef = pSect->FindLastContent( SwFindMode::LastCnt );
2100  }
2101  else if (bEndnote && rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
2102  {
2103  // Endnotes at the end of the document.
2105  pRef = pPage->FindLastBodyContent();
2106  }
2107  if( !pRef )
2108  // Endnotes on a separate page.
2109  pRef = pFootnote->GetRef();
2110 
2111  OSL_ENSURE( pRef, "MoveBwd: Endnote for an empty section?" );
2112 
2113  if( !bEndnote )
2114  pOldBoss = pOldBoss->FindFootnoteBossFrame( true );
2115  SwFootnoteBossFrame *pRefBoss = pRef->FindFootnoteBossFrame( !bEndnote );
2116  if ( pOldBoss != pRefBoss &&
2117  // OD 08.11.2002 #104840# - use <SwLayoutFrame::IsBefore(..)>
2118  ( !bEndnote ||
2119  pRefBoss->IsBefore( pOldBoss ) )
2120  )
2121  pNewUpper = m_rThis.GetLeaf( MAKEPAGE_FTN, false );
2122  }
2123  else if ( IsPageBreak( true ) ) // Do we have to respect a PageBreak?
2124  {
2125  // If the previous page doesn't have a Frame in the body,
2126  // flowing back makes sense despite the PageBreak (otherwise,
2127  // we'd get an empty page).
2128  // Of course we need to overlook empty pages!
2129  const SwFrame *pFlow = &m_rThis;
2130  do
2131  {
2132  pFlow = pFlow->FindPrev();
2133  } while ( pFlow &&
2134  ( pFlow->FindPageFrame() == pOldPage ||
2135  !pFlow->IsInDocBody() ) );
2136  if ( pFlow )
2137  {
2138  long nDiff = pOldPage->GetPhyPageNum() - pFlow->GetPhyPageNum();
2139  if ( nDiff > 1 )
2140  {
2141  if ( static_cast<SwPageFrame*>(pOldPage->GetPrev())->IsEmptyPage() )
2142  nDiff -= 1;
2143  if ( nDiff > 1 )
2144  {
2145  pNewUpper = m_rThis.GetLeaf( MAKEPAGE_NONE, false );
2146  // #i53139#
2147  // Now <pNewUpper> is a previous layout frame, which contains
2148  // content. But the new upper layout frame has to be the next one.
2149  // Thus, hack for issue i14206 no longer needed, but fix for issue 114442
2150  // #136024# - correct fix for i53139
2151  // Check for wrong page description before using next new upper.
2152  // #i66051# - further correction of fix for i53139
2153  // Check for correct type of new next upper layout frame
2154  // #136538# - another correction of fix for i53139
2155  // Assumption, that in all cases <pNewUpper> is a previous
2156  // layout frame, which contains content, is wrong.
2157  // #136538# - another correction of fix for i53139
2158  // Beside type check, check also, if proposed new next upper
2159  // frame is inside the same frame types.
2160  // #i73194# - and yet another correction
2161  // of fix for i53139:
2162  // Assure that the new next upper layout frame doesn't
2163  // equal the current one.
2164  // E.g.: content is on page 3, on page 2 is only a 'ghost'
2165  // section and on page 1 is normal content. Method <FindPrev(..)>
2166  // will find the last content of page 1, but <GetLeaf(..)>
2167  // returns new upper on page 2.
2168  if (pNewUpper && pNewUpper->Lower())
2169  {
2170  SwLayoutFrame* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NONE, true );
2171  if ( pNewNextUpper &&
2172  pNewNextUpper != m_rThis.GetUpper() &&
2173  pNewNextUpper->GetType() == pNewUpper->GetType() &&
2174  pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
2175  pNewNextUpper->IsInFootnote() == pNewUpper->IsInFootnote() &&
2176  pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
2177  pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
2178  !m_rThis.WrongPageDesc( pNewNextUpper->FindPageFrame() ) )
2179  {
2180  pNewUpper = pNewNextUpper;
2181  bCheckPageDescOfNextPage = true;
2182  }
2183  }
2184 
2185  bCheckPageDescs = true;
2186  }
2187  }
2188  }
2189  }
2190  else if ( IsColBreak( true ) )
2191  {
2192  // If the previous column doesn't contain a ContentFrame, flowing back
2193  // makes sense despite the ColumnBreak, as otherwise we'd get
2194  // an empty column.
2195  if( m_rThis.IsInSct() )
2196  {
2197  pNewUpper = m_rThis.GetLeaf( MAKEPAGE_NONE, false );
2198  if( pNewUpper && !SwFlowFrame::IsMoveBwdJump() &&
2199  ( pNewUpper->ContainsContent() ||
2200  ( ( !pNewUpper->IsColBodyFrame() ||
2201  !pNewUpper->GetUpper()->GetPrev() ) &&
2202  !pNewUpper->FindSctFrame()->GetPrev() ) ) )
2203  {
2204  pNewUpper = nullptr;
2205  }
2206  // #i53139#
2207  // #i69409# - check <pNewUpper>
2208  // #i71065# - check <SwFlowFrame::IsMoveBwdJump()>
2209  else if ( pNewUpper && !SwFlowFrame::IsMoveBwdJump() )
2210  {
2211  // Now <pNewUpper> is a previous layout frame, which
2212  // contains content. But the new upper layout frame
2213  // has to be the next one.
2214  // #136024# - correct fix for i53139
2215  // Check for wrong page description before using next new upper.
2216  // #i66051# - further correction of fix for i53139
2217  // Check for correct type of new next upper layout frame
2218  // #136538# - another correction of fix for i53139
2219  // Beside type check, check also, if proposed new next upper
2220  // frame is inside the same frame types.
2221  SwLayoutFrame* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NOSECTION, true );
2222  if ( pNewNextUpper &&
2223  pNewNextUpper->GetType() == pNewUpper->GetType() &&
2224  pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
2225  pNewNextUpper->IsInFootnote() == pNewUpper->IsInFootnote() &&
2226  pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
2227  pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
2228  !m_rThis.WrongPageDesc( pNewNextUpper->FindPageFrame() ) )
2229  {
2230  pNewUpper = pNewNextUpper;
2231  }
2232  }
2233  }
2234  else
2235  {
2236  const SwFrame *pCol = m_rThis.FindColFrame();
2237  bool bGoOn = true;
2238  bool bJump = false;
2239  do
2240  {
2241  if ( pCol->GetPrev() )
2242  pCol = pCol->GetPrev();
2243  else
2244  {
2245  bGoOn = false;
2246  pCol = m_rThis.GetLeaf( MAKEPAGE_NONE, false );
2247  }
2248  if ( pCol )
2249  {
2250  // ColumnFrames now with BodyFrame
2251  SwLayoutFrame* pColBody = pCol->IsColumnFrame() ?
2252  const_cast<SwLayoutFrame*>(static_cast<const SwLayoutFrame*>(static_cast<const SwLayoutFrame*>(pCol)->Lower())) :
2253  const_cast<SwLayoutFrame*>(static_cast<const SwLayoutFrame*>(pCol));
2254  if ( pColBody->ContainsContent() )
2255  {
2256  bGoOn = false; // We have content here! we accept this
2257  // only if GetLeaf() has set the MoveBwdJump.
2259  {
2260  pNewUpper = pColBody;
2261  // #i53139#
2262  // Now <pNewUpper> is a previous layout frame, which
2263  // contains content. But the new upper layout frame
2264  // has to be the next one.
2265  // #136024# - correct fix for i53139
2266  // Check for wrong page description before using next new upper.
2267  // #i66051# - further correction of fix for i53139
2268  // Check for correct type of new next upper layout frame
2269  // #136538# - another correction of fix for i53139
2270  // Beside type check, check also, if proposed new next upper
2271  // frame is inside the same frame types.
2272  // #i71065#
2273  // Check that the proposed new next upper layout
2274  // frame isn't the current one.
2275  SwLayoutFrame* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NONE, true );
2276  if ( pNewNextUpper &&
2277  pNewNextUpper != m_rThis.GetUpper() &&
2278  pNewNextUpper->GetType() == pNewUpper->GetType() &&
2279  pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
2280  pNewNextUpper->IsInFootnote() == pNewUpper->IsInFootnote() &&
2281  pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
2282  pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
2283  !m_rThis.WrongPageDesc( pNewNextUpper->FindPageFrame() ) )
2284  {
2285  pNewUpper = pNewNextUpper;
2286  }
2287  }
2288  }
2289  else
2290  {
2291  if( pNewUpper ) // We already had an empty column, in other
2292  bJump = true; // words we skipped one.
2293  pNewUpper = pColBody; // this empty column could be considered,
2294  // but we continue searching nevertheless.
2295  }
2296  }
2297  } while( bGoOn );
2298  if( bJump )
2300  }
2301  }
2302  else // No breaks - we can flow back.
2303  pNewUpper = m_rThis.GetLeaf( MAKEPAGE_NONE, false );
2304 
2305  // #i27801# - no move backward of 'master' text frame,
2306  // if - due to its object positioning - it isn't allowed to be on the new page frame
2307  // #i44049# - add another condition for not moving backward
2308  // If one of its objects has restarted the layout process, moving backward
2309  // isn't sensible either.
2310  // #i47697# - refine condition made for issue i44049
2311  // - allow move backward as long as the anchored object is only temporarily
2312  // positions considering its wrapping style.
2313  if ( pNewUpper &&
2314  m_rThis.IsTextFrame() && !IsFollow() )
2315  {
2316  sal_uInt32 nToPageNum( 0 );
2317  const bool bMoveFwdByObjPos = SwLayouter::FrameMovedFwdByObjPos(
2318  *(pOldPage->GetFormat()->GetDoc()),
2319  static_cast<SwTextFrame&>(m_rThis),
2320  nToPageNum );
2321  if ( bMoveFwdByObjPos &&
2322  pNewUpper->FindPageFrame()->GetPhyPageNum() < nToPageNum )
2323  {
2324  pNewUpper = nullptr;
2325  }
2326  // #i44049# - check, if one of its anchored objects
2327  // has restarted the layout process.
2328  else if ( m_rThis.GetDrawObjs() )
2329  {
2330  for (SwAnchoredObject* pAnchoredObj : *m_rThis.GetDrawObjs())
2331  {
2332  // #i47697# - refine condition - see above
2333  if ( pAnchoredObj->RestartLayoutProcess() &&
2334  !pAnchoredObj->IsTmpConsiderWrapInfluence() )
2335  {
2336  pNewUpper = nullptr;
2337  break;
2338  }
2339  }
2340  }
2341  }
2342 
2343  // With Follows, it's only allowed to flow back if there's no neighbor
2344  // in the new environment (because that would be the Master).
2345  // (6677) If however we skipped empty pages, we still have to move.
2346  if ( pNewUpper && IsFollow() && pNewUpper->Lower() )
2347  {
2348  // #i79774#
2349  // neglect empty sections in proposed new upper frame
2350  bool bProposedNewUpperContainsOnlyEmptySections( true );
2351  {
2352  const SwFrame* pLower( pNewUpper->Lower() );
2353  while ( pLower )
2354  {
2355  if ( pLower->IsSctFrame() &&
2356  !dynamic_cast<const SwSectionFrame*>(pLower)->GetSection() )
2357  {
2358  pLower = pLower->GetNext();
2359  continue;
2360  }
2361  else
2362  {
2363  bProposedNewUpperContainsOnlyEmptySections = false;
2364  break;
2365  }
2366  }
2367  }
2368  if ( !bProposedNewUpperContainsOnlyEmptySections )
2369  {
2371  {
2372  // Don't move after the Master, but into the next empty page.
2373  SwFrame *pFrame = pNewUpper->Lower();
2374  while ( pFrame->GetNext() )
2375  pFrame = pFrame->GetNext();
2376  pNewUpper = pFrame->GetLeaf( MAKEPAGE_INSERT, true );
2377  if( pNewUpper == m_rThis.GetUpper() ) // Did we end up in the same place?
2378  pNewUpper = nullptr; // If so, moving is not needed.
2379  }
2380  else
2381  pNewUpper = nullptr;
2382  }
2383  }
2384  if ( pNewUpper && !ShouldBwdMoved( pNewUpper, rbReformat ) )
2385  {
2386  if( !pNewUpper->Lower() )
2387  {
2388  if( pNewUpper->IsFootnoteContFrame() )
2389  {
2390  pNewUpper->Cut();
2391  SwFrame::DestroyFrame(pNewUpper);
2392  }
2393  else
2394  {
2395  SwSectionFrame* pSectFrame = pNewUpper->FindSctFrame();
2396  // #126020# - adjust check for empty section
2397  // #130797# - correct fix #126020#
2398  if ( pSectFrame && !pSectFrame->IsColLocked() &&
2399  !pSectFrame->ContainsContent() && !pSectFrame->ContainsAny( true ) )
2400  {
2401  pSectFrame->DelEmpty( true );
2402  SwFrame::DestroyFrame(pSectFrame);
2404  }
2405  }
2406  }
2407  pNewUpper = nullptr;
2408  }
2409 
2410  // OD 2004-05-26 #i21478# - don't move backward, if flow frame wants to
2411  // keep with next frame and next frame is locked.
2412  // #i38232# - If next frame is a table, do *not* check,
2413  // if it's locked.
2414  if ( pNewUpper && !IsFollow() &&
2415  m_rThis.GetAttrSet()->GetKeep().GetValue() && m_rThis.GetIndNext() )
2416  {
2417  SwFrame* pIndNext = m_rThis.GetIndNext();
2418  // #i38232#
2419  if ( !pIndNext->IsTabFrame() )
2420  {
2421  // get first content of section, while empty sections are skipped
2422  while ( pIndNext && pIndNext->IsSctFrame() )
2423  {
2424  if( static_cast<SwSectionFrame*>(pIndNext)->GetSection() )
2425  {
2426  SwFrame* pTmp = static_cast<SwSectionFrame*>(pIndNext)->ContainsAny();
2427  if ( pTmp )
2428  {
2429  pIndNext = pTmp;
2430  break;
2431  }
2432  }
2433  pIndNext = pIndNext->GetIndNext();
2434  }
2435  OSL_ENSURE( !pIndNext || dynamic_cast<const SwTextFrame*>( pIndNext) != nullptr,
2436  "<SwFlowFrame::MovedBwd(..)> - incorrect next found." );
2437  if ( pIndNext && pIndNext->IsFlowFrame() &&
2439  {
2440  pNewUpper = nullptr;
2441  }
2442  }
2443  }
2444 
2445  // #i65250#
2446  // layout loop control for flowing content again and again moving
2447  // backward under the same layout condition.
2448  if ( pNewUpper && !IsFollow() &&
2449  pNewUpper != m_rThis.GetUpper() &&
2450  SwLayouter::MoveBwdSuppressed( *(pOldPage->GetFormat()->GetDoc()),
2451  *this, *pNewUpper ) )
2452  {
2453  SwLayoutFrame* pNextNewUpper = pNewUpper->GetLeaf(
2454  ( !m_rThis.IsSctFrame() && m_rThis.IsInSct() )
2456  : MAKEPAGE_NONE,
2457  true );
2458  // #i73194# - make code robust
2459  OSL_ENSURE( pNextNewUpper, "<SwFlowFrame::MoveBwd(..)> - missing next new upper" );
2460  if ( pNextNewUpper &&
2461  ( pNextNewUpper == m_rThis.GetUpper() ||
2462  pNextNewUpper->GetType() != m_rThis.GetUpper()->GetType() ) )
2463  {
2464  // tdf#107398 do not leave empty footnote container around
2465  if (!pNewUpper->Lower() && pNewUpper->IsFootnoteContFrame())
2466  {
2467  pNewUpper->Cut();
2468  SwFrame::DestroyFrame(pNewUpper);
2469  }
2470  pNewUpper = nullptr;
2471  OSL_FAIL( "<SwFlowFrame::MoveBwd(..)> - layout loop control for layout action <Move Backward> applied!" );
2472  }
2473  }
2474 
2475  OSL_ENSURE( pNewUpper != m_rThis.GetUpper(),
2476  "<SwFlowFrame::MoveBwd(..)> - moving backward to the current upper frame!?" );
2477  if ( pNewUpper )
2478  {
2480  if ( pNewUpper->IsFootnoteContFrame() )
2481  {
2482  // I may have gotten a Container
2484  SwFootnoteFrame *pNew = new SwFootnoteFrame( pOld->GetFormat(), pOld,
2485  pOld->GetRef(), pOld->GetAttr() );
2486  if ( pOld->GetMaster() )
2487  {
2488  pNew->SetMaster( pOld->GetMaster() );
2489  pOld->GetMaster()->SetFollow( pNew );
2490  }
2491  pNew->SetFollow( pOld );
2492  pOld->SetMaster( pNew );
2493  pNew->Paste( pNewUpper );
2494  pNewUpper = pNew;
2495  }
2496  if( pNewUpper->IsFootnoteFrame() && m_rThis.IsInSct() )
2497  {
2499  // If we're in a section of a footnote, we may need to create
2500  // a SwSectionFrame in the new upper
2501  if( pSct->IsInFootnote() )
2502  {
2503  SwFrame* pTmp = pNewUpper->Lower();
2504  if( pTmp )
2505  {
2506  while( pTmp->GetNext() )
2507  pTmp = pTmp->GetNext();
2508  if( !pTmp->IsSctFrame() ||
2509  static_cast<SwSectionFrame*>(pTmp)->GetFollow() != pSct )
2510  pTmp = nullptr;
2511  }
2512  if( pTmp )
2513  pNewUpper = static_cast<SwSectionFrame*>(pTmp);
2514  else
2515  {
2516  pSct = new SwSectionFrame( *pSct, true );
2517  pSct->Paste( pNewUpper );
2518  pSct->Init();
2519  pNewUpper = pSct;
2520  pSct->SimpleFormat();
2521  }
2522  }
2523  }
2524  bool bUnlock = false;
2525  bool bFollow = false;
2526  // Lock section. Otherwise, it could get destroyed if the only Content
2527  // moves e.g. from the second into the first column.
2528  SwSectionFrame* pSect = pNewUpper->FindSctFrame();
2529  if( pSect )
2530  {
2531  bUnlock = !pSect->IsColLocked();
2532  pSect->ColLock();
2533  bFollow = pSect->HasFollow();
2534  }
2535 
2536  {
2537  auto const pOld = m_rThis.GetUpper();
2538 #if BOOST_VERSION < 105600
2539  std::list<SwFrameDeleteGuard> g;
2540 #else
2542 #endif
2543  if (m_rThis.GetUpper()->IsCellFrame())
2544  {
2545  // note: IsFollowFlowRow() is never set for new-style tables
2546  SwTabFrame const*const pTabFrame(m_rThis.FindTabFrame());
2547  if ( pTabFrame->IsFollow()
2548  && static_cast<SwTabFrame const*>(pTabFrame->GetPrecede())->HasFollowFlowLine()
2549  && pTabFrame->GetFirstNonHeadlineRow() == m_rThis.GetUpper()->GetUpper())
2550  {
2551  // lock follow-flow-row (similar to sections above)
2552 #if BOOST_VERSION < 105600
2553  g.emplace_back(m_rThis.GetUpper()->GetUpper());
2554 #else
2555  g.emplace(m_rThis.GetUpper()->GetUpper());
2556 #endif
2557  assert(m_rThis.GetUpper()->GetUpper()->IsDeleteForbidden());
2558  }
2559  }
2560  pNewUpper->Calc(m_rThis.getRootFrame()->GetCurrShell()->GetOut());
2561  SAL_WARN_IF(pOld != m_rThis.GetUpper(), "sw.core",
2562  "MoveBwd(): pNewUpper->Calc() moved this frame?");
2563  }
2564 
2565  m_rThis.Cut();
2566 
2567  // optimization: format section, if its size is invalidated and if it's
2568  // the new parent of moved backward frame.
2569  bool bFormatSect( false );
2570  if( bUnlock )
2571  {
2572  pSect->ColUnlock();
2573  if( pSect->HasFollow() != bFollow )
2574  {
2575  pSect->InvalidateSize();
2576  // - optimization
2577  if ( pSect == pNewUpper )
2578  bFormatSect = true;
2579  }
2580  }
2581 
2582  m_rThis.Paste( pNewUpper );
2583  // - optimization
2584  if ( bFormatSect )
2585  pSect->Calc(m_rThis.getRootFrame()->GetCurrShell()->GetOut());
2586 
2587  SwPageFrame *pNewPage = m_rThis.FindPageFrame();
2588  if( pNewPage != pOldPage )
2589  {
2590  m_rThis.Prepare( PREP_BOSS_CHGD, static_cast<const void*>(pOldPage), false );
2592  if ( pSh && !pSh->Imp()->IsUpdateExpFields() )
2593  pSh->GetDoc()->getIDocumentFieldsAccess().SetNewFieldLst(true); // Will be done by CalcLayout() later on
2594 
2595  pNewPage->InvalidateSpelling();
2596  pNewPage->InvalidateSmartTags();
2597  pNewPage->InvalidateAutoCompleteWords();
2598  pNewPage->InvalidateWordCount();
2599 
2600  // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
2601  if ( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) )
2602  {
2603  if ( bCheckPageDescs && pNewPage->GetNext() )
2604  {
2605  SwPageFrame* pStartPage = bCheckPageDescOfNextPage ?
2606  pNewPage :
2607  static_cast<SwPageFrame*>(pNewPage->GetNext());
2608  SwFrame::CheckPageDescs( pStartPage, false);
2609  }
2610  else if (m_rThis.GetPageDescItem().GetPageDesc())
2611  {
2612  // First page could get empty for example by disabling
2613  // a section
2614  SwFrame::CheckPageDescs( pNewPage, false);
2615  }
2616  }
2617  }
2618  }
2619  return pNewUpper != nullptr;
2620 }
2621 
2623 {
2624  if ( pFrame->IsContentFrame() )
2625  return static_cast<SwContentFrame*>(pFrame);
2626  if ( pFrame->IsTabFrame() )
2627  return static_cast<SwTabFrame*>(pFrame);
2628  if ( pFrame->IsSctFrame() )
2629  return static_cast<SwSectionFrame*>(pFrame);
2630  return nullptr;
2631 }
2632 
2634 {
2635  if ( pFrame->IsContentFrame() )
2636  return static_cast<const SwContentFrame*>(pFrame);
2637  if ( pFrame->IsTabFrame() )
2638  return static_cast<const SwTabFrame*>(pFrame);
2639  if ( pFrame->IsSctFrame() )
2640  return static_cast<const SwSectionFrame*>(pFrame);
2641  return nullptr;
2642 }
2643 
2644 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetFollow(SwFootnoteFrame *pNew)
Definition: ftnfrm.hxx:110
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:206
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
bool GetValue() const
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:547
SwSectionFrame * FindMaster() const
Definition: flowfrm.cxx:697
bool IsKeepFwdMoveAllowed(bool bIgnoreMyOwnKeepValue=false)
Definition: flowfrm.cxx:123
SvxBreak
sal_uInt16 CalcBottomLine() const
Definition: frmtool.hxx:484
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
virtual SwRect GetObjRect() const =0
sal_uLong GetIndex() const
Definition: node.hxx:282
bool IsFollow() const
Definition: flowfrm.hxx:166
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:543
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
SwFrame * mpNext
Definition: frame.hxx:319
SwFrame * mpPrev
Definition: frame.hxx:320
SwPageDesc * FindPageDesc()
Definition: pagechg.cxx:745
bool IsEndnAtEnd() const
Definition: sectfrm.hxx:148
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:98
bool IsInDocBody() const
Definition: frame.hxx:919
bool IsInFly() const
Definition: frame.hxx:937
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1462
long YInc(long n1, long n2) const
Definition: frame.hxx:1401
sal_uInt16 GetLower() const
bool IsInSct() const
Definition: frame.hxx:943
static void SetMoveBwdJump(bool bNew)
Definition: flowfrm.hxx:155
bool MoveFwd(bool bMakePage, bool bPageBreak, bool bMoveAlways=false)
Return value tells us whether the Frame has changed the page.
Definition: flowfrm.cxx:1836
SwPageDesc * GetPageDesc()
Definition: fmtpdsc.hxx:62
SwViewShellImp * Imp()
Definition: viewsh.hxx:185
void DelEmpty(bool bRemove)
Definition: sectfrm.cxx:185
static void CheckPageDescs(SwPageFrame *pStart, bool bNotifyFields=true, SwPageFrame **ppPrev=nullptr)
Check all pages (starting from the given one) if they use the right frame format. ...
Definition: pagechg.cxx:1002
void ColLock()
Definition: sectfrm.hxx:86
bool IsColLocked() const
Definition: frame.hxx:862
bool IsBefore(const SwLayoutFrame *_pCheckRefLayFrame) const
method to check relative position of layout frame to a given layout frame.
Definition: findfrm.cxx:233
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: ftnfrm.cxx:551
bool IsKeep(SvxFormatKeepItem const &rKeep, SvxFormatBreakItem const &rBreak, bool bBreakCheck=false) const
method to determine if a Keep needs to be considered (Breaks!)
Definition: flowfrm.cxx:179
const SwTable * GetTable() const
Definition: tabfrm.hxx:144
SwNodeIndex nNode
Definition: pam.hxx:37
void SetCompletePaint() const
Definition: frame.hxx:970
void SetMaster(SwFootnoteFrame *pNew)
Definition: ftnfrm.hxx:111
bool IsInFootnote() const
Definition: frame.hxx:925
SwLayoutFrame * GetPrevLeaf()
Returns the previous layout leaf where we can move the frame.
Definition: flowfrm.cxx:1035
SwFrameType GetType() const
Definition: frame.hxx:498
SvxBreak GetBreak() const
bool IsPrevObjMove() const
Definition: flowfrm.cxx:1068
sal_uIntPtr sal_uLong
void InvalidateLineNum_()
Definition: frame.hxx:773
static SwCache & GetCache()
Definition: frame.hxx:500
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:30
SwFrame * FindPrev()
Definition: frame.hxx:1131
bool IsComplete() const
Definition: layact.hxx:161
static bool m_bMoveBwdJump
indicates that a backward move was done over multiple pages
Definition: flowfrm.hxx:88
TElementType * Next()
Definition: calbck.hxx:373
bool HasFollow() const
Definition: flowfrm.hxx:165
SwTwips GetUpperSpaceAmountConsideredForPageGrid_(const SwTwips _nUpperSpaceWithoutGrid) const
method to determine the upper space amount, which is considered for the page grid ...
Definition: flowfrm.cxx:1559
void UpdateFootnoteNum()
Definition: ftnfrm.cxx:2395
sal_uInt16 sal_Char sal_Char * pDesc
SwTwips CalcLowerSpace(const SwBorderAttrs *_pAttrs=nullptr) const
calculation of lower space
Definition: flowfrm.cxx:1669
void InvalidatePos()
Definition: frame.hxx:1019
long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1354
bool MoveBwd(bool &rbReformat)
Return value tells whether the Frame should change the page.
Definition: flowfrm.cxx:2039
long SwTwips
Definition: swtypes.hxx:49
SwSectionFormat * GetFormat()
Definition: section.hxx:336
static bool lcl_IdenticalStyles(const SwFrame *pPrevFrame, const SwFrame *pFrame)
Compare styles attached to these text frames.
Definition: flowfrm.cxx:1358
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:382
bool IsEndNote() const
Definition: fmtftn.hxx:74
SwFrame * FindNext()
Definition: frame.hxx:1117
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1787
bool IsCellFrame() const
Definition: frame.hxx:1202
bool IsFootnotePage() const
Foot note interface.
Definition: pagefrm.hxx:185
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
virtual const SvxFormatBreakItem & GetBreakItem() const
Definition: findfrm.cxx:654
SwContentFrame * FindFirstBodyContent()
Definition: pagefrm.hxx:333
virtual const SwFormatPageDesc & GetPageDescItem() const
Definition: findfrm.cxx:659
long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1385
const SwFrame * GetPrevFrameForUpperSpaceCalc_(const SwFrame *_pProposedPrevFrame=nullptr) const
helper method to determine previous frame for calculation of the upper space
Definition: flowfrm.cxx:1285
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2622
bool IsFootnoteFrame() const
Definition: frame.hxx:1178
SwLayoutFrame * GetPrevSctLeaf()
Returns the preceding layout sheet where the frame can be moved into.
Definition: sectfrm.cxx:1917
void CheckDirChange()
checks the layout direction and invalidates the lower frames recursively, if necessary.
Definition: ssfrm.cxx:190
SwFrame & m_rThis
Definition: flowfrm.hxx:76
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:190
long YDiff(long n1, long n2) const
Definition: frame.hxx:1399
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:356
void SetRetouche() const
Definition: frame.hxx:979
SwTwips CalcUpperSpace(const SwBorderAttrs *pAttrs=nullptr, const SwFrame *pPr=nullptr, const bool _bConsiderGrid=true) const
method to determine the upper space hold by the frame
Definition: flowfrm.cxx:1391
bool IsFlyFrame() const
Definition: frame.hxx:1186
void InvalidateNextPrtArea()
method to invalidate printing area of next frame #i11859#
Definition: findfrm.cxx:1279
wrapper class for the positioning of Writer fly frames and drawing objects
const SvxFormatBreakItem & GetBreak(bool=true) const
Definition: frmatr.hxx:62
SwSection * m_pSection
Definition: sectfrm.hxx:38
void SetContentLock(bool bNew)
Definition: sectfrm.hxx:151
bool IsMoveable(const SwLayoutFrame *_pLayoutFrame=nullptr) const
determine, if frame is moveable in given environment
Definition: findfrm.cxx:1359
const SwFormatNoBalancedColumns & GetBalancedColumns(bool=true) const
Definition: fmtclbl.hxx:42
const SwLayoutFrame * GetPrevLayoutLeaf() const
Definition: frame.hxx:1000
const SwRect & getFrameArea() const
Definition: frame.hxx:175
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:965
bool getBrowseMode() const
Definition: viewopt.hxx:433
SwLayoutFrame * GetNextLeaf(MakePageType eMakePage)
Returns the next layout leaf in which we can move the frame.
Definition: flowfrm.cxx:903
bool IsEmptyPage() const
Definition: pagefrm.hxx:143
SwFlowFrame * m_pFollow
Definition: flowfrm.hxx:117
bool IsInTab() const
Definition: frame.hxx:931
const SwPageFrame * GetLastPage() const
Definition: rootfrm.hxx:357
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
bool IsFrameInSameContext(const SwFrame *pInnerFrame, const SwFrame *pFrame)
Definition: frmtool.cxx:3390
bool IsTextFrame() const
Definition: frame.hxx:1210
void GetSpacingValuesOfFrame(const SwFrame &rFrame, SwTwips &onLowerSpacing, SwTwips &onLineSpacing, bool &obIsLineSpacingProportional)
method to determine the spacing values of a frame
Definition: frmtool.cxx:3671
bool OnRightPage() const
Definition: frame.hxx:711
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
bool IsSctFrame() const
Definition: frame.hxx:1190
bool IsPageBreak(bool bAct) const
|* If there's a hard page break before the Frame AND there's a |* predecessor on the same page...
Definition: flowfrm.cxx:1139
bool IsFlowFrame() const
Definition: frame.hxx:1218
const SvxFormatKeepItem & GetKeep(bool=true) const
Definition: frmatr.hxx:56
SwLayoutFrame * GetNextCellLeaf()
Definition: findfrm.cxx:1511
SwLayoutFrame * GetNextSctLeaf(MakePageType eMakePage)
Returns the next layout sheet where the frame can be moved in.
Definition: sectfrm.cxx:1564
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 bool MoveBwdSuppressed(const SwDoc &p_rDoc, const SwFlowFrame &p_rFlowFrame, const SwLayoutFrame &p_rNewUpperFrame)
Definition: layouter.cxx:436
const SwFrame & GetFrame() const
Definition: flowfrm.hxx:151
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr)=0
virtual void Cut()=0
bool IsColumnFrame() const
Definition: frame.hxx:1158
const ::boost::optional< sal_uInt16 > & GetNumOffset() const
Definition: fmtpdsc.hxx:65
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1083
bool FrameContainsNode(SwContentFrame const &rFrame, sal_uLong nNodeIndex)
Definition: txtfrm.cxx:296
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1300
void InvalidateAutoCompleteWords() const
Definition: pagefrm.hxx:376
Style of a layout element.
Definition: frmfmt.hxx:57
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:717
bool IsContentFrame() const
Definition: frame.hxx:1206
SwFrame * GetIndPrev() const
Definition: frame.hxx:702
const SwContentFrame * GetFollow() const
Definition: cntfrm.hxx:114
const SdrObject * GetDrawObj() const
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:118
void InvalidateSpelling() const
Definition: pagefrm.hxx:367
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
bool HasParaSpaceAtPages(bool bSct) const
Definition: flowfrm.cxx:1243
bool IsFwdMoveAllowed() const
Definition: flowfrm.hxx:240
const SwFrame * GetLastLower() const
Definition: findfrm.cxx:1817
virtual bool ShouldBwdMoved(SwLayoutFrame *pNewUpper, bool &rReformat)=0
SwTwips CalcAddLowerSpaceAsLastInTableCell(const SwBorderAttrs *_pAttrs=nullptr) const
calculation of the additional space to be considered, if flow frame is the last inside a table cell ...
Definition: flowfrm.cxx:1709
sal_uInt16 GetBottomLine(const SwFrame &_rFrame) const
Definition: frmtool.hxx:462
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: sectfrm.cxx:334
SwFrame * GetIndNext()
Definition: frame.hxx:705
const SwSectionFrame * GetFollow() const
Definition: sectfrm.hxx:160
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
size_t size() const
Definition: sortedobjs.cxx:42
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:863
SwFrame * m_pLower
Definition: layfrm.hxx:53
virtual void Cut() override
Definition: wsfrm.cxx:1393
SwFrameFormat * GetLeftFormat(bool const bFirst=false)
Definition: pagedesc.cxx:362
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:190
SwTextGridItem const * GetGridItem(SwPageFrame const *const)
Definition: pagechg.cxx:2514
TElementType * First()
Definition: calbck.hxx:342
int i
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:129
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:597
virtual void SetNewFieldLst(bool bFlag)=0
SwSection * GetSection()
Definition: sectfrm.hxx:84
bool IsJoinLocked() const
Definition: flowfrm.hxx:175
void SetFollow(SwFlowFrame *const pFollow)
Definition: flowfrm.cxx:91
bool IsAction() const
SS for the Lay-/IdleAction and relatives.
Definition: viewimp.hxx:188
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
static bool PasteTree(SwFrame *, SwLayoutFrame *, SwFrame *, SwFrame *)
A specialized form of Paste(), which relocates a whole chain (this and the following, in particular).
Definition: flowfrm.cxx:464
void InvalidateSmartTags() const
Definition: pagefrm.hxx:372
bool IsRowFrame() const
Definition: frame.hxx:1198
SwTwips GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid() const
method to determine the upper space amount, which is considered for the previous frame and the page g...
Definition: flowfrm.cxx:1649
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:435
Provides access to settings of a document.
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
SwFrame * GetPrev()
Definition: frame.hxx:655
SwLayoutFrame * mpUpper
Definition: frame.hxx:318
bool HasLockedFollow() const
Definition: flowfrm.cxx:111
sal_uInt16 GetTopLine(const SwFrame &_rFrame, const SwFrame *_pPrevFrame=nullptr) const
Definition: frmtool.hxx:453
SwFlowFrame * m_pPrecede
Definition: flowfrm.hxx:118
bool isFrameAreaPositionValid() const
Definition: frame.hxx:162
bool IsUpdateExpFields()
Definition: viewimp.cxx:157
virtual ~SwFlowFrame()
Definition: flowfrm.cxx:79
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:119
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document settings interface.
Definition: format.cxx:757
bool isFrameAreaSizeValid() const
Definition: frame.hxx:163
SwContentFrame * FindLastContent(SwFindMode nMode=SwFindMode::None)
Definition: sectfrm.cxx:905
void InvalidatePos_()
Definition: frame.hxx:765
A page of the document layout.
Definition: pagefrm.hxx:40
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:200
sal_uInt8 BwdMoveNecessary(const SwPageFrame *pPage, const SwRect &rRect)
method to determine overlapping of an object that requests floating
Definition: flowfrm.cxx:273
SwTwips Shrink(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1507
void InvalidateSize()
Definition: frame.hxx:1005
SwLayoutFrame * GetPrevFootnoteLeaf(MakePageType eMakeFootnote)
Get the preceding layout leaf in that the frame can be moved.
Definition: ftnfrm.cxx:696
bool CheckMoveFwd(bool &rbMakePage, bool bKeep, bool bIgnoreMyOwnKeepValue)
Moves the Frame forward if it seems necessary regarding the current conditions and attributes...
Definition: flowfrm.cxx:1746
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1091
SwLayoutFrame * FindBodyCont()
Searches the first ContentFrame in BodyText below the page.
Definition: findfrm.cxx:42
const SwFootnoteFrame * GetMaster() const
Definition: ftnfrm.hxx:104
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:246
SwFrame * FindColFrame()
Definition: findfrm.cxx:529
void setFrameAreaPositionValid(bool bNew)
Definition: wsfrm.cxx:81
bool IsLayoutFrame() const
Definition: frame.hxx:1146
const SwFlowFrame * GetPrecede() const
Definition: flowfrm.hxx:172
SwContentFrame * FindLastBodyContent()
Searches the last ContentFrame in BodyText below the page.
Definition: findfrm.cxx:51
SwRowFrame * GetFirstNonHeadlineRow() const
Definition: tabfrm.cxx:5360
void MoveSubTree(SwLayoutFrame *pParent, SwFrame *pSibling=nullptr)
hook tree onto new parent with minimal operations and notifications
Definition: flowfrm.cxx:577
SwLayoutFrame * GetLeaf(MakePageType eMakePage, bool bFwd)
Definition: flowfrm.cxx:786
bool IsSquaredPageMode() const
Definition: docdesc.cxx:913
bool Is_Lower_Of(const SwFrame *pCurrFrame, const SdrObject *pObj)
Definition: frmtool.cxx:3344
MakePageType
Definition: frame.hxx:110
SwLayAction & GetLayAction()
Definition: viewimp.hxx:190
bool IsTabFrame() const
Definition: frame.hxx:1194
void CheckKeep()
Definition: flowfrm.cxx:146
void SimpleFormat()
Definition: sectfrm.cxx:1160
virtual SwFrameFormat & GetFrameFormat()=0
#define SAL_WARN_IF(condition, area, stream)
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:681
void ColUnlock()
Definition: sectfrm.hxx:87
unsigned char sal_uInt8
sal_uInt16 GetPhyPageNum() const
Definition: trvlfrm.cxx:1688
bool MoveLowerFootnotes(SwContentFrame *pStart, SwFootnoteBossFrame *pOldBoss, SwFootnoteBossFrame *pNewBoss, const bool bFootnoteNums)
Moving the Footnotes of all Lowers - starting from StartContent.
Definition: ftnfrm.cxx:2625
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
bool ForbiddenForFootnoteCntFwd() const
Definition: flowfrm.cxx:1830
const SwFrame * ContainsAny(const bool _bInvestigateFootnoteForSections=false) const
Method doesn't investigate content of footnotes by default.
Definition: findfrm.cxx:125
SwTwips GetUpperSpaceAmountConsideredForPrevFrame() const
method to determine the upper space amount, which is considered for the previous frame ...
Definition: flowfrm.cxx:1613
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:261
bool IsBackMoveLocked() const
Definition: ftnfrm.hxx:118
void InvalidateAll_()
Definition: frame.hxx:781
const SvxParaGridItem & GetParaGrid(bool=true) const
Definition: paratr.hxx:206
#define SAL_INFO(area, stream)
const SwFormatPageDesc & GetPageDesc(bool=true) const
Definition: fmtpdsc.hxx:76
SwFrameFormat * GetRightFormat(bool const bFirst=false)
Layout uses the following methods to obtain a format in order to be able to create a page...
Definition: pagedesc.cxx:369
bool IsNoTextFrame() const
Definition: frame.hxx:1214
static SwLayoutFrame * CutTree(SwFrame *)
A specialized form of Cut(), which relocates a whole chain (this and the following, in particular).
Definition: flowfrm.cxx:388
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:175
const SwDoc * GetDoc() const
Definition: swatrset.hxx:204
SwLayoutFrame * GetPrevCellLeaf()
Definition: findfrm.cxx:1521
bool IsColBodyFrame() const
These SwFrame inlines are here, so that frame.hxx does not need to include layfrm.hxx.
Definition: layfrm.hxx:209
const SwContentFrame * GetRef() const
Definition: ftnfrm.cxx:2878
bool IsPageFrame() const
Definition: frame.hxx:1154
const SwTextFootnote * GetAttr() const
Definition: ftnfrm.hxx:107
bool IsColBreak(bool bAct) const
|* If there's a hard column break before the Frame AND there is |* a predecessor in the same column...
Definition: flowfrm.cxx:1202
long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1358
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
bool IsAnFollow(const SwFlowFrame *pFlow) const
Definition: flowfrm.cxx:670
bool OnFirstPage() const
Definition: trvlfrm.cxx:1759
bool IsContentLocked() const
Definition: sectfrm.hxx:152
const SwTabFrame * GetFollow() const
Definition: tabfrm.hxx:243
SwLayoutFrame * GetNextFootnoteLeaf(MakePageType eMakePage)
Return the next layout leaf in that the frame can be moved.
Definition: ftnfrm.cxx:614
SwFlowFrame(SwFrame &rFrame)
Definition: flowfrm.cxx:70
long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1353
void InvalidatePrt_()
Definition: frame.hxx:757
#define SAL_WARN(area, stream)
SwFormatColl * GetFormatColl() const
Definition: node.hxx:447
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
const SwFrame * GetAnchorFrame() const
const SwLayoutFrame * GetNextLayoutLeaf() const
Definition: frame.hxx:996
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
SwPageFrame * InsertPage(SwPageFrame *pSibling, bool bFootnote)
Definition: pagechg.cxx:1287
static bool FrameMovedFwdByObjPos(const SwDoc &_rDoc, const SwTextFrame &_rTextFrame, sal_uInt32 &_ornToPageNum)
Definition: layouter.cxx:341
sal_uInt16 GetBaseHeight() const
Definition: tgrditem.hxx:75
bool IsFootnoteContFrame() const
Definition: frame.hxx:1174
bool WrongPageDesc(SwPageFrame *pNew)
Definition: flowfrm.cxx:827
virtual bool Prepare(const PrepareHint ePrep=PREP_CLEAR, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:587
const SwContentFrame * ContainsContent() const
Checks if the frame contains one or more ContentFrame's anywhere in his subsidiary structure; if so t...
Definition: findfrm.cxx:66
void InvalidateWordCount() const
Definition: pagefrm.hxx:380
const SwFlowFrame * GetFollow() const
Definition: flowfrm.hxx:168
bool IsBodyFrame() const
Definition: frame.hxx:1182
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:204
class for collecting anchored objects
Definition: sortedobjs.hxx:48
Container of body content (i.e.
Definition: bodyfrm.hxx:28
sal_uInt16 GetRubyHeight() const
Definition: tgrditem.hxx:78
bool IsFooterFrame() const
Definition: frame.hxx:1170
SwRootFrame * getRootFrame()
Definition: frame.hxx:657
bool GetContext() const
sal_uInt16 GetUpper() const
bool IsHeaderFrame() const
Definition: frame.hxx:1166
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:393
#define PROTOCOL_ENTER(pFrame, nFunc, nAct, pPar)
Definition: dbg_lay.hxx:92
const SvxULSpaceItem & GetULSpace() const
Definition: frmtool.hxx:364
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1075
static bool IsMoveBwdJump()
Definition: flowfrm.hxx:154
static bool lcl_getContextualSpacing(const SwFrame *pPrevFrame)
Definition: flowfrm.cxx:1379
SwFrame * GetNext()
Definition: frame.hxx:654
Base class of the Writer document model elements.
Definition: node.hxx:79