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