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.
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  pDel->Cut();
625  SwFrame::DestroyFrame(pDel);
626  }
627  if ( GetNext() && GetNext() == GetFollow() )
628  {
629  OSL_ENSURE( SwFlowFrame::CastFlowFrame( GetNext()->GetLower() ),
630  "Footnote without content?" );
632  SwFrame *pDel = GetNext();
633  pDel->Cut();
634  SwFrame::DestroyFrame(pDel);
635  }
636 #if OSL_DEBUG_LEVEL > 0
637  SwDoc *pDoc = GetFormat()->GetDoc();
638  if ( GetPrev() )
639  {
640  OSL_ENSURE( lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrame*>(GetPrev())->GetAttr() ) <=
641  lcl_FindFootnotePos( pDoc, GetAttr() ), "Prev is not FootnotePrev" );
642  }
643  if ( GetNext() )
644  {
645  OSL_ENSURE( lcl_FindFootnotePos( pDoc, GetAttr() ) <=
646  lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrame*>(GetNext())->GetAttr() ),
647  "Next is not FootnoteNext" );
648  }
649 #endif
650  InvalidateNxtFootnoteCnts( pPage );
651 }
652 
656 {
658  SwPageFrame* pOldPage = pOldBoss->FindPageFrame();
659  SwPageFrame* pPage;
660  SwFootnoteBossFrame *pBoss = pOldBoss->IsColumnFrame() ?
661  static_cast<SwFootnoteBossFrame*>(pOldBoss->GetNext()) : nullptr; // next column, if existing
662  if( pBoss )
663  pPage = nullptr;
664  else
665  {
666  if( pOldBoss->GetUpper()->IsSctFrame() )
667  { // this can only be in a column area
668  SwLayoutFrame* pNxt = pOldBoss->GetNextSctLeaf( eMakePage );
669  if( pNxt )
670  {
671  OSL_ENSURE( pNxt->IsColBodyFrame(), "GetNextFootnoteLeaf: Funny Leaf" );
672  pBoss = static_cast<SwFootnoteBossFrame*>(pNxt->GetUpper());
673  pPage = pBoss->FindPageFrame();
674  }
675  else
676  return nullptr;
677  }
678  else
679  {
680  // next page
681  pPage = static_cast<SwPageFrame*>(pOldPage->GetNext());
682  // skip empty pages
683  if( pPage && pPage->IsEmptyPage() )
684  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
685  pBoss = pPage;
686  }
687  }
688  // What do we have until here?
689  // pBoss != NULL, pPage==NULL => pBoss is the next column on the same page
690  // pBoss != NULL, pPage!=NULL => pBoss and pPage are the following page (empty pages skipped)
691  // pBoss == NULL => pPage == NULL, so there are no following pages
692 
693  // If the footnote has already a Follow we do not need to search.
694  // However, if there are unwanted empty columns/pages between Footnote and Follow,
695  // create another Follow on the next best column/page and the rest will sort itself out.
696  SwFootnoteFrame *pFootnote = FindFootnoteFrame();
697  if ( pFootnote && pFootnote->GetFollow() )
698  {
699  SwFootnoteBossFrame* pTmpBoss = pFootnote->GetFollow()->FindFootnoteBossFrame();
700  // Following cases will be handled:
701  // 1. both "FootnoteBoss"es are neighboring columns/pages
702  // 2. the new one is the first column of a neighboring page
703  // 3. the new one is the first column in a section of the next page
704  while( pTmpBoss != pBoss && pTmpBoss && !pTmpBoss->GetPrev() )
705  pTmpBoss = pTmpBoss->GetUpper()->FindFootnoteBossFrame();
706  if( pTmpBoss == pBoss )
707  return pFootnote->GetFollow();
708  }
709 
710  // If no pBoss could be found or it is a "wrong" page, we need a new page.
711  if ( !pBoss || ( pPage && pPage->IsEndNotePage() && !pOldPage->IsEndNotePage() ) )
712  {
713  if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
714  {
715  pBoss = InsertPage( pOldPage, pOldPage->IsFootnotePage() );
716  static_cast<SwPageFrame*>(pBoss)->SetEndNotePage( pOldPage->IsEndNotePage() );
717  }
718  else
719  return nullptr;
720  }
721  if( pBoss->IsPageFrame() )
722  {
723  // If this page has columns, then go to the first one
724  SwLayoutFrame* pLay = pBoss->FindBodyCont();
725  if( pLay && pLay->Lower() && pLay->Lower()->IsColumnFrame() )
726  pBoss = static_cast<SwFootnoteBossFrame*>(pLay->Lower());
727  }
728  // found column/page - add myself
729  SwFootnoteContFrame *pCont = pBoss->FindFootnoteCont();
730  if ( !pCont && pBoss->GetMaxFootnoteHeight() &&
731  ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
732  pCont = pBoss->MakeFootnoteCont();
733  return pCont;
734 }
735 
738 {
739  // The predecessor of a footnote is (if possible)
740  // the master of the chain of the footnote.
741  SwFootnoteFrame *pFootnote = FindFootnoteFrame();
742  SwLayoutFrame *pRet = pFootnote->GetMaster();
743 
745  SwPageFrame *pOldPage = pOldBoss->FindPageFrame();
746 
747  if ( !pOldBoss->GetPrev() && !pOldPage->GetPrev() )
748  return pRet; // there is neither a predecessor column nor page
749 
750  if ( !pRet )
751  {
752  bool bEndn = pFootnote->GetAttr()->GetFootnote().IsEndNote();
753  SwFrame* pTmpRef = nullptr;
754  const IDocumentSettingAccess& rSettings
755  = pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
756  if( bEndn && pFootnote->IsInSct() )
757  {
758  SwSectionFrame* pSect = pFootnote->FindSctFrame();
759  if( pSect->IsEndnAtEnd() )
760  // Endnotes at the end of the section.
761  pTmpRef = pSect->FindLastContent( SwFindMode::LastCnt );
762  }
763  else if (bEndn && rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
764  {
765  // Endnotes at the end of the document.
766  SwPageFrame* pPage = getRootFrame()->GetLastPage();
767  assert(pPage);
768  SwFrame* pPrevPage = pPage->GetPrev();
769  if (pPrevPage)
770  {
771  // Have a last but one page, use that since we try to get a preceding frame.
772  assert(pPrevPage->IsPageFrame());
773  pPage = static_cast<SwPageFrame*>(pPrevPage);
774  }
775  pTmpRef = pPage->FindLastBodyContent();
776  }
777  if( !pTmpRef )
778  // Endnotes on a separate page.
779  pTmpRef = pFootnote->GetRef();
780  SwFootnoteBossFrame* pStop = pTmpRef->FindFootnoteBossFrame( !bEndn );
781 
782  const sal_uInt16 nNum = pStop->GetPhyPageNum();
783 
784  // Do not leave the corresponding page if the footnote should
785  // be shown at the document ending or the footnote is an endnote.
786  const bool bEndNote = pOldPage->IsEndNotePage();
787  const bool bFootnoteEndDoc = pOldPage->IsFootnotePage();
788  SwFootnoteBossFrame* pNxtBoss = pOldBoss;
789  SwSectionFrame *pSect = pNxtBoss->GetUpper()->IsSctFrame() ?
790  static_cast<SwSectionFrame*>(pNxtBoss->GetUpper()) : nullptr;
791 
792  do
793  {
794  if( pNxtBoss->IsColumnFrame() && pNxtBoss->GetPrev() )
795  pNxtBoss = static_cast<SwFootnoteBossFrame*>(pNxtBoss->GetPrev()); // one column backwards
796  else // one page backwards
797  {
798  SwLayoutFrame* pBody = nullptr;
799  if( pSect )
800  {
801  if( pSect->IsFootnoteLock() )
802  {
803  if( pNxtBoss == pOldBoss )
804  return nullptr;
805  pStop = pNxtBoss;
806  }
807  else
808  {
809  pSect = pSect->FindMaster();
810  if( !pSect || !pSect->Lower() )
811  return nullptr;
812  OSL_ENSURE( pSect->Lower()->IsColumnFrame(),
813  "GetPrevFootnoteLeaf: Where's the column?" );
814  pNxtBoss = static_cast<SwFootnoteBossFrame*>(pSect->Lower());
815  pBody = pSect;
816  }
817  }
818  else
819  {
820  SwPageFrame* pPage = static_cast<SwPageFrame*>(pNxtBoss->FindPageFrame()->GetPrev());
821  if( !pPage || pPage->GetPhyPageNum() < nNum ||
822  bEndNote != pPage->IsEndNotePage() || bFootnoteEndDoc != pPage->IsFootnotePage() )
823  return nullptr; // no further pages found
824  pNxtBoss = pPage;
825  pBody = pPage->FindBodyCont();
826  }
827  // We have the previous page, we might need to find the last column of it
828  if( pBody )
829  {
830  if ( pBody->Lower() && pBody->Lower()->IsColumnFrame() )
831  {
832  pNxtBoss = static_cast<SwFootnoteBossFrame*>(pBody->GetLastLower());
833  }
834  }
835  }
836  SwFootnoteContFrame *pCont = pNxtBoss->FindFootnoteCont();
837  if ( pCont )
838  {
839  pRet = pCont;
840  break;
841  }
842  if ( pStop == pNxtBoss )
843  {
844  // Reached the column/page of the reference.
845  // Try to add a container and paste our content.
846  if ( eMakeFootnote == MAKEPAGE_FTN && pNxtBoss->GetMaxFootnoteHeight() )
847  pRet = pNxtBoss->MakeFootnoteCont();
848  break;
849  }
850  } while( !pRet );
851  }
852  if ( pRet )
853  {
854  const SwFootnoteBossFrame* pNewBoss = pRet->FindFootnoteBossFrame();
855  bool bJump = false;
856  if( pOldBoss->IsColumnFrame() && pOldBoss->GetPrev() ) // a previous column exists
857  bJump = pOldBoss->GetPrev() != static_cast<SwFrame const *>(pNewBoss); // did we chose it?
858  else if( pNewBoss->IsColumnFrame() && pNewBoss->GetNext() )
859  bJump = true; // there is another column after the boss (not the old boss)
860  else
861  {
862  // Will be reached only if old and new boss are both either pages or the last (new)
863  // or first (old) column of a page. In this case, check if pages were skipped.
864  const sal_uInt16 nDiff = pOldPage->GetPhyPageNum() - pRet->FindPageFrame()->GetPhyPageNum();
865  if ( nDiff > 2 ||
866  (nDiff > 1 && !static_cast<SwPageFrame*>(pOldPage->GetPrev())->IsEmptyPage()) )
867  bJump = true;
868  }
869  if( bJump )
871  }
872  return pRet;
873 }
874 
876 {
877  if ( !IsInDocBody() )
878  return false;
879 
880  if ( IsInTab() )
881  {
882  // no footnotes in repeated headlines
883  const SwTabFrame *pTab = const_cast<SwFrame*>(this)->ImplFindTabFrame();
884  assert(pTab);
885  if ( pTab->IsFollow() )
886  return !pTab->IsInHeadline( *this );
887  }
888  return true;
889 }
890 
892 {
893  // page numbering only if set at the document
894  if ( GetFormat()->GetDoc()->GetFootnoteInfo().m_eNum == FTNNUM_PAGE )
895  {
896  SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower());
897  while ( pPage && !pPage->IsFootnotePage() )
898  {
899  pPage->UpdateFootnoteNum();
900  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
901  }
902  }
903 }
904 
906 void sw_RemoveFootnotes( SwFootnoteBossFrame* pBoss, bool bPageOnly, bool bEndNotes )
907 {
908  do
909  {
910  SwFootnoteContFrame *pCont = pBoss->FindFootnoteCont();
911  if ( pCont )
912  {
913  SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower());
914  assert(pFootnote);
915  if ( bPageOnly )
916  while ( pFootnote->GetMaster() )
917  pFootnote = pFootnote->GetMaster();
918  do
919  {
920  SwFootnoteFrame *pNxt = static_cast<SwFootnoteFrame*>(pFootnote->GetNext());
921  if ( !pFootnote->GetAttr()->GetFootnote().IsEndNote() ||
922  bEndNotes )
923  {
924  pFootnote->GetRef()->Prepare( PrepareHint::FootnoteInvalidation, static_cast<void*>(pFootnote->GetAttr()) );
925  if ( bPageOnly && !pNxt )
926  pNxt = pFootnote->GetFollow();
927  pFootnote->Cut();
928  SwFrame::DestroyFrame(pFootnote);
929  }
930  pFootnote = pNxt;
931 
932  } while ( pFootnote );
933  }
934  if( !pBoss->IsInSct() )
935  {
936  // A sectionframe with the Footnote/EndnAtEnd-flags may contain
937  // foot/endnotes. If the last lower frame of the bodyframe is
938  // a multicolumned sectionframe, it may contain footnotes, too.
939  SwLayoutFrame* pBody = pBoss->FindBodyCont();
940  if( pBody && pBody->Lower() )
941  {
942  SwFrame* pLow = pBody->Lower();
943  while (pLow)
944  {
945  if( pLow->IsSctFrame() && ( !pLow->GetNext() ||
946  static_cast<SwSectionFrame*>(pLow)->IsAnyNoteAtEnd() ) &&
947  static_cast<SwSectionFrame*>(pLow)->Lower() &&
948  static_cast<SwSectionFrame*>(pLow)->Lower()->IsColumnFrame() )
949  sw_RemoveFootnotes( static_cast<SwColumnFrame*>(static_cast<SwSectionFrame*>(pLow)->Lower()),
950  bPageOnly, bEndNotes );
951  pLow = pLow->GetNext();
952  }
953  }
954  }
955  // is there another column?
956  pBoss = pBoss->IsColumnFrame() ? static_cast<SwColumnFrame*>(pBoss->GetNext()) : nullptr;
957  } while( pBoss );
958 }
959 
960 void SwRootFrame::RemoveFootnotes( SwPageFrame *pPage, bool bPageOnly, bool bEndNotes )
961 {
962  if ( !pPage )
963  pPage = static_cast<SwPageFrame*>(Lower());
964 
965  do
966  { // On columned pages we have to clean up in all columns
967  SwFootnoteBossFrame* pBoss;
968  SwLayoutFrame* pBody = pPage->FindBodyCont();
969  if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() )
970  pBoss = static_cast<SwFootnoteBossFrame*>(pBody->Lower()); // the first column
971  else
972  pBoss = pPage; // no columns
973  sw_RemoveFootnotes( pBoss, bPageOnly, bEndNotes );
974  if ( !bPageOnly )
975  {
976  if ( pPage->IsFootnotePage() &&
977  (!pPage->IsEndNotePage() || bEndNotes) )
978  {
979  SwFrame *pDel = pPage;
980  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
981  pDel->Cut();
982  SwFrame::DestroyFrame(pDel);
983  }
984  else
985  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
986  }
987  else
988  break;
989 
990  } while ( pPage );
991 }
992 
995 {
996  SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower());
997  while ( pPage && !pPage->IsFootnotePage() )
998  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
999  while ( pPage && pPage->IsEndNotePage() != bEndNote )
1000  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1001 
1002  if ( pPage )
1003  SwFrame::CheckPageDescs( pPage, false );
1004 }
1005 
1015 {
1016  SAL_WARN_IF(FindFootnoteCont(), "sw.core", "footnote container exists already");
1017 
1018  SwFootnoteContFrame *pNew = new SwFootnoteContFrame( GetFormat()->GetDoc()->GetDfltFrameFormat(), this );
1019  SwLayoutFrame *pLay = FindBodyCont();
1020  pNew->Paste( this, pLay->GetNext() );
1021  return pNew;
1022 }
1023 
1025 {
1026  SwFrame *pFrame = Lower();
1027  while( pFrame && !pFrame->IsFootnoteContFrame() )
1028  pFrame = pFrame->GetNext();
1029 
1030 #if OSL_DEBUG_LEVEL > 0
1031  if ( pFrame )
1032  {
1033  SwFrame *pFootnote = pFrame->GetLower();
1034  assert(pFootnote);
1035  while ( pFootnote )
1036  {
1037  assert(pFootnote->IsFootnoteFrame() && "Neighbor of footnote must be a footnote");
1038  pFootnote = pFootnote->GetNext();
1039  }
1040  }
1041 #endif
1042 
1043  return static_cast<SwFootnoteContFrame*>(pFrame);
1044 }
1045 
1048 {
1049  SwFootnoteContFrame *pCont = nullptr;
1050  if ( !GetFormat()->GetDoc()->GetFootnoteIdxs().empty() )
1051  {
1052  pCont = FindFootnoteCont();
1053  if ( !pCont )
1054  {
1055  SwPageFrame *pPage = FindPageFrame();
1056  SwFootnoteBossFrame* pBoss = this;
1057  bool bEndNote = pPage->IsEndNotePage();
1058  do
1059  {
1060  bool bChgPage = lcl_NextFootnoteBoss( pBoss, pPage, bDontLeave );
1061  // Found another boss? When changing pages, also the endnote flag must match.
1062  if( pBoss && ( !bChgPage || pPage->IsEndNotePage() == bEndNote ) )
1063  pCont = pBoss->FindFootnoteCont();
1064  } while ( !pCont && pPage );
1065  }
1066  }
1067  return pCont;
1068 }
1069 
1071 {
1072  // search for the nearest footnote container
1074  if ( !pCont )
1075  return nullptr;
1076 
1077  // Starting from the first footnote, search the first
1078  // footnote that is referenced by the current column/page
1079 
1080  SwFootnoteFrame *pRet = static_cast<SwFootnoteFrame*>(pCont->Lower());
1081  const sal_uInt16 nRefNum = FindPageFrame()->GetPhyPageNum();
1082  const sal_uInt16 nRefCol = lcl_ColumnNum( this );
1083  sal_uInt16 nPgNum, nColNum; // page number, column number
1084  SwFootnoteBossFrame* pBoss;
1085  SwPageFrame* pPage;
1086  if( pRet )
1087  {
1088  pBoss = pRet->GetRef()->FindFootnoteBossFrame();
1089  OSL_ENSURE( pBoss, "FindFirstFootnote: No boss found" );
1090  if( !pBoss )
1091  return nullptr; // ?There must be a bug, but no GPF
1092  pPage = pBoss->FindPageFrame();
1093  nPgNum = pPage->GetPhyPageNum();
1094  if ( nPgNum == nRefNum )
1095  {
1096  nColNum = lcl_ColumnNum( pBoss );
1097  if( nColNum == nRefCol )
1098  return pRet; // found
1099  else if( nColNum > nRefCol )
1100  return nullptr; // at least one column too far
1101  }
1102  else if ( nPgNum > nRefNum )
1103  return nullptr; // at least one column too far
1104  }
1105  else
1106  return nullptr;
1107  // Done if Ref is on a subsequent page or on the same page in a subsequent column
1108 
1109  do
1110  {
1111  while ( pRet->GetFollow() )
1112  pRet = pRet->GetFollow();
1113 
1114  SwFootnoteFrame *pNxt = static_cast<SwFootnoteFrame*>(pRet->GetNext());
1115  if ( !pNxt )
1116  {
1117  pBoss = pRet->FindFootnoteBossFrame();
1118  pPage = pBoss->FindPageFrame();
1119  lcl_NextFootnoteBoss( pBoss, pPage, false ); // next FootnoteBoss
1120  pCont = pBoss ? pBoss->FindNearestFootnoteCont() : nullptr;
1121  if ( pCont )
1122  pNxt = static_cast<SwFootnoteFrame*>(pCont->Lower());
1123  }
1124  if ( pNxt )
1125  {
1126  pRet = pNxt;
1127  pBoss = pRet->GetRef()->FindFootnoteBossFrame();
1128  pPage = pBoss->FindPageFrame();
1129  nPgNum = pPage->GetPhyPageNum();
1130  if ( nPgNum == nRefNum )
1131  {
1132  nColNum = lcl_ColumnNum( pBoss );
1133  if( nColNum == nRefCol )
1134  break; // found
1135  else if( nColNum > nRefCol )
1136  pRet = nullptr; // at least one column too far
1137  }
1138  else if ( nPgNum > nRefNum )
1139  pRet = nullptr; // at least a page too far
1140  }
1141  else
1142  pRet = nullptr; // there is none
1143  } while( pRet );
1144  return pRet;
1145 }
1146 
1149 {
1150  const SwFootnoteFrame *pRet = const_cast<SwFootnoteBossFrame*>(this)->FindFirstFootnote();
1151  if ( pRet )
1152  {
1153  const sal_uInt16 nColNum = lcl_ColumnNum( this );
1154  const sal_uInt16 nPageNum = GetPhyPageNum();
1155  while ( pRet && (pRet->GetRef() != pCnt) )
1156  {
1157  while ( pRet->GetFollow() )
1158  pRet = pRet->GetFollow();
1159 
1160  if ( pRet->GetNext() )
1161  pRet = static_cast<const SwFootnoteFrame*>(pRet->GetNext());
1162  else
1163  { SwFootnoteBossFrame *pBoss = const_cast<SwFootnoteBossFrame*>(pRet->FindFootnoteBossFrame());
1164  SwPageFrame *pPage = pBoss->FindPageFrame();
1165  lcl_NextFootnoteBoss( pBoss, pPage, false ); // next FootnoteBoss
1166  SwFootnoteContFrame *pCont = pBoss ? pBoss->FindNearestFootnoteCont() : nullptr;
1167  pRet = pCont ? static_cast<SwFootnoteFrame*>(pCont->Lower()) : nullptr;
1168  }
1169  if ( pRet )
1170  {
1171  const SwFootnoteBossFrame* pBoss = pRet->GetRef()->FindFootnoteBossFrame();
1172  if( pBoss->GetPhyPageNum() != nPageNum ||
1173  nColNum != lcl_ColumnNum( pBoss ) )
1174  pRet = nullptr;
1175  }
1176  }
1177  }
1178  return pRet;
1179 }
1180 
1182 {
1183  // Destroy the incarnations of footnotes to an attribute, if they don't
1184  // belong to pAssumed
1185  OSL_ENSURE( !pCheck->GetMaster(), "given master is not a Master." );
1186 
1187  SwNodeIndex aIdx( *pCheck->GetAttr()->GetStartNode(), 1 );
1188  SwContentNode *pNd = aIdx.GetNode().GetContentNode();
1189  if ( !pNd )
1190  pNd = pCheck->GetFormat()->GetDoc()->
1191  GetNodes().GoNextSection( &aIdx, true, false );
1193  SwFrame* pFrame = aIter.First();
1194  while( pFrame )
1195  {
1196  if( pFrame->getRootFrame() == pCheck->getRootFrame() )
1197  {
1198  SwFrame *pTmp = pFrame->GetUpper();
1199  while ( pTmp && !pTmp->IsFootnoteFrame() )
1200  pTmp = pTmp->GetUpper();
1201 
1202  SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pTmp);
1203  while ( pFootnote && pFootnote->GetMaster() )
1204  pFootnote = pFootnote->GetMaster();
1205  if ( pFootnote != pCheck )
1206  {
1207  while (pFootnote && !pFootnote->IsDeleteForbidden())
1208  {
1209  SwFootnoteFrame *pNxt = pFootnote->GetFollow();
1210  pFootnote->Cut();
1211  SwFrame::DestroyFrame(pFootnote);
1212  pFootnote = pNxt;
1213  }
1214  }
1215  }
1216 
1217  pFrame = aIter.Next();
1218  }
1219 }
1220 
1222 {
1223  // Place the footnote in front of the footnote whose attribute
1224  // is in front of the new one (get position via the Doc).
1225  // If there is no footnote in this footnote-boss yet, create a new container.
1226  // If there is a container but no footnote for this footnote-boss yet, place
1227  // the footnote behind the last footnote of the closest previous column/page.
1228 
1229  ResetFootnote( pNew );
1230  SwFootnoteFrame *pSibling = FindFirstFootnote();
1231  bool bDontLeave = false;
1232 
1233  // Ok, a sibling has been found, but is the sibling in an acceptable
1234  // environment?
1235  if( IsInSct() )
1236  {
1237  SwSectionFrame* pMySect = ImplFindSctFrame();
1238  bool bEndnt = pNew->GetAttr()->GetFootnote().IsEndNote();
1239  if( bEndnt )
1240  {
1241  const SwSectionFormat* pEndFormat = pMySect->GetEndSectFormat();
1242  bDontLeave = nullptr != pEndFormat;
1243  if( pSibling )
1244  {
1245  if( pEndFormat )
1246  {
1247  if( !pSibling->IsInSct() ||
1248  !pSibling->ImplFindSctFrame()->IsDescendantFrom( pEndFormat ) )
1249  pSibling = nullptr;
1250  }
1251  else if( pSibling->IsInSct() )
1252  pSibling = nullptr;
1253  }
1254  }
1255  else
1256  {
1257  bDontLeave = pMySect->IsFootnoteAtEnd();
1258  if( pSibling )
1259  {
1260  if( pMySect->IsFootnoteAtEnd() )
1261  {
1262  if( !pSibling->IsInSct() ||
1263  !pMySect->IsAnFollow( pSibling->ImplFindSctFrame() ) )
1264  pSibling = nullptr;
1265  }
1266  else if( pSibling->IsInSct() )
1267  pSibling = nullptr;
1268  }
1269  }
1270  }
1271 
1272  if( pSibling && pSibling->FindPageFrame()->IsEndNotePage() !=
1274  pSibling = nullptr;
1275 
1276  // use the Doc to find out the position
1277  SwDoc *pDoc = GetFormat()->GetDoc();
1278  const sal_uLong nStPos = ::lcl_FindFootnotePos( pDoc, pNew->GetAttr() );
1279 
1280  sal_uLong nCmpPos = 0;
1281  sal_uLong nLastPos = 0;
1282  SwFootnoteContFrame *pParent = nullptr;
1283  if( pSibling )
1284  {
1285  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1286  if( nCmpPos > nStPos )
1287  pSibling = nullptr;
1288  }
1289 
1290  if ( !pSibling )
1291  { pParent = FindFootnoteCont();
1292  if ( !pParent )
1293  {
1294  // There is no footnote container yet. Before creating one, keep in mind that
1295  // there might exist another following footnote that must be placed before the
1296  // new inserted one e.g. because it was divided over multiple pages etc.
1297  pParent = FindNearestFootnoteCont( bDontLeave );
1298  if ( pParent )
1299  {
1300  SwFootnoteFrame *pFootnote = static_cast<SwFootnoteFrame*>(pParent->Lower());
1301  if ( pFootnote )
1302  {
1303 
1304  nCmpPos = ::lcl_FindFootnotePos( pDoc, pFootnote->GetAttr() );
1305  if ( nCmpPos > nStPos )
1306  pParent = nullptr;
1307  }
1308  else
1309  pParent = nullptr;
1310  }
1311  }
1312  if ( !pParent )
1313  // here, we are sure that we can create a footnote container
1314  pParent = MakeFootnoteCont();
1315  else
1316  {
1317  // Based on the first footnote below the Parent, search for the first footnote whose
1318  // index is after the index of the newly inserted, to place the new one correctly
1319  pSibling = static_cast<SwFootnoteFrame*>(pParent->Lower());
1320  if ( !pSibling )
1321  {
1322  OSL_ENSURE( false, "Could not find space for footnote.");
1323  return;
1324  }
1325  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1326 
1327  SwFootnoteBossFrame *pNxtB; // remember the last one to not
1328  SwFootnoteFrame *pLastSib = nullptr; // go too far.
1329 
1330  while ( pSibling && nCmpPos <= nStPos )
1331  {
1332  pLastSib = pSibling; // potential candidate
1333  nLastPos = nCmpPos;
1334 
1335  while ( pSibling->GetFollow() )
1336  pSibling = pSibling->GetFollow();
1337 
1338  if ( pSibling->GetNext() )
1339  {
1340  pSibling = static_cast<SwFootnoteFrame*>(pSibling->GetNext());
1341  OSL_ENSURE( !pSibling->GetMaster() || ( ENDNOTE > nStPos &&
1342  pSibling->GetAttr()->GetFootnote().IsEndNote() ),
1343  "InsertFootnote: Master expected I" );
1344  }
1345  else
1346  {
1347  pNxtB = pSibling->FindFootnoteBossFrame();
1348  SwPageFrame *pSibPage = pNxtB->FindPageFrame();
1349  bool bEndNote = pSibPage->IsEndNotePage();
1350  bool bChgPage = lcl_NextFootnoteBoss( pNxtB, pSibPage, bDontLeave );
1351  // When changing pages, also the endnote flag must match.
1352  SwFootnoteContFrame *pCont = pNxtB && ( !bChgPage ||
1353  pSibPage->IsEndNotePage() == bEndNote )
1354  ? pNxtB->FindNearestFootnoteCont( bDontLeave ) : nullptr;
1355  if( pCont )
1356  pSibling = static_cast<SwFootnoteFrame*>(pCont->Lower());
1357  else // no further FootnoteContainer, insert after pSibling
1358  break;
1359  }
1360  if ( pSibling )
1361  {
1362  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1363  OSL_ENSURE( nCmpPos > nLastPos, "InsertFootnote: Order of FootnoteFrame's buggy" );
1364  }
1365  }
1366  // pLastSib is the last footnote before the new one and
1367  // pSibling is empty or the first one after the new one
1368  if ( pSibling && pLastSib && (pSibling != pLastSib) )
1369  {
1370  // too far?
1371  if ( nCmpPos > nStPos )
1372  pSibling = pLastSib;
1373  }
1374  else if ( !pSibling )
1375  {
1376  // Last chance: Take the last footnote of the parent.
1377  // Special case that happens e.g. when moving paragraphs with multiple footnotes.
1378  // To keep the order, use the parent of the last inspected footnote.
1379  pSibling = pLastSib;
1380  while( pSibling->GetFollow() )
1381  pSibling = pSibling->GetFollow();
1382  OSL_ENSURE( !pSibling->GetNext(), "InsertFootnote: Who's that guy?" );
1383  }
1384  }
1385  }
1386  else
1387  {
1388  // First footnote of the column/page found. Now search from there for the first one on the
1389  // same column/page whose index is after the given one. The last one found is the predecessor.
1391  !pNew->GetAttr()->GetFootnote().IsEndNote() );
1392  sal_uInt16 nRefNum = pBoss->GetPhyPageNum(); // page number of the new footnote
1393  sal_uInt16 nRefCol = lcl_ColumnNum( pBoss ); // column number of the new footnote
1394  bool bEnd = false;
1395  SwFootnoteFrame *pLastSib = nullptr;
1396  while ( pSibling && !bEnd && (nCmpPos <= nStPos) )
1397  {
1398  pLastSib = pSibling;
1399  nLastPos = nCmpPos;
1400 
1401  while ( pSibling->GetFollow() )
1402  pSibling = pSibling->GetFollow();
1403 
1404  SwFootnoteFrame *pFoll = static_cast<SwFootnoteFrame*>(pSibling->GetNext());
1405  if ( pFoll )
1406  {
1407  pBoss = pSibling->GetRef()->FindFootnoteBossFrame( !pSibling->
1408  GetAttr()->GetFootnote().IsEndNote() );
1409  sal_uInt16 nTmpRef;
1410  if( nStPos >= ENDNOTE ||
1411  (nTmpRef = pBoss->GetPhyPageNum()) < nRefNum ||
1412  ( nTmpRef == nRefNum && lcl_ColumnNum( pBoss ) <= nRefCol ))
1413  pSibling = pFoll;
1414  else
1415  bEnd = true;
1416  }
1417  else
1418  {
1419  SwFootnoteBossFrame* pNxtB = pSibling->FindFootnoteBossFrame();
1420  SwPageFrame *pSibPage = pNxtB->FindPageFrame();
1421  bool bEndNote = pSibPage->IsEndNotePage();
1422  bool bChgPage = lcl_NextFootnoteBoss( pNxtB, pSibPage, bDontLeave );
1423  // When changing pages, also the endnote flag must match.
1424  SwFootnoteContFrame *pCont = pNxtB && ( !bChgPage ||
1425  pSibPage->IsEndNotePage() == bEndNote )
1426  ? pNxtB->FindNearestFootnoteCont( bDontLeave ) : nullptr;
1427  if ( pCont )
1428  pSibling = static_cast<SwFootnoteFrame*>(pCont->Lower());
1429  else
1430  bEnd = true;
1431  }
1432  if ( !bEnd && pSibling )
1433  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1434  if (pSibling && (pSibling != pLastSib))
1435  {
1436  // too far?
1437  if ( (nLastPos < nCmpPos) && (nCmpPos > nStPos) )
1438  {
1439  pSibling = pLastSib;
1440  bEnd = true;
1441  }
1442  }
1443  }
1444  }
1445  if ( pSibling )
1446  {
1447  nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
1448  if ( nCmpPos < nStPos )
1449  {
1450  while ( pSibling->GetFollow() )
1451  pSibling = pSibling->GetFollow();
1452  pParent = static_cast<SwFootnoteContFrame*>(pSibling->GetUpper());
1453  pSibling = static_cast<SwFootnoteFrame*>(pSibling->GetNext());
1454  }
1455  else
1456  {
1457  if( pSibling->GetMaster() )
1458  {
1459  if( ENDNOTE > nCmpPos || nStPos >= ENDNOTE )
1460  {
1461  OSL_FAIL( "InsertFootnote: Master expected II" );
1462  do
1463  pSibling = pSibling->GetMaster();
1464  while ( pSibling->GetMaster() );
1465  }
1466  }
1467  pParent = static_cast<SwFootnoteContFrame*>(pSibling->GetUpper());
1468  }
1469  }
1470  OSL_ENSURE( pParent, "paste in space?" );
1471  pNew->Paste( pParent, pSibling );
1472 }
1473 
1474 static SwPageFrame* lcl_GetApproximateFootnotePage(const bool bEnd, const SwPageFrame* pPage,
1475  const SwDoc *pDoc, const SwTextFootnote *pAttr)
1476 {
1477  // We can at least search the approximately correct page
1478  // to ensure that we will finish in finite time even if
1479  // hundreds of footnotes exist.
1480  const SwPageFrame *pNxt = static_cast<const SwPageFrame*>(pPage->GetNext());
1481  const sal_uLong nStPos = ::lcl_FindFootnotePos(pDoc, pAttr);
1482  while (pNxt && (bEnd ? pNxt->IsEndNotePage() : pNxt->IsFootnotePage() && !pNxt->IsEndNotePage()))
1483  {
1484  const SwFootnoteContFrame *pCont = pNxt->FindFootnoteCont();
1485  if (pCont && pCont->Lower())
1486  {
1487  OSL_ENSURE( pCont->Lower()->IsFootnoteFrame(), "no footnote in the container" );
1488  if (nStPos > ::lcl_FindFootnotePos(pDoc,
1489  static_cast<const SwFootnoteFrame*>(pCont->Lower())->GetAttr()))
1490  {
1491  pPage = pNxt;
1492  pNxt = static_cast<const SwPageFrame*>(pPage->GetNext());
1493  continue;
1494  }
1495  }
1496  break;
1497  }
1498  return const_cast<SwPageFrame*>(pPage);
1499 }
1500 
1502 {
1503  // If the footnote already exists, do nothing.
1504  if ( FindFootnote( pRef, pAttr ) )
1505  return;
1506 
1507  // If footnotes are inserted at the end of the document,
1508  // we only need to search from the relevant page on.
1509  // If there is none yet, we need to create one.
1510  // If it is an Endnote, we need to search for or create an
1511  // Endnote page.
1512  SwDoc *pDoc = GetFormat()->GetDoc();
1513  SwFootnoteBossFrame *pBoss = this;
1514  SwPageFrame *pPage = FindPageFrame();
1515  SwPageFrame *pMyPage = pPage;
1516  bool bChgPage = false;
1517  const bool bEnd = pAttr->GetFootnote().IsEndNote();
1518  if (bEnd)
1519  {
1520  const IDocumentSettingAccess& rSettings = *pAttr->GetTextNode().getIDocumentSettingAccess();
1521  if( GetUpper()->IsSctFrame() &&
1522  static_cast<SwSectionFrame*>(GetUpper())->IsEndnAtEnd() )
1523  {
1524  // Endnotes at the end of the section.
1525  SwFrame* pLast =
1526  static_cast<SwSectionFrame*>(GetUpper())->FindLastContent( SwFindMode::EndNote );
1527  if( pLast )
1528  {
1529  pBoss = pLast->FindFootnoteBossFrame();
1530  pPage = pBoss->FindPageFrame();
1531  }
1532  }
1533  else if (rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
1534  {
1535  // Endnotes at the end of the document.
1536  pBoss = getRootFrame()->GetLastPage();
1537  pPage = pBoss->FindPageFrame();
1538  }
1539  else
1540  {
1541  // Endnotes on a separate page.
1542  while ( pPage->GetNext() && !pPage->IsEndNotePage() )
1543  {
1544  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1545  bChgPage = true;
1546  }
1547  if ( !pPage->IsEndNotePage() )
1548  {
1549  SwPageDesc *pDesc = pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
1550  pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(),
1551  !pPage->OnRightPage(), false, false, true, nullptr );
1552  pPage->SetEndNotePage( true );
1553  bChgPage = true;
1554  }
1555  else
1556  pPage = lcl_GetApproximateFootnotePage(true, pPage, pDoc, pAttr);
1557  }
1558  }
1559  else if( FTNPOS_CHAPTER == pDoc->GetFootnoteInfo().m_ePos && ( !GetUpper()->
1560  IsSctFrame() || !static_cast<SwSectionFrame*>(GetUpper())->IsFootnoteAtEnd() ) )
1561  {
1562  while ( pPage->GetNext() && !pPage->IsFootnotePage() &&
1563  !static_cast<SwPageFrame*>(pPage->GetNext())->IsEndNotePage() )
1564  {
1565  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1566  bChgPage = true;
1567  }
1568 
1569  if ( !pPage->IsFootnotePage() )
1570  {
1571  SwPageDesc *pDesc = pDoc->GetFootnoteInfo().GetPageDesc( *pDoc );
1572  pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(),
1573  !pPage->OnRightPage(), false, false, true, pPage->GetNext() );
1574  bChgPage = true;
1575  }
1576  else
1577  pPage = lcl_GetApproximateFootnotePage(false, pPage, pDoc, pAttr);
1578  }
1579 
1580  // For now, create a footnote and the corresponding content frames
1581  if ( !pAttr->GetStartNode() )
1582  {
1583  OSL_ENSURE( false, "no footnote content." );
1584  return;
1585  }
1586 
1587  // If there is already a footnote content on the column/page,
1588  // another one cannot be created in a column area.
1589  if( pBoss->IsInSct() && pBoss->IsColumnFrame() && !pPage->IsFootnotePage() )
1590  {
1591  SwSectionFrame* pSct = pBoss->FindSctFrame();
1592  if( bEnd ? !pSct->IsEndnAtEnd() : !pSct->IsFootnoteAtEnd() )
1593  {
1594  SwFootnoteContFrame* pFootnoteCont = pSct->FindFootnoteBossFrame(!bEnd)->FindFootnoteCont();
1595  if( pFootnoteCont )
1596  {
1597  SwFootnoteFrame* pTmp = static_cast<SwFootnoteFrame*>(pFootnoteCont->Lower());
1598  if( bEnd )
1599  while( pTmp && !pTmp->GetAttr()->GetFootnote().IsEndNote() )
1600  pTmp = static_cast<SwFootnoteFrame*>(pTmp->GetNext());
1601  if( pTmp && *pTmp < pAttr )
1602  return;
1603  }
1604  }
1605  }
1606 
1607  SwFootnoteFrame *pNew = new SwFootnoteFrame( pDoc->GetDfltFrameFormat(), this, pRef, pAttr );
1608  {
1609  SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
1610  ::InsertCnt_( pNew, pDoc, aIdx.GetIndex() );
1611  }
1612  // If the page was changed or newly created,
1613  // we need to place ourselves in the first column
1614  if( bChgPage )
1615  {
1616  SwLayoutFrame* pBody = pPage->FindBodyCont();
1617  OSL_ENSURE( pBody, "AppendFootnote: NoPageBody?" );
1618  if( pBody->Lower() && pBody->Lower()->IsColumnFrame() )
1619  pBoss = static_cast<SwFootnoteBossFrame*>(pBody->Lower());
1620  else
1621  pBoss = pPage; // page if no columns exist
1622  }
1623  pBoss->InsertFootnote( pNew );
1624  if ( pNew->GetUpper() ) // inserted or not?
1625  {
1626  ::RegistFlys( pNew->FindPageFrame(), pNew );
1627  SwSectionFrame* pSect = FindSctFrame();
1628  // The content of a FootnoteContainer in a (column) section only need to be calculated
1629  // if the section stretches already to the bottom edge of the Upper.
1630  if( pSect && !pSect->IsJoinLocked() && ( bEnd ? !pSect->IsEndnAtEnd() :
1631  !pSect->IsFootnoteAtEnd() ) && pSect->Growable() )
1632  pSect->InvalidateSize();
1633  else
1634  {
1635  // #i49383# - disable unlock of position of
1636  // lower objects during format of footnote content.
1637  const bool bOldFootnoteFrameLocked( pNew->IsColLocked() );
1638  pNew->ColLock();
1639  pNew->KeepLockPosOfLowerObjs();
1640  // #i57914# - adjust fix #i49383#
1641  SwContentFrame *pCnt = pNew->ContainsContent();
1642  while ( pCnt && pCnt->FindFootnoteFrame()->GetAttr() == pAttr )
1643  {
1644  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
1645  // #i49383# - format anchored objects
1646  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
1647  {
1649  *(pCnt->FindPageFrame()) ) )
1650  {
1651  // restart format with first content
1652  pCnt = pNew->ContainsContent();
1653  continue;
1654  }
1655  }
1656  pCnt = pCnt->FindNextCnt();
1657  }
1658  // #i49383#
1659  if ( !bOldFootnoteFrameLocked )
1660  {
1661  pNew->ColUnlock();
1662  }
1663  // #i57914# - adjust fix #i49383#
1664  // enable lock of lower object position before format of footnote frame.
1665  pNew->UnlockPosOfLowerObjs();
1666  pNew->Calc(getRootFrame()->GetCurrShell()->GetOut());
1667  // #i57914# - adjust fix #i49383#
1668  if ( !bOldFootnoteFrameLocked && !pNew->GetLower() &&
1669  !pNew->IsColLocked() && !pNew->IsBackMoveLocked() &&
1670  !pNew->IsDeleteForbidden() )
1671  {
1672  pNew->Cut();
1673  SwFrame::DestroyFrame(pNew);
1674  }
1675  }
1676  pMyPage->UpdateFootnoteNum();
1677  }
1678  else
1679  SwFrame::DestroyFrame(pNew);
1680 }
1681 
1683 {
1684  // the easiest and savest way goes via the attribute
1685  OSL_ENSURE( pAttr->GetStartNode(), "FootnoteAtr without StartNode." );
1686  SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
1687  SwContentNode *pNd = aIdx.GetNode().GetContentNode();
1688  if ( !pNd )
1689  pNd = pRef->GetAttrSet()->GetDoc()->
1690  GetNodes().GoNextSection( &aIdx, true, false );
1691  if ( !pNd )
1692  return nullptr;
1694  SwFrame* pFrame = aIter.First();
1695  if( pFrame )
1696  do
1697  {
1698  pFrame = pFrame->GetUpper();
1699  // #i28500#, #i27243# Due to the endnode collector, there are
1700  // SwFootnoteFrames, which are not in the layout. Therefore the
1701  // bInfFootnote flags are not set correctly, and a cell of FindFootnoteFrame
1702  // would return 0. Therefore we better call ImplFindFootnoteFrame().
1703  SwFootnoteFrame *pFootnote = pFrame->ImplFindFootnoteFrame();
1704  if ( pFootnote && pFootnote->GetRef() == pRef )
1705  {
1706  // The following condition becomes true, if the whole
1707  // footnotecontent is a section. While no frames exist,
1708  // the HiddenFlag of the section is set, this causes
1709  // the GoNextSection-function leaves the footnote.
1710  if( pFootnote->GetAttr() != pAttr )
1711  return nullptr;
1712  while ( pFootnote && pFootnote->GetMaster() )
1713  pFootnote = pFootnote->GetMaster();
1714  return pFootnote;
1715  }
1716 
1717  } while ( nullptr != (pFrame = aIter.Next()) );
1718 
1719  return nullptr;
1720 }
1721 
1723  const SwContentFrame *const pRef, const SwTextFootnote *const pAttr,
1724  bool bPrep )
1725 {
1726  bool ret(false);
1727  SwFootnoteFrame *pFootnote = FindFootnote( pRef, pAttr );
1728  if( pFootnote )
1729  {
1730  ret = true;
1731  do
1732  {
1733  SwFootnoteFrame *pFoll = pFootnote->GetFollow();
1734  pFootnote->Cut();
1735  SwFrame::DestroyFrame(pFootnote);
1736  pFootnote = pFoll;
1737  } while ( pFootnote );
1738  if( bPrep && pRef->IsFollow() )
1739  {
1740  OSL_ENSURE( pRef->IsTextFrame(), "NoTextFrame has Footnote?" );
1741  SwTextFrame* pMaster = pRef->FindMaster();
1742  if( !pMaster->IsLocked() )
1744  }
1745  }
1747  return ret;
1748 }
1749 
1751  SwContentFrame *pNew )
1752 {
1753  SwFootnoteFrame *pFootnote = FindFootnote( pOld, pAttr );
1754  while ( pFootnote )
1755  {
1756  pFootnote->SetRef( pNew );
1757  pFootnote = pFootnote->GetFollow();
1758  }
1759 }
1760 
1765  SwFootnoteBossFrame* _pOld,
1766  SwFootnoteFrames& _rFootnoteArr,
1767  const bool _bCollectOnlyPreviousFootnotes )
1768 {
1769  SwFootnoteFrame *pFootnote = _pOld->FindFirstFootnote();
1770  while( !pFootnote )
1771  {
1772  if( _pOld->IsColumnFrame() )
1773  {
1774  // visit columns
1775  while ( !pFootnote && _pOld->GetPrev() )
1776  {
1777  // Still no problem if no footnote was found yet. The loop is needed to pick up
1778  // following rows in tables. In all other cases it might correct bad contexts.
1779  _pOld = static_cast<SwFootnoteBossFrame*>(_pOld->GetPrev());
1780  pFootnote = _pOld->FindFirstFootnote();
1781  }
1782  }
1783  if( !pFootnote )
1784  {
1785  // previous page
1786  SwPageFrame* pPg;
1787  for ( SwFrame* pTmp = _pOld;
1788  nullptr != ( pPg = static_cast<SwPageFrame*>(pTmp->FindPageFrame()->GetPrev()))
1789  && pPg->IsEmptyPage() ;
1790  )
1791  {
1792  pTmp = pPg;
1793  }
1794  if( !pPg )
1795  return;
1796 
1797  SwLayoutFrame* pBody = pPg->FindBodyCont();
1798  if( pBody->Lower() && pBody->Lower()->IsColumnFrame() )
1799  {
1800  // multiple columns on one page => search last column
1801  _pOld = static_cast<SwFootnoteBossFrame*>(pBody->GetLastLower());
1802  }
1803  else
1804  _pOld = pPg; // single column page
1805  pFootnote = _pOld->FindFirstFootnote();
1806  }
1807  }
1808 
1809  CollectFootnotes_(_pRef, pFootnote, _rFootnoteArr, _bCollectOnlyPreviousFootnotes ? this : nullptr);
1810 }
1811 
1812 static void FootnoteInArr( SwFootnoteFrames& rFootnoteArr, SwFootnoteFrame* pFootnote )
1813 {
1814  if ( rFootnoteArr.end() == std::find( rFootnoteArr.begin(), rFootnoteArr.end(), pFootnote ) )
1815  rFootnoteArr.push_back( pFootnote );
1816 }
1817 
1819  SwFootnoteFrame* _pFootnote,
1820  SwFootnoteFrames& _rFootnoteArr,
1821  const SwFootnoteBossFrame* _pRefFootnoteBossFrame)
1822 {
1823  // Collect all footnotes referenced by pRef (attribute by attribute), combine them
1824  // (the content might be divided over multiple pages) and cut them.
1825 
1826  // For robustness, we do not log the corresponding footnotes here. If a footnote
1827  // is touched twice, there might be a crash. This allows this function here to
1828  // also handle corrupt layouts in some degrees (without loops or even crashes).
1829  SwFootnoteFrames aNotFootnoteArr;
1830 
1831  // here we have a footnote placed in front of the first one of the reference
1832  OSL_ENSURE( !_pFootnote->GetMaster() || _pFootnote->GetRef() != _pRef, "move FollowFootnote?" );
1833  while ( _pFootnote->GetMaster() )
1834  _pFootnote = _pFootnote->GetMaster();
1835 
1836  bool bFound = false;
1837 
1838  do
1839  {
1840  // Search for the next footnote in this column/page so that
1841  // we do not start from zero again after cutting one footnote.
1842  SwFootnoteFrame *pNxtFootnote = _pFootnote;
1843  while ( pNxtFootnote->GetFollow() )
1844  pNxtFootnote = pNxtFootnote->GetFollow();
1845  pNxtFootnote = static_cast<SwFootnoteFrame*>(pNxtFootnote->GetNext());
1846 
1847  if ( !pNxtFootnote )
1848  {
1849  SwFootnoteBossFrame* pBoss = _pFootnote->FindFootnoteBossFrame();
1850  SwPageFrame* pPage = pBoss->FindPageFrame();
1851  do
1852  {
1853  lcl_NextFootnoteBoss( pBoss, pPage, false );
1854  if( pBoss )
1855  {
1856  SwLayoutFrame* pCont = pBoss->FindFootnoteCont();
1857  if( pCont )
1858  {
1859  pNxtFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower());
1860  if( pNxtFootnote )
1861  {
1862  while( pNxtFootnote->GetMaster() )
1863  pNxtFootnote = pNxtFootnote->GetMaster();
1864  if( pNxtFootnote == _pFootnote )
1865  pNxtFootnote = nullptr;
1866  }
1867  }
1868  }
1869  } while( !pNxtFootnote && pBoss );
1870  }
1871  else if( !pNxtFootnote->GetAttr()->GetFootnote().IsEndNote() )
1872  {
1873  OSL_ENSURE( !pNxtFootnote->GetMaster(), "_CollectFootnote: Master expected" );
1874  while ( pNxtFootnote->GetMaster() )
1875  pNxtFootnote = pNxtFootnote->GetMaster();
1876  }
1877  if ( pNxtFootnote == _pFootnote )
1878  {
1879  OSL_FAIL( "_CollectFootnote: Vicious circle" );
1880  pNxtFootnote = nullptr;
1881  }
1882 
1883  // OD 03.04.2003 #108446# - determine, if found footnote has to be collected.
1884  bool bCollectFoundFootnote = false;
1885  // Ignore endnotes which are on a separate endnote page.
1886  bool bEndNote = _pFootnote->GetAttr()->GetFootnote().IsEndNote();
1887  const IDocumentSettingAccess& rSettings
1888  = _pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
1889  bool bContinuousEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES);
1890  if (_pFootnote->GetRef() == _pRef && (!bEndNote || bContinuousEndnotes))
1891  {
1892  if (_pRefFootnoteBossFrame)
1893  {
1894  SwFootnoteBossFrame* pBossOfFoundFootnote = _pFootnote->FindFootnoteBossFrame( true );
1895  OSL_ENSURE( pBossOfFoundFootnote,
1896  "<SwFootnoteBossFrame::CollectFootnotes_(..)> - footnote boss frame of found footnote frame missing.\nWrong layout!" );
1897  if ( !pBossOfFoundFootnote || // don't crash, if no footnote boss is found.
1898  pBossOfFoundFootnote->IsBefore( _pRefFootnoteBossFrame )
1899  )
1900  {
1901  bCollectFoundFootnote = true;
1902  }
1903  }
1904  else
1905  {
1906  bCollectFoundFootnote = true;
1907  }
1908  }
1909 
1910  if ( bCollectFoundFootnote )
1911  {
1912  OSL_ENSURE( !_pFootnote->GetMaster(), "move FollowFootnote?" );
1913  SwFootnoteFrame *pNxt = _pFootnote->GetFollow();
1914  while ( pNxt )
1915  {
1916  SwFrame *pCnt = pNxt->ContainsAny();
1917  if ( pCnt )
1918  {
1919  // destroy the follow on the way as it is empty
1920  do
1921  { SwFrame *pNxtCnt = pCnt->GetNext();
1922  pCnt->Cut();
1923  pCnt->Paste( _pFootnote );
1924  pCnt = pNxtCnt;
1925  } while ( pCnt );
1926  }
1927  else
1928  {
1929  OSL_ENSURE( !pNxt, "footnote without content?" );
1930  pNxt->Cut();
1931  SwFrame::DestroyFrame(pNxt);
1932  }
1933  pNxt = _pFootnote->GetFollow();
1934  }
1935  _pFootnote->Cut();
1936  FootnoteInArr( _rFootnoteArr, _pFootnote );
1937  bFound = true;
1938  }
1939  else
1940  {
1941  FootnoteInArr( aNotFootnoteArr, _pFootnote );
1942  if( bFound )
1943  break;
1944  }
1945  if ( pNxtFootnote &&
1946  _rFootnoteArr.end() == std::find( _rFootnoteArr.begin(), _rFootnoteArr.end(), pNxtFootnote ) &&
1947  aNotFootnoteArr.end() == std::find( aNotFootnoteArr.begin(), aNotFootnoteArr.end(), pNxtFootnote ) )
1948  _pFootnote = pNxtFootnote;
1949  else
1950  break;
1951  }
1952  while ( _pFootnote );
1953 }
1954 
1956 {
1957  // All footnotes referenced by pRef need to be moved
1958  // to a new position (based on the new column/page)
1959  const sal_uInt16 nMyNum = FindPageFrame()->GetPhyPageNum();
1960  const sal_uInt16 nMyCol = lcl_ColumnNum( this );
1961  SwRectFnSet aRectFnSet(this);
1962 
1963  // #i21478# - keep last inserted footnote in order to
1964  // format the content of the following one.
1965  SwFootnoteFrame* pLastInsertedFootnote = nullptr;
1966  for (SwFootnoteFrame* pFootnote : rFootnoteArr)
1967  {
1968  SwFootnoteBossFrame* pRefBoss(pFootnote->GetRef()->FindFootnoteBossFrame(
1969  !pFootnote->GetAttr()->GetFootnote().IsEndNote()));
1970  if( pRefBoss != this )
1971  {
1972  const sal_uInt16 nRefNum = pRefBoss->FindPageFrame()->GetPhyPageNum();
1973  const sal_uInt16 nRefCol = lcl_ColumnNum( this );
1974  if( nRefNum < nMyNum || ( nRefNum == nMyNum && nRefCol <= nMyCol ) )
1975  pRefBoss = this;
1976  }
1977  pRefBoss->InsertFootnote( pFootnote );
1978 
1979  if ( pFootnote->GetUpper() ) // robust, e.g. with duplicates
1980  {
1981  // First condense the content so that footnote frames that do not fit on the page
1982  // do not do too much harm (Loop 66312). So, the footnote content first grows as
1983  // soon as the content gets formatted and it is sure that it fits on the page.
1984  SwFrame *pCnt = pFootnote->ContainsAny();
1985  while( pCnt )
1986  {
1987  if( pCnt->IsLayoutFrame() )
1988  {
1989  SwFrame* pTmp = static_cast<SwLayoutFrame*>(pCnt)->ContainsAny();
1990  while( pTmp && static_cast<SwLayoutFrame*>(pCnt)->IsAnLower( pTmp ) )
1991  {
1993 
1995  aRectFnSet.SetHeight(aFrm, 0);
1996 
1998  aRectFnSet.SetHeight(aPrt, 0);
1999 
2000  pTmp = pTmp->FindNext();
2001  }
2002  }
2003  else
2004  {
2006  }
2007 
2009  aRectFnSet.SetHeight(aFrm, 0);
2010 
2012  aRectFnSet.SetHeight(aPrt, 0);
2013 
2014  pCnt = pCnt->GetNext();
2015  }
2016 
2017  {
2019  aRectFnSet.SetHeight(aFrm, 0);
2020  }
2021 
2022  {
2024  aRectFnSet.SetHeight(aPrt, 0);
2025  }
2026 
2027  pFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut());
2028  pFootnote->GetUpper()->Calc(getRootFrame()->GetCurrShell()->GetOut());
2029 
2030  if( bCalc )
2031  {
2032  SwTextFootnote *pAttr = pFootnote->GetAttr();
2033  pCnt = pFootnote->ContainsAny();
2034  bool bUnlock = !pFootnote->IsBackMoveLocked();
2035  pFootnote->LockBackMove();
2036 
2037  // #i49383# - disable unlock of position of
2038  // lower objects during format of footnote content.
2039  pFootnote->KeepLockPosOfLowerObjs();
2040  // #i57914# - adjust fix #i49383#
2041 
2042  while ( pCnt && pCnt->FindFootnoteFrame()->GetAttr() == pAttr )
2043  {
2044  pCnt->InvalidatePos_();
2045  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
2046  // #i49383# - format anchored objects
2047  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
2048  {
2050  *(pCnt->FindPageFrame()) ) )
2051  {
2052  // restart format with first content
2053  pCnt = pFootnote->ContainsAny();
2054  continue;
2055  }
2056  }
2057  if( pCnt->IsSctFrame() )
2058  {
2059  // If the area is not empty, iterate also over the content
2060  SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny();
2061  if( pTmp )
2062  pCnt = pTmp;
2063  else
2064  pCnt = pCnt->FindNext();
2065  }
2066  else
2067  pCnt = pCnt->FindNext();
2068  }
2069  if( bUnlock )
2070  {
2071  pFootnote->UnlockBackMove();
2072  if( !pFootnote->ContainsAny() && !pFootnote->IsColLocked() )
2073  {
2074  pFootnote->Cut();
2075  SwFrame::DestroyFrame(pFootnote);
2076  // #i21478#
2077  pFootnote = nullptr;
2078  }
2079  }
2080  // #i49383#
2081  if ( pFootnote )
2082  {
2083  // #i57914# - adjust fix #i49383#
2084  // enable lock of lower object position before format of footnote frame.
2085  pFootnote->UnlockPosOfLowerObjs();
2086  pFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut());
2087  }
2088  }
2089  }
2090  else
2091  {
2092  OSL_ENSURE( !pFootnote->GetMaster() && !pFootnote->GetFollow(),
2093  "DelFootnote and Master/Follow?" );
2094  SwFrame::DestroyFrame(pFootnote);
2095  // #i21478#
2096  pFootnote = nullptr;
2097  }
2098 
2099  // #i21478#
2100  if ( pFootnote )
2101  {
2102  pLastInsertedFootnote = pFootnote;
2103  }
2104  }
2105 
2106  // #i21478# - format content of footnote following
2107  // the new inserted ones.
2108  if ( !(bCalc && pLastInsertedFootnote) )
2109  return;
2110 
2111  if ( !pLastInsertedFootnote->GetNext() )
2112  return;
2113 
2114  SwFootnoteFrame* pNextFootnote = static_cast<SwFootnoteFrame*>(pLastInsertedFootnote->GetNext());
2115  SwTextFootnote* pAttr = pNextFootnote->GetAttr();
2116  SwFrame* pCnt = pNextFootnote->ContainsAny();
2117 
2118  bool bUnlock = !pNextFootnote->IsBackMoveLocked();
2119  pNextFootnote->LockBackMove();
2120  // #i49383# - disable unlock of position of
2121  // lower objects during format of footnote content.
2122  pNextFootnote->KeepLockPosOfLowerObjs();
2123  // #i57914# - adjust fix #i49383#
2124 
2125  while ( pCnt && pCnt->FindFootnoteFrame()->GetAttr() == pAttr )
2126  {
2127  pCnt->InvalidatePos_();
2128  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
2129  // #i49383# - format anchored objects
2130  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
2131  {
2133  *(pCnt->FindPageFrame()) ) )
2134  {
2135  // restart format with first content
2136  pCnt = pNextFootnote->ContainsAny();
2137  continue;
2138  }
2139  }
2140  if( pCnt->IsSctFrame() )
2141  {
2142  // If the area is not empty, iterate also over the content
2143  SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny();
2144  if( pTmp )
2145  pCnt = pTmp;
2146  else
2147  pCnt = pCnt->FindNext();
2148  }
2149  else
2150  pCnt = pCnt->FindNext();
2151  }
2152  if( bUnlock )
2153  {
2154  pNextFootnote->UnlockBackMove();
2155  }
2156  // #i49383#
2157  // #i57914# - adjust fix #i49383#
2158  // enable lock of lower object position before format of footnote frame.
2159  pNextFootnote->UnlockPosOfLowerObjs();
2160  pNextFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut());
2161 }
2162 
2164  SwTextFootnote const *pAttr )
2165 {
2166  if( ( GetFormat()->GetDoc()->GetFootnoteInfo().m_ePos == FTNPOS_CHAPTER &&
2167  (!GetUpper()->IsSctFrame() || !static_cast<SwSectionFrame*>(GetUpper())->IsFootnoteAtEnd()))
2168  || pAttr->GetFootnote().IsEndNote() )
2169  return;
2170 
2171  OSL_ENSURE( this == pSrc->FindFootnoteBossFrame( true ),
2172  "SwPageFrame::MoveFootnotes: source frame isn't on that FootnoteBoss" );
2173 
2174  SwFootnoteFrame *pFootnote = FindFirstFootnote();
2175  if( !pFootnote )
2176  return;
2177 
2178  ChangeFootnoteRef( pSrc, pAttr, pDest );
2179  SwFootnoteBossFrame *pDestBoss = pDest->FindFootnoteBossFrame( true );
2180  OSL_ENSURE( pDestBoss, "+SwPageFrame::MoveFootnotes: no destination boss" );
2181  if( !pDestBoss ) // robust
2182  return;
2183 
2184  SwFootnoteFrames aFootnoteArr;
2185  SwFootnoteBossFrame::CollectFootnotes_(pDest, pFootnote, aFootnoteArr, nullptr);
2186  if ( aFootnoteArr.empty() )
2187  return;
2188 
2189  pDestBoss->MoveFootnotes_( aFootnoteArr, true );
2190  SwPageFrame* pSrcPage = FindPageFrame();
2191  SwPageFrame* pDestPage = pDestBoss->FindPageFrame();
2192  // update FootnoteNum only at page change
2193  if( pSrcPage != pDestPage )
2194  {
2195  if( pSrcPage->GetPhyPageNum() > pDestPage->GetPhyPageNum() )
2196  pSrcPage->UpdateFootnoteNum();
2197  pDestPage->UpdateFootnoteNum();
2198  }
2199 }
2200 
2201 void SwFootnoteBossFrame::RearrangeFootnotes( const SwTwips nDeadLine, const bool bLock,
2202  const SwTextFootnote *pAttr )
2203 {
2204  // Format all footnotes of a column/page so that they might change the column/page.
2205 
2206  SwSaveFootnoteHeight aSave( this, nDeadLine );
2207  SwFootnoteFrame *pFootnote = FindFirstFootnote();
2208  if( pFootnote && pFootnote->GetPrev() && bLock )
2209  {
2210  SwFootnoteFrame* pFirst = static_cast<SwFootnoteFrame*>(pFootnote->GetUpper()->Lower());
2211  SwFrame* pContent = pFirst->ContainsAny();
2212  if( pContent )
2213  {
2214  bool bUnlock = !pFirst->IsBackMoveLocked();
2215  pFirst->LockBackMove();
2216  pFirst->Calc(getRootFrame()->GetCurrShell()->GetOut());
2217  pContent->Calc(getRootFrame()->GetCurrShell()->GetOut());
2218  // #i49383# - format anchored objects
2219  if ( pContent->IsTextFrame() && pContent->isFrameAreaDefinitionValid() )
2220  {
2222  *(pContent->FindPageFrame()) );
2223  }
2224  if( bUnlock )
2225  pFirst->UnlockBackMove();
2226  }
2227  pFootnote = FindFirstFootnote();
2228  }
2229  SwDoc *pDoc = GetFormat()->GetDoc();
2230  const sal_uLong nFootnotePos = pAttr ? ::lcl_FindFootnotePos( pDoc, pAttr ) : 0;
2231  SwFrame *pCnt = pFootnote ? pFootnote->ContainsAny() : nullptr;
2232  if ( !pCnt )
2233  return;
2234 
2235  bool bMore = true;
2236  bool bStart = pAttr == nullptr; // If no attribute is given, process all
2237  // #i49383# - disable unlock of position of
2238  // lower objects during format of footnote and footnote content.
2239  SwFootnoteFrame* pLastFootnoteFrame( nullptr );
2240  // footnote frame needs to be locked, if <bLock> isn't set.
2241  bool bUnlockLastFootnoteFrame( false );
2242  do
2243  {
2244  if( !bStart )
2245  bStart = ::lcl_FindFootnotePos( pDoc, pCnt->FindFootnoteFrame()->GetAttr() )
2246  == nFootnotePos;
2247  if( bStart )
2248  {
2249  pCnt->InvalidatePos_();
2250  pCnt->InvalidateSize_();
2252  SwFootnoteFrame* pFootnoteFrame = pCnt->FindFootnoteFrame();
2253  // #i49383#
2254  if ( pFootnoteFrame != pLastFootnoteFrame )
2255  {
2256  if ( pLastFootnoteFrame )
2257  {
2258  if ( !bLock && bUnlockLastFootnoteFrame )
2259  {
2260  pLastFootnoteFrame->ColUnlock();
2261  }
2262  // #i57914# - adjust fix #i49383#
2263  // enable lock of lower object position before format of footnote frame.
2264  pLastFootnoteFrame->UnlockPosOfLowerObjs();
2265  pLastFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut());
2266  if ( !bLock && bUnlockLastFootnoteFrame &&
2267  !pLastFootnoteFrame->GetLower() &&
2268  !pLastFootnoteFrame->IsColLocked() &&
2269  !pLastFootnoteFrame->IsBackMoveLocked() &&
2270  !pLastFootnoteFrame->IsDeleteForbidden() )
2271  {
2272  pLastFootnoteFrame->Cut();
2273  SwFrame::DestroyFrame(pLastFootnoteFrame);
2274  pLastFootnoteFrame = nullptr;
2275  }
2276  }
2277  if ( !bLock )
2278  {
2279  bUnlockLastFootnoteFrame = !pFootnoteFrame->IsColLocked();
2280  pFootnoteFrame->ColLock();
2281  }
2282  pFootnoteFrame->KeepLockPosOfLowerObjs();
2283  pLastFootnoteFrame = pFootnoteFrame;
2284  }
2285  // OD 30.10.2002 #97265# - invalidate position of footnote
2286  // frame, if it's below its footnote container, in order to
2287  // assure its correct position, probably calculating its previous
2288  // footnote frames.
2289  {
2290  SwRectFnSet aRectFnSet(this);
2291  SwFrame* pFootnoteContFrame = pFootnoteFrame->GetUpper();
2292  if ( aRectFnSet.TopDist(pFootnoteFrame->getFrameArea(), aRectFnSet.GetPrtBottom(*pFootnoteContFrame)) > 0 )
2293  {
2294  pFootnoteFrame->InvalidatePos_();
2295  }
2296  }
2297  if ( bLock )
2298  {
2299  bool bUnlock = !pFootnoteFrame->IsBackMoveLocked();
2300  pFootnoteFrame->LockBackMove();
2301  pFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut());
2302  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
2303  // #i49383# - format anchored objects
2304  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
2305  {
2306  SwFrameDeleteGuard aDeleteGuard(pFootnote);
2308  *(pCnt->FindPageFrame()) ) )
2309  {
2310  // restart format with first content
2311  pCnt = pFootnote ? pFootnote->ContainsAny() : nullptr;
2312  if (!pCnt)
2313  bMore = false;
2314  continue;
2315  }
2316  }
2317  if( bUnlock )
2318  {
2319  pFootnoteFrame->UnlockBackMove();
2320  if( !pFootnoteFrame->Lower() &&
2321  !pFootnoteFrame->IsColLocked() )
2322  {
2323  // #i49383#
2324  OSL_ENSURE( pLastFootnoteFrame == pFootnoteFrame,
2325  "<SwFootnoteBossFrame::RearrangeFootnotes(..)> - <pLastFootnoteFrame> != <pFootnoteFrame>" );
2326  pLastFootnoteFrame = nullptr;
2327  pFootnoteFrame->Cut();
2328  SwFrame::DestroyFrame(pFootnoteFrame);
2329  if (pFootnote == pFootnoteFrame)
2330  pFootnote = nullptr;
2331  }
2332  }
2333  }
2334  else
2335  {
2336  pFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut());
2337  pCnt->Calc(getRootFrame()->GetCurrShell()->GetOut());
2338  // #i49383# - format anchored objects
2339  if ( pCnt->IsTextFrame() && pCnt->isFrameAreaDefinitionValid() )
2340  {
2342  *(pCnt->FindPageFrame()) ) )
2343  {
2344  // restart format with first content
2345  pCnt = pFootnote->ContainsAny();
2346  continue;
2347  }
2348  }
2349  }
2350  }
2351  SwSectionFrame *pDel = nullptr;
2352  if( pCnt->IsSctFrame() )
2353  {
2354  SwFrame* pTmp = static_cast<SwSectionFrame*>(pCnt)->ContainsAny();
2355  if( pTmp )
2356  {
2357  pCnt = pTmp;
2358  continue;
2359  }
2360  pDel = static_cast<SwSectionFrame*>(pCnt);
2361  }
2362  if ( pCnt->GetNext() )
2363  pCnt = pCnt->GetNext();
2364  else
2365  {
2366  pCnt = pCnt->FindNext();
2367  if ( pCnt )
2368  {
2369  SwFootnoteFrame* pFootnoteFrame = pCnt->FindFootnoteFrame();
2370  if( pFootnoteFrame->GetRef()->FindFootnoteBossFrame(
2371  pFootnoteFrame->GetAttr()->GetFootnote().IsEndNote() ) != this )
2372  bMore = false;
2373  }
2374  else
2375  bMore = false;
2376  }
2377  if( pDel )
2378  {
2379  bool bUnlockLastFootnoteFrameGuard = pLastFootnoteFrame && !pLastFootnoteFrame->IsColLocked();
2380  if (bUnlockLastFootnoteFrameGuard)
2381  pLastFootnoteFrame->ColLock();
2382  pDel->Cut();
2383  if (bUnlockLastFootnoteFrameGuard)
2384  pLastFootnoteFrame->ColUnlock();
2385  SwFrame::DestroyFrame(pDel);
2386  }
2387  if ( bMore )
2388  {
2389  // Go not further than to the provided footnote (if given)
2390  if ( pAttr &&
2391  (::lcl_FindFootnotePos( pDoc,
2392  pCnt->FindFootnoteFrame()->GetAttr()) > nFootnotePos ) )
2393  bMore = false;
2394  }
2395  } while ( bMore );
2396  // #i49383#
2397  if ( !pLastFootnoteFrame )
2398  return;
2399 
2400  if ( !bLock && bUnlockLastFootnoteFrame )
2401  {
2402  pLastFootnoteFrame->ColUnlock();
2403  }
2404  // #i57914# - adjust fix #i49383#
2405  // enable lock of lower object position before format of footnote frame.
2406  pLastFootnoteFrame->UnlockPosOfLowerObjs();
2407  pLastFootnoteFrame->Calc(getRootFrame()->GetCurrShell()->GetOut());
2408  if ( !bLock && bUnlockLastFootnoteFrame &&
2409  !pLastFootnoteFrame->GetLower() &&
2410  !pLastFootnoteFrame->IsColLocked() &&
2411  !pLastFootnoteFrame->IsBackMoveLocked() )
2412  {
2413  pLastFootnoteFrame->Cut();
2414  SwFrame::DestroyFrame(pLastFootnoteFrame);
2415  }
2416 }
2417 
2419 {
2420  // page numbering only if set at the document
2421  if ( GetFormat()->GetDoc()->GetFootnoteInfo().m_eNum != FTNNUM_PAGE )
2422  return;
2423 
2424  SwLayoutFrame* pBody = FindBodyCont();
2425  if( !pBody || !pBody->Lower() )
2426  return;
2427 
2429  sal_uInt16 nNum = 0;
2430 
2431  while( pContent && pContent->FindPageFrame() == this )
2432  {
2433  if( static_cast<SwTextFrame*>(pContent)->HasFootnote() )
2434  {
2435  SwFootnoteBossFrame* pBoss = pContent->FindFootnoteBossFrame( true );
2436  if( pBoss->GetUpper()->IsSctFrame() &&
2437  static_cast<SwSectionFrame*>(pBoss->GetUpper())->IsOwnFootnoteNum() )
2438  pContent = static_cast<SwSectionFrame*>(pBoss->GetUpper())->FindLastContent();
2439  else
2440  {
2441  SwFootnoteFrame* pFootnote = const_cast<SwFootnoteFrame*>(pBoss->FindFirstFootnote( pContent ));
2442  while( pFootnote )
2443  {
2444  SwTextFootnote* pTextFootnote = pFootnote->GetAttr();
2445  if( !pTextFootnote->GetFootnote().IsEndNote() &&
2446  pTextFootnote->GetFootnote().GetNumStr().isEmpty() &&
2447  !pFootnote->GetMaster())
2448  {
2449  // sw_redlinehide: the layout can only keep one number
2450  // up to date; depending on its setting, this is either
2451  // the non-hidden or the hidden number; the other
2452  // number will simply be preserved as-is (so in case
2453  // there are 2 layouts, maybe both can be updated...)
2454  ++nNum;
2455  sal_uInt16 const nOldNum(pTextFootnote->GetFootnote().GetNumber());
2456  sal_uInt16 const nOldNumRLHidden(pTextFootnote->GetFootnote().GetNumberRLHidden());
2457  if (getRootFrame()->IsHideRedlines())
2458  {
2459  if (nNum != nOldNumRLHidden)
2460  {
2461  pTextFootnote->SetNumber(nOldNum, nNum, OUString());
2462  }
2463  }
2464  else
2465  {
2466  if (nNum != nOldNum)
2467  {
2468  pTextFootnote->SetNumber(nNum, nOldNumRLHidden, OUString());
2469  }
2470  }
2471  }
2472  if ( pFootnote->GetNext() )
2473  pFootnote = static_cast<SwFootnoteFrame*>(pFootnote->GetNext());
2474  else
2475  {
2476  SwFootnoteBossFrame* pTmpBoss = pFootnote->FindFootnoteBossFrame( true );
2477  if( pTmpBoss )
2478  {
2479  SwPageFrame* pPage = pTmpBoss->FindPageFrame();
2480  pFootnote = nullptr;
2481  lcl_NextFootnoteBoss( pTmpBoss, pPage, false );
2482  SwFootnoteContFrame *pCont = pTmpBoss ? pTmpBoss->FindNearestFootnoteCont() : nullptr;
2483  if ( pCont )
2484  pFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower());
2485  }
2486  }
2487  if( pFootnote && pFootnote->GetRef() != pContent )
2488  pFootnote = nullptr;
2489  }
2490  }
2491  }
2492  pContent = pContent->FindNextCnt();
2493  }
2494 }
2495 
2497 {
2498  SwFrame *pBody = FindBodyCont();
2499  pBody->Calc(getRootFrame()->GetCurrShell()->GetOut());
2500 
2501  SwFrame *pCont = FindFootnoteCont();
2502  const SwTwips nMax = m_nMaxFootnoteHeight;// current should exceed MaxHeight
2503  SwRectFnSet aRectFnSet(this);
2504  if ( pCont )
2505  {
2506  pCont->Calc(getRootFrame()->GetCurrShell()->GetOut());
2507  m_nMaxFootnoteHeight = -aRectFnSet.BottomDist( pCont->getFrameArea(), nDeadLine );
2508  }
2509  else
2510  m_nMaxFootnoteHeight = -aRectFnSet.BottomDist( pBody->getFrameArea(), nDeadLine );
2511 
2512  const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
2513  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
2514  m_nMaxFootnoteHeight += pBody->Grow( LONG_MAX, true );
2515  if ( IsInSct() )
2517 
2518  if ( m_nMaxFootnoteHeight < 0 )
2520  if ( nMax != LONG_MAX && m_nMaxFootnoteHeight > nMax )
2521  m_nMaxFootnoteHeight = nMax;
2522 }
2523 
2525 {
2526  // To not fall below 20% of the page height
2527  // (in contrast to MSOffice where footnotes can fill a whole column/page)
2528 
2529  const SwPageFrame* pPg = FindPageFrame();
2530  OSL_ENSURE( pPg || IsInSct(), "Footnote lost page" );
2531 
2532  const SwFrame *pBody = FindBodyCont();
2533  SwTwips nRet;
2534  if( pBody )
2535  {
2536  SwRectFnSet aRectFnSet(this);
2537  if( IsInSct() )
2538  {
2539  nRet = 0;
2540  SwTwips nTmp = aRectFnSet.YDiff( aRectFnSet.GetPrtTop(*pBody),
2541  aRectFnSet.GetTop(getFrameArea()) );
2542  const SwSectionFrame* pSect = FindSctFrame();
2543  // Endnotes in a ftncontainer causes a deadline:
2544  // the bottom of the last contentfrm
2545  if( pSect->IsEndnAtEnd() ) // endnotes allowed?
2546  {
2547  OSL_ENSURE( !Lower() || !Lower()->GetNext() || Lower()->GetNext()->
2548  IsFootnoteContFrame(), "FootnoteContainer expected" );
2549  const SwFootnoteContFrame* pCont = Lower() ?
2550  static_cast<const SwFootnoteContFrame*>(Lower()->GetNext()) : nullptr;
2551  if( pCont )
2552  {
2553  const SwFootnoteFrame* pFootnote = static_cast<const SwFootnoteFrame*>(pCont->Lower());
2554  while( pFootnote)
2555  {
2556  if( pFootnote->GetAttr()->GetFootnote().IsEndNote() )
2557  { // endnote found
2558  const SwFrame* pFrame = static_cast<const SwLayoutFrame*>(Lower())->Lower();
2559  if( pFrame )
2560  {
2561  while( pFrame->GetNext() )
2562  pFrame = pFrame->GetNext(); // last cntntfrm
2563  nTmp += aRectFnSet.YDiff(
2564  aRectFnSet.GetTop(getFrameArea()),
2565  aRectFnSet.GetBottom(pFrame->getFrameArea()) );
2566  }
2567  break;
2568  }
2569  pFootnote = static_cast<const SwFootnoteFrame*>(pFootnote->GetNext());
2570  }
2571  }
2572  }
2573  if( nTmp < nRet )
2574  nRet = nTmp;
2575  }
2576  else
2577  nRet = - aRectFnSet.GetHeight(pPg->getFramePrintArea())/5;
2578  nRet += aRectFnSet.GetHeight(pBody->getFrameArea());
2579  if( nRet < 0 )
2580  nRet = 0;
2581  }
2582  else
2583  nRet = 0;
2584  if ( IsPageFrame() )
2585  {
2586  const SwViewShell *pSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
2587  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
2588  nRet += BROWSE_HEIGHT - getFrameArea().Height();
2589  }
2590  return nRet;
2591 }
2592 
2606 {
2608  if( GetUpper() && !GetUpper()->IsPageBodyFrame() )
2609  {
2610  // column sections need grow/shrink
2611  if( GetUpper()->IsFlyFrame() )
2613  else
2614  {
2615  OSL_ENSURE( GetUpper()->IsSctFrame(), "NeighbourhoodAdjustment: Unexpected Upper" );
2616  if( !GetNext() && !GetPrev() )
2617  nRet = SwNeighbourAdjust::GrowAdjust; // section with a single column (FootnoteAtEnd)
2618  else
2619  {
2620  const SwFrame* pTmp = Lower();
2621  OSL_ENSURE( pTmp, "NeighbourhoodAdjustment: Missing Lower()" );
2622  if( !pTmp->GetNext() )
2624  else if( !GetUpper()->IsColLocked() )
2626  OSL_ENSURE( !pTmp->GetNext() || pTmp->GetNext()->IsFootnoteContFrame(),
2627  "NeighbourhoodAdjustment: Who's that guy?" );
2628  }
2629  }
2630  }
2631  return nRet;
2632 }
2633 
2635 {
2636  SwLayoutFrame *pBody = FindBodyCont();
2637  if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() )
2638  {
2639  SwColumnFrame* pCol = static_cast<SwColumnFrame*>(pBody->Lower());
2640  do
2641  {
2643  pCol = static_cast<SwColumnFrame*>(pCol->GetNext());
2644  } while ( pCol );
2645  }
2646 }
2647 
2649  SwFootnoteBossFrame *pNewBoss, const bool bFootnoteNums )
2650 {
2651  SwDoc *pDoc = GetFormat()->GetDoc();
2652  if ( pDoc->GetFootnoteIdxs().empty() )
2653  return false;
2654  if( pDoc->GetFootnoteInfo().m_ePos == FTNPOS_CHAPTER &&
2655  ( !IsInSct() || !FindSctFrame()->IsFootnoteAtEnd() ) )
2656  return true;
2657 
2658  if ( !pNewBoss )
2659  pNewBoss = FindFootnoteBossFrame( true );
2660  if ( pNewBoss == pOldBoss )
2661  return false;
2662 
2663  bool bMoved = false;
2664  if( !pStart )
2665  pStart = ContainsContent();
2666 
2667  SwFootnoteFrames aFootnoteArr;
2668 
2669  while ( IsAnLower( pStart ) )
2670  {
2671  if ( static_cast<SwTextFrame*>(pStart)->HasFootnote() )
2672  {
2673  // OD 03.04.2003 #108446# - To avoid unnecessary moves of footnotes
2674  // use new parameter <_bCollectOnlyPreviousFootnote> (4th parameter of
2675  // method <SwFootnoteBossFrame::CollectFootnote(..)>) to control, that only
2676  // footnotes have to be collected, that are positioned before the
2677  // new dedicated footnote boss frame.
2678  pNewBoss->CollectFootnotes( pStart, pOldBoss, aFootnoteArr, true );
2679  }
2680  pStart = pStart->GetNextContentFrame();
2681  }
2682 
2683  OSL_ENSURE( pOldBoss->IsInSct() == pNewBoss->IsInSct(),
2684  "MoveLowerFootnotes: Section confusion" );
2685  std::unique_ptr<SwFootnoteFrames> pFootnoteArr;
2686  SwLayoutFrame* pNewChief = nullptr;
2687  SwLayoutFrame* pOldChief = nullptr;
2688 
2689  bool bFoundCandidate = false;
2690  if (pStart && pOldBoss->IsInSct())
2691  {
2692  pOldChief = pOldBoss->FindSctFrame();
2693  pNewChief = pNewBoss->FindSctFrame();
2694  bFoundCandidate = pOldChief != pNewChief;
2695  }
2696 
2697  if (bFoundCandidate)
2698  {
2699  pFootnoteArr.reset(new SwFootnoteFrames);
2700  pOldChief = pOldBoss->FindFootnoteBossFrame( true );
2701  pNewChief = pNewBoss->FindFootnoteBossFrame( true );
2702  while( pOldChief->IsAnLower( pStart ) )
2703  {
2704  if ( static_cast<SwTextFrame*>(pStart)->HasFootnote() )
2705  static_cast<SwFootnoteBossFrame*>(pNewChief)->CollectFootnotes( pStart,
2706  pOldBoss, *pFootnoteArr );
2707  pStart = pStart->GetNextContentFrame();
2708  }
2709  if( pFootnoteArr->empty() )
2710  {
2711  pFootnoteArr.reset();
2712  }
2713  }
2714  else
2715  pFootnoteArr = nullptr;
2716 
2717  if ( !aFootnoteArr.empty() || pFootnoteArr )
2718  {
2719  if( !aFootnoteArr.empty() )
2720  pNewBoss->MoveFootnotes_( aFootnoteArr, true );
2721  if( pFootnoteArr )
2722  {
2723  assert(pNewChief);
2724  static_cast<SwFootnoteBossFrame*>(pNewChief)->MoveFootnotes_( *pFootnoteArr, true );
2725  pFootnoteArr.reset();
2726  }
2727  bMoved = true;
2728 
2729  // update FootnoteNum only at page change
2730  if ( bFootnoteNums )
2731  {
2732  SwPageFrame* pOldPage = pOldBoss->FindPageFrame();
2733  SwPageFrame* pNewPage =pNewBoss->FindPageFrame();
2734  if( pOldPage != pNewPage )
2735  {
2736  pOldPage->UpdateFootnoteNum();
2737  pNewPage->UpdateFootnoteNum();
2738  }
2739  }
2740  }
2741  return bMoved;
2742 }
2743 
2746 {
2747  OSL_ENSURE( IsInFootnote(), "no footnote." );
2748  SwLayoutFrame *pFootnote = FindFootnoteFrame();
2749 
2750  // The first paragraph in the first footnote in the first column in the
2751  // sectionfrm at the top of the page has not to move forward, if the
2752  // columnbody is empty.
2753  if( pOldBoss->IsInSct() && !pOldBoss->GetIndPrev() && !GetIndPrev() &&
2754  !pFootnote->GetPrev() )
2755  {
2756  SwLayoutFrame* pBody = pOldBoss->FindBodyCont();
2757  if( !pBody || !pBody->Lower() )
2758  return true;
2759  }
2760 
2761  //fix(9538): if the footnote has neighbors behind itself, remove them temporarily
2762  SwLayoutFrame *pNxt = static_cast<SwLayoutFrame*>(pFootnote->GetNext());
2763  SwLayoutFrame *pLst = nullptr;
2764  while ( pNxt )
2765  {
2766  while ( pNxt->GetNext() )
2767  pNxt = static_cast<SwLayoutFrame*>(pNxt->GetNext());
2768  if ( pNxt == pLst )
2769  pNxt = nullptr;
2770  else
2771  { pLst = pNxt;
2772  SwContentFrame *pCnt = pNxt->ContainsContent();
2773  if( pCnt )
2774  pCnt->MoveFootnoteCntFwd( true, pOldBoss );
2775  pNxt = static_cast<SwLayoutFrame*>(pFootnote->GetNext());
2776  }
2777  }
2778 
2779  bool bSamePage = true;
2780  SwLayoutFrame *pNewUpper =
2781  GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, true );
2782 
2783  if ( pNewUpper )
2784  {
2785  SwFootnoteBossFrame * const pNewBoss = pNewUpper->FindFootnoteBossFrame();
2786  // Are we changing the column/page?
2787  bool bSameBoss = pNewBoss == pOldBoss;
2788  if ( !bSameBoss )
2789  {
2790  bSamePage = pOldBoss->FindPageFrame() == pNewBoss->FindPageFrame(); // page change?
2791  pNewUpper->Calc(getRootFrame()->GetCurrShell()->GetOut());
2792  }
2793 
2794  // The layout leaf of the footnote is either a footnote container or a footnote.
2795  // If it is a footnote and it has the same footnote reference like the old Upper,
2796  // then move the content inside of it.
2797  // If it is a container or the reference differs, create a new footnote and add
2798  // it into the container.
2799  // Create also a SectionFrame if currently in an area inside a footnote.
2800  SwFootnoteFrame* pTmpFootnote = pNewUpper->IsFootnoteFrame() ? static_cast<SwFootnoteFrame*>(pNewUpper) : nullptr;
2801  if (!pTmpFootnote && pNewUpper->IsFootnoteContFrame())
2802  {
2803  SwFootnoteContFrame *pCont = static_cast<SwFootnoteContFrame*>(pNewUpper);
2804  pTmpFootnote = SwFootnoteContFrame::AppendChained(this, true);
2805  SwFrame* pNx = pCont->Lower();
2806  if( pNx && pTmpFootnote->GetAttr()->GetFootnote().IsEndNote() )
2807  while(pNx && !static_cast<SwFootnoteFrame*>(pNx)->GetAttr()->GetFootnote().IsEndNote())
2808  pNx = pNx->GetNext();
2809  pTmpFootnote->Paste( pCont, pNx );
2810  pTmpFootnote->Calc(getRootFrame()->GetCurrShell()->GetOut());
2811  }
2812  OSL_ENSURE( pTmpFootnote->GetAttr() == FindFootnoteFrame()->GetAttr(), "Wrong Footnote!" );
2813  // areas inside of footnotes get a special treatment
2814  SwLayoutFrame *pNewUp = pTmpFootnote;
2815  if( IsInSct() )
2816  {
2817  SwSectionFrame* pSect = FindSctFrame();
2818  // area inside of a footnote (or only footnote in an area)?
2819  if( pSect->IsInFootnote() )
2820  {
2821  if( pTmpFootnote->Lower() && pTmpFootnote->Lower()->IsSctFrame() &&
2822  pSect->GetFollow() == static_cast<SwSectionFrame*>(pTmpFootnote->Lower()) )
2823  pNewUp = static_cast<SwSectionFrame*>(pTmpFootnote->Lower());
2824  else
2825  {
2826  pNewUp = new SwSectionFrame( *pSect, false );
2827  pNewUp->InsertBefore( pTmpFootnote, pTmpFootnote->Lower() );
2828  static_cast<SwSectionFrame*>(pNewUp)->Init();
2829 
2830  {
2832  aFrm.Pos() = pTmpFootnote->getFrameArea().Pos();
2833  aFrm.Pos().AdjustY(1 ); // for notifications
2834  }
2835 
2836  // If the section frame has a successor then the latter needs
2837  // to be moved behind the new Follow of the section frame.
2838  SwFrame* pTmp = pSect->GetNext();
2839  if( pTmp )
2840  {
2841  SwFlowFrame* pTmpNxt;
2842  if( pTmp->IsContentFrame() )
2843  pTmpNxt = static_cast<SwContentFrame*>(pTmp);
2844  else if( pTmp->IsSctFrame() )
2845  pTmpNxt = static_cast<SwSectionFrame*>(pTmp);
2846  else
2847  {
2848  OSL_ENSURE( pTmp->IsTabFrame(), "GetNextSctLeaf: Wrong Type" );
2849  pTmpNxt = static_cast<SwTabFrame*>(pTmp);
2850  }
2851  pTmpNxt->MoveSubTree( pTmpFootnote, pNewUp->GetNext() );
2852  }
2853  }
2854  }
2855  }
2856 
2857  MoveSubTree( pNewUp, pNewUp->Lower() );
2858 
2859  if( !bSameBoss )
2861  }
2862  return bSamePage;
2863 }
2864 
2866  pBoss( pBs ),
2867  nOldHeight( pBs->GetMaxFootnoteHeight() )
2868 {
2869  pBoss->SetFootnoteDeadLine( nDeadLine );
2871 }
2872 
2874 {
2875  // If somebody tweaked the deadline meanwhile, we let it happen
2878 }
2879 
2880 #ifdef DBG_UTIL
2881 //JP 15.10.2001: in a non pro version test if the attribute has the same
2882 // meaning which his reference is
2883 
2884 // Normally, the pRef member and the GetRefFromAttr() result has to be
2885 // identically. Sometimes footnote will be moved from a master to its follow,
2886 // but the GetRef() is called first, so we have to ignore a master/follow
2887 // mismatch.
2888 
2890 {
2891  const SwContentFrame* pRefAttr = GetRefFromAttr();
2892  // check consistency: access to deleted frame?
2893  assert(mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr)
2894  || pRefAttr->IsAnFollow(mpReference));
2895  (void) pRefAttr;
2896  return mpReference;
2897 }
2898 
2900 {
2901  const SwContentFrame* pRefAttr = GetRefFromAttr();
2902  // check consistency: access to deleted frame?
2903  assert(mpReference == pRefAttr || mpReference->IsAnFollow(pRefAttr)
2904  || pRefAttr->IsAnFollow(mpReference));
2905  (void) pRefAttr;
2906  return mpReference;
2907 }
2908 #endif
2909 
2911 {
2912  SwFootnoteFrame* pThis = const_cast<SwFootnoteFrame*>(this);
2913  return pThis->GetRefFromAttr();
2914 }
2915 
2917 {
2918  assert(mpAttribute && "invalid Attribute");
2919  SwTextNode& rTNd = const_cast<SwTextNode&>(mpAttribute->GetTextNode());
2920  SwPosition aPos( rTNd, SwIndex( &rTNd, mpAttribute->GetStart() ));
2921  SwContentFrame* pCFrame = rTNd.getLayoutFrame(getRootFrame(), &aPos);
2922  return pCFrame;
2923 }
2924 
2930 {
2931  SwContentFrame* pLastContentFrame( nullptr );
2932 
2933  // find last lower, which is a content frame or contains content.
2934  // hidden text frames, empty sections and empty tables have to be skipped.
2935  SwFrame* pLastLowerOfFootnote( GetLower() );
2936  SwFrame* pTmpLastLower( pLastLowerOfFootnote );
2937  while ( pTmpLastLower && pTmpLastLower->GetNext() )
2938  {
2939  pTmpLastLower = pTmpLastLower->GetNext();
2940  if ( ( pTmpLastLower->IsTextFrame() &&
2941  !static_cast<SwTextFrame*>(pTmpLastLower)->IsHiddenNow() ) ||
2942  ( pTmpLastLower->IsSctFrame() &&
2943  static_cast<SwSectionFrame*>(pTmpLastLower)->GetSection() &&
2944  static_cast<SwSectionFrame*>(pTmpLastLower)->ContainsContent() ) ||
2945  ( pTmpLastLower->IsTabFrame() &&
2946  static_cast<SwTabFrame*>(pTmpLastLower)->ContainsContent() ) )
2947  {
2948  pLastLowerOfFootnote = pTmpLastLower;
2949  }
2950  }
2951 
2952  // determine last content frame depending on type of found last lower.
2953  if ( pLastLowerOfFootnote && pLastLowerOfFootnote->IsTabFrame() )
2954  {
2955  pLastContentFrame = static_cast<SwTabFrame*>(pLastLowerOfFootnote)->FindLastContent();
2956  }
2957  else if ( pLastLowerOfFootnote && pLastLowerOfFootnote->IsSctFrame() )
2958  {
2959  pLastContentFrame = static_cast<SwSectionFrame*>(pLastLowerOfFootnote)->FindLastContent();
2960  }
2961  else
2962  {
2963  pLastContentFrame = dynamic_cast<SwContentFrame*>(pLastLowerOfFootnote);
2964  }
2965 
2966  return pLastContentFrame;
2967 }
2968 
2969 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void InsertBefore(SwLayoutFrame *pParent, SwFrame *pBehind)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:827
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:2865
void SetTop(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1367
Base class of the Writer layout elements.
Definition: frame.hxx:298
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:157
SwFootnoteContFrame * FindNearestFootnoteCont(bool bDontLeave=false)
Search the next available footnote container.
Definition: ftnfrm.cxx:1047
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:1379
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:1443
bool IsEndnAtEnd() const
Definition: sectfrm.hxx:146
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:98
bool IsInDocBody() const
Definition: frame.hxx:924
void Init()
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1491
bool IsInSct() const
Definition: frame.hxx:948
void RemoveFootnotes(SwPageFrame *pPage=nullptr, bool bPageOnly=false, bool bEndNotes=false)
Remove all footnotes (but no references)
Definition: ftnfrm.cxx:960
static void SetMoveBwdJump(bool bNew)
Definition: flowfrm.hxx:155
tools::Long BottomDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1395
bool MoveFootnoteCntFwd(bool, SwFootnoteBossFrame *)
Return value guarantees that a new page was not created. See SwFlowFrame::MoveFwd.
Definition: ftnfrm.cxx:2745
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:1055
bool IsColLocked() const
Definition: frame.hxx:867
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:1818
static SwFootnoteFrame * FindFootnote(const SwContentFrame *, const SwTextFootnote *)
Definition: ftnfrm.cxx:1682
void SetCompletePaint() const
Definition: frame.hxx:975
void SetMaster(SwFootnoteFrame *pNew)
Definition: ftnfrm.hxx:126
bool IsInFootnote() const
Definition: frame.hxx:930
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:594
sal_uInt16 char char * pDesc
sal_uIntPtr sal_uLong
long Long
const SwRect & getFramePrintArea() const
Definition: frame.hxx:179
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:2713
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:30
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1212
#define ENDNOTE
Definition: ftnfrm.cxx:43
void InvalidateSize_()
Definition: frame.hxx:754
Definition: doc.hxx:187
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:2634
void SetMaxFootnoteHeight(const SwTwips nNewMax)
Definition: ftnboss.hxx:77
TElementType * Next()
Definition: calbck.hxx:333
void UpdateFootnoteNum()
Definition: ftnfrm.cxx:2418
void InsertFootnote(SwFootnoteFrame *)
Definition: ftnfrm.cxx:1221
void InvalidatePos()
Definition: frame.hxx:1024
const_iterator find(const Value &x) const
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: wsfrm.cxx:1325
static void ChangeFootnoteRef(const SwContentFrame *pOld, const SwTextFootnote *, SwContentFrame *pNew)
Definition: ftnfrm.cxx:1750
void SubTop(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1374
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:169
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:1122
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:183
void InvalidateNxtFootnoteCnts(SwPageFrame const *pPage)
Definition: ftnfrm.cxx:496
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1362
void KeepLockPosOfLowerObjs()
Definition: ftnfrm.hxx:144
void RearrangeFootnotes(const SwTwips nDeadLine, const bool bLock, const SwTextFootnote *pAttr=nullptr)
Definition: ftnfrm.cxx:2201
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2704
void AddBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1375
SwFootnoteContFrame(SwFrameFormat *, SwFrame *)
Definition: ftnfrm.cxx:151
bool IsFootnoteFrame() const
Definition: frame.hxx:1183
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:2736
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:170
SwTwips GetTopDist() const
Definition: pagedesc.hxx:67
tools::Long TopDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1394
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:188
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1358
SwSectionFrame * ImplFindSctFrame()
Definition: findfrm.cxx:481
void SetFootnoteDeadLine(const SwTwips nDeadLine)
Definition: ftnfrm.cxx:2496
void SetRetouche() const
Definition: frame.hxx:984
const SwPageFootnoteInfo & GetFootnoteInfo() const
Definition: pagedesc.hxx:206
bool IsFlyFrame() const
Definition: frame.hxx:1191
void sw_RemoveFootnotes(SwFootnoteBossFrame *pBoss, bool bPageOnly, bool bEndNotes)
remove all footnotes (not the references) and all footnote pages
Definition: ftnfrm.cxx:906
void MoveFootnotes_(SwFootnoteFrames &rFootnoteArr, bool bCalc=false)
Definition: ftnfrm.cxx:1955
const SwRect & getFrameArea() const
Definition: frame.hxx:178
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1024
bool getBrowseMode() const
Definition: viewopt.hxx:472
bool IsEmptyPage() const
Definition: pagefrm.hxx:141
SwTextFootnote * mpAttribute
Definition: ftnfrm.hxx:88
bool IsInTab() const
Definition: frame.hxx:936
const SwPageFrame * GetLastPage() const
Definition: rootfrm.hxx:361
bool IsTextFrame() const
Definition: frame.hxx:1215
sal_Int32 GetStart() const
Definition: txatbase.hxx:86
void SetSuperfluous()
Remove superfluous Pages.
Definition: rootfrm.hxx:300
void setFramePrintAreaValid(bool bNew)
Definition: wsfrm.cxx:99
bool OnRightPage() const
Definition: frame.hxx:716
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:1195
void AppendFootnote(SwContentFrame *, SwTextFootnote *)
Definition: ftnfrm.cxx:1501
SwNeighbourAdjust NeighbourhoodAdjustment_() const
Obtain if pFrame's size adjustment should be processed.
Definition: ftnfrm.cxx:2605
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:1571
bool IsDescendantFrom(const SwSectionFormat *pSect) const
Definition: sectfrm.cxx:2512
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:675
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr)=0
bool IsFootnoteLock() const
Definition: sectfrm.hxx:155
virtual void Cut()=0
bool IsColumnFrame() const
Definition: frame.hxx:1163
void SetNumber(sal_uInt16 nNumber, sal_uInt16 nNumberRLHidden, const OUString &sNumStr)
Definition: atrftn.cxx:361
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1088
SwTabFrame * ImplFindTabFrame()
Definition: findfrm.cxx:469
Style of a layout element.
Definition: frmfmt.hxx:58
bool IsContentFrame() const
Definition: frame.hxx:1211
static void FootnoteInArr(SwFootnoteFrames &rFootnoteArr, SwFootnoteFrame *pFootnote)
Definition: ftnfrm.cxx:1812
SwFrame * GetIndPrev() const
Definition: frame.hxx:707
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1391
const SwFrame * GetLastLower() const
Definition: findfrm.cxx:1829
const SwSectionFrame * GetFollow() const
Definition: sectfrm.hxx:158
SwPageFrame * FindPageFrame()
Definition: frame.hxx:663
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:868
SwFrame * m_pLower
Definition: layfrm.hxx:53
virtual void Cut() override
Definition: wsfrm.cxx:1422
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:191
TElementType * First()
Definition: calbck.hxx:325
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:127
SwTwips AdjustNeighbourhood(SwTwips nDiff, bool bTst=false)
Adjust surrounding neighbourhood after insertion.
Definition: wsfrm.cxx:1597
SwContentNode * GetContentNode()
Definition: node.hxx:619
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:604
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1363
SwLayoutFrame * GetUpper()
Definition: frame.hxx:661
sal_uInt16 GetNumberRLHidden() const
Definition: fmtftn.hxx:70
void AddHeight(const tools::Long nAdd)
Definition: swrect.cxx:161
bool isFramePrintAreaValid() const
Definition: frame.hxx:167
SwFootnoteFrame * FindFirstFootnote()
Definition: ftnfrm.cxx:1070
Marks a character position inside a document model node.
Definition: index.hxx:33
::rtl::Reference< Content > pContent
bool IsEndNotePage() const
Definition: pagefrm.hxx:184
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:1390
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:660
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:2092
void UnlockBackMove()
Definition: ftnfrm.hxx:132
const_iterator end() const
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1404
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:166
SwContentFrame * FindLastContent(SwFindMode nMode=SwFindMode::None)
Definition: sectfrm.cxx:908
void InvalidatePos_()
Definition: frame.hxx:770
SwFootnoteContFrame * MakeFootnoteCont()
Insert a footnote container.
Definition: ftnfrm.cxx:1014
void UpdateFootnoteNums()
Update the footnote numbers of all Pages.
Definition: ftnfrm.cxx:891
A page of the document layout.
Definition: pagefrm.hxx:41
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:204
void LockBackMove()
Definition: ftnfrm.hxx:131
tools::Long SwTwips
Definition: swtypes.hxx:49
static sal_uInt16 nPgNum
Definition: viewport.cxx:50
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:1536
void InvalidateSize()
Definition: frame.hxx:1010
SwLayoutFrame * GetPrevFootnoteLeaf(MakePageType eMakeFootnote)
Get the preceding layout leaf in that the frame can be moved.
Definition: ftnfrm.cxx:737
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1096
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:746
const_iterator begin() const
tools::Long const nBorder
bool RemoveFootnote(const SwContentFrame *, const SwTextFootnote *, bool bPrep=true)
Definition: ftnfrm.cxx:1722
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:1764
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:1151
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:2143
static void ResetFootnote(const SwFootnoteFrame *pAssumed)
Definition: ftnfrm.cxx:1181
void SetRef(SwContentFrame *pNew)
Definition: ftnfrm.hxx:127
void SetWidth(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1371
SwContentFrame * FindLastBodyContent()
Searches the last ContentFrame in BodyText below the page.
Definition: findfrm.cxx:52
bool IsVertLR() const
Definition: frame.hxx:960
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:2524
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:994
MakePageType
Definition: frame.hxx:111
SwPageDesc * GetPageDesc(SwDoc &rDoc) const
Definition: docftn.cxx:105
bool IsTabFrame() const
Definition: frame.hxx:1199
static SwPageFrame * lcl_GetApproximateFootnotePage(const bool bEnd, const SwPageFrame *pPage, const SwDoc *pDoc, const SwTextFootnote *pAttr)
Definition: ftnfrm.cxx:1474
virtual SwTwips ShrinkFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: wsfrm.cxx:2781
#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:2648
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:134
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1372
void RemoveFromLayout()
Definition: wsfrm.cxx:1004
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
const SwFootnoteFrame * GetFollow() const
Definition: ftnfrm.hxx:116
const SwDoc * GetDoc() const
Definition: swatrset.hxx:204
SwPageFrame * InsertNewPage(SwPageDesc &rDesc, SwFrame *pUpper, bool isRightPage, bool bFirst, bool bInsertEmpty, bool bFootnote, SwFrame *pSibling, bool bVeryFirstPage=false)
Definition: frmtool.cxx:3055
SwTwips m_nMaxFootnoteHeight
Definition: ftnboss.hxx:56
void InvalidateNextPos(bool bNoFootnote=false)
Definition: frame.hxx:1053
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:2889
SwFrameType mnFrameType
Definition: frame.hxx:398
bool IsPageFrame() const
Definition: frame.hxx:1159
bool IsFootnoteAllowed() const
Definition: ftnfrm.cxx:875
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:2163
virtual void Cut() override
Definition: sectfrm.cxx:250
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:420
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:2910
SwLayoutFrame * GetNextFootnoteLeaf(MakePageType eMakePage)
Return the next layout leaf in that the frame can be moved.
Definition: ftnfrm.cxx:655
bool IsVertical() const
Definition: frame.hxx:954
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1359
void InvalidatePrt_()
Definition: frame.hxx:762
SwNodeIndex * GetStartNode() const
Definition: txtftn.hxx:41
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:633
SwFootnotePos m_ePos
Definition: ftninfo.hxx:97
bool IsFootnoteAtEnd() const
Definition: sectfrm.hxx:145
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:3160
bool IsFootnoteBossFrame() const
Definition: frame.hxx:1167
void ColUnlock()
Definition: ftnfrm.hxx:137
SwTwips FootnoteSeparatorHeight(SwPageFootnoteInfo const &rInf)
Definition: ftnfrm.cxx:222
SwPageFrame * InsertPage(SwPageFrame *pSibling, bool bFootnote)
Definition: pagechg.cxx:1350
bool IsFootnoteContFrame() const
Definition: frame.hxx:1179
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:186
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:208
void Height(tools::Long nNew)
Definition: swrect.hxx:191
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:629
SwRootFrame * getRootFrame()
Definition: frame.hxx:662
const SwEndNoteInfo & GetEndNoteInfo() const
Definition: doc.hxx:631
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:5616
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:395
SwFrame * GetNext()
Definition: frame.hxx:659
SwContentFrame * FindLastContent()
search for last content in the current footnote frame
Definition: ftnfrm.cxx:2929
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo