1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ftnfrm.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
38 #include <pagefrm.hxx>
40 #include <rootfrm.hxx>
44 #include <frmtool.hxx>
45 #include <swtable.hxx>
49 #include <pagedesc.hxx>
50 #include <ftninfo.hxx>
51 #include <ndindex.hxx>
52 #include <sectfrm.hxx>
54 // --> OD 2005-05-17 #i49383#
55 #include <objectformatter.hxx>
58 /*************************************************************************
60 |* lcl_FindFtnPos() Sucht die Position des Attributes im FtnArray am
61 |* Dokument, dort stehen die Fussnoten gluecklicherweise nach ihrem
64 |* Ersterstellung MA 29. Jun. 93
65 |* Letzte Aenderung MA 13. Dec. 93
67 |*************************************************************************/
69 #define ENDNOTE 0x80000000
71 ULONG MA_FASTCALL
lcl_FindFtnPos( const SwDoc
*pDoc
, const SwTxtFtn
*pAttr
)
73 const SwFtnIdxs
&rFtnIdxs
= pDoc
->GetFtnIdxs();
76 //Wenn das Array nicht stimmt haben wir ein Problem, denn viele
77 //Ftn-Functions bauen auf dem Array auf.
78 for ( USHORT k
= 0; k
+1 < rFtnIdxs
.Count(); ++k
)
80 SwIndex
aIdx1(&pDoc
->GetNodes());
81 SwIndex
aIdx2(&pDoc
->GetNodes());
82 rFtnIdxs
[k
]->pFtn
-> GetTxtNode().GetIndex(aIdx1
);
83 rFtnIdxs
[k
+1]->pFtn
->GetTxtNode().GetIndex(aIdx2
);
84 if ( aIdx1
.GetIndex() > aIdx2
.GetIndex() )
86 ASSERT( !rFtnIdxs
.Count(), "FtnIdxs not up to date" );
88 else if ( aIdx1
.GetIndex() == aIdx2
.GetIndex() )
90 SwTxtFtn
*p1
= rFtnIdxs
[k
];
91 SwTxtFtn
*p2
= rFtnIdxs
[k
+1];
92 ASSERT( *p1
->GetStart() < *p2
->GetStart(),
93 "FtnIdxs not up to date" );
99 SwTxtFtnPtr pBla
= (SwTxtFtn
*)pAttr
;
100 if ( rFtnIdxs
.Seek_Entry( pBla
, &nRet
) )
102 if( pAttr
->GetFtn().IsEndNote() )
103 return ULONG(nRet
) + ENDNOTE
;
106 ASSERT( !pDoc
, "FtnPos not found." );
110 BOOL
SwFtnFrm::operator<( const SwTxtFtn
* pTxtFtn
) const
112 const SwDoc
* pDoc
= GetFmt()->GetDoc();
113 ASSERT( pDoc
, "SwFtnFrm: Missing doc!" );
114 return lcl_FindFtnPos( pDoc
, GetAttr() ) <
115 lcl_FindFtnPos( pDoc
, pTxtFtn
);
118 /*************************************************************************
120 |* BOOL lcl_NextFtnBoss( SwFtnBossFrm* pBoss, SwPageFrm* pPage)
121 |* setzt pBoss auf den naechsten SwFtnBossFrm, das kann entweder eine Spalte
122 |* oder eine Seite (ohne Spalten) sein. Wenn die Seite dabei gewechselt wird
123 |* enthaelt pPage die neue Seite und die Funktion liefert TRUE.
125 |* Ersterstellung AMA 06. Nov. 98
126 |* Letzte Aenderung AMA 06. Nov. 98
128 |*************************************************************************/
130 BOOL
lcl_NextFtnBoss( SwFtnBossFrm
* &rpBoss
, SwPageFrm
* &rpPage
,
133 if( rpBoss
->IsColumnFrm() )
135 if( rpBoss
->GetNext() )
137 rpBoss
= (SwFtnBossFrm
*)rpBoss
->GetNext(); //naechste Spalte
140 if( rpBoss
->IsInSct() )
142 SwSectionFrm
* pSct
= rpBoss
->FindSctFrm()->GetFollow();
145 ASSERT( pSct
->Lower() && pSct
->Lower()->IsColumnFrm(),
146 "Where's the column?" );
147 rpBoss
= (SwColumnFrm
*)pSct
->Lower();
148 SwPageFrm
* pOld
= rpPage
;
149 rpPage
= pSct
->FindPageFrm();
150 return pOld
!= rpPage
;
152 else if( bDontLeave
)
160 rpPage
= (SwPageFrm
*)rpPage
->GetNext(); // naechste Seite
164 SwLayoutFrm
* pBody
= rpPage
->FindBodyCont();
165 if( pBody
&& pBody
->Lower() && pBody
->Lower()->IsColumnFrm() )
166 rpBoss
= (SwFtnBossFrm
*)pBody
->Lower(); // erste Spalte
171 /*************************************************************************
173 |* USHORT lcl_ColumnNum( SwFrm* pBoss )
174 |* liefert die Spaltennummer, wenn pBoss eine Spalte ist,
175 |* sonst eine Null (bei Seiten).
177 |* Ersterstellung AMA 06. Nov. 98
178 |* Letzte Aenderung AMA 06. Nov. 98
180 |*************************************************************************/
182 USHORT
lcl_ColumnNum( const SwFrm
* pBoss
)
185 if( !pBoss
->IsColumnFrm() )
188 if( pBoss
->IsInSct() )
190 pCol
= pBoss
->GetUpper()->FindColFrm();
191 if( pBoss
->GetNext() || pBoss
->GetPrev() )
195 ++nRet
; // Section columns
196 pBoss
= pBoss
->GetPrev();
204 nRet
+= 256; // Page columns
205 pCol
= pCol
->GetPrev();
210 /*************************************************************************
212 |* SwFtnContFrm::SwFtnContFrm()
214 |* Ersterstellung MA 24. Feb. 93
215 |* Letzte Aenderung MA 02. Mar. 93
217 |*************************************************************************/
220 SwFtnContFrm::SwFtnContFrm( SwFrmFmt
*pFmt
):
223 nType
= FRMC_FTNCONT
;
227 // lcl_Undersize(..) klappert einen SwFrm und dessen Inneres ab
228 // und liefert die Summe aller TxtFrm-Vergroesserungswuensche
230 long lcl_Undersize( const SwFrm
* pFrm
)
234 if( pFrm
->IsTxtFrm() )
236 if( ((SwTxtFrm
*)pFrm
)->IsUndersized() )
238 // Dieser TxtFrm waere gern ein bisschen groesser
239 nRet
= ((SwTxtFrm
*)pFrm
)->GetParHeight() -
240 (pFrm
->Prt().*fnRect
->fnGetHeight
)();
245 else if( pFrm
->IsLayoutFrm() )
247 const SwFrm
* pNxt
= ((SwLayoutFrm
*)pFrm
)->Lower();
250 nRet
+= lcl_Undersize( pNxt
);
251 pNxt
= pNxt
->GetNext();
257 /*************************************************************************
259 |* SwFtnContFrm::Format()
261 |* Beschreibung: "Formatiert" den Frame;
262 |* Die Fixsize wird hier nicht eingestellt.
263 |* Ersterstellung MA 01. Mar. 93
264 |* Letzte Aenderung MA 17. Nov. 98
266 |*************************************************************************/
269 void SwFtnContFrm::Format( const SwBorderAttrs
* )
271 //GesamtBorder ermitteln, es gibt nur einen Abstand nach oben.
272 const SwPageFrm
* pPage
= FindPageFrm();
273 const SwPageFtnInfo
&rInf
= pPage
->GetPageDesc()->GetFtnInfo();
274 const SwTwips nBorder
= rInf
.GetTopDist() + rInf
.GetBottomDist() +
277 if ( !bValidPrtArea
)
279 bValidPrtArea
= TRUE
;
280 (Prt().*fnRect
->fnSetTop
)( nBorder
);
281 (Prt().*fnRect
->fnSetWidth
)( (Frm().*fnRect
->fnGetWidth
)() );
282 (Prt().*fnRect
->fnSetHeight
)((Frm().*fnRect
->fnGetHeight
)() - nBorder
);
283 if( (Prt().*fnRect
->fnGetHeight
)() < 0 && !pPage
->IsFtnPage() )
289 if ( pPage
->IsFtnPage() && !GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
290 Grow( LONG_MAX
, FALSE
);
293 //Die Groesse in der VarSize wird durch den Inhalt plus den
295 SwTwips nRemaining
= 0;
296 SwFrm
*pFrm
= pLower
;
298 { // lcl_Undersize(..) beruecksichtigt (rekursiv) TxtFrms, die gerne
299 // groesser waeren. Diese entstehen insbesondere in spaltigen Rahmen,
300 // wenn diese noch nicht ihre maximale Groesse haben.
301 nRemaining
+= (pFrm
->Frm().*fnRect
->fnGetHeight
)()
302 + lcl_Undersize( pFrm
);
303 pFrm
= pFrm
->GetNext();
305 //Jetzt noch den Rand addieren
306 nRemaining
+= nBorder
;
311 nDiff
= -(Frm().*fnRect
->fnBottomDist
)(
312 (GetUpper()->*fnRect
->fnGetPrtBottom
)() );
315 if( nDiff
> (Frm().*fnRect
->fnGetHeight
)() )
316 nDiff
= (Frm().*fnRect
->fnGetHeight
)();
317 (Frm().*fnRect
->fnAddBottom
)( -nDiff
);
318 (Prt().*fnRect
->fnAddHeight
)( -nDiff
);
321 nDiff
= (Frm().*fnRect
->fnGetHeight
)() - nRemaining
;
324 else if ( nDiff
< 0 )
327 //Es kann passieren, dass weniger Platz zur Verfuegung steht,
328 //als der bereits der Border benoetigt - die Groesse der
329 //PrtArea wird dann negativ.
330 SwTwips nPrtHeight
= (Prt().*fnRect
->fnGetHeight
)();
333 const SwTwips nTmpDiff
= Max( (Prt().*fnRect
->fnGetTop
)(),
335 (Prt().*fnRect
->fnSubTop
)( nTmpDiff
);
342 /*************************************************************************
344 |* SwFtnContFrm::GrowFrm(), ShrinkFrm()
346 |* Ersterstellung MA 24. Feb. 93
347 |* Letzte Aenderung AMA 05. Nov. 98
349 |*************************************************************************/
351 SwTwips
SwFtnContFrm::GrowFrm( SwTwips nDist
, BOOL bTst
, BOOL
)
353 //Keine Pruefung ob FixSize oder nicht, die FtnContainer sind immer bis
354 //zur Maximalhoehe variabel.
355 //Wenn die Maximalhoehe LONG_MAX ist, so nehmen wir uns soviel Platz wie eben
357 //Wenn die Seite eine spezielle Fussnotenseite ist, so nehmen wir uns auch
358 //soviel Platz wie eben moeglich.
360 if ( !GetUpper() || !GetUpper()->IsFtnBossFrm() )
361 { ASSERT( !this, "Keine FtnBoss." );
367 if( (Frm().*fnRect
->fnGetHeight
)() > 0 &&
368 nDist
> ( LONG_MAX
- (Frm().*fnRect
->fnGetHeight
)() ) )
369 nDist
= LONG_MAX
- (Frm().*fnRect
->fnGetHeight
)();
371 SwFtnBossFrm
*pBoss
= (SwFtnBossFrm
*)GetUpper();
374 SwSectionFrm
* pSect
= FindSctFrm();
375 ASSERT( pSect
, "GrowFrm: Missing SectFrm" );
376 // In a section, which has to maximize, a footnotecontainer is allowed
377 // to grow, when the section can't grow anymore.
378 if( !bTst
&& !pSect
->IsColLocked() &&
379 pSect
->ToMaximize( FALSE
) && pSect
->Growable() )
381 pSect
->InvalidateSize();
385 const bool bBrowseMode
= GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
);
386 SwPageFrm
*pPage
= pBoss
->FindPageFrm();
387 if ( bBrowseMode
|| !pPage
->IsFtnPage() )
389 if ( pBoss
->GetMaxFtnHeight() != LONG_MAX
)
391 nDist
= Min( nDist
, pBoss
->GetMaxFtnHeight()
392 - (Frm().*fnRect
->fnGetHeight
)() );
396 //Der FtnBoss will bezueglich des MaxWerts auch noch mitreden.
399 const SwTwips nMax
= pBoss
->GetVarSpace();
406 else if( nDist
> (GetPrev()->Frm().*fnRect
->fnGetHeight
)() )
407 //aber mehr als der Body kann koennen und wollen wir nun auch wieder
408 //nicht herausruecken.
409 nDist
= (GetPrev()->Frm().*fnRect
->fnGetHeight
)();
414 nAvail
= GetUpper()->Prt().Height();
415 const SwFrm
*pAvail
= GetUpper()->Lower();
417 { nAvail
-= pAvail
->Frm().Height();
418 pAvail
= pAvail
->GetNext();
420 if ( nAvail
> nDist
)
426 (Frm().*fnRect
->fnSetHeight
)( (Frm().*fnRect
->fnGetHeight
)() + nDist
);
427 if( IsVertical() && !IsReverse() )
428 Frm().Pos().X() -= nDist
;
430 long nGrow
= nDist
- nAvail
,
434 BYTE nAdjust
= pBoss
->NeighbourhoodAdjustment( this );
435 if( NA_ONLY_ADJUST
== nAdjust
)
436 nReal
= AdjustNeighbourhood( nGrow
, bTst
);
439 if( NA_GROW_ADJUST
== nAdjust
)
441 SwFrm
* pFtn
= Lower();
444 while( pFtn
->GetNext() )
445 pFtn
= pFtn
->GetNext();
446 if( ((SwFtnFrm
*)pFtn
)->GetAttr()->GetFtn().IsEndNote() )
448 nReal
= AdjustNeighbourhood( nGrow
, bTst
);
449 nAdjust
= NA_GROW_SHRINK
; // no more AdjustNeighbourhood
453 nReal
+= pBoss
->Grow( nGrow
- nReal
, bTst
);
454 if( ( NA_GROW_ADJUST
== nAdjust
|| NA_ADJUST_GROW
== nAdjust
)
456 nReal
+= AdjustNeighbourhood( nGrow
- nReal
, bTst
);
464 if ( nReal
!= nDist
)
467 //Den masslosen Wunsch koennen wir leider nur in Grenzen erfuellen.
468 Frm().SSize().Height() -= nDist
;
469 if( IsVertical() && !IsReverse() )
470 Frm().Pos().X() += nDist
;
473 //Nachfolger braucht nicht invalidiert werden, denn wir wachsen
479 InvalidatePage( pPage
);
486 SwTwips
SwFtnContFrm::ShrinkFrm( SwTwips nDiff
, BOOL bTst
, BOOL bInfo
)
488 SwPageFrm
*pPage
= FindPageFrm();
490 ( !pPage
->IsFtnPage() ||
491 GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) ) )
493 SwTwips nRet
= SwLayoutFrm::ShrinkFrm( nDiff
, bTst
, bInfo
);
494 if( IsInSct() && !bTst
)
495 FindSctFrm()->InvalidateNextPos();
499 InvalidatePage( pPage
);
507 /*************************************************************************
509 |* SwFtnFrm::SwFtnFrm()
511 |* Ersterstellung MA 24. Feb. 93
512 |* Letzte Aenderung MA 11. Oct. 93
514 |*************************************************************************/
517 SwFtnFrm::SwFtnFrm( SwFrmFmt
*pFmt
, SwCntntFrm
*pCnt
, SwTxtFtn
*pAt
):
523 bBackMoveLocked( FALSE
),
524 // --> OD 2005-08-11 #i49383#
525 mbUnlockPosOfLowerObjs( true )
531 /*************************************************************************
533 |* SwFtnFrm::InvalidateNxtFtnCnts()
535 |* Ersterstellung MA 29. Jun. 93
536 |* Letzte Aenderung MA 29. Jun. 93
538 |*************************************************************************/
541 void SwFtnFrm::InvalidateNxtFtnCnts( SwPageFrm
*pPage
)
545 SwFrm
*pCnt
= ((SwLayoutFrm
*)GetNext())->ContainsAny();
548 pCnt
->InvalidatePage( pPage
);
549 pCnt
->_InvalidatePrt();
551 { pCnt
->_InvalidatePos();
552 if( pCnt
->IsSctFrm() )
554 SwFrm
* pTmp
= ((SwSectionFrm
*)pCnt
)->ContainsAny();
556 pTmp
->_InvalidatePos();
558 pCnt
->GetUpper()->_InvalidateSize();
559 pCnt
= pCnt
->FindNext();
560 } while ( pCnt
&& GetUpper()->IsAnLower( pCnt
) );
567 SwTwips
SwFtnFrm::GrowFrm( SwTwips nDist
, BOOL bTst
, BOOL bInfo
)
569 #if OSL_DEBUG_LEVEL > 1
570 static USHORT nNum
= USHRT_MAX
;
571 SwTxtFtn
* pTxtFtn
= GetAttr();
572 if ( pTxtFtn
->GetFtn().GetNumber() == nNum
)
579 return SwLayoutFrm::GrowFrm( nDist
, bTst
, bInfo
);
583 SwTwips
SwFtnFrm::ShrinkFrm( SwTwips nDist
, BOOL bTst
, BOOL bInfo
)
585 #if OSL_DEBUG_LEVEL > 1
586 static USHORT nNum
= USHRT_MAX
;
587 if( nNum
!= USHRT_MAX
)
589 SwTxtFtn
* pTxtFtn
= GetAttr();
590 if( &pTxtFtn
->GetAttr() && pTxtFtn
->GetFtn().GetNumber() == nNum
)
597 return SwLayoutFrm::ShrinkFrm( nDist
, bTst
, bInfo
);
601 /*************************************************************************
605 |* Ersterstellung MA 23. Feb. 94
606 |* Letzte Aenderung MA 24. Jul. 95
608 |*************************************************************************/
614 GetNext()->InvalidatePos();
615 else if ( GetPrev() )
616 GetPrev()->SetRetouche();
618 //Erst removen, dann Upper Shrinken.
619 SwLayoutFrm
*pUp
= GetUpper();
621 //Verkettung korrigieren.
622 SwFtnFrm
*pFtn
= (SwFtnFrm
*)this;
623 if ( pFtn
->GetFollow() )
624 pFtn
->GetFollow()->SetMaster( pFtn
->GetMaster() );
625 if ( pFtn
->GetMaster() )
626 pFtn
->GetMaster()->SetFollow( pFtn
->GetFollow() );
627 pFtn
->SetFollow( 0 );
628 pFtn
->SetMaster( 0 );
630 // Alle Verbindungen kappen.
635 //Die letzte Fussnote nimmt ihren Container mit.
638 SwPageFrm
*pPage
= pUp
->FindPageFrm();
641 SwLayoutFrm
*pBody
= pPage
->FindBodyCont();
642 if ( !pBody
->ContainsCntnt() )
643 pPage
->FindRootFrm()->SetSuperfluous();
645 SwSectionFrm
* pSect
= pUp
->FindSctFrm();
648 // Wenn der letzte Fussnotencontainer aus einem spaltigen Bereich verschwindet,
649 // so kann dieser, falls er keinen Follow besitzt, zusammenschrumpfen.
650 if( pSect
&& !pSect
->ToMaximize( FALSE
) && !pSect
->IsColLocked() )
651 pSect
->_InvalidateSize();
654 { if ( Frm().Height() )
655 pUp
->Shrink( Frm().Height() );
656 pUp
->SetCompletePaint();
657 pUp
->InvalidatePage();
662 /*************************************************************************
666 |* Ersterstellung MA 23. Feb. 94
667 |* Letzte Aenderung MA 23. Feb. 94
669 |*************************************************************************/
672 void SwFtnFrm::Paste( SwFrm
* pParent
, SwFrm
* pSibling
)
674 ASSERT( pParent
, "Kein Parent fuer Paste." );
675 ASSERT( pParent
->IsLayoutFrm(), "Parent ist CntntFrm." );
676 ASSERT( pParent
!= this, "Bin selbst der Parent." );
677 ASSERT( pSibling
!= this, "Bin mein eigener Nachbar." );
678 ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
679 "Bin noch irgendwo angemeldet." );
681 //In den Baum einhaengen.
682 InsertBefore( (SwLayoutFrm
*)pParent
, pSibling
);
685 if( (Frm().*fnRect
->fnGetWidth
)()!=(pParent
->Prt().*fnRect
->fnGetWidth
)() )
688 SwPageFrm
*pPage
= FindPageFrm();
689 InvalidatePage( pPage
);
691 GetNext()->_InvalidatePos();
692 if( (Frm().*fnRect
->fnGetHeight
)() )
693 pParent
->Grow( (Frm().*fnRect
->fnGetHeight
)() );
695 //Wenn mein Vorgaenger mein Master ist und/oder wenn mein Nachfolger mein
696 //Follow ist so kann ich deren Inhalt uebernehmen und sie vernichten.
697 if ( GetPrev() && GetPrev() == GetMaster() )
698 { ASSERT( SwFlowFrm::CastFlowFrm( GetPrev()->GetLower() ),
699 "Fussnote ohne Inhalt?" );
700 (SwFlowFrm::CastFlowFrm( GetPrev()->GetLower()))->
701 MoveSubTree( this, GetLower() );
702 SwFrm
*pDel
= GetPrev();
706 if ( GetNext() && GetNext() == GetFollow() )
707 { ASSERT( SwFlowFrm::CastFlowFrm( GetNext()->GetLower() ),
708 "Fussnote ohne Inhalt?" );
709 (SwFlowFrm::CastFlowFrm( GetNext()->GetLower()))->MoveSubTree( this );
710 SwFrm
*pDel
= GetNext();
715 SwDoc
*pDoc
= GetFmt()->GetDoc();
718 ASSERT( lcl_FindFtnPos( pDoc
, ((SwFtnFrm
*)GetPrev())->GetAttr() ) <=
719 lcl_FindFtnPos( pDoc
, GetAttr() ), "Prev ist not FtnPrev" );
723 ASSERT( lcl_FindFtnPos( pDoc
, GetAttr() ) <=
724 lcl_FindFtnPos( pDoc
, ((SwFtnFrm
*)GetNext())->GetAttr() ),
725 "Next is not FtnNext" );
728 InvalidateNxtFtnCnts( pPage
);
731 /*************************************************************************
733 |* SwFrm::GetNextFtnLeaf()
735 |* Beschreibung Liefert das naechste LayoutBlatt in den das
736 |* Frame gemoved werden kann.
737 |* Neue Seiten werden nur dann erzeugt, wenn der Parameter TRUE ist.
738 |* Ersterstellung MA 16. Nov. 92
739 |* Letzte Aenderung AMA 09. Nov. 98
741 |*************************************************************************/
744 SwLayoutFrm
*SwFrm::GetNextFtnLeaf( MakePageType eMakePage
)
746 SwFtnBossFrm
*pOldBoss
= FindFtnBossFrm();
747 SwPageFrm
* pOldPage
= pOldBoss
->FindPageFrm();
749 SwFtnBossFrm
*pBoss
= pOldBoss
->IsColumnFrm() ?
750 (SwFtnBossFrm
*)pOldBoss
->GetNext() : 0; // naechste Spalte, wenn vorhanden
755 if( pOldBoss
->GetUpper()->IsSctFrm() )
756 { // Das kann nur in einem spaltigen Bereich sein
757 SwLayoutFrm
* pNxt
= pOldBoss
->GetNextSctLeaf( eMakePage
);
760 ASSERT( pNxt
->IsColBodyFrm(), "GetNextFtnLeaf: Funny Leaf" );
761 pBoss
= (SwFtnBossFrm
*)pNxt
->GetUpper();
762 pPage
= pBoss
->FindPageFrm();
770 pPage
= (SwPageFrm
*)pOldPage
->GetNext();
771 // Leerseiten ueberspringen
772 if( pPage
&& pPage
->IsEmptyPage() )
773 pPage
= (SwPageFrm
*)pPage
->GetNext();
777 // Was haben wir jetzt?
778 // pBoss != NULL, pPage==NULL => pBoss ist die auf der gleichen Seite folgende Spalte
779 // pBoss != NULL, pPage!=NULL => pBoss und pPage sind die folgende Seite (Empty uebersprungen)
780 // pBoss == NULL => pPage == NULL, es gibt keine folgende Seite
782 //Wenn die Fussnote bereits einen Follow hat brauchen wir nicht zu suchen.
783 //Wenn allerdings zwischen Ftn und Follow unerwuenschte Leerseiten/spalten
784 //herumlungern, so legen wir auf der naechstbesten Seite/Spalte einen weiteren
785 //Follow an, der Rest wird sich schon finden.
786 SwFtnFrm
*pFtn
= FindFtnFrm();
787 if ( pFtn
&& pFtn
->GetFollow() )
789 SwFtnBossFrm
* pTmpBoss
= pFtn
->GetFollow()->FindFtnBossFrm();
790 // Folgende Faelle werden hier erkannt und akzeptiert
791 // 1. Die FtnBosse sind benachbarte Seiten oder benachbarte Spalten
792 // 2. Der neue ist die erste Spalte der benachbarten Seite
793 // 3. Der neue ist die erste Spalte in einem Bereich in der naechsten Spalte/Seite
794 while( pTmpBoss
!= pBoss
&& pTmpBoss
&& !pTmpBoss
->GetPrev() )
795 pTmpBoss
= pTmpBoss
->GetUpper()->FindFtnBossFrm();
796 if( pTmpBoss
== pBoss
)
797 return pFtn
->GetFollow();
800 // Wenn wir keinen pBoss gefunden haben oder es sich um eine "falsche" Seite handelt,
801 // muss eine neue Seite her
802 if ( !pBoss
|| ( pPage
&& pPage
->IsEndNotePage() && !pOldPage
->IsEndNotePage() ) )
804 if ( eMakePage
== MAKEPAGE_APPEND
|| eMakePage
== MAKEPAGE_INSERT
)
806 pBoss
= InsertPage( pOldPage
, pOldPage
->IsFtnPage() );
807 ((SwPageFrm
*)pBoss
)->SetEndNotePage( pOldPage
->IsEndNotePage() );
812 if( pBoss
->IsPageFrm() )
813 { // Wenn wir auf einer spaltigen Seite gelandet sind,
814 // gehen wir in die erste Spalte
815 SwLayoutFrm
* pLay
= pBoss
->FindBodyCont();
816 if( pLay
&& pLay
->Lower() && pLay
->Lower()->IsColumnFrm() )
817 pBoss
= (SwFtnBossFrm
*)pLay
->Lower();
819 //Seite/Spalte gefunden, da schummeln wir uns doch gleich mal 'rein
820 SwFtnContFrm
*pCont
= pBoss
->FindFtnCont();
821 if ( !pCont
&& pBoss
->GetMaxFtnHeight() &&
822 ( eMakePage
== MAKEPAGE_APPEND
|| eMakePage
== MAKEPAGE_INSERT
) )
823 pCont
= pBoss
->MakeFtnCont();
827 /*************************************************************************
829 |* SwFrm::GetPrevFtnLeaf()
831 |* Beschreibung Liefert das vorhergehende LayoutBlatt in das der
832 |* Frame gemoved werden kann.
833 |* Ersterstellung MA 16. Nov. 92
834 |* Letzte Aenderung AMA 06. Nov. 98
836 |*************************************************************************/
839 SwLayoutFrm
*SwFrm::GetPrevFtnLeaf( MakePageType eMakeFtn
)
841 //Der Vorgaenger fuer eine Fussnote ist falls moeglich der Master
842 //in der Fussnoteneigenen Verkettung.
843 SwLayoutFrm
*pRet
= 0;
844 SwFtnFrm
*pFtn
= FindFtnFrm();
845 pRet
= pFtn
->GetMaster();
847 SwFtnBossFrm
* pOldBoss
= FindFtnBossFrm();
848 SwPageFrm
*pOldPage
= pOldBoss
->FindPageFrm();
850 if ( !pOldBoss
->GetPrev() && !pOldPage
->GetPrev() )
851 return pRet
; // es gibt weder eine Spalte noch eine Seite vor uns
855 bool bEndn
= pFtn
->GetAttr()->GetFtn().IsEndNote();
856 SwFrm
* pTmpRef
= NULL
;
857 if( bEndn
&& pFtn
->IsInSct() )
859 SwSectionFrm
* pSect
= pFtn
->FindSctFrm();
860 if( pSect
->IsEndnAtEnd() )
861 pTmpRef
= pSect
->FindLastCntnt( FINDMODE_LASTCNT
);
864 pTmpRef
= pFtn
->GetRef();
865 SwFtnBossFrm
* pStop
= pTmpRef
->FindFtnBossFrm( !bEndn
);
867 const USHORT nNum
= pStop
->GetPhyPageNum();
869 //Wenn die Fussnoten am Dokumentende angezeigt werden, so verlassen wir
870 //die Entsprechenden Seiten nicht.
871 //Selbiges gilt analog fuer die Endnotenseiten.
872 const BOOL bEndNote
= pOldPage
->IsEndNotePage();
873 const BOOL bFtnEndDoc
= pOldPage
->IsFtnPage();
874 SwFtnBossFrm
* pNxtBoss
= pOldBoss
;
875 SwSectionFrm
*pSect
= pNxtBoss
->GetUpper()->IsSctFrm() ?
876 (SwSectionFrm
*)pNxtBoss
->GetUpper() : 0;
880 if( pNxtBoss
->IsColumnFrm() && pNxtBoss
->GetPrev() )
881 pNxtBoss
= (SwFtnBossFrm
*)pNxtBoss
->GetPrev(); // eine Spalte zurueck
882 else // oder eine Seite zurueck
884 SwLayoutFrm
* pBody
= 0;
887 if( pSect
->IsFtnLock() )
889 if( pNxtBoss
== pOldBoss
)
895 pSect
= (SwSectionFrm
*)pSect
->FindMaster();
896 if( !pSect
|| !pSect
->Lower() )
898 ASSERT( pSect
->Lower()->IsColumnFrm(),
899 "GetPrevFtnLeaf: Where's the column?" );
900 pNxtBoss
= (SwFtnBossFrm
*)pSect
->Lower();
906 SwPageFrm
* pPage
= (SwPageFrm
*)pNxtBoss
->FindPageFrm()->GetPrev();
907 if( !pPage
|| pPage
->GetPhyPageNum() < nNum
||
908 bEndNote
!= pPage
->IsEndNotePage() || bFtnEndDoc
!= pPage
->IsFtnPage() )
909 return NULL
; // Keine in Frage kommende Seite mehr gefunden
911 pBody
= pPage
->FindBodyCont();
913 // Die vorherige Seite haben wir nun, ggf. sollten wir in die letzte Spalte
914 // der Seite wechseln
917 if ( pBody
->Lower() && pBody
->Lower()->IsColumnFrm() )
919 pNxtBoss
= static_cast<SwFtnBossFrm
*>(pBody
->GetLastLower());
923 SwFtnContFrm
*pCont
= pNxtBoss
->FindFtnCont();
929 if ( pStop
== pNxtBoss
)
930 { //Die Seite/Spalte auf der sich auch die Referenz tummelt, ist erreicht.
931 //Wir koennen jetzt probehalber mal einen Container erzeugen und
933 if ( eMakeFtn
== MAKEPAGE_FTN
&& pNxtBoss
->GetMaxFtnHeight() )
934 pRet
= pNxtBoss
->MakeFtnCont();
941 const SwFtnBossFrm
* pNewBoss
= pRet
->FindFtnBossFrm();
943 if( pOldBoss
->IsColumnFrm() && pOldBoss
->GetPrev() ) // es gibt eine vorherige Spalte
944 bJump
= pOldBoss
->GetPrev() != (SwFrm
*)pNewBoss
; // sind wir darin gelandet?
945 else if( pNewBoss
->IsColumnFrm() && pNewBoss
->GetNext() )
946 bJump
= TRUE
; // es gibt hinter dem neuen Boss noch eine Spalte, die aber nicht
947 // der alte Boss sein kann, das haben wir ja bereits geprueft.
948 else // hier landen wir nur, wenn neuer und alter Boss entweder Seiten oder letzte (neu)
949 { // bzw. erste (alt) Spalten einer Seite sind. In diesem Fall muss noch geprueft
950 // werden, ob Seiten ueberspringen wurden.
951 USHORT nDiff
= pOldPage
->GetPhyPageNum() - pRet
->FindPageFrm()->GetPhyPageNum();
953 (nDiff
> 1 && !((SwPageFrm
*)pOldPage
->GetPrev())->IsEmptyPage()) )
957 SwFlowFrm::SetMoveBwdJump( TRUE
);
962 /*************************************************************************
964 |* SwFrm::IsFtnAllowed()
966 |* Ersterstellung MA 22. Mar. 94
967 |* Letzte Aenderung MA 01. Dec. 94
969 |*************************************************************************/
972 BOOL
SwFrm::IsFtnAllowed() const
974 if ( !IsInDocBody() )
979 //Keine Ftns in wiederholten Headlines.
980 const SwTabFrm
*pTab
= ((SwFrm
*)this)->ImplFindTabFrm();
981 if ( pTab
->IsFollow() )
982 return !pTab
->IsInHeadline( *this );
987 /*************************************************************************
989 |* SwRootFrm::UpdateFtnNums()
991 |* Ersterstellung MA 02. Mar. 93
992 |* Letzte Aenderung MA 09. Dec. 97
994 |*************************************************************************/
997 void SwRootFrm::UpdateFtnNums()
999 //Seitenweise Numerierung nur wenn es am Dokument so eingestellt ist.
1000 if ( GetFmt()->GetDoc()->GetFtnInfo().eNum
== FTNNUM_PAGE
)
1002 SwPageFrm
*pPage
= (SwPageFrm
*)Lower();
1003 while ( pPage
&& !pPage
->IsFtnPage() )
1005 pPage
->UpdateFtnNum();
1006 pPage
= (SwPageFrm
*)pPage
->GetNext();
1011 /*************************************************************************
1013 |* RemoveFtns() Entfernen aller Fussnoten (nicht etwa die Referenzen)
1014 |* und Entfernen aller Fussnotenseiten.
1016 |* Ersterstellung MA 05. Dec. 97
1017 |* Letzte Aenderung AMA 06. Nov. 98
1019 |*************************************************************************/
1021 void lcl_RemoveFtns( SwFtnBossFrm
* pBoss
, BOOL bPageOnly
, BOOL bEndNotes
)
1025 SwFtnContFrm
*pCont
= pBoss
->FindFtnCont();
1028 SwFtnFrm
*pFtn
= (SwFtnFrm
*)pCont
->Lower();
1029 ASSERT( pFtn
, "FtnCont ohne Ftn." );
1031 while ( pFtn
->GetMaster() )
1032 pFtn
= pFtn
->GetMaster();
1035 SwFtnFrm
*pNxt
= (SwFtnFrm
*)pFtn
->GetNext();
1036 if ( !pFtn
->GetAttr()->GetFtn().IsEndNote() ||
1039 pFtn
->GetRef()->Prepare( PREP_FTN
, (void*)pFtn
->GetAttr() );
1040 if ( bPageOnly
&& !pNxt
)
1041 pNxt
= pFtn
->GetFollow();
1049 if( !pBoss
->IsInSct() )
1051 // A sectionframe with the Ftn/EndnAtEnd-flags may contain
1052 // foot/endnotes. If the last lower frame of the bodyframe is
1053 // a multicolumned sectionframe, it may contain footnotes, too.
1054 SwLayoutFrm
* pBody
= pBoss
->FindBodyCont();
1055 if( pBody
&& pBody
->Lower() )
1057 SwFrm
* pLow
= pBody
->Lower();
1058 while( pLow
->GetNext() )
1060 if( pLow
->IsSctFrm() && ( !pLow
->GetNext() ||
1061 ((SwSectionFrm
*)pLow
)->IsAnyNoteAtEnd() ) &&
1062 ((SwSectionFrm
*)pLow
)->Lower() &&
1063 ((SwSectionFrm
*)pLow
)->Lower()->IsColumnFrm() )
1064 lcl_RemoveFtns( (SwColumnFrm
*)((SwSectionFrm
*)pLow
)->Lower(),
1065 bPageOnly
, bEndNotes
);
1066 pLow
= pLow
->GetNext();
1071 pBoss
= pBoss
->IsColumnFrm() ? (SwColumnFrm
*)pBoss
->GetNext() : NULL
;
1075 void SwRootFrm::RemoveFtns( SwPageFrm
*pPage
, BOOL bPageOnly
, BOOL bEndNotes
)
1078 pPage
= (SwPageFrm
*)Lower();
1081 { // Bei spaltigen Seiten muessen wir in allen Spalten aufraeumen
1082 SwFtnBossFrm
* pBoss
;
1083 SwLayoutFrm
* pBody
= pPage
->FindBodyCont();
1084 if( pBody
&& pBody
->Lower() && pBody
->Lower()->IsColumnFrm() )
1085 pBoss
= (SwFtnBossFrm
*)pBody
->Lower(); // die erste Spalte
1087 pBoss
= pPage
; // keine Spalten
1088 lcl_RemoveFtns( pBoss
, bPageOnly
, bEndNotes
);
1091 if ( pPage
->IsFtnPage() &&
1092 (!pPage
->IsEndNotePage() || bEndNotes
) )
1094 SwFrm
*pDel
= pPage
;
1095 pPage
= (SwPageFrm
*)pPage
->GetNext();
1100 pPage
= (SwPageFrm
*)pPage
->GetNext();
1108 /*************************************************************************
1110 |* SetFtnPageDescs() Seitenvorlagen der Fussnotenseiten aendern
1112 |* Ersterstellung MA 11. Dec. 97
1113 |* Letzte Aenderung MA 11. Dec. 97
1115 |*************************************************************************/
1117 void SwRootFrm::CheckFtnPageDescs( BOOL bEndNote
)
1119 SwPageFrm
*pPage
= (SwPageFrm
*)Lower();
1120 while ( pPage
&& !pPage
->IsFtnPage() )
1121 pPage
= (SwPageFrm
*)pPage
->GetNext();
1122 while ( pPage
&& pPage
->IsEndNotePage() != bEndNote
)
1123 pPage
= (SwPageFrm
*)pPage
->GetNext();
1125 SwFrm::CheckPageDescs( pPage
, FALSE
);
1129 /*************************************************************************
1131 |* SwFtnBossFrm::MakeFtnCont()
1133 |* Ersterstellung MA 25. Feb. 93
1134 |* Letzte Aenderung AMA 29. Oct. 98
1136 |*************************************************************************/
1139 SwFtnContFrm
*SwFtnBossFrm::MakeFtnCont()
1141 //Einfuegen eines Fussnotencontainers. Der Fussnotencontainer sitzt
1142 //immer direkt hinter dem Bodytext.
1143 //Sein FrmFmt ist immer das DefaultFrmFmt.
1146 if ( FindFtnCont() )
1147 { ASSERT( !this, "Fussnotencontainer bereits vorhanden." );
1152 SwFtnContFrm
*pNew
= new SwFtnContFrm( GetFmt()->GetDoc()->GetDfltFrmFmt());
1153 SwLayoutFrm
*pLay
= FindBodyCont();
1154 pNew
->Paste( this, pLay
->GetNext() );
1158 /*************************************************************************
1160 |* SwFtnBossFrm::FindFtnCont()
1162 |* Ersterstellung MA 25. Feb. 93
1163 |* Letzte Aenderung AMA 29. Oct. 98
1165 |*************************************************************************/
1168 SwFtnContFrm
*SwFtnBossFrm::FindFtnCont()
1170 SwFrm
*pFrm
= Lower();
1171 while( pFrm
&& !pFrm
->IsFtnContFrm() )
1172 pFrm
= pFrm
->GetNext();
1177 SwFrm
*pFtn
= pFrm
->GetLower();
1178 ASSERT( pFtn
, "Cont ohne Fussnote." );
1181 ASSERT( pFtn
->IsFtnFrm(), "Nachbar von Fussnote keine Fussnote." );
1182 pFtn
= pFtn
->GetNext();
1187 return (SwFtnContFrm
*)pFrm
;
1190 /*************************************************************************
1192 |* SwFtnBossFrm::FindNearestFtnCont() Sucht den naechst greifbaren Fussnotencontainer.
1194 |* Ersterstellung MA 02. Aug. 93
1195 |* Letzte Aenderung AMA 29. Oct. 98
1197 |*************************************************************************/
1199 SwFtnContFrm
*SwFtnBossFrm::FindNearestFtnCont( BOOL bDontLeave
)
1201 SwFtnContFrm
*pCont
= 0;
1202 if ( GetFmt()->GetDoc()->GetFtnIdxs().Count() )
1204 pCont
= FindFtnCont();
1207 SwPageFrm
*pPage
= FindPageFrm();
1208 SwFtnBossFrm
* pBoss
= this;
1209 BOOL bEndNote
= pPage
->IsEndNotePage();
1212 BOOL bChgPage
= lcl_NextFtnBoss( pBoss
, pPage
, bDontLeave
);
1213 // Haben wir noch einen Boss gefunden? Bei einem Seitenwechsel muss
1214 // zudem noch das EndNotenFlag uebereinstimmen
1215 if( pBoss
&& ( !bChgPage
|| pPage
->IsEndNotePage() == bEndNote
) )
1216 pCont
= pBoss
->FindFtnCont();
1217 } while ( !pCont
&& pPage
);
1224 /*************************************************************************
1226 |* SwFtnBossFrm::FindFirstFtn()
1228 |* Beschreibung Erste Fussnote des Fussnotenbosses suchen.
1229 |* Ersterstellung MA 26. Feb. 93
1230 |* Letzte Aenderung AMA 29. Oct. 99
1232 |*************************************************************************/
1235 SwFtnFrm
*SwFtnBossFrm::FindFirstFtn()
1237 //Erstmal den naechsten FussnotenContainer suchen.
1238 SwFtnContFrm
*pCont
= FindNearestFtnCont();
1242 //Ab der ersten Fussnote im Container die erste suchen, die
1243 //von der aktuellen Spalte (bzw. einspaltigen Seite) referenziert wird.
1245 SwFtnFrm
*pRet
= (SwFtnFrm
*)pCont
->Lower();
1246 const USHORT nRefNum
= FindPageFrm()->GetPhyPageNum();
1247 const USHORT nRefCol
= lcl_ColumnNum( this );
1248 USHORT nPgNum
, nColNum
; //Seitennummer, Spaltennummer
1249 SwFtnBossFrm
* pBoss
;
1253 pBoss
= pRet
->GetRef()->FindFtnBossFrm();
1254 ASSERT( pBoss
, "FindFirstFtn: No boss found" );
1256 return FALSE
; // ?There must be a bug, but no GPF
1257 pPage
= pBoss
->FindPageFrm();
1258 nPgNum
= pPage
->GetPhyPageNum();
1259 if ( nPgNum
== nRefNum
)
1261 nColNum
= lcl_ColumnNum( pBoss
);
1262 if( nColNum
== nRefCol
)
1263 return pRet
; //hat ihn.
1264 else if( nColNum
> nRefCol
)
1265 return NULL
; //mind. eine Spalte zu weit.
1267 else if ( nPgNum
> nRefNum
)
1268 return NULL
; //mind. eine Seite zu weit.
1272 // Ende, wenn Ref auf einer spaeteren Seite oder auf der gleichen Seite in einer
1273 // spaeteren Spalte liegt
1277 while ( pRet
->GetFollow() )
1278 pRet
= pRet
->GetFollow();
1280 SwFtnFrm
*pNxt
= (SwFtnFrm
*)pRet
->GetNext();
1283 pBoss
= pRet
->FindFtnBossFrm();
1284 pPage
= pBoss
->FindPageFrm();
1285 lcl_NextFtnBoss( pBoss
, pPage
, FALSE
); // naechster FtnBoss
1286 pCont
= pBoss
? pBoss
->FindNearestFtnCont() : 0;
1288 pNxt
= (SwFtnFrm
*)pCont
->Lower();
1293 pBoss
= pRet
->GetRef()->FindFtnBossFrm();
1294 pPage
= pBoss
->FindPageFrm();
1295 nPgNum
= pPage
->GetPhyPageNum();
1296 if ( nPgNum
== nRefNum
)
1298 nColNum
= lcl_ColumnNum( pBoss
);
1299 if( nColNum
== nRefCol
)
1301 else if( nColNum
> nRefCol
)
1302 pRet
= 0; //mind. eine Spalte zu weit.
1304 else if ( nPgNum
> nRefNum
)
1305 pRet
= 0; //mind. eine Seite zu weit.
1308 pRet
= 0; //Gibt eben keinen.
1313 /*************************************************************************
1315 |* SwFtnBossFrm::FindFirstFtn()
1317 |* Beschreibunt Erste Fussnote zum Cnt suchen.
1318 |* Ersterstellung MA 04. Mar. 93
1319 |* Letzte Aenderung AMA 28. Oct. 98
1321 |*************************************************************************/
1324 const SwFtnFrm
*SwFtnBossFrm::FindFirstFtn( SwCntntFrm
*pCnt
) const
1326 const SwFtnFrm
*pRet
= ((SwFtnBossFrm
*)this)->FindFirstFtn();
1329 const USHORT nColNum
= lcl_ColumnNum( this ); //Spaltennummer
1330 const USHORT nPageNum
= GetPhyPageNum();
1331 while ( pRet
&& (pRet
->GetRef() != pCnt
) )
1333 while ( pRet
->GetFollow() )
1334 pRet
= pRet
->GetFollow();
1336 if ( pRet
->GetNext() )
1337 pRet
= (const SwFtnFrm
*)pRet
->GetNext();
1339 { SwFtnBossFrm
*pBoss
= (SwFtnBossFrm
*)pRet
->FindFtnBossFrm();
1340 SwPageFrm
*pPage
= pBoss
->FindPageFrm();
1341 lcl_NextFtnBoss( pBoss
, pPage
, FALSE
); // naechster FtnBoss
1342 SwFtnContFrm
*pCont
= pBoss
? pBoss
->FindNearestFtnCont() : 0;
1343 pRet
= pCont
? (SwFtnFrm
*)pCont
->Lower() : 0;
1347 const SwFtnBossFrm
* pBoss
= pRet
->GetRef()->FindFtnBossFrm();
1348 if( pBoss
->GetPhyPageNum() != nPageNum
||
1349 nColNum
!= lcl_ColumnNum( pBoss
) )
1357 /*************************************************************************
1359 |* SwFtnBossFrm::ResetFtn()
1361 |* Ersterstellung MA 11. May. 95
1362 |* Letzte Aenderung AMA 29. Oct. 98
1364 |*************************************************************************/
1367 void SwFtnBossFrm::ResetFtn( const SwFtnFrm
*pCheck
)
1369 //Vernichten der Inkarnationen von Fussnoten zum Attribut, wenn sie nicht
1370 //zu pAssumed gehoeren.
1371 ASSERT( !pCheck
->GetMaster(), "Master not an Master." );
1373 SwNodeIndex
aIdx( *pCheck
->GetAttr()->GetStartNode(), 1 );
1374 SwCntntNode
*pNd
= aIdx
.GetNode().GetCntntNode();
1376 pNd
= pCheck
->GetFmt()->GetDoc()->
1377 GetNodes().GoNextSection( &aIdx
, TRUE
, FALSE
);
1378 SwClientIter
aIter( *pNd
);
1379 SwClient
* pLast
= aIter
.GoStart();
1382 if ( pLast
->ISA(SwFrm
) )
1384 SwFrm
*pFrm
= (SwFrm
*)pLast
;
1385 SwFrm
*pTmp
= pFrm
->GetUpper();
1386 while ( pTmp
&& !pTmp
->IsFtnFrm() )
1387 pTmp
= pTmp
->GetUpper();
1389 SwFtnFrm
*pFtn
= (SwFtnFrm
*)pTmp
;
1390 while ( pFtn
&& pFtn
->GetMaster() )
1391 pFtn
= pFtn
->GetMaster();
1392 if ( pFtn
!= pCheck
)
1396 SwFtnFrm
*pNxt
= pFtn
->GetFollow();
1407 /*************************************************************************
1409 |* SwFtnBossFrm::InsertFtn()
1411 |* Ersterstellung MA 26. Feb. 93
1412 |* Letzte Aenderung AMA 29. Oct. 98
1414 |*************************************************************************/
1417 void SwFtnBossFrm::InsertFtn( SwFtnFrm
* pNew
)
1419 #if (OSL_DEBUG_LEVEL > 1) && !defined(PRODUCT)
1420 static USHORT nStop
= 0;
1421 if ( nStop
== pNew
->GetFrmId() )
1427 //Die Fussnote haben wir, sie muss jetzt nur noch irgendwo
1428 //hin und zwar vor die Fussnote, deren Attribut vor das
1429 //der neuen zeigt (Position wird ueber das Doc ermittelt)
1430 //Gibt es in diesem Fussnotenboss noch keine Fussnoten, so muss eben ein
1431 //Container erzeugt werden.
1432 //Gibt es bereits einen Container aber noch keine Fussnote zu diesem
1433 //Fussnotenboss, so muss die Fussnote hinter die letzte Fussnote der dichtesten
1437 SwFtnFrm
*pSibling
= FindFirstFtn();
1438 BOOL bDontLeave
= FALSE
;
1440 // Ok, a sibling has been found, but is the sibling in an acceptable
1444 SwSectionFrm
* pMySect
= ImplFindSctFrm();
1445 bool bEndnt
= pNew
->GetAttr()->GetFtn().IsEndNote();
1448 const SwSectionFmt
* pEndFmt
= pMySect
->GetEndSectFmt();
1449 bDontLeave
= 0 != pEndFmt
;
1454 if( !pSibling
->IsInSct() ||
1455 !pSibling
->ImplFindSctFrm()->IsDescendantFrom( pEndFmt
) )
1458 else if( pSibling
->IsInSct() )
1464 bDontLeave
= pMySect
->IsFtnAtEnd();
1467 if( pMySect
->IsFtnAtEnd() )
1469 if( !pSibling
->IsInSct() ||
1470 !pMySect
->IsAnFollow( pSibling
->ImplFindSctFrm() ) )
1473 else if( pSibling
->IsInSct() )
1479 if( pSibling
&& pSibling
->FindPageFrm()->IsEndNotePage() !=
1480 FindPageFrm()->IsEndNotePage() )
1483 //Damit die Position herausgefunden werden kann.
1484 SwDoc
*pDoc
= GetFmt()->GetDoc();
1485 const ULONG nStPos
= ::lcl_FindFtnPos( pDoc
, pNew
->GetAttr() );
1489 SwFtnContFrm
*pParent
= 0;
1492 nCmpPos
= ::lcl_FindFtnPos( pDoc
, pSibling
->GetAttr() );
1493 if( nCmpPos
> nStPos
)
1498 { pParent
= FindFtnCont();
1501 //Es gibt noch keinen FussnotenContainer, also machen wir einen.
1502 //HAAAAAAAALT! So einfach ist das leider mal wieder nicht: Es kann
1503 //sein, dass irgendeine naechste Fussnote existiert die vor der
1504 //einzufuegenden zu stehen hat, weil z.B. eine Fussnote ueber zig
1505 //Seiten aufgespalten ist usw.
1506 pParent
= FindNearestFtnCont( bDontLeave
);
1509 SwFtnFrm
*pFtn
= (SwFtnFrm
*)pParent
->Lower();
1513 nCmpPos
= ::lcl_FindFtnPos( pDoc
, pFtn
->GetAttr() );
1514 if ( nCmpPos
> nStPos
)
1522 //Jetzt kann aber ein Fussnotencontainer gebaut werden.
1523 pParent
= MakeFtnCont();
1526 //Ausgehend von der ersten Fussnote unterhalb des Parents wird die
1527 //erste Fussnote gesucht deren Index hinter dem Index der
1528 //einzufuegenden liegt; vor dieser kann der neue dann gepastet
1530 pSibling
= (SwFtnFrm
*)pParent
->Lower();
1532 { ASSERT( !this, "Keinen Platz fuer Fussnote gefunden.");
1535 nCmpPos
= ::lcl_FindFtnPos( pDoc
, pSibling
->GetAttr() );
1537 SwFtnBossFrm
*pNxtB
= this; //Immer den letzten merken, damit wir nicht
1538 SwFtnFrm
*pLastSib
= 0; //ueber das Ziel hinausschiessen.
1540 while ( pSibling
&& nCmpPos
<= nStPos
)
1542 pLastSib
= pSibling
; // der kommt schon mal in Frage
1545 while ( pSibling
->GetFollow() )
1546 pSibling
= pSibling
->GetFollow();
1548 if ( pSibling
->GetNext() )
1550 pSibling
= (SwFtnFrm
*)pSibling
->GetNext();
1551 ASSERT( !pSibling
->GetMaster() || ( ENDNOTE
> nStPos
&&
1552 pSibling
->GetAttr()->GetFtn().IsEndNote() ),
1553 "InsertFtn: Master expected I" );
1557 pNxtB
= pSibling
->FindFtnBossFrm();
1558 SwPageFrm
*pSibPage
= pNxtB
->FindPageFrm();
1559 BOOL bEndNote
= pSibPage
->IsEndNotePage();
1560 BOOL bChgPage
= lcl_NextFtnBoss( pNxtB
, pSibPage
, bDontLeave
);
1561 // Bei Seitenwechsel muss das EndNoteFlag ueberprueft werden.
1562 SwFtnContFrm
*pCont
= pNxtB
&& ( !bChgPage
||
1563 pSibPage
->IsEndNotePage() == bEndNote
)
1564 ? pNxtB
->FindNearestFtnCont( bDontLeave
) : 0;
1566 pSibling
= (SwFtnFrm
*)pCont
->Lower();
1567 else // kein weiterer FtnContainer, dann werden wir uns wohl hinter
1568 break; // pSibling haengen
1572 nCmpPos
= ::lcl_FindFtnPos( pDoc
, pSibling
->GetAttr() );
1573 ASSERT( nCmpPos
> nLastPos
, "InsertFtn: Order of FtnFrm's buggy" );
1576 // pLastSib ist jetzt die letzte Fussnote vor uns,
1577 // pSibling leer oder die erste nach uns.
1578 if ( pSibling
&& pLastSib
&& (pSibling
!= pLastSib
) )
1579 { //Sind wir vielleicht bereits ueber das Ziel hinausgeschossen?
1580 if ( nCmpPos
> nStPos
)
1581 pSibling
= pLastSib
;
1583 else if ( !pSibling
)
1584 { //Eine Chance haben wir noch: wir nehmen einfach die letzte
1585 //Fussnote im Parent. Ein Sonderfall, der z.B. beim
1586 //zurueckfliessen von Absaetzen mit mehreren Fussnoten
1588 //Damit wir nicht die Reihenfolge verwuerfeln muessen wir den
1589 //Parent der letzten Fussnote, die wir an der Hand hatten benutzen.
1590 pSibling
= pLastSib
;
1591 while( pSibling
->GetFollow() )
1592 pSibling
= pSibling
->GetFollow();
1593 ASSERT( !pSibling
->GetNext(), "InsertFtn: Who's that guy?" );
1598 { //Die erste Fussnote der Spalte/Seite haben wir an der Hand, jetzt ausgehend
1599 //von dieser die erste zur selben Spalte/Seite suchen deren Index hinter
1600 //den uebergebenen zeigt, die letzte, die wir an der Hand hatten, ist
1601 //dann der Vorgaenger.
1602 SwFtnBossFrm
* pBoss
= pNew
->GetRef()->FindFtnBossFrm(
1603 !pNew
->GetAttr()->GetFtn().IsEndNote() );
1604 USHORT nRefNum
= pBoss
->GetPhyPageNum(); // Die Seiten- und
1605 USHORT nRefCol
= lcl_ColumnNum( pBoss
); // Spaltennummer der neuen Fussnote
1607 SwFtnFrm
*pLastSib
= 0;
1608 while ( pSibling
&& !bEnd
&& (nCmpPos
<= nStPos
) )
1610 pLastSib
= pSibling
;
1613 while ( pSibling
->GetFollow() )
1614 pSibling
= pSibling
->GetFollow();
1616 SwFtnFrm
*pFoll
= (SwFtnFrm
*)pSibling
->GetNext();
1619 pBoss
= pSibling
->GetRef()->FindFtnBossFrm( !pSibling
->
1620 GetAttr()->GetFtn().IsEndNote() );
1622 if( nStPos
>= ENDNOTE
||
1623 (nTmpRef
= pBoss
->GetPhyPageNum()) < nRefNum
||
1624 ( nTmpRef
== nRefNum
&& lcl_ColumnNum( pBoss
) <= nRefCol
))
1631 SwFtnBossFrm
* pNxtB
= pSibling
->FindFtnBossFrm();
1632 SwPageFrm
*pSibPage
= pNxtB
->FindPageFrm();
1633 BOOL bEndNote
= pSibPage
->IsEndNotePage();
1634 BOOL bChgPage
= lcl_NextFtnBoss( pNxtB
, pSibPage
, bDontLeave
);
1635 // Bei Seitenwechsel muss das EndNoteFlag ueberprueft werden.
1636 SwFtnContFrm
*pCont
= pNxtB
&& ( !bChgPage
||
1637 pSibPage
->IsEndNotePage() == bEndNote
)
1638 ? pNxtB
->FindNearestFtnCont( bDontLeave
) : 0;
1640 pSibling
= (SwFtnFrm
*)pCont
->Lower();
1644 if ( !bEnd
&& pSibling
)
1645 nCmpPos
= ::lcl_FindFtnPos( pDoc
, pSibling
->GetAttr() );
1646 if ( pSibling
&& pLastSib
&& (pSibling
!= pLastSib
) )
1647 { //Sind wir vielleicht bereits ueber das Ziel hinausgeschossen?
1648 if ( (nLastPos
< nCmpPos
) && (nCmpPos
> nStPos
) )
1650 pSibling
= pLastSib
;
1658 nCmpPos
= ::lcl_FindFtnPos( pDoc
, pSibling
->GetAttr() );
1659 if ( nCmpPos
< nStPos
)
1661 while ( pSibling
->GetFollow() )
1662 pSibling
= pSibling
->GetFollow();
1663 pParent
= (SwFtnContFrm
*)pSibling
->GetUpper();
1664 pSibling
= (SwFtnFrm
*)pSibling
->GetNext();
1668 if( pSibling
->GetMaster() )
1670 if( ENDNOTE
> nCmpPos
|| nStPos
>= ENDNOTE
)
1672 ASSERT( FALSE
, "InsertFtn: Master expected II" );
1674 pSibling
= pSibling
->GetMaster();
1675 while ( pSibling
->GetMaster() );
1678 pParent
= (SwFtnContFrm
*)pSibling
->GetUpper();
1681 ASSERT( pParent
, "paste in space?" );
1682 pNew
->Paste( pParent
, pSibling
);
1685 /*************************************************************************
1687 |* SwFtnBossFrm::AppendFtn()
1689 |* Ersterstellung MA 25. Feb. 93
1690 |* Letzte Aenderung AMA 29. Oct. 98
1692 |*************************************************************************/
1695 void SwFtnBossFrm::AppendFtn( SwCntntFrm
*pRef
, SwTxtFtn
*pAttr
)
1697 //Wenn es die Fussnote schon gibt tun wir nix.
1698 if ( FindFtn( pRef
, pAttr
) )
1701 //Wenn Fussnoten am Dokumentende eingestellt sind, so brauchen wir 'eh erst
1702 //ab der entsprechenden Seite zu suchen.
1703 //Wenn es noch keine gibt, muss eben eine erzeugt werden.
1704 //Wenn es sich um eine Endnote handelt, muss eine Endnotenseite gesucht
1705 //bzw. erzeugt werden.
1706 SwDoc
*pDoc
= GetFmt()->GetDoc();
1707 SwFtnBossFrm
*pBoss
= this;
1708 SwPageFrm
*pPage
= FindPageFrm();
1709 SwPageFrm
*pMyPage
= pPage
;
1710 BOOL bChgPage
= FALSE
;
1712 if ( pAttr
->GetFtn().IsEndNote() )
1715 if( GetUpper()->IsSctFrm() &&
1716 ((SwSectionFrm
*)GetUpper())->IsEndnAtEnd() )
1719 ((SwSectionFrm
*)GetUpper())->FindLastCntnt( FINDMODE_ENDNOTE
);
1722 pBoss
= pLast
->FindFtnBossFrm();
1723 pPage
= pBoss
->FindPageFrm();
1728 while ( pPage
->GetNext() && !pPage
->IsEndNotePage() )
1730 pPage
= (SwPageFrm
*)pPage
->GetNext();
1733 if ( !pPage
->IsEndNotePage() )
1735 SwPageDesc
*pDesc
= pDoc
->GetEndNoteInfo().GetPageDesc( *pDoc
);
1736 pPage
= ::InsertNewPage( *pDesc
, pPage
->GetUpper(),
1737 !pPage
->OnRightPage(), FALSE
, TRUE
, 0 );
1738 pPage
->SetEndNotePage( TRUE
);
1743 //Wir koennen wenigstens schon mal ungefaehr die richtige Seite
1744 //suchen. Damit stellen wir sicher das wir auch bei hunderten
1745 //Fussnoten noch in endlicher Zeit fertig werden.
1746 SwPageFrm
*pNxt
= (SwPageFrm
*)pPage
->GetNext();
1747 const ULONG nStPos
= ::lcl_FindFtnPos( pDoc
, pAttr
);
1748 while ( pNxt
&& pNxt
->IsEndNotePage() )
1750 SwFtnContFrm
*pCont
= pNxt
->FindFtnCont();
1751 if ( pCont
&& pCont
->Lower() )
1753 ASSERT( pCont
->Lower()->IsFtnFrm(), "Keine Ftn im Container" );
1754 if ( nStPos
> ::lcl_FindFtnPos( pDoc
,
1755 ((SwFtnFrm
*)pCont
->Lower())->GetAttr()))
1758 pNxt
= (SwPageFrm
*)pPage
->GetNext();
1767 else if( FTNPOS_CHAPTER
== pDoc
->GetFtnInfo().ePos
&& ( !GetUpper()->
1768 IsSctFrm() || !((SwSectionFrm
*)GetUpper())->IsFtnAtEnd() ) )
1770 while ( pPage
->GetNext() && !pPage
->IsFtnPage() &&
1771 !((SwPageFrm
*)pPage
->GetNext())->IsEndNotePage() )
1773 pPage
= (SwPageFrm
*)pPage
->GetNext();
1777 if ( !pPage
->IsFtnPage() )
1779 SwPageDesc
*pDesc
= pDoc
->GetFtnInfo().GetPageDesc( *pDoc
);
1780 pPage
= ::InsertNewPage( *pDesc
, pPage
->GetUpper(),
1781 !pPage
->OnRightPage(), FALSE
, TRUE
, pPage
->GetNext() );
1786 //Wir koennen wenigstens schon mal ungefaehr die richtige Seite
1787 //suchen. Damit stellen wir sicher das wir auch bei hunderten
1788 //Fussnoten noch in endlicher Zeit fertig werden.
1789 SwPageFrm
*pNxt
= (SwPageFrm
*)pPage
->GetNext();
1790 const ULONG nStPos
= ::lcl_FindFtnPos( pDoc
, pAttr
);
1791 while ( pNxt
&& pNxt
->IsFtnPage() && !pNxt
->IsEndNotePage() )
1793 SwFtnContFrm
*pCont
= pNxt
->FindFtnCont();
1794 if ( pCont
&& pCont
->Lower() )
1796 ASSERT( pCont
->Lower()->IsFtnFrm(), "Keine Ftn im Container" );
1797 if ( nStPos
> ::lcl_FindFtnPos( pDoc
,
1798 ((SwFtnFrm
*)pCont
->Lower())->GetAttr()))
1801 pNxt
= (SwPageFrm
*)pPage
->GetNext();
1810 //Erstmal eine Fussnote und die benoetigten CntntFrms anlegen.
1811 if ( !pAttr
->GetStartNode() )
1812 { ASSERT( !this, "Kein Fussnoteninhalt." );
1816 // Wenn es auf der Seite/Spalte bereits einen FtnCont gibt,
1817 // kann in einen spaltigen Bereich keiner erzeugt werden.
1818 if( pBoss
->IsInSct() && pBoss
->IsColumnFrm() && !pPage
->IsFtnPage() )
1820 SwSectionFrm
* pSct
= pBoss
->FindSctFrm();
1821 if( bEnd
? !pSct
->IsEndnAtEnd() : !pSct
->IsFtnAtEnd() )
1823 SwFtnContFrm
* pFtnCont
= pSct
->FindFtnBossFrm(!bEnd
)->FindFtnCont();
1826 SwFtnFrm
* pTmp
= (SwFtnFrm
*)pFtnCont
->Lower();
1828 while( pTmp
&& !pTmp
->GetAttr()->GetFtn().IsEndNote() )
1829 pTmp
= (SwFtnFrm
*)pTmp
->GetNext();
1830 if( pTmp
&& *pTmp
< pAttr
)
1836 SwFtnFrm
*pNew
= new SwFtnFrm( pDoc
->GetDfltFrmFmt(), pRef
, pAttr
);
1838 SwNodeIndex
aIdx( *pAttr
->GetStartNode(), 1 );
1839 ::_InsertCnt( pNew
, pDoc
, aIdx
.GetIndex() );
1841 // Wenn die Seite gewechselt (oder gar neu angelegt) wurde,
1842 // muessen wir uns dort in die erste Spalte setzen
1845 SwLayoutFrm
* pBody
= pPage
->FindBodyCont();
1846 ASSERT( pBody
, "AppendFtn: NoPageBody?" );
1847 if( pBody
->Lower() && pBody
->Lower()->IsColumnFrm() )
1848 pBoss
= (SwFtnBossFrm
*)pBody
->Lower();
1850 pBoss
= pPage
; // bei nichtspaltigen Seiten auf die Seite selbst
1852 pBoss
->InsertFtn( pNew
);
1853 if ( pNew
->GetUpper() ) //Eingesetzt oder nicht?
1855 ::RegistFlys( pNew
->FindPageFrm(), pNew
);
1856 SwSectionFrm
* pSect
= FindSctFrm();
1857 // Der Inhalt des FtnContainers in einem (spaltigen) Bereich
1858 // braucht nur kalkuliert zu werden,
1859 // wenn der Bereich bereits bis zur Unterkante seines Uppers geht.
1860 if( pSect
&& !pSect
->IsJoinLocked() && ( bEnd
? !pSect
->IsEndnAtEnd() :
1861 !pSect
->IsFtnAtEnd() ) && pSect
->Growable() )
1862 pSect
->InvalidateSize();
1865 // --> OD 2005-05-18 #i49383# - disable unlock of position of
1866 // lower objects during format of footnote content.
1867 const bool bOldFtnFrmLocked( pNew
->IsColLocked() );
1869 pNew
->KeepLockPosOfLowerObjs();
1870 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
1871 // no extra notify for footnote frame
1872 // SwLayNotify* pFtnFrmNotitfy = new SwLayNotify( pNew );
1874 SwCntntFrm
*pCnt
= pNew
->ContainsCntnt();
1875 while ( pCnt
&& pCnt
->FindFtnFrm()->GetAttr() == pAttr
)
1878 // --> OD 2005-05-17 #i49383# - format anchored objects
1879 if ( pCnt
->IsTxtFrm() && pCnt
->IsValid() )
1881 if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt
,
1882 *(pCnt
->FindPageFrm()) ) )
1884 // restart format with first content
1885 pCnt
= pNew
->ContainsCntnt();
1890 pCnt
= (SwCntntFrm
*)pCnt
->FindNextCnt();
1892 // --> OD 2005-05-18 #i49383#
1893 if ( !bOldFtnFrmLocked
)
1897 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
1898 // enable lock of lower object position before format of footnote frame.
1899 pNew
->UnlockPosOfLowerObjs();
1902 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
1903 // no extra notify for footnote frame
1904 // pNew->UnlockPosOfLowerObjs();
1905 // delete pFtnFrmNotitfy;
1907 if ( !bOldFtnFrmLocked
&& !pNew
->GetLower() &&
1908 !pNew
->IsColLocked() && !pNew
->IsBackMoveLocked() )
1915 pMyPage
->UpdateFtnNum();
1920 /*************************************************************************
1922 |* SwFtnBossFrm::FindFtn()
1924 |* Ersterstellung MA 25. Feb. 93
1925 |* Letzte Aenderung AMA 29. Oct. 98
1927 |*************************************************************************/
1930 SwFtnFrm
*SwFtnBossFrm::FindFtn( const SwCntntFrm
*pRef
, const SwTxtFtn
*pAttr
)
1932 //Der einfachste und sicherste Weg geht ueber das Attribut.
1933 ASSERT( pAttr
->GetStartNode(), "FtnAtr ohne StartNode." );
1934 SwNodeIndex
aIdx( *pAttr
->GetStartNode(), 1 );
1935 SwCntntNode
*pNd
= aIdx
.GetNode().GetCntntNode();
1937 pNd
= pRef
->GetAttrSet()->GetDoc()->
1938 GetNodes().GoNextSection( &aIdx
, TRUE
, FALSE
);
1941 SwClientIter
aIter( *pNd
);
1943 if ( 0 != (pClient
= aIter
.GoStart()) )
1946 if ( pClient
->IsA( TYPE(SwFrm
) ) )
1948 SwFrm
*pFrm
= ((SwFrm
*)pClient
)->GetUpper();
1949 // #i28500#, #i27243# Due to the endnode collector, there are
1950 // SwFtnFrms, which are not in the layout. Therefore the
1951 // bInfFtn flags are not set correctly, and a cell of FindFtnFrm
1952 // would return 0. Therefore we better call ImplFindFtnFrm().
1953 SwFtnFrm
*pFtn
= pFrm
->ImplFindFtnFrm();
1954 if ( pFtn
&& pFtn
->GetRef() == pRef
)
1956 // The following condition becomes true, if the whole
1957 // footnotecontent is a section. While no frames exist,
1958 // the HiddenFlag of the section is set, this causes
1959 // the GoNextSection-function leaves the footnote.
1960 if( pFtn
->GetAttr() != pAttr
)
1962 while ( pFtn
&& pFtn
->GetMaster() )
1963 pFtn
= pFtn
->GetMaster();
1967 } while ( 0 != (pClient
= aIter
++) );
1971 /*************************************************************************
1973 |* SwFtnBossFrm::RemoveFtn()
1975 |* Ersterstellung MA 25. Feb. 93
1976 |* Letzte Aenderung AMA 29. Oct. 98
1978 |*************************************************************************/
1981 void SwFtnBossFrm::RemoveFtn( const SwCntntFrm
*pRef
, const SwTxtFtn
*pAttr
,
1984 SwFtnFrm
*pFtn
= FindFtn( pRef
, pAttr
);
1989 SwFtnFrm
*pFoll
= pFtn
->GetFollow();
1994 if( bPrep
&& pRef
->IsFollow() )
1996 ASSERT( pRef
->IsTxtFrm(), "NoTxtFrm has Footnote?" );
1997 SwTxtFrm
* pMaster
= (SwTxtFrm
*)pRef
->FindMaster();
1998 if( !pMaster
->IsLocked() )
1999 pMaster
->Prepare( PREP_FTN_GONE
);
2002 FindPageFrm()->UpdateFtnNum();
2005 /*************************************************************************
2007 |* SwFtnBossFrm::ChangeFtnRef()
2009 |* Ersterstellung MA 25. Feb. 93
2010 |* Letzte Aenderung AMA 29. Oct. 98
2012 |*************************************************************************/
2015 void SwFtnBossFrm::ChangeFtnRef( const SwCntntFrm
*pOld
, const SwTxtFtn
*pAttr
,
2018 SwFtnFrm
*pFtn
= FindFtn( pOld
, pAttr
);
2021 pFtn
->SetRef( pNew
);
2022 pFtn
= pFtn
->GetFollow();
2026 /*************************************************************************
2028 |* SwFtnBossFrm::CollectFtns()
2030 |* Ersterstellung MA 24. Jul. 95
2031 |* Letzte Aenderung AMA 29. Oct. 98
2033 |*************************************************************************/
2036 /// OD 03.04.2003 #108446# - add parameter <_bCollectOnlyPreviousFtns> in
2037 /// order to control, if only footnotes, which are positioned before the
2038 /// footnote boss frame <this> have to be collected.
2039 void SwFtnBossFrm::CollectFtns( const SwCntntFrm
* _pRef
,
2040 SwFtnBossFrm
* _pOld
,
2042 const sal_Bool _bCollectOnlyPreviousFtns
)
2044 SwFtnFrm
*pFtn
= _pOld
->FindFirstFtn();
2047 if( _pOld
->IsColumnFrm() )
2048 { // Spalten abklappern
2049 while ( !pFtn
&& _pOld
->GetPrev() )
2051 //Wenn wir keine Fussnote gefunden haben, ist noch nicht alles zu
2052 //spaet. Die Schleife wird beim Aufnehmen von Follow-Zeilen durch
2053 //Tabellen benoetigt. Fuer alle anderen Faelle ist sie in der Lage
2054 //'krumme' Verhaeltnisse zu korrigieren.
2055 _pOld
= (SwFtnBossFrm
*)_pOld
->GetPrev();
2056 pFtn
= _pOld
->FindFirstFtn();
2063 for ( SwFrm
* pTmp
= _pOld
;
2064 0 != ( pPg
= (SwPageFrm
*)pTmp
->FindPageFrm()->GetPrev())
2065 && pPg
->IsEmptyPage() ;
2073 SwLayoutFrm
* pBody
= pPg
->FindBodyCont();
2074 if( pBody
->Lower() && pBody
->Lower()->IsColumnFrm() )
2076 // mehrspaltige Seite => letzte Spalte suchen
2077 _pOld
= static_cast<SwFtnBossFrm
*>(pBody
->GetLastLower());
2080 _pOld
= pPg
; // einspaltige Seite
2081 pFtn
= _pOld
->FindFirstFtn();
2084 // OD 03.04.2003 #108446# - consider new parameter <_bCollectOnlyPreviousFtns>
2085 SwFtnBossFrm
* pRefBossFrm
= NULL
;
2086 if ( _bCollectOnlyPreviousFtns
)
2090 _CollectFtns( _pRef
, pFtn
, _rFtnArr
, _bCollectOnlyPreviousFtns
, pRefBossFrm
);
2094 /*************************************************************************
2096 |* SwFtnBossFrm::_CollectFtns()
2098 |* Ersterstellung MA 24. Jul. 95
2099 |* Letzte Aenderung AMA 29. Oct. 98
2101 |*************************************************************************/
2102 inline void FtnInArr( SvPtrarr
& rFtnArr
, SwFtnFrm
* pFtn
)
2104 if ( USHRT_MAX
== rFtnArr
.GetPos( (VoidPtr
)pFtn
) )
2105 rFtnArr
.Insert( (VoidPtr
)pFtn
, rFtnArr
.Count() );
2108 /// OD 03.04.2003 #108446# - add parameters <_bCollectOnlyPreviousFtns> and
2109 /// <_pRefFtnBossFrm> in order to control, if only footnotes, which are positioned
2110 /// before the given reference footnote boss frame have to be collected.
2111 /// Note: if parameter <_bCollectOnlyPreviousFtns> is true, then parameter
2112 /// <_pRefFtnBossFrm> have to be referenced to an object.
2113 /// Adjust parameter names.
2114 void SwFtnBossFrm::_CollectFtns( const SwCntntFrm
* _pRef
,
2117 sal_Bool _bCollectOnlyPreviousFtns
,
2118 const SwFtnBossFrm
* _pRefFtnBossFrm
)
2120 // OD 03.04.2003 #108446# - assert, that no reference footnote boss frame
2121 // is set, in spite of the order, that only previous footnotes has to be
2123 ASSERT( !_bCollectOnlyPreviousFtns
|| _pRefFtnBossFrm
,
2124 "<SwFtnBossFrm::_CollectFtns(..)> - No reference footnote boss frame for collecting only previous footnotes set.\nCrash will be caused!" );
2126 //Alle Fussnoten die von pRef referenziert werden nacheinander
2127 //einsammeln (Attribut fuer Attribut), zusammengefuegen
2128 //(der Inhalt zu einem Attribut kann ueber mehrere Seiten verteilt sein)
2131 SvPtrarr
aNotFtnArr( 20, 20 ); //Zur Robustheit werden hier die nicht
2132 //dazugehoerigen Fussnoten eingetragen.
2133 //Wenn eine Fussnote zweimal angefasst wird
2134 //ists vorbei! So kommt die Funktion auch
2135 //noch mit einem kaputten Layout
2136 //einigermassen (ohne Schleife und Absturz)
2139 //Hier sollte keiner mit einer Follow-Ftn ankommen, es sei denn er hat
2140 //ernste Absichten (:-)); spricht er kommt mit einer Ftn an die vor der
2141 //ersten der Referenz liegt.
2142 ASSERT( !_pFtn
->GetMaster() || _pFtn
->GetRef() != _pRef
, "FollowFtn moven?" );
2143 while ( _pFtn
->GetMaster() )
2144 _pFtn
= _pFtn
->GetMaster();
2146 BOOL bFound
= FALSE
;
2150 //Erstmal die naechste Fussnote der Spalte/Seite suchen, damit wir nicht
2151 //nach dem Cut jeder Fussnote von vorn anfangen muessen.
2152 SwFtnFrm
*pNxtFtn
= _pFtn
;
2153 while ( pNxtFtn
->GetFollow() )
2154 pNxtFtn
= pNxtFtn
->GetFollow();
2155 pNxtFtn
= (SwFtnFrm
*)pNxtFtn
->GetNext();
2159 SwFtnBossFrm
* pBoss
= _pFtn
->FindFtnBossFrm();
2160 SwPageFrm
* pPage
= pBoss
->FindPageFrm();
2163 lcl_NextFtnBoss( pBoss
, pPage
, FALSE
);
2166 SwLayoutFrm
* pCont
= pBoss
->FindFtnCont();
2169 pNxtFtn
= (SwFtnFrm
*)pCont
->Lower();
2172 while( pNxtFtn
->GetMaster() )
2173 pNxtFtn
= pNxtFtn
->GetMaster();
2174 if( pNxtFtn
== _pFtn
)
2179 } while( !pNxtFtn
&& pBoss
);
2181 else if( !pNxtFtn
->GetAttr()->GetFtn().IsEndNote() )
2182 { ASSERT( !pNxtFtn
->GetMaster(), "_CollectFtn: Master exspected" );
2183 while ( pNxtFtn
->GetMaster() )
2184 pNxtFtn
= pNxtFtn
->GetMaster();
2186 if ( pNxtFtn
== _pFtn
)
2188 ASSERT( FALSE
, "_CollectFtn: Devil's circle" );
2192 // OD 03.04.2003 #108446# - determine, if found footnote has to be collected.
2193 sal_Bool bCollectFoundFtn
= sal_False
;
2194 if ( _pFtn
->GetRef() == _pRef
&& !_pFtn
->GetAttr()->GetFtn().IsEndNote() )
2196 if ( _bCollectOnlyPreviousFtns
)
2198 SwFtnBossFrm
* pBossOfFoundFtn
= _pFtn
->FindFtnBossFrm( sal_True
);
2199 ASSERT( pBossOfFoundFtn
,
2200 "<SwFtnBossFrm::_CollectFtns(..)> - footnote boss frame of found footnote frame missing.\nWrong layout!" );
2201 if ( !pBossOfFoundFtn
|| // don't crash, if no footnote boss is found.
2202 pBossOfFoundFtn
->IsBefore( _pRefFtnBossFrm
)
2205 bCollectFoundFtn
= sal_True
;
2210 bCollectFoundFtn
= sal_True
;
2214 if ( bCollectFoundFtn
)
2216 ASSERT( !_pFtn
->GetMaster(), "FollowFtn moven?" );
2217 SwFtnFrm
*pNxt
= _pFtn
->GetFollow();
2220 SwFrm
*pCnt
= pNxt
->ContainsAny();
2222 { //Unterwegs wird der Follow zerstoert weil er leer wird!
2224 { SwFrm
*pNxtCnt
= pCnt
->GetNext();
2226 pCnt
->Paste( _pFtn
);
2231 { ASSERT( !pNxt
, "Fussnote ohne Inhalt?" );
2235 pNxt
= _pFtn
->GetFollow();
2238 FtnInArr( _rFtnArr
, _pFtn
);
2243 FtnInArr( aNotFtnArr
, _pFtn
);
2248 USHRT_MAX
== _rFtnArr
.GetPos( (VoidPtr
)pNxtFtn
) &&
2249 USHRT_MAX
== aNotFtnArr
.GetPos( (VoidPtr
)pNxtFtn
) )
2256 /*************************************************************************
2258 |* SwFtnBossFrm::_MoveFtns()
2260 |* Ersterstellung MA 26. Feb. 93
2261 |* Letzte Aenderung AMA 29. Oct. 98
2263 |*************************************************************************/
2266 void SwFtnBossFrm::_MoveFtns( SvPtrarr
&rFtnArr
, BOOL bCalc
)
2268 //Alle Fussnoten die von pRef referenziert werden muessen von der
2269 //aktuellen Position, die sich durch die alte Spalte/Seite ergab, auf eine
2270 //neue Position, bestimmt durch die neue Spalte/Seite, gemoved werden.
2271 const USHORT nMyNum
= FindPageFrm()->GetPhyPageNum();
2272 const USHORT nMyCol
= lcl_ColumnNum( this );
2275 // --> OD 2004-06-11 #i21478# - keep last inserted footnote in order to
2276 // format the content of the following one.
2277 SwFtnFrm
* pLastInsertedFtn
= 0L;
2278 for ( USHORT i
= 0; i
< rFtnArr
.Count(); ++i
)
2280 SwFtnFrm
*pFtn
= (SwFtnFrm
*)rFtnArr
[i
];
2282 SwFtnBossFrm
* pRefBoss
= pFtn
->GetRef()->FindFtnBossFrm( TRUE
);
2283 if( pRefBoss
!= this )
2285 const USHORT nRefNum
= pRefBoss
->FindPageFrm()->GetPhyPageNum();
2286 const USHORT nRefCol
= lcl_ColumnNum( this );
2287 if( nRefNum
< nMyNum
|| ( nRefNum
== nMyNum
&& nRefCol
<= nMyCol
) )
2290 pRefBoss
->InsertFtn( pFtn
);
2292 if ( pFtn
->GetUpper() ) //Robust, z.B. bei doppelten
2294 // Damit FtnFrms, die nicht auf die Seite passen, nicht fuer zuviel
2295 // Unruhe sorgen (Loop 66312), wird ihr Inhalt zunaechst zusammengestaucht.
2296 // Damit wird der FtnCont erst gegrowt, wenn der Inhalt formatiert wird
2297 // und feststellt, dass er auf die Seite passt.
2298 SwFrm
*pCnt
= pFtn
->ContainsAny();
2301 if( pCnt
->IsLayoutFrm() )
2303 SwFrm
* pTmp
= ((SwLayoutFrm
*)pCnt
)->ContainsAny();
2304 while( pTmp
&& ((SwLayoutFrm
*)pCnt
)->IsAnLower( pTmp
) )
2306 pTmp
->Prepare( PREP_MOVEFTN
);
2307 (pTmp
->Frm().*fnRect
->fnSetHeight
)(0);
2308 (pTmp
->Prt().*fnRect
->fnSetHeight
)(0);
2309 pTmp
= pTmp
->FindNext();
2313 pCnt
->Prepare( PREP_MOVEFTN
);
2314 (pCnt
->Frm().*fnRect
->fnSetHeight
)(0);
2315 (pCnt
->Prt().*fnRect
->fnSetHeight
)(0);
2316 pCnt
= pCnt
->GetNext();
2318 (pFtn
->Frm().*fnRect
->fnSetHeight
)(0);
2319 (pFtn
->Prt().*fnRect
->fnSetHeight
)(0);
2321 pFtn
->GetUpper()->Calc();
2325 SwTxtFtn
*pAttr
= pFtn
->GetAttr();
2326 pCnt
= pFtn
->ContainsAny();
2327 BOOL bUnlock
= !pFtn
->IsBackMoveLocked();
2328 pFtn
->LockBackMove();
2330 // --> OD 2005-05-18 #i49383# - disable unlock of position of
2331 // lower objects during format of footnote content.
2332 pFtn
->KeepLockPosOfLowerObjs();
2333 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2334 // no extra notify for footnote frame
2335 // SwLayNotify aFtnFrmNotitfy( pFtn );
2338 while ( pCnt
&& pCnt
->FindFtnFrm()->GetAttr() == pAttr
)
2340 pCnt
->_InvalidatePos();
2342 // --> OD 2005-05-17 #i49383# - format anchored objects
2343 if ( pCnt
->IsTxtFrm() && pCnt
->IsValid() )
2345 if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt
,
2346 *(pCnt
->FindPageFrm()) ) )
2348 // restart format with first content
2349 pCnt
= pFtn
->ContainsAny();
2354 if( pCnt
->IsSctFrm() )
2355 { // Wenn es sich um einen nichtleeren Bereich handelt,
2356 // iterieren wir auch ueber seinen Inhalt
2357 SwFrm
* pTmp
= ((SwSectionFrm
*)pCnt
)->ContainsAny();
2361 pCnt
= pCnt
->FindNext();
2364 pCnt
= pCnt
->FindNext();
2368 pFtn
->UnlockBackMove();
2369 if( !pFtn
->ContainsAny() && !pFtn
->IsColLocked() )
2373 // --> OD 2004-06-10 #i21478#
2377 // --> OD 2005-05-18 #i49383#
2380 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2381 // enable lock of lower object position before format of footnote frame.
2382 pFtn
->UnlockPosOfLowerObjs();
2384 // pFtn->UnlockPosOfLowerObjs();
2387 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2388 // no extra notify for footnote frame
2391 // aFtnFrmNotitfy.FrmDeleted();
2397 { ASSERT( !pFtn
->GetMaster() && !pFtn
->GetFollow(),
2398 "DelFtn und Master/Follow?" );
2400 // --> OD 2004-06-10 #i21478#
2404 // --> OD 2004-06-10 #i21478#
2407 pLastInsertedFtn
= pFtn
;
2411 // --> OD 2004-06-10 #i21478# - format content of footnote following
2412 // the new inserted ones.
2413 if ( bCalc
&& pLastInsertedFtn
)
2415 if ( pLastInsertedFtn
->GetNext() )
2417 SwFtnFrm
* pNextFtn
= static_cast<SwFtnFrm
*>(pLastInsertedFtn
->GetNext());
2418 SwTxtFtn
* pAttr
= pNextFtn
->GetAttr();
2419 SwFrm
* pCnt
= pNextFtn
->ContainsAny();
2421 BOOL bUnlock
= !pNextFtn
->IsBackMoveLocked();
2422 pNextFtn
->LockBackMove();
2423 // --> OD 2005-05-18 #i49383# - disable unlock of position of
2424 // lower objects during format of footnote content.
2425 pNextFtn
->KeepLockPosOfLowerObjs();
2426 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2427 // no extra notify for footnote frame
2428 // SwLayNotify aFtnFrmNotitfy( pNextFtn );
2431 while ( pCnt
&& pCnt
->FindFtnFrm()->GetAttr() == pAttr
)
2433 pCnt
->_InvalidatePos();
2435 // --> OD 2005-05-17 #i49383# - format anchored objects
2436 if ( pCnt
->IsTxtFrm() && pCnt
->IsValid() )
2438 if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt
,
2439 *(pCnt
->FindPageFrm()) ) )
2441 // restart format with first content
2442 pCnt
= pNextFtn
->ContainsAny();
2447 if( pCnt
->IsSctFrm() )
2448 { // Wenn es sich um einen nichtleeren Bereich handelt,
2449 // iterieren wir auch ueber seinen Inhalt
2450 SwFrm
* pTmp
= ((SwSectionFrm
*)pCnt
)->ContainsAny();
2454 pCnt
= pCnt
->FindNext();
2457 pCnt
= pCnt
->FindNext();
2461 pNextFtn
->UnlockBackMove();
2463 // --> OD 2005-05-18 #i49383#
2464 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2465 // enable lock of lower object position before format of footnote frame.
2466 pNextFtn
->UnlockPosOfLowerObjs();
2468 // pNextFtn->UnlockPosOfLowerObjs();
2474 /*************************************************************************
2476 |* SwFtnBossFrm::MoveFtns()
2478 |* Ersterstellung BP 05. Aug. 93
2479 |* Letzte Aenderung AMA 29. Oct. 98
2481 |*************************************************************************/
2484 void SwFtnBossFrm::MoveFtns( const SwCntntFrm
*pSrc
, SwCntntFrm
*pDest
,
2487 if( ( GetFmt()->GetDoc()->GetFtnInfo().ePos
== FTNPOS_CHAPTER
&&
2488 (!GetUpper()->IsSctFrm() || !((SwSectionFrm
*)GetUpper())->IsFtnAtEnd()))
2489 || pAttr
->GetFtn().IsEndNote() )
2492 ASSERT( this == pSrc
->FindFtnBossFrm( TRUE
),
2493 "SwPageFrm::MoveFtns: source frame isn't on that FtnBoss" );
2495 SwFtnFrm
*pFtn
= FindFirstFtn();
2498 ChangeFtnRef( pSrc
, pAttr
, pDest
);
2499 SwFtnBossFrm
*pDestBoss
= pDest
->FindFtnBossFrm( TRUE
);
2500 ASSERT( pDestBoss
, "+SwPageFrm::MoveFtns: no destination boss" );
2501 if( pDestBoss
) // robust
2503 SvPtrarr
aFtnArr( 5, 5 );
2504 pDestBoss
->_CollectFtns( pDest
, pFtn
, aFtnArr
);
2505 if ( aFtnArr
.Count() )
2507 pDestBoss
->_MoveFtns( aFtnArr
, TRUE
);
2508 SwPageFrm
* pSrcPage
= FindPageFrm();
2509 SwPageFrm
* pDestPage
= pDestBoss
->FindPageFrm();
2510 // Nur beim Seitenwechsel FtnNum Updaten
2511 if( pSrcPage
!= pDestPage
)
2513 if( pSrcPage
->GetPhyPageNum() > pDestPage
->GetPhyPageNum() )
2514 pSrcPage
->UpdateFtnNum();
2515 pDestPage
->UpdateFtnNum();
2522 /*************************************************************************
2524 |* SwFtnBossFrm::RearrangeFtns()
2526 |* Ersterstellung MA 20. Jan. 94
2527 |* Letzte Aenderung AMA 29. Oct. 98
2529 |*************************************************************************/
2532 void SwFtnBossFrm::RearrangeFtns( const SwTwips nDeadLine
, const BOOL bLock
,
2533 const SwTxtFtn
*pAttr
)
2535 //Alle Fussnoten der Spalte/Seite dergestalt anformatieren,
2536 //dass sie ggf. die Spalte/Seite wechseln.
2538 SwSaveFtnHeight
aSave( this, nDeadLine
);
2539 SwFtnFrm
*pFtn
= FindFirstFtn();
2540 if( pFtn
&& pFtn
->GetPrev() && bLock
)
2542 SwFtnFrm
* pFirst
= (SwFtnFrm
*)pFtn
->GetUpper()->Lower();
2543 SwFrm
* pCntnt
= pFirst
->ContainsAny();
2546 BOOL bUnlock
= !pFirst
->IsBackMoveLocked();
2547 pFirst
->LockBackMove();
2550 // --> OD 2005-05-17 #i49383# - format anchored objects
2551 if ( pCntnt
->IsTxtFrm() && pCntnt
->IsValid() )
2553 SwObjectFormatter::FormatObjsAtFrm( *pCntnt
,
2554 *(pCntnt
->FindPageFrm()) );
2558 pFirst
->UnlockBackMove();
2560 pFtn
= FindFirstFtn();
2562 SwDoc
*pDoc
= GetFmt()->GetDoc();
2563 const ULONG nFtnPos
= pAttr
? ::lcl_FindFtnPos( pDoc
, pAttr
) : 0;
2564 SwFrm
*pCnt
= pFtn
? pFtn
->ContainsAny() : 0;
2568 BOOL bStart
= pAttr
== 0; // wenn kein Attribut uebergeben wird, alle bearbeiten
2569 // --> OD 2005-05-18 #i49383# - disable unlock of position of
2570 // lower objects during format of footnote and footnote content.
2571 SwFtnFrm
* pLastFtnFrm( 0L );
2572 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2573 // no extra notify for footnote frame
2574 // SwLayNotify* pFtnFrmNotify( 0L );
2575 // footnote frame needs to be locked, if <bLock> isn't set.
2576 bool bUnlockLastFtnFrm( false );
2581 bStart
= ::lcl_FindFtnPos( pDoc
, pCnt
->FindFtnFrm()->GetAttr() )
2585 pCnt
->_InvalidatePos();
2586 pCnt
->_InvalidateSize();
2587 pCnt
->Prepare( PREP_ADJUST_FRM
);
2588 SwFtnFrm
* pFtnFrm
= pCnt
->FindFtnFrm();
2589 // --> OD 2005-05-18 #i49383#
2590 if ( pFtnFrm
!= pLastFtnFrm
)
2594 if ( !bLock
&& bUnlockLastFtnFrm
)
2596 pLastFtnFrm
->ColUnlock();
2598 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2599 // enable lock of lower object position before format of footnote frame.
2600 pLastFtnFrm
->UnlockPosOfLowerObjs();
2601 pLastFtnFrm
->Calc();
2602 // pLastFtnFrm->UnlockPosOfLowerObjs();
2603 // no extra notify for footnote frame
2604 // delete pFtnFrmNotify;
2606 if ( !bLock
&& bUnlockLastFtnFrm
&&
2607 !pLastFtnFrm
->GetLower() &&
2608 !pLastFtnFrm
->IsColLocked() &&
2609 !pLastFtnFrm
->IsBackMoveLocked() )
2618 bUnlockLastFtnFrm
= !pFtnFrm
->IsColLocked();
2621 pFtnFrm
->KeepLockPosOfLowerObjs();
2622 pLastFtnFrm
= pFtnFrm
;
2623 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2624 // no extra notify for footnote frame
2625 // pFtnFrmNotify = new SwLayNotify( pLastFtnFrm );
2629 // OD 30.10.2002 #97265# - invalidate position of footnote
2630 // frame, if it's below its footnote container, in order to
2631 // assure its correct position, probably calculating its previous
2635 SwFrm
* aFtnContFrm
= pFtnFrm
->GetUpper();
2636 if ( (pFtnFrm
->Frm().*fnRect
->fnTopDist
)((aFtnContFrm
->*fnRect
->fnGetPrtBottom
)()) > 0 )
2638 pFtnFrm
->_InvalidatePos();
2643 BOOL bUnlock
= !pFtnFrm
->IsBackMoveLocked();
2644 pFtnFrm
->LockBackMove();
2647 // --> OD 2005-05-17 #i49383# - format anchored objects
2648 if ( pCnt
->IsTxtFrm() && pCnt
->IsValid() )
2650 if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt
,
2651 *(pCnt
->FindPageFrm()) ) )
2653 // restart format with first content
2654 pCnt
= pFtn
->ContainsAny();
2661 pFtnFrm
->UnlockBackMove();
2662 if( !pFtnFrm
->Lower() &&
2663 !pFtnFrm
->IsColLocked() )
2665 // --> OD 2005-08-10 #i49383#
2666 ASSERT( pLastFtnFrm
== pFtnFrm
,
2667 "<SwFtnBossFrm::RearrangeFtns(..)> - <pLastFtnFrm> != <pFtnFrm>" );
2669 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2670 // no extra notify for footnote frame
2671 // pFtnFrmNotify->FrmDeleted();
2672 // delete pFtnFrmNotify;
2683 // --> OD 2005-05-17 #i49383# - format anchored objects
2684 if ( pCnt
->IsTxtFrm() && pCnt
->IsValid() )
2686 if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt
,
2687 *(pCnt
->FindPageFrm()) ) )
2689 // restart format with first content
2690 pCnt
= pFtn
->ContainsAny();
2697 SwSectionFrm
*pDel
= NULL
;
2698 if( pCnt
->IsSctFrm() )
2700 SwFrm
* pTmp
= ((SwSectionFrm
*)pCnt
)->ContainsAny();
2706 pDel
= (SwSectionFrm
*)pCnt
;
2708 if ( pCnt
->GetNext() )
2709 pCnt
= pCnt
->GetNext();
2712 pCnt
= pCnt
->FindNext();
2715 SwFtnFrm
* pFtnFrm
= pCnt
->FindFtnFrm();
2716 if( pFtnFrm
->GetRef()->FindFtnBossFrm(
2717 pFtnFrm
->GetAttr()->GetFtn().IsEndNote() ) != this )
2730 //Nicht weiter als bis zur angegebenen Fussnote, falls eine
2733 (::lcl_FindFtnPos( pDoc
,
2734 pCnt
->FindFtnFrm()->GetAttr()) > nFtnPos
) )
2738 // --> OD 2005-05-18 #i49383#
2741 if ( !bLock
&& bUnlockLastFtnFrm
)
2743 pLastFtnFrm
->ColUnlock();
2745 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2746 // enable lock of lower object position before format of footnote frame.
2747 pLastFtnFrm
->UnlockPosOfLowerObjs();
2748 pLastFtnFrm
->Calc();
2749 // pLastFtnFrm->UnlockPosOfLowerObjs();
2750 // no extra notify for footnote frame
2751 // delete pFtnFrmNotify;
2753 if ( !bLock
&& bUnlockLastFtnFrm
&&
2754 !pLastFtnFrm
->GetLower() &&
2755 !pLastFtnFrm
->IsColLocked() &&
2756 !pLastFtnFrm
->IsBackMoveLocked() )
2766 /*************************************************************************
2768 |* SwPageFrm::UpdateFtnNum()
2770 |* Ersterstellung MA 02. Mar. 93
2771 |* Letzte Aenderung AMA 29. Oct. 98
2773 |*************************************************************************/
2775 void SwPageFrm::UpdateFtnNum()
2777 //Seitenweise Numerierung nur wenn es am Dokument so eingestellt ist.
2778 if ( GetFmt()->GetDoc()->GetFtnInfo().eNum
!= FTNNUM_PAGE
)
2781 SwLayoutFrm
* pBody
= FindBodyCont();
2782 if( !pBody
|| !pBody
->Lower() )
2785 SwCntntFrm
* pCntnt
= pBody
->ContainsCntnt();
2788 while( pCntnt
&& pCntnt
->FindPageFrm() == this )
2790 if( ((SwTxtFrm
*)pCntnt
)->HasFtn() )
2792 SwFtnBossFrm
* pBoss
= pCntnt
->FindFtnBossFrm( TRUE
);
2793 if( pBoss
->GetUpper()->IsSctFrm() &&
2794 ((SwSectionFrm
*)pBoss
->GetUpper())->IsOwnFtnNum() )
2795 pCntnt
= ((SwSectionFrm
*)pBoss
->GetUpper())->FindLastCntnt();
2798 SwFtnFrm
* pFtn
= (SwFtnFrm
*)pBoss
->FindFirstFtn( pCntnt
);
2801 SwTxtFtn
* pTxtFtn
= pFtn
->GetAttr();
2802 if( !pTxtFtn
->GetFtn().IsEndNote() &&
2803 !pTxtFtn
->GetFtn().GetNumStr().Len() &&
2804 !pFtn
->GetMaster() &&
2805 (pTxtFtn
->GetFtn().GetNumber() != ++nNum
) )
2806 pTxtFtn
->SetNumber( nNum
);
2807 if ( pFtn
->GetNext() )
2808 pFtn
= (SwFtnFrm
*)pFtn
->GetNext();
2811 SwFtnBossFrm
* pTmpBoss
= pFtn
->FindFtnBossFrm( TRUE
);
2812 SwPageFrm
* pPage
= pTmpBoss
->FindPageFrm();
2814 lcl_NextFtnBoss( pTmpBoss
, pPage
, FALSE
);
2817 SwFtnContFrm
*pCont
= pTmpBoss
->FindNearestFtnCont();
2819 pFtn
= (SwFtnFrm
*)pCont
->Lower();
2822 if( pFtn
&& pFtn
->GetRef() != pCntnt
)
2827 pCntnt
= pCntnt
->FindNextCnt();
2831 /*************************************************************************
2833 |* SwFtnBossFrm::SetFtnDeadLine()
2835 |* Ersterstellung MA 02. Aug. 93
2836 |* Letzte Aenderung MA 16. Nov. 98
2838 |*************************************************************************/
2840 void SwFtnBossFrm::SetFtnDeadLine( const SwTwips nDeadLine
)
2842 SwFrm
*pBody
= FindBodyCont();
2845 SwFrm
*pCont
= FindFtnCont();
2846 const SwTwips nMax
= nMaxFtnHeight
;//Aktuelle MaxHeight nicht ueberschreiten.
2851 nMaxFtnHeight
= -(pCont
->Frm().*fnRect
->fnBottomDist
)( nDeadLine
);
2854 nMaxFtnHeight
= -(pBody
->Frm().*fnRect
->fnBottomDist
)( nDeadLine
);
2856 if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
2857 nMaxFtnHeight
+= pBody
->Grow( LONG_MAX
, TRUE
);
2859 nMaxFtnHeight
+= FindSctFrm()->Grow( LONG_MAX
, TRUE
);
2861 if ( nMaxFtnHeight
< 0 )
2863 if ( nMax
!= LONG_MAX
&& nMaxFtnHeight
> nMax
)
2864 nMaxFtnHeight
= nMax
;
2867 /*************************************************************************
2869 |* SwFtnBossFrm::GetVarSpace()
2871 |* Ersterstellung MA 03. Apr. 95
2872 |* Letzte Aenderung MA 16. Nov. 98
2874 |*************************************************************************/
2875 SwTwips
SwFtnBossFrm::GetVarSpace() const
2877 //Fuer Seiten soll ein Wert von 20% der Seitenhoehe nicht unterschritten
2878 //werden (->AMA: was macht MS da?)
2879 //->AMA: Was ist da fuer Bereiche sinnvoll (und kompatibel zu MS ;-)?
2880 //AMA: MS kennt scheinbar kein Begrenzung, die Fussnoten nehmen durchaus
2881 // die ganze Seite/Spalte ein.
2883 const SwPageFrm
* pPg
= FindPageFrm();
2884 ASSERT( pPg
|| IsInSct(), "Footnote lost page" );
2886 const SwFrm
*pBody
= FindBodyCont();
2894 SwTwips nTmp
= (*fnRect
->fnYDiff
)( (pBody
->*fnRect
->fnGetPrtTop
)(),
2895 (Frm().*fnRect
->fnGetTop
)() );
2896 const SwSectionFrm
* pSect
= FindSctFrm();
2897 // Endnotes in a ftncontainer causes a deadline:
2898 // the bottom of the last contentfrm
2899 if( pSect
->IsEndnAtEnd() ) // endnotes allowed?
2901 ASSERT( !Lower() || !Lower()->GetNext() || Lower()->GetNext()->
2902 IsFtnContFrm(), "FtnContainer exspected" );
2903 const SwFtnContFrm
* pCont
= Lower() ?
2904 (SwFtnContFrm
*)Lower()->GetNext() : 0;
2907 SwFtnFrm
* pFtn
= (SwFtnFrm
*)pCont
->Lower();
2910 if( pFtn
->GetAttr()->GetFtn().IsEndNote() )
2912 SwFrm
* pFrm
= ((SwLayoutFrm
*)Lower())->Lower();
2915 while( pFrm
->GetNext() )
2916 pFrm
= pFrm
->GetNext(); // last cntntfrm
2917 nTmp
+= (*fnRect
->fnYDiff
)(
2918 (Frm().*fnRect
->fnGetTop
)(),
2919 (pFrm
->Frm().*fnRect
->fnGetBottom
)() );
2923 pFtn
= (SwFtnFrm
*)pFtn
->GetNext();
2931 nRet
= - (pPg
->Prt().*fnRect
->fnGetHeight
)()/5;
2932 nRet
+= (pBody
->Frm().*fnRect
->fnGetHeight
)();
2939 GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
2940 nRet
+= BROWSE_HEIGHT
- Frm().Height();
2944 /*************************************************************************
2946 |* SwFtnBossFrm::NeighbourhoodAdjustment(SwFrm*)
2948 |* gibt Auskunft, ob die Groessenveraenderung von pFrm von AdjustNeighbourhood(...)
2949 |* oder von Grow/Shrink(..) verarbeitet werden sollte.
2950 |* Bei einem PageFrm oder in Spalten direkt unterhalb der Seite muss AdjustNei..
2951 |* gerufen werden, in Rahmenspalten Grow/Shrink.
2952 |* Spannend sind die spaltigen Bereiche: Wenn es in der Spalte einen Fussnotencontainer
2953 |* gibt und die Fussnoten nicht vom Bereich eingesammelt werden, ist ein Adjust..,
2954 |* ansonsten ein Grow/Shrink notwendig.
2956 |* Ersterstellung AMA 09. Dec 98
2957 |* Letzte Aenderung AMA 09. Dec 98
2959 |*************************************************************************/
2961 BYTE
SwFtnBossFrm::_NeighbourhoodAdjustment( const SwFrm
* ) const
2963 BYTE nRet
= NA_ONLY_ADJUST
;
2964 if( GetUpper() && !GetUpper()->IsPageBodyFrm() )
2966 // Spaltige Rahmen erfordern Grow/Shrink
2967 if( GetUpper()->IsFlyFrm() )
2968 nRet
= NA_GROW_SHRINK
;
2971 ASSERT( GetUpper()->IsSctFrm(), "NeighbourhoodAdjustment: Unexspected Upper" );
2972 if( !GetNext() && !GetPrev() )
2973 nRet
= NA_GROW_ADJUST
; // section with a single column (FtnAtEnd)
2976 const SwFrm
* pTmp
= Lower();
2977 ASSERT( pTmp
, "NeighbourhoodAdjustment: Missing Lower()" );
2978 if( !pTmp
->GetNext() )
2979 nRet
= NA_GROW_SHRINK
;
2980 else if( !GetUpper()->IsColLocked() )
2981 nRet
= NA_ADJUST_GROW
;
2982 ASSERT( !pTmp
->GetNext() || pTmp
->GetNext()->IsFtnContFrm(),
2983 "NeighbourhoodAdjustment: Who's that guy?" );
2990 /*************************************************************************
2992 |* SwPageFrm::SetColMaxFtnHeight()
2994 |* Ersterstellung AMA 29. Oct 98
2995 |* Letzte Aenderung AMA 29. Oct 98
2997 |*************************************************************************/
2998 void SwPageFrm::SetColMaxFtnHeight()
3000 SwLayoutFrm
*pBody
= FindBodyCont();
3001 if( pBody
&& pBody
->Lower() && pBody
->Lower()->IsColumnFrm() )
3003 SwColumnFrm
* pCol
= (SwColumnFrm
*)pBody
->Lower();
3006 pCol
->SetMaxFtnHeight( GetMaxFtnHeight() );
3007 pCol
= (SwColumnFrm
*)pCol
->GetNext();
3012 /*************************************************************************
3014 |* SwLayoutFrm::MoveLowerFtns
3016 |* Ersterstellung MA 01. Sep. 94
3017 |* Letzte Aenderung MA 05. Sep. 95
3019 |*************************************************************************/
3022 BOOL
SwLayoutFrm::MoveLowerFtns( SwCntntFrm
*pStart
, SwFtnBossFrm
*pOldBoss
,
3023 SwFtnBossFrm
*pNewBoss
, const BOOL bFtnNums
)
3025 SwDoc
*pDoc
= GetFmt()->GetDoc();
3026 if ( !pDoc
->GetFtnIdxs().Count() )
3028 if( pDoc
->GetFtnInfo().ePos
== FTNPOS_CHAPTER
&&
3029 ( !IsInSct() || !FindSctFrm()->IsFtnAtEnd() ) )
3033 pNewBoss
= FindFtnBossFrm( TRUE
);
3034 if ( pNewBoss
== pOldBoss
)
3037 BOOL bMoved
= FALSE
;
3039 pStart
= ContainsCntnt();
3041 SvPtrarr
aFtnArr( 5, 5 );
3043 while ( IsAnLower( pStart
) )
3045 if ( ((SwTxtFrm
*)pStart
)->HasFtn() )
3047 // OD 03.04.2003 #108446# - To avoid unnecessary moves of footnotes
3048 // use new parameter <_bCollectOnlyPreviousFtn> (4th parameter of
3049 // method <SwFtnBossFrm::CollectFtn(..)>) to control, that only
3050 // footnotes have to be collected, that are positioned before the
3051 // new dedicated footnote boss frame.
3052 pNewBoss
->CollectFtns( pStart
, pOldBoss
, aFtnArr
, sal_True
);
3054 pStart
= pStart
->GetNextCntntFrm();
3057 ASSERT( pOldBoss
->IsInSct() == pNewBoss
->IsInSct(),
3058 "MoveLowerFtns: Section confusion" );
3060 SwLayoutFrm
* pNewChief
= 0;
3061 SwLayoutFrm
* pOldChief
= 0;
3062 if( pStart
&& pOldBoss
->IsInSct() && ( pOldChief
= pOldBoss
->FindSctFrm() )
3063 != ( pNewChief
= pNewBoss
->FindSctFrm() ) )
3065 pFtnArr
= new SvPtrarr( 5, 5 );
3066 pOldChief
= pOldBoss
->FindFtnBossFrm( TRUE
);
3067 pNewChief
= pNewBoss
->FindFtnBossFrm( TRUE
);
3068 while( pOldChief
->IsAnLower( pStart
) )
3070 if ( ((SwTxtFrm
*)pStart
)->HasFtn() )
3071 ((SwFtnBossFrm
*)pNewChief
)->CollectFtns( pStart
,
3072 (SwFtnBossFrm
*)pOldBoss
, *pFtnArr
);
3073 pStart
= pStart
->GetNextCntntFrm();
3075 if( !pFtnArr
->Count() )
3084 if ( aFtnArr
.Count() || pFtnArr
)
3086 if( aFtnArr
.Count() )
3087 pNewBoss
->_MoveFtns( aFtnArr
, TRUE
);
3090 ((SwFtnBossFrm
*)pNewChief
)->_MoveFtns( *pFtnArr
, TRUE
);
3095 // Nur bei einem Seitenwechsel muss die FtnNum neu berechnet werden
3098 SwPageFrm
* pOldPage
= pOldBoss
->FindPageFrm();
3099 SwPageFrm
* pNewPage
=pNewBoss
->FindPageFrm();
3100 if( pOldPage
!= pNewPage
)
3102 pOldPage
->UpdateFtnNum();
3103 pNewPage
->UpdateFtnNum();
3110 /*************************************************************************
3112 |* SwLayoutFrm::MoveFtnCntFwd()
3114 |* Ersterstellung MA 24. Nov. 94
3115 |* Letzte Aenderung MA 15. Jun. 95
3117 |*************************************************************************/
3120 BOOL
SwCntntFrm::MoveFtnCntFwd( BOOL bMakePage
, SwFtnBossFrm
*pOldBoss
)
3122 ASSERT( IsInFtn(), "Keine Ftn." );
3123 SwLayoutFrm
*pFtn
= FindFtnFrm();
3125 // The first paragraph in the first footnote in the first column in the
3126 // sectionfrm at the top of the page has not to move forward, if the
3127 // columnbody is empty.
3128 if( pOldBoss
->IsInSct() && !pOldBoss
->GetIndPrev() && !GetIndPrev() &&
3131 SwLayoutFrm
* pBody
= pOldBoss
->FindBodyCont();
3132 if( !pBody
|| !pBody
->Lower() )
3136 //fix(9538): Wenn die Ftn noch Nachbarn hinter sich hat, so muessen
3137 //diese ersteinmal verschwinden.
3138 SwLayoutFrm
*pNxt
= (SwLayoutFrm
*)pFtn
->GetNext();
3139 SwLayoutFrm
*pLst
= 0;
3142 while ( pNxt
->GetNext() )
3143 pNxt
= (SwLayoutFrm
*)pNxt
->GetNext();
3148 SwCntntFrm
*pCnt
= pNxt
->ContainsCntnt();
3150 pCnt
->MoveFtnCntFwd( TRUE
, pOldBoss
);
3151 pNxt
= (SwLayoutFrm
*)pFtn
->GetNext();
3155 BOOL bSamePage
= TRUE
;
3156 SwLayoutFrm
*pNewUpper
=
3157 GetLeaf( bMakePage
? MAKEPAGE_INSERT
: MAKEPAGE_NONE
, TRUE
);
3161 BOOL bSameBoss
= TRUE
;
3162 SwFtnBossFrm
* const pNewBoss
= pNewUpper
->FindFtnBossFrm();
3163 //Wechseln wir die Spalte/Seite?
3164 if ( FALSE
== ( bSameBoss
= pNewBoss
== pOldBoss
) )
3166 bSamePage
= pOldBoss
->FindPageFrm() == pNewBoss
->FindPageFrm(); // Seitenwechsel?
3170 //Das Layoutblatt, dass wir fuer Fussnoten bekommen ist entweder
3171 //ein Fussnotencontainer oder eine Fussnote
3172 //Wenn es eine Fussnote ist, und sie die gleiche Fussnotenreferez
3173 //wie der alte Upper hat, so moven wir uns direkt hinein.
3174 //Ist die Referenz einen andere oder ist es ein Container, so wird
3175 //eine neue Fussnote erzeugt und in den Container gestellt.
3176 // Wenn wir in einem Bereich innerhalb der Fussnote sind, muss
3177 // SectionFrame noch angelegt werden.
3178 SwFtnFrm
* pTmpFtn
= pNewUpper
->IsFtnFrm() ? ((SwFtnFrm
*)pNewUpper
) : 0;
3181 ASSERT( pNewUpper
->IsFtnContFrm(), "Neuer Upper kein FtnCont.");
3182 SwFtnContFrm
*pCont
= (SwFtnContFrm
*)pNewUpper
;
3184 //Fussnote erzeugen.
3185 SwFtnFrm
*pOld
= FindFtnFrm();
3186 pTmpFtn
= new SwFtnFrm( pOld
->GetFmt()->GetDoc()->GetDfltFrmFmt(),
3187 pOld
->GetRef(), pOld
->GetAttr() );
3188 //Verkettung der Fussnoten.
3189 if ( pOld
->GetFollow() )
3191 pTmpFtn
->SetFollow( pOld
->GetFollow() );
3192 pOld
->GetFollow()->SetMaster( pTmpFtn
);
3194 pOld
->SetFollow( pTmpFtn
);
3195 pTmpFtn
->SetMaster( pOld
);
3196 SwFrm
* pNx
= pCont
->Lower();
3197 if( pNx
&& pTmpFtn
->GetAttr()->GetFtn().IsEndNote() )
3198 while(pNx
&& !((SwFtnFrm
*)pNx
)->GetAttr()->GetFtn().IsEndNote())
3199 pNx
= pNx
->GetNext();
3200 pTmpFtn
->Paste( pCont
, pNx
);
3203 ASSERT( pTmpFtn
->GetAttr() == FindFtnFrm()->GetAttr(), "Wrong Footnote!" );
3204 // Bereiche in Fussnoten beduerfen besonderer Behandlung
3205 SwLayoutFrm
*pNewUp
= pTmpFtn
;
3208 SwSectionFrm
* pSect
= FindSctFrm();
3209 // Bereich in Fussnote (oder nur Fussnote in Bereich)?
3210 if( pSect
->IsInFtn() )
3212 if( pTmpFtn
->Lower() && pTmpFtn
->Lower()->IsSctFrm() &&
3213 pSect
->GetFollow() == (SwSectionFrm
*)pTmpFtn
->Lower() )
3214 pNewUp
= (SwSectionFrm
*)pTmpFtn
->Lower();
3217 pNewUp
= new SwSectionFrm( *pSect
, FALSE
);
3218 pNewUp
->InsertBefore( pTmpFtn
, pTmpFtn
->Lower() );
3219 static_cast<SwSectionFrm
*>(pNewUp
)->Init();
3220 pNewUp
->Frm().Pos() = pTmpFtn
->Frm().Pos();
3221 pNewUp
->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
3223 // Wenn unser Bereichsframe einen Nachfolger hat, so muss dieser
3224 // umgehaengt werden hinter den neuen Follow der Bereichsframes.
3225 SwFrm
* pTmp
= pSect
->GetNext();
3229 if( pTmp
->IsCntntFrm() )
3230 pTmpNxt
= (SwCntntFrm
*)pTmp
;
3231 else if( pTmp
->IsSctFrm() )
3232 pTmpNxt
= (SwSectionFrm
*)pTmp
;
3235 ASSERT( pTmp
->IsTabFrm(), "GetNextSctLeaf: Wrong Type" );
3236 pTmpNxt
= (SwTabFrm
*)pTmp
;
3238 pTmpNxt
->MoveSubTree( pTmpFtn
, pNewUp
->GetNext() );
3244 MoveSubTree( pNewUp
, pNewUp
->Lower() );
3247 Prepare( PREP_BOSS_CHGD
);
3252 /*************************************************************************
3254 |* class SwSaveFtnHeight
3256 |* Ersterstellung MA 19. Jan. 94
3257 |* Letzte Aenderung MA 19. Jan. 94
3259 |*************************************************************************/
3262 SwSaveFtnHeight::SwSaveFtnHeight( SwFtnBossFrm
*pBs
, const SwTwips nDeadLine
) :
3264 nOldHeight( pBs
->GetMaxFtnHeight() )
3266 pBoss
->SetFtnDeadLine( nDeadLine
);
3267 nNewHeight
= pBoss
->GetMaxFtnHeight();
3272 SwSaveFtnHeight::~SwSaveFtnHeight()
3274 //Wenn zwischendurch jemand an der DeadLine gedreht hat, so lassen wir
3276 if ( nNewHeight
== pBoss
->GetMaxFtnHeight() )
3277 pBoss
->nMaxFtnHeight
= nOldHeight
;
3282 //JP 15.10.2001: in a non pro version test if the attribute has the same
3283 // meaning which his reference is
3285 // Normally, the pRef member and the GetRefFromAttr() result has to be
3286 // identically. Sometimes footnote will be moved from a master to its follow,
3287 // but the GetRef() is called first, so we have to ignore a master/follow
3290 const SwCntntFrm
* SwFtnFrm::GetRef() const
3292 const SwCntntFrm
* pRefAttr
= GetRefFromAttr();
3293 ASSERT( pRef
== pRefAttr
|| pRef
->IsAnFollow( pRefAttr
)
3294 || pRefAttr
->IsAnFollow( pRef
),
3295 "access to deleted Frame? pRef != pAttr->GetRef()" );
3299 SwCntntFrm
* SwFtnFrm::GetRef()
3301 const SwCntntFrm
* pRefAttr
= GetRefFromAttr();
3302 ASSERT( pRef
== pRefAttr
|| pRef
->IsAnFollow( pRefAttr
)
3303 || pRefAttr
->IsAnFollow( pRef
),
3304 "access to deleted Frame? pRef != pAttr->GetRef()" );
3310 const SwCntntFrm
* SwFtnFrm::GetRefFromAttr() const
3312 SwFtnFrm
* pThis
= (SwFtnFrm
*)this;
3313 return pThis
->GetRefFromAttr();
3316 SwCntntFrm
* SwFtnFrm::GetRefFromAttr()
3318 ASSERT( pAttr
, "invalid Attribute" );
3319 SwTxtNode
& rTNd
= (SwTxtNode
&)pAttr
->GetTxtNode();
3320 SwPosition
aPos( rTNd
, SwIndex( &rTNd
, *pAttr
->GetStart() ));
3321 SwCntntFrm
* pCFrm
= rTNd
.GetFrm( 0, &aPos
, FALSE
);
3325 /** search for last content in the current footnote frame
3327 OD 2005-12-02 #i27138#
3331 SwCntntFrm
* SwFtnFrm::FindLastCntnt()
3333 SwCntntFrm
* pLastCntntFrm( 0L );
3335 // find last lower, which is a content frame or contains content.
3336 // hidden text frames, empty sections and empty tables have to be skipped.
3337 SwFrm
* pLastLowerOfFtn( GetLower() );
3338 SwFrm
* pTmpLastLower( pLastLowerOfFtn
);
3339 while ( pTmpLastLower
&& pTmpLastLower
->GetNext() )
3341 pTmpLastLower
= pTmpLastLower
->GetNext();
3342 if ( ( pTmpLastLower
->IsTxtFrm() &&
3343 !static_cast<SwTxtFrm
*>(pTmpLastLower
)->IsHiddenNow() ) ||
3344 ( pTmpLastLower
->IsSctFrm() &&
3345 static_cast<SwSectionFrm
*>(pTmpLastLower
)->GetSection() &&
3346 static_cast<SwSectionFrm
*>(pTmpLastLower
)->ContainsCntnt() ) ||
3347 ( pTmpLastLower
->IsTabFrm() &&
3348 static_cast<SwTabFrm
*>(pTmpLastLower
)->ContainsCntnt() ) )
3350 pLastLowerOfFtn
= pTmpLastLower
;
3354 // determine last content frame depending on type of found last lower.
3355 if ( pLastLowerOfFtn
&& pLastLowerOfFtn
->IsTabFrm() )
3357 pLastCntntFrm
= static_cast<SwTabFrm
*>(pLastLowerOfFtn
)->FindLastCntnt();
3359 else if ( pLastLowerOfFtn
&& pLastLowerOfFtn
->IsSctFrm() )
3361 pLastCntntFrm
= static_cast<SwSectionFrm
*>(pLastLowerOfFtn
)->FindLastCntnt();
3365 pLastCntntFrm
= dynamic_cast<SwCntntFrm
*>(pLastLowerOfFtn
);
3368 return pLastCntntFrm
;