LibreOffice Module sw (master)  1
ftnfrm.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 <txtftn.hxx>
21 #include <fmtftn.hxx>
22 #include <ftnidx.hxx>
23 #include <pagefrm.hxx>
24 #include <colfrm.hxx>
25 #include <rootfrm.hxx>
26 #include <frmtool.hxx>
27 #include <ftnfrm.hxx>
28 #include <txtfrm.hxx>
29 #include <tabfrm.hxx>
30 #include <pagedesc.hxx>
31 #include <ftninfo.hxx>
32 #include <sectfrm.hxx>
33 #include <objectformatter.hxx>
34 #include <viewopt.hxx>
35 #include <calbck.hxx>
36 #include <ndindex.hxx>
37 #include <pam.hxx>
38 #include <ndtxt.hxx>
39 #include <osl/diagnose.h>
40 #include <sal/log.hxx>
42 
43 #define ENDNOTE 0x80000000
44 
47 static sal_uLong lcl_FindFootnotePos( const SwDoc *pDoc, const SwTextFootnote *pAttr )
48 {
49  const SwFootnoteIdxs &rFootnoteIdxs = pDoc->GetFootnoteIdxs();
50 
51  SwTextFootnote* pBla = const_cast<SwTextFootnote*>(pAttr);
52  SwFootnoteIdxs::const_iterator it = rFootnoteIdxs.find( pBla );
53  if ( it != rFootnoteIdxs.end() )
54  {
55  sal_uLong nRet = it - rFootnoteIdxs.begin();
56  if( pAttr->GetFootnote().IsEndNote() )
57  return nRet + ENDNOTE;
58  return nRet;
59  }
60  OSL_ENSURE( !pDoc, "FootnotePos not found." );
61  return 0;
62 }
63 
64 bool SwFootnoteFrame::operator<( const SwTextFootnote* pTextFootnote ) const
65 {
66  const SwDoc* pDoc = GetFormat()->GetDoc();
67  OSL_ENSURE( pDoc, "SwFootnoteFrame: Missing doc!" );
68  return lcl_FindFootnotePos( pDoc, GetAttr() ) <
69  lcl_FindFootnotePos( pDoc, pTextFootnote );
70 }
71 
72 /*
73 |*
74 |* bool lcl_NextFootnoteBoss( SwFootnoteBossFrame* pBoss, SwPageFrame* pPage)
75 |* sets pBoss on the next SwFootnoteBossFrame, which can either be a column
76 |* or a page (without columns). If the page changes meanwhile,
77 |* pPage contains the new page and this function returns true.
78 |*
79 |*/
80 
81 static bool lcl_NextFootnoteBoss( SwFootnoteBossFrame* &rpBoss, SwPageFrame* &rpPage,
82  bool bDontLeave )
83 {
84  if( rpBoss->IsColumnFrame() )
85  {
86  if( rpBoss->GetNext() )
87  {
88  rpBoss = static_cast<SwFootnoteBossFrame*>(rpBoss->GetNext()); //next column
89  return false;
90  }
91  if( rpBoss->IsInSct() )
92  {
93  SwSectionFrame* pSct = rpBoss->FindSctFrame()->GetFollow();
94  if( pSct )
95  {
96  OSL_ENSURE( pSct->Lower() && pSct->Lower()->IsColumnFrame(),
97  "Where's the column?" );
98  rpBoss = static_cast<SwColumnFrame*>(pSct->Lower());
99  SwPageFrame* pOld = rpPage;
100  rpPage = pSct->FindPageFrame();
101  return pOld != rpPage;
102  }
103  else if( bDontLeave )
104  {
105  rpPage = nullptr;
106  rpBoss = nullptr;
107  return false;
108  }
109  }
110  }
111  rpPage = static_cast<SwPageFrame*>(rpPage->GetNext()); // next page
112  rpBoss = rpPage;
113  if( rpPage )
114  {
115  SwLayoutFrame* pBody = rpPage->FindBodyCont();
116  if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() )
117  rpBoss = static_cast<SwFootnoteBossFrame*>(pBody->Lower()); // first column
118  }
119  return true;
120 }
121 
123 static sal_uInt16 lcl_ColumnNum( const SwFrame* pBoss )
124 {
125  sal_uInt16 nRet = 0;
126  if( !pBoss->IsColumnFrame() )
127  return 0;
128  const SwFrame* pCol;
129  if( pBoss->IsInSct() )
130  {
131  pCol = pBoss->GetUpper()->FindColFrame();
132  if( pBoss->GetNext() || pBoss->GetPrev() )
133  {
134  while( pBoss )
135  {
136  ++nRet; // Section columns
137  pBoss = pBoss->GetPrev();
138  }
139  }
140  }
141  else
142  pCol = pBoss;
143  while( pCol )
144  {
145  nRet += 256; // Page columns
146  pCol = pCol->GetPrev();
147  }
148  return nRet;
149 }
150 
152  SwLayoutFrame( pFormat, pSib )
153 {
155 }
156 
157 SwFootnoteFrame* SwFootnoteContFrame::AddChained(bool bAppend, SwFrame* pThis, bool bDefaultFormat)
158 {
159  SwFootnoteFrame *pOld = pThis->FindFootnoteFrame();
160  SwFrameFormat *pFormat = pOld->GetFormat();
161  if (bDefaultFormat)
162  pFormat = pFormat->GetDoc()->GetDfltFrameFormat();
163 
164  SwFootnoteFrame *pNew = new SwFootnoteFrame(pFormat, pOld, pOld->GetRef(), pOld->GetAttr());
165 
166  if (bAppend)
167  {
168  if (pOld->GetFollow())
169  {
170  pNew->SetFollow(pOld->GetFollow());
171  pOld->GetFollow()->SetMaster(pNew);
172  }
173  pOld->SetFollow(pNew);
174  pNew->SetMaster(pOld);
175  }
176  else
177  {
178  if (pOld->GetMaster())
179  {
180  pNew->SetMaster(pOld->GetMaster());
181  pOld->GetMaster()->SetFollow(pNew);
182  }
183  pNew->SetFollow(pOld);
184  pOld->SetMaster(pNew);
185  }
186 
187  return pNew;
188 }
189 
190 // lcl_Undersize(..) walks over a SwFrame and its contents
191 // and returns the sum of all requested TextFrame magnifications.
192 
193 static tools::Long lcl_Undersize( const SwFrame* pFrame )
194 {
195  tools::Long nRet = 0;
196  SwRectFnSet aRectFnSet(pFrame);
197  if( pFrame->IsTextFrame() )
198  {
199  if( static_cast<const SwTextFrame*>(pFrame)->IsUndersized() )
200  {
201  // Does this TextFrame would like to be a little bit bigger?
202  nRet = static_cast<const SwTextFrame*>(pFrame)->GetParHeight() -
203  aRectFnSet.GetHeight(pFrame->getFramePrintArea());
204  if( nRet < 0 )
205  nRet = 0;
206  }
207  }
208  else if( pFrame->IsLayoutFrame() )
209  {
210  const SwFrame* pNxt = static_cast<const SwLayoutFrame*>(pFrame)->Lower();
211  while( pNxt )
212  {
213  nRet += lcl_Undersize( pNxt );
214  pNxt = pNxt->GetNext();
215  }
216  }
217  return nRet;
218 }
219 
220 namespace sw {
221 
223 {
224  return rInf.GetTopDist() + rInf.GetBottomDist() + rInf.GetLineWidth();
225 }
226 
227 } // namespace sw
228 
231 {
232  // calculate total border, only one distance to the top
233  const SwPageFrame* pPage = FindPageFrame();
234  const SwPageFootnoteInfo &rInf = pPage->GetPageDesc()->GetFootnoteInfo();
236  SwRectFnSet aRectFnSet(this);
237 
238  if ( !isFramePrintAreaValid() )
239  {
242 
243  aRectFnSet.SetTop( aPrt, nBorder );
244  aRectFnSet.SetWidth( aPrt, aRectFnSet.GetWidth(getFrameArea()) );
245  aRectFnSet.SetHeight(aPrt, aRectFnSet.GetHeight(getFrameArea()) - nBorder );
246 
247  if( aRectFnSet.GetHeight(aPrt) < 0 && !pPage->IsFootnotePage() )
248  {
249  setFrameAreaSizeValid(false);
250  }
251  }
252 
253  if ( isFrameAreaSizeValid() )
254  return;
255 
256  bool bGrow = pPage->IsFootnotePage();
257  if( bGrow )
258  {
259  const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
260  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
261  bGrow = false;
262  }
263  if( bGrow )
264  Grow( LONG_MAX );
265  else
266  {
267  // VarSize is determined based on the content plus the borders
268  SwTwips nRemaining = 0;
269  SwFrame *pFrame = m_pLower;
270  while ( pFrame )
271  { // lcl_Undersize(..) respects (recursively) TextFrames, which
272  // would like to be bigger. They are created especially in
273  // columnized borders, if these do not have their maximum
274  // size yet.
275  nRemaining += aRectFnSet.GetHeight(pFrame->getFrameArea()) + lcl_Undersize( pFrame );
276  pFrame = pFrame->GetNext();
277  }
278  // add the own border
279  nRemaining += nBorder;
280 
281  SwTwips nDiff;
282  if( IsInSct() )
283  {
284  nDiff = -aRectFnSet.BottomDist( getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper()) );
285  if( nDiff > 0 )
286  {
287  if( nDiff > aRectFnSet.GetHeight(getFrameArea()) )
288  {
289  nDiff = aRectFnSet.GetHeight(getFrameArea());
290  }
291 
293  aRectFnSet.AddBottom( aFrm, -nDiff );
294  aRectFnSet.AddHeight( aFrm, -nDiff );
295  }
296  }
297  nDiff = aRectFnSet.GetHeight(getFrameArea()) - nRemaining;
298  if ( nDiff > 0 )
299  Shrink( nDiff );
300  else if ( nDiff < 0 )
301  {
302  Grow( -nDiff );
303  // It may happen that there is less space available,
304  // than what the border needs - the size of the PrtArea
305  // will then be negative.
306  SwTwips nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
307  if( nPrtHeight < 0 )
308  {
309  const SwTwips nTmpDiff = std::max( SwTwips(aRectFnSet.GetTop(getFramePrintArea())), -nPrtHeight );
311  aRectFnSet.SubTop( aPrt, nTmpDiff );
312  }
313  }
314  }
315 
316  setFrameAreaSizeValid(true);
317 }
318 
320 {
321  // No check if FixSize since FootnoteContainer are variable up to their max. height.
322  // If the max. height is LONG_MAX, take as much space as needed.
323  // If the page is a special footnote page, take also as much as possible.
324  assert(GetUpper() && GetUpper()->IsFootnoteBossFrame());
325 
326  SwRectFnSet aRectFnSet(this);
327  if( aRectFnSet.GetHeight(getFrameArea()) > 0 &&
328  nDist > ( LONG_MAX - aRectFnSet.GetHeight(getFrameArea()) ) )
329  nDist = LONG_MAX - aRectFnSet.GetHeight(getFrameArea());
330 
331  SwFootnoteBossFrame *pBoss = static_cast<SwFootnoteBossFrame*>(GetUpper());
332  if( IsInSct() )
333  {
334  SwSectionFrame* pSect = FindSctFrame();
335  OSL_ENSURE( pSect, "GrowFrame: Missing SectFrame" );
336  // In a section, which has to maximize, a footnotecontainer is allowed
337  // to grow, when the section can't grow anymore.
338  if( !bTst && !pSect->IsColLocked() &&
339  pSect->ToMaximize( false ) && pSect->Growable() )
340  {
341  pSect->InvalidateSize();
342  return 0;
343  }
344  }
345  const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
346  const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
347  SwPageFrame *pPage = pBoss->FindPageFrame();
348  if ( bBrowseMode || !pPage->IsFootnotePage() )
349  {
350  if ( pBoss->GetMaxFootnoteHeight() != LONG_MAX )
351  {
352  nDist = std::min( nDist,
353  SwTwips(pBoss->GetMaxFootnoteHeight() - aRectFnSet.GetHeight(getFrameArea())) );
354  if ( nDist <= 0 )
355  return 0;
356  }
357  // FootnoteBoss also influences the max value
358  if( !IsInSct() )
359  {
360  const SwTwips nMax = pBoss->GetVarSpace();
361  if ( nDist > nMax )
362  nDist = nMax;
363  if ( nDist <= 0 )
364  return 0;
365  }
366  }
367  else if( nDist > aRectFnSet.GetHeight(GetPrev()->getFrameArea()) )
368  // do not use more space than the body has
369  nDist = aRectFnSet.GetHeight(GetPrev()->getFrameArea());
370 
371  tools::Long nAvail = 0;
372  if ( bBrowseMode )
373  {
374  nAvail = GetUpper()->getFramePrintArea().Height();
375  const SwFrame *pAvail = GetUpper()->Lower();
376  do
377  { nAvail -= pAvail->getFrameArea().Height();
378  pAvail = pAvail->GetNext();
379  } while ( pAvail );
380  if ( nAvail > nDist )
381  nAvail = nDist;
382  }
383 
384  if ( !bTst )
385  {
387  aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) + nDist );
388 
389  if( IsVertical() && !IsVertLR() )
390  {
391  aFrm.Pos().AdjustX( -nDist );
392  }
393  }
394  tools::Long nGrow = nDist - nAvail,
395  nReal = 0;
396  if ( nGrow > 0 )
397  {
398  SwNeighbourAdjust nAdjust = pBoss->NeighbourhoodAdjustment();
399  if( SwNeighbourAdjust::OnlyAdjust == nAdjust )
400  nReal = AdjustNeighbourhood( nGrow, bTst );
401  else
402  {
403  if( SwNeighbourAdjust::GrowAdjust == nAdjust )
404  {
405  SwFrame* pFootnote = Lower();
406  if( pFootnote )
407  {
408  while( pFootnote->GetNext() )
409  pFootnote = pFootnote->GetNext();
410  if( static_cast<SwFootnoteFrame*>(pFootnote)->GetAttr()->GetFootnote().IsEndNote() )
411  {
412  nReal = AdjustNeighbourhood( nGrow, bTst );
413  nAdjust = SwNeighbourAdjust::GrowShrink; // no more AdjustNeighbourhood
414  }
415  }
416  }
417  nReal += pBoss->Grow( nGrow - nReal, bTst );
418  if( ( SwNeighbourAdjust::GrowAdjust == nAdjust || SwNeighbourAdjust::AdjustGrow == nAdjust )
419  && nReal < nGrow )
420  nReal += AdjustNeighbourhood( nGrow - nReal, bTst );
421  }
422  }
423 
424  nReal += nAvail;
425 
426  if ( !bTst )
427  {
428  if ( nReal != nDist )
429  {
430  nDist -= nReal;
431 
432  // We can only respect the boundless wish so much
434  aFrm.AddHeight( -nDist );
435 
436  if( IsVertical() && !IsVertLR() )
437  {
438  aFrm.Pos().AdjustX(nDist );
439  }
440  }
441 
442  // growing happens upwards, so successors to not need to be invalidated
443  if( nReal )
444  {
445  InvalidateSize_();
446  InvalidatePos_();
447  InvalidatePage( pPage );
448  }
449  }
450  return nReal;
451 }
452 
453 SwTwips SwFootnoteContFrame::ShrinkFrame( SwTwips nDiff, bool bTst, bool bInfo )
454 {
455  SwPageFrame *pPage = FindPageFrame();
456  bool bShrink = false;
457  if ( pPage )
458  {
459  if( !pPage->IsFootnotePage() )
460  bShrink = true;
461  else
462  {
463  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
464  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
465  bShrink = true;
466  }
467  }
468  if( bShrink )
469  {
470  SwTwips nRet = SwLayoutFrame::ShrinkFrame( nDiff, bTst, bInfo );
471  if( IsInSct() && !bTst )
473  if ( !bTst && nRet )
474  {
475  InvalidatePos_();
476  InvalidatePage( pPage );
477  }
478  return nRet;
479  }
480  return 0;
481 }
482 
484  SwLayoutFrame( pFormat, pSib ),
485  mpFollow( nullptr ),
486  mpMaster( nullptr ),
487  mpReference( pCnt ),
488  mpAttribute( pAt ),
489  mbBackMoveLocked( false ),
490  // #i49383#
491  mbUnlockPosOfLowerObjs( true )
492 {
494 }
495 
497 {
498  if ( !GetNext() )
499  return;
500 
501  SwFrame *pCnt = static_cast<SwLayoutFrame*>(GetNext())->ContainsAny();
502  if( !pCnt )
503  return;
504 
505  pCnt->InvalidatePage( pPage );
506  pCnt->InvalidatePrt_();
507  do
508  { pCnt->InvalidatePos_();
509  if( pCnt->IsSctFrame() )
510  {
511  SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny();
512  if( pTmp )
513  pTmp->InvalidatePos_();
514  }
515  pCnt->GetUpper()->InvalidateSize_();
516  pCnt = pCnt->FindNext();
517  } while ( pCnt && GetUpper()->IsAnLower( pCnt ) );
518 }
519 
521 {
523  return true;
524  // needs to be in sync with the ::Cut logic
525  const SwLayoutFrame *pUp = GetUpper();
526  if (pUp)
527  {
528  if (GetPrev())
529  return false;
530 
531  // The last footnote takes its container along if it
532  // is deleted. Cut would put pUp->Lower() to the value
533  // of GetNext(), so if there is no GetNext then
534  // Cut would delete pUp. If that condition is true
535  // here then check if the container is delete-forbidden
536  return !GetNext() && pUp->IsDeleteForbidden();
537  }
538  return false;
539 }
540 
542 {
543  if ( GetNext() )
544  GetNext()->InvalidatePos();
545  else if ( GetPrev() )
546  GetPrev()->SetRetouche();
547 
548  // first move then shrink Upper
549  SwLayoutFrame *pUp = GetUpper();
550 
551  // correct chaining
552  SwFootnoteFrame *pFootnote = this;
553  if ( pFootnote->GetFollow() )
554  pFootnote->GetFollow()->SetMaster( pFootnote->GetMaster() );
555  if ( pFootnote->GetMaster() )
556  pFootnote->GetMaster()->SetFollow( pFootnote->GetFollow() );
557  pFootnote->SetFollow( nullptr );
558  pFootnote->SetMaster( nullptr );
559 
560  // cut all connections
562 
563  if ( !pUp )
564  return;
565 
566  // The last footnote takes its container along
567  if (!pUp->Lower())
568  {
569  SwPageFrame *pPage = pUp->FindPageFrame();
570  if ( pPage )
571  {
572  SwLayoutFrame *pBody = pPage->FindBodyCont();
573  if( pBody && !pBody->ContainsContent() )
574  pPage->getRootFrame()->SetSuperfluous();
575  }
576  SwSectionFrame* pSect = pUp->FindSctFrame();
577  pUp->Cut();
579  // If the last footnote container was removed from a column
580  // section without a Follow, then this section can be shrunk.
581  if( pSect && !pSect->ToMaximize( false ) && !pSect->IsColLocked() )
582  pSect->InvalidateSize_();
583  }
584  else
585  { if ( getFrameArea().Height() )
586  pUp->Shrink( getFrameArea().Height() );
587  pUp->SetCompletePaint();
588  pUp->InvalidatePage();
589  }
590 }
591 
592 void SwFootnoteFrame::Paste( SwFrame* pParent, SwFrame* pSibling )
593 {
594  OSL_ENSURE( pParent, "no parent in Paste." );
595  OSL_ENSURE( pParent->IsLayoutFrame(), "Parent is ContentFrame." );
596  OSL_ENSURE( pParent != this, "I am my own parent." );
597  OSL_ENSURE( pSibling != this, "I am my own sibling." );
598  OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
599  "I am still somewhere registered." );
600 
601  // insert into tree structure
602  InsertBefore( static_cast<SwLayoutFrame*>(pParent), pSibling );
603 
604  SwRectFnSet aRectFnSet(this);
605  if( aRectFnSet.GetWidth(getFrameArea())!=aRectFnSet.GetWidth(pParent->getFramePrintArea()) )
606  InvalidateSize_();
607  InvalidatePos_();
608  SwPageFrame *pPage = FindPageFrame();
609  InvalidatePage( pPage );
610  if ( GetNext() )
611  GetNext()->InvalidatePos_();
612  if( aRectFnSet.GetHeight(getFrameArea()) )
613  pParent->Grow( aRectFnSet.GetHeight(getFrameArea()) );
614 
615  // If the predecessor is the master and/or the successor is the Follow,
616  // then take their content and destroy them.
617  if ( GetPrev() && GetPrev() == GetMaster() )
618  {
619  OSL_ENSURE( SwFlowFrame::CastFlowFrame( GetPrev()->GetLower() ),
620  "Footnote without content?" );
622  MoveSubTree( this, GetLower() );
623  SwFrame *pDel = GetPrev();
624  assert(pDel != this);
625  pDel->Cut();
626  SwFrame::DestroyFrame(pDel);
627  }
628  if ( GetNext() && GetNext() == GetFollow() )
629  {
630  OSL_ENSURE( SwFlowFrame::CastFlowFrame( GetNext()->GetLower() ),
631  "Footnote without content?" );
633  SwFrame *pDel = GetNext();
634  assert(pDel != this);
635  pDel->Cut();
636  SwFrame::DestroyFrame(pDel);
637  }
638 #if OSL_DEBUG_LEVEL > 0
639  SwDoc *pDoc = GetFormat()->GetDoc();
640  if ( GetPrev() )
641  {
642  OSL_ENSURE( lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrame*>(GetPrev())->GetAttr() ) <=
643  lcl_FindFootnotePos( pDoc, GetAttr() ), "Prev is not FootnotePrev" );
644  }
645  if ( GetNext() )
646  {
647  OSL_ENSURE( lcl_FindFootnotePos( pDoc, GetAttr() ) <=
648  lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrame*>(GetNext())->GetAttr() ),
649  "Next is not FootnoteNext" );
650  }
651 #endif
652  InvalidateNxtFootnoteCnts( pPage );
653 }
654 
658 {
660  SwPageFrame* pOldPage = pOldBoss->FindPageFrame();
661  SwPageFrame* pPage;
662  SwFootnoteBossFrame *pBoss = pOldBoss->IsColumnFrame() ?
663  static_cast<SwFootnoteBossFrame*>(pOldBoss->GetNext()) : nullptr; // next column, if existing
664  if( pBoss )
665  pPage = nullptr;
666  else
667  {
668  if( pOldBoss->GetUpper()->IsSctFrame() )
669  { // this can only be in a column area
670  SwLayoutFrame* pNxt = pOldBoss->GetNextSctLeaf( eMakePage );
671  if( pNxt )
672  {
673  OSL_ENSURE( pNxt->IsColBodyFrame(), "GetNextFootnoteLeaf: Funny Leaf" );
674  pBoss = static_cast<SwFootnoteBossFrame*>(pNxt->GetUpper());
675  pPage = pBoss->FindPageFrame();
676  }
677  else
678  return nullptr;
679  }
680  else
681  {
682  // next page
683  pPage = static_cast<SwPageFrame*>(pOldPage->GetNext());
684  // skip empty pages
685  if( pPage && pPage->IsEmptyPage() )
686  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
687  pBoss = pPage;
688  }
689  }
690  // What do we have until here?
691  // pBoss != NULL, pPage==NULL => pBoss is the next column on the same page
692  // pBoss != NULL, pPage!=NULL => pBoss and pPage are the following page (empty pages skipped)
693  // pBoss == NULL => pPage == NULL, so there are no following pages
694 
695  // If the footnote has already a Follow we do not need to search.
696  // However, if there are unwanted empty columns/pages between Footnote and Follow,
697  // create another Follow on the next best column/page and the rest will sort itself out.
698  SwFootnoteFrame *pFootnote = FindFootnoteFrame();
699  if ( pFootnote && pFootnote->GetFollow() )
700  {
701  SwFootnoteBossFrame* pTmpBoss = pFootnote->GetFollow()->FindFootnoteBossFrame();
702  // Following cases will be handled:
703  // 1. both "FootnoteBoss"es are neighboring columns/pages
704  // 2. the new one is the first column of a neighboring page
705  // 3. the new one is the first column in a section of the next page
706  while( pTmpBoss != pBoss && pTmpBoss && !pTmpBoss->GetPrev() )
707  pTmpBoss = pTmpBoss->GetUpper()->FindFootnoteBossFrame();
708  if( pTmpBoss == pBoss )
709  return pFootnote->GetFollow();
710  }
711 
712  // If no pBoss could be found or it is a "wrong" page, we need a new page.
713  if ( !pBoss || ( pPage && pPage->IsEndNotePage() && !pOldPage->IsEndNotePage() ) )
714  {
715  if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
716  {
717  pBoss = InsertPage( pOldPage, pOldPage->IsFootnotePage() );
718  static_cast<SwPageFrame*>(pBoss)->SetEndNotePage( pOldPage->IsEndNotePage() );
719  }
720  else
721  return nullptr;
722  }
723  if( pBoss->IsPageFrame() )
724  {
725  // If this page has columns, then go to the first one
726  SwLayoutFrame* pLay = pBoss->FindBodyCont();
727  if( pLay && pLay->Lower() && pLay->Lower()->IsColumnFrame() )
728  pBoss = static_cast<SwFootnoteBossFrame*>(pLay->Lower());
729  }
730  // found column/page - add myself
731  SwFootnoteContFrame *pCont = pBoss->FindFootnoteCont();
732  if ( !pCont && pBoss->GetMaxFootnoteHeight() &&
733  ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
734  pCont = pBoss->MakeFootnoteCont();
735  return pCont;
736 }
737 
740 {
741  // The predecessor of a footnote is (if possible)
742  // the master of the chain of the footnote.
743  SwFootnoteFrame *pFootnote = FindFootnoteFrame();
744  SwLayoutFrame *pRet = pFootnote->GetMaster();
745 
747  SwPageFrame *pOldPage = pOldBoss->FindPageFrame();
748 
749  if ( !pOldBoss->GetPrev() && !pOldPage->GetPrev() )
750  return pRet; // there is neither a predecessor column nor page
751 
752  if ( !pRet )
753  {
754  bool bEndn = pFootnote->GetAttr()->GetFootnote().IsEndNote();
755  SwFrame* pTmpRef = nullptr;
756  const IDocumentSettingAccess& rSettings
757  = pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
758  if( bEndn && pFootnote->IsInSct() )
759  {
760  SwSectionFrame* pSect = pFootnote->FindSctFrame();
761  if( pSect->IsEndnAtEnd() )
762  // Endnotes at the end of the section.
763  pTmpRef = pSect->FindLastContent( SwFindMode::LastCnt );
764  }
765  else if (bEndn && rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
766  {
767  // Endnotes at the end of the document.
768  SwPageFrame* pPage = getRootFrame()->GetLastPage();
769  assert(pPage);
770  SwFrame* pPrevPage = pPage->GetPrev();
771  if (pPrevPage)
772  {
773  // Have a last but one page, use that since we try to get a preceding frame.
774  assert(pPrevPage->IsPageFrame());
775  pPage = static_cast<SwPageFrame*>(pPrevPage);
776  }
777  pTmpRef = pPage->FindLastBodyContent();
778  }
779  if( !pTmpRef )
780  // Endnotes on a separate page.
781  pTmpRef = pFootnote->GetRef();
782  SwFootnoteBossFrame* pStop = pTmpRef->FindFootnoteBossFrame( !bEndn );
783 
784  const sal_uInt16 nNum = pStop->GetPhyPageNum();
785 
786  // Do not leave the corresponding page if the footnote should
787  // be shown at the document ending or the footnote is an endnote.
788  const bool bEndNote = pOldPage->IsEndNotePage();
789  const bool bFootnoteEndDoc = pOldPage->IsFootnotePage();
790  SwFootnoteBossFrame* pNxtBoss = pOldBoss;
791  SwSectionFrame *pSect = pNxtBoss->GetUpper()->IsSctFrame() ?
792  static_cast<SwSectionFrame*>(pNxtBoss->GetUpper()) : nullptr;
793 
794  do
795  {
796  if( pNxtBoss->IsColumnFrame() && pNxtBoss->GetPrev() )
797  pNxtBoss = static_cast<SwFootnoteBossFrame*>(pNxtBoss->GetPrev()); // one column backwards
798  else // one page backwards
799  {
800  SwLayoutFrame* pBody = nullptr;
801  if( pSect )
802  {
803  if( pSect->IsFootnoteLock() )
804  {
805  if( pNxtBoss == pOldBoss )
806  return nullptr;
807  pStop = pNxtBoss;
808  }
809  else
810  {
811  pSect = pSect->FindMaster();
812  if( !pSect || !pSect->Lower() )
813  return nullptr;
814  OSL_ENSURE( pSect->Lower()->IsColumnFrame(),
815  "GetPrevFootnoteLeaf: Where's the column?" );
816  pNxtBoss = static_cast<SwFootnoteBossFrame*>(pSect->Lower());
817  pBody = pSect;
818  }
819  }
820  else
821  {
822  SwPageFrame* pPage = static_cast<SwPageFrame*>(pNxtBoss->FindPageFrame()->GetPrev());
823  if( !pPage || pPage->GetPhyPageNum() < nNum ||
824  bEndNote != pPage->IsEndNotePage() || bFootnoteEndDoc != pPage->IsFootnotePage() )
825  return nullptr; // no further pages found
826  pNxtBoss = pPage;
827  pBody = pPage->FindBodyCont();
828  }
829  // We have the previous page, we might need to find the last column of it
830  if( pBody )
831  {
832  if ( pBody->Lower() && pBody->Lower()->IsColumnFrame() )
833  {
834  pNxtBoss = static_cast<SwFootnoteBossFrame*>(pBody->GetLastLower());
835  }
836  }
837  }
838  SwFootnoteContFrame *pCont = pNxtBoss->FindFootnoteCont();
839  if ( pCont )
840  {
841  pRet = pCont;
842  break;
843  }
844  if ( pStop == pNxtBoss )
845  {
846  // Reached the column/page of the reference.
847  // Try to add a container and paste our content.
848  if ( eMakeFootnote == MAKEPAGE_FTN && pNxtBoss->GetMaxFootnoteHeight() )
849  pRet = pNxtBoss->MakeFootnoteCont();
850  break;
851  }
852  } while( !pRet );
853  }
854  if ( pRet )
855  {
856  const SwFootnoteBossFrame* pNewBoss = pRet->FindFootnoteBossFrame();
857  bool bJump = false;
858  if( pOldBoss->IsColumnFrame() && pOldBoss->GetPrev() ) // a previous column exists
859  bJump = pOldBoss->GetPrev() != static_cast<SwFrame const *>(pNewBoss); // did we chose it?
860  else if( pNewBoss->IsColumnFrame() && pNewBoss->GetNext() )
861  bJump = true; // there is another column after the boss (not the old boss)
862  else
863  {
864  // Will be reached only if old and new boss are both either pages or the last (new)
865  // or first (old) column of a page. In this case, check if pages were skipped.
866  const sal_uInt16 nDiff = pOldPage->GetPhyPageNum() - pRet->FindPageFrame()->GetPhyPageNum();
867  if ( nDiff > 2 ||
868  (nDiff > 1 && !static_cast<SwPageFrame*>(pOldPage->GetPrev())->IsEmptyPage()) )
869  bJump = true;
870  }
871  if( bJump )
873  }
874  return pRet;
875 }
876 
878 {
879  if ( !IsInDocBody() )
880  return false;
881 
882  if ( IsInTab() )
883  {
884  // no footnotes in repeated headlines
885  const SwTabFrame *pTab = const_cast<SwFrame*>(this)->ImplFindTabFrame();
886  assert(pTab);
887  if ( pTab->IsFollow() )
888  return !pTab->IsInHeadline( *this );
889  }
890  return true;
891 }
892 
894 {
895  // page numbering only if set at the document
896  if ( GetFormat()->GetDoc()->GetFootnoteInfo().m_eNum == FTNNUM_PAGE )
897  {
898  SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower());
899  while ( pPage && !pPage->IsFootnotePage() )
900  {
901  pPage->UpdateFootnoteNum();
902  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
903  }
904  }
905 }
906 
908 void sw_RemoveFootnotes( SwFootnoteBossFrame* pBoss, bool bPageOnly, bool bEndNotes )
909 {
910  do
911  {
912  SwFootnoteContFrame *pCont = pBoss->FindFootnoteCont();
913  if ( pCont )
914  {
915  SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower());
916  assert(pFootnote);
917  if ( bPageOnly )
918  while ( pFootnote->GetMaster() )
919  pFootnote = pFootnote->GetMaster();
920  do
921  {
922  SwFootnoteFrame *pNxt = static_cast<SwFootnoteFrame*>(pFootnote->GetNext());
923  if ( !pFootnote->GetAttr()->GetFootnote().IsEndNote() ||
924  bEndNotes )
925  {
926  pFootnote->GetRef()->Prepare( PrepareHint::FootnoteInvalidation, static_cast<void*>(pFootnote->GetAttr()) );
927  if ( bPageOnly && !pNxt )
928  pNxt = pFootnote->GetFollow();
929  pFootnote->Cut();
930  SwFrame::DestroyFrame(pFootnote);
931  }
932  pFootnote = pNxt;
933 
934  } while ( pFootnote );
935  }
936  if( !pBoss->IsInSct() )
937  {
938  // A sectionframe with the Footnote/EndnAtEnd-flags may contain
939  // foot/endnotes. If the last lower frame of the bodyframe is
940  // a multicolumned sectionframe, it may contain footnotes, too.
941  SwLayoutFrame* pBody = pBoss->FindBodyCont();
942  if( pBody && pBody->Lower() )
943  {
944  SwFrame* pLow = pBody->Lower();
945  while (pLow)
946  {
947  if( pLow->IsSctFrame() && ( !pLow->GetNext() ||
948  static_cast<SwSectionFrame*>(pLow)->IsAnyNoteAtEnd() ) &&
949  static_cast<SwSectionFrame*>(pLow)->Lower() &&
950  static_cast<SwSectionFrame*>(pLow)->Lower()->IsColumnFrame() )
951  sw_RemoveFootnotes( static_cast<SwColumnFrame*>(static_cast<SwSectionFrame*>(pLow)->Lower()),
952  bPageOnly, bEndNotes );
953  pLow = pLow->GetNext();
954  }
955  }
956  }
957  // is there another column?
958  pBoss = pBoss->IsColumnFrame() ? static_cast<SwColumnFrame*>(pBoss->GetNext()) : nullptr;
959  } while( pBoss );
960 }
961 
962 void SwRootFrame::RemoveFootnotes( SwPageFrame *pPage, bool bPageOnly, bool bEndNotes )
963 {
964  if ( !pPage )
965  pPage = static_cast<SwPageFrame*>(Lower());
966 
967  do
968  { // On columned pages we have to clean up in all columns
969  SwFootnoteBossFrame* pBoss;
970  SwLayoutFrame* pBody = pPage->FindBodyCont();
971  if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() )
972  pBoss = static_cast<SwFootnoteBossFrame*>(pBody->Lower()); // the first column
973  else
974  pBoss = pPage; // no columns
975  sw_RemoveFootnotes( pBoss, bPageOnly, bEndNotes );
976  if ( !bPageOnly )
977  {
978  if ( pPage->IsFootnotePage() &&
979  (!pPage->IsEndNotePage() || bEndNotes) )
980  {
981  SwFrame *pDel = pPage;
982  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
983  pDel->Cut();
984  SwFrame::DestroyFrame(pDel);
985  }
986  else
987  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
988  }
989  else
990  break;
991 
992  } while ( pPage );
993 }
994 
997 {
998  SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower());
999  while ( pPage && !pPage->IsFootnotePage() )
1000  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1001  while ( pPage && pPage->IsEndNotePage() != bEndNote )
1002  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1003 
1004  if ( pPage )
1005  SwFrame::CheckPageDescs( pPage, false );
1006 }
1007 
1017 {
1018  SAL_WARN_IF(FindFootnoteCont(), "sw.core", "footnote container exists already");
1019 
1020  SwFootnoteContFrame *pNew = new SwFootnoteContFrame( GetFormat()->GetDoc()->GetDfltFrameFormat(), this );
1021  SwLayoutFrame *pLay = FindBodyCont();
1022  pNew->Paste( this, pLay->GetNext() );
1023  return pNew;
1024 }
1025 
1027 {
1028  SwFrame *pFrame = Lower();
1029  while( pFrame && !pFrame->IsFootnoteContFrame() )
1030  pFrame = pFrame->GetNext();
1031 
1032 #if OSL_DEBUG_LEVEL > 0
1033  if ( pFrame )
1034  {
1035  SwFrame *pFootnote = pFrame->GetLower();
1036  assert(pFootnote);
1037  while ( pFootnote )
1038  {
1039  assert(pFootnote->IsFootnoteFrame() && "Neighbor of footnote must be a footnote");
1040  pFootnote = pFootnote->GetNext();
1041  }
1042  }
1043 #endif
1044 
1045  return static_cast<SwFootnoteContFrame*>(pFrame);
1046 }
1047 
1050 {
1051  SwFootnoteContFrame *pCont = nullptr;
1052  if ( !GetFormat()->GetDoc()->GetFootnoteIdxs().empty() )
1053  {
1054  pCont = FindFootnoteCont();
1055  if ( !pCont )
1056  {
1057  SwPageFrame *pPage = FindPageFrame();
1058  SwFootnoteBossFrame* pBoss = this;
1059  bool bEndNote = pPage->IsEndNotePage();
1060  do
1061  {
1062  bool bChgPage = lcl_NextFootnoteBoss( pBoss, pPage, bDontLeave );
1063  // Found another boss? When changing pages, also the endnote flag must match.
1064  if( pBoss && ( !bChgPage || pPage->IsEndNotePage() == bEndNote ) )
1065  pCont = pBoss->FindFootnoteCont();
1066  } while ( !pCont && pPage );
1067  }
1068  }
1069  return pCont;
1070 }
1071 
1073 {
1074  // search for the nearest footnote container
1076  if ( !pCont )
1077  return nullptr;
1078 
1079  // Starting from the first footnote, search the first
1080  // footnote that is referenced by the current column/page
1081 
1082  SwFootnoteFrame *pRet = static_cast<SwFootnoteFrame*>(pCont->Lower());
1083  const sal_uInt16 nRefNum = FindPageFrame()->GetPhyPageNum();
1084  const sal_uInt16 nRefCol = lcl_ColumnNum( this );
1085  sal_uInt16 nPgNum, nColNum; // page number, column number
1086  SwFootnoteBossFrame* pBoss;
1087  SwPageFrame* pPage;
1088  if( pRet )
1089  {
1090  pBoss = pRet->GetRef()->FindFootnoteBossFrame();
1091  OSL_ENSURE( pBoss, "FindFirstFootnote: No boss found" );
1092  if( !pBoss )
1093  return nullptr; // ?There must be a bug, but no GPF
1094  pPage = pBoss->FindPageFrame();
1095  nPgNum = pPage->GetPhyPageNum();
1096  if ( nPgNum == nRefNum )
1097  {
1098  nColNum = lcl_ColumnNum( pBoss );
1099  if( nColNum == nRefCol )
1100  return pRet; // found
1101  else if( nColNum > nRefCol )
1102  return nullptr; // at least one column too far
1103  }
1104  else if ( nPgNum > nRefNum )
1105  return nullptr; // at least one column too far
1106  }
1107  else
1108  return nullptr;
1109  // Done if Ref is on a subsequent page or on the same page in a subsequent column
1110 
1111  do
1112  {
1113  while ( pRet->GetFollow() )
1114  pRet = pRet->GetFollow();
1115 
1116  SwFootnoteFrame *pNxt = static_cast<SwFootnoteFrame*>(pRet->GetNext());
1117  if ( !pNxt )
1118  {
1119  pBoss = pRet->FindFootnoteBossFrame();
1120  pPage = pBoss->FindPageFrame();
1121  lcl_NextFootnoteBoss( pBoss, pPage, false ); // next FootnoteBoss
1122  pCont = pBoss ? pBoss->FindNearestFootnoteCont() : nullptr;
1123  if ( pCont )
1124  pNxt = static_cast<SwFootnoteFrame*>(pCont->Lower());
1125  }
1126  if ( pNxt )
1127  {
1128  pRet = pNxt;
1129  pBoss = pRet->GetRef()->FindFootnoteBossFrame();
1130  pPage = pBoss->FindPageFrame();
1131  nPgNum = pPage->GetPhyPageNum();
1132  if ( nPgNum == nRefNum )
1133  {
1134  nColNum = lcl_ColumnNum( pBoss );
1135  if( nColNum == nRefCol )
1136  break; // found
1137  else if( nColNum > nRefCol )
1138  pRet = nullptr; // at least one column too far
1139  }
1140  else if ( nPgNum > nRefNum )
1141  pRet = nullptr; // at least a page too far
1142  }
1143  else
1144  pRet = nullptr; // there is none
1145  } while( pRet );
1146  return pRet;
1147 }
1148 
1151 {
1152  const SwFootnoteFrame *pRet = const_cast<SwFootnoteBossFrame*>(this)->FindFirstFootnote();
1153  if ( pRet )
1154  {
1155  const sal_uInt16 nColNum = lcl_ColumnNum( this );
1156  const sal_uInt16 nPageNum = GetPhyPageNum();
1157  while ( pRet && (pRet->GetRef() != pCnt) )
1158  {
1159  while ( pRet->GetFollow() )
1160  pRet = pRet->GetFollow();
1161 
1162  if ( pRet->GetNext() )
1163  pRet = static_cast<const SwFootnoteFrame*>(pRet->GetNext());
1164  else
1165  { SwFootnoteBossFrame *pBoss = const_cast<SwFootnoteBossFrame*>(pRet->FindFootnoteBossFrame());
1166  SwPageFrame *pPage = pBoss->FindPageFrame();
1167  lcl_NextFootnoteBoss( pBoss, pPage, false ); // next FootnoteBoss
1168  SwFootnoteContFrame *pCont = pBoss ? pBoss->FindNearestFootnoteCont() : nullptr;
1169  pRet = pCont ? static_cast<SwFootnoteFrame*>(pCont->Lower()) : nullptr;
1170  }
1171  if ( pRet )
1172  {
1173  const SwFootnoteBossFrame* pBoss = pRet->GetRef()->FindFootnoteBossFrame();
1174  if( pBoss->GetPhyPageNum() != nPageNum ||
1175  nColNum != lcl_ColumnNum( pBoss ) )
1176  pRet = nullptr;
1177  }
1178  }
1179  }
1180  return pRet;
1181 }
1182 
1184 {
1185  // Destroy the incarnations of footnotes to an attribute, if they don't
1186  // belong to pAssumed
1187  OSL_ENSURE( !pCheck->GetMaster(), "given master is not a Master." );
1188 
1189  SwNodeIndex aIdx( *pCheck->GetAttr()->GetStartNode(), 1 );
1190  SwContentNode *pNd = aIdx.GetNode().GetContentNode();
1191  if ( !pNd )
1192  pNd = pCheck->GetFormat()->GetDoc()->
1193  GetNodes().GoNextSection( &aIdx, true, false );
1195  SwFrame* pFrame = aIter.First();
1196  while( pFrame )
1197  {
1198  if( pFrame->getRootFrame() == pCheck->getRootFrame() )
1199  {
1200  SwFrame *pTmp = pFrame->GetUpper();
1201  while ( pTmp && !pTmp->IsFootnoteFrame() )
1202  pTmp = pTmp->GetUpper();
1203 
1204  SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pTmp);
1205  while ( pFootnote && pFootnote->GetMaster() )
1206  pFootnote = pFootnote->GetMaster();
1207  if ( pFootnote != pCheck )
1208  {
1209  while (pFootnote && !pFootnote->IsDeleteForbidden())
1210  {
1211  SwFootnoteFrame *pNxt = pFootnote->GetFollow();
1212  pFootnote->Cut();
1213  SwFrame::DestroyFrame(pFootnote);
1214  pFootnote = pNxt;
1215  }
1216  }
1217  }
1218 
1219  pFrame = aIter.Next();
1220  }
1221 }
1222 
1224 {
1225  // Place the footnote in front of the footnote whose attribute
1226  // is in front of the new one (get position via the Doc).
1227  // If there is no footnote in this footnote-boss yet, create a new container.
1228  // If there is a container but no footnote for this footnote-boss yet, place
1229  // the footnote behind the last footnote of the closest previous column/page.
1230 
1231  ResetFootnote( pNew );
1232  SwFootnoteFrame *pSibling = FindFirstFootnote();
1233  bool bDontLeave = false;
1234 
1235  // Ok, a sibling has been found, but is the sibling in an acceptable
1236  // environment?
1237  if( IsInSct() )
1238  {
1239  SwSectionFrame* pMySect = ImplFindSctFrame();
1240  bool bEndnt = pNew->GetAttr()->GetFootnote().IsEndNote();
1241  if( bEndnt )
1242  {
1243  const SwSectionFormat* pEndFormat = pMySect->GetEndSectFormat();
1244  bDontLeave = nullptr != pEndFormat;
1245  if( pSibling )
1246  {
1247  if( pEndFormat )
1248  {
1249  if( !pSibling->IsInSct() ||
1250  !pSibling->ImplFindSctFrame()->IsDescendantFrom( pEndFormat ) )
1251  pSibling = nullptr;
1252  }
1253  else if( pSibling->IsInSct() )
1254  pSibling = nullptr;
1255  }
1256  }
1257  else
1258  {
1259  bDontLeave = pMySect->IsFootnoteAtEnd();
1260  if( pSibling )
1261  {
1262  if( pMySect->IsFootnoteAtEnd() )
1263  {
1264  if( !pSibling->IsInSct() ||
1265  !pMySect->IsAnFollow( pSibling->ImplFindSctFrame() ) )
1266  pSibling = nullptr;
1267  }
1268  else if( pSibling->IsInSct() )
1269  pSibling = nullptr;
1270  }
1271  }
1272  }
1273 
1274  if( pSibling && pSibling->FindPageFrame()->IsEndNotePage() !=
1276  pSibling = nullptr;
1277 
1278  // use the Doc to find out the position
1279  SwDoc *pDoc = GetFormat()->GetDoc();
1280  const sal_uLong nStPos = ::lcl_FindFootnotePos( pDoc, pNew->GetAttr() );
1281 
1282  sal_uLong nCmpPos = 0;
1283  sal_uLong nLastPos = 0;
1284  SwFootnoteContFrame *pParent = nullptr;
1285  if( pSibling )
1286  {
1287  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1288  if( nCmpPos > nStPos )
1289  pSibling = nullptr;
1290  }
1291 
1292  if ( !pSibling )
1293  { pParent = FindFootnoteCont();
1294  if ( !pParent )
1295  {
1296  // There is no footnote container yet. Before creating one, keep in mind that
1297  // there might exist another following footnote that must be placed before the
1298  // new inserted one e.g. because it was divided over multiple pages etc.
1299  pParent = FindNearestFootnoteCont( bDontLeave );
1300  if ( pParent )
1301  {
1302  SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pParent->Lower());
1303  if ( pFootnote )
1304  {
1305 
1306  nCmpPos = ::lcl_FindFootnotePos( pDoc, pFootnote->GetAttr() );
1307  if ( nCmpPos > nStPos )
1308  pParent = nullptr;
1309  }
1310  else
1311  pParent = nullptr;
1312  }
1313  }
1314  if ( !pParent )
1315  // here, we are sure that we can create a footnote container
1316  pParent = MakeFootnoteCont();
1317  else
1318  {
1319  // Based on the first footnote below the Parent, search for the first footnote whose
1320  // index is after the index of the newly inserted, to place the new one correctly
1321  pSibling = static_cast<SwFootnoteFrame*>(pParent->Lower());
1322  if ( !pSibling )
1323  {
1324  OSL_ENSURE( false, "Could not find space for footnote.");
1325  return;
1326  }
1327  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1328 
1329  SwFootnoteBossFrame *pNxtB; // remember the last one to not
1330  SwFootnoteFrame *pLastSib = nullptr; // go too far.
1331 
1332  while ( pSibling && nCmpPos <= nStPos )
1333  {
1334  pLastSib = pSibling; // potential candidate
1335  nLastPos = nCmpPos;
1336 
1337  while ( pSibling->GetFollow() )
1338  pSibling = pSibling->GetFollow();
1339 
1340  if ( pSibling->GetNext() )
1341  {
1342  pSibling = static_cast<SwFootnoteFrame*>(pSibling->GetNext());
1343  OSL_ENSURE( !pSibling->GetMaster() || ( ENDNOTE > nStPos &&
1344  pSibling->GetAttr()->GetFootnote().IsEndNote() ),
1345  "InsertFootnote: Master expected I" );
1346  }
1347  else
1348  {
1349  pNxtB = pSibling->FindFootnoteBossFrame();
1350  SwPageFrame *pSibPage = pNxtB->FindPageFrame();
1351  bool bEndNote = pSibPage->IsEndNotePage();
1352  bool bChgPage = lcl_NextFootnoteBoss( pNxtB, pSibPage, bDontLeave );
1353  // When changing pages, also the endnote flag must match.
1354  SwFootnoteContFrame *pCont = pNxtB && ( !bChgPage ||
1355  pSibPage->IsEndNotePage() == bEndNote )
1356  ? pNxtB->FindNearestFootnoteCont( bDontLeave ) : nullptr;
1357  if( pCont )
1358  pSibling = static_cast<SwFootnoteFrame*>(pCont->Lower());
1359  else // no further FootnoteContainer, insert after pSibling
1360  break;
1361  }
1362  if ( pSibling )
1363  {
1364  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1365  OSL_ENSURE( nCmpPos > nLastPos, "InsertFootnote: Order of FootnoteFrame's buggy" );
1366  }
1367  }
1368  // pLastSib is the last footnote before the new one and
1369  // pSibling is empty or the first one after the new one
1370  if ( pSibling && pLastSib && (pSibling != pLastSib) )
1371  {
1372  // too far?
1373  if ( nCmpPos > nStPos )
1374  pSibling = pLastSib;
1375  }
1376  else if ( !pSibling )
1377  {
1378  // Last chance: Take the last footnote of the parent.
1379  // Special case that happens e.g. when moving paragraphs with multiple footnotes.
1380  // To keep the order, use the parent of the last inspected footnote.
1381  pSibling = pLastSib;
1382  while( pSibling->GetFollow() )
1383  pSibling = pSibling->GetFollow();
1384  OSL_ENSURE( !pSibling->GetNext(), "InsertFootnote: Who's that guy?" );
1385  }
1386  }
1387  }
1388  else
1389  {
1390  // First footnote of the column/page found. Now search from there for the first one on the
1391  // same column/page whose index is after the given one. The last one found is the predecessor.
1393  !pNew->GetAttr()->GetFootnote().IsEndNote() );
1394  sal_uInt16 nRefNum = pBoss->GetPhyPageNum(); // page number of the new footnote
1395  sal_uInt16 nRefCol = lcl_ColumnNum( pBoss ); // column number of the new footnote
1396  bool bEnd = false;
1397  SwFootnoteFrame *pLastSib = nullptr;
1398  while ( pSibling && !bEnd && (nCmpPos <= nStPos) )
1399  {
1400  pLastSib = pSibling;
1401  nLastPos = nCmpPos;
1402 
1403  while ( pSibling->GetFollow() )
1404  pSibling = pSibling->GetFollow();
1405 
1406  SwFootnoteFrame *pFoll = static_cast<SwFootnoteFrame*>(pSibling->GetNext());
1407  if ( pFoll )
1408  {
1409  pBoss = pSibling->GetRef()->FindFootnoteBossFrame( !pSibling->
1410  GetAttr()->GetFootnote().IsEndNote() );
1411  sal_uInt16 nTmpRef;
1412  if( nStPos >= ENDNOTE ||
1413  (nTmpRef = pBoss->GetPhyPageNum()) < nRefNum ||
1414  ( nTmpRef == nRefNum && lcl_ColumnNum( pBoss ) <= nRefCol ))
1415  pSibling = pFoll;
1416  else
1417  bEnd = true;
1418  }
1419  else
1420  {
1421  SwFootnoteBossFrame* pNxtB = pSibling->FindFootnoteBossFrame();
1422  SwPageFrame *pSibPage = pNxtB->FindPageFrame();
1423  bool bEndNote = pSibPage->IsEndNotePage();
1424  bool bChgPage = lcl_NextFootnoteBoss( pNxtB, pSibPage, bDontLeave );
1425  // When changing pages, also the endnote flag must match.
1426  SwFootnoteContFrame *pCont = pNxtB && ( !bChgPage ||
1427  pSibPage->IsEndNotePage() == bEndNote )
1428  ? pNxtB->FindNearestFootnoteCont( bDontLeave ) : nullptr;
1429  if ( pCont )
1430  pSibling = static_cast<SwFootnoteFrame*>(pCont->Lower());
1431  else
1432  bEnd = true;
1433  }
1434  if ( !bEnd && pSibling )
1435  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1436  if (pSibling && (pSibling != pLastSib))
1437  {
1438  // too far?
1439  if ( (nLastPos < nCmpPos) && (nCmpPos > nStPos) )
1440  {
1441  pSibling = pLastSib;
1442  bEnd = true;
1443  }
1444  }
1445  }
1446  }
1447  if ( pSibling )
1448  {
1449  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1450  if ( nCmpPos < nStPos )
1451  {
1452  while ( pSibling->GetFollow() )
1453  pSibling = pSibling->GetFollow();
1454  pParent = static_cast<SwFootnoteContFrame*>(pSibling->GetUpper());
1455  pSibling = static_cast<SwFootnoteFrame*>(pSibling->GetNext());
1456  }
1457  else
1458  {
1459  if( pSibling->GetMaster() )
1460  {
1461  if( ENDNOTE > nCmpPos || nStPos >= ENDNOTE )
1462  {
1463  OSL_FAIL( "InsertFootnote: Master expected II" );
1464  do
1465  pSibling = pSibling->GetMaster();
1466  while ( pSibling->GetMaster() );
1467  }
1468  }
1469  pParent = static_cast<SwFootnoteContFrame*>(pSibling->GetUpper());
1470  }
1471  }
1472  OSL_ENSURE( pParent, "paste in space?" );
1473  pNew->Paste( pParent, pSibling );
1474 }
1475 
1476 static SwPageFrame* lcl_GetApproximateFootnotePage(const bool bEnd, const SwPageFrame* pPage,
1477  const SwDoc *pDoc, const SwTextFootnote *pAttr)
1478 {
1479  // We can at least search the approximately correct page
1480  // to ensure that we will finish in finite time even if
1481  // hundreds of footnotes exist.
1482  const SwPageFrame *pNxt = static_cast<const SwPageFrame*>(pPage->GetNext());
1483  const sal_uLong nStPos = ::lcl_FindFootnotePos(pDoc, pAttr);
1484  while (pNxt && (bEnd ? pNxt->IsEndNotePage() : pNxt->IsFootnotePage() && !pNxt->IsEndNotePage()))
1485  {
1486  const SwFootnoteContFrame *pCont = pNxt->FindFootnoteCont();
1487  if (pCont && pCont->Lower())
1488  {
1489  OSL_ENSURE( pCont->Lower()->IsFootnoteFrame(), "no footnote in the container" );
1490  if (nStPos > ::lcl_FindFootnotePos(pDoc,
1491  static_cast<const SwFootnoteFrame*>(pCont->Lower())->GetAttr()))
1492  {
1493  pPage = pNxt;
1494  pNxt = static_cast<const SwPageFrame*>(pPage->GetNext());
1495  continue;
1496  }
1497  }
1498  break;
1499  }
1500  return const_cast<SwPageFrame*>(pPage);
1501 }
1502 
1504 {
1505  // If the footnote already exists, do nothing.
1506  if ( FindFootnote( pRef, pAttr ) )
1507  return;
1508 
1509  // If footnotes are inserted at the end of the document,
1510  // we only need to search from the relevant page on.
1511  // If there is none yet, we need to create one.
1512  // If it is an Endnote, we need to search for or create an
1513  // Endnote page.
1514  SwDoc *pDoc = GetFormat()->GetDoc();
1515  SwFootnoteBossFrame *pBoss = this;
1516  SwPageFrame *pPage = FindPageFrame();
1517  SwPageFrame *pMyPage = pPage;
1518  bool bChgPage = false;
1519  const bool bEnd = pAttr->GetFootnote().IsEndNote();
1520  if (bEnd)
1521  {
1522  const IDocumentSettingAccess& rSettings = *pAttr->GetTextNode().getIDocumentSettingAccess();
1523  if( GetUpper()->IsSctFrame() &&
1524  static_cast<SwSectionFrame*>(GetUpper())->IsEndnAtEnd() )
1525  {
1526  // Endnotes at the end of the section.
1527  SwFrame* pLast =
1528  static_cast<SwSectionFrame*>(GetUpper())->FindLastContent( SwFindMode::EndNote );
1529  if( pLast )
1530  {
1531  pBoss = pLast->FindFootnoteBossFrame();
1532  pPage = pBoss->FindPageFrame();
1533  }
1534  }
1535  else if (rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
1536  {
1537  // Endnotes at the end of the document.
1538  pBoss = getRootFrame()->GetLastPage();
1539  pPage = pBoss->FindPageFrame();
1540  }
1541  else
1542  {
1543  // Endnotes on a separate page.
1544  while ( pPage->GetNext() && !pPage->IsEndNotePage() )
1545  {
1546  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1547  bChgPage = true;
1548  }
1549  if ( !pPage->IsEndNotePage() )
1550  {
1551  SwPageDesc *pDesc = pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
1552  pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(),
1553  !pPage->OnRightPage(), false, false, true, nullptr );
1554  pPage->SetEndNotePage( true );
1555  bChgPage = true;
1556  }
1557  else
1558  pPage = lcl_GetApproximateFootnotePage(true, pPage, pDoc, pAttr);
1559  }
1560  }
1561  else if( FTNPOS_CHAPTER == pDoc->GetFootnoteInfo().m_ePos && ( !GetUpper()->
1562  IsSctFrame() || !static_cast<SwSectionFrame*>(GetUpper())->IsFootnoteAtEnd() ) )
1563  {
1564  while ( pPage->GetNext() && !pPage->IsFootnotePage() &&
1565  !static_cast<SwPageFrame*>(pPage->GetNext())->IsEndNotePage() )
1566  {
1567  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1568  bChgPage = true;
1569  }
1570 
1571  if ( !pPage->IsFootnotePage() )
1572  {
1573  SwPageDesc *pDesc = pDoc->GetFootnoteInfo().GetPageDesc( *pDoc );
1574  pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(),
1575  !pPage->OnRightPage(), false, false, true, pPage->GetNext() );
1576  bChgPage = true;
1577  }
1578  else
1579  pPage = lcl_GetApproximateFootnotePage(false, pPage, pDoc, pAttr);
1580  }
1581 
1582  // For now, create a footnote and the corresponding content frames
1583  if ( !pAttr->GetStartNode() )
1584  {
1585  OSL_ENSURE( false, "no footnote content." );
1586  return;
1587  }
1588 
1589  // If there is already a footnote content on the column/page,
1590  // another one cannot be created in a column area.
1591  if( pBoss->IsInSct() && pBoss->IsColumnFrame() && !pPage->IsFootnotePage() )
1592  {
1593  SwSectionFrame* pSct = pBoss->FindSctFrame();
1594  if( bEnd ? !pSct->IsEndnAtEnd() : !pSct->IsFootnoteAtEnd() )
1595  {
1596  SwFootnoteContFrame* pFootnoteCont = pSct->FindFootnoteBossFrame(!bEnd)->FindFootnoteCont();
1597  if( pFootnoteCont )
1598  {
1599  SwFootnoteFrame* pTmp = static_cast<SwFootnoteFrame*>(pFootnoteCont->Lower());
1600  if( bEnd )
1601  while( pTmp && !pTmp->GetAttr()->GetFootnote().IsEndNote() )
1602  pTmp = static_cast<SwFootnoteFrame*>(pTmp->GetNext());
1603  if( pTmp && *pTmp < pAttr )
1604  return;
1605  }
1606  }
1607  }
1608 
1609  SwFootnoteFrame *pNew = new SwFootnoteFrame( pDoc->GetDfltFrameFormat(), this, pRef, pAttr );
1610  {
1611  SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
1612  ::InsertCnt_( pNew, pDoc, aIdx.GetIndex() );
1613  }
1614  // If the page was changed or newly created,
1615  // we need to place ourselves in the first column
1616  if( bChgPage )
1617  {
1618  SwLayoutFrame* pBody = pPage->FindBodyCont();
1619  OSL_ENSURE( pBody, "AppendFootnote: NoPageBody?" );
1620  if( pBody->Lower() && pBody->Lower()->IsColumnFrame() )
1621  pBoss = static_cast<SwFootnoteBossFrame*>(pBody->Lower());
1622  else
1623  pBoss = pPage; // page if no columns exist
1624  }
1625  pBoss->InsertFootnote( pNew );
1626  if ( pNew->GetUpper() ) // inserted or not?
1627  {
1628  ::RegistFlys( pNew->FindPageFrame(), pNew );
1629  SwSectionFrame* pSect = FindSctFrame();
1630  // The content of a FootnoteContainer in a (column) section only need to be calculated
1631  // if the section stretches already to the bottom edge of the Upper.
1632  if( pSect && !pSect->IsJoinLocked() && ( bEnd ? !pSect->IsEndnAtEnd() :
1633  !pSect->IsFootnoteAtEnd() ) && pSect->Growable() )
1634  pSect->InvalidateSize();
1635  else
1636  {
1637  // #i49383# - disable unlock of position of
1638  // lower objects during format of footnote content.
1639  const bool bOldFootnoteFrameLocked( pNew->IsColLocked() );
1640  pNew->ColLock();
1641  pNew->KeepLockPosOfLowerObjs();
1642  // #i57914# - adjust fix #i49383#
1643  SwContentFrame *pCnt = pNew->ContainsContent();
1644  while ( pCnt && pCnt->FindFootnoteFrame()->GetAttr() == pAttr )
1645  {
1646  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
1647  // #i49383# - format anchored objects
1648  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
1649  {
1651  *(pCnt->FindPageFrame()) ) )
1652  {
1653  // restart format with first content
1654  pCnt = pNew->ContainsContent();
1655  continue;
1656  }
1657  }
1658  pCnt = pCnt->FindNextCnt();
1659  }
1660  // #i49383#
1661  if ( !bOldFootnoteFrameLocked )
1662  {
1663  pNew->ColUnlock();
1664  }
1665  // #i57914# - adjust fix #i49383#
1666  // enable lock of lower object position before format of footnote frame.
1667  pNew->UnlockPosOfLowerObjs();
1668  pNew->Calc(getRootFrame()->GetCurrShell()->GetOut());
1669  // #i57914# - adjust fix #i49383#
1670  if ( !bOldFootnoteFrameLocked && !pNew->GetLower() &&
1671  !pNew->IsColLocked() && !pNew->IsBackMoveLocked() &&
1672  !pNew->IsDeleteForbidden() )
1673  {
1674  pNew->Cut();
1675  SwFrame::DestroyFrame(pNew);
1676  }
1677  }
1678  pMyPage->UpdateFootnoteNum();
1679  }
1680  else
1681  SwFrame::DestroyFrame(pNew);
1682 }
1683 
1685 {
1686  // the easiest and savest way goes via the attribute
1687  OSL_ENSURE( pAttr->GetStartNode(), "FootnoteAtr without StartNode." );
1688  SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
1689  SwContentNode *pNd = aIdx.GetNode().GetContentNode();
1690  if ( !pNd )
1691  pNd = pRef->GetAttrSet()->GetDoc()->
1692  GetNodes().GoNextSection( &aIdx, true, false );
1693  if ( !pNd )
1694  return nullptr;
1696  SwFrame* pFrame = aIter.First();
1697  if( pFrame )
1698  do
1699  {
1700  pFrame = pFrame->GetUpper();
1701  // #i28500#, #i27243# Due to the endnode collector, there are
1702  // SwFootnoteFrames, which are not in the layout. Therefore the
1703  // bInfFootnote flags are not set correctly, and a cell of FindFootnoteFrame
1704  // would return 0. Therefore we better call ImplFindFootnoteFrame().
1705  SwFootnoteFrame *pFootnote = pFrame->ImplFindFootnoteFrame();
1706  if ( pFootnote && pFootnote->GetRef() == pRef )
1707  {
1708  // The following condition becomes true, if the whole
1709  // footnotecontent is a section. While no frames exist,
1710  // the HiddenFlag of the section is set, this causes
1711  // the GoNextSection-function leaves the footnote.
1712  if( pFootnote->GetAttr() != pAttr )
1713  return nullptr;
1714  while ( pFootnote && pFootnote->GetMaster() )
1715  pFootnote = pFootnote->GetMaster();
1716  return pFootnote;
1717  }
1718 
1719  } while ( nullptr != (pFrame = aIter.Next()) );
1720 
1721  return nullptr;
1722 }
1723 
1725  const SwContentFrame *const pRef, const SwTextFootnote *const pAttr,
1726  bool bPrep )
1727 {
1728  bool ret(false);
1729  SwFootnoteFrame *pFootnote = FindFootnote( pRef, pAttr );
1730  if( pFootnote )
1731  {
1732  ret = true;
1733  do
1734  {
1735  SwFootnoteFrame *pFoll = pFootnote->GetFollow();
1736  pFootnote->Cut();
1737  SwFrame::DestroyFrame(pFootnote);
1738  pFootnote = pFoll;
1739  } while ( pFootnote );
1740  if( bPrep && pRef->IsFollow() )
1741  {
1742  OSL_ENSURE( pRef->IsTextFrame(), "NoTextFrame has Footnote?" );
1743  SwTextFrame* pMaster = pRef->FindMaster();
1744  if( !pMaster->IsLocked() )
1746  }
1747  }
1749  return ret;
1750 }
1751 
1753  SwContentFrame *pNew )
1754 {
1755  SwFootnoteFrame *pFootnote = FindFootnote( pOld, pAttr );
1756  while ( pFootnote )
1757  {
1758  pFootnote->SetRef( pNew );
1759  pFootnote = pFootnote->GetFollow();
1760  }
1761 }
1762 
1767  SwFootnoteBossFrame* _pOld,
1768  SwFootnoteFrames& _rFootnoteArr,
1769  const bool _bCollectOnlyPreviousFootnotes )
1770 {
1771  SwFootnoteFrame *pFootnote = _pOld->FindFirstFootnote();
1772  while( !pFootnote )
1773  {
1774  if( _pOld->IsColumnFrame() )
1775  {
1776  // visit columns
1777  while ( !pFootnote && _pOld->GetPrev() )
1778  {
1779  // Still no problem if no footnote was found yet. The loop is needed to pick up
1780  // following rows in tables. In all other cases it might correct bad contexts.
1781  _pOld = static_cast<SwFootnoteBossFrame*>(_pOld->GetPrev());
1782  pFootnote = _pOld->FindFirstFootnote();
1783  }
1784  }
1785  if( !pFootnote )
1786  {
1787  // previous page
1788  SwPageFrame* pPg;
1789  for ( SwFrame* pTmp = _pOld;
1790  nullptr != ( pPg = static_cast<SwPageFrame*>(pTmp->FindPageFrame()->GetPrev()))
1791  && pPg->IsEmptyPage() ;
1792  )
1793  {
1794  pTmp = pPg;
1795  }
1796  if( !pPg )
1797  return;
1798 
1799  SwLayoutFrame* pBody = pPg->FindBodyCont();
1800  if( pBody->Lower() && pBody->Lower()->IsColumnFrame() )
1801  {
1802  // multiple columns on one page => search last column
1803  _pOld = static_cast<SwFootnoteBossFrame*>(pBody->GetLastLower());
1804  }
1805  else
1806  _pOld = pPg; // single column page
1807  pFootnote = _pOld->FindFirstFootnote();
1808  }
1809  }
1810 
1811  CollectFootnotes_(_pRef, pFootnote, _rFootnoteArr, _bCollectOnlyPreviousFootnotes ? this : nullptr);
1812 }
1813 
1814 static void FootnoteInArr( SwFootnoteFrames& rFootnoteArr, SwFootnoteFrame* pFootnote )
1815 {
1816  if ( rFootnoteArr.end() == std::find( rFootnoteArr.begin(), rFootnoteArr.end(), pFootnote ) )
1817  rFootnoteArr.push_back( pFootnote );
1818 }
1819 
1821  SwFootnoteFrame* _pFootnote,
1822  SwFootnoteFrames& _rFootnoteArr,
1823  const SwFootnoteBossFrame* _pRefFootnoteBossFrame)
1824 {
1825  // Collect all footnotes referenced by pRef (attribute by attribute), combine them
1826  // (the content might be divided over multiple pages) and cut them.
1827 
1828  // For robustness, we do not log the corresponding footnotes here. If a footnote
1829  // is touched twice, there might be a crash. This allows this function here to
1830  // also handle corrupt layouts in some degrees (without loops or even crashes).
1831  SwFootnoteFrames aNotFootnoteArr;
1832 
1833  // here we have a footnote placed in front of the first one of the reference
1834  OSL_ENSURE( !_pFootnote->GetMaster() || _pFootnote->GetRef() != _pRef, "move FollowFootnote?" );
1835  while ( _pFootnote->GetMaster() )
1836  _pFootnote = _pFootnote->GetMaster();
1837 
1838  bool bFound = false;
1839 
1840  do
1841  {
1842  // Search for the next footnote in this column/page so that
1843  // we do not start from zero again after cutting one footnote.
1844  SwFootnoteFrame *pNxtFootnote = _pFootnote;
1845  while ( pNxtFootnote->GetFollow() )
1846  pNxtFootnote = pNxtFootnote->GetFollow();
1847  pNxtFootnote = static_cast<SwFootnoteFrame*>(pNxtFootnote->GetNext());
1848 
1849  if ( !pNxtFootnote )
1850  {
1851  SwFootnoteBossFrame* pBoss = _pFootnote->FindFootnoteBossFrame();
1852  SwPageFrame* pPage = pBoss->FindPageFrame();
1853  do
1854  {
1855  lcl_NextFootnoteBoss( pBoss, pPage, false );
1856  if( pBoss )
1857  {
1858  SwLayoutFrame* pCont = pBoss->FindFootnoteCont();
1859  if( pCont )
1860  {
1861  pNxtFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower());
1862  if( pNxtFootnote )
1863  {
1864  while( pNxtFootnote->GetMaster() )
1865  pNxtFootnote = pNxtFootnote->GetMaster();
1866  if( pNxtFootnote == _pFootnote )
1867  pNxtFootnote = nullptr;
1868  }
1869  }
1870  }
1871  } while( !pNxtFootnote && pBoss );
1872  }
1873  else if( !pNxtFootnote->GetAttr()->GetFootnote().IsEndNote() )
1874  {
1875  OSL_ENSURE( !pNxtFootnote->GetMaster(), "_CollectFootnote: Master expected" );
1876  while ( pNxtFootnote->GetMaster() )
1877  pNxtFootnote = pNxtFootnote->GetMaster();
1878  }
1879  if ( pNxtFootnote == _pFootnote )
1880  {
1881  OSL_FAIL( "_CollectFootnote: Vicious circle" );
1882  pNxtFootnote = nullptr;
1883  }
1884 
1885  // OD 03.04.2003 #108446# - determine, if found footnote has to be collected.
1886  bool bCollectFoundFootnote = false;
1887  // Ignore endnotes which are on a separate endnote page.
1888  bool bEndNote = _pFootnote->GetAttr()->GetFootnote().IsEndNote();
1889  const IDocumentSettingAccess& rSettings
1890  = _pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
1891  bool bContinuousEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES);
1892  if (_pFootnote->GetRef() == _pRef && (!bEndNote || bContinuousEndnotes))
1893  {
1894  if (_pRefFootnoteBossFrame)
1895  {
1896  SwFootnoteBossFrame* pBossOfFoundFootnote = _pFootnote->FindFootnoteBossFrame( true );
1897  OSL_ENSURE( pBossOfFoundFootnote,
1898  "<SwFootnoteBossFrame::CollectFootnotes_(..)> - footnote boss frame of found footnote frame missing.\nWrong layout!" );
1899  if ( !pBossOfFoundFootnote || // don't crash, if no footnote boss is found.
1900  pBossOfFoundFootnote->IsBefore( _pRefFootnoteBossFrame )
1901  )
1902  {
1903  bCollectFoundFootnote = true;
1904  }
1905  }
1906  else
1907  {
1908  bCollectFoundFootnote = true;
1909  }
1910  }
1911 
1912  if ( bCollectFoundFootnote )
1913  {
1914  OSL_ENSURE( !_pFootnote->GetMaster(), "move FollowFootnote?" );
1915  SwFootnoteFrame *pNxt = _pFootnote->GetFollow();
1916  while ( pNxt )
1917  {
1918  SwFrame *pCnt = pNxt->ContainsAny();
1919  if ( pCnt )
1920  {
1921  // destroy the follow on the way as it is empty
1922  do
1923  { SwFrame *pNxtCnt = pCnt->GetNext();
1924  pCnt->Cut();
1925  pCnt->Paste( _pFootnote );
1926  pCnt = pNxtCnt;
1927  } while ( pCnt );
1928  }
1929  else
1930  {
1931  OSL_ENSURE( !pNxt, "footnote without content?" );
1932  pNxt->Cut();
1933  SwFrame::DestroyFrame(pNxt);
1934  }
1935  pNxt = _pFootnote->GetFollow();
1936  }
1937  _pFootnote->Cut();
1938  FootnoteInArr( _rFootnoteArr, _pFootnote );
1939  bFound = true;
1940  }
1941  else
1942  {
1943  FootnoteInArr( aNotFootnoteArr, _pFootnote );
1944  if( bFound )
1945  break;
1946  }
1947  if ( pNxtFootnote &&
1948  _rFootnoteArr.end() == std::find( _rFootnoteArr.begin(), _rFootnoteArr.end(), pNxtFootnote ) &&
1949  aNotFootnoteArr.end() == std::find( aNotFootnoteArr.begin(), aNotFootnoteArr.end(), pNxtFootnote ) )
1950  _pFootnote = pNxtFootnote;
1951  else
1952  break;
1953  }
1954  while ( _pFootnote );
1955 }
1956 
1958 {
1959  // All footnotes referenced by pRef need to be moved
1960  // to a new position (based on the new column/page)
1961  const sal_uInt16 nMyNum = FindPageFrame()->GetPhyPageNum();
1962  const sal_uInt16 nMyCol = lcl_ColumnNum( this );
1963  SwRectFnSet aRectFnSet(this);
1964 
1965  // #i21478# - keep last inserted footnote in order to
1966  // format the content of the following one.
1967  SwFootnoteFrame* pLastInsertedFootnote = nullptr;
1968  for (SwFootnoteFrame* pFootnote : rFootnoteArr)
1969  {
1970  SwFootnoteBossFrame* pRefBoss(pFootnote->GetRef()->FindFootnoteBossFrame(
1971  !pFootnote->GetAttr()->GetFootnote().IsEndNote()));
1972  if( pRefBoss != this )
1973  {
1974  const sal_uInt16 nRefNum = pRefBoss->FindPageFrame()->GetPhyPageNum();
1975  const sal_uInt16 nRefCol = lcl_ColumnNum( this );
1976  if( nRefNum < nMyNum || ( nRefNum == nMyNum && nRefCol <= nMyCol ) )
1977  pRefBoss = this;
1978  }
1979  pRefBoss->InsertFootnote( pFootnote );
1980 
1981  if ( pFootnote->GetUpper() ) // robust, e.g. with duplicates
1982  {
1983  // First condense the content so that footnote frames that do not fit on the page
1984  // do not do too much harm (Loop 66312). So, the footnote content first grows as
1985  // soon as the content gets formatted and it is sure that it fits on the page.
1986  SwFrame *pCnt = pFootnote->ContainsAny();
1987  while( pCnt )
1988  {
1989  if( pCnt->IsLayoutFrame() )
1990  {
1991  SwFrame* pTmp = static_cast<SwLayoutFrame*>(pCnt)->ContainsAny();
1992  while( pTmp && static_cast<SwLayoutFrame*>(pCnt)->IsAnLower( pTmp ) )
1993  {
1995 
1997  aRectFnSet.SetHeight(aFrm, 0);
1998 
2000  aRectFnSet.SetHeight(aPrt, 0);
2001 
2002  pTmp = pTmp->FindNext();
2003  }
2004  }
2005  else
2006  {
2008  }
2009 
2011  aRectFnSet.SetHeight(aFrm, 0);
2012 
2014  aRectFnSet.SetHeight(aPrt, 0);
2015 
2016  pCnt = pCnt->GetNext();
2017  }
2018 
2019  {
2021  aRectFnSet.SetHeight(aFrm, 0);
2022  }
2023 
2024  {
2026  aRectFnSet.SetHeight(aPrt, 0);
2027  }
2028 
2029  pFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut());
2030  pFootnote->GetUpper()->Calc(getRootFrame()->GetCurrShell()->GetOut());
2031 
2032  if( bCalc )
2033  {
2034  SwTextFootnote *pAttr = pFootnote->GetAttr();
2035  pCnt = pFootnote->ContainsAny();
2036  bool bUnlock = !pFootnote->IsBackMoveLocked();
2037  pFootnote->LockBackMove();
2038 
2039  // #i49383# - disable unlock of position of
2040  // lower objects during format of footnote content.
2041  pFootnote->KeepLockPosOfLowerObjs();
2042  // #i57914# - adjust fix #i49383#
2043 
2044  while ( pCnt && pCnt->FindFootnoteFrame()->GetAttr() == pAttr )
2045  {
2046  pCnt->InvalidatePos_();
2047  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
2048  // #i49383# - format anchored objects
2049  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
2050  {
2052  *(pCnt->FindPageFrame()) ) )
2053  {
2054  // restart format with first content
2055  pCnt = pFootnote->ContainsAny();
2056  continue;
2057  }
2058  }
2059  if( pCnt->IsSctFrame() )
2060  {
2061  // If the area is not empty, iterate also over the content
2062  SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny();
2063  if( pTmp )
2064  pCnt = pTmp;
2065  else
2066  pCnt = pCnt->FindNext();
2067  }
2068  else
2069  pCnt = pCnt->FindNext();
2070  }
2071  if( bUnlock )
2072  {
2073  pFootnote->UnlockBackMove();
2074  if( !pFootnote->ContainsAny() && !pFootnote->IsColLocked() )
2075  {
2076  pFootnote->Cut();
2077  SwFrame::DestroyFrame(pFootnote);
2078  // #i21478#
2079  pFootnote = nullptr;
2080  }
2081  }
2082  // #i49383#
2083  if ( pFootnote )
2084  {
2085  // #i57914# - adjust fix #i49383#
2086  // enable lock of lower object position before format of footnote frame.
2087  pFootnote->UnlockPosOfLowerObjs();
2088  pFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut());
2089  }
2090  }
2091  }
2092  else
2093  {
2094  OSL_ENSURE( !pFootnote->GetMaster() && !pFootnote->GetFollow(),
2095  "DelFootnote and Master/Follow?" );
2096  SwFrame::DestroyFrame(pFootnote);
2097  // #i21478#
2098  pFootnote = nullptr;
2099  }
2100 
2101  // #i21478#
2102  if ( pFootnote )
2103  {
2104  pLastInsertedFootnote = pFootnote;
2105  }
2106  }
2107 
2108  // #i21478# - format content of footnote following
2109  // the new inserted ones.
2110  if ( !(bCalc && pLastInsertedFootnote) )
2111  return;
2112 
2113  if ( !pLastInsertedFootnote->GetNext() )
2114  return;
2115 
2116  SwFootnoteFrame* pNextFootnote = static_cast<SwFootnoteFrame*>(pLastInsertedFootnote->GetNext());
2117  SwTextFootnote* pAttr = pNextFootnote->GetAttr();
2118  SwFrame* pCnt = pNextFootnote->ContainsAny();
2119 
2120  bool bUnlock = !pNextFootnote->IsBackMoveLocked();
2121  pNextFootnote->LockBackMove();
2122  // #i49383# - disable unlock of position of
2123  // lower objects during format of footnote content.
2124  pNextFootnote->KeepLockPosOfLowerObjs();
2125  // #i57914# - adjust fix #i49383#
2126 
2127  while ( pCnt && pCnt->FindFootnoteFrame()->GetAttr() == pAttr )
2128  {
2129  pCnt->InvalidatePos_();
2130  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
2131  // #i49383# - format anchored objects
2132  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
2133  {
2135  *(pCnt->FindPageFrame()) ) )
2136  {
2137  // restart format with first content
2138  pCnt = pNextFootnote->ContainsAny();
2139  continue;
2140  }
2141  }
2142  if( pCnt->IsSctFrame() )
2143  {
2144  // If the area is not empty, iterate also over the content
2145  SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny();
2146  if( pTmp )
2147  pCnt = pTmp;
2148  else
2149  pCnt = pCnt->FindNext();
2150  }
2151  else
2152  pCnt = pCnt->FindNext();
2153  }
2154  if( bUnlock )
2155  {
2156  pNextFootnote->UnlockBackMove();
2157  }
2158  // #i49383#
2159  // #i57914# - adjust fix #i49383#
2160  // enable lock of lower object position before format of footnote frame.
2161  pNextFootnote->UnlockPosOfLowerObjs();
2162  pNextFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut());
2163 }
2164 
2166  SwTextFootnote const *pAttr )
2167 {
2168  if( ( GetFormat()->GetDoc()->GetFootnoteInfo().m_ePos == FTNPOS_CHAPTER &&
2169  (!GetUpper()->IsSctFrame() || !static_cast<SwSectionFrame*>(GetUpper())->IsFootnoteAtEnd()))
2170  || pAttr->GetFootnote().IsEndNote() )
2171  return;
2172 
2173  OSL_ENSURE( this == pSrc->FindFootnoteBossFrame( true ),
2174  "SwPageFrame::MoveFootnotes: source frame isn't on that FootnoteBoss" );
2175 
2176  SwFootnoteFrame *pFootnote = FindFirstFootnote();
2177  if( !pFootnote )
2178  return;
2179 
2180  ChangeFootnoteRef( pSrc, pAttr, pDest );
2181  SwFootnoteBossFrame *pDestBoss = pDest->FindFootnoteBossFrame( true );
2182  OSL_ENSURE( pDestBoss, "+SwPageFrame::MoveFootnotes: no destination boss" );
2183  if( !pDestBoss ) // robust
2184  return;
2185 
2186  SwFootnoteFrames aFootnoteArr;
2187  SwFootnoteBossFrame::CollectFootnotes_(pDest, pFootnote, aFootnoteArr, nullptr);
2188  if ( aFootnoteArr.empty() )
2189  return;
2190 
2191  pDestBoss->MoveFootnotes_( aFootnoteArr, true );
2192  SwPageFrame* pSrcPage = FindPageFrame();
2193  SwPageFrame* pDestPage = pDestBoss->FindPageFrame();
2194  // update FootnoteNum only at page change
2195  if( pSrcPage != pDestPage )
2196  {
2197  if( pSrcPage->GetPhyPageNum() > pDestPage->GetPhyPageNum() )
2198  pSrcPage->UpdateFootnoteNum();
2199  pDestPage->UpdateFootnoteNum();
2200  }
2201 }
2202 
2203 void SwFootnoteBossFrame::RearrangeFootnotes( const SwTwips nDeadLine, const bool bLock,
2204  const SwTextFootnote *pAttr )
2205 {
2206  // Format all footnotes of a column/page so that they might change the column/page.
2207 
2208  SwSaveFootnoteHeight aSave( this, nDeadLine );
2209  SwFootnoteFrame *pFootnote = FindFirstFootnote();
2210  if( pFootnote && pFootnote->GetPrev() && bLock )
2211  {
2212  SwFootnoteFrame* pFirst = static_cast<SwFootnoteFrame*>(pFootnote->GetUpper()->Lower());
2213  SwFrame* pContent = pFirst->ContainsAny();
2214  if( pContent )
2215  {
2216  bool bUnlock = !pFirst->IsBackMoveLocked();
2217  pFirst->LockBackMove();
2218  pFirst->Calc(getRootFrame()->GetCurrShell()->GetOut());
2219  pContent->Calc(getRootFrame()->GetCurrShell()->GetOut());
2220  // #i49383# - format anchored objects
2221  if ( pContent->IsTextFrame() && pContent->isFrameAreaDefinitionValid() )
2222  {
2224  *(pContent->FindPageFrame()) );
2225  }
2226  if( bUnlock )
2227  pFirst->UnlockBackMove();
2228  }
2229  pFootnote = FindFirstFootnote();
2230  }
2231  SwDoc *pDoc = GetFormat()->GetDoc();
2232  const sal_uLong nFootnotePos = pAttr ? ::lcl_FindFootnotePos( pDoc, pAttr ) : 0;
2233  SwFrame *pCnt = pFootnote ? pFootnote->ContainsAny() : nullptr;
2234  if ( !pCnt )
2235  return;
2236 
2237  bool bMore = true;
2238  bool bStart = pAttr == nullptr; // If no attribute is given, process all
2239  // #i49383# - disable unlock of position of
2240  // lower objects during format of footnote and footnote content.
2241  SwFootnoteFrame* pLastFootnoteFrame( nullptr );
2242  // footnote frame needs to be locked, if <bLock> isn't set.
2243  bool bUnlockLastFootnoteFrame( false );
2244  do
2245  {
2246  if( !bStart )
2247  bStart = ::lcl_FindFootnotePos( pDoc, pCnt->FindFootnoteFrame()->GetAttr() )
2248  == nFootnotePos;
2249  if( bStart )
2250  {
2251  pCnt->InvalidatePos_();
2252  pCnt->InvalidateSize_();
2254  SwFootnoteFrame* pFootnoteFrame = pCnt->FindFootnoteFrame();
2255  // #i49383#
2256  if ( pFootnoteFrame != pLastFootnoteFrame )
2257  {
2258  if ( pLastFootnoteFrame )
2259  {
2260  if ( !bLock && bUnlockLastFootnoteFrame )
2261  {
2262  pLastFootnoteFrame->ColUnlock();
2263  }
2264  // #i57914# - adjust fix #i49383#
2265  // enable lock of lower object position before format of footnote frame.
2266  pLastFootnoteFrame->UnlockPosOfLowerObjs();
2267  pLastFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut());
2268  if ( !bLock && bUnlockLastFootnoteFrame &&
2269  !pLastFootnoteFrame->GetLower() &&
2270  !pLastFootnoteFrame->IsColLocked() &&
2271  !pLastFootnoteFrame->IsBackMoveLocked() &&
2272  !pLastFootnoteFrame->IsDeleteForbidden() )
2273  {
2274  pLastFootnoteFrame->Cut();
2275  SwFrame::DestroyFrame(pLastFootnoteFrame);
2276  pLastFootnoteFrame = nullptr;
2277  }
2278  }
2279  if ( !bLock )
2280  {
2281  bUnlockLastFootnoteFrame = !pFootnoteFrame->IsColLocked();
2282  pFootnoteFrame->ColLock();
2283  }
2284  pFootnoteFrame->KeepLockPosOfLowerObjs();
2285  pLastFootnoteFrame = pFootnoteFrame;
2286  }
2287  // OD 30.10.2002 #97265# - invalidate position of footnote
2288  // frame, if it's below its footnote container, in order to
2289  // assure its correct position, probably calculating its previous
2290  // footnote frames.
2291  {
2292  SwRectFnSet aRectFnSet(this);
2293  SwFrame* pFootnoteContFrame = pFootnoteFrame->GetUpper();
2294  if ( aRectFnSet.TopDist(pFootnoteFrame->getFrameArea(), aRectFnSet.GetPrtBottom(*pFootnoteContFrame)) > 0 )
2295  {
2296  pFootnoteFrame->InvalidatePos_();
2297  }
2298  }
2299  if ( bLock )
2300  {
2301  bool bUnlock = !pFootnoteFrame->IsBackMoveLocked();
2302  pFootnoteFrame->LockBackMove();
2303  pFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut());
2304  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
2305  // #i49383# - format anchored objects
2306  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
2307  {
2308  SwFrameDeleteGuard aDeleteGuard(pFootnote);
2310  *(pCnt->FindPageFrame()) ) )
2311  {
2312  // restart format with first content
2313  pCnt = pFootnote ? pFootnote->ContainsAny() : nullptr;
2314  if (!pCnt)
2315  bMore = false;
2316  continue;
2317  }
2318  }
2319  if( bUnlock )
2320  {
2321  pFootnoteFrame->UnlockBackMove();
2322  if( !pFootnoteFrame->Lower() &&
2323  !pFootnoteFrame->IsColLocked() )
2324  {
2325  // #i49383#
2326  OSL_ENSURE( pLastFootnoteFrame == pFootnoteFrame,
2327  "<SwFootnoteBossFrame::RearrangeFootnotes(..)> - <pLastFootnoteFrame> != <pFootnoteFrame>" );
2328  pLastFootnoteFrame = nullptr;
2329  pFootnoteFrame->Cut();
2330  SwFrame::DestroyFrame(pFootnoteFrame);
2331  if (pFootnote == pFootnoteFrame)
2332  pFootnote = nullptr;
2333  }
2334  }
2335  }
2336  else
2337  {
2338  pFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut());
2339  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
2340  // #i49383# - format anchored objects
2341  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
2342  {
2344  *(pCnt->FindPageFrame()) ) )
2345  {
2346  // restart format with first content
2347  pCnt = pFootnote->ContainsAny();
2348  continue;
2349  }
2350  }
2351  }
2352  }
2353  SwSectionFrame *pDel = nullptr;
2354  if( pCnt->IsSctFrame() )
2355  {
2356  SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny();
2357  if( pTmp )
2358  {
2359  pCnt = pTmp;
2360  continue;
2361  }
2362  pDel = static_cast<SwSectionFrame*>(pCnt);
2363  }
2364  if ( pCnt->GetNext() )
2365  pCnt = pCnt->GetNext();
2366  else
2367  {
2368  pCnt = pCnt->FindNext();
2369  if ( pCnt )
2370  {
2371  SwFootnoteFrame* pFootnoteFrame = pCnt->FindFootnoteFrame();
2372  if( pFootnoteFrame->GetRef()->FindFootnoteBossFrame(
2373  pFootnoteFrame->GetAttr()->GetFootnote().IsEndNote() ) != this )
2374  bMore = false;
2375  }
2376  else
2377  bMore = false;
2378  }
2379  if( pDel )
2380  {
2381  bool bUnlockLastFootnoteFrameGuard = pLastFootnoteFrame && !pLastFootnoteFrame->IsColLocked();
2382  if (bUnlockLastFootnoteFrameGuard)
2383  pLastFootnoteFrame->ColLock();
2384  pDel->Cut();
2385  if (bUnlockLastFootnoteFrameGuard)
2386  pLastFootnoteFrame->ColUnlock();
2387  SwFrame::DestroyFrame(pDel);
2388  }
2389  if ( bMore )
2390  {
2391  // Go not further than to the provided footnote (if given)
2392  if ( pAttr &&
2393  (::lcl_FindFootnotePos( pDoc,
2394  pCnt->FindFootnoteFrame()->GetAttr()) > nFootnotePos ) )
2395  bMore = false;
2396  }
2397  } while ( bMore );
2398  // #i49383#
2399  if ( !pLastFootnoteFrame )
2400  return;
2401 
2402  if ( !bLock && bUnlockLastFootnoteFrame )
2403  {
2404  pLastFootnoteFrame->ColUnlock();
2405  }
2406  // #i57914# - adjust fix #i49383#
2407  // enable lock of lower object position before format of footnote frame.
2408  pLastFootnoteFrame->UnlockPosOfLowerObjs();
2409  pLastFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut());
2410  if ( !bLock && bUnlockLastFootnoteFrame &&
2411  !pLastFootnoteFrame->GetLower() &&
2412  !pLastFootnoteFrame->IsColLocked() &&
2413  !pLastFootnoteFrame->IsBackMoveLocked() )
2414  {
2415  pLastFootnoteFrame->Cut();
2416  SwFrame::DestroyFrame(pLastFootnoteFrame);
2417  }
2418 }
2419 
2421 {
2422  // page numbering only if set at the document
2423  if ( GetFormat()->GetDoc()->GetFootnoteInfo().m_eNum != FTNNUM_PAGE )
2424  return;
2425 
2426  SwLayoutFrame* pBody = FindBodyCont();
2427  if( !pBody || !pBody->Lower() )
2428  return;
2429 
2430  SwContentFrame* pContent = pBody->ContainsContent();
2431  sal_uInt16 nNum = 0;
2432 
2433  while( pContent && pContent->FindPageFrame() == this )
2434  {
2435  if( static_cast<SwTextFrame*>(pContent)->HasFootnote() )
2436  {
2437  SwFootnoteBossFrame* pBoss = pContent->FindFootnoteBossFrame( true );
2438  if( pBoss->GetUpper()->IsSctFrame() &&
2439  static_cast<SwSectionFrame*>(pBoss->GetUpper())->IsOwnFootnoteNum() )
2440  pContent = static_cast<SwSectionFrame*>(pBoss->GetUpper())->FindLastContent();
2441  else
2442  {
2443  SwFootnoteFrame* pFootnote = const_cast<SwFootnoteFrame*>(pBoss->FindFirstFootnote( pContent ));
2444  while( pFootnote )
2445  {
2446  SwTextFootnote* pTextFootnote = pFootnote->GetAttr();
2447  if( !pTextFootnote->GetFootnote().IsEndNote() &&
2448  pTextFootnote->GetFootnote().GetNumStr().isEmpty() &&
2449  !pFootnote->GetMaster())
2450  {
2451  // sw_redlinehide: the layout can only keep one number
2452  // up to date; depending on its setting, this is either
2453  // the non-hidden or the hidden number; the other
2454  // number will simply be preserved as-is (so in case
2455  // there are 2 layouts, maybe both can be updated...)
2456  ++nNum;
2457  sal_uInt16 const nOldNum(pTextFootnote->GetFootnote().GetNumber());
2458  sal_uInt16 const nOldNumRLHidden(pTextFootnote->GetFootnote().GetNumberRLHidden());
2459  if (getRootFrame()->IsHideRedlines())
2460  {
2461  if (nNum != nOldNumRLHidden)
2462  {
2463  pTextFootnote->SetNumber(nOldNum, nNum, OUString());
2464  }
2465  }
2466  else
2467  {
2468  if (nNum != nOldNum)
2469  {
2470  pTextFootnote->SetNumber(nNum, nOldNumRLHidden, OUString());
2471  }
2472  }
2473  }
2474  if ( pFootnote->GetNext() )
2475  pFootnote = static_cast<SwFootnoteFrame*>(pFootnote->GetNext());
2476  else
2477  {
2478  SwFootnoteBossFrame* pTmpBoss = pFootnote->FindFootnoteBossFrame( true );
2479  if( pTmpBoss )
2480  {
2481  SwPageFrame* pPage = pTmpBoss->FindPageFrame();
2482  pFootnote = nullptr;
2483  lcl_NextFootnoteBoss( pTmpBoss, pPage, false );
2484  SwFootnoteContFrame *pCont = pTmpBoss ? pTmpBoss->FindNearestFootnoteCont() : nullptr;
2485  if ( pCont )
2486  pFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower());
2487  }
2488  }
2489  if( pFootnote && pFootnote->GetRef() != pContent )
2490  pFootnote = nullptr;
2491  }
2492  }
2493  }
2494  pContent = pContent->FindNextCnt();
2495  }
2496 }
2497 
2499 {
2500  SwFrame *pBody = FindBodyCont();
2501  pBody->Calc(getRootFrame()->GetCurrShell()->GetOut());
2502 
2503  SwFrame *pCont = FindFootnoteCont();
2504  const SwTwips nMax = m_nMaxFootnoteHeight;// current should exceed MaxHeight
2505  SwRectFnSet aRectFnSet(this);
2506  if ( pCont )
2507  {
2508  pCont->Calc(getRootFrame()->GetCurrShell()->GetOut());
2509  m_nMaxFootnoteHeight = -aRectFnSet.BottomDist( pCont->getFrameArea(), nDeadLine );
2510  }
2511  else
2512  m_nMaxFootnoteHeight = -aRectFnSet.BottomDist( pBody->getFrameArea(), nDeadLine );
2513 
2514  const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
2515  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
2516  m_nMaxFootnoteHeight += pBody->Grow( LONG_MAX, true );
2517  if ( IsInSct() )
2519 
2520  if ( m_nMaxFootnoteHeight < 0 )
2522  if ( nMax != LONG_MAX && m_nMaxFootnoteHeight > nMax )
2523  m_nMaxFootnoteHeight = nMax;
2524 }
2525 
2527 {
2528  // To not fall below 20% of the page height
2529  // (in contrast to MSOffice where footnotes can fill a whole column/page)
2530 
2531  const SwPageFrame* pPg = FindPageFrame();
2532  OSL_ENSURE( pPg || IsInSct(), "Footnote lost page" );
2533 
2534  const SwFrame *pBody = FindBodyCont();
2535  SwTwips nRet;
2536  if( pBody )
2537  {
2538  SwRectFnSet aRectFnSet(this);
2539  if( IsInSct() )
2540  {
2541  nRet = 0;
2542  SwTwips nTmp = aRectFnSet.YDiff( aRectFnSet.GetPrtTop(*pBody),
2543  aRectFnSet.GetTop(getFrameArea()) );
2544  const SwSectionFrame* pSect = FindSctFrame();
2545  // Endnotes in a ftncontainer causes a deadline:
2546  // the bottom of the last contentfrm
2547  if( pSect->IsEndnAtEnd() ) // endnotes allowed?
2548  {
2549  OSL_ENSURE( !Lower() || !Lower()->GetNext() || Lower()->GetNext()->
2550  IsFootnoteContFrame(), "FootnoteContainer expected" );
2551  const SwFootnoteContFrame* pCont = Lower() ?
2552  static_cast<const SwFootnoteContFrame*>(Lower()->GetNext()) : nullptr;
2553  if( pCont )
2554  {
2555  const SwFootnoteFrame* pFootnote = static_cast<const SwFootnoteFrame*>(pCont->Lower());
2556  while( pFootnote)
2557  {
2558  if( pFootnote->GetAttr()->GetFootnote().IsEndNote() )
2559  { // endnote found
2560  const SwFrame* pFrame = static_cast<const SwLayoutFrame*>(Lower())->Lower();
2561  if( pFrame )
2562  {
2563  while( pFrame->GetNext() )
2564  pFrame = pFrame->GetNext(); // last cntntfrm
2565  nTmp += aRectFnSet.YDiff(
2566  aRectFnSet.GetTop(getFrameArea()),
2567  aRectFnSet.GetBottom(pFrame->getFrameArea()) );
2568  }
2569  break;
2570  }
2571  pFootnote = static_cast<const SwFootnoteFrame*>(pFootnote->GetNext());
2572  }
2573  }
2574  }
2575  if( nTmp < nRet )
2576  nRet = nTmp;
2577  }
2578  else
2579  nRet = - aRectFnSet.GetHeight(pPg->getFramePrintArea())/5;
2580  nRet += aRectFnSet.GetHeight(pBody->getFrameArea());
2581  if( nRet < 0 )
2582  nRet = 0;
2583  }
2584  else
2585  nRet = 0;
2586  if ( IsPageFrame() )
2587  {
2588  const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
2589  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
2590  nRet += BROWSE_HEIGHT - getFrameArea().Height();
2591  }
2592  return nRet;
2593 }
2594 
2608 {
2610  if( GetUpper() && !GetUpper()->IsPageBodyFrame() )
2611  {
2612  // column sections need grow/shrink
2613  if( GetUpper()->IsFlyFrame() )
2615  else
2616  {
2617  OSL_ENSURE( GetUpper()->IsSctFrame(), "NeighbourhoodAdjustment: Unexpected Upper" );
2618  if( !GetNext() && !GetPrev() )
2619  nRet = SwNeighbourAdjust::GrowAdjust; // section with a single column (FootnoteAtEnd)
2620  else
2621  {
2622  const SwFrame* pTmp = Lower();
2623  OSL_ENSURE( pTmp, "NeighbourhoodAdjustment: Missing Lower()" );
2624  if( !pTmp->GetNext() )
2626  else if( !GetUpper()->IsColLocked() )
2628  OSL_ENSURE( !pTmp->GetNext() || pTmp->GetNext()->IsFootnoteContFrame(),
2629  "NeighbourhoodAdjustment: Who's that guy?" );
2630  }
2631  }
2632  }
2633  return nRet;
2634 }
2635 
2637 {
2638  SwLayoutFrame *pBody = FindBodyCont();
2639  if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() )
2640  {
2641  SwColumnFrame* pCol = static_cast<SwColumnFrame*>(pBody->Lower());
2642  do
2643  {
2645  pCol = static_cast<SwColumnFrame*>(pCol->GetNext());
2646  } while ( pCol );
2647  }
2648 }
2649 
2651  SwFootnoteBossFrame *pNewBoss, const bool bFootnoteNums )
2652 {
2653  SwDoc *pDoc = GetFormat()->GetDoc();
2654  if ( pDoc->GetFootnoteIdxs().empty() )
2655  return false;
2656  if( pDoc->GetFootnoteInfo().m_ePos == FTNPOS_CHAPTER &&
2657  ( !IsInSct() || !FindSctFrame()->IsFootnoteAtEnd() ) )
2658  return true;
2659 
2660  if ( !pNewBoss )
2661  pNewBoss = FindFootnoteBossFrame( true );
2662  if ( pNewBoss == pOldBoss )
2663  return false;
2664 
2665  bool bMoved = false;
2666  if( !pStart )
2667  pStart = ContainsContent();
2668 
2669  SwFootnoteFrames aFootnoteArr;
2670 
2671  while ( IsAnLower( pStart ) )
2672  {
2673  if ( static_cast<SwTextFrame*>(pStart)->HasFootnote() )
2674  {
2675  // OD 03.04.2003 #108446# - To avoid unnecessary moves of footnotes
2676  // use new parameter <_bCollectOnlyPreviousFootnote> (4th parameter of
2677  // method <SwFootnoteBossFrame::CollectFootnote(..)>) to control, that only
2678  // footnotes have to be collected, that are positioned before the
2679  // new dedicated footnote boss frame.
2680  pNewBoss->CollectFootnotes( pStart, pOldBoss, aFootnoteArr, true );
2681  }
2682  pStart = pStart->GetNextContentFrame();
2683  }
2684 
2685  OSL_ENSURE( pOldBoss->IsInSct() == pNewBoss->IsInSct(),
2686  "MoveLowerFootnotes: Section confusion" );
2687  std::unique_ptr<SwFootnoteFrames> pFootnoteArr;
2688  SwLayoutFrame* pNewChief = nullptr;
2689  SwLayoutFrame* pOldChief = nullptr;
2690 
2691  bool bFoundCandidate = false;
2692  if (pStart && pOldBoss->IsInSct())
2693  {
2694  pOldChief = pOldBoss->FindSctFrame();
2695  pNewChief = pNewBoss->FindSctFrame();
2696  bFoundCandidate = pOldChief != pNewChief;
2697  }
2698 
2699  if (bFoundCandidate)
2700  {
2701  pFootnoteArr.reset(new SwFootnoteFrames);
2702  pOldChief = pOldBoss->FindFootnoteBossFrame( true );
2703  pNewChief = pNewBoss->FindFootnoteBossFrame( true );
2704  while( pOldChief->IsAnLower( pStart ) )
2705  {
2706  if ( static_cast<SwTextFrame*>(pStart)->HasFootnote() )
2707  static_cast<SwFootnoteBossFrame*>(pNewChief)->CollectFootnotes( pStart,
2708  pOldBoss, *pFootnoteArr );
2709  pStart = pStart->GetNextContentFrame();
2710  }
2711  if( pFootnoteArr->empty() )
2712  {
2713  pFootnoteArr.reset();
2714  }
2715  }
2716  else
2717  pFootnoteArr = nullptr;
2718 
2719  if ( !aFootnoteArr.empty() || pFootnoteArr )
2720  {
2721  if( !aFootnoteArr.empty() )
2722  pNewBoss->MoveFootnotes_( aFootnoteArr, true );
2723  if( pFootnoteArr )
2724  {
2725  assert(pNewChief);
2726  static_cast<SwFootnoteBossFrame*>(pNewChief)->MoveFootnotes_( *pFootnoteArr, true );
2727  pFootnoteArr.reset();
2728  }
2729  bMoved = true;
2730 
2731  // update FootnoteNum only at page change
2732  if ( bFootnoteNums )
2733  {
2734  SwPageFrame* pOldPage = pOldBoss->FindPageFrame();
2735  SwPageFrame* pNewPage =pNewBoss->FindPageFrame();
2736  if( pOldPage != pNewPage )
2737  {
2738  pOldPage->UpdateFootnoteNum();
2739  pNewPage->UpdateFootnoteNum();
2740  }
2741  }
2742  }
2743  return bMoved;
2744 }
2745 
2748 {
2749  OSL_ENSURE( IsInFootnote(), "no footnote." );
2750  SwLayoutFrame *pFootnote = FindFootnoteFrame();
2751 
2752  // The first paragraph in the first footnote in the first column in the
2753  // sectionfrm at the top of the page has not to move forward, if the
2754  // columnbody is empty.
2755  if( pOldBoss->IsInSct() && !pOldBoss->GetIndPrev() && !GetIndPrev() &&
2756  !pFootnote->GetPrev() )
2757  {
2758  SwLayoutFrame* pBody = pOldBoss->FindBodyCont();
2759  if( !pBody || !pBody->Lower() )
2760  return true;
2761  }
2762 
2763  //fix(9538): if the footnote has neighbors behind itself, remove them temporarily
2764  SwLayoutFrame *pNxt = static_cast<SwLayoutFrame*>(pFootnote->GetNext());
2765  SwLayoutFrame *pLst = nullptr;
2766  while ( pNxt )
2767  {
2768  while ( pNxt->GetNext() )
2769  pNxt = static_cast<SwLayoutFrame*>(pNxt->GetNext());
2770  if ( pNxt == pLst )
2771  pNxt = nullptr;
2772  else
2773  { pLst = pNxt;
2774  SwContentFrame *pCnt = pNxt->ContainsContent();
2775  if( pCnt )
2776  pCnt->MoveFootnoteCntFwd( true, pOldBoss );
2777  pNxt = static_cast<SwLayoutFrame*>(pFootnote->GetNext());
2778  }
2779  }
2780 
2781  bool bSamePage = true;
2782  SwLayoutFrame *pNewUpper =
2783  GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, true );
2784 
2785  if ( pNewUpper )
2786  {
2787  SwFootnoteBossFrame * const pNewBoss = pNewUpper->FindFootnoteBossFrame();
2788  // Are we changing the column/page?
2789  bool bSameBoss = pNewBoss == pOldBoss;
2790  if ( !bSameBoss )
2791  {
2792  bSamePage = pOldBoss->FindPageFrame() == pNewBoss->FindPageFrame(); // page change?
2793  pNewUpper->Calc(getRootFrame()->GetCurrShell()->GetOut());
2794  }
2795 
2796  // The layout leaf of the footnote is either a footnote container or a footnote.
2797  // If it is a footnote and it has the same footnote reference like the old Upper,
2798  // then move the content inside of it.
2799  // If it is a container or the reference differs, create a new footnote and add
2800  // it into the container.
2801  // Create also a SectionFrame if currently in an area inside a footnote.
2802  SwFootnoteFrame* pTmpFootnote = pNewUpper->IsFootnoteFrame() ? static_cast<SwFootnoteFrame*>(pNewUpper) : nullptr;
2803  if (!pTmpFootnote && pNewUpper->IsFootnoteContFrame())
2804  {
2805  SwFootnoteContFrame *pCont = static_cast<SwFootnoteContFrame*>(pNewUpper);
2806  pTmpFootnote = SwFootnoteContFrame::AppendChained(this, true);
2807  SwFrame* pNx = pCont->Lower();
2808  if( pNx && pTmpFootnote->GetAttr()->GetFootnote().IsEndNote() )
2809  while(pNx && !static_cast<SwFootnoteFrame*>(pNx)->GetAttr()->GetFootnote().IsEndNote())
2810  pNx = pNx->GetNext();
2811  pTmpFootnote->Paste( pCont, pNx );
2812  pTmpFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut());
2813  }
2814  OSL_ENSURE( pTmpFootnote->GetAttr() == FindFootnoteFrame()->GetAttr(), "Wrong Footnote!" );
2815  // areas inside of footnotes get a special treatment
2816  SwLayoutFrame *pNewUp = pTmpFootnote;
2817  if( IsInSct() )
2818  {
2819  SwSectionFrame* pSect = FindSctFrame();
2820  // area inside of a footnote (or only footnote in an area)?
2821  if( pSect->IsInFootnote() )
2822  {
2823  if( pTmpFootnote->Lower() && pTmpFootnote->Lower()->IsSctFrame() &&
2824  pSect->GetFollow() == static_cast<SwSectionFrame*>(pTmpFootnote->Lower()) )
2825  pNewUp = static_cast<SwSectionFrame*>(pTmpFootnote->Lower());
2826  else
2827  {
2828  pNewUp = new SwSectionFrame( *pSect, false );
2829  pNewUp->InsertBefore( pTmpFootnote, pTmpFootnote->Lower() );
2830  static_cast<SwSectionFrame*>(pNewUp)->Init();
2831 
2832  {
2834  aFrm.Pos() = pTmpFootnote->getFrameArea().Pos();
2835  aFrm.Pos().AdjustY(1 ); // for notifications
2836  }
2837 
2838  // If the section frame has a successor then the latter needs
2839  // to be moved behind the new Follow of the section frame.
2840  SwFrame* pTmp = pSect->GetNext();
2841  if( pTmp )
2842  {
2843  SwFlowFrame* pTmpNxt;
2844  if( pTmp->IsContentFrame() )
2845  pTmpNxt = static_cast<SwContentFrame*>(pTmp);
2846  else if( pTmp->IsSctFrame() )
2847  pTmpNxt = static_cast<SwSectionFrame*>(pTmp);
2848  else
2849  {
2850  OSL_ENSURE( pTmp->IsTabFrame(), "GetNextSctLeaf: Wrong Type" );
2851  pTmpNxt = static_cast<SwTabFrame*>(pTmp);
2852  }
2853  pTmpNxt->MoveSubTree( pTmpFootnote, pNewUp->GetNext() );
2854  }
2855  }
2856  }
2857  }
2858 
2859  MoveSubTree( pNewUp, pNewUp->Lower() );
2860 
2861  if( !bSameBoss )
2863  }
2864  return bSamePage;
2865 }
2866 
2868  pBoss( pBs ),
2869  nOldHeight( pBs->GetMaxFootnoteHeight() )
2870 {
2871  pBoss->SetFootnoteDeadLine( nDeadLine );
2873 }
2874 
2876 {
2877  // If somebody tweaked the deadline meanwhile, we let it happen
2880 }
2881 
2882 #ifdef DBG_UTIL
2883 //JP 15.10.2001: in a non pro version test if the attribute has the same
2884 // meaning which his reference is
2885 
2886 // Normally, the pRef member and the GetRefFromAttr() result has to be
2887 // identically. Sometimes footnote will be moved from a master to its follow,
2888 // but the GetRef() is called first, so we have to ignore a master/follow
2889 // mismatch.
2890 
2892 {
2893  const SwContentFrame* pRefAttr = GetRefFromAttr();
2894  // check consistency: access to deleted frame?
2895  assert(mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr)
2896  || pRefAttr->IsAnFollow(mpReference));
2897  (void) pRefAttr;
2898  return mpReference;
2899 }
2900 
2902 {
2903  const SwContentFrame* pRefAttr = GetRefFromAttr();
2904  // check consistency: access to deleted frame?
2905  assert(mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr)
2906  || pRefAttr->IsAnFollow(mpReference));
2907  (void) pRefAttr;
2908  return mpReference;
2909 }
2910 #endif
2911 
2913 {
2914  SwFootnoteFrame* pThis = const_cast<SwFootnoteFrame*>(this);
2915  return pThis->GetRefFromAttr();
2916 }
2917 
2919 {
2920  assert(mpAttribute && "invalid Attribute");
2921  SwTextNode& rTNd = const_cast<SwTextNode&>(mpAttribute->GetTextNode());
2922  SwPosition aPos( rTNd, SwIndex( &rTNd, mpAttribute->GetStart() ));
2923  SwContentFrame* pCFrame = rTNd.getLayoutFrame(getRootFrame(), &aPos);
2924  return pCFrame;
2925 }
2926 
2932 {
2933  SwContentFrame* pLastContentFrame( nullptr );
2934 
2935  // find last lower, which is a content frame or contains content.
2936  // hidden text frames, empty sections and empty tables have to be skipped.
2937  SwFrame* pLastLowerOfFootnote( GetLower() );
2938  SwFrame* pTmpLastLower( pLastLowerOfFootnote );
2939  while ( pTmpLastLower && pTmpLastLower->GetNext() )
2940  {
2941  pTmpLastLower = pTmpLastLower->GetNext();
2942  if ( ( pTmpLastLower->IsTextFrame() &&
2943  !static_cast<SwTextFrame*>(pTmpLastLower)->IsHiddenNow() ) ||
2944  ( pTmpLastLower->IsSctFrame() &&
2945  static_cast<SwSectionFrame*>(pTmpLastLower)->GetSection() &&
2946  static_cast<SwSectionFrame*>(pTmpLastLower)->ContainsContent() ) ||
2947  ( pTmpLastLower->IsTabFrame() &&
2948  static_cast<SwTabFrame*>(pTmpLastLower)->ContainsContent() ) )
2949  {
2950  pLastLowerOfFootnote = pTmpLastLower;
2951  }
2952  }
2953 
2954  // determine last content frame depending on type of found last lower.
2955  if ( pLastLowerOfFootnote && pLastLowerOfFootnote->IsTabFrame() )
2956  {
2957  pLastContentFrame = static_cast<SwTabFrame*>(pLastLowerOfFootnote)->FindLastContent();
2958  }
2959  else if ( pLastLowerOfFootnote && pLastLowerOfFootnote->IsSctFrame() )
2960  {
2961  pLastContentFrame = static_cast<SwSectionFrame*>(pLastLowerOfFootnote)->FindLastContent();
2962  }
2963  else
2964  {
2965  pLastContentFrame = dynamic_cast<SwContentFrame*>(pLastLowerOfFootnote);
2966  }
2967 
2968  return pLastContentFrame;
2969 }
2970 
2971 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void InsertBefore(SwLayoutFrame *pParent, SwFrame *pBehind)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:830
void SetFollow(SwFootnoteFrame *pNew)
Definition: ftnfrm.hxx:125
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:207
static SwFootnoteFrame * AppendChained(SwFrame *pThis, bool bDefaultFormat)
Definition: ftnfrm.hxx:69
SwSectionFrame * FindMaster() const
Definition: flowfrm.cxx:754
SwSaveFootnoteHeight(SwFootnoteBossFrame *pBs, const SwTwips nDeadLine)
Definition: ftnfrm.cxx:2867
void SetTop(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1387
Base class of the Writer layout elements.
Definition: frame.hxx:315
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:158
SwFootnoteContFrame * FindNearestFootnoteCont(bool bDontLeave=false)
Search the next available footnote container.
Definition: ftnfrm.cxx:1049
void ColLock()
Definition: ftnfrm.hxx:136
bool IsFollow() const
Definition: flowfrm.hxx:166
Marks a position in the document model.
Definition: pam.hxx:35
void AddHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1399
void InsertCnt_(SwLayoutFrame *pLay, SwDoc *pDoc, sal_uLong nIndex, bool bPages=false, sal_uLong nEndIndex=0, SwFrame *pPrv=nullptr, sw::FrameMode eMode=sw::FrameMode::New)
Definition: frmtool.cxx:1458
bool IsEndnAtEnd() const
Definition: sectfrm.hxx:157
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:115
bool IsInDocBody() const
Definition: frame.hxx:944
void Init()
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1503
bool IsInSct() const
Definition: frame.hxx:968
void RemoveFootnotes(SwPageFrame *pPage=nullptr, bool bPageOnly=false, bool bEndNotes=false)
Remove all footnotes (but no references)
Definition: ftnfrm.cxx:962
static void SetMoveBwdJump(bool bNew)
Definition: flowfrm.hxx:155
tools::Long BottomDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1415
bool MoveFootnoteCntFwd(bool, SwFootnoteBossFrame *)
Return value guarantees that a new page was not created. See SwFlowFrame::MoveFwd.
Definition: ftnfrm.cxx:2747
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
"format" the frame (Fixsize is not set here).
Definition: ftnfrm.cxx:230
SwFootnoteFrame * ImplFindFootnoteFrame()
Definition: findfrm.cxx:505
static void CheckPageDescs(SwPageFrame *pStart, bool bNotifyFields=true, SwPageFrame **ppPrev=nullptr)
Check all pages (starting from the given one) if they use the appropriate frame format.
Definition: pagechg.cxx:1056
bool IsColLocked() const
Definition: frame.hxx:887
bool IsBefore(const SwLayoutFrame *_pCheckRefLayFrame) const
method to check relative position of layout frame to a given layout frame.
Definition: findfrm.cxx:234
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: ftnfrm.cxx:592
static void CollectFootnotes_(const SwContentFrame *, SwFootnoteFrame *, SwFootnoteFrames &, const SwFootnoteBossFrame *)
Definition: ftnfrm.cxx:1820
static SwFootnoteFrame * FindFootnote(const SwContentFrame *, const SwTextFootnote *)
Definition: ftnfrm.cxx:1684
void SetCompletePaint() const
Definition: frame.hxx:995
void SetMaster(SwFootnoteFrame *pNew)
Definition: ftnfrm.hxx:126
bool IsInFootnote() const
Definition: frame.hxx:950
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:597
sal_uInt16 char char * pDesc
sal_uIntPtr sal_uLong
long Long
const SwRect & getFramePrintArea() const
Definition: frame.hxx:181
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true) override
SwContentFrame: the shortcut for the Frames If the void* casts wrongly, it's its own fault! The void*...
Definition: txtfrm.cxx:2724
SwTwips GetBottomDist() const
Definition: pagedesc.hxx:68
virtual bool IsDeleteForbidden() const override
Definition: ftnfrm.cxx:520
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:46
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1213
#define ENDNOTE
Definition: ftnfrm.cxx:43
void InvalidateSize_()
Definition: frame.hxx:772
Definition: doc.hxx:188
static sal_uInt16 lcl_ColumnNum(const SwFrame *pBoss)
Definition: ftnfrm.cxx:123
void SetColMaxFootnoteHeight()
Adapt the max. footnote height in each single column.
Definition: ftnfrm.cxx:2636
void SetMaxFootnoteHeight(const SwTwips nNewMax)
Definition: ftnboss.hxx:77
TElementType * Next()
Definition: calbck.hxx:365
void UpdateFootnoteNum()
Definition: ftnfrm.cxx:2420
void InsertFootnote(SwFootnoteFrame *)
Definition: ftnfrm.cxx:1223
void InvalidatePos()
Definition: frame.hxx:1044
const_iterator find(const Value &x) const
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: wsfrm.cxx:1337
static void ChangeFootnoteRef(const SwContentFrame *pOld, const SwTextFootnote *, SwContentFrame *pNew)
Definition: ftnfrm.cxx:1752
void SubTop(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1394
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:384
void Pos(const Point &rNew)
Definition: swrect.hxx:168
bool IsEndNote() const
Definition: fmtftn.hxx:71
Dialog to specify the properties of date form field.
SwTwips GetMaxFootnoteHeight() const
Definition: ftnboss.hxx:96
SwFrame * FindNext()
Definition: frame.hxx:1142
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1788
virtual void Cut() override
Definition: ftnfrm.cxx:541
bool IsFootnotePage() const
Foot note interface.
Definition: pagefrm.hxx:199
void InvalidateNxtFootnoteCnts(SwPageFrame const *pPage)
Definition: ftnfrm.cxx:496
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1382
void KeepLockPosOfLowerObjs()
Definition: ftnfrm.hxx:144
void RearrangeFootnotes(const SwTwips nDeadLine, const bool bLock, const SwTextFootnote *pAttr=nullptr)
Definition: ftnfrm.cxx:2203
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2703
void AddBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1395
SwFootnoteContFrame(SwFrameFormat *, SwFrame *)
Definition: ftnfrm.cxx:151
bool IsFootnoteFrame() const
Definition: frame.hxx:1203
bool ToMaximize(bool bCheckFollow) const
A sectionfrm has to maximize, if he has a follow or a ftncontainer at the end of the page...
Definition: sectfrm.cxx:2738
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:172
SwTwips GetTopDist() const
Definition: pagedesc.hxx:67
tools::Long TopDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1414
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:204
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1378
SwSectionFrame * ImplFindSctFrame()
Definition: findfrm.cxx:481
void SetFootnoteDeadLine(const SwTwips nDeadLine)
Definition: ftnfrm.cxx:2498
void SetRetouche() const
Definition: frame.hxx:1004
const SwPageFootnoteInfo & GetFootnoteInfo() const
Definition: pagedesc.hxx:205
bool IsFlyFrame() const
Definition: frame.hxx:1211
void sw_RemoveFootnotes(SwFootnoteBossFrame *pBoss, bool bPageOnly, bool bEndNotes)
remove all footnotes (not the references) and all footnote pages
Definition: ftnfrm.cxx:908
void MoveFootnotes_(SwFootnoteFrames &rFootnoteArr, bool bCalc=false)
Definition: ftnfrm.cxx:1957
const SwRect & getFrameArea() const
Definition: frame.hxx:180
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1026
bool getBrowseMode() const
Definition: viewopt.hxx:472
bool IsEmptyPage() const
Definition: pagefrm.hxx:157
SwTextFootnote * mpAttribute
Definition: ftnfrm.hxx:88
bool IsInTab() const
Definition: frame.hxx:956
const SwPageFrame * GetLastPage() const
Definition: rootfrm.hxx:363
bool IsTextFrame() const
Definition: frame.hxx:1235
sal_Int32 GetStart() const
Definition: txatbase.hxx:86
void SetSuperfluous()
Remove superfluous Pages.
Definition: rootfrm.hxx:302
void setFramePrintAreaValid(bool bNew)
Definition: wsfrm.cxx:99
bool OnRightPage() const
Definition: frame.hxx:734
virtual SwTwips ShrinkFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: ftnfrm.cxx:453
bool IsPageBodyFrame() const
Definition: layfrm.hxx:214
const OUString & GetNumStr() const
Definition: fmtftn.hxx:68
bool IsSctFrame() const
Definition: frame.hxx:1215
void AppendFootnote(SwContentFrame *, SwTextFootnote *)
Definition: ftnfrm.cxx:1503
SwNeighbourAdjust NeighbourhoodAdjustment_() const
Obtain if pFrame's size adjustment should be processed.
Definition: ftnfrm.cxx:2607
void UnlockPosOfLowerObjs()
Definition: ftnfrm.hxx:140
SwLayoutFrame * GetNextSctLeaf(MakePageType eMakePage)
Returns the next layout sheet where the frame can be moved in.
Definition: sectfrm.cxx:1572
bool IsDescendantFrom(const SwSectionFormat *pSect) const
Definition: sectfrm.cxx:2513
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:677
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr)=0
bool IsFootnoteLock() const
Definition: sectfrm.hxx:166
virtual void Cut()=0
bool IsColumnFrame() const
Definition: frame.hxx:1183
void SetNumber(sal_uInt16 nNumber, sal_uInt16 nNumberRLHidden, const OUString &sNumStr)
Definition: atrftn.cxx:361
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1108
SwTabFrame * ImplFindTabFrame()
Definition: findfrm.cxx:469
Style of a layout element.
Definition: frmfmt.hxx:59
bool IsContentFrame() const
Definition: frame.hxx:1231
static void FootnoteInArr(SwFootnoteFrames &rFootnoteArr, SwFootnoteFrame *pFootnote)
Definition: ftnfrm.cxx:1814
SwFrame * GetIndPrev() const
Definition: frame.hxx:725
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1411
const SwFrame * GetLastLower() const
Definition: findfrm.cxx:1831
const SwSectionFrame * GetFollow() const
Definition: sectfrm.hxx:169
SwPageFrame * FindPageFrame()
Definition: frame.hxx:681
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:888
SwFrame * m_pLower
Definition: layfrm.hxx:53
virtual void Cut() override
Definition: wsfrm.cxx:1434
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:191
TElementType * First()
Definition: calbck.hxx:357
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:143
SwTwips AdjustNeighbourhood(SwTwips nDiff, bool bTst=false)
Adjust surrounding neighbourhood after insertion.
Definition: wsfrm.cxx:1607
SwContentNode * GetContentNode()
Definition: node.hxx:616
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:607
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1383
SwLayoutFrame * GetUpper()
Definition: frame.hxx:679
sal_uInt16 GetNumberRLHidden() const
Definition: fmtftn.hxx:70
void AddHeight(const tools::Long nAdd)
Definition: swrect.cxx:161
bool isFramePrintAreaValid() const
Definition: frame.hxx:169
SwFootnoteFrame * FindFirstFootnote()
Definition: ftnfrm.cxx:1072
Marks a character position inside a document model node.
Definition: index.hxx:33
bool IsEndNotePage() const
Definition: pagefrm.hxx:200
static sal_uLong lcl_FindFootnotePos(const SwDoc *pDoc, const SwTextFootnote *pAttr)
Search the position of an attribute in the FootnoteArray at the document, because all footnotes are l...
Definition: ftnfrm.cxx:47
tools::Long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1410
constexpr tools::Long BROWSE_HEIGHT
Definition: frmtool.hxx:54
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:436
Provides access to settings of a document.
SwFrame * GetPrev()
Definition: frame.hxx:678
Marks a node in the document model.
Definition: ndindex.hxx:31
const IDocumentSettingAccess * getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: node.cxx:2097
void UnlockBackMove()
Definition: ftnfrm.hxx:132
const_iterator end() const
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1424
bool empty() const
SwFootnoteBossFrame * pBoss
Definition: ftnboss.hxx:34
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:123
SwNeighbourAdjust NeighbourhoodAdjustment() const
Definition: ftnboss.hxx:114
bool isFrameAreaSizeValid() const
Definition: frame.hxx:168
SwContentFrame * FindLastContent(SwFindMode nMode=SwFindMode::None)
Definition: sectfrm.cxx:910
void InvalidatePos_()
Definition: frame.hxx:788
SwFootnoteContFrame * MakeFootnoteCont()
Insert a footnote container.
Definition: ftnfrm.cxx:1016
void UpdateFootnoteNums()
Update the footnote numbers of all Pages.
Definition: ftnfrm.cxx:893
A page of the document layout.
Definition: pagefrm.hxx:57
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:204
void LockBackMove()
Definition: ftnfrm.hxx:131
tools::Long SwTwips
Definition: swtypes.hxx:52
static sal_uInt16 nPgNum
Definition: viewport.cxx:52
const long LONG_MAX
SwFootnoteFrame(SwFrameFormat *, SwFrame *, SwContentFrame *, SwTextFootnote *)
Definition: ftnfrm.cxx:483
SwTwips Shrink(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1547
void InvalidateSize()
Definition: frame.hxx:1030
SwLayoutFrame * GetPrevFootnoteLeaf(MakePageType eMakeFootnote)
Get the preceding layout leaf in that the frame can be moved.
Definition: ftnfrm.cxx:739
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1116
SwLayoutFrame * FindBodyCont()
Searches the first ContentFrame in BodyText below the page.
Definition: findfrm.cxx:43
const SwFootnoteFrame * GetMaster() const
Definition: ftnfrm.hxx:119
SwFrame * FindColFrame()
Definition: findfrm.cxx:530
const SwFrameFormat * GetDfltFrameFormat() const
Definition: doc.hxx:747
const_iterator begin() const
tools::Long const nBorder
bool RemoveFootnote(const SwContentFrame *, const SwTextFootnote *, bool bPrep=true)
Definition: ftnfrm.cxx:1724
void CollectFootnotes(const SwContentFrame *_pRef, SwFootnoteBossFrame *_pOld, SwFootnoteFrames &_rFootnoteArr, const bool _bCollectOnlyPreviousFootnotes=false)
OD 03.04.2003 #108446# - add parameter <_bCollectOnlyPreviousFootnotes> in order to control...
Definition: ftnfrm.cxx:1766
static bool FormatObjsAtFrame(SwFrame &_rAnchorFrame, const SwPageFrame &_rPageFrame, SwLayAction *_pLayAction=nullptr)
method to format all floating screen objects at the given anchor frame
bool IsLayoutFrame() const
Definition: frame.hxx:1171
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
SwNeighbourAdjust
Definition: ftnboss.hxx:42
Footnote information.
Definition: pagedesc.hxx:48
bool Growable() const
checks whether the SectionFrame is still able to grow, as case may be the environment has to be asked...
Definition: sectfrm.cxx:2144
static void ResetFootnote(const SwFootnoteFrame *pAssumed)
Definition: ftnfrm.cxx:1183
void SetRef(SwContentFrame *pNew)
Definition: ftnfrm.hxx:127
void SetWidth(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1391
SwContentFrame * FindLastBodyContent()
Searches the last ContentFrame in BodyText below the page.
Definition: findfrm.cxx:52
bool IsVertLR() const
Definition: frame.hxx:980
void MoveSubTree(SwLayoutFrame *pParent, SwFrame *pSibling=nullptr)
hook tree onto new parent with minimal operations and notifications
Definition: flowfrm.cxx:635
SwTwips GetVarSpace() const
Definition: ftnfrm.cxx:2526
SwLayoutFrame * GetLeaf(MakePageType eMakePage, bool bFwd)
Definition: flowfrm.cxx:843
void CheckFootnotePageDescs(bool bEndNote)
Change the page template of the footnote pages.
Definition: ftnfrm.cxx:996
MakePageType
Definition: frame.hxx:113
SwPageDesc * GetPageDesc(SwDoc &rDoc) const
Definition: docftn.cxx:105
bool IsTabFrame() const
Definition: frame.hxx:1219
static SwPageFrame * lcl_GetApproximateFootnotePage(const bool bEnd, const SwPageFrame *pPage, const SwDoc *pDoc, const SwTextFootnote *pAttr)
Definition: ftnfrm.cxx:1476
virtual SwTwips ShrinkFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: wsfrm.cxx:2800
#define SAL_WARN_IF(condition, area, stream)
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:738
sal_uInt16 GetPhyPageNum() const
Definition: trvlfrm.cxx:1695
bool MoveLowerFootnotes(SwContentFrame *pStart, SwFootnoteBossFrame *pOldBoss, SwFootnoteBossFrame *pNewBoss, const bool bFootnoteNums)
Moving the Footnotes of all Lowers - starting from StartContent.
Definition: ftnfrm.cxx:2650
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:423
const SwFrame * ContainsAny(const bool _bInvestigateFootnoteForSections=false) const
Method doesn't investigate content of footnotes by default.
Definition: findfrm.cxx:126
bool IsBackMoveLocked() const
Definition: ftnfrm.hxx:133
const SwSectionFormat * GetEndSectFormat() const
Definition: sectfrm.hxx:145
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1392
void RemoveFromLayout()
Definition: wsfrm.cxx:1007
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
const SwFootnoteFrame * GetFollow() const
Definition: ftnfrm.hxx:116
const SwDoc * GetDoc() const
Definition: swatrset.hxx:197
SwPageFrame * InsertNewPage(SwPageDesc &rDesc, SwFrame *pUpper, bool isRightPage, bool bFirst, bool bInsertEmpty, bool bFootnote, SwFrame *pSibling, bool bVeryFirstPage=false)
Definition: frmtool.cxx:3083
SwTwips m_nMaxFootnoteHeight
Definition: ftnboss.hxx:56
void InvalidateNextPos(bool bNoFootnote=false)
Definition: frame.hxx:1073
sal_uLong GetLineWidth() const
Definition: pagedesc.hxx:62
bool IsColBodyFrame() const
These SwFrame inlines are here, so that frame.hxx does not need to include layfrm.hxx.
Definition: layfrm.hxx:209
static bool lcl_NextFootnoteBoss(SwFootnoteBossFrame *&rpBoss, SwPageFrame *&rpPage, bool bDontLeave)
Definition: ftnfrm.cxx:81
bool operator<(const SwTextFootnote *pTextFootnote) const
Definition: ftnfrm.cxx:64
void setFrameAreaSizeValid(bool bNew)
Definition: wsfrm.cxx:91
SwFrame * GetLower()
Definition: findfrm.cxx:170
const SwContentFrame * GetRef() const
Definition: ftnfrm.cxx:2891
SwFrameType mnFrameType
Definition: frame.hxx:415
bool IsPageFrame() const
Definition: frame.hxx:1179
bool IsFootnoteAllowed() const
Definition: ftnfrm.cxx:877
const SwTextFootnote * GetAttr() const
Definition: ftnfrm.hxx:122
SwContentFrame * mpReference
Definition: ftnfrm.hxx:87
void MoveFootnotes(const SwContentFrame *pSrc, SwContentFrame *pDest, SwTextFootnote const *pAttr)
Definition: ftnfrm.cxx:2165
virtual void Cut() override
Definition: sectfrm.cxx:252
static SwFootnoteFrame * AddChained(bool bAppend, SwFrame *pNewUpper, bool bDefaultFormat)
Definition: ftnfrm.cxx:157
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:422
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
bool IsAnFollow(const SwFlowFrame *pFlow) const
Definition: flowfrm.cxx:727
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:163
const SwContentFrame * GetRefFromAttr() const
Definition: ftnfrm.cxx:2912
SwLayoutFrame * GetNextFootnoteLeaf(MakePageType eMakePage)
Return the next layout leaf in that the frame can be moved.
Definition: ftnfrm.cxx:657
bool IsVertical() const
Definition: frame.hxx:974
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1379
void InvalidatePrt_()
Definition: frame.hxx:780
SwNodeIndex * GetStartNode() const
Definition: txtftn.hxx:41
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:634
SwFootnotePos m_ePos
Definition: ftninfo.hxx:97
bool IsFootnoteAtEnd() const
Definition: sectfrm.hxx:156
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
void RegistFlys(SwPageFrame *, const SwLayoutFrame *)
Definition: frmtool.cxx:3188
bool IsFootnoteBossFrame() const
Definition: frame.hxx:1187
void ColUnlock()
Definition: ftnfrm.hxx:137
SwTwips FootnoteSeparatorHeight(SwPageFootnoteInfo const &rInf)
Definition: ftnfrm.cxx:222
SwPageFrame * InsertPage(SwPageFrame *pSibling, bool bFootnote)
Definition: pagechg.cxx:1351
bool IsFootnoteContFrame() const
Definition: frame.hxx:1199
std::vector< SwFootnoteFrame * > SwFootnoteFrames
Definition: ftnboss.hxx:46
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:67
void SetEndNotePage(bool b)
Definition: pagefrm.hxx:202
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:207
void Height(tools::Long nNew)
Definition: swrect.hxx:190
sal_uInt16 GetNumber() const
Definition: fmtftn.hxx:69
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:70
const SwTwips nOldHeight
Definition: ftnboss.hxx:35
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:630
SwRootFrame * getRootFrame()
Definition: frame.hxx:680
const SwEndNoteInfo & GetEndNoteInfo() const
Definition: doc.hxx:632
std::vector< SwTextFootnote * >::const_iterator const_iterator
static tools::Long lcl_Undersize(const SwFrame *pFrame)
Definition: ftnfrm.cxx:193
virtual SwTwips GrowFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: ftnfrm.cxx:319
bool IsInHeadline(const SwFrame &rFrame) const
Definition: tabfrm.cxx:5718
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:395
SwFrame * GetNext()
Definition: frame.hxx:677
SwContentFrame * FindLastContent()
search for last content in the current footnote frame
Definition: ftnfrm.cxx:2931
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo