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