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