xref: /trunk/main/sw/source/core/layout/ftnfrm.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <txtftn.hxx>
29cdf0e10cSrcweir #include <fmtftn.hxx>
30cdf0e10cSrcweir #include <ftnidx.hxx>
31cdf0e10cSrcweir #include <pagefrm.hxx>
32cdf0e10cSrcweir #include <colfrm.hxx>
33cdf0e10cSrcweir #include <rootfrm.hxx>
34cdf0e10cSrcweir #include <cntfrm.hxx>
35cdf0e10cSrcweir #include <doc.hxx>
36cdf0e10cSrcweir #include <ndtxt.hxx>
37cdf0e10cSrcweir #include <frmtool.hxx>
38cdf0e10cSrcweir #include <swtable.hxx>
39cdf0e10cSrcweir #include <ftnfrm.hxx>
40cdf0e10cSrcweir #include <txtfrm.hxx>
41cdf0e10cSrcweir #include <tabfrm.hxx>
42cdf0e10cSrcweir #include <pagedesc.hxx>
43cdf0e10cSrcweir #include <ftninfo.hxx>
44cdf0e10cSrcweir #include <ndindex.hxx>
45cdf0e10cSrcweir #include <sectfrm.hxx>
46cdf0e10cSrcweir #include <pam.hxx>
47cdf0e10cSrcweir #include <objectformatter.hxx>
48cdf0e10cSrcweir #include "viewopt.hxx"
49cdf0e10cSrcweir #include "viewsh.hxx"
50cdf0e10cSrcweir #include <switerator.hxx>
51cdf0e10cSrcweir 
52cdf0e10cSrcweir /*************************************************************************
53cdf0e10cSrcweir |*
54cdf0e10cSrcweir |*  lcl_FindFtnPos()        Sucht die Position des Attributes im FtnArray am
55cdf0e10cSrcweir |*      Dokument, dort stehen die Fussnoten gluecklicherweise nach ihrem
56cdf0e10cSrcweir |*      Index sortiert.
57cdf0e10cSrcweir |*
58cdf0e10cSrcweir |*************************************************************************/
59cdf0e10cSrcweir 
60cdf0e10cSrcweir #define ENDNOTE 0x80000000
61cdf0e10cSrcweir 
lcl_FindFtnPos(const SwDoc * pDoc,const SwTxtFtn * pAttr)62cdf0e10cSrcweir sal_uLong MA_FASTCALL lcl_FindFtnPos( const SwDoc *pDoc, const SwTxtFtn *pAttr )
63cdf0e10cSrcweir {
64cdf0e10cSrcweir     const SwFtnIdxs &rFtnIdxs = pDoc->GetFtnIdxs();
65cdf0e10cSrcweir 
66cdf0e10cSrcweir #ifdef MA_DEBUG
67cdf0e10cSrcweir     //Wenn das Array nicht stimmt haben wir ein Problem, denn viele
68cdf0e10cSrcweir     //Ftn-Functions bauen auf dem Array auf.
69cdf0e10cSrcweir     for ( sal_uInt16 k = 0; k+1 < rFtnIdxs.Count(); ++k )
70cdf0e10cSrcweir     {
71cdf0e10cSrcweir         SwIndex aIdx1(&pDoc->GetNodes());
72cdf0e10cSrcweir         SwIndex aIdx2(&pDoc->GetNodes());
73cdf0e10cSrcweir         rFtnIdxs[k]->pFtn->  GetTxtNode().GetIndex(aIdx1);
74cdf0e10cSrcweir         rFtnIdxs[k+1]->pFtn->GetTxtNode().GetIndex(aIdx2);
75cdf0e10cSrcweir         if ( aIdx1.GetIndex() > aIdx2.GetIndex() )
76cdf0e10cSrcweir         {
77cdf0e10cSrcweir             ASSERT( !rFtnIdxs.Count(), "FtnIdxs not up to date" );
78cdf0e10cSrcweir         }
79cdf0e10cSrcweir         else if ( aIdx1.GetIndex() == aIdx2.GetIndex() )
80cdf0e10cSrcweir         {
81cdf0e10cSrcweir             SwTxtFtn *p1 = rFtnIdxs[k];
82cdf0e10cSrcweir             SwTxtFtn *p2 = rFtnIdxs[k+1];
83cdf0e10cSrcweir             ASSERT( *p1->GetStart() < *p2->GetStart(),
84cdf0e10cSrcweir                     "FtnIdxs not up to date" );
85cdf0e10cSrcweir         }
86cdf0e10cSrcweir     }
87cdf0e10cSrcweir #endif
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     sal_uInt16 nRet;
90cdf0e10cSrcweir     SwTxtFtnPtr pBla = (SwTxtFtn*)pAttr;
91cdf0e10cSrcweir     if ( rFtnIdxs.Seek_Entry( pBla, &nRet ) )
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir         if( pAttr->GetFtn().IsEndNote() )
94cdf0e10cSrcweir             return sal_uLong(nRet) + ENDNOTE;
95cdf0e10cSrcweir         return nRet;
96cdf0e10cSrcweir     }
97cdf0e10cSrcweir     ASSERT( !pDoc, "FtnPos not found." );
98cdf0e10cSrcweir     return 0;
99cdf0e10cSrcweir }
100cdf0e10cSrcweir 
operator <(const SwTxtFtn * pTxtFtn) const101cdf0e10cSrcweir sal_Bool SwFtnFrm::operator<( const SwTxtFtn* pTxtFtn ) const
102cdf0e10cSrcweir {
103cdf0e10cSrcweir     const SwDoc* pDoc = GetFmt()->GetDoc();
104cdf0e10cSrcweir     ASSERT( pDoc, "SwFtnFrm: Missing doc!" );
105cdf0e10cSrcweir     return lcl_FindFtnPos( pDoc, GetAttr() ) <
106cdf0e10cSrcweir            lcl_FindFtnPos( pDoc, pTxtFtn );
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir /*************************************************************************
110cdf0e10cSrcweir |*
111cdf0e10cSrcweir |*  sal_Bool lcl_NextFtnBoss( SwFtnBossFrm* pBoss, SwPageFrm* pPage)
112cdf0e10cSrcweir |*  setzt pBoss auf den naechsten SwFtnBossFrm, das kann entweder eine Spalte
113cdf0e10cSrcweir |*  oder eine Seite (ohne Spalten) sein. Wenn die Seite dabei gewechselt wird
114cdf0e10cSrcweir |*  enthaelt pPage die neue Seite und die Funktion liefert sal_True.
115cdf0e10cSrcweir |*
116cdf0e10cSrcweir |*************************************************************************/
117cdf0e10cSrcweir 
lcl_NextFtnBoss(SwFtnBossFrm * & rpBoss,SwPageFrm * & rpPage,sal_Bool bDontLeave)118cdf0e10cSrcweir sal_Bool lcl_NextFtnBoss( SwFtnBossFrm* &rpBoss, SwPageFrm* &rpPage,
119cdf0e10cSrcweir     sal_Bool bDontLeave )
120cdf0e10cSrcweir {
121cdf0e10cSrcweir     if( rpBoss->IsColumnFrm() )
122cdf0e10cSrcweir     {
123cdf0e10cSrcweir         if( rpBoss->GetNext() )
124cdf0e10cSrcweir         {
125cdf0e10cSrcweir             rpBoss = (SwFtnBossFrm*)rpBoss->GetNext(); //naechste Spalte
126cdf0e10cSrcweir             return sal_False;
127cdf0e10cSrcweir         }
128cdf0e10cSrcweir         if( rpBoss->IsInSct() )
129cdf0e10cSrcweir         {
130cdf0e10cSrcweir             SwSectionFrm* pSct = rpBoss->FindSctFrm()->GetFollow();
131cdf0e10cSrcweir             if( pSct )
132cdf0e10cSrcweir             {
133cdf0e10cSrcweir                 ASSERT( pSct->Lower() && pSct->Lower()->IsColumnFrm(),
134cdf0e10cSrcweir                         "Where's the column?" );
135cdf0e10cSrcweir                 rpBoss = (SwColumnFrm*)pSct->Lower();
136cdf0e10cSrcweir                 SwPageFrm* pOld = rpPage;
137cdf0e10cSrcweir                 rpPage = pSct->FindPageFrm();
138cdf0e10cSrcweir                 return pOld != rpPage;
139cdf0e10cSrcweir             }
140cdf0e10cSrcweir             else if( bDontLeave )
141cdf0e10cSrcweir             {
142cdf0e10cSrcweir                 rpPage = NULL;
143cdf0e10cSrcweir                 rpBoss = NULL;
144cdf0e10cSrcweir                 return sal_False;
145cdf0e10cSrcweir             }
146cdf0e10cSrcweir         }
147cdf0e10cSrcweir     }
148cdf0e10cSrcweir     rpPage = (SwPageFrm*)rpPage->GetNext(); // naechste Seite
149cdf0e10cSrcweir     rpBoss = rpPage;
150cdf0e10cSrcweir     if( rpPage )
151cdf0e10cSrcweir     {
152cdf0e10cSrcweir         SwLayoutFrm* pBody = rpPage->FindBodyCont();
153cdf0e10cSrcweir         if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
154cdf0e10cSrcweir             rpBoss = (SwFtnBossFrm*)pBody->Lower(); // erste Spalte
155cdf0e10cSrcweir     }
156cdf0e10cSrcweir     return sal_True;
157cdf0e10cSrcweir }
158cdf0e10cSrcweir 
159cdf0e10cSrcweir /*************************************************************************
160cdf0e10cSrcweir |*
161cdf0e10cSrcweir |*  sal_uInt16 lcl_ColumnNum( SwFrm* pBoss )
162cdf0e10cSrcweir |*  liefert die Spaltennummer, wenn pBoss eine Spalte ist,
163cdf0e10cSrcweir |*  sonst eine Null (bei Seiten).
164cdf0e10cSrcweir |*
165cdf0e10cSrcweir |*************************************************************************/
166cdf0e10cSrcweir 
lcl_ColumnNum(const SwFrm * pBoss)167cdf0e10cSrcweir sal_uInt16 lcl_ColumnNum( const SwFrm* pBoss )
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     sal_uInt16 nRet = 0;
170cdf0e10cSrcweir     if( !pBoss->IsColumnFrm() )
171cdf0e10cSrcweir         return 0;
172cdf0e10cSrcweir     const SwFrm* pCol;
173cdf0e10cSrcweir     if( pBoss->IsInSct() )
174cdf0e10cSrcweir     {
175cdf0e10cSrcweir         pCol = pBoss->GetUpper()->FindColFrm();
176cdf0e10cSrcweir         if( pBoss->GetNext() || pBoss->GetPrev() )
177cdf0e10cSrcweir         {
178cdf0e10cSrcweir             while( pBoss )
179cdf0e10cSrcweir             {
180cdf0e10cSrcweir                 ++nRet;                     // Section columns
181cdf0e10cSrcweir                 pBoss = pBoss->GetPrev();
182cdf0e10cSrcweir             }
183cdf0e10cSrcweir         }
184cdf0e10cSrcweir     }
185cdf0e10cSrcweir     else
186cdf0e10cSrcweir         pCol = pBoss;
187cdf0e10cSrcweir     while( pCol )
188cdf0e10cSrcweir     {
189cdf0e10cSrcweir         nRet += 256;                    // Page columns
190cdf0e10cSrcweir         pCol = pCol->GetPrev();
191cdf0e10cSrcweir     }
192cdf0e10cSrcweir     return nRet;
193cdf0e10cSrcweir }
194cdf0e10cSrcweir 
195cdf0e10cSrcweir /*************************************************************************
196cdf0e10cSrcweir |*
197cdf0e10cSrcweir |*  SwFtnContFrm::SwFtnContFrm()
198cdf0e10cSrcweir |*
199cdf0e10cSrcweir |*************************************************************************/
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 
SwFtnContFrm(SwFrmFmt * pFmt,SwFrm * pSib)202cdf0e10cSrcweir SwFtnContFrm::SwFtnContFrm( SwFrmFmt *pFmt, SwFrm* pSib ):
203cdf0e10cSrcweir     SwLayoutFrm( pFmt, pSib )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir     nType = FRMC_FTNCONT;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir 
208cdf0e10cSrcweir 
209cdf0e10cSrcweir // lcl_Undersize(..) klappert einen SwFrm und dessen Inneres ab
210cdf0e10cSrcweir // und liefert die Summe aller TxtFrm-Vergroesserungswuensche
211cdf0e10cSrcweir 
lcl_Undersize(const SwFrm * pFrm)212cdf0e10cSrcweir long lcl_Undersize( const SwFrm* pFrm )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir     long nRet = 0;
215cdf0e10cSrcweir     SWRECTFN( pFrm )
216cdf0e10cSrcweir     if( pFrm->IsTxtFrm() )
217cdf0e10cSrcweir     {
218cdf0e10cSrcweir         if( ((SwTxtFrm*)pFrm)->IsUndersized() )
219cdf0e10cSrcweir         {
220cdf0e10cSrcweir             // Dieser TxtFrm waere gern ein bisschen groesser
221cdf0e10cSrcweir             nRet = ((SwTxtFrm*)pFrm)->GetParHeight() -
222cdf0e10cSrcweir                     (pFrm->Prt().*fnRect->fnGetHeight)();
223cdf0e10cSrcweir             if( nRet < 0 )
224cdf0e10cSrcweir                 nRet = 0;
225cdf0e10cSrcweir         }
226cdf0e10cSrcweir     }
227cdf0e10cSrcweir     else if( pFrm->IsLayoutFrm() )
228cdf0e10cSrcweir     {
229cdf0e10cSrcweir         const SwFrm* pNxt = ((SwLayoutFrm*)pFrm)->Lower();
230cdf0e10cSrcweir         while( pNxt )
231cdf0e10cSrcweir         {
232cdf0e10cSrcweir             nRet += lcl_Undersize( pNxt );
233cdf0e10cSrcweir             pNxt = pNxt->GetNext();
234cdf0e10cSrcweir         }
235cdf0e10cSrcweir     }
236cdf0e10cSrcweir     return nRet;
237cdf0e10cSrcweir }
238cdf0e10cSrcweir 
239cdf0e10cSrcweir /*************************************************************************
240cdf0e10cSrcweir |*
241cdf0e10cSrcweir |*  SwFtnContFrm::Format()
242cdf0e10cSrcweir |*
243cdf0e10cSrcweir |*  Beschreibung:       "Formatiert" den Frame;
244cdf0e10cSrcweir |*                      Die Fixsize wird hier nicht eingestellt.
245cdf0e10cSrcweir |*
246cdf0e10cSrcweir |*************************************************************************/
247cdf0e10cSrcweir 
248cdf0e10cSrcweir 
Format(const SwBorderAttrs *)249cdf0e10cSrcweir void SwFtnContFrm::Format( const SwBorderAttrs * )
250cdf0e10cSrcweir {
251cdf0e10cSrcweir     //GesamtBorder ermitteln, es gibt nur einen Abstand nach oben.
252cdf0e10cSrcweir     const SwPageFrm* pPage = FindPageFrm();
253cdf0e10cSrcweir     const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo();
254cdf0e10cSrcweir     const SwTwips nBorder = rInf.GetTopDist() + rInf.GetBottomDist() +
255cdf0e10cSrcweir                             rInf.GetLineWidth();
256cdf0e10cSrcweir     SWRECTFN( this )
257cdf0e10cSrcweir     if ( !bValidPrtArea )
258cdf0e10cSrcweir     {
259cdf0e10cSrcweir         bValidPrtArea = sal_True;
260cdf0e10cSrcweir         (Prt().*fnRect->fnSetTop)( nBorder );
261cdf0e10cSrcweir         (Prt().*fnRect->fnSetWidth)( (Frm().*fnRect->fnGetWidth)() );
262cdf0e10cSrcweir         (Prt().*fnRect->fnSetHeight)((Frm().*fnRect->fnGetHeight)() - nBorder );
263cdf0e10cSrcweir         if( (Prt().*fnRect->fnGetHeight)() < 0 && !pPage->IsFtnPage() )
264cdf0e10cSrcweir             bValidSize = sal_False;
265cdf0e10cSrcweir     }
266cdf0e10cSrcweir 
267cdf0e10cSrcweir     if ( !bValidSize )
268cdf0e10cSrcweir     {
269cdf0e10cSrcweir         bool bGrow = pPage->IsFtnPage();
270cdf0e10cSrcweir         if( bGrow )
271cdf0e10cSrcweir         {
272cdf0e10cSrcweir             const ViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
273cdf0e10cSrcweir             if( pSh && pSh->GetViewOptions()->getBrowseMode() )
274cdf0e10cSrcweir                 bGrow = false;
275cdf0e10cSrcweir         }
276cdf0e10cSrcweir         if( bGrow )
277cdf0e10cSrcweir                 Grow( LONG_MAX, sal_False );
278cdf0e10cSrcweir         else
279cdf0e10cSrcweir         {
280cdf0e10cSrcweir             //Die Groesse in der VarSize wird durch den Inhalt plus den
281cdf0e10cSrcweir             //Raendern bestimmt.
282cdf0e10cSrcweir             SwTwips nRemaining = 0;
283cdf0e10cSrcweir             SwFrm *pFrm = pLower;
284cdf0e10cSrcweir             while ( pFrm )
285cdf0e10cSrcweir             {   // lcl_Undersize(..) beruecksichtigt (rekursiv) TxtFrms, die gerne
286cdf0e10cSrcweir                 // groesser waeren. Diese entstehen insbesondere in spaltigen Rahmen,
287cdf0e10cSrcweir                 // wenn diese noch nicht ihre maximale Groesse haben.
288cdf0e10cSrcweir                 nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)()
289cdf0e10cSrcweir                               + lcl_Undersize( pFrm );
290cdf0e10cSrcweir                 pFrm = pFrm->GetNext();
291cdf0e10cSrcweir             }
292cdf0e10cSrcweir             //Jetzt noch den Rand addieren
293cdf0e10cSrcweir             nRemaining += nBorder;
294cdf0e10cSrcweir 
295cdf0e10cSrcweir             SwTwips nDiff;
296cdf0e10cSrcweir             if( IsInSct() )
297cdf0e10cSrcweir             {
298cdf0e10cSrcweir                 nDiff = -(Frm().*fnRect->fnBottomDist)(
299cdf0e10cSrcweir                                         (GetUpper()->*fnRect->fnGetPrtBottom)() );
300cdf0e10cSrcweir                 if( nDiff > 0 )
301cdf0e10cSrcweir                 {
302cdf0e10cSrcweir                     if( nDiff > (Frm().*fnRect->fnGetHeight)() )
303cdf0e10cSrcweir                         nDiff = (Frm().*fnRect->fnGetHeight)();
304cdf0e10cSrcweir                     (Frm().*fnRect->fnAddBottom)( -nDiff );
305cdf0e10cSrcweir                     (Prt().*fnRect->fnAddHeight)( -nDiff );
306cdf0e10cSrcweir                 }
307cdf0e10cSrcweir             }
308cdf0e10cSrcweir             nDiff = (Frm().*fnRect->fnGetHeight)() - nRemaining;
309cdf0e10cSrcweir             if ( nDiff > 0 )
310cdf0e10cSrcweir                 Shrink( nDiff );
311cdf0e10cSrcweir             else if ( nDiff < 0 )
312cdf0e10cSrcweir             {
313cdf0e10cSrcweir                 Grow( -nDiff );
314cdf0e10cSrcweir                 //Es kann passieren, dass weniger Platz zur Verfuegung steht,
315cdf0e10cSrcweir                 //als der bereits der Border benoetigt - die Groesse der
316cdf0e10cSrcweir                 //PrtArea wird dann negativ.
317cdf0e10cSrcweir                 SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
318cdf0e10cSrcweir                 if( nPrtHeight < 0 )
319cdf0e10cSrcweir                 {
320cdf0e10cSrcweir                     const SwTwips nTmpDiff = Max( (Prt().*fnRect->fnGetTop)(),
321cdf0e10cSrcweir                                                 -nPrtHeight );
322cdf0e10cSrcweir                     (Prt().*fnRect->fnSubTop)( nTmpDiff );
323cdf0e10cSrcweir                 }
324cdf0e10cSrcweir             }
325cdf0e10cSrcweir         }
326cdf0e10cSrcweir         bValidSize = sal_True;
327cdf0e10cSrcweir     }
328cdf0e10cSrcweir }
329cdf0e10cSrcweir /*************************************************************************
330cdf0e10cSrcweir |*
331cdf0e10cSrcweir |*  SwFtnContFrm::GrowFrm(), ShrinkFrm()
332cdf0e10cSrcweir |*
333cdf0e10cSrcweir |*************************************************************************/
334cdf0e10cSrcweir 
GrowFrm(SwTwips nDist,sal_Bool bTst,sal_Bool)335cdf0e10cSrcweir SwTwips SwFtnContFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool )
336cdf0e10cSrcweir {
337cdf0e10cSrcweir     //Keine Pruefung ob FixSize oder nicht, die FtnContainer sind immer bis
338cdf0e10cSrcweir     //zur Maximalhoehe variabel.
339cdf0e10cSrcweir     //Wenn die Maximalhoehe LONG_MAX ist, so nehmen wir uns soviel Platz wie eben
340cdf0e10cSrcweir     //moeglich.
341cdf0e10cSrcweir     //Wenn die Seite eine spezielle Fussnotenseite ist, so nehmen wir uns auch
342cdf0e10cSrcweir     //soviel Platz wie eben moeglich.
343cdf0e10cSrcweir #ifdef DBG_UTIL
344cdf0e10cSrcweir     if ( !GetUpper() || !GetUpper()->IsFtnBossFrm() )
345870262e3SDon Lewis     {   ASSERT( sal_False, "No FtnBoss." );
346cdf0e10cSrcweir         return 0;
347cdf0e10cSrcweir     }
348cdf0e10cSrcweir #endif
349cdf0e10cSrcweir 
350cdf0e10cSrcweir     SWRECTFN( this )
351cdf0e10cSrcweir     if( (Frm().*fnRect->fnGetHeight)() > 0 &&
352cdf0e10cSrcweir          nDist > ( LONG_MAX - (Frm().*fnRect->fnGetHeight)() ) )
353cdf0e10cSrcweir         nDist = LONG_MAX - (Frm().*fnRect->fnGetHeight)();
354cdf0e10cSrcweir 
355cdf0e10cSrcweir     SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper();
356cdf0e10cSrcweir     if( IsInSct() )
357cdf0e10cSrcweir     {
358cdf0e10cSrcweir         SwSectionFrm* pSect = FindSctFrm();
359cdf0e10cSrcweir         ASSERT( pSect, "GrowFrm: Missing SectFrm" );
360cdf0e10cSrcweir         // In a section, which has to maximize, a footnotecontainer is allowed
361cdf0e10cSrcweir         // to grow, when the section can't grow anymore.
362cdf0e10cSrcweir         if( !bTst && !pSect->IsColLocked() &&
363cdf0e10cSrcweir             pSect->ToMaximize( sal_False ) && pSect->Growable() )
364cdf0e10cSrcweir         {
365cdf0e10cSrcweir             pSect->InvalidateSize();
366cdf0e10cSrcweir             return 0;
367cdf0e10cSrcweir         }
368cdf0e10cSrcweir     }
369cdf0e10cSrcweir     const ViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
370cdf0e10cSrcweir     const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
371cdf0e10cSrcweir     SwPageFrm *pPage = pBoss->FindPageFrm();
372cdf0e10cSrcweir     if ( bBrowseMode || !pPage->IsFtnPage() )
373cdf0e10cSrcweir     {
374cdf0e10cSrcweir         if ( pBoss->GetMaxFtnHeight() != LONG_MAX )
375cdf0e10cSrcweir         {
376cdf0e10cSrcweir             nDist = Min( nDist, pBoss->GetMaxFtnHeight()
377cdf0e10cSrcweir                          - (Frm().*fnRect->fnGetHeight)() );
378cdf0e10cSrcweir             if ( nDist <= 0 )
379cdf0e10cSrcweir                 return 0L;
380cdf0e10cSrcweir         }
381cdf0e10cSrcweir         //Der FtnBoss will bezueglich des MaxWerts auch noch mitreden.
382cdf0e10cSrcweir         if( !IsInSct() )
383cdf0e10cSrcweir         {
384cdf0e10cSrcweir             const SwTwips nMax = pBoss->GetVarSpace();
385cdf0e10cSrcweir             if ( nDist > nMax )
386cdf0e10cSrcweir                 nDist = nMax;
387cdf0e10cSrcweir             if ( nDist <= 0 )
388cdf0e10cSrcweir                 return 0L;
389cdf0e10cSrcweir         }
390cdf0e10cSrcweir     }
391cdf0e10cSrcweir     else if( nDist > (GetPrev()->Frm().*fnRect->fnGetHeight)() )
392cdf0e10cSrcweir         //aber mehr als der Body kann koennen und wollen wir nun auch wieder
393cdf0e10cSrcweir         //nicht herausruecken.
394cdf0e10cSrcweir         nDist = (GetPrev()->Frm().*fnRect->fnGetHeight)();
395cdf0e10cSrcweir 
396cdf0e10cSrcweir     long nAvail = 0;
397cdf0e10cSrcweir     if ( bBrowseMode )
398cdf0e10cSrcweir     {
399cdf0e10cSrcweir         nAvail = GetUpper()->Prt().Height();
400cdf0e10cSrcweir         const SwFrm *pAvail = GetUpper()->Lower();
401cdf0e10cSrcweir         do
402cdf0e10cSrcweir         {   nAvail -= pAvail->Frm().Height();
403cdf0e10cSrcweir             pAvail = pAvail->GetNext();
404cdf0e10cSrcweir         } while ( pAvail );
405cdf0e10cSrcweir         if ( nAvail > nDist )
406cdf0e10cSrcweir             nAvail = nDist;
407cdf0e10cSrcweir     }
408cdf0e10cSrcweir 
409cdf0e10cSrcweir     if ( !bTst )
410cdf0e10cSrcweir     {
411cdf0e10cSrcweir         (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() + nDist );
412cdf0e10cSrcweir         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
413cdf0e10cSrcweir         if( IsVertical() && !IsVertLR() && !IsReverse() )
414cdf0e10cSrcweir             Frm().Pos().X() -= nDist;
415cdf0e10cSrcweir     }
416cdf0e10cSrcweir     long nGrow = nDist - nAvail,
417cdf0e10cSrcweir          nReal = 0;
418cdf0e10cSrcweir     if ( nGrow > 0 )
419cdf0e10cSrcweir     {
420cdf0e10cSrcweir         sal_uInt8 nAdjust = pBoss->NeighbourhoodAdjustment( this );
421cdf0e10cSrcweir         if( NA_ONLY_ADJUST == nAdjust )
422cdf0e10cSrcweir             nReal = AdjustNeighbourhood( nGrow, bTst );
423cdf0e10cSrcweir         else
424cdf0e10cSrcweir         {
425cdf0e10cSrcweir             if( NA_GROW_ADJUST == nAdjust )
426cdf0e10cSrcweir             {
427cdf0e10cSrcweir                 SwFrm* pFtn = Lower();
428cdf0e10cSrcweir                 if( pFtn )
429cdf0e10cSrcweir                 {
430cdf0e10cSrcweir                     while( pFtn->GetNext() )
431cdf0e10cSrcweir                         pFtn = pFtn->GetNext();
432cdf0e10cSrcweir                     if( ((SwFtnFrm*)pFtn)->GetAttr()->GetFtn().IsEndNote() )
433cdf0e10cSrcweir                     {
434cdf0e10cSrcweir                         nReal = AdjustNeighbourhood( nGrow, bTst );
435cdf0e10cSrcweir                         nAdjust = NA_GROW_SHRINK; // no more AdjustNeighbourhood
436cdf0e10cSrcweir                     }
437cdf0e10cSrcweir                 }
438cdf0e10cSrcweir             }
439cdf0e10cSrcweir             nReal += pBoss->Grow( nGrow - nReal, bTst );
440cdf0e10cSrcweir             if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
441cdf0e10cSrcweir                   && nReal < nGrow )
442cdf0e10cSrcweir                 nReal += AdjustNeighbourhood( nGrow - nReal, bTst );
443cdf0e10cSrcweir         }
444cdf0e10cSrcweir     }
445cdf0e10cSrcweir 
446cdf0e10cSrcweir     nReal += nAvail;
447cdf0e10cSrcweir 
448cdf0e10cSrcweir     if ( !bTst )
449cdf0e10cSrcweir     {
450cdf0e10cSrcweir         if ( nReal != nDist )
451cdf0e10cSrcweir         {
452cdf0e10cSrcweir             nDist -= nReal;
453cdf0e10cSrcweir             //Den masslosen Wunsch koennen wir leider nur in Grenzen erfuellen.
454cdf0e10cSrcweir             Frm().SSize().Height() -= nDist;
455cdf0e10cSrcweir             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
456cdf0e10cSrcweir             if( IsVertical() && !IsVertLR() && !IsReverse() )
457cdf0e10cSrcweir                 Frm().Pos().X() += nDist;
458cdf0e10cSrcweir         }
459cdf0e10cSrcweir 
460cdf0e10cSrcweir         //Nachfolger braucht nicht invalidiert werden, denn wir wachsen
461cdf0e10cSrcweir         //immer nach oben.
462cdf0e10cSrcweir         if( nReal )
463cdf0e10cSrcweir         {
464cdf0e10cSrcweir             _InvalidateSize();
465cdf0e10cSrcweir             _InvalidatePos();
466cdf0e10cSrcweir             InvalidatePage( pPage );
467cdf0e10cSrcweir         }
468cdf0e10cSrcweir     }
469cdf0e10cSrcweir     return nReal;
470cdf0e10cSrcweir }
471cdf0e10cSrcweir 
472cdf0e10cSrcweir 
ShrinkFrm(SwTwips nDiff,sal_Bool bTst,sal_Bool bInfo)473cdf0e10cSrcweir SwTwips SwFtnContFrm::ShrinkFrm( SwTwips nDiff, sal_Bool bTst, sal_Bool bInfo )
474cdf0e10cSrcweir {
475cdf0e10cSrcweir     SwPageFrm *pPage = FindPageFrm();
476cdf0e10cSrcweir     bool bShrink = false;
477cdf0e10cSrcweir     if ( pPage )
478cdf0e10cSrcweir     {
479cdf0e10cSrcweir         if( !pPage->IsFtnPage() )
480cdf0e10cSrcweir             bShrink = true;
481cdf0e10cSrcweir         else
482cdf0e10cSrcweir         {
483cdf0e10cSrcweir             const ViewShell *pSh = getRootFrm()->GetCurrShell();
484cdf0e10cSrcweir             if( pSh && pSh->GetViewOptions()->getBrowseMode() )
485cdf0e10cSrcweir                 bShrink = true;
486cdf0e10cSrcweir         }
487cdf0e10cSrcweir     }
488cdf0e10cSrcweir     if( bShrink )
489cdf0e10cSrcweir     {
490cdf0e10cSrcweir         SwTwips nRet = SwLayoutFrm::ShrinkFrm( nDiff, bTst, bInfo );
491cdf0e10cSrcweir         if( IsInSct() && !bTst )
492cdf0e10cSrcweir             FindSctFrm()->InvalidateNextPos();
493cdf0e10cSrcweir         if ( !bTst && nRet )
494cdf0e10cSrcweir         {
495cdf0e10cSrcweir             _InvalidatePos();
496cdf0e10cSrcweir             InvalidatePage( pPage );
497cdf0e10cSrcweir         }
498cdf0e10cSrcweir         return nRet;
499cdf0e10cSrcweir     }
500cdf0e10cSrcweir     return 0;
501cdf0e10cSrcweir }
502cdf0e10cSrcweir 
503cdf0e10cSrcweir 
504cdf0e10cSrcweir /*************************************************************************
505cdf0e10cSrcweir |*
506cdf0e10cSrcweir |*  SwFtnFrm::SwFtnFrm()
507cdf0e10cSrcweir |*
508cdf0e10cSrcweir |*************************************************************************/
509cdf0e10cSrcweir 
510cdf0e10cSrcweir 
SwFtnFrm(SwFrmFmt * pFmt,SwFrm * pSib,SwCntntFrm * pCnt,SwTxtFtn * pAt)511cdf0e10cSrcweir SwFtnFrm::SwFtnFrm( SwFrmFmt *pFmt, SwFrm* pSib, SwCntntFrm *pCnt, SwTxtFtn *pAt ):
512cdf0e10cSrcweir     SwLayoutFrm( pFmt, pSib ),
513cdf0e10cSrcweir     pFollow( 0 ),
514cdf0e10cSrcweir     pMaster( 0 ),
515cdf0e10cSrcweir     pRef( pCnt ),
516cdf0e10cSrcweir     pAttr( pAt ),
517cdf0e10cSrcweir     bBackMoveLocked( sal_False ),
518cdf0e10cSrcweir     // --> OD 2005-08-11 #i49383#
519cdf0e10cSrcweir     mbUnlockPosOfLowerObjs( true )
520cdf0e10cSrcweir     // <--
521cdf0e10cSrcweir {
522cdf0e10cSrcweir     nType = FRMC_FTN;
523cdf0e10cSrcweir }
524cdf0e10cSrcweir 
525cdf0e10cSrcweir /*************************************************************************
526cdf0e10cSrcweir |*
527cdf0e10cSrcweir |*  SwFtnFrm::InvalidateNxtFtnCnts()
528cdf0e10cSrcweir |*
529cdf0e10cSrcweir |*************************************************************************/
530cdf0e10cSrcweir 
531cdf0e10cSrcweir 
InvalidateNxtFtnCnts(SwPageFrm * pPage)532cdf0e10cSrcweir void SwFtnFrm::InvalidateNxtFtnCnts( SwPageFrm *pPage )
533cdf0e10cSrcweir {
534cdf0e10cSrcweir     if ( GetNext() )
535cdf0e10cSrcweir     {
536cdf0e10cSrcweir         SwFrm *pCnt = ((SwLayoutFrm*)GetNext())->ContainsAny();
537cdf0e10cSrcweir         if( pCnt )
538cdf0e10cSrcweir         {
539cdf0e10cSrcweir             pCnt->InvalidatePage( pPage );
540cdf0e10cSrcweir             pCnt->_InvalidatePrt();
541cdf0e10cSrcweir             do
542cdf0e10cSrcweir             {   pCnt->_InvalidatePos();
543cdf0e10cSrcweir                 if( pCnt->IsSctFrm() )
544cdf0e10cSrcweir                 {
545cdf0e10cSrcweir                     SwFrm* pTmp = ((SwSectionFrm*)pCnt)->ContainsAny();
546cdf0e10cSrcweir                     if( pTmp )
547cdf0e10cSrcweir                         pTmp->_InvalidatePos();
548cdf0e10cSrcweir                 }
549cdf0e10cSrcweir                 pCnt->GetUpper()->_InvalidateSize();
550cdf0e10cSrcweir                 pCnt = pCnt->FindNext();
551cdf0e10cSrcweir             } while ( pCnt && GetUpper()->IsAnLower( pCnt ) );
552cdf0e10cSrcweir         }
553cdf0e10cSrcweir     }
554cdf0e10cSrcweir }
555cdf0e10cSrcweir 
556cdf0e10cSrcweir #ifdef DBG_UTIL
557cdf0e10cSrcweir 
GrowFrm(SwTwips nDist,sal_Bool bTst,sal_Bool bInfo)558cdf0e10cSrcweir SwTwips SwFtnFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
559cdf0e10cSrcweir {
560cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
561cdf0e10cSrcweir     static sal_uInt16 nNum = USHRT_MAX;
562cdf0e10cSrcweir     SwTxtFtn* pTxtFtn = GetAttr();
563cdf0e10cSrcweir     if ( pTxtFtn->GetFtn().GetNumber() == nNum )
564cdf0e10cSrcweir     {
565cdf0e10cSrcweir         int bla = 5;
566cdf0e10cSrcweir         (void)bla;
567cdf0e10cSrcweir 
568cdf0e10cSrcweir     }
569cdf0e10cSrcweir #endif
570cdf0e10cSrcweir     return SwLayoutFrm::GrowFrm( nDist, bTst, bInfo );
571cdf0e10cSrcweir }
572cdf0e10cSrcweir 
573cdf0e10cSrcweir 
ShrinkFrm(SwTwips nDist,sal_Bool bTst,sal_Bool bInfo)574cdf0e10cSrcweir SwTwips SwFtnFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
575cdf0e10cSrcweir {
576cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
577cdf0e10cSrcweir     static sal_uInt16 nNum = USHRT_MAX;
578cdf0e10cSrcweir     if( nNum != USHRT_MAX )
579cdf0e10cSrcweir     {
580cdf0e10cSrcweir         SwTxtFtn* pTxtFtn = GetAttr();
581cdf0e10cSrcweir         if( &pTxtFtn->GetAttr() && pTxtFtn->GetFtn().GetNumber() == nNum )
582cdf0e10cSrcweir         {
583cdf0e10cSrcweir             int bla = 5;
584cdf0e10cSrcweir             (void)bla;
585cdf0e10cSrcweir         }
586cdf0e10cSrcweir     }
587cdf0e10cSrcweir #endif
588cdf0e10cSrcweir     return SwLayoutFrm::ShrinkFrm( nDist, bTst, bInfo );
589cdf0e10cSrcweir }
590cdf0e10cSrcweir #endif
591cdf0e10cSrcweir 
592cdf0e10cSrcweir /*************************************************************************
593cdf0e10cSrcweir |*
594cdf0e10cSrcweir |*  SwFtnFrm::Cut()
595cdf0e10cSrcweir |*
596cdf0e10cSrcweir |*************************************************************************/
597cdf0e10cSrcweir 
598cdf0e10cSrcweir 
Cut()599cdf0e10cSrcweir void SwFtnFrm::Cut()
600cdf0e10cSrcweir {
601cdf0e10cSrcweir     if ( GetNext() )
602cdf0e10cSrcweir         GetNext()->InvalidatePos();
603cdf0e10cSrcweir     else if ( GetPrev() )
604cdf0e10cSrcweir         GetPrev()->SetRetouche();
605cdf0e10cSrcweir 
606cdf0e10cSrcweir     //Erst removen, dann Upper Shrinken.
607cdf0e10cSrcweir     SwLayoutFrm *pUp = GetUpper();
608cdf0e10cSrcweir 
609cdf0e10cSrcweir     //Verkettung korrigieren.
610cdf0e10cSrcweir     SwFtnFrm *pFtn = (SwFtnFrm*)this;
611cdf0e10cSrcweir     if ( pFtn->GetFollow() )
612cdf0e10cSrcweir         pFtn->GetFollow()->SetMaster( pFtn->GetMaster() );
613cdf0e10cSrcweir     if ( pFtn->GetMaster() )
614cdf0e10cSrcweir         pFtn->GetMaster()->SetFollow( pFtn->GetFollow() );
615cdf0e10cSrcweir     pFtn->SetFollow( 0 );
616cdf0e10cSrcweir     pFtn->SetMaster( 0 );
617cdf0e10cSrcweir 
618cdf0e10cSrcweir     // Alle Verbindungen kappen.
619cdf0e10cSrcweir     Remove();
620cdf0e10cSrcweir 
621cdf0e10cSrcweir     if ( pUp )
622cdf0e10cSrcweir     {
623cdf0e10cSrcweir         //Die letzte Fussnote nimmt ihren Container mit.
624cdf0e10cSrcweir         if ( !pUp->Lower() )
625cdf0e10cSrcweir         {
626cdf0e10cSrcweir             SwPageFrm *pPage = pUp->FindPageFrm();
627cdf0e10cSrcweir             if ( pPage )
628cdf0e10cSrcweir             {
629cdf0e10cSrcweir                 SwLayoutFrm *pBody = pPage->FindBodyCont();
630cdf0e10cSrcweir                 if( pBody && !pBody->ContainsCntnt() )
631cdf0e10cSrcweir                     pPage->getRootFrm()->SetSuperfluous();
632cdf0e10cSrcweir             }
633cdf0e10cSrcweir             SwSectionFrm* pSect = pUp->FindSctFrm();
634cdf0e10cSrcweir             pUp->Cut();
635cdf0e10cSrcweir             delete pUp;
636cdf0e10cSrcweir             // Wenn der letzte Fussnotencontainer aus einem spaltigen Bereich verschwindet,
637cdf0e10cSrcweir             // so kann dieser, falls er keinen Follow besitzt, zusammenschrumpfen.
638cdf0e10cSrcweir             if( pSect && !pSect->ToMaximize( sal_False ) && !pSect->IsColLocked() )
639cdf0e10cSrcweir                 pSect->_InvalidateSize();
640cdf0e10cSrcweir         }
641cdf0e10cSrcweir         else
642cdf0e10cSrcweir         {   if ( Frm().Height() )
643cdf0e10cSrcweir                 pUp->Shrink( Frm().Height() );
644cdf0e10cSrcweir             pUp->SetCompletePaint();
645cdf0e10cSrcweir             pUp->InvalidatePage();
646cdf0e10cSrcweir         }
647cdf0e10cSrcweir     }
648cdf0e10cSrcweir }
649cdf0e10cSrcweir 
650cdf0e10cSrcweir /*************************************************************************
651cdf0e10cSrcweir |*
652cdf0e10cSrcweir |*  SwFtnFrm::Paste()
653cdf0e10cSrcweir |*
654cdf0e10cSrcweir |*************************************************************************/
655cdf0e10cSrcweir 
656cdf0e10cSrcweir 
Paste(SwFrm * pParent,SwFrm * pSibling)657cdf0e10cSrcweir void SwFtnFrm::Paste(  SwFrm* pParent, SwFrm* pSibling )
658cdf0e10cSrcweir {
659cdf0e10cSrcweir     ASSERT( pParent, "Kein Parent fuer Paste." );
660cdf0e10cSrcweir     ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
661cdf0e10cSrcweir     ASSERT( pParent != this, "Bin selbst der Parent." );
662cdf0e10cSrcweir     ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
663cdf0e10cSrcweir     ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
664cdf0e10cSrcweir             "Bin noch irgendwo angemeldet." );
665cdf0e10cSrcweir 
666cdf0e10cSrcweir     //In den Baum einhaengen.
667cdf0e10cSrcweir     InsertBefore( (SwLayoutFrm*)pParent, pSibling );
668cdf0e10cSrcweir 
669cdf0e10cSrcweir     SWRECTFN( this )
670cdf0e10cSrcweir     if( (Frm().*fnRect->fnGetWidth)()!=(pParent->Prt().*fnRect->fnGetWidth)() )
671cdf0e10cSrcweir         _InvalidateSize();
672cdf0e10cSrcweir     _InvalidatePos();
673cdf0e10cSrcweir     SwPageFrm *pPage = FindPageFrm();
674cdf0e10cSrcweir     InvalidatePage( pPage );
675cdf0e10cSrcweir     if ( GetNext() )
676cdf0e10cSrcweir         GetNext()->_InvalidatePos();
677cdf0e10cSrcweir     if( (Frm().*fnRect->fnGetHeight)() )
678cdf0e10cSrcweir         pParent->Grow( (Frm().*fnRect->fnGetHeight)() );
679cdf0e10cSrcweir 
680cdf0e10cSrcweir     //Wenn mein Vorgaenger mein Master ist und/oder wenn mein Nachfolger mein
681cdf0e10cSrcweir     //Follow ist so kann ich deren Inhalt uebernehmen und sie vernichten.
682cdf0e10cSrcweir     if ( GetPrev() && GetPrev() == GetMaster() )
683cdf0e10cSrcweir     {   ASSERT( SwFlowFrm::CastFlowFrm( GetPrev()->GetLower() ),
684cdf0e10cSrcweir                 "Fussnote ohne Inhalt?" );
685cdf0e10cSrcweir         (SwFlowFrm::CastFlowFrm( GetPrev()->GetLower()))->
686cdf0e10cSrcweir             MoveSubTree( this, GetLower() );
687cdf0e10cSrcweir         SwFrm *pDel = GetPrev();
688cdf0e10cSrcweir         pDel->Cut();
689cdf0e10cSrcweir         delete pDel;
690cdf0e10cSrcweir     }
691cdf0e10cSrcweir     if ( GetNext() && GetNext() == GetFollow() )
692cdf0e10cSrcweir     {   ASSERT( SwFlowFrm::CastFlowFrm( GetNext()->GetLower() ),
693cdf0e10cSrcweir                 "Fussnote ohne Inhalt?" );
694cdf0e10cSrcweir         (SwFlowFrm::CastFlowFrm( GetNext()->GetLower()))->MoveSubTree( this );
695cdf0e10cSrcweir         SwFrm *pDel = GetNext();
696cdf0e10cSrcweir         pDel->Cut();
697cdf0e10cSrcweir         delete pDel;
698cdf0e10cSrcweir     }
699cdf0e10cSrcweir #ifdef DBG_UTIL
700cdf0e10cSrcweir     SwDoc *pDoc = GetFmt()->GetDoc();
701cdf0e10cSrcweir     if ( GetPrev() )
702cdf0e10cSrcweir     {
703cdf0e10cSrcweir         ASSERT( lcl_FindFtnPos( pDoc, ((SwFtnFrm*)GetPrev())->GetAttr() ) <=
704cdf0e10cSrcweir                 lcl_FindFtnPos( pDoc, GetAttr() ), "Prev ist not FtnPrev" );
705cdf0e10cSrcweir     }
706cdf0e10cSrcweir     if ( GetNext() )
707cdf0e10cSrcweir     {
708cdf0e10cSrcweir         ASSERT( lcl_FindFtnPos( pDoc, GetAttr() ) <=
709cdf0e10cSrcweir                 lcl_FindFtnPos( pDoc, ((SwFtnFrm*)GetNext())->GetAttr() ),
710cdf0e10cSrcweir                 "Next is not FtnNext" );
711cdf0e10cSrcweir     }
712cdf0e10cSrcweir #endif
713cdf0e10cSrcweir     InvalidateNxtFtnCnts( pPage );
714cdf0e10cSrcweir }
715cdf0e10cSrcweir 
716cdf0e10cSrcweir /*************************************************************************
717cdf0e10cSrcweir |*
718cdf0e10cSrcweir |*  SwFrm::GetNextFtnLeaf()
719cdf0e10cSrcweir |*
720cdf0e10cSrcweir |*  Beschreibung        Liefert das naechste LayoutBlatt in den das
721cdf0e10cSrcweir |*      Frame gemoved werden kann.
722cdf0e10cSrcweir |*      Neue Seiten werden nur dann erzeugt, wenn der Parameter sal_True ist.
723cdf0e10cSrcweir |*
724cdf0e10cSrcweir |*************************************************************************/
725cdf0e10cSrcweir 
726cdf0e10cSrcweir 
GetNextFtnLeaf(MakePageType eMakePage)727cdf0e10cSrcweir SwLayoutFrm *SwFrm::GetNextFtnLeaf( MakePageType eMakePage )
728cdf0e10cSrcweir {
729cdf0e10cSrcweir     SwFtnBossFrm *pOldBoss = FindFtnBossFrm();
730cdf0e10cSrcweir     SwPageFrm* pOldPage = pOldBoss->FindPageFrm();
731cdf0e10cSrcweir     SwPageFrm* pPage;
732cdf0e10cSrcweir     SwFtnBossFrm *pBoss = pOldBoss->IsColumnFrm() ?
733cdf0e10cSrcweir         (SwFtnBossFrm*)pOldBoss->GetNext() : 0; // naechste Spalte, wenn vorhanden
734cdf0e10cSrcweir     if( pBoss )
735cdf0e10cSrcweir         pPage = NULL;
736cdf0e10cSrcweir     else
737cdf0e10cSrcweir     {
738cdf0e10cSrcweir         if( pOldBoss->GetUpper()->IsSctFrm() )
739cdf0e10cSrcweir         {   // Das kann nur in einem spaltigen Bereich sein
740cdf0e10cSrcweir             SwLayoutFrm* pNxt = pOldBoss->GetNextSctLeaf( eMakePage );
741cdf0e10cSrcweir             if( pNxt )
742cdf0e10cSrcweir             {
743cdf0e10cSrcweir                 ASSERT( pNxt->IsColBodyFrm(), "GetNextFtnLeaf: Funny Leaf" );
744cdf0e10cSrcweir                 pBoss = (SwFtnBossFrm*)pNxt->GetUpper();
745cdf0e10cSrcweir                 pPage = pBoss->FindPageFrm();
746cdf0e10cSrcweir             }
747cdf0e10cSrcweir             else
748cdf0e10cSrcweir                 return 0;
749cdf0e10cSrcweir         }
750cdf0e10cSrcweir         else
751cdf0e10cSrcweir         {
752cdf0e10cSrcweir             // naechste Seite
753cdf0e10cSrcweir             pPage = (SwPageFrm*)pOldPage->GetNext();
754cdf0e10cSrcweir             // Leerseiten ueberspringen
755cdf0e10cSrcweir             if( pPage && pPage->IsEmptyPage() )
756cdf0e10cSrcweir                 pPage = (SwPageFrm*)pPage->GetNext();
757cdf0e10cSrcweir             pBoss = pPage;
758cdf0e10cSrcweir         }
759cdf0e10cSrcweir     }
760cdf0e10cSrcweir     // Was haben wir jetzt?
761cdf0e10cSrcweir     // pBoss != NULL, pPage==NULL => pBoss ist die auf der gleichen Seite folgende Spalte
762cdf0e10cSrcweir     // pBoss != NULL, pPage!=NULL => pBoss und pPage sind die folgende Seite (Empty uebersprungen)
763cdf0e10cSrcweir     // pBoss == NULL => pPage == NULL, es gibt keine folgende Seite
764cdf0e10cSrcweir 
765cdf0e10cSrcweir     //Wenn die Fussnote bereits einen Follow hat brauchen wir nicht zu suchen.
766cdf0e10cSrcweir     //Wenn allerdings zwischen Ftn und Follow unerwuenschte Leerseiten/spalten
767cdf0e10cSrcweir     //herumlungern, so legen wir auf der naechstbesten Seite/Spalte einen weiteren
768cdf0e10cSrcweir     //Follow an, der Rest wird sich schon finden.
769cdf0e10cSrcweir     SwFtnFrm *pFtn = FindFtnFrm();
770cdf0e10cSrcweir     if ( pFtn && pFtn->GetFollow() )
771cdf0e10cSrcweir     {
772cdf0e10cSrcweir         SwFtnBossFrm* pTmpBoss = pFtn->GetFollow()->FindFtnBossFrm();
773cdf0e10cSrcweir         // Folgende Faelle werden hier erkannt und akzeptiert
774cdf0e10cSrcweir         // 1. Die FtnBosse sind benachbarte Seiten oder benachbarte Spalten
775cdf0e10cSrcweir         // 2. Der neue ist die erste Spalte der benachbarten Seite
776cdf0e10cSrcweir         // 3. Der neue ist die erste Spalte in einem Bereich in der naechsten Spalte/Seite
777cdf0e10cSrcweir         while( pTmpBoss != pBoss && pTmpBoss && !pTmpBoss->GetPrev() )
778cdf0e10cSrcweir             pTmpBoss = pTmpBoss->GetUpper()->FindFtnBossFrm();
779cdf0e10cSrcweir         if( pTmpBoss == pBoss )
780cdf0e10cSrcweir             return pFtn->GetFollow();
781cdf0e10cSrcweir     }
782cdf0e10cSrcweir 
783cdf0e10cSrcweir     // Wenn wir keinen pBoss gefunden haben oder es sich um eine "falsche" Seite handelt,
784cdf0e10cSrcweir     // muss eine neue Seite her
785cdf0e10cSrcweir     if ( !pBoss || ( pPage && pPage->IsEndNotePage() && !pOldPage->IsEndNotePage() ) )
786cdf0e10cSrcweir     {
787cdf0e10cSrcweir         if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
788cdf0e10cSrcweir         {
789cdf0e10cSrcweir             pBoss = InsertPage( pOldPage, pOldPage->IsFtnPage() );
790cdf0e10cSrcweir             ((SwPageFrm*)pBoss)->SetEndNotePage( pOldPage->IsEndNotePage() );
791cdf0e10cSrcweir         }
792cdf0e10cSrcweir         else
793cdf0e10cSrcweir             return 0;
794cdf0e10cSrcweir     }
795cdf0e10cSrcweir     if( pBoss->IsPageFrm() )
796cdf0e10cSrcweir     {   // Wenn wir auf einer spaltigen Seite gelandet sind,
797cdf0e10cSrcweir         // gehen wir in die erste Spalte
798cdf0e10cSrcweir         SwLayoutFrm* pLay = pBoss->FindBodyCont();
799cdf0e10cSrcweir         if( pLay && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
800cdf0e10cSrcweir             pBoss = (SwFtnBossFrm*)pLay->Lower();
801cdf0e10cSrcweir     }
802cdf0e10cSrcweir     //Seite/Spalte gefunden, da schummeln wir uns doch gleich mal 'rein
803cdf0e10cSrcweir     SwFtnContFrm *pCont = pBoss->FindFtnCont();
804cdf0e10cSrcweir     if ( !pCont && pBoss->GetMaxFtnHeight() &&
805cdf0e10cSrcweir          ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
806cdf0e10cSrcweir         pCont = pBoss->MakeFtnCont();
807cdf0e10cSrcweir     return pCont;
808cdf0e10cSrcweir }
809cdf0e10cSrcweir 
810cdf0e10cSrcweir /*************************************************************************
811cdf0e10cSrcweir |*
812cdf0e10cSrcweir |*  SwFrm::GetPrevFtnLeaf()
813cdf0e10cSrcweir |*
814cdf0e10cSrcweir |*  Beschreibung        Liefert das vorhergehende LayoutBlatt in das der
815cdf0e10cSrcweir |*      Frame gemoved werden kann.
816cdf0e10cSrcweir |*
817cdf0e10cSrcweir |*************************************************************************/
818cdf0e10cSrcweir 
819cdf0e10cSrcweir 
GetPrevFtnLeaf(MakePageType eMakeFtn)820cdf0e10cSrcweir SwLayoutFrm *SwFrm::GetPrevFtnLeaf( MakePageType eMakeFtn )
821cdf0e10cSrcweir {
822cdf0e10cSrcweir     //Der Vorgaenger fuer eine Fussnote ist falls moeglich der Master
823cdf0e10cSrcweir     //in der Fussnoteneigenen Verkettung.
824cdf0e10cSrcweir     SwLayoutFrm *pRet = 0;
825cdf0e10cSrcweir     SwFtnFrm *pFtn = FindFtnFrm();
826cdf0e10cSrcweir     pRet = pFtn->GetMaster();
827cdf0e10cSrcweir 
828cdf0e10cSrcweir     SwFtnBossFrm* pOldBoss = FindFtnBossFrm();
829cdf0e10cSrcweir     SwPageFrm *pOldPage = pOldBoss->FindPageFrm();
830cdf0e10cSrcweir 
831cdf0e10cSrcweir     if ( !pOldBoss->GetPrev() && !pOldPage->GetPrev() )
832cdf0e10cSrcweir         return pRet; // es gibt weder eine Spalte noch eine Seite vor uns
833cdf0e10cSrcweir 
834cdf0e10cSrcweir     if ( !pRet )
835cdf0e10cSrcweir     {
836cdf0e10cSrcweir         bool bEndn = pFtn->GetAttr()->GetFtn().IsEndNote();
837cdf0e10cSrcweir         SwFrm* pTmpRef = NULL;
838cdf0e10cSrcweir         if( bEndn && pFtn->IsInSct() )
839cdf0e10cSrcweir         {
840cdf0e10cSrcweir             SwSectionFrm* pSect = pFtn->FindSctFrm();
841cdf0e10cSrcweir             if( pSect->IsEndnAtEnd() )
842cdf0e10cSrcweir                 pTmpRef = pSect->FindLastCntnt( FINDMODE_LASTCNT );
843cdf0e10cSrcweir         }
844cdf0e10cSrcweir         if( !pTmpRef )
845cdf0e10cSrcweir             pTmpRef = pFtn->GetRef();
846cdf0e10cSrcweir         SwFtnBossFrm* pStop = pTmpRef->FindFtnBossFrm( !bEndn );
847cdf0e10cSrcweir 
848cdf0e10cSrcweir         const sal_uInt16 nNum = pStop->GetPhyPageNum();
849cdf0e10cSrcweir 
850cdf0e10cSrcweir         //Wenn die Fussnoten am Dokumentende angezeigt werden, so verlassen wir
851cdf0e10cSrcweir         //die Entsprechenden Seiten nicht.
852cdf0e10cSrcweir         //Selbiges gilt analog fuer die Endnotenseiten.
853cdf0e10cSrcweir         const sal_Bool bEndNote = pOldPage->IsEndNotePage();
854cdf0e10cSrcweir         const sal_Bool bFtnEndDoc = pOldPage->IsFtnPage();
855cdf0e10cSrcweir         SwFtnBossFrm* pNxtBoss = pOldBoss;
856cdf0e10cSrcweir         SwSectionFrm *pSect = pNxtBoss->GetUpper()->IsSctFrm() ?
857cdf0e10cSrcweir                               (SwSectionFrm*)pNxtBoss->GetUpper() : 0;
858cdf0e10cSrcweir 
859cdf0e10cSrcweir         do
860cdf0e10cSrcweir         {
861cdf0e10cSrcweir             if( pNxtBoss->IsColumnFrm() && pNxtBoss->GetPrev() )
862cdf0e10cSrcweir                 pNxtBoss = (SwFtnBossFrm*)pNxtBoss->GetPrev();  // eine Spalte zurueck
863cdf0e10cSrcweir             else                                // oder eine Seite zurueck
864cdf0e10cSrcweir             {
865cdf0e10cSrcweir                 SwLayoutFrm* pBody = 0;
866cdf0e10cSrcweir                 if( pSect )
867cdf0e10cSrcweir                 {
868cdf0e10cSrcweir                     if( pSect->IsFtnLock() )
869cdf0e10cSrcweir                     {
870cdf0e10cSrcweir                         if( pNxtBoss == pOldBoss )
871cdf0e10cSrcweir                             return 0;
872cdf0e10cSrcweir                         pStop = pNxtBoss;
873cdf0e10cSrcweir                     }
874cdf0e10cSrcweir                     else
875cdf0e10cSrcweir                     {
876cdf0e10cSrcweir                         pSect = (SwSectionFrm*)pSect->FindMaster();
877cdf0e10cSrcweir                         if( !pSect || !pSect->Lower() )
878cdf0e10cSrcweir                             return 0;
879cdf0e10cSrcweir                         ASSERT( pSect->Lower()->IsColumnFrm(),
880cdf0e10cSrcweir                                 "GetPrevFtnLeaf: Where's the column?" );
881cdf0e10cSrcweir                         pNxtBoss = (SwFtnBossFrm*)pSect->Lower();
882cdf0e10cSrcweir                         pBody = pSect;
883cdf0e10cSrcweir                     }
884cdf0e10cSrcweir                 }
885cdf0e10cSrcweir                 else
886cdf0e10cSrcweir                 {
887cdf0e10cSrcweir                     SwPageFrm* pPage = (SwPageFrm*)pNxtBoss->FindPageFrm()->GetPrev();
888cdf0e10cSrcweir                     if( !pPage || pPage->GetPhyPageNum() < nNum ||
889cdf0e10cSrcweir                         bEndNote != pPage->IsEndNotePage() || bFtnEndDoc != pPage->IsFtnPage() )
890cdf0e10cSrcweir                         return NULL; // Keine in Frage kommende Seite mehr gefunden
891cdf0e10cSrcweir                     pNxtBoss = pPage;
892cdf0e10cSrcweir                     pBody = pPage->FindBodyCont();
893cdf0e10cSrcweir                 }
894cdf0e10cSrcweir                 // Die vorherige Seite haben wir nun, ggf. sollten wir in die letzte Spalte
895cdf0e10cSrcweir                 // der Seite wechseln
896cdf0e10cSrcweir                 if( pBody )
897cdf0e10cSrcweir                 {
898cdf0e10cSrcweir                     if ( pBody->Lower() && pBody->Lower()->IsColumnFrm() )
899cdf0e10cSrcweir                     {
900cdf0e10cSrcweir                         pNxtBoss = static_cast<SwFtnBossFrm*>(pBody->GetLastLower());
901cdf0e10cSrcweir                     }
902cdf0e10cSrcweir                 }
903cdf0e10cSrcweir             }
904cdf0e10cSrcweir             SwFtnContFrm *pCont = pNxtBoss->FindFtnCont();
905cdf0e10cSrcweir             if ( pCont )
906cdf0e10cSrcweir             {
907cdf0e10cSrcweir                 pRet = pCont;
908cdf0e10cSrcweir                 break;
909cdf0e10cSrcweir             }
910cdf0e10cSrcweir             if ( pStop == pNxtBoss )
911cdf0e10cSrcweir             {   //Die Seite/Spalte auf der sich auch die Referenz tummelt, ist erreicht.
912cdf0e10cSrcweir                 //Wir koennen jetzt probehalber mal einen Container erzeugen und
913cdf0e10cSrcweir                 //uns hineinpasten.
914cdf0e10cSrcweir                 if ( eMakeFtn == MAKEPAGE_FTN && pNxtBoss->GetMaxFtnHeight() )
915cdf0e10cSrcweir                     pRet = pNxtBoss->MakeFtnCont();
916cdf0e10cSrcweir                 break;
917cdf0e10cSrcweir             }
918cdf0e10cSrcweir         } while( !pRet );
919cdf0e10cSrcweir     }
920cdf0e10cSrcweir     if ( pRet )
921cdf0e10cSrcweir     {
922cdf0e10cSrcweir         const SwFtnBossFrm* pNewBoss = pRet->FindFtnBossFrm();
923cdf0e10cSrcweir         sal_Bool bJump = sal_False;
924cdf0e10cSrcweir         if( pOldBoss->IsColumnFrm() && pOldBoss->GetPrev() ) // es gibt eine vorherige Spalte
925cdf0e10cSrcweir             bJump = pOldBoss->GetPrev() != (SwFrm*)pNewBoss;         // sind wir darin gelandet?
926cdf0e10cSrcweir         else if( pNewBoss->IsColumnFrm() && pNewBoss->GetNext() )
927cdf0e10cSrcweir             bJump = sal_True; // es gibt hinter dem neuen Boss noch eine Spalte, die aber nicht
928cdf0e10cSrcweir                           // der alte Boss sein kann, das haben wir ja bereits geprueft.
929cdf0e10cSrcweir         else // hier landen wir nur, wenn neuer und alter Boss entweder Seiten oder letzte (neu)
930cdf0e10cSrcweir         {   // bzw. erste (alt) Spalten einer Seite sind. In diesem Fall muss noch geprueft
931cdf0e10cSrcweir             // werden, ob Seiten ueberspringen wurden.
932cdf0e10cSrcweir             sal_uInt16 nDiff = pOldPage->GetPhyPageNum() - pRet->FindPageFrm()->GetPhyPageNum();
933cdf0e10cSrcweir             if ( nDiff > 2 ||
934cdf0e10cSrcweir                  (nDiff > 1 && !((SwPageFrm*)pOldPage->GetPrev())->IsEmptyPage()) )
935cdf0e10cSrcweir                 bJump = sal_True;
936cdf0e10cSrcweir         }
937cdf0e10cSrcweir         if( bJump )
938cdf0e10cSrcweir             SwFlowFrm::SetMoveBwdJump( sal_True );
939cdf0e10cSrcweir     }
940cdf0e10cSrcweir     return pRet;
941cdf0e10cSrcweir }
942cdf0e10cSrcweir 
943cdf0e10cSrcweir /*************************************************************************
944cdf0e10cSrcweir |*
945cdf0e10cSrcweir |*  SwFrm::IsFtnAllowed()
946cdf0e10cSrcweir |*
947cdf0e10cSrcweir |*************************************************************************/
948cdf0e10cSrcweir 
949cdf0e10cSrcweir 
IsFtnAllowed() const950cdf0e10cSrcweir sal_Bool SwFrm::IsFtnAllowed() const
951cdf0e10cSrcweir {
952cdf0e10cSrcweir     if ( !IsInDocBody() )
953cdf0e10cSrcweir         return sal_False;
954cdf0e10cSrcweir 
955cdf0e10cSrcweir     if ( IsInTab() )
956cdf0e10cSrcweir     {
957cdf0e10cSrcweir         //Keine Ftns in wiederholten Headlines.
958cdf0e10cSrcweir         const SwTabFrm *pTab = ((SwFrm*)this)->ImplFindTabFrm();
959cdf0e10cSrcweir         if ( pTab->IsFollow() )
960cdf0e10cSrcweir             return !pTab->IsInHeadline( *this );
961cdf0e10cSrcweir     }
962cdf0e10cSrcweir     return sal_True;
963cdf0e10cSrcweir }
964cdf0e10cSrcweir 
965cdf0e10cSrcweir /*************************************************************************
966cdf0e10cSrcweir |*
967cdf0e10cSrcweir |*  SwRootFrm::UpdateFtnNums()
968cdf0e10cSrcweir |*
969cdf0e10cSrcweir |*************************************************************************/
970cdf0e10cSrcweir 
971cdf0e10cSrcweir 
UpdateFtnNums()972cdf0e10cSrcweir void SwRootFrm::UpdateFtnNums()
973cdf0e10cSrcweir {
974cdf0e10cSrcweir     //Seitenweise Numerierung nur wenn es am Dokument so eingestellt ist.
975cdf0e10cSrcweir     if ( GetFmt()->GetDoc()->GetFtnInfo().eNum == FTNNUM_PAGE )
976cdf0e10cSrcweir     {
977cdf0e10cSrcweir         SwPageFrm *pPage = (SwPageFrm*)Lower();
978cdf0e10cSrcweir         while ( pPage && !pPage->IsFtnPage() )
979cdf0e10cSrcweir         {
980cdf0e10cSrcweir             pPage->UpdateFtnNum();
981cdf0e10cSrcweir             pPage = (SwPageFrm*)pPage->GetNext();
982cdf0e10cSrcweir         }
983cdf0e10cSrcweir     }
984cdf0e10cSrcweir }
985cdf0e10cSrcweir 
986cdf0e10cSrcweir /*************************************************************************
987cdf0e10cSrcweir |*
988cdf0e10cSrcweir |*  RemoveFtns()        Entfernen aller Fussnoten (nicht etwa die Referenzen)
989cdf0e10cSrcweir |*                      und Entfernen aller Fussnotenseiten.
990cdf0e10cSrcweir |*
991cdf0e10cSrcweir |*************************************************************************/
992cdf0e10cSrcweir 
lcl_RemoveFtns(SwFtnBossFrm * pBoss,sal_Bool bPageOnly,sal_Bool bEndNotes)993cdf0e10cSrcweir void lcl_RemoveFtns( SwFtnBossFrm* pBoss, sal_Bool bPageOnly, sal_Bool bEndNotes )
994cdf0e10cSrcweir {
995cdf0e10cSrcweir     do
996cdf0e10cSrcweir     {
997cdf0e10cSrcweir         SwFtnContFrm *pCont = pBoss->FindFtnCont();
998cdf0e10cSrcweir         if ( pCont )
999cdf0e10cSrcweir         {
1000cdf0e10cSrcweir             SwFtnFrm *pFtn = (SwFtnFrm*)pCont->Lower();
1001cdf0e10cSrcweir             ASSERT( pFtn, "FtnCont ohne Ftn." );
1002cdf0e10cSrcweir             if ( bPageOnly )
1003cdf0e10cSrcweir                 while ( pFtn->GetMaster() )
1004cdf0e10cSrcweir                     pFtn = pFtn->GetMaster();
1005cdf0e10cSrcweir             do
1006cdf0e10cSrcweir             {
1007cdf0e10cSrcweir                 SwFtnFrm *pNxt = (SwFtnFrm*)pFtn->GetNext();
1008cdf0e10cSrcweir                 if ( !pFtn->GetAttr()->GetFtn().IsEndNote() ||
1009cdf0e10cSrcweir                         bEndNotes )
1010cdf0e10cSrcweir                 {
1011cdf0e10cSrcweir                     pFtn->GetRef()->Prepare( PREP_FTN, (void*)pFtn->GetAttr() );
1012cdf0e10cSrcweir                     if ( bPageOnly && !pNxt )
1013cdf0e10cSrcweir                         pNxt = pFtn->GetFollow();
1014cdf0e10cSrcweir                     pFtn->Cut();
1015cdf0e10cSrcweir                     delete pFtn;
1016cdf0e10cSrcweir                 }
1017cdf0e10cSrcweir                 pFtn = pNxt;
1018cdf0e10cSrcweir 
1019cdf0e10cSrcweir             } while ( pFtn );
1020cdf0e10cSrcweir         }
1021cdf0e10cSrcweir         if( !pBoss->IsInSct() )
1022cdf0e10cSrcweir         {
1023cdf0e10cSrcweir             // A sectionframe with the Ftn/EndnAtEnd-flags may contain
1024cdf0e10cSrcweir             // foot/endnotes. If the last lower frame of the bodyframe is
1025cdf0e10cSrcweir             // a multicolumned sectionframe, it may contain footnotes, too.
1026cdf0e10cSrcweir             SwLayoutFrm* pBody = pBoss->FindBodyCont();
1027cdf0e10cSrcweir             if( pBody && pBody->Lower() )
1028cdf0e10cSrcweir             {
1029cdf0e10cSrcweir                 SwFrm* pLow = pBody->Lower();
1030cdf0e10cSrcweir                 while( pLow->GetNext() )
1031cdf0e10cSrcweir                 {
1032cdf0e10cSrcweir                     if( pLow->IsSctFrm() && ( !pLow->GetNext() ||
1033cdf0e10cSrcweir                         ((SwSectionFrm*)pLow)->IsAnyNoteAtEnd() ) &&
1034cdf0e10cSrcweir                         ((SwSectionFrm*)pLow)->Lower() &&
1035cdf0e10cSrcweir                         ((SwSectionFrm*)pLow)->Lower()->IsColumnFrm() )
1036cdf0e10cSrcweir                         lcl_RemoveFtns( (SwColumnFrm*)((SwSectionFrm*)pLow)->Lower(),
1037cdf0e10cSrcweir                             bPageOnly, bEndNotes );
1038cdf0e10cSrcweir                     pLow = pLow->GetNext();
1039cdf0e10cSrcweir                 }
1040cdf0e10cSrcweir             }
1041cdf0e10cSrcweir         }
1042cdf0e10cSrcweir         // noch 'ne Spalte?
1043cdf0e10cSrcweir         pBoss = pBoss->IsColumnFrm() ? (SwColumnFrm*)pBoss->GetNext() : NULL;
1044cdf0e10cSrcweir     } while( pBoss );
1045cdf0e10cSrcweir }
1046cdf0e10cSrcweir 
RemoveFtns(SwPageFrm * pPage,sal_Bool bPageOnly,sal_Bool bEndNotes)1047cdf0e10cSrcweir void SwRootFrm::RemoveFtns( SwPageFrm *pPage, sal_Bool bPageOnly, sal_Bool bEndNotes )
1048cdf0e10cSrcweir {
1049cdf0e10cSrcweir     if ( !pPage )
1050cdf0e10cSrcweir         pPage = (SwPageFrm*)Lower();
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir     do
1053cdf0e10cSrcweir     {   // Bei spaltigen Seiten muessen wir in allen Spalten aufraeumen
1054cdf0e10cSrcweir         SwFtnBossFrm* pBoss;
1055cdf0e10cSrcweir         SwLayoutFrm* pBody = pPage->FindBodyCont();
1056cdf0e10cSrcweir         if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
1057cdf0e10cSrcweir             pBoss = (SwFtnBossFrm*)pBody->Lower(); // die erste Spalte
1058cdf0e10cSrcweir         else
1059cdf0e10cSrcweir             pBoss = pPage; // keine Spalten
1060cdf0e10cSrcweir         lcl_RemoveFtns( pBoss, bPageOnly, bEndNotes );
1061cdf0e10cSrcweir         if ( !bPageOnly )
1062cdf0e10cSrcweir         {
1063cdf0e10cSrcweir             if ( pPage->IsFtnPage() &&
1064cdf0e10cSrcweir                  (!pPage->IsEndNotePage() || bEndNotes) )
1065cdf0e10cSrcweir             {
1066cdf0e10cSrcweir                 SwFrm *pDel = pPage;
1067cdf0e10cSrcweir                 pPage = (SwPageFrm*)pPage->GetNext();
1068cdf0e10cSrcweir                 pDel->Cut();
1069cdf0e10cSrcweir                 delete pDel;
1070cdf0e10cSrcweir             }
1071cdf0e10cSrcweir             else
1072cdf0e10cSrcweir                 pPage = (SwPageFrm*)pPage->GetNext();
1073cdf0e10cSrcweir         }
1074cdf0e10cSrcweir         else
1075cdf0e10cSrcweir             break;
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir     } while ( pPage );
1078cdf0e10cSrcweir }
1079cdf0e10cSrcweir 
1080cdf0e10cSrcweir /*************************************************************************
1081cdf0e10cSrcweir |*
1082cdf0e10cSrcweir |*  SetFtnPageDescs()   Seitenvorlagen der Fussnotenseiten aendern
1083cdf0e10cSrcweir |*
1084cdf0e10cSrcweir |*************************************************************************/
1085cdf0e10cSrcweir 
CheckFtnPageDescs(sal_Bool bEndNote)1086cdf0e10cSrcweir void SwRootFrm::CheckFtnPageDescs( sal_Bool bEndNote )
1087cdf0e10cSrcweir {
1088cdf0e10cSrcweir     SwPageFrm *pPage = (SwPageFrm*)Lower();
1089cdf0e10cSrcweir     while ( pPage && !pPage->IsFtnPage() )
1090cdf0e10cSrcweir         pPage = (SwPageFrm*)pPage->GetNext();
1091cdf0e10cSrcweir     while ( pPage && pPage->IsEndNotePage() != bEndNote )
1092cdf0e10cSrcweir         pPage = (SwPageFrm*)pPage->GetNext();
1093cdf0e10cSrcweir     if ( pPage )
1094cdf0e10cSrcweir         SwFrm::CheckPageDescs( pPage, sal_False );
1095cdf0e10cSrcweir }
1096cdf0e10cSrcweir 
1097cdf0e10cSrcweir 
1098cdf0e10cSrcweir /*************************************************************************
1099cdf0e10cSrcweir |*
1100cdf0e10cSrcweir |*  SwFtnBossFrm::MakeFtnCont()
1101cdf0e10cSrcweir |*
1102cdf0e10cSrcweir |*************************************************************************/
1103cdf0e10cSrcweir 
1104cdf0e10cSrcweir 
MakeFtnCont()1105cdf0e10cSrcweir SwFtnContFrm *SwFtnBossFrm::MakeFtnCont()
1106cdf0e10cSrcweir {
1107cdf0e10cSrcweir     //Einfuegen eines Fussnotencontainers. Der Fussnotencontainer sitzt
1108cdf0e10cSrcweir     //immer direkt hinter dem Bodytext.
1109cdf0e10cSrcweir     //Sein FrmFmt ist immer das DefaultFrmFmt.
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir #ifdef DBG_UTIL
1112cdf0e10cSrcweir     if ( FindFtnCont() )
1113870262e3SDon Lewis     {   ASSERT( sal_False, "Footnote container already available." );
1114cdf0e10cSrcweir         return 0;
1115cdf0e10cSrcweir     }
1116cdf0e10cSrcweir #endif
1117cdf0e10cSrcweir 
1118cdf0e10cSrcweir     SwFtnContFrm *pNew = new SwFtnContFrm( GetFmt()->GetDoc()->GetDfltFrmFmt(), this );
1119cdf0e10cSrcweir     SwLayoutFrm *pLay = FindBodyCont();
1120cdf0e10cSrcweir     pNew->Paste( this, pLay->GetNext() );
1121cdf0e10cSrcweir     return pNew;
1122cdf0e10cSrcweir }
1123cdf0e10cSrcweir 
1124cdf0e10cSrcweir /*************************************************************************
1125cdf0e10cSrcweir |*
1126cdf0e10cSrcweir |*  SwFtnBossFrm::FindFtnCont()
1127cdf0e10cSrcweir |*
1128cdf0e10cSrcweir |*************************************************************************/
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir 
FindFtnCont()1131cdf0e10cSrcweir SwFtnContFrm *SwFtnBossFrm::FindFtnCont()
1132cdf0e10cSrcweir {
1133cdf0e10cSrcweir     SwFrm *pFrm = Lower();
1134cdf0e10cSrcweir     while( pFrm && !pFrm->IsFtnContFrm() )
1135cdf0e10cSrcweir         pFrm = pFrm->GetNext();
1136cdf0e10cSrcweir 
1137cdf0e10cSrcweir #ifdef DBG_UTIL
1138cdf0e10cSrcweir     if ( pFrm )
1139cdf0e10cSrcweir     {
1140cdf0e10cSrcweir         SwFrm *pFtn = pFrm->GetLower();
1141cdf0e10cSrcweir         ASSERT( pFtn, "Cont ohne Fussnote." );
1142cdf0e10cSrcweir         while ( pFtn )
1143cdf0e10cSrcweir         {
1144cdf0e10cSrcweir             ASSERT( pFtn->IsFtnFrm(), "Nachbar von Fussnote keine Fussnote." );
1145cdf0e10cSrcweir             pFtn = pFtn->GetNext();
1146cdf0e10cSrcweir         }
1147cdf0e10cSrcweir     }
1148cdf0e10cSrcweir #endif
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir     return (SwFtnContFrm*)pFrm;
1151cdf0e10cSrcweir }
1152cdf0e10cSrcweir 
1153cdf0e10cSrcweir /*************************************************************************
1154cdf0e10cSrcweir |*
1155cdf0e10cSrcweir |*  SwFtnBossFrm::FindNearestFtnCont()  Sucht den naechst greifbaren Fussnotencontainer.
1156cdf0e10cSrcweir |*
1157cdf0e10cSrcweir |*************************************************************************/
1158cdf0e10cSrcweir 
FindNearestFtnCont(sal_Bool bDontLeave)1159cdf0e10cSrcweir SwFtnContFrm *SwFtnBossFrm::FindNearestFtnCont( sal_Bool bDontLeave )
1160cdf0e10cSrcweir {
1161cdf0e10cSrcweir     SwFtnContFrm *pCont = 0;
1162cdf0e10cSrcweir     if ( GetFmt()->GetDoc()->GetFtnIdxs().Count() )
1163cdf0e10cSrcweir     {
1164cdf0e10cSrcweir         pCont = FindFtnCont();
1165cdf0e10cSrcweir         if ( !pCont )
1166cdf0e10cSrcweir         {
1167cdf0e10cSrcweir             SwPageFrm *pPage = FindPageFrm();
1168cdf0e10cSrcweir             SwFtnBossFrm* pBoss = this;
1169cdf0e10cSrcweir             sal_Bool bEndNote = pPage->IsEndNotePage();
1170cdf0e10cSrcweir             do
1171cdf0e10cSrcweir             {
1172cdf0e10cSrcweir                 sal_Bool bChgPage = lcl_NextFtnBoss( pBoss, pPage, bDontLeave );
1173cdf0e10cSrcweir                 // Haben wir noch einen Boss gefunden? Bei einem Seitenwechsel muss
1174cdf0e10cSrcweir                 // zudem noch das EndNotenFlag uebereinstimmen
1175cdf0e10cSrcweir                 if( pBoss && ( !bChgPage || pPage->IsEndNotePage() == bEndNote ) )
1176cdf0e10cSrcweir                     pCont = pBoss->FindFtnCont();
1177cdf0e10cSrcweir             } while ( !pCont && pPage );
1178cdf0e10cSrcweir         }
1179cdf0e10cSrcweir     }
1180cdf0e10cSrcweir     return pCont;
1181cdf0e10cSrcweir }
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir 
1184cdf0e10cSrcweir /*************************************************************************
1185cdf0e10cSrcweir |*
1186cdf0e10cSrcweir |*  SwFtnBossFrm::FindFirstFtn()
1187cdf0e10cSrcweir |*
1188cdf0e10cSrcweir |*  Beschreibung        Erste Fussnote des Fussnotenbosses suchen.
1189cdf0e10cSrcweir |*
1190cdf0e10cSrcweir |*************************************************************************/
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir 
FindFirstFtn()1193cdf0e10cSrcweir SwFtnFrm *SwFtnBossFrm::FindFirstFtn()
1194cdf0e10cSrcweir {
1195cdf0e10cSrcweir     //Erstmal den naechsten FussnotenContainer suchen.
1196cdf0e10cSrcweir     SwFtnContFrm *pCont = FindNearestFtnCont();
1197cdf0e10cSrcweir     if ( !pCont )
1198cdf0e10cSrcweir         return 0;
1199cdf0e10cSrcweir 
1200cdf0e10cSrcweir     //Ab der ersten Fussnote im Container die erste suchen, die
1201cdf0e10cSrcweir     //von der aktuellen Spalte (bzw. einspaltigen Seite) referenziert wird.
1202cdf0e10cSrcweir 
1203cdf0e10cSrcweir     SwFtnFrm *pRet = (SwFtnFrm*)pCont->Lower();
1204cdf0e10cSrcweir     const sal_uInt16 nRefNum = FindPageFrm()->GetPhyPageNum();
1205cdf0e10cSrcweir     const sal_uInt16 nRefCol = lcl_ColumnNum( this );
1206cdf0e10cSrcweir     sal_uInt16 nPgNum, nColNum; //Seitennummer, Spaltennummer
1207cdf0e10cSrcweir     SwFtnBossFrm* pBoss;
1208cdf0e10cSrcweir     SwPageFrm* pPage;
1209cdf0e10cSrcweir     if( pRet )
1210cdf0e10cSrcweir     {
1211cdf0e10cSrcweir         pBoss = pRet->GetRef()->FindFtnBossFrm();
1212cdf0e10cSrcweir         ASSERT( pBoss, "FindFirstFtn: No boss found" );
1213cdf0e10cSrcweir         if( !pBoss )
121446d2a04eSHerbert Dürr             return NULL; // ?There must be a bug, but no GPF
1215cdf0e10cSrcweir         pPage = pBoss->FindPageFrm();
1216cdf0e10cSrcweir         nPgNum = pPage->GetPhyPageNum();
1217cdf0e10cSrcweir         if ( nPgNum == nRefNum )
1218cdf0e10cSrcweir         {
1219cdf0e10cSrcweir             nColNum = lcl_ColumnNum( pBoss );
1220cdf0e10cSrcweir             if( nColNum == nRefCol )
1221cdf0e10cSrcweir                 return pRet; //hat ihn.
1222cdf0e10cSrcweir             else if( nColNum > nRefCol )
1223cdf0e10cSrcweir                 return NULL; //mind. eine Spalte zu weit.
1224cdf0e10cSrcweir         }
1225cdf0e10cSrcweir         else if ( nPgNum > nRefNum )
1226cdf0e10cSrcweir             return NULL;    //mind. eine Seite zu weit.
1227cdf0e10cSrcweir     }
1228cdf0e10cSrcweir     else
1229cdf0e10cSrcweir         return NULL;
1230cdf0e10cSrcweir     // Ende, wenn Ref auf einer spaeteren Seite oder auf der gleichen Seite in einer
1231cdf0e10cSrcweir     // spaeteren Spalte liegt
1232cdf0e10cSrcweir 
1233cdf0e10cSrcweir     do
1234cdf0e10cSrcweir     {
1235cdf0e10cSrcweir         while ( pRet->GetFollow() )
1236cdf0e10cSrcweir             pRet = pRet->GetFollow();
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir         SwFtnFrm *pNxt = (SwFtnFrm*)pRet->GetNext();
1239cdf0e10cSrcweir         if ( !pNxt )
1240cdf0e10cSrcweir         {
1241cdf0e10cSrcweir             pBoss = pRet->FindFtnBossFrm();
1242cdf0e10cSrcweir             pPage = pBoss->FindPageFrm();
1243cdf0e10cSrcweir             lcl_NextFtnBoss( pBoss, pPage, sal_False ); // naechster FtnBoss
1244cdf0e10cSrcweir             pCont = pBoss ? pBoss->FindNearestFtnCont() : 0;
1245cdf0e10cSrcweir             if ( pCont )
1246cdf0e10cSrcweir                 pNxt = (SwFtnFrm*)pCont->Lower();
1247cdf0e10cSrcweir         }
1248cdf0e10cSrcweir         if ( pNxt )
1249cdf0e10cSrcweir         {
1250cdf0e10cSrcweir             pRet = pNxt;
1251cdf0e10cSrcweir             pBoss = pRet->GetRef()->FindFtnBossFrm();
1252cdf0e10cSrcweir             pPage = pBoss->FindPageFrm();
1253cdf0e10cSrcweir             nPgNum = pPage->GetPhyPageNum();
1254cdf0e10cSrcweir             if ( nPgNum == nRefNum )
1255cdf0e10cSrcweir             {
1256cdf0e10cSrcweir                 nColNum = lcl_ColumnNum( pBoss );
1257cdf0e10cSrcweir                 if( nColNum == nRefCol )
1258cdf0e10cSrcweir                     break; //hat ihn.
1259cdf0e10cSrcweir                 else if( nColNum > nRefCol )
1260cdf0e10cSrcweir                     pRet = 0; //mind. eine Spalte zu weit.
1261cdf0e10cSrcweir             }
1262cdf0e10cSrcweir             else if ( nPgNum > nRefNum )
1263cdf0e10cSrcweir                 pRet = 0;   //mind. eine Seite zu weit.
1264cdf0e10cSrcweir         }
1265cdf0e10cSrcweir         else
1266cdf0e10cSrcweir             pRet = 0;   //Gibt eben keinen.
1267cdf0e10cSrcweir     } while( pRet );
1268cdf0e10cSrcweir     return pRet;
1269cdf0e10cSrcweir }
1270cdf0e10cSrcweir 
1271cdf0e10cSrcweir /*************************************************************************
1272cdf0e10cSrcweir |*
1273cdf0e10cSrcweir |*  SwFtnBossFrm::FindFirstFtn()
1274cdf0e10cSrcweir |*
1275cdf0e10cSrcweir |*  Beschreibunt        Erste Fussnote zum Cnt suchen.
1276cdf0e10cSrcweir |*
1277cdf0e10cSrcweir |*************************************************************************/
1278cdf0e10cSrcweir 
1279cdf0e10cSrcweir 
FindFirstFtn(SwCntntFrm * pCnt) const1280cdf0e10cSrcweir const SwFtnFrm *SwFtnBossFrm::FindFirstFtn( SwCntntFrm *pCnt ) const
1281cdf0e10cSrcweir {
1282cdf0e10cSrcweir     const SwFtnFrm *pRet = ((SwFtnBossFrm*)this)->FindFirstFtn();
1283cdf0e10cSrcweir     if ( pRet )
1284cdf0e10cSrcweir     {
1285cdf0e10cSrcweir         const sal_uInt16 nColNum = lcl_ColumnNum( this ); //Spaltennummer
1286cdf0e10cSrcweir         const sal_uInt16 nPageNum = GetPhyPageNum();
1287cdf0e10cSrcweir         while ( pRet && (pRet->GetRef() != pCnt) )
1288cdf0e10cSrcweir         {
1289cdf0e10cSrcweir             while ( pRet->GetFollow() )
1290cdf0e10cSrcweir                 pRet = pRet->GetFollow();
1291cdf0e10cSrcweir 
1292cdf0e10cSrcweir             if ( pRet->GetNext() )
1293cdf0e10cSrcweir                 pRet = (const SwFtnFrm*)pRet->GetNext();
1294cdf0e10cSrcweir             else
1295cdf0e10cSrcweir             {   SwFtnBossFrm *pBoss = (SwFtnBossFrm*)pRet->FindFtnBossFrm();
1296cdf0e10cSrcweir                 SwPageFrm *pPage = pBoss->FindPageFrm();
1297cdf0e10cSrcweir                 lcl_NextFtnBoss( pBoss, pPage, sal_False ); // naechster FtnBoss
1298cdf0e10cSrcweir                 SwFtnContFrm *pCont = pBoss ? pBoss->FindNearestFtnCont() : 0;
1299cdf0e10cSrcweir                 pRet = pCont ? (SwFtnFrm*)pCont->Lower() : 0;
1300cdf0e10cSrcweir             }
1301cdf0e10cSrcweir             if ( pRet )
1302cdf0e10cSrcweir             {
1303cdf0e10cSrcweir                 const SwFtnBossFrm* pBoss = pRet->GetRef()->FindFtnBossFrm();
1304cdf0e10cSrcweir                 if( pBoss->GetPhyPageNum() != nPageNum ||
1305cdf0e10cSrcweir                     nColNum != lcl_ColumnNum( pBoss ) )
1306cdf0e10cSrcweir                 pRet = 0;
1307cdf0e10cSrcweir             }
1308cdf0e10cSrcweir         }
1309cdf0e10cSrcweir     }
1310cdf0e10cSrcweir     return pRet;
1311cdf0e10cSrcweir }
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir /*************************************************************************
1314cdf0e10cSrcweir |*
1315cdf0e10cSrcweir |*  SwFtnBossFrm::ResetFtn()
1316cdf0e10cSrcweir |*
1317cdf0e10cSrcweir |*************************************************************************/
1318cdf0e10cSrcweir 
1319cdf0e10cSrcweir 
ResetFtn(const SwFtnFrm * pCheck)1320cdf0e10cSrcweir void SwFtnBossFrm::ResetFtn( const SwFtnFrm *pCheck )
1321cdf0e10cSrcweir {
1322cdf0e10cSrcweir     //Vernichten der Inkarnationen von Fussnoten zum Attribut, wenn sie nicht
1323cdf0e10cSrcweir     //zu pAssumed gehoeren.
1324cdf0e10cSrcweir     ASSERT( !pCheck->GetMaster(), "Master not an Master." );
1325cdf0e10cSrcweir 
1326cdf0e10cSrcweir     SwNodeIndex aIdx( *pCheck->GetAttr()->GetStartNode(), 1 );
1327cdf0e10cSrcweir     SwCntntNode *pNd = aIdx.GetNode().GetCntntNode();
1328cdf0e10cSrcweir     if ( !pNd )
1329cdf0e10cSrcweir         pNd = pCheck->GetFmt()->GetDoc()->
1330cdf0e10cSrcweir               GetNodes().GoNextSection( &aIdx, sal_True, sal_False );
1331cdf0e10cSrcweir     SwIterator<SwFrm,SwCntntNode> aIter( *pNd );
1332cdf0e10cSrcweir     SwFrm* pFrm = aIter.First();
1333cdf0e10cSrcweir     while( pFrm )
1334cdf0e10cSrcweir     {
1335cdf0e10cSrcweir             if( pFrm->getRootFrm() == pCheck->getRootFrm() )
1336cdf0e10cSrcweir             {
1337cdf0e10cSrcweir             SwFrm *pTmp = pFrm->GetUpper();
1338cdf0e10cSrcweir             while ( pTmp && !pTmp->IsFtnFrm() )
1339cdf0e10cSrcweir                 pTmp = pTmp->GetUpper();
1340cdf0e10cSrcweir 
1341cdf0e10cSrcweir             SwFtnFrm *pFtn = (SwFtnFrm*)pTmp;
1342cdf0e10cSrcweir             while ( pFtn && pFtn->GetMaster() )
1343cdf0e10cSrcweir                 pFtn = pFtn->GetMaster();
1344cdf0e10cSrcweir             if ( pFtn != pCheck )
1345cdf0e10cSrcweir             {
1346cdf0e10cSrcweir                 while ( pFtn )
1347cdf0e10cSrcweir                 {
1348cdf0e10cSrcweir                     SwFtnFrm *pNxt = pFtn->GetFollow();
1349cdf0e10cSrcweir                     pFtn->Cut();
1350cdf0e10cSrcweir                     delete pFtn;
1351cdf0e10cSrcweir                     pFtn = pNxt;
1352cdf0e10cSrcweir                 }
1353cdf0e10cSrcweir             }
1354cdf0e10cSrcweir         }
1355cdf0e10cSrcweir 
1356cdf0e10cSrcweir         pFrm = aIter.Next();
1357cdf0e10cSrcweir     }
1358cdf0e10cSrcweir }
1359cdf0e10cSrcweir 
1360cdf0e10cSrcweir /*************************************************************************
1361cdf0e10cSrcweir |*
1362cdf0e10cSrcweir |*  SwFtnBossFrm::InsertFtn()
1363cdf0e10cSrcweir |*
1364cdf0e10cSrcweir |*************************************************************************/
1365cdf0e10cSrcweir 
1366cdf0e10cSrcweir 
InsertFtn(SwFtnFrm * pNew)1367cdf0e10cSrcweir void SwFtnBossFrm::InsertFtn( SwFtnFrm* pNew )
1368cdf0e10cSrcweir {
1369cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL)
1370cdf0e10cSrcweir     static sal_uInt16 nStop = 0;
1371cdf0e10cSrcweir     if ( nStop == pNew->GetFrmId() )
1372cdf0e10cSrcweir     {
1373cdf0e10cSrcweir         int bla = 5;
1374cdf0e10cSrcweir         (void)bla;
1375cdf0e10cSrcweir     }
1376cdf0e10cSrcweir #endif
1377cdf0e10cSrcweir     //Die Fussnote haben wir, sie muss jetzt nur noch irgendwo
1378cdf0e10cSrcweir     //hin und zwar vor die Fussnote, deren Attribut vor das
1379cdf0e10cSrcweir     //der neuen zeigt (Position wird ueber das Doc ermittelt)
1380cdf0e10cSrcweir     //Gibt es in diesem Fussnotenboss noch keine Fussnoten, so muss eben ein
1381cdf0e10cSrcweir     //Container erzeugt werden.
1382cdf0e10cSrcweir     //Gibt es bereits einen Container aber noch keine Fussnote zu diesem
1383cdf0e10cSrcweir     //Fussnotenboss, so muss die Fussnote hinter die letzte Fussnote der dichtesten
1384cdf0e10cSrcweir     //Vorseite/spalte.
1385cdf0e10cSrcweir 
1386cdf0e10cSrcweir     ResetFtn( pNew );
1387cdf0e10cSrcweir     SwFtnFrm *pSibling = FindFirstFtn();
1388cdf0e10cSrcweir     sal_Bool bDontLeave = sal_False;
1389cdf0e10cSrcweir 
1390cdf0e10cSrcweir     // Ok, a sibling has been found, but is the sibling in an acceptable
1391cdf0e10cSrcweir     // environment?
1392cdf0e10cSrcweir     if( IsInSct() )
1393cdf0e10cSrcweir     {
1394cdf0e10cSrcweir         SwSectionFrm* pMySect = ImplFindSctFrm();
1395cdf0e10cSrcweir         bool bEndnt = pNew->GetAttr()->GetFtn().IsEndNote();
1396cdf0e10cSrcweir         if( bEndnt )
1397cdf0e10cSrcweir         {
1398cdf0e10cSrcweir             const SwSectionFmt* pEndFmt = pMySect->GetEndSectFmt();
1399cdf0e10cSrcweir             bDontLeave = 0 != pEndFmt;
1400cdf0e10cSrcweir             if( pSibling )
1401cdf0e10cSrcweir             {
1402cdf0e10cSrcweir                 if( pEndFmt )
1403cdf0e10cSrcweir                 {
1404cdf0e10cSrcweir                     if( !pSibling->IsInSct() ||
1405cdf0e10cSrcweir                         !pSibling->ImplFindSctFrm()->IsDescendantFrom( pEndFmt ) )
1406cdf0e10cSrcweir                         pSibling = NULL;
1407cdf0e10cSrcweir                 }
1408cdf0e10cSrcweir                 else if( pSibling->IsInSct() )
1409cdf0e10cSrcweir                     pSibling = NULL;
1410cdf0e10cSrcweir             }
1411cdf0e10cSrcweir         }
1412cdf0e10cSrcweir         else
1413cdf0e10cSrcweir         {
1414cdf0e10cSrcweir             bDontLeave = pMySect->IsFtnAtEnd();
1415cdf0e10cSrcweir             if( pSibling )
1416cdf0e10cSrcweir             {
1417cdf0e10cSrcweir                 if( pMySect->IsFtnAtEnd() )
1418cdf0e10cSrcweir                 {
1419cdf0e10cSrcweir                     if( !pSibling->IsInSct() ||
1420cdf0e10cSrcweir                         !pMySect->IsAnFollow( pSibling->ImplFindSctFrm() ) )
1421cdf0e10cSrcweir                         pSibling = NULL;
1422cdf0e10cSrcweir                 }
1423cdf0e10cSrcweir                 else if( pSibling->IsInSct() )
1424cdf0e10cSrcweir                     pSibling = NULL;
1425cdf0e10cSrcweir             }
1426cdf0e10cSrcweir         }
1427cdf0e10cSrcweir     }
1428cdf0e10cSrcweir 
1429cdf0e10cSrcweir     if( pSibling && pSibling->FindPageFrm()->IsEndNotePage() !=
1430cdf0e10cSrcweir         FindPageFrm()->IsEndNotePage() )
1431cdf0e10cSrcweir         pSibling = NULL;
1432cdf0e10cSrcweir 
1433cdf0e10cSrcweir     //Damit die Position herausgefunden werden kann.
1434cdf0e10cSrcweir     SwDoc *pDoc = GetFmt()->GetDoc();
1435cdf0e10cSrcweir     const sal_uLong nStPos = ::lcl_FindFtnPos( pDoc, pNew->GetAttr() );
1436cdf0e10cSrcweir 
1437cdf0e10cSrcweir     sal_uLong nCmpPos = 0;
1438cdf0e10cSrcweir     sal_uLong nLastPos = 0;
1439cdf0e10cSrcweir     SwFtnContFrm *pParent = 0;
1440cdf0e10cSrcweir     if( pSibling )
1441cdf0e10cSrcweir     {
1442cdf0e10cSrcweir         nCmpPos = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
1443cdf0e10cSrcweir         if( nCmpPos > nStPos )
1444cdf0e10cSrcweir             pSibling = NULL;
1445cdf0e10cSrcweir     }
1446cdf0e10cSrcweir 
1447cdf0e10cSrcweir     if ( !pSibling )
1448cdf0e10cSrcweir     {   pParent = FindFtnCont();
1449cdf0e10cSrcweir         if ( !pParent )
1450cdf0e10cSrcweir         {
1451cdf0e10cSrcweir             //Es gibt noch keinen FussnotenContainer, also machen wir einen.
1452cdf0e10cSrcweir             //HAAAAAAAALT! So einfach ist das leider mal wieder nicht: Es kann
1453cdf0e10cSrcweir             //sein, dass irgendeine naechste Fussnote existiert die vor der
1454cdf0e10cSrcweir             //einzufuegenden zu stehen hat, weil z.B. eine Fussnote ueber zig
1455cdf0e10cSrcweir             //Seiten aufgespalten ist usw.
1456cdf0e10cSrcweir             pParent = FindNearestFtnCont( bDontLeave );
1457cdf0e10cSrcweir             if ( pParent )
1458cdf0e10cSrcweir             {
1459cdf0e10cSrcweir                 SwFtnFrm *pFtn = (SwFtnFrm*)pParent->Lower();
1460cdf0e10cSrcweir                 if ( pFtn )
1461cdf0e10cSrcweir                 {
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir                     nCmpPos = ::lcl_FindFtnPos( pDoc, pFtn->GetAttr() );
1464cdf0e10cSrcweir                     if ( nCmpPos > nStPos )
1465cdf0e10cSrcweir                         pParent = 0;
1466cdf0e10cSrcweir                 }
1467cdf0e10cSrcweir                 else
1468cdf0e10cSrcweir                     pParent = 0;
1469cdf0e10cSrcweir             }
1470cdf0e10cSrcweir         }
1471cdf0e10cSrcweir         if ( !pParent )
1472cdf0e10cSrcweir             //Jetzt kann aber ein Fussnotencontainer gebaut werden.
1473cdf0e10cSrcweir             pParent = MakeFtnCont();
1474cdf0e10cSrcweir         else
1475cdf0e10cSrcweir         {
1476cdf0e10cSrcweir             //Ausgehend von der ersten Fussnote unterhalb des Parents wird die
1477cdf0e10cSrcweir             //erste Fussnote gesucht deren Index hinter dem Index der
1478cdf0e10cSrcweir             //einzufuegenden liegt; vor dieser kann der neue dann gepastet
1479cdf0e10cSrcweir             //werden.
1480cdf0e10cSrcweir             pSibling = (SwFtnFrm*)pParent->Lower();
1481cdf0e10cSrcweir             if ( !pSibling )
1482870262e3SDon Lewis             {   ASSERT( sal_False, "No space for footnote found.");
1483cdf0e10cSrcweir                 return;
1484cdf0e10cSrcweir             }
1485cdf0e10cSrcweir             nCmpPos  = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
1486cdf0e10cSrcweir 
1487cdf0e10cSrcweir             SwFtnBossFrm *pNxtB = this; //Immer den letzten merken, damit wir nicht
1488cdf0e10cSrcweir             SwFtnFrm  *pLastSib = 0;    //ueber das Ziel hinausschiessen.
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir             while ( pSibling && nCmpPos <= nStPos )
1491cdf0e10cSrcweir             {
1492cdf0e10cSrcweir                 pLastSib = pSibling; // der kommt schon mal in Frage
1493cdf0e10cSrcweir                 nLastPos = nCmpPos;
1494cdf0e10cSrcweir 
1495cdf0e10cSrcweir                 while ( pSibling->GetFollow() )
1496cdf0e10cSrcweir                     pSibling = pSibling->GetFollow();
1497cdf0e10cSrcweir 
1498cdf0e10cSrcweir                 if ( pSibling->GetNext() )
1499cdf0e10cSrcweir                 {
1500cdf0e10cSrcweir                     pSibling = (SwFtnFrm*)pSibling->GetNext();
1501cdf0e10cSrcweir                     ASSERT( !pSibling->GetMaster() || ( ENDNOTE > nStPos &&
1502cdf0e10cSrcweir                             pSibling->GetAttr()->GetFtn().IsEndNote() ),
1503cdf0e10cSrcweir                             "InsertFtn: Master expected I" );
1504cdf0e10cSrcweir                 }
1505cdf0e10cSrcweir                 else
1506cdf0e10cSrcweir                 {
1507cdf0e10cSrcweir                     pNxtB = pSibling->FindFtnBossFrm();
1508cdf0e10cSrcweir                     SwPageFrm *pSibPage = pNxtB->FindPageFrm();
1509cdf0e10cSrcweir                     sal_Bool bEndNote = pSibPage->IsEndNotePage();
1510cdf0e10cSrcweir                     sal_Bool bChgPage = lcl_NextFtnBoss( pNxtB, pSibPage, bDontLeave );
1511cdf0e10cSrcweir                     // Bei Seitenwechsel muss das EndNoteFlag ueberprueft werden.
1512cdf0e10cSrcweir                     SwFtnContFrm *pCont = pNxtB && ( !bChgPage ||
1513cdf0e10cSrcweir                         pSibPage->IsEndNotePage() == bEndNote )
1514cdf0e10cSrcweir                         ? pNxtB->FindNearestFtnCont( bDontLeave ) : 0;
1515cdf0e10cSrcweir                     if( pCont )
1516cdf0e10cSrcweir                         pSibling = (SwFtnFrm*)pCont->Lower();
1517cdf0e10cSrcweir                     else // kein weiterer FtnContainer, dann werden  wir uns wohl hinter
1518cdf0e10cSrcweir                         break; // pSibling haengen
1519cdf0e10cSrcweir                 }
1520cdf0e10cSrcweir                 if ( pSibling )
1521cdf0e10cSrcweir                 {
1522cdf0e10cSrcweir                     nCmpPos = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
1523cdf0e10cSrcweir                     ASSERT( nCmpPos > nLastPos, "InsertFtn: Order of FtnFrm's buggy" );
1524cdf0e10cSrcweir                 }
1525cdf0e10cSrcweir             }
1526cdf0e10cSrcweir             // pLastSib ist jetzt die letzte Fussnote vor uns,
1527cdf0e10cSrcweir             // pSibling leer oder die erste nach uns.
1528cdf0e10cSrcweir             if ( pSibling && pLastSib && (pSibling != pLastSib) )
1529cdf0e10cSrcweir             {   //Sind wir vielleicht bereits ueber das Ziel hinausgeschossen?
1530cdf0e10cSrcweir                 if ( nCmpPos > nStPos )
1531cdf0e10cSrcweir                     pSibling = pLastSib;
1532cdf0e10cSrcweir             }
1533cdf0e10cSrcweir             else if ( !pSibling )
1534cdf0e10cSrcweir             {   //Eine Chance haben wir noch: wir nehmen einfach die letzte
1535cdf0e10cSrcweir                 //Fussnote im Parent. Ein Sonderfall, der z.B. beim
1536cdf0e10cSrcweir                 //zurueckfliessen von Absaetzen mit mehreren Fussnoten
1537cdf0e10cSrcweir                 //vorkommt.
1538cdf0e10cSrcweir                 //Damit wir nicht die Reihenfolge verwuerfeln muessen wir den
1539cdf0e10cSrcweir                 //Parent der letzten Fussnote, die wir an der Hand hatten benutzen.
1540cdf0e10cSrcweir                 pSibling = pLastSib;
1541cdf0e10cSrcweir                 while( pSibling->GetFollow() )
1542cdf0e10cSrcweir                     pSibling = pSibling->GetFollow();
1543cdf0e10cSrcweir                 ASSERT( !pSibling->GetNext(), "InsertFtn: Who's that guy?" );
1544cdf0e10cSrcweir             }
1545cdf0e10cSrcweir         }
1546cdf0e10cSrcweir     }
1547cdf0e10cSrcweir     else
1548cdf0e10cSrcweir     {   //Die erste Fussnote der Spalte/Seite haben wir an der Hand, jetzt ausgehend
1549cdf0e10cSrcweir         //von dieser die erste zur selben Spalte/Seite suchen deren Index hinter
1550cdf0e10cSrcweir         //den uebergebenen zeigt, die letzte, die wir an der Hand hatten, ist
1551cdf0e10cSrcweir         //dann der Vorgaenger.
1552cdf0e10cSrcweir         SwFtnBossFrm* pBoss = pNew->GetRef()->FindFtnBossFrm(
1553cdf0e10cSrcweir             !pNew->GetAttr()->GetFtn().IsEndNote() );
1554cdf0e10cSrcweir         sal_uInt16 nRefNum = pBoss->GetPhyPageNum();    // Die Seiten- und
1555cdf0e10cSrcweir         sal_uInt16 nRefCol = lcl_ColumnNum( pBoss );    // Spaltennummer der neuen Fussnote
1556cdf0e10cSrcweir         sal_Bool bEnd = sal_False;
1557cdf0e10cSrcweir         SwFtnFrm *pLastSib = 0;
1558cdf0e10cSrcweir         while ( pSibling && !bEnd && (nCmpPos <= nStPos) )
1559cdf0e10cSrcweir         {
1560cdf0e10cSrcweir             pLastSib = pSibling;
1561cdf0e10cSrcweir             nLastPos = nCmpPos;
1562cdf0e10cSrcweir 
1563cdf0e10cSrcweir             while ( pSibling->GetFollow() )
1564cdf0e10cSrcweir                 pSibling = pSibling->GetFollow();
1565cdf0e10cSrcweir 
1566cdf0e10cSrcweir             SwFtnFrm *pFoll = (SwFtnFrm*)pSibling->GetNext();
1567cdf0e10cSrcweir             if ( pFoll )
1568cdf0e10cSrcweir             {
1569cdf0e10cSrcweir                 pBoss = pSibling->GetRef()->FindFtnBossFrm( !pSibling->
1570cdf0e10cSrcweir                                             GetAttr()->GetFtn().IsEndNote() );
1571cdf0e10cSrcweir                 sal_uInt16 nTmpRef;
1572cdf0e10cSrcweir                 if( nStPos >= ENDNOTE ||
1573cdf0e10cSrcweir                     (nTmpRef = pBoss->GetPhyPageNum()) < nRefNum ||
1574cdf0e10cSrcweir                     ( nTmpRef == nRefNum && lcl_ColumnNum( pBoss ) <= nRefCol ))
1575cdf0e10cSrcweir                     pSibling = pFoll;
1576cdf0e10cSrcweir                 else
1577cdf0e10cSrcweir                     bEnd = sal_True;
1578cdf0e10cSrcweir             }
1579cdf0e10cSrcweir             else
1580cdf0e10cSrcweir             {
1581cdf0e10cSrcweir                 SwFtnBossFrm* pNxtB = pSibling->FindFtnBossFrm();
1582cdf0e10cSrcweir                 SwPageFrm *pSibPage = pNxtB->FindPageFrm();
1583cdf0e10cSrcweir                 sal_Bool bEndNote = pSibPage->IsEndNotePage();
1584cdf0e10cSrcweir                 sal_Bool bChgPage = lcl_NextFtnBoss( pNxtB, pSibPage, bDontLeave );
1585cdf0e10cSrcweir                 // Bei Seitenwechsel muss das EndNoteFlag ueberprueft werden.
1586cdf0e10cSrcweir                 SwFtnContFrm *pCont = pNxtB && ( !bChgPage ||
1587cdf0e10cSrcweir                     pSibPage->IsEndNotePage() == bEndNote )
1588cdf0e10cSrcweir                     ? pNxtB->FindNearestFtnCont( bDontLeave ) : 0;
1589cdf0e10cSrcweir                 if ( pCont )
1590cdf0e10cSrcweir                     pSibling = (SwFtnFrm*)pCont->Lower();
1591cdf0e10cSrcweir                 else
1592cdf0e10cSrcweir                     bEnd = sal_True;
1593cdf0e10cSrcweir             }
1594cdf0e10cSrcweir             if ( !bEnd && pSibling )
1595cdf0e10cSrcweir                 nCmpPos = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
1596cdf0e10cSrcweir             if ( pSibling && pLastSib && (pSibling != pLastSib) )
1597cdf0e10cSrcweir             {   //Sind wir vielleicht bereits ueber das Ziel hinausgeschossen?
1598cdf0e10cSrcweir                 if ( (nLastPos < nCmpPos) && (nCmpPos > nStPos) )
1599cdf0e10cSrcweir                 {
1600cdf0e10cSrcweir                     pSibling = pLastSib;
1601cdf0e10cSrcweir                     bEnd = sal_True;
1602cdf0e10cSrcweir                 }
1603cdf0e10cSrcweir             }
1604cdf0e10cSrcweir         }
1605cdf0e10cSrcweir     }
1606cdf0e10cSrcweir     if ( pSibling )
1607cdf0e10cSrcweir     {
1608cdf0e10cSrcweir         nCmpPos = ::lcl_FindFtnPos( pDoc, pSibling->GetAttr() );
1609cdf0e10cSrcweir         if ( nCmpPos < nStPos )
1610cdf0e10cSrcweir         {
1611cdf0e10cSrcweir             while ( pSibling->GetFollow() )
1612cdf0e10cSrcweir                 pSibling = pSibling->GetFollow();
1613cdf0e10cSrcweir             pParent = (SwFtnContFrm*)pSibling->GetUpper();
1614cdf0e10cSrcweir             pSibling = (SwFtnFrm*)pSibling->GetNext();
1615cdf0e10cSrcweir         }
1616cdf0e10cSrcweir         else
1617cdf0e10cSrcweir         {
1618cdf0e10cSrcweir             if( pSibling->GetMaster() )
1619cdf0e10cSrcweir             {
1620cdf0e10cSrcweir                 if( ENDNOTE > nCmpPos || nStPos >= ENDNOTE )
1621cdf0e10cSrcweir                 {
1622cdf0e10cSrcweir                     ASSERT( sal_False, "InsertFtn: Master expected II" );
1623cdf0e10cSrcweir                     do
1624cdf0e10cSrcweir                         pSibling = pSibling->GetMaster();
1625cdf0e10cSrcweir                     while ( pSibling->GetMaster() );
1626cdf0e10cSrcweir                 }
1627cdf0e10cSrcweir             }
1628cdf0e10cSrcweir             pParent = (SwFtnContFrm*)pSibling->GetUpper();
1629cdf0e10cSrcweir         }
1630cdf0e10cSrcweir     }
1631cdf0e10cSrcweir     ASSERT( pParent, "paste in space?" );
1632cdf0e10cSrcweir     pNew->Paste( pParent, pSibling );
1633cdf0e10cSrcweir }
1634cdf0e10cSrcweir 
1635cdf0e10cSrcweir /*************************************************************************
1636cdf0e10cSrcweir |*
1637cdf0e10cSrcweir |*  SwFtnBossFrm::AppendFtn()
1638cdf0e10cSrcweir |*
1639cdf0e10cSrcweir |*************************************************************************/
1640cdf0e10cSrcweir 
1641cdf0e10cSrcweir 
AppendFtn(SwCntntFrm * pRef,SwTxtFtn * pAttr)1642cdf0e10cSrcweir void SwFtnBossFrm::AppendFtn( SwCntntFrm *pRef, SwTxtFtn *pAttr )
1643cdf0e10cSrcweir {
1644cdf0e10cSrcweir     //Wenn es die Fussnote schon gibt tun wir nix.
1645cdf0e10cSrcweir     if ( FindFtn( pRef, pAttr ) )
1646cdf0e10cSrcweir         return;
1647cdf0e10cSrcweir 
1648cdf0e10cSrcweir     //Wenn Fussnoten am Dokumentende eingestellt sind, so brauchen wir 'eh erst
1649cdf0e10cSrcweir     //ab der entsprechenden Seite zu suchen.
1650cdf0e10cSrcweir     //Wenn es noch keine gibt, muss eben eine erzeugt werden.
1651cdf0e10cSrcweir     //Wenn es sich um eine Endnote handelt, muss eine Endnotenseite gesucht
1652cdf0e10cSrcweir     //bzw. erzeugt werden.
1653cdf0e10cSrcweir     SwDoc *pDoc = GetFmt()->GetDoc();
1654cdf0e10cSrcweir     SwFtnBossFrm *pBoss = this;
1655cdf0e10cSrcweir     SwPageFrm *pPage = FindPageFrm();
1656cdf0e10cSrcweir     SwPageFrm *pMyPage = pPage;
1657cdf0e10cSrcweir     sal_Bool bChgPage = sal_False;
1658cdf0e10cSrcweir     sal_Bool bEnd = sal_False;
1659cdf0e10cSrcweir     if ( pAttr->GetFtn().IsEndNote() )
1660cdf0e10cSrcweir     {
1661cdf0e10cSrcweir         bEnd = sal_True;
1662cdf0e10cSrcweir         if( GetUpper()->IsSctFrm() &&
1663cdf0e10cSrcweir             ((SwSectionFrm*)GetUpper())->IsEndnAtEnd() )
1664cdf0e10cSrcweir         {
1665cdf0e10cSrcweir             SwFrm* pLast =
1666cdf0e10cSrcweir                 ((SwSectionFrm*)GetUpper())->FindLastCntnt( FINDMODE_ENDNOTE );
1667cdf0e10cSrcweir             if( pLast )
1668cdf0e10cSrcweir             {
1669cdf0e10cSrcweir                 pBoss = pLast->FindFtnBossFrm();
1670cdf0e10cSrcweir                 pPage = pBoss->FindPageFrm();
1671cdf0e10cSrcweir             }
1672cdf0e10cSrcweir         }
1673cdf0e10cSrcweir         else
1674cdf0e10cSrcweir         {
1675cdf0e10cSrcweir             while ( pPage->GetNext() && !pPage->IsEndNotePage() )
1676cdf0e10cSrcweir             {
1677cdf0e10cSrcweir                 pPage = (SwPageFrm*)pPage->GetNext();
1678cdf0e10cSrcweir                 bChgPage = sal_True;
1679cdf0e10cSrcweir             }
1680cdf0e10cSrcweir             if ( !pPage->IsEndNotePage() )
1681cdf0e10cSrcweir             {
1682cdf0e10cSrcweir                 SwPageDesc *pDesc = pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
1683cdf0e10cSrcweir                 pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(),
1684cdf0e10cSrcweir                         !pPage->OnRightPage(), sal_False, sal_True, 0 );
1685cdf0e10cSrcweir                 pPage->SetEndNotePage( sal_True );
1686cdf0e10cSrcweir                 bChgPage = sal_True;
1687cdf0e10cSrcweir             }
1688cdf0e10cSrcweir             else
1689cdf0e10cSrcweir             {
1690cdf0e10cSrcweir                 //Wir koennen wenigstens schon mal ungefaehr die richtige Seite
1691cdf0e10cSrcweir                 //suchen. Damit stellen wir sicher das wir auch bei hunderten
1692cdf0e10cSrcweir                 //Fussnoten noch in endlicher Zeit fertig werden.
1693cdf0e10cSrcweir                 SwPageFrm *pNxt = (SwPageFrm*)pPage->GetNext();
1694cdf0e10cSrcweir                 const sal_uLong nStPos = ::lcl_FindFtnPos( pDoc, pAttr );
1695cdf0e10cSrcweir                 while ( pNxt && pNxt->IsEndNotePage() )
1696cdf0e10cSrcweir                 {
1697cdf0e10cSrcweir                     SwFtnContFrm *pCont = pNxt->FindFtnCont();
1698cdf0e10cSrcweir                     if ( pCont && pCont->Lower() )
1699cdf0e10cSrcweir                     {
1700cdf0e10cSrcweir                         ASSERT( pCont->Lower()->IsFtnFrm(), "Keine Ftn im Container" );
1701cdf0e10cSrcweir                         if ( nStPos > ::lcl_FindFtnPos( pDoc,
1702cdf0e10cSrcweir                                         ((SwFtnFrm*)pCont->Lower())->GetAttr()))
1703cdf0e10cSrcweir                         {
1704cdf0e10cSrcweir                             pPage = pNxt;
1705cdf0e10cSrcweir                             pNxt = (SwPageFrm*)pPage->GetNext();
1706cdf0e10cSrcweir                             continue;
1707cdf0e10cSrcweir                         }
1708cdf0e10cSrcweir                     }
1709cdf0e10cSrcweir                     break;
1710cdf0e10cSrcweir                 }
1711cdf0e10cSrcweir             }
1712cdf0e10cSrcweir         }
1713cdf0e10cSrcweir     }
1714cdf0e10cSrcweir     else if( FTNPOS_CHAPTER == pDoc->GetFtnInfo().ePos && ( !GetUpper()->
1715cdf0e10cSrcweir              IsSctFrm() || !((SwSectionFrm*)GetUpper())->IsFtnAtEnd() ) )
1716cdf0e10cSrcweir     {
1717cdf0e10cSrcweir         while ( pPage->GetNext() && !pPage->IsFtnPage() &&
1718cdf0e10cSrcweir                 !((SwPageFrm*)pPage->GetNext())->IsEndNotePage() )
1719cdf0e10cSrcweir         {
1720cdf0e10cSrcweir             pPage = (SwPageFrm*)pPage->GetNext();
1721cdf0e10cSrcweir             bChgPage = sal_True;
1722cdf0e10cSrcweir         }
1723cdf0e10cSrcweir 
1724cdf0e10cSrcweir         if ( !pPage->IsFtnPage() )
1725cdf0e10cSrcweir         {
1726cdf0e10cSrcweir             SwPageDesc *pDesc = pDoc->GetFtnInfo().GetPageDesc( *pDoc );
1727cdf0e10cSrcweir             pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(),
1728cdf0e10cSrcweir                 !pPage->OnRightPage(), sal_False, sal_True, pPage->GetNext() );
1729cdf0e10cSrcweir             bChgPage = sal_True;
1730cdf0e10cSrcweir         }
1731cdf0e10cSrcweir         else
1732cdf0e10cSrcweir         {
1733cdf0e10cSrcweir             //Wir koennen wenigstens schon mal ungefaehr die richtige Seite
1734cdf0e10cSrcweir             //suchen. Damit stellen wir sicher das wir auch bei hunderten
1735cdf0e10cSrcweir             //Fussnoten noch in endlicher Zeit fertig werden.
1736cdf0e10cSrcweir             SwPageFrm *pNxt = (SwPageFrm*)pPage->GetNext();
1737cdf0e10cSrcweir             const sal_uLong nStPos = ::lcl_FindFtnPos( pDoc, pAttr );
1738cdf0e10cSrcweir             while ( pNxt && pNxt->IsFtnPage() && !pNxt->IsEndNotePage() )
1739cdf0e10cSrcweir             {
1740cdf0e10cSrcweir                 SwFtnContFrm *pCont = pNxt->FindFtnCont();
1741cdf0e10cSrcweir                 if ( pCont && pCont->Lower() )
1742cdf0e10cSrcweir                 {
1743cdf0e10cSrcweir                     ASSERT( pCont->Lower()->IsFtnFrm(), "Keine Ftn im Container" );
1744cdf0e10cSrcweir                     if ( nStPos > ::lcl_FindFtnPos( pDoc,
1745cdf0e10cSrcweir                                         ((SwFtnFrm*)pCont->Lower())->GetAttr()))
1746cdf0e10cSrcweir                     {
1747cdf0e10cSrcweir                         pPage = pNxt;
1748cdf0e10cSrcweir                         pNxt = (SwPageFrm*)pPage->GetNext();
1749cdf0e10cSrcweir                         continue;
1750cdf0e10cSrcweir                     }
1751cdf0e10cSrcweir                 }
1752cdf0e10cSrcweir                 break;
1753cdf0e10cSrcweir             }
1754cdf0e10cSrcweir         }
1755cdf0e10cSrcweir     }
1756cdf0e10cSrcweir 
1757cdf0e10cSrcweir     //Erstmal eine Fussnote und die benoetigten CntntFrms anlegen.
1758cdf0e10cSrcweir     if ( !pAttr->GetStartNode() )
1759870262e3SDon Lewis     {   ASSERT( sal_False, "No footnote content." );
1760cdf0e10cSrcweir         return;
1761cdf0e10cSrcweir     }
1762cdf0e10cSrcweir 
1763cdf0e10cSrcweir     // Wenn es auf der Seite/Spalte bereits einen FtnCont gibt,
1764cdf0e10cSrcweir     // kann in einen spaltigen Bereich keiner erzeugt werden.
1765cdf0e10cSrcweir     if( pBoss->IsInSct() && pBoss->IsColumnFrm() && !pPage->IsFtnPage() )
1766cdf0e10cSrcweir     {
1767cdf0e10cSrcweir         SwSectionFrm* pSct = pBoss->FindSctFrm();
1768cdf0e10cSrcweir         if( bEnd ? !pSct->IsEndnAtEnd() : !pSct->IsFtnAtEnd() )
1769cdf0e10cSrcweir         {
1770cdf0e10cSrcweir             SwFtnContFrm* pFtnCont = pSct->FindFtnBossFrm(!bEnd)->FindFtnCont();
1771cdf0e10cSrcweir             if( pFtnCont )
1772cdf0e10cSrcweir             {
1773cdf0e10cSrcweir                 SwFtnFrm* pTmp = (SwFtnFrm*)pFtnCont->Lower();
1774cdf0e10cSrcweir                 if( bEnd )
1775cdf0e10cSrcweir                     while( pTmp && !pTmp->GetAttr()->GetFtn().IsEndNote() )
1776cdf0e10cSrcweir                         pTmp = (SwFtnFrm*)pTmp->GetNext();
1777cdf0e10cSrcweir                 if( pTmp && *pTmp < pAttr )
1778cdf0e10cSrcweir                     return;
1779cdf0e10cSrcweir             }
1780cdf0e10cSrcweir         }
1781cdf0e10cSrcweir     }
1782cdf0e10cSrcweir 
1783cdf0e10cSrcweir     SwFtnFrm *pNew = new SwFtnFrm( pDoc->GetDfltFrmFmt(), this, pRef, pAttr );
1784cdf0e10cSrcweir     {
1785cdf0e10cSrcweir         SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
1786cdf0e10cSrcweir         ::_InsertCnt( pNew, pDoc, aIdx.GetIndex() );
1787cdf0e10cSrcweir     }
1788cdf0e10cSrcweir     // Wenn die Seite gewechselt (oder gar neu angelegt) wurde,
1789cdf0e10cSrcweir     // muessen wir uns dort in die erste Spalte setzen
1790cdf0e10cSrcweir     if( bChgPage )
1791cdf0e10cSrcweir     {
1792cdf0e10cSrcweir         SwLayoutFrm* pBody = pPage->FindBodyCont();
1793cdf0e10cSrcweir         ASSERT( pBody, "AppendFtn: NoPageBody?" );
1794cdf0e10cSrcweir         if( pBody->Lower() && pBody->Lower()->IsColumnFrm() )
1795cdf0e10cSrcweir             pBoss = (SwFtnBossFrm*)pBody->Lower();
1796cdf0e10cSrcweir         else
1797cdf0e10cSrcweir             pBoss = pPage; // bei nichtspaltigen Seiten auf die Seite selbst
1798cdf0e10cSrcweir     }
1799cdf0e10cSrcweir     pBoss->InsertFtn( pNew );
1800cdf0e10cSrcweir     if ( pNew->GetUpper() )         //Eingesetzt oder nicht?
1801cdf0e10cSrcweir     {
1802cdf0e10cSrcweir         ::RegistFlys( pNew->FindPageFrm(), pNew );
1803cdf0e10cSrcweir         SwSectionFrm* pSect = FindSctFrm();
1804cdf0e10cSrcweir         // Der Inhalt des FtnContainers in einem (spaltigen) Bereich
1805cdf0e10cSrcweir         // braucht nur kalkuliert zu werden,
1806cdf0e10cSrcweir         // wenn der Bereich bereits bis zur Unterkante seines Uppers geht.
1807cdf0e10cSrcweir         if( pSect && !pSect->IsJoinLocked() && ( bEnd ? !pSect->IsEndnAtEnd() :
1808cdf0e10cSrcweir             !pSect->IsFtnAtEnd() ) && pSect->Growable() )
1809cdf0e10cSrcweir             pSect->InvalidateSize();
1810cdf0e10cSrcweir         else
1811cdf0e10cSrcweir         {
1812cdf0e10cSrcweir             // --> OD 2005-05-18 #i49383# - disable unlock of position of
1813cdf0e10cSrcweir             // lower objects during format of footnote content.
1814cdf0e10cSrcweir             const bool bOldFtnFrmLocked( pNew->IsColLocked() );
1815cdf0e10cSrcweir             pNew->ColLock();
1816cdf0e10cSrcweir             pNew->KeepLockPosOfLowerObjs();
1817cdf0e10cSrcweir             // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
1818cdf0e10cSrcweir             // no extra notify for footnote frame
1819cdf0e10cSrcweir //            SwLayNotify* pFtnFrmNotitfy = new SwLayNotify( pNew );
1820cdf0e10cSrcweir             // <--
1821cdf0e10cSrcweir             SwCntntFrm *pCnt = pNew->ContainsCntnt();
1822cdf0e10cSrcweir             while ( pCnt && pCnt->FindFtnFrm()->GetAttr() == pAttr )
1823cdf0e10cSrcweir             {
1824cdf0e10cSrcweir                 pCnt->Calc();
1825cdf0e10cSrcweir                 // --> OD 2005-05-17 #i49383# - format anchored objects
1826cdf0e10cSrcweir                 if ( pCnt->IsTxtFrm() && pCnt->IsValid() )
1827cdf0e10cSrcweir                 {
1828cdf0e10cSrcweir                     if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
1829cdf0e10cSrcweir                                                               *(pCnt->FindPageFrm()) ) )
1830cdf0e10cSrcweir                     {
1831cdf0e10cSrcweir                         // restart format with first content
1832cdf0e10cSrcweir                         pCnt = pNew->ContainsCntnt();
1833cdf0e10cSrcweir                         continue;
1834cdf0e10cSrcweir                     }
1835cdf0e10cSrcweir                 }
1836cdf0e10cSrcweir                 // <--
1837cdf0e10cSrcweir                 pCnt = (SwCntntFrm*)pCnt->FindNextCnt();
1838cdf0e10cSrcweir             }
1839cdf0e10cSrcweir             // --> OD 2005-05-18 #i49383#
1840cdf0e10cSrcweir             if ( !bOldFtnFrmLocked )
1841cdf0e10cSrcweir             {
1842cdf0e10cSrcweir                 pNew->ColUnlock();
1843cdf0e10cSrcweir             }
1844cdf0e10cSrcweir             // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
1845cdf0e10cSrcweir             // enable lock of lower object position before format of footnote frame.
1846cdf0e10cSrcweir             pNew->UnlockPosOfLowerObjs();
1847cdf0e10cSrcweir             // <--
1848cdf0e10cSrcweir             pNew->Calc();
1849cdf0e10cSrcweir             // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
1850cdf0e10cSrcweir             // no extra notify for footnote frame
1851cdf0e10cSrcweir //            pNew->UnlockPosOfLowerObjs();
1852cdf0e10cSrcweir //            delete pFtnFrmNotitfy;
1853cdf0e10cSrcweir             // <--
1854cdf0e10cSrcweir             if ( !bOldFtnFrmLocked && !pNew->GetLower() &&
1855cdf0e10cSrcweir                  !pNew->IsColLocked() && !pNew->IsBackMoveLocked() )
1856cdf0e10cSrcweir             {
1857cdf0e10cSrcweir                 pNew->Cut();
1858cdf0e10cSrcweir                 delete pNew;
1859cdf0e10cSrcweir             }
1860cdf0e10cSrcweir             // <--
1861cdf0e10cSrcweir         }
1862cdf0e10cSrcweir         pMyPage->UpdateFtnNum();
1863cdf0e10cSrcweir     }
1864cdf0e10cSrcweir     else
1865cdf0e10cSrcweir         delete pNew;
1866cdf0e10cSrcweir }
1867cdf0e10cSrcweir /*************************************************************************
1868cdf0e10cSrcweir |*
1869cdf0e10cSrcweir |*  SwFtnBossFrm::FindFtn()
1870cdf0e10cSrcweir |*
1871cdf0e10cSrcweir |*************************************************************************/
1872cdf0e10cSrcweir 
1873cdf0e10cSrcweir 
FindFtn(const SwCntntFrm * pRef,const SwTxtFtn * pAttr)1874cdf0e10cSrcweir SwFtnFrm *SwFtnBossFrm::FindFtn( const SwCntntFrm *pRef, const SwTxtFtn *pAttr )
1875cdf0e10cSrcweir {
1876cdf0e10cSrcweir     //Der einfachste und sicherste Weg geht ueber das Attribut.
1877cdf0e10cSrcweir     ASSERT( pAttr->GetStartNode(), "FtnAtr ohne StartNode." );
1878cdf0e10cSrcweir     SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
1879cdf0e10cSrcweir     SwCntntNode *pNd = aIdx.GetNode().GetCntntNode();
1880cdf0e10cSrcweir     if ( !pNd )
1881cdf0e10cSrcweir         pNd = pRef->GetAttrSet()->GetDoc()->
1882cdf0e10cSrcweir               GetNodes().GoNextSection( &aIdx, sal_True, sal_False );
1883cdf0e10cSrcweir     if ( !pNd )
1884cdf0e10cSrcweir         return 0;
1885cdf0e10cSrcweir     SwIterator<SwFrm,SwCntntNode> aIter( *pNd );
1886cdf0e10cSrcweir     SwFrm* pFrm = aIter.First();
1887cdf0e10cSrcweir     if( pFrm )
1888cdf0e10cSrcweir         do
1889cdf0e10cSrcweir         {
1890cdf0e10cSrcweir                 pFrm = pFrm->GetUpper();
1891cdf0e10cSrcweir                 // #i28500#, #i27243# Due to the endnode collector, there are
1892cdf0e10cSrcweir                 // SwFtnFrms, which are not in the layout. Therefore the
1893cdf0e10cSrcweir                 // bInfFtn flags are not set correctly, and a cell of FindFtnFrm
1894cdf0e10cSrcweir                 // would return 0. Therefore we better call ImplFindFtnFrm().
1895cdf0e10cSrcweir                 SwFtnFrm *pFtn = pFrm->ImplFindFtnFrm();
1896cdf0e10cSrcweir                 if ( pFtn && pFtn->GetRef() == pRef )
1897cdf0e10cSrcweir                 {
1898cdf0e10cSrcweir                     // The following condition becomes true, if the whole
1899cdf0e10cSrcweir                     // footnotecontent is a section. While no frames exist,
1900cdf0e10cSrcweir                     // the HiddenFlag of the section is set, this causes
1901cdf0e10cSrcweir                     // the GoNextSection-function leaves the footnote.
1902cdf0e10cSrcweir                     if( pFtn->GetAttr() != pAttr )
1903cdf0e10cSrcweir                         return 0;
1904cdf0e10cSrcweir                     while ( pFtn && pFtn->GetMaster() )
1905cdf0e10cSrcweir                         pFtn = pFtn->GetMaster();
1906cdf0e10cSrcweir                     return pFtn;
1907cdf0e10cSrcweir                 }
1908cdf0e10cSrcweir 
1909cdf0e10cSrcweir         } while ( 0 != (pFrm = aIter.Next()) );
1910cdf0e10cSrcweir 
1911cdf0e10cSrcweir     return 0;
1912cdf0e10cSrcweir }
1913cdf0e10cSrcweir /*************************************************************************
1914cdf0e10cSrcweir |*
1915cdf0e10cSrcweir |*  SwFtnBossFrm::RemoveFtn()
1916cdf0e10cSrcweir |*
1917cdf0e10cSrcweir |*************************************************************************/
1918cdf0e10cSrcweir 
1919cdf0e10cSrcweir 
RemoveFtn(const SwCntntFrm * pRef,const SwTxtFtn * pAttr,sal_Bool bPrep)1920cdf0e10cSrcweir void SwFtnBossFrm::RemoveFtn( const SwCntntFrm *pRef, const SwTxtFtn *pAttr,
1921cdf0e10cSrcweir                               sal_Bool bPrep )
1922cdf0e10cSrcweir {
1923cdf0e10cSrcweir     SwFtnFrm *pFtn = FindFtn( pRef, pAttr );
1924cdf0e10cSrcweir     if( pFtn )
1925cdf0e10cSrcweir     {
1926cdf0e10cSrcweir         do
1927cdf0e10cSrcweir         {
1928cdf0e10cSrcweir             SwFtnFrm *pFoll = pFtn->GetFollow();
1929cdf0e10cSrcweir             pFtn->Cut();
1930cdf0e10cSrcweir             delete pFtn;
1931cdf0e10cSrcweir             pFtn = pFoll;
1932cdf0e10cSrcweir         } while ( pFtn );
1933cdf0e10cSrcweir         if( bPrep && pRef->IsFollow() )
1934cdf0e10cSrcweir         {
1935cdf0e10cSrcweir             ASSERT( pRef->IsTxtFrm(), "NoTxtFrm has Footnote?" );
1936cdf0e10cSrcweir             SwTxtFrm* pMaster = (SwTxtFrm*)pRef->FindMaster();
1937cdf0e10cSrcweir             if( !pMaster->IsLocked() )
1938cdf0e10cSrcweir                 pMaster->Prepare( PREP_FTN_GONE );
1939cdf0e10cSrcweir         }
1940cdf0e10cSrcweir     }
1941cdf0e10cSrcweir     FindPageFrm()->UpdateFtnNum();
1942cdf0e10cSrcweir }
1943cdf0e10cSrcweir 
1944cdf0e10cSrcweir /*************************************************************************
1945cdf0e10cSrcweir |*
1946cdf0e10cSrcweir |*  SwFtnBossFrm::ChangeFtnRef()
1947cdf0e10cSrcweir |*
1948cdf0e10cSrcweir |*************************************************************************/
1949cdf0e10cSrcweir 
1950cdf0e10cSrcweir 
ChangeFtnRef(const SwCntntFrm * pOld,const SwTxtFtn * pAttr,SwCntntFrm * pNew)1951cdf0e10cSrcweir void SwFtnBossFrm::ChangeFtnRef( const SwCntntFrm *pOld, const SwTxtFtn *pAttr,
1952cdf0e10cSrcweir                                  SwCntntFrm *pNew )
1953cdf0e10cSrcweir {
1954cdf0e10cSrcweir     SwFtnFrm *pFtn = FindFtn( pOld, pAttr );
1955cdf0e10cSrcweir     while ( pFtn )
1956cdf0e10cSrcweir     {
1957cdf0e10cSrcweir         pFtn->SetRef( pNew );
1958cdf0e10cSrcweir         pFtn = pFtn->GetFollow();
1959cdf0e10cSrcweir     }
1960cdf0e10cSrcweir }
1961cdf0e10cSrcweir 
1962cdf0e10cSrcweir /*************************************************************************
1963cdf0e10cSrcweir |*
1964cdf0e10cSrcweir |*  SwFtnBossFrm::CollectFtns()
1965cdf0e10cSrcweir |*
1966cdf0e10cSrcweir |*************************************************************************/
1967cdf0e10cSrcweir 
1968cdf0e10cSrcweir 
1969cdf0e10cSrcweir /// OD 03.04.2003 #108446# - add parameter <_bCollectOnlyPreviousFtns> in
1970cdf0e10cSrcweir /// order to control, if only footnotes, which are positioned before the
1971cdf0e10cSrcweir /// footnote boss frame <this> have to be collected.
CollectFtns(const SwCntntFrm * _pRef,SwFtnBossFrm * _pOld,SvPtrarr & _rFtnArr,const sal_Bool _bCollectOnlyPreviousFtns)1972cdf0e10cSrcweir void SwFtnBossFrm::CollectFtns( const SwCntntFrm* _pRef,
1973cdf0e10cSrcweir                                 SwFtnBossFrm*     _pOld,
1974cdf0e10cSrcweir                                 SvPtrarr&         _rFtnArr,
1975cdf0e10cSrcweir                                 const sal_Bool    _bCollectOnlyPreviousFtns )
1976cdf0e10cSrcweir {
1977cdf0e10cSrcweir     SwFtnFrm *pFtn = _pOld->FindFirstFtn();
1978cdf0e10cSrcweir     while( !pFtn )
1979cdf0e10cSrcweir     {
1980cdf0e10cSrcweir         if( _pOld->IsColumnFrm() )
1981cdf0e10cSrcweir         {   // Spalten abklappern
1982cdf0e10cSrcweir             while ( !pFtn && _pOld->GetPrev() )
1983cdf0e10cSrcweir             {
1984cdf0e10cSrcweir                 //Wenn wir keine Fussnote gefunden haben, ist noch nicht alles zu
1985cdf0e10cSrcweir                 //spaet. Die Schleife wird beim Aufnehmen von Follow-Zeilen durch
1986cdf0e10cSrcweir                 //Tabellen benoetigt. Fuer alle anderen Faelle ist sie in der Lage
1987cdf0e10cSrcweir                 //'krumme' Verhaeltnisse zu korrigieren.
1988cdf0e10cSrcweir                 _pOld = (SwFtnBossFrm*)_pOld->GetPrev();
1989cdf0e10cSrcweir                 pFtn = _pOld->FindFirstFtn();
1990cdf0e10cSrcweir             }
1991cdf0e10cSrcweir         }
1992cdf0e10cSrcweir         if( !pFtn )
1993cdf0e10cSrcweir         {
1994cdf0e10cSrcweir             //  vorherige Seite
1995cdf0e10cSrcweir             SwPageFrm* pPg;
1996cdf0e10cSrcweir             for ( SwFrm* pTmp = _pOld;
1997cdf0e10cSrcweir                   0 != ( pPg = (SwPageFrm*)pTmp->FindPageFrm()->GetPrev())
1998cdf0e10cSrcweir                     && pPg->IsEmptyPage() ;
1999cdf0e10cSrcweir                 )
2000cdf0e10cSrcweir             {
2001cdf0e10cSrcweir                 pTmp = pPg;
2002cdf0e10cSrcweir             }
2003cdf0e10cSrcweir             if( !pPg )
2004cdf0e10cSrcweir                 return;
2005cdf0e10cSrcweir 
2006cdf0e10cSrcweir             SwLayoutFrm* pBody = pPg->FindBodyCont();
2007cdf0e10cSrcweir             if( pBody->Lower() && pBody->Lower()->IsColumnFrm() )
2008cdf0e10cSrcweir             {
2009cdf0e10cSrcweir                 // mehrspaltige Seite => letzte Spalte suchen
2010cdf0e10cSrcweir                 _pOld = static_cast<SwFtnBossFrm*>(pBody->GetLastLower());
2011cdf0e10cSrcweir             }
2012cdf0e10cSrcweir             else
2013cdf0e10cSrcweir                 _pOld = pPg; // einspaltige Seite
2014cdf0e10cSrcweir             pFtn = _pOld->FindFirstFtn();
2015cdf0e10cSrcweir         }
2016cdf0e10cSrcweir     }
2017cdf0e10cSrcweir     // OD 03.04.2003 #108446# - consider new parameter <_bCollectOnlyPreviousFtns>
2018cdf0e10cSrcweir     SwFtnBossFrm* pRefBossFrm = NULL;
2019cdf0e10cSrcweir     if ( _bCollectOnlyPreviousFtns )
2020cdf0e10cSrcweir     {
2021cdf0e10cSrcweir         pRefBossFrm = this;
2022cdf0e10cSrcweir     }
2023cdf0e10cSrcweir     _CollectFtns( _pRef, pFtn, _rFtnArr, _bCollectOnlyPreviousFtns, pRefBossFrm );
2024cdf0e10cSrcweir }
2025cdf0e10cSrcweir 
2026cdf0e10cSrcweir 
2027cdf0e10cSrcweir /*************************************************************************
2028cdf0e10cSrcweir |*
2029cdf0e10cSrcweir |*  SwFtnBossFrm::_CollectFtns()
2030cdf0e10cSrcweir |*
2031cdf0e10cSrcweir |*************************************************************************/
FtnInArr(SvPtrarr & rFtnArr,SwFtnFrm * pFtn)2032cdf0e10cSrcweir inline void FtnInArr( SvPtrarr& rFtnArr, SwFtnFrm* pFtn )
2033cdf0e10cSrcweir {
2034cdf0e10cSrcweir     if ( USHRT_MAX == rFtnArr.GetPos( (VoidPtr)pFtn ) )
2035cdf0e10cSrcweir         rFtnArr.Insert( (VoidPtr)pFtn, rFtnArr.Count() );
2036cdf0e10cSrcweir }
2037cdf0e10cSrcweir 
2038cdf0e10cSrcweir /// OD 03.04.2003 #108446# - add parameters <_bCollectOnlyPreviousFtns> and
2039cdf0e10cSrcweir /// <_pRefFtnBossFrm> in order to control, if only footnotes, which are positioned
2040cdf0e10cSrcweir /// before the given reference footnote boss frame have to be collected.
2041cdf0e10cSrcweir /// Note: if parameter <_bCollectOnlyPreviousFtns> is true, then parameter
2042cdf0e10cSrcweir /// <_pRefFtnBossFrm> have to be referenced to an object.
2043cdf0e10cSrcweir /// Adjust parameter names.
_CollectFtns(const SwCntntFrm * _pRef,SwFtnFrm * _pFtn,SvPtrarr & _rFtnArr,sal_Bool _bCollectOnlyPreviousFtns,const SwFtnBossFrm * _pRefFtnBossFrm)2044cdf0e10cSrcweir void SwFtnBossFrm::_CollectFtns( const SwCntntFrm*   _pRef,
2045cdf0e10cSrcweir                                  SwFtnFrm*           _pFtn,
2046cdf0e10cSrcweir                                  SvPtrarr&           _rFtnArr,
2047cdf0e10cSrcweir                                  sal_Bool            _bCollectOnlyPreviousFtns,
2048cdf0e10cSrcweir                                  const SwFtnBossFrm* _pRefFtnBossFrm)
2049cdf0e10cSrcweir {
2050cdf0e10cSrcweir     // OD 03.04.2003 #108446# - assert, that no reference footnote boss frame
2051cdf0e10cSrcweir     // is set, in spite of the order, that only previous footnotes has to be
2052cdf0e10cSrcweir     // collected.
2053cdf0e10cSrcweir     ASSERT( !_bCollectOnlyPreviousFtns || _pRefFtnBossFrm,
2054cdf0e10cSrcweir             "<SwFtnBossFrm::_CollectFtns(..)> - No reference footnote boss frame for collecting only previous footnotes set.\nCrash will be caused!" );
2055cdf0e10cSrcweir 
2056cdf0e10cSrcweir     //Alle Fussnoten die von pRef referenziert werden nacheinander
2057cdf0e10cSrcweir     //einsammeln (Attribut fuer Attribut), zusammengefuegen
2058cdf0e10cSrcweir     //(der Inhalt zu einem Attribut kann ueber mehrere Seiten verteilt sein)
2059cdf0e10cSrcweir     //und ausschneiden.
2060cdf0e10cSrcweir 
2061cdf0e10cSrcweir     SvPtrarr aNotFtnArr( 20, 20 );  //Zur Robustheit werden hier die nicht
2062cdf0e10cSrcweir                                     //dazugehoerigen Fussnoten eingetragen.
2063cdf0e10cSrcweir                                     //Wenn eine Fussnote zweimal angefasst wird
2064cdf0e10cSrcweir                                     //ists vorbei! So kommt die Funktion auch
2065cdf0e10cSrcweir                                     //noch mit einem kaputten Layout
2066cdf0e10cSrcweir                                     //einigermassen (ohne Schleife und Absturz)
2067cdf0e10cSrcweir                                     //"klar".
2068cdf0e10cSrcweir 
2069cdf0e10cSrcweir     //Hier sollte keiner mit einer Follow-Ftn ankommen, es sei denn er hat
2070cdf0e10cSrcweir     //ernste Absichten (:-)); spricht er kommt mit einer Ftn an die vor der
2071cdf0e10cSrcweir     //ersten der Referenz liegt.
2072cdf0e10cSrcweir     ASSERT( !_pFtn->GetMaster() || _pFtn->GetRef() != _pRef, "FollowFtn moven?" );
2073cdf0e10cSrcweir     while ( _pFtn->GetMaster() )
2074cdf0e10cSrcweir         _pFtn = _pFtn->GetMaster();
2075cdf0e10cSrcweir 
2076cdf0e10cSrcweir     sal_Bool bFound = sal_False;
2077cdf0e10cSrcweir 
2078cdf0e10cSrcweir     while ( _pFtn )
2079cdf0e10cSrcweir     {
2080cdf0e10cSrcweir         //Erstmal die naechste Fussnote der Spalte/Seite suchen, damit wir nicht
2081cdf0e10cSrcweir         //nach dem Cut jeder Fussnote von vorn anfangen muessen.
2082cdf0e10cSrcweir         SwFtnFrm *pNxtFtn = _pFtn;
2083cdf0e10cSrcweir         while ( pNxtFtn->GetFollow() )
2084cdf0e10cSrcweir             pNxtFtn = pNxtFtn->GetFollow();
2085cdf0e10cSrcweir         pNxtFtn = (SwFtnFrm*)pNxtFtn->GetNext();
2086cdf0e10cSrcweir 
2087cdf0e10cSrcweir         if ( !pNxtFtn )
2088cdf0e10cSrcweir         {
2089cdf0e10cSrcweir             SwFtnBossFrm* pBoss = _pFtn->FindFtnBossFrm();
2090cdf0e10cSrcweir             SwPageFrm* pPage = pBoss->FindPageFrm();
2091cdf0e10cSrcweir             do
2092cdf0e10cSrcweir             {
2093cdf0e10cSrcweir                 lcl_NextFtnBoss( pBoss, pPage, sal_False );
2094cdf0e10cSrcweir                 if( pBoss )
2095cdf0e10cSrcweir                 {
2096cdf0e10cSrcweir                     SwLayoutFrm* pCont = pBoss->FindFtnCont();
2097cdf0e10cSrcweir                     if( pCont )
2098cdf0e10cSrcweir                     {
2099cdf0e10cSrcweir                         pNxtFtn = (SwFtnFrm*)pCont->Lower();
2100cdf0e10cSrcweir                         if( pNxtFtn )
2101cdf0e10cSrcweir                         {
2102cdf0e10cSrcweir                             while( pNxtFtn->GetMaster() )
2103cdf0e10cSrcweir                                 pNxtFtn = pNxtFtn->GetMaster();
2104cdf0e10cSrcweir                             if( pNxtFtn == _pFtn )
2105cdf0e10cSrcweir                                 pNxtFtn = NULL;
2106cdf0e10cSrcweir                         }
2107cdf0e10cSrcweir                     }
2108cdf0e10cSrcweir                 }
2109cdf0e10cSrcweir             } while( !pNxtFtn && pBoss );
2110cdf0e10cSrcweir         }
2111cdf0e10cSrcweir         else if( !pNxtFtn->GetAttr()->GetFtn().IsEndNote() )
2112*7de601c3SJohn Bampton         {   ASSERT( !pNxtFtn->GetMaster(), "_CollectFtn: Master expected" );
2113cdf0e10cSrcweir             while ( pNxtFtn->GetMaster() )
2114cdf0e10cSrcweir                 pNxtFtn = pNxtFtn->GetMaster();
2115cdf0e10cSrcweir         }
2116cdf0e10cSrcweir         if ( pNxtFtn == _pFtn )
2117cdf0e10cSrcweir         {
2118cdf0e10cSrcweir             ASSERT( sal_False, "_CollectFtn: Devil's circle" );
2119cdf0e10cSrcweir             pNxtFtn = 0;
2120cdf0e10cSrcweir         }
2121cdf0e10cSrcweir 
2122cdf0e10cSrcweir         // OD 03.04.2003 #108446# - determine, if found footnote has to be collected.
2123cdf0e10cSrcweir         sal_Bool bCollectFoundFtn = sal_False;
2124cdf0e10cSrcweir         if ( _pFtn->GetRef() == _pRef && !_pFtn->GetAttr()->GetFtn().IsEndNote() )
2125cdf0e10cSrcweir         {
2126cdf0e10cSrcweir             if ( _bCollectOnlyPreviousFtns )
2127cdf0e10cSrcweir             {
2128cdf0e10cSrcweir                 SwFtnBossFrm* pBossOfFoundFtn = _pFtn->FindFtnBossFrm( sal_True );
2129cdf0e10cSrcweir                 ASSERT( pBossOfFoundFtn,
2130cdf0e10cSrcweir                         "<SwFtnBossFrm::_CollectFtns(..)> - footnote boss frame of found footnote frame missing.\nWrong layout!" );
2131cdf0e10cSrcweir                 if ( !pBossOfFoundFtn ||    // don't crash, if no footnote boss is found.
2132cdf0e10cSrcweir                      pBossOfFoundFtn->IsBefore( _pRefFtnBossFrm )
2133cdf0e10cSrcweir                    )
2134cdf0e10cSrcweir                 {
2135cdf0e10cSrcweir                     bCollectFoundFtn = sal_True;
2136cdf0e10cSrcweir                 }
2137cdf0e10cSrcweir             }
2138cdf0e10cSrcweir             else
2139cdf0e10cSrcweir             {
2140cdf0e10cSrcweir                 bCollectFoundFtn = sal_True;
2141cdf0e10cSrcweir             }
2142cdf0e10cSrcweir         }
2143cdf0e10cSrcweir 
2144cdf0e10cSrcweir         if ( bCollectFoundFtn )
2145cdf0e10cSrcweir         {
2146cdf0e10cSrcweir             ASSERT( !_pFtn->GetMaster(), "FollowFtn moven?" );
2147cdf0e10cSrcweir             SwFtnFrm *pNxt = _pFtn->GetFollow();
2148cdf0e10cSrcweir             while ( pNxt )
2149cdf0e10cSrcweir             {
2150cdf0e10cSrcweir                 SwFrm *pCnt = pNxt->ContainsAny();
2151cdf0e10cSrcweir                 if ( pCnt )
2152cdf0e10cSrcweir                 {   //Unterwegs wird der Follow zerstoert weil er leer wird!
2153cdf0e10cSrcweir                     do
2154cdf0e10cSrcweir                     {   SwFrm *pNxtCnt = pCnt->GetNext();
2155cdf0e10cSrcweir                         pCnt->Cut();
2156cdf0e10cSrcweir                         pCnt->Paste( _pFtn );
2157cdf0e10cSrcweir                         pCnt = pNxtCnt;
2158cdf0e10cSrcweir                     } while ( pCnt );
2159cdf0e10cSrcweir                 }
2160cdf0e10cSrcweir                 else
2161cdf0e10cSrcweir                 {   ASSERT( !pNxt, "Fussnote ohne Inhalt?" );
2162cdf0e10cSrcweir                     pNxt->Cut();
2163cdf0e10cSrcweir                     delete pNxt;
2164cdf0e10cSrcweir                 }
2165cdf0e10cSrcweir                 pNxt = _pFtn->GetFollow();
2166cdf0e10cSrcweir             }
2167cdf0e10cSrcweir             _pFtn->Cut();
2168cdf0e10cSrcweir             FtnInArr( _rFtnArr, _pFtn );
2169cdf0e10cSrcweir             bFound = sal_True;
2170cdf0e10cSrcweir         }
2171cdf0e10cSrcweir         else
2172cdf0e10cSrcweir         {
2173cdf0e10cSrcweir             FtnInArr( aNotFtnArr, _pFtn );
2174cdf0e10cSrcweir             if( bFound )
2175cdf0e10cSrcweir                 break;
2176cdf0e10cSrcweir         }
2177cdf0e10cSrcweir         if ( pNxtFtn &&
2178cdf0e10cSrcweir              USHRT_MAX == _rFtnArr.GetPos( (VoidPtr)pNxtFtn ) &&
2179cdf0e10cSrcweir              USHRT_MAX == aNotFtnArr.GetPos( (VoidPtr)pNxtFtn ) )
2180cdf0e10cSrcweir             _pFtn = pNxtFtn;
2181cdf0e10cSrcweir         else
2182cdf0e10cSrcweir             break;
2183cdf0e10cSrcweir     }
2184cdf0e10cSrcweir }
2185cdf0e10cSrcweir 
2186cdf0e10cSrcweir /*************************************************************************
2187cdf0e10cSrcweir |*
2188cdf0e10cSrcweir |*  SwFtnBossFrm::_MoveFtns()
2189cdf0e10cSrcweir |*
2190cdf0e10cSrcweir |*************************************************************************/
2191cdf0e10cSrcweir 
2192cdf0e10cSrcweir 
_MoveFtns(SvPtrarr & rFtnArr,sal_Bool bCalc)2193cdf0e10cSrcweir void SwFtnBossFrm::_MoveFtns( SvPtrarr &rFtnArr, sal_Bool bCalc )
2194cdf0e10cSrcweir {
2195cdf0e10cSrcweir     //Alle Fussnoten die von pRef referenziert werden muessen von der
2196cdf0e10cSrcweir     //aktuellen Position, die sich durch die alte Spalte/Seite ergab, auf eine
2197cdf0e10cSrcweir     //neue Position, bestimmt durch die neue Spalte/Seite, gemoved werden.
2198cdf0e10cSrcweir     const sal_uInt16 nMyNum = FindPageFrm()->GetPhyPageNum();
2199cdf0e10cSrcweir     const sal_uInt16 nMyCol = lcl_ColumnNum( this );
2200cdf0e10cSrcweir     SWRECTFN( this )
2201cdf0e10cSrcweir 
2202cdf0e10cSrcweir     // --> OD 2004-06-11 #i21478# - keep last inserted footnote in order to
2203cdf0e10cSrcweir     // format the content of the following one.
2204cdf0e10cSrcweir     SwFtnFrm* pLastInsertedFtn = 0L;
2205cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rFtnArr.Count(); ++i )
2206cdf0e10cSrcweir     {
2207cdf0e10cSrcweir         SwFtnFrm *pFtn = (SwFtnFrm*)rFtnArr[i];
2208cdf0e10cSrcweir 
2209cdf0e10cSrcweir         SwFtnBossFrm* pRefBoss = pFtn->GetRef()->FindFtnBossFrm( sal_True );
2210cdf0e10cSrcweir         if( pRefBoss != this )
2211cdf0e10cSrcweir         {
2212cdf0e10cSrcweir             const sal_uInt16 nRefNum = pRefBoss->FindPageFrm()->GetPhyPageNum();
2213cdf0e10cSrcweir             const sal_uInt16 nRefCol = lcl_ColumnNum( this );
2214cdf0e10cSrcweir             if( nRefNum < nMyNum || ( nRefNum == nMyNum && nRefCol <= nMyCol ) )
2215cdf0e10cSrcweir                 pRefBoss = this;
2216cdf0e10cSrcweir         }
2217cdf0e10cSrcweir         pRefBoss->InsertFtn( pFtn );
2218cdf0e10cSrcweir 
2219cdf0e10cSrcweir         if ( pFtn->GetUpper() ) //Robust, z.B. bei doppelten
2220cdf0e10cSrcweir         {
2221cdf0e10cSrcweir             // Damit FtnFrms, die nicht auf die Seite passen, nicht fuer zuviel
2222cdf0e10cSrcweir             // Unruhe sorgen (Loop 66312), wird ihr Inhalt zunaechst zusammengestaucht.
2223cdf0e10cSrcweir             // Damit wird der FtnCont erst gegrowt, wenn der Inhalt formatiert wird
2224cdf0e10cSrcweir             // und feststellt, dass er auf die Seite passt.
2225cdf0e10cSrcweir             SwFrm *pCnt = pFtn->ContainsAny();
2226cdf0e10cSrcweir             while( pCnt )
2227cdf0e10cSrcweir             {
2228cdf0e10cSrcweir                 if( pCnt->IsLayoutFrm() )
2229cdf0e10cSrcweir                 {
2230cdf0e10cSrcweir                     SwFrm* pTmp = ((SwLayoutFrm*)pCnt)->ContainsAny();
2231cdf0e10cSrcweir                     while( pTmp && ((SwLayoutFrm*)pCnt)->IsAnLower( pTmp ) )
2232cdf0e10cSrcweir                     {
2233cdf0e10cSrcweir                         pTmp->Prepare( PREP_MOVEFTN );
2234cdf0e10cSrcweir                         (pTmp->Frm().*fnRect->fnSetHeight)(0);
2235cdf0e10cSrcweir                         (pTmp->Prt().*fnRect->fnSetHeight)(0);
2236cdf0e10cSrcweir                         pTmp = pTmp->FindNext();
2237cdf0e10cSrcweir                     }
2238cdf0e10cSrcweir                 }
2239cdf0e10cSrcweir                 else
2240cdf0e10cSrcweir                     pCnt->Prepare( PREP_MOVEFTN );
2241cdf0e10cSrcweir                 (pCnt->Frm().*fnRect->fnSetHeight)(0);
2242cdf0e10cSrcweir                 (pCnt->Prt().*fnRect->fnSetHeight)(0);
2243cdf0e10cSrcweir                 pCnt = pCnt->GetNext();
2244cdf0e10cSrcweir             }
2245cdf0e10cSrcweir             (pFtn->Frm().*fnRect->fnSetHeight)(0);
2246cdf0e10cSrcweir             (pFtn->Prt().*fnRect->fnSetHeight)(0);
2247cdf0e10cSrcweir             pFtn->Calc();
2248cdf0e10cSrcweir             pFtn->GetUpper()->Calc();
2249cdf0e10cSrcweir 
2250cdf0e10cSrcweir             if( bCalc )
2251cdf0e10cSrcweir             {
2252cdf0e10cSrcweir                 SwTxtFtn *pAttr = pFtn->GetAttr();
2253cdf0e10cSrcweir                 pCnt = pFtn->ContainsAny();
2254cdf0e10cSrcweir                 sal_Bool bUnlock = !pFtn->IsBackMoveLocked();
2255cdf0e10cSrcweir                 pFtn->LockBackMove();
2256cdf0e10cSrcweir 
2257cdf0e10cSrcweir                 // --> OD 2005-05-18 #i49383# - disable unlock of position of
2258cdf0e10cSrcweir                 // lower objects during format of footnote content.
2259cdf0e10cSrcweir                 pFtn->KeepLockPosOfLowerObjs();
2260cdf0e10cSrcweir                 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2261cdf0e10cSrcweir                 // no extra notify for footnote frame
2262cdf0e10cSrcweir //                SwLayNotify aFtnFrmNotitfy( pFtn );
2263cdf0e10cSrcweir                 // <--
2264cdf0e10cSrcweir 
2265cdf0e10cSrcweir                 while ( pCnt && pCnt->FindFtnFrm()->GetAttr() == pAttr )
2266cdf0e10cSrcweir                 {
2267cdf0e10cSrcweir                     pCnt->_InvalidatePos();
2268cdf0e10cSrcweir                     pCnt->Calc();
2269cdf0e10cSrcweir                     // --> OD 2005-05-17 #i49383# - format anchored objects
2270cdf0e10cSrcweir                     if ( pCnt->IsTxtFrm() && pCnt->IsValid() )
2271cdf0e10cSrcweir                     {
2272cdf0e10cSrcweir                         if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
2273cdf0e10cSrcweir                                                                   *(pCnt->FindPageFrm()) ) )
2274cdf0e10cSrcweir                         {
2275cdf0e10cSrcweir                             // restart format with first content
2276cdf0e10cSrcweir                             pCnt = pFtn->ContainsAny();
2277cdf0e10cSrcweir                             continue;
2278cdf0e10cSrcweir                         }
2279cdf0e10cSrcweir                     }
2280cdf0e10cSrcweir                     // <--
2281cdf0e10cSrcweir                     if( pCnt->IsSctFrm() )
2282cdf0e10cSrcweir                     {   // Wenn es sich um einen nichtleeren Bereich handelt,
2283cdf0e10cSrcweir                         // iterieren wir auch ueber seinen Inhalt
2284cdf0e10cSrcweir                         SwFrm* pTmp = ((SwSectionFrm*)pCnt)->ContainsAny();
2285cdf0e10cSrcweir                         if( pTmp )
2286cdf0e10cSrcweir                             pCnt = pTmp;
2287cdf0e10cSrcweir                         else
2288cdf0e10cSrcweir                             pCnt = pCnt->FindNext();
2289cdf0e10cSrcweir                     }
2290cdf0e10cSrcweir                     else
2291cdf0e10cSrcweir                         pCnt = pCnt->FindNext();
2292cdf0e10cSrcweir                 }
2293cdf0e10cSrcweir                 if( bUnlock )
2294cdf0e10cSrcweir                 {
2295cdf0e10cSrcweir                     pFtn->UnlockBackMove();
2296cdf0e10cSrcweir                     if( !pFtn->ContainsAny() && !pFtn->IsColLocked() )
2297cdf0e10cSrcweir                     {
2298cdf0e10cSrcweir                         pFtn->Cut();
2299cdf0e10cSrcweir                         delete pFtn;
2300cdf0e10cSrcweir                         // --> OD 2004-06-10 #i21478#
2301cdf0e10cSrcweir                         pFtn = 0L;
2302cdf0e10cSrcweir                     }
2303cdf0e10cSrcweir                 }
2304cdf0e10cSrcweir                 // --> OD 2005-05-18 #i49383#
2305cdf0e10cSrcweir                 if ( pFtn )
2306cdf0e10cSrcweir                 {
2307cdf0e10cSrcweir                     // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2308cdf0e10cSrcweir                     // enable lock of lower object position before format of footnote frame.
2309cdf0e10cSrcweir                     pFtn->UnlockPosOfLowerObjs();
2310cdf0e10cSrcweir                     pFtn->Calc();
2311cdf0e10cSrcweir //                    pFtn->UnlockPosOfLowerObjs();
2312cdf0e10cSrcweir                     // <--
2313cdf0e10cSrcweir                 }
2314cdf0e10cSrcweir                 // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2315cdf0e10cSrcweir                 // no extra notify for footnote frame
2316cdf0e10cSrcweir //                else
2317cdf0e10cSrcweir //                {
2318cdf0e10cSrcweir //                    aFtnFrmNotitfy.FrmDeleted();
2319cdf0e10cSrcweir //                }
2320cdf0e10cSrcweir                 // <--
2321cdf0e10cSrcweir             }
2322cdf0e10cSrcweir         }
2323cdf0e10cSrcweir         else
2324cdf0e10cSrcweir         {   ASSERT( !pFtn->GetMaster() && !pFtn->GetFollow(),
2325cdf0e10cSrcweir                     "DelFtn und Master/Follow?" );
2326cdf0e10cSrcweir             delete pFtn;
2327cdf0e10cSrcweir             // --> OD 2004-06-10 #i21478#
2328cdf0e10cSrcweir             pFtn = 0L;
2329cdf0e10cSrcweir         }
2330cdf0e10cSrcweir 
2331cdf0e10cSrcweir         // --> OD 2004-06-10 #i21478#
2332cdf0e10cSrcweir         if ( pFtn )
2333cdf0e10cSrcweir         {
2334cdf0e10cSrcweir             pLastInsertedFtn = pFtn;
2335cdf0e10cSrcweir         }
2336cdf0e10cSrcweir     }
2337cdf0e10cSrcweir 
2338cdf0e10cSrcweir     // --> OD 2004-06-10 #i21478# - format content of footnote following
2339cdf0e10cSrcweir     // the new inserted ones.
2340cdf0e10cSrcweir     if ( bCalc && pLastInsertedFtn )
2341cdf0e10cSrcweir     {
2342cdf0e10cSrcweir         if ( pLastInsertedFtn->GetNext() )
2343cdf0e10cSrcweir         {
2344cdf0e10cSrcweir             SwFtnFrm* pNextFtn = static_cast<SwFtnFrm*>(pLastInsertedFtn->GetNext());
2345cdf0e10cSrcweir             SwTxtFtn* pAttr = pNextFtn->GetAttr();
2346cdf0e10cSrcweir             SwFrm* pCnt = pNextFtn->ContainsAny();
2347cdf0e10cSrcweir 
2348cdf0e10cSrcweir             sal_Bool bUnlock = !pNextFtn->IsBackMoveLocked();
2349cdf0e10cSrcweir             pNextFtn->LockBackMove();
2350cdf0e10cSrcweir             // --> OD 2005-05-18 #i49383# - disable unlock of position of
2351cdf0e10cSrcweir             // lower objects during format of footnote content.
2352cdf0e10cSrcweir             pNextFtn->KeepLockPosOfLowerObjs();
2353cdf0e10cSrcweir             // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2354cdf0e10cSrcweir             // no extra notify for footnote frame
2355cdf0e10cSrcweir //            SwLayNotify aFtnFrmNotitfy( pNextFtn );
2356cdf0e10cSrcweir             // <--
2357cdf0e10cSrcweir 
2358cdf0e10cSrcweir             while ( pCnt && pCnt->FindFtnFrm()->GetAttr() == pAttr )
2359cdf0e10cSrcweir             {
2360cdf0e10cSrcweir                 pCnt->_InvalidatePos();
2361cdf0e10cSrcweir                 pCnt->Calc();
2362cdf0e10cSrcweir                 // --> OD 2005-05-17 #i49383# - format anchored objects
2363cdf0e10cSrcweir                 if ( pCnt->IsTxtFrm() && pCnt->IsValid() )
2364cdf0e10cSrcweir                 {
2365cdf0e10cSrcweir                     if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
2366cdf0e10cSrcweir                                                               *(pCnt->FindPageFrm()) ) )
2367cdf0e10cSrcweir                     {
2368cdf0e10cSrcweir                         // restart format with first content
2369cdf0e10cSrcweir                         pCnt = pNextFtn->ContainsAny();
2370cdf0e10cSrcweir                         continue;
2371cdf0e10cSrcweir                     }
2372cdf0e10cSrcweir                 }
2373cdf0e10cSrcweir                 // <--
2374cdf0e10cSrcweir                 if( pCnt->IsSctFrm() )
2375cdf0e10cSrcweir                 {   // Wenn es sich um einen nichtleeren Bereich handelt,
2376cdf0e10cSrcweir                     // iterieren wir auch ueber seinen Inhalt
2377cdf0e10cSrcweir                     SwFrm* pTmp = ((SwSectionFrm*)pCnt)->ContainsAny();
2378cdf0e10cSrcweir                     if( pTmp )
2379cdf0e10cSrcweir                         pCnt = pTmp;
2380cdf0e10cSrcweir                     else
2381cdf0e10cSrcweir                         pCnt = pCnt->FindNext();
2382cdf0e10cSrcweir                 }
2383cdf0e10cSrcweir                 else
2384cdf0e10cSrcweir                     pCnt = pCnt->FindNext();
2385cdf0e10cSrcweir             }
2386cdf0e10cSrcweir             if( bUnlock )
2387cdf0e10cSrcweir             {
2388cdf0e10cSrcweir                 pNextFtn->UnlockBackMove();
2389cdf0e10cSrcweir             }
2390cdf0e10cSrcweir             // --> OD 2005-05-18 #i49383#
2391cdf0e10cSrcweir             // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2392cdf0e10cSrcweir             // enable lock of lower object position before format of footnote frame.
2393cdf0e10cSrcweir             pNextFtn->UnlockPosOfLowerObjs();
2394cdf0e10cSrcweir             pNextFtn->Calc();
2395cdf0e10cSrcweir //            pNextFtn->UnlockPosOfLowerObjs();
2396cdf0e10cSrcweir             // <--
2397cdf0e10cSrcweir         }
2398cdf0e10cSrcweir     }
2399cdf0e10cSrcweir }
2400cdf0e10cSrcweir 
2401cdf0e10cSrcweir /*************************************************************************
2402cdf0e10cSrcweir |*
2403cdf0e10cSrcweir |*  SwFtnBossFrm::MoveFtns()
2404cdf0e10cSrcweir |*
2405cdf0e10cSrcweir |*************************************************************************/
2406cdf0e10cSrcweir 
2407cdf0e10cSrcweir 
MoveFtns(const SwCntntFrm * pSrc,SwCntntFrm * pDest,SwTxtFtn * pAttr)2408cdf0e10cSrcweir void SwFtnBossFrm::MoveFtns( const SwCntntFrm *pSrc, SwCntntFrm *pDest,
2409cdf0e10cSrcweir                              SwTxtFtn *pAttr )
2410cdf0e10cSrcweir {
2411cdf0e10cSrcweir     if( ( GetFmt()->GetDoc()->GetFtnInfo().ePos == FTNPOS_CHAPTER &&
2412cdf0e10cSrcweir         (!GetUpper()->IsSctFrm() || !((SwSectionFrm*)GetUpper())->IsFtnAtEnd()))
2413cdf0e10cSrcweir         || pAttr->GetFtn().IsEndNote() )
2414cdf0e10cSrcweir         return;
2415cdf0e10cSrcweir 
2416cdf0e10cSrcweir     ASSERT( this == pSrc->FindFtnBossFrm( sal_True ),
2417cdf0e10cSrcweir             "SwPageFrm::MoveFtns: source frame isn't on that FtnBoss" );
2418cdf0e10cSrcweir 
2419cdf0e10cSrcweir     SwFtnFrm *pFtn = FindFirstFtn();
2420cdf0e10cSrcweir     if( pFtn )
2421cdf0e10cSrcweir     {
2422cdf0e10cSrcweir         ChangeFtnRef( pSrc, pAttr, pDest );
2423cdf0e10cSrcweir         SwFtnBossFrm *pDestBoss = pDest->FindFtnBossFrm( sal_True );
2424cdf0e10cSrcweir         ASSERT( pDestBoss, "+SwPageFrm::MoveFtns: no destination boss" );
2425cdf0e10cSrcweir         if( pDestBoss )     // robust
2426cdf0e10cSrcweir         {
2427cdf0e10cSrcweir             SvPtrarr aFtnArr( 5, 5 );
2428cdf0e10cSrcweir             pDestBoss->_CollectFtns( pDest, pFtn, aFtnArr );
2429cdf0e10cSrcweir             if ( aFtnArr.Count() )
2430cdf0e10cSrcweir             {
2431cdf0e10cSrcweir                 pDestBoss->_MoveFtns( aFtnArr, sal_True );
2432cdf0e10cSrcweir                 SwPageFrm* pSrcPage = FindPageFrm();
2433cdf0e10cSrcweir                 SwPageFrm* pDestPage = pDestBoss->FindPageFrm();
2434cdf0e10cSrcweir                 // Nur beim Seitenwechsel FtnNum Updaten
2435cdf0e10cSrcweir                 if( pSrcPage != pDestPage )
2436cdf0e10cSrcweir                 {
2437cdf0e10cSrcweir                     if( pSrcPage->GetPhyPageNum() > pDestPage->GetPhyPageNum() )
2438cdf0e10cSrcweir                         pSrcPage->UpdateFtnNum();
2439cdf0e10cSrcweir                     pDestPage->UpdateFtnNum();
2440cdf0e10cSrcweir                 }
2441cdf0e10cSrcweir             }
2442cdf0e10cSrcweir         }
2443cdf0e10cSrcweir     }
2444cdf0e10cSrcweir }
2445cdf0e10cSrcweir 
2446cdf0e10cSrcweir /*************************************************************************
2447cdf0e10cSrcweir |*
2448cdf0e10cSrcweir |*  SwFtnBossFrm::RearrangeFtns()
2449cdf0e10cSrcweir |*
2450cdf0e10cSrcweir |*************************************************************************/
2451cdf0e10cSrcweir 
2452cdf0e10cSrcweir 
RearrangeFtns(const SwTwips nDeadLine,const sal_Bool bLock,const SwTxtFtn * pAttr)2453cdf0e10cSrcweir void SwFtnBossFrm::RearrangeFtns( const SwTwips nDeadLine, const sal_Bool bLock,
2454cdf0e10cSrcweir                                   const SwTxtFtn *pAttr )
2455cdf0e10cSrcweir {
2456cdf0e10cSrcweir     //Alle Fussnoten der Spalte/Seite dergestalt anformatieren,
2457cdf0e10cSrcweir     //dass sie ggf. die Spalte/Seite wechseln.
2458cdf0e10cSrcweir 
2459cdf0e10cSrcweir     SwSaveFtnHeight aSave( this, nDeadLine );
2460cdf0e10cSrcweir     SwFtnFrm *pFtn = FindFirstFtn();
2461cdf0e10cSrcweir     if( pFtn && pFtn->GetPrev() && bLock )
2462cdf0e10cSrcweir     {
2463cdf0e10cSrcweir         SwFtnFrm* pFirst = (SwFtnFrm*)pFtn->GetUpper()->Lower();
2464cdf0e10cSrcweir         SwFrm* pCntnt = pFirst->ContainsAny();
2465cdf0e10cSrcweir         if( pCntnt )
2466cdf0e10cSrcweir         {
2467cdf0e10cSrcweir             sal_Bool bUnlock = !pFirst->IsBackMoveLocked();
2468cdf0e10cSrcweir             pFirst->LockBackMove();
2469cdf0e10cSrcweir             pFirst->Calc();
2470cdf0e10cSrcweir             pCntnt->Calc();
2471cdf0e10cSrcweir             // --> OD 2005-05-17 #i49383# - format anchored objects
2472cdf0e10cSrcweir             if ( pCntnt->IsTxtFrm() && pCntnt->IsValid() )
2473cdf0e10cSrcweir             {
2474cdf0e10cSrcweir                 SwObjectFormatter::FormatObjsAtFrm( *pCntnt,
2475cdf0e10cSrcweir                                                     *(pCntnt->FindPageFrm()) );
2476cdf0e10cSrcweir             }
2477cdf0e10cSrcweir             // <--
2478cdf0e10cSrcweir             if( bUnlock )
2479cdf0e10cSrcweir                 pFirst->UnlockBackMove();
2480cdf0e10cSrcweir         }
2481cdf0e10cSrcweir         pFtn = FindFirstFtn();
2482cdf0e10cSrcweir     }
2483cdf0e10cSrcweir     SwDoc *pDoc = GetFmt()->GetDoc();
2484cdf0e10cSrcweir     const sal_uLong nFtnPos = pAttr ? ::lcl_FindFtnPos( pDoc, pAttr ) : 0;
2485cdf0e10cSrcweir     SwFrm *pCnt = pFtn ? pFtn->ContainsAny() : 0;
2486cdf0e10cSrcweir     if ( pCnt )
2487cdf0e10cSrcweir     {
2488cdf0e10cSrcweir         sal_Bool bMore = sal_True;
2489cdf0e10cSrcweir         sal_Bool bStart = pAttr == 0; // wenn kein Attribut uebergeben wird, alle bearbeiten
2490cdf0e10cSrcweir         // --> OD 2005-05-18 #i49383# - disable unlock of position of
2491cdf0e10cSrcweir         // lower objects during format of footnote and footnote content.
2492cdf0e10cSrcweir         SwFtnFrm* pLastFtnFrm( 0L );
2493cdf0e10cSrcweir         // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2494cdf0e10cSrcweir         // no extra notify for footnote frame
2495cdf0e10cSrcweir //        SwLayNotify* pFtnFrmNotify( 0L );
2496cdf0e10cSrcweir         // footnote frame needs to be locked, if <bLock> isn't set.
2497cdf0e10cSrcweir         bool bUnlockLastFtnFrm( false );
2498cdf0e10cSrcweir         // <--
2499cdf0e10cSrcweir         do
2500cdf0e10cSrcweir         {
2501cdf0e10cSrcweir             if( !bStart )
2502cdf0e10cSrcweir                 bStart = ::lcl_FindFtnPos( pDoc, pCnt->FindFtnFrm()->GetAttr() )
2503cdf0e10cSrcweir                          == nFtnPos;
2504cdf0e10cSrcweir             if( bStart )
2505cdf0e10cSrcweir             {
2506cdf0e10cSrcweir                 pCnt->_InvalidatePos();
2507cdf0e10cSrcweir                 pCnt->_InvalidateSize();
2508cdf0e10cSrcweir                 pCnt->Prepare( PREP_ADJUST_FRM );
2509cdf0e10cSrcweir                 SwFtnFrm* pFtnFrm = pCnt->FindFtnFrm();
2510cdf0e10cSrcweir                 // --> OD 2005-05-18 #i49383#
2511cdf0e10cSrcweir                 if ( pFtnFrm != pLastFtnFrm )
2512cdf0e10cSrcweir                 {
2513cdf0e10cSrcweir                     if ( pLastFtnFrm )
2514cdf0e10cSrcweir                     {
2515cdf0e10cSrcweir                         if ( !bLock && bUnlockLastFtnFrm )
2516cdf0e10cSrcweir                         {
2517cdf0e10cSrcweir                             pLastFtnFrm->ColUnlock();
2518cdf0e10cSrcweir                         }
2519cdf0e10cSrcweir                         // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2520cdf0e10cSrcweir                         // enable lock of lower object position before format of footnote frame.
2521cdf0e10cSrcweir                         pLastFtnFrm->UnlockPosOfLowerObjs();
2522cdf0e10cSrcweir                         pLastFtnFrm->Calc();
2523cdf0e10cSrcweir //                        pLastFtnFrm->UnlockPosOfLowerObjs();
2524cdf0e10cSrcweir                         // no extra notify for footnote frame
2525cdf0e10cSrcweir //                        delete pFtnFrmNotify;
2526cdf0e10cSrcweir                         // <--
2527cdf0e10cSrcweir                         if ( !bLock && bUnlockLastFtnFrm &&
2528cdf0e10cSrcweir                              !pLastFtnFrm->GetLower() &&
2529cdf0e10cSrcweir                              !pLastFtnFrm->IsColLocked() &&
2530cdf0e10cSrcweir                              !pLastFtnFrm->IsBackMoveLocked() )
2531cdf0e10cSrcweir                         {
2532cdf0e10cSrcweir                             pLastFtnFrm->Cut();
2533cdf0e10cSrcweir                             delete pLastFtnFrm;
2534cdf0e10cSrcweir                             pLastFtnFrm = 0L;
2535cdf0e10cSrcweir                         }
2536cdf0e10cSrcweir                     }
2537cdf0e10cSrcweir                     if ( !bLock )
2538cdf0e10cSrcweir                     {
2539cdf0e10cSrcweir                         bUnlockLastFtnFrm = !pFtnFrm->IsColLocked();
2540cdf0e10cSrcweir                         pFtnFrm->ColLock();
2541cdf0e10cSrcweir                     }
2542cdf0e10cSrcweir                     pFtnFrm->KeepLockPosOfLowerObjs();
2543cdf0e10cSrcweir                     pLastFtnFrm = pFtnFrm;
2544cdf0e10cSrcweir                     // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2545cdf0e10cSrcweir                     // no extra notify for footnote frame
2546cdf0e10cSrcweir //                    pFtnFrmNotify = new SwLayNotify( pLastFtnFrm );
2547cdf0e10cSrcweir                     // <--
2548cdf0e10cSrcweir                 }
2549cdf0e10cSrcweir                 // <--
2550cdf0e10cSrcweir                 // OD 30.10.2002 #97265# - invalidate position of footnote
2551cdf0e10cSrcweir                 // frame, if it's below its footnote container, in order to
2552cdf0e10cSrcweir                 // assure its correct position, probably calculating its previous
2553cdf0e10cSrcweir                 // footnote frames.
2554cdf0e10cSrcweir                 {
2555cdf0e10cSrcweir                     SWRECTFN( this );
2556cdf0e10cSrcweir                     SwFrm* aFtnContFrm = pFtnFrm->GetUpper();
2557cdf0e10cSrcweir                     if ( (pFtnFrm->Frm().*fnRect->fnTopDist)((aFtnContFrm->*fnRect->fnGetPrtBottom)()) > 0 )
2558cdf0e10cSrcweir                     {
2559cdf0e10cSrcweir                         pFtnFrm->_InvalidatePos();
2560cdf0e10cSrcweir                     }
2561cdf0e10cSrcweir                 }
2562cdf0e10cSrcweir                 if ( bLock )
2563cdf0e10cSrcweir                 {
2564cdf0e10cSrcweir                     sal_Bool bUnlock = !pFtnFrm->IsBackMoveLocked();
2565cdf0e10cSrcweir                     pFtnFrm->LockBackMove();
2566cdf0e10cSrcweir                     pFtnFrm->Calc();
2567cdf0e10cSrcweir                     pCnt->Calc();
2568cdf0e10cSrcweir                     // --> OD 2005-05-17 #i49383# - format anchored objects
2569cdf0e10cSrcweir                     if ( pCnt->IsTxtFrm() && pCnt->IsValid() )
2570cdf0e10cSrcweir                     {
2571cdf0e10cSrcweir                         if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
2572cdf0e10cSrcweir                                                                   *(pCnt->FindPageFrm()) ) )
2573cdf0e10cSrcweir                         {
2574cdf0e10cSrcweir                             // restart format with first content
2575cdf0e10cSrcweir                             pCnt = pFtn->ContainsAny();
2576cdf0e10cSrcweir                             continue;
2577cdf0e10cSrcweir                         }
2578cdf0e10cSrcweir                     }
2579cdf0e10cSrcweir                     // <--
2580cdf0e10cSrcweir                     if( bUnlock )
2581cdf0e10cSrcweir                     {
2582cdf0e10cSrcweir                         pFtnFrm->UnlockBackMove();
2583cdf0e10cSrcweir                         if( !pFtnFrm->Lower() &&
2584cdf0e10cSrcweir                             !pFtnFrm->IsColLocked() )
2585cdf0e10cSrcweir                         {
2586cdf0e10cSrcweir                             // --> OD 2005-08-10 #i49383#
2587cdf0e10cSrcweir                             ASSERT( pLastFtnFrm == pFtnFrm,
2588cdf0e10cSrcweir                                     "<SwFtnBossFrm::RearrangeFtns(..)> - <pLastFtnFrm> != <pFtnFrm>" );
2589cdf0e10cSrcweir                             pLastFtnFrm = 0L;
2590cdf0e10cSrcweir                             // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2591cdf0e10cSrcweir                             // no extra notify for footnote frame
2592cdf0e10cSrcweir //                            pFtnFrmNotify->FrmDeleted();
2593cdf0e10cSrcweir //                            delete pFtnFrmNotify;
2594cdf0e10cSrcweir                             // <--
2595cdf0e10cSrcweir                             pFtnFrm->Cut();
2596cdf0e10cSrcweir                             delete pFtnFrm;
2597cdf0e10cSrcweir                         }
2598cdf0e10cSrcweir                     }
2599cdf0e10cSrcweir                 }
2600cdf0e10cSrcweir                 else
2601cdf0e10cSrcweir                 {
2602cdf0e10cSrcweir                     pFtnFrm->Calc();
2603cdf0e10cSrcweir                     pCnt->Calc();
2604cdf0e10cSrcweir                     // --> OD 2005-05-17 #i49383# - format anchored objects
2605cdf0e10cSrcweir                     if ( pCnt->IsTxtFrm() && pCnt->IsValid() )
2606cdf0e10cSrcweir                     {
2607cdf0e10cSrcweir                         if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
2608cdf0e10cSrcweir                                                                   *(pCnt->FindPageFrm()) ) )
2609cdf0e10cSrcweir                         {
2610cdf0e10cSrcweir                             // restart format with first content
2611cdf0e10cSrcweir                             pCnt = pFtn->ContainsAny();
2612cdf0e10cSrcweir                             continue;
2613cdf0e10cSrcweir                         }
2614cdf0e10cSrcweir                     }
2615cdf0e10cSrcweir                     // <--
2616cdf0e10cSrcweir                 }
2617cdf0e10cSrcweir             }
2618cdf0e10cSrcweir             SwSectionFrm *pDel = NULL;
2619cdf0e10cSrcweir             if( pCnt->IsSctFrm() )
2620cdf0e10cSrcweir             {
2621cdf0e10cSrcweir                 SwFrm* pTmp = ((SwSectionFrm*)pCnt)->ContainsAny();
2622cdf0e10cSrcweir                 if( pTmp )
2623cdf0e10cSrcweir                 {
2624cdf0e10cSrcweir                     pCnt = pTmp;
2625cdf0e10cSrcweir                     continue;
2626cdf0e10cSrcweir                 }
2627cdf0e10cSrcweir                 pDel = (SwSectionFrm*)pCnt;
2628cdf0e10cSrcweir             }
2629cdf0e10cSrcweir             if ( pCnt->GetNext() )
2630cdf0e10cSrcweir                 pCnt = pCnt->GetNext();
2631cdf0e10cSrcweir             else
2632cdf0e10cSrcweir             {
2633cdf0e10cSrcweir                 pCnt = pCnt->FindNext();
2634cdf0e10cSrcweir                 if ( pCnt )
2635cdf0e10cSrcweir                 {
2636cdf0e10cSrcweir                     SwFtnFrm* pFtnFrm = pCnt->FindFtnFrm();
2637cdf0e10cSrcweir                     if( pFtnFrm->GetRef()->FindFtnBossFrm(
2638cdf0e10cSrcweir                         pFtnFrm->GetAttr()->GetFtn().IsEndNote() ) != this )
2639cdf0e10cSrcweir                         bMore = sal_False;
2640cdf0e10cSrcweir                 }
2641cdf0e10cSrcweir                 else
2642cdf0e10cSrcweir                     bMore = sal_False;
2643cdf0e10cSrcweir             }
2644cdf0e10cSrcweir             if( pDel )
2645cdf0e10cSrcweir             {
2646cdf0e10cSrcweir                 pDel->Cut();
2647cdf0e10cSrcweir                 delete pDel;
2648cdf0e10cSrcweir             }
2649cdf0e10cSrcweir             if ( bMore )
2650cdf0e10cSrcweir             {
2651cdf0e10cSrcweir                 //Nicht weiter als bis zur angegebenen Fussnote, falls eine
2652cdf0e10cSrcweir                 //angegeben wurde.
2653cdf0e10cSrcweir                 if ( pAttr &&
2654cdf0e10cSrcweir                      (::lcl_FindFtnPos( pDoc,
2655cdf0e10cSrcweir                                     pCnt->FindFtnFrm()->GetAttr()) > nFtnPos ) )
2656cdf0e10cSrcweir                     bMore = sal_False;
2657cdf0e10cSrcweir             }
2658cdf0e10cSrcweir         } while ( bMore );
2659cdf0e10cSrcweir         // --> OD 2005-05-18 #i49383#
2660cdf0e10cSrcweir         if ( pLastFtnFrm )
2661cdf0e10cSrcweir         {
2662cdf0e10cSrcweir             if ( !bLock && bUnlockLastFtnFrm )
2663cdf0e10cSrcweir             {
2664cdf0e10cSrcweir                 pLastFtnFrm->ColUnlock();
2665cdf0e10cSrcweir             }
2666cdf0e10cSrcweir             // --> OD 2006-02-02 #i57914# - adjust fix #i49383#
2667cdf0e10cSrcweir             // enable lock of lower object position before format of footnote frame.
2668cdf0e10cSrcweir             pLastFtnFrm->UnlockPosOfLowerObjs();
2669cdf0e10cSrcweir             pLastFtnFrm->Calc();
2670cdf0e10cSrcweir //            pLastFtnFrm->UnlockPosOfLowerObjs();
2671cdf0e10cSrcweir             // no extra notify for footnote frame
2672cdf0e10cSrcweir //            delete pFtnFrmNotify;
2673cdf0e10cSrcweir             // <--
2674cdf0e10cSrcweir             if ( !bLock && bUnlockLastFtnFrm &&
2675cdf0e10cSrcweir                  !pLastFtnFrm->GetLower() &&
2676cdf0e10cSrcweir                  !pLastFtnFrm->IsColLocked() &&
2677cdf0e10cSrcweir                  !pLastFtnFrm->IsBackMoveLocked() )
2678cdf0e10cSrcweir             {
2679cdf0e10cSrcweir                 pLastFtnFrm->Cut();
2680cdf0e10cSrcweir                 delete pLastFtnFrm;
2681cdf0e10cSrcweir             }
2682cdf0e10cSrcweir         }
2683cdf0e10cSrcweir         // <--
2684cdf0e10cSrcweir     }
2685cdf0e10cSrcweir }
2686cdf0e10cSrcweir 
2687cdf0e10cSrcweir /*************************************************************************
2688cdf0e10cSrcweir |*
2689cdf0e10cSrcweir |*  SwPageFrm::UpdateFtnNum()
2690cdf0e10cSrcweir |*
2691cdf0e10cSrcweir |*************************************************************************/
2692cdf0e10cSrcweir 
UpdateFtnNum()2693cdf0e10cSrcweir void SwPageFrm::UpdateFtnNum()
2694cdf0e10cSrcweir {
2695cdf0e10cSrcweir     //Seitenweise Numerierung nur wenn es am Dokument so eingestellt ist.
2696cdf0e10cSrcweir     if ( GetFmt()->GetDoc()->GetFtnInfo().eNum != FTNNUM_PAGE )
2697cdf0e10cSrcweir         return;
2698cdf0e10cSrcweir 
2699cdf0e10cSrcweir     SwLayoutFrm* pBody = FindBodyCont();
2700cdf0e10cSrcweir     if( !pBody || !pBody->Lower() )
2701cdf0e10cSrcweir         return;
2702cdf0e10cSrcweir 
2703cdf0e10cSrcweir     SwCntntFrm* pCntnt = pBody->ContainsCntnt();
2704cdf0e10cSrcweir     sal_uInt16 nNum = 0;
2705cdf0e10cSrcweir 
2706cdf0e10cSrcweir     while( pCntnt && pCntnt->FindPageFrm() == this )
2707cdf0e10cSrcweir     {
2708cdf0e10cSrcweir         if( ((SwTxtFrm*)pCntnt)->HasFtn() )
2709cdf0e10cSrcweir         {
2710cdf0e10cSrcweir             SwFtnBossFrm* pBoss = pCntnt->FindFtnBossFrm( sal_True );
2711cdf0e10cSrcweir             if( pBoss->GetUpper()->IsSctFrm() &&
2712cdf0e10cSrcweir                 ((SwSectionFrm*)pBoss->GetUpper())->IsOwnFtnNum() )
2713cdf0e10cSrcweir                 pCntnt = ((SwSectionFrm*)pBoss->GetUpper())->FindLastCntnt();
2714cdf0e10cSrcweir             else
2715cdf0e10cSrcweir             {
2716cdf0e10cSrcweir                 SwFtnFrm* pFtn = (SwFtnFrm*)pBoss->FindFirstFtn( pCntnt );
2717cdf0e10cSrcweir                 while( pFtn )
2718cdf0e10cSrcweir                 {
2719cdf0e10cSrcweir                     SwTxtFtn* pTxtFtn = pFtn->GetAttr();
2720cdf0e10cSrcweir                     if( !pTxtFtn->GetFtn().IsEndNote() &&
2721cdf0e10cSrcweir                         !pTxtFtn->GetFtn().GetNumStr().Len() &&
2722cdf0e10cSrcweir                         !pFtn->GetMaster() &&
2723cdf0e10cSrcweir                         (pTxtFtn->GetFtn().GetNumber() != ++nNum) )
2724cdf0e10cSrcweir                         pTxtFtn->SetNumber( nNum );
2725cdf0e10cSrcweir                     if ( pFtn->GetNext() )
2726cdf0e10cSrcweir                         pFtn = (SwFtnFrm*)pFtn->GetNext();
2727cdf0e10cSrcweir                     else
2728cdf0e10cSrcweir                     {
2729cdf0e10cSrcweir                         SwFtnBossFrm* pTmpBoss = pFtn->FindFtnBossFrm( sal_True );
2730cdf0e10cSrcweir                         SwPageFrm* pPage = pTmpBoss->FindPageFrm();
2731cdf0e10cSrcweir                         pFtn = NULL;
2732cdf0e10cSrcweir                         lcl_NextFtnBoss( pTmpBoss, pPage, sal_False );
2733cdf0e10cSrcweir                         if( pTmpBoss )
2734cdf0e10cSrcweir                         {
2735cdf0e10cSrcweir                             SwFtnContFrm *pCont = pTmpBoss->FindNearestFtnCont();
2736cdf0e10cSrcweir                             if ( pCont )
2737cdf0e10cSrcweir                                 pFtn = (SwFtnFrm*)pCont->Lower();
2738cdf0e10cSrcweir                         }
2739cdf0e10cSrcweir                     }
2740cdf0e10cSrcweir                     if( pFtn && pFtn->GetRef() != pCntnt )
2741cdf0e10cSrcweir                         pFtn = NULL;
2742cdf0e10cSrcweir                 }
2743cdf0e10cSrcweir             }
2744cdf0e10cSrcweir         }
2745cdf0e10cSrcweir         pCntnt = pCntnt->FindNextCnt();
2746cdf0e10cSrcweir     }
2747cdf0e10cSrcweir }
2748cdf0e10cSrcweir 
2749cdf0e10cSrcweir /*************************************************************************
2750cdf0e10cSrcweir |*
2751cdf0e10cSrcweir |*  SwFtnBossFrm::SetFtnDeadLine()
2752cdf0e10cSrcweir |*
2753cdf0e10cSrcweir |*************************************************************************/
2754cdf0e10cSrcweir 
SetFtnDeadLine(const SwTwips nDeadLine)2755cdf0e10cSrcweir void SwFtnBossFrm::SetFtnDeadLine( const SwTwips nDeadLine )
2756cdf0e10cSrcweir {
2757cdf0e10cSrcweir     SwFrm *pBody = FindBodyCont();
2758cdf0e10cSrcweir     pBody->Calc();
2759cdf0e10cSrcweir 
2760cdf0e10cSrcweir     SwFrm *pCont = FindFtnCont();
2761cdf0e10cSrcweir     const SwTwips nMax = nMaxFtnHeight;//Aktuelle MaxHeight nicht ueberschreiten.
2762cdf0e10cSrcweir     SWRECTFN( this )
2763cdf0e10cSrcweir     if ( pCont )
2764cdf0e10cSrcweir     {
2765cdf0e10cSrcweir         pCont->Calc();
2766cdf0e10cSrcweir         nMaxFtnHeight = -(pCont->Frm().*fnRect->fnBottomDist)( nDeadLine );
2767cdf0e10cSrcweir     }
2768cdf0e10cSrcweir     else
2769cdf0e10cSrcweir         nMaxFtnHeight = -(pBody->Frm().*fnRect->fnBottomDist)( nDeadLine );
2770cdf0e10cSrcweir 
2771cdf0e10cSrcweir     const ViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
2772cdf0e10cSrcweir     if( pSh && pSh->GetViewOptions()->getBrowseMode() )
2773cdf0e10cSrcweir         nMaxFtnHeight += pBody->Grow( LONG_MAX, sal_True );
2774cdf0e10cSrcweir     if ( IsInSct() )
2775cdf0e10cSrcweir         nMaxFtnHeight += FindSctFrm()->Grow( LONG_MAX, sal_True );
2776cdf0e10cSrcweir 
2777cdf0e10cSrcweir     if ( nMaxFtnHeight < 0 )
2778cdf0e10cSrcweir         nMaxFtnHeight = 0;
2779cdf0e10cSrcweir     if ( nMax != LONG_MAX && nMaxFtnHeight > nMax )
2780cdf0e10cSrcweir         nMaxFtnHeight = nMax;
2781cdf0e10cSrcweir }
2782cdf0e10cSrcweir 
2783cdf0e10cSrcweir /*************************************************************************
2784cdf0e10cSrcweir |*
2785cdf0e10cSrcweir |*  SwFtnBossFrm::GetVarSpace()
2786cdf0e10cSrcweir |*
2787cdf0e10cSrcweir |*************************************************************************/
GetVarSpace() const2788cdf0e10cSrcweir SwTwips SwFtnBossFrm::GetVarSpace() const
2789cdf0e10cSrcweir {
2790cdf0e10cSrcweir     //Fuer Seiten soll ein Wert von 20% der Seitenhoehe nicht unterschritten
2791cdf0e10cSrcweir     //werden (->AMA: was macht MS da?)
2792cdf0e10cSrcweir     //->AMA: Was ist da fuer Bereiche sinnvoll (und kompatibel zu MS ;-)?
2793cdf0e10cSrcweir     //AMA: MS kennt scheinbar kein Begrenzung, die Fussnoten nehmen durchaus
2794cdf0e10cSrcweir     // die ganze Seite/Spalte ein.
2795cdf0e10cSrcweir 
2796cdf0e10cSrcweir     const SwPageFrm* pPg = FindPageFrm();
2797cdf0e10cSrcweir     ASSERT( pPg || IsInSct(), "Footnote lost page" );
2798cdf0e10cSrcweir 
2799cdf0e10cSrcweir     const SwFrm *pBody = FindBodyCont();
2800cdf0e10cSrcweir     SwTwips nRet;
2801cdf0e10cSrcweir     if( pBody )
2802cdf0e10cSrcweir     {
2803cdf0e10cSrcweir         SWRECTFN( this )
2804cdf0e10cSrcweir         if( IsInSct() )
2805cdf0e10cSrcweir         {
2806cdf0e10cSrcweir             nRet = 0;
2807cdf0e10cSrcweir             SwTwips nTmp = (*fnRect->fnYDiff)( (pBody->*fnRect->fnGetPrtTop)(),
2808cdf0e10cSrcweir                                                (Frm().*fnRect->fnGetTop)() );
2809cdf0e10cSrcweir             const SwSectionFrm* pSect = FindSctFrm();
2810cdf0e10cSrcweir             //  Endnotes in a ftncontainer causes a deadline:
2811cdf0e10cSrcweir             // the bottom of the last contentfrm
2812cdf0e10cSrcweir             if( pSect->IsEndnAtEnd() ) // endnotes allowed?
2813cdf0e10cSrcweir             {
2814cdf0e10cSrcweir                 ASSERT( !Lower() || !Lower()->GetNext() || Lower()->GetNext()->
2815*7de601c3SJohn Bampton                         IsFtnContFrm(), "FtnContainer expected" );
2816cdf0e10cSrcweir                 const SwFtnContFrm* pCont = Lower() ?
2817cdf0e10cSrcweir                     (SwFtnContFrm*)Lower()->GetNext() : 0;
2818cdf0e10cSrcweir                 if( pCont )
2819cdf0e10cSrcweir                 {
2820cdf0e10cSrcweir                     SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower();
2821cdf0e10cSrcweir                     while( pFtn)
2822cdf0e10cSrcweir                     {
2823cdf0e10cSrcweir                         if( pFtn->GetAttr()->GetFtn().IsEndNote() )
2824cdf0e10cSrcweir                         { // endnote found
2825cdf0e10cSrcweir                             SwFrm* pFrm = ((SwLayoutFrm*)Lower())->Lower();
2826cdf0e10cSrcweir                             if( pFrm )
2827cdf0e10cSrcweir                             {
2828cdf0e10cSrcweir                                 while( pFrm->GetNext() )
2829cdf0e10cSrcweir                                     pFrm = pFrm->GetNext(); // last cntntfrm
2830cdf0e10cSrcweir                                 nTmp += (*fnRect->fnYDiff)(
2831cdf0e10cSrcweir                                          (Frm().*fnRect->fnGetTop)(),
2832cdf0e10cSrcweir                                          (pFrm->Frm().*fnRect->fnGetBottom)() );
2833cdf0e10cSrcweir                             }
2834cdf0e10cSrcweir                             break;
2835cdf0e10cSrcweir                         }
2836cdf0e10cSrcweir                         pFtn = (SwFtnFrm*)pFtn->GetNext();
2837cdf0e10cSrcweir                     }
2838cdf0e10cSrcweir                 }
2839cdf0e10cSrcweir             }
2840cdf0e10cSrcweir             if( nTmp < nRet )
2841cdf0e10cSrcweir                 nRet = nTmp;
2842cdf0e10cSrcweir         }
2843cdf0e10cSrcweir         else
2844cdf0e10cSrcweir             nRet = - (pPg->Prt().*fnRect->fnGetHeight)()/5;
2845cdf0e10cSrcweir         nRet += (pBody->Frm().*fnRect->fnGetHeight)();
2846cdf0e10cSrcweir         if( nRet < 0 )
2847cdf0e10cSrcweir             nRet = 0;
2848cdf0e10cSrcweir     }
2849cdf0e10cSrcweir     else
2850cdf0e10cSrcweir         nRet = 0;
2851cdf0e10cSrcweir     if ( IsPageFrm() )
2852cdf0e10cSrcweir     {
2853cdf0e10cSrcweir         const ViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
2854cdf0e10cSrcweir         if( pSh && pSh->GetViewOptions()->getBrowseMode() )
2855cdf0e10cSrcweir         nRet += BROWSE_HEIGHT - Frm().Height();
2856cdf0e10cSrcweir     }
2857cdf0e10cSrcweir     return nRet;
2858cdf0e10cSrcweir }
2859cdf0e10cSrcweir 
2860cdf0e10cSrcweir /*************************************************************************
2861cdf0e10cSrcweir |*
2862cdf0e10cSrcweir |*  SwFtnBossFrm::NeighbourhoodAdjustment(SwFrm*)
2863cdf0e10cSrcweir |*
2864cdf0e10cSrcweir |*  gibt Auskunft, ob die Groessenveraenderung von pFrm von AdjustNeighbourhood(...)
2865cdf0e10cSrcweir |*  oder von Grow/Shrink(..) verarbeitet werden sollte.
2866cdf0e10cSrcweir |*  Bei einem PageFrm oder in Spalten direkt unterhalb der Seite muss AdjustNei..
2867cdf0e10cSrcweir |*  gerufen werden, in Rahmenspalten Grow/Shrink.
2868cdf0e10cSrcweir |*  Spannend sind die spaltigen Bereiche: Wenn es in der Spalte einen Fussnotencontainer
2869cdf0e10cSrcweir |*  gibt und die Fussnoten nicht vom Bereich eingesammelt werden, ist ein Adjust..,
2870cdf0e10cSrcweir |*  ansonsten ein Grow/Shrink notwendig.
2871cdf0e10cSrcweir |*
2872cdf0e10cSrcweir |*************************************************************************/
2873cdf0e10cSrcweir 
_NeighbourhoodAdjustment(const SwFrm *) const2874cdf0e10cSrcweir sal_uInt8 SwFtnBossFrm::_NeighbourhoodAdjustment( const SwFrm* ) const
2875cdf0e10cSrcweir {
2876cdf0e10cSrcweir     sal_uInt8 nRet = NA_ONLY_ADJUST;
2877cdf0e10cSrcweir     if( GetUpper() && !GetUpper()->IsPageBodyFrm() )
2878cdf0e10cSrcweir     {
2879cdf0e10cSrcweir         // Spaltige Rahmen erfordern Grow/Shrink
2880cdf0e10cSrcweir         if( GetUpper()->IsFlyFrm() )
2881cdf0e10cSrcweir             nRet = NA_GROW_SHRINK;
2882cdf0e10cSrcweir         else
2883cdf0e10cSrcweir         {
2884565bea5dSJohn Bampton             ASSERT( GetUpper()->IsSctFrm(), "NeighbourhoodAdjustment: Unexpected Upper" );
2885cdf0e10cSrcweir             if( !GetNext() && !GetPrev() )
2886cdf0e10cSrcweir                 nRet = NA_GROW_ADJUST; // section with a single column (FtnAtEnd)
2887cdf0e10cSrcweir             else
2888cdf0e10cSrcweir             {
2889cdf0e10cSrcweir                 const SwFrm* pTmp = Lower();
2890cdf0e10cSrcweir                 ASSERT( pTmp, "NeighbourhoodAdjustment: Missing Lower()" );
2891cdf0e10cSrcweir                 if( !pTmp->GetNext() )
2892cdf0e10cSrcweir                     nRet = NA_GROW_SHRINK;
2893cdf0e10cSrcweir                 else if( !GetUpper()->IsColLocked() )
2894cdf0e10cSrcweir                     nRet = NA_ADJUST_GROW;
2895cdf0e10cSrcweir                 ASSERT( !pTmp->GetNext() || pTmp->GetNext()->IsFtnContFrm(),
2896cdf0e10cSrcweir                         "NeighbourhoodAdjustment: Who's that guy?" );
2897cdf0e10cSrcweir             }
2898cdf0e10cSrcweir         }
2899cdf0e10cSrcweir     }
2900cdf0e10cSrcweir     return nRet;
2901cdf0e10cSrcweir }
2902cdf0e10cSrcweir 
2903cdf0e10cSrcweir /*************************************************************************
2904cdf0e10cSrcweir |*
2905cdf0e10cSrcweir |*  SwPageFrm::SetColMaxFtnHeight()
2906cdf0e10cSrcweir |*
2907cdf0e10cSrcweir |*************************************************************************/
SetColMaxFtnHeight()2908cdf0e10cSrcweir void SwPageFrm::SetColMaxFtnHeight()
2909cdf0e10cSrcweir {
2910cdf0e10cSrcweir     SwLayoutFrm *pBody = FindBodyCont();
2911cdf0e10cSrcweir     if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
2912cdf0e10cSrcweir     {
2913cdf0e10cSrcweir         SwColumnFrm* pCol = (SwColumnFrm*)pBody->Lower();
2914cdf0e10cSrcweir         do
2915cdf0e10cSrcweir         {
2916cdf0e10cSrcweir             pCol->SetMaxFtnHeight( GetMaxFtnHeight() );
2917cdf0e10cSrcweir             pCol = (SwColumnFrm*)pCol->GetNext();
2918cdf0e10cSrcweir         } while ( pCol );
2919cdf0e10cSrcweir     }
2920cdf0e10cSrcweir }
2921cdf0e10cSrcweir 
2922cdf0e10cSrcweir /*************************************************************************
2923cdf0e10cSrcweir |*
2924cdf0e10cSrcweir |*  SwLayoutFrm::MoveLowerFtns
2925cdf0e10cSrcweir |*
2926cdf0e10cSrcweir |*************************************************************************/
2927cdf0e10cSrcweir 
2928cdf0e10cSrcweir 
MoveLowerFtns(SwCntntFrm * pStart,SwFtnBossFrm * pOldBoss,SwFtnBossFrm * pNewBoss,const sal_Bool bFtnNums)2929cdf0e10cSrcweir sal_Bool SwLayoutFrm::MoveLowerFtns( SwCntntFrm *pStart, SwFtnBossFrm *pOldBoss,
2930cdf0e10cSrcweir                                  SwFtnBossFrm *pNewBoss, const sal_Bool bFtnNums )
2931cdf0e10cSrcweir {
2932cdf0e10cSrcweir     SwDoc *pDoc = GetFmt()->GetDoc();
2933cdf0e10cSrcweir     if ( !pDoc->GetFtnIdxs().Count() )
2934cdf0e10cSrcweir         return sal_False;
2935cdf0e10cSrcweir     if( pDoc->GetFtnInfo().ePos == FTNPOS_CHAPTER &&
2936cdf0e10cSrcweir         ( !IsInSct() || !FindSctFrm()->IsFtnAtEnd() ) )
2937cdf0e10cSrcweir         return sal_True;
2938cdf0e10cSrcweir 
2939cdf0e10cSrcweir     if ( !pNewBoss )
2940cdf0e10cSrcweir         pNewBoss = FindFtnBossFrm( sal_True );
2941cdf0e10cSrcweir     if ( pNewBoss == pOldBoss )
2942cdf0e10cSrcweir         return sal_False;
2943cdf0e10cSrcweir 
2944cdf0e10cSrcweir     sal_Bool bMoved = sal_False;
2945cdf0e10cSrcweir     if( !pStart )
2946cdf0e10cSrcweir         pStart = ContainsCntnt();
2947cdf0e10cSrcweir 
2948cdf0e10cSrcweir     SvPtrarr aFtnArr( 5, 5 );
2949cdf0e10cSrcweir 
2950cdf0e10cSrcweir     while ( IsAnLower( pStart ) )
2951cdf0e10cSrcweir     {
2952cdf0e10cSrcweir         if ( ((SwTxtFrm*)pStart)->HasFtn() )
2953cdf0e10cSrcweir         {
2954cdf0e10cSrcweir             // OD 03.04.2003 #108446# - To avoid unnecessary moves of footnotes
2955cdf0e10cSrcweir             // use new parameter <_bCollectOnlyPreviousFtn> (4th parameter of
2956cdf0e10cSrcweir             // method <SwFtnBossFrm::CollectFtn(..)>) to control, that only
2957cdf0e10cSrcweir             // footnotes have to be collected, that are positioned before the
2958cdf0e10cSrcweir             // new dedicated footnote boss frame.
2959cdf0e10cSrcweir             pNewBoss->CollectFtns( pStart, pOldBoss, aFtnArr, sal_True );
2960cdf0e10cSrcweir         }
2961cdf0e10cSrcweir         pStart = pStart->GetNextCntntFrm();
2962cdf0e10cSrcweir     }
2963cdf0e10cSrcweir 
2964cdf0e10cSrcweir     ASSERT( pOldBoss->IsInSct() == pNewBoss->IsInSct(),
2965cdf0e10cSrcweir             "MoveLowerFtns: Section confusion" );
2966cdf0e10cSrcweir     SvPtrarr *pFtnArr;
2967cdf0e10cSrcweir     SwLayoutFrm* pNewChief = 0;
2968cdf0e10cSrcweir     SwLayoutFrm* pOldChief = 0;
2969cdf0e10cSrcweir     if( pStart && pOldBoss->IsInSct() && ( pOldChief = pOldBoss->FindSctFrm() )
2970cdf0e10cSrcweir         != ( pNewChief = pNewBoss->FindSctFrm() ) )
2971cdf0e10cSrcweir     {
2972cdf0e10cSrcweir         pFtnArr = new SvPtrarr( 5, 5 );
2973cdf0e10cSrcweir         pOldChief = pOldBoss->FindFtnBossFrm( sal_True );
2974cdf0e10cSrcweir         pNewChief = pNewBoss->FindFtnBossFrm( sal_True );
2975cdf0e10cSrcweir         while( pOldChief->IsAnLower( pStart ) )
2976cdf0e10cSrcweir         {
2977cdf0e10cSrcweir             if ( ((SwTxtFrm*)pStart)->HasFtn() )
2978cdf0e10cSrcweir                 ((SwFtnBossFrm*)pNewChief)->CollectFtns( pStart,
2979cdf0e10cSrcweir                                         (SwFtnBossFrm*)pOldBoss, *pFtnArr );
2980cdf0e10cSrcweir             pStart = pStart->GetNextCntntFrm();
2981cdf0e10cSrcweir         }
2982cdf0e10cSrcweir         if( !pFtnArr->Count() )
2983cdf0e10cSrcweir         {
2984cdf0e10cSrcweir             delete pFtnArr;
2985cdf0e10cSrcweir             pFtnArr = NULL;
2986cdf0e10cSrcweir         }
2987cdf0e10cSrcweir     }
2988cdf0e10cSrcweir     else
2989cdf0e10cSrcweir         pFtnArr = NULL;
2990cdf0e10cSrcweir 
2991cdf0e10cSrcweir     if ( aFtnArr.Count() || pFtnArr )
2992cdf0e10cSrcweir     {
2993cdf0e10cSrcweir         if( aFtnArr.Count() )
2994cdf0e10cSrcweir             pNewBoss->_MoveFtns( aFtnArr, sal_True );
2995cdf0e10cSrcweir         if( pFtnArr )
2996cdf0e10cSrcweir         {
2997cdf0e10cSrcweir             ((SwFtnBossFrm*)pNewChief)->_MoveFtns( *pFtnArr, sal_True );
2998cdf0e10cSrcweir             delete pFtnArr;
2999cdf0e10cSrcweir         }
3000cdf0e10cSrcweir         bMoved = sal_True;
3001cdf0e10cSrcweir 
3002cdf0e10cSrcweir         // Nur bei einem Seitenwechsel muss die FtnNum neu berechnet werden
3003cdf0e10cSrcweir         if ( bFtnNums )
3004cdf0e10cSrcweir         {
3005cdf0e10cSrcweir             SwPageFrm* pOldPage = pOldBoss->FindPageFrm();
3006cdf0e10cSrcweir             SwPageFrm* pNewPage =pNewBoss->FindPageFrm();
3007cdf0e10cSrcweir             if( pOldPage != pNewPage )
3008cdf0e10cSrcweir             {
3009cdf0e10cSrcweir                 pOldPage->UpdateFtnNum();
3010cdf0e10cSrcweir                 pNewPage->UpdateFtnNum();
3011cdf0e10cSrcweir             }
3012cdf0e10cSrcweir         }
3013cdf0e10cSrcweir     }
3014cdf0e10cSrcweir     return bMoved;
3015cdf0e10cSrcweir }
3016cdf0e10cSrcweir 
3017cdf0e10cSrcweir /*************************************************************************
3018cdf0e10cSrcweir |*
3019cdf0e10cSrcweir |*  SwLayoutFrm::MoveFtnCntFwd()
3020cdf0e10cSrcweir |*
3021cdf0e10cSrcweir |*************************************************************************/
3022cdf0e10cSrcweir 
3023cdf0e10cSrcweir 
MoveFtnCntFwd(sal_Bool bMakePage,SwFtnBossFrm * pOldBoss)3024cdf0e10cSrcweir sal_Bool SwCntntFrm::MoveFtnCntFwd( sal_Bool bMakePage, SwFtnBossFrm *pOldBoss )
3025cdf0e10cSrcweir {
3026cdf0e10cSrcweir     ASSERT( IsInFtn(), "Keine Ftn." );
3027cdf0e10cSrcweir     SwLayoutFrm *pFtn = FindFtnFrm();
3028cdf0e10cSrcweir 
3029cdf0e10cSrcweir     // The first paragraph in the first footnote in the first column in the
3030cdf0e10cSrcweir     // sectionfrm at the top of the page has not to move forward, if the
3031cdf0e10cSrcweir     // columnbody is empty.
3032cdf0e10cSrcweir     if( pOldBoss->IsInSct() && !pOldBoss->GetIndPrev() && !GetIndPrev() &&
3033cdf0e10cSrcweir         !pFtn->GetPrev() )
3034cdf0e10cSrcweir     {
3035cdf0e10cSrcweir         SwLayoutFrm* pBody = pOldBoss->FindBodyCont();
3036cdf0e10cSrcweir         if( !pBody || !pBody->Lower() )
3037cdf0e10cSrcweir             return sal_True;
3038cdf0e10cSrcweir     }
3039cdf0e10cSrcweir 
3040cdf0e10cSrcweir     //fix(9538): Wenn die Ftn noch Nachbarn hinter sich hat, so muessen
3041cdf0e10cSrcweir     //diese ersteinmal verschwinden.
3042cdf0e10cSrcweir     SwLayoutFrm *pNxt = (SwLayoutFrm*)pFtn->GetNext();
3043cdf0e10cSrcweir     SwLayoutFrm *pLst = 0;
3044cdf0e10cSrcweir     while ( pNxt )
3045cdf0e10cSrcweir     {
3046cdf0e10cSrcweir         while ( pNxt->GetNext() )
3047cdf0e10cSrcweir             pNxt = (SwLayoutFrm*)pNxt->GetNext();
3048cdf0e10cSrcweir         if ( pNxt == pLst )
3049cdf0e10cSrcweir             pNxt = 0;
3050cdf0e10cSrcweir         else
3051cdf0e10cSrcweir         {   pLst = pNxt;
3052cdf0e10cSrcweir             SwCntntFrm *pCnt = pNxt->ContainsCntnt();
3053cdf0e10cSrcweir             if( pCnt )
3054cdf0e10cSrcweir                 pCnt->MoveFtnCntFwd( sal_True, pOldBoss );
3055cdf0e10cSrcweir             pNxt = (SwLayoutFrm*)pFtn->GetNext();
3056cdf0e10cSrcweir         }
3057cdf0e10cSrcweir     }
3058cdf0e10cSrcweir 
3059cdf0e10cSrcweir     sal_Bool bSamePage = sal_True;
3060cdf0e10cSrcweir     SwLayoutFrm *pNewUpper =
3061cdf0e10cSrcweir                 GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, sal_True );
3062cdf0e10cSrcweir 
3063cdf0e10cSrcweir     if ( pNewUpper )
3064cdf0e10cSrcweir     {
3065cdf0e10cSrcweir         sal_Bool bSameBoss = sal_True;
3066cdf0e10cSrcweir         SwFtnBossFrm * const pNewBoss = pNewUpper->FindFtnBossFrm();
3067cdf0e10cSrcweir         //Wechseln wir die Spalte/Seite?
3068cdf0e10cSrcweir         if ( sal_False == ( bSameBoss = pNewBoss == pOldBoss ) )
3069cdf0e10cSrcweir         {
3070cdf0e10cSrcweir             bSamePage = pOldBoss->FindPageFrm() == pNewBoss->FindPageFrm(); // Seitenwechsel?
3071cdf0e10cSrcweir             pNewUpper->Calc();
3072cdf0e10cSrcweir         }
3073cdf0e10cSrcweir 
3074cdf0e10cSrcweir         //Das Layoutblatt, dass wir fuer Fussnoten bekommen ist entweder
3075cdf0e10cSrcweir         //ein Fussnotencontainer oder eine Fussnote
3076cdf0e10cSrcweir         //Wenn es eine Fussnote ist, und sie die gleiche Fussnotenreferez
3077cdf0e10cSrcweir         //wie der alte Upper hat, so moven wir uns direkt hinein.
3078cdf0e10cSrcweir         //Ist die Referenz einen andere oder ist es ein Container, so wird
3079cdf0e10cSrcweir         //eine neue Fussnote erzeugt und in den Container gestellt.
3080cdf0e10cSrcweir         // Wenn wir in einem Bereich innerhalb der Fussnote sind, muss
3081cdf0e10cSrcweir         // SectionFrame noch angelegt werden.
3082cdf0e10cSrcweir         SwFtnFrm* pTmpFtn = pNewUpper->IsFtnFrm() ? ((SwFtnFrm*)pNewUpper) : 0;
3083cdf0e10cSrcweir         if( !pTmpFtn )
3084cdf0e10cSrcweir         {
3085cdf0e10cSrcweir             ASSERT( pNewUpper->IsFtnContFrm(), "Neuer Upper kein FtnCont.");
3086cdf0e10cSrcweir             SwFtnContFrm *pCont = (SwFtnContFrm*)pNewUpper;
3087cdf0e10cSrcweir 
3088cdf0e10cSrcweir             //Fussnote erzeugen.
3089cdf0e10cSrcweir             SwFtnFrm *pOld = FindFtnFrm();
3090cdf0e10cSrcweir             pTmpFtn = new SwFtnFrm( pOld->GetFmt()->GetDoc()->GetDfltFrmFmt(),
3091cdf0e10cSrcweir                                     pOld, pOld->GetRef(), pOld->GetAttr() );
3092cdf0e10cSrcweir             //Verkettung der Fussnoten.
3093cdf0e10cSrcweir             if ( pOld->GetFollow() )
3094cdf0e10cSrcweir             {
3095cdf0e10cSrcweir                 pTmpFtn->SetFollow( pOld->GetFollow() );
3096cdf0e10cSrcweir                 pOld->GetFollow()->SetMaster( pTmpFtn );
3097cdf0e10cSrcweir             }
3098cdf0e10cSrcweir             pOld->SetFollow( pTmpFtn );
3099cdf0e10cSrcweir             pTmpFtn->SetMaster( pOld );
3100cdf0e10cSrcweir             SwFrm* pNx = pCont->Lower();
3101cdf0e10cSrcweir             if( pNx && pTmpFtn->GetAttr()->GetFtn().IsEndNote() )
3102cdf0e10cSrcweir                 while(pNx && !((SwFtnFrm*)pNx)->GetAttr()->GetFtn().IsEndNote())
3103cdf0e10cSrcweir                     pNx = pNx->GetNext();
3104cdf0e10cSrcweir             pTmpFtn->Paste( pCont, pNx );
3105cdf0e10cSrcweir             pTmpFtn->Calc();
3106cdf0e10cSrcweir         }
3107cdf0e10cSrcweir         ASSERT( pTmpFtn->GetAttr() == FindFtnFrm()->GetAttr(), "Wrong Footnote!" );
3108cdf0e10cSrcweir         // Bereiche in Fussnoten beduerfen besonderer Behandlung
3109cdf0e10cSrcweir         SwLayoutFrm *pNewUp = pTmpFtn;
3110cdf0e10cSrcweir         if( IsInSct() )
3111cdf0e10cSrcweir         {
3112cdf0e10cSrcweir             SwSectionFrm* pSect = FindSctFrm();
3113cdf0e10cSrcweir             // Bereich in Fussnote (oder nur Fussnote in Bereich)?
3114cdf0e10cSrcweir             if( pSect->IsInFtn() )
3115cdf0e10cSrcweir             {
3116cdf0e10cSrcweir                 if( pTmpFtn->Lower() && pTmpFtn->Lower()->IsSctFrm() &&
3117cdf0e10cSrcweir                     pSect->GetFollow() == (SwSectionFrm*)pTmpFtn->Lower() )
3118cdf0e10cSrcweir                     pNewUp = (SwSectionFrm*)pTmpFtn->Lower();
3119cdf0e10cSrcweir                 else
3120cdf0e10cSrcweir                 {
3121cdf0e10cSrcweir                     pNewUp = new SwSectionFrm( *pSect, sal_False );
3122cdf0e10cSrcweir                     pNewUp->InsertBefore( pTmpFtn, pTmpFtn->Lower() );
3123cdf0e10cSrcweir                     static_cast<SwSectionFrm*>(pNewUp)->Init();
3124cdf0e10cSrcweir                     pNewUp->Frm().Pos() = pTmpFtn->Frm().Pos();
3125cdf0e10cSrcweir                     pNewUp->Frm().Pos().Y() += 1; //wg. Benachrichtigungen.
3126cdf0e10cSrcweir 
3127cdf0e10cSrcweir                     // Wenn unser Bereichsframe einen Nachfolger hat, so muss dieser
3128cdf0e10cSrcweir                     // umgehaengt werden hinter den neuen Follow der Bereichsframes.
3129cdf0e10cSrcweir                     SwFrm* pTmp = pSect->GetNext();
3130cdf0e10cSrcweir                     if( pTmp )
3131cdf0e10cSrcweir                     {
3132cdf0e10cSrcweir                         SwFlowFrm* pTmpNxt;
3133cdf0e10cSrcweir                         if( pTmp->IsCntntFrm() )
3134cdf0e10cSrcweir                             pTmpNxt = (SwCntntFrm*)pTmp;
3135cdf0e10cSrcweir                         else if( pTmp->IsSctFrm() )
3136cdf0e10cSrcweir                             pTmpNxt = (SwSectionFrm*)pTmp;
3137cdf0e10cSrcweir                         else
3138cdf0e10cSrcweir                         {
3139cdf0e10cSrcweir                             ASSERT( pTmp->IsTabFrm(), "GetNextSctLeaf: Wrong Type" );
3140cdf0e10cSrcweir                             pTmpNxt = (SwTabFrm*)pTmp;
3141cdf0e10cSrcweir                         }
3142cdf0e10cSrcweir                         pTmpNxt->MoveSubTree( pTmpFtn, pNewUp->GetNext() );
3143cdf0e10cSrcweir                     }
3144cdf0e10cSrcweir                 }
3145cdf0e10cSrcweir             }
3146cdf0e10cSrcweir         }
3147cdf0e10cSrcweir 
3148cdf0e10cSrcweir         MoveSubTree( pNewUp, pNewUp->Lower() );
3149cdf0e10cSrcweir 
3150cdf0e10cSrcweir         if( !bSameBoss )
3151cdf0e10cSrcweir             Prepare( PREP_BOSS_CHGD );
3152cdf0e10cSrcweir     }
3153cdf0e10cSrcweir     return bSamePage;
3154cdf0e10cSrcweir }
3155cdf0e10cSrcweir 
3156cdf0e10cSrcweir /*************************************************************************
3157cdf0e10cSrcweir |*
3158cdf0e10cSrcweir |*  class SwSaveFtnHeight
3159cdf0e10cSrcweir |*
3160cdf0e10cSrcweir |*************************************************************************/
3161cdf0e10cSrcweir 
3162cdf0e10cSrcweir 
SwSaveFtnHeight(SwFtnBossFrm * pBs,const SwTwips nDeadLine)3163cdf0e10cSrcweir SwSaveFtnHeight::SwSaveFtnHeight( SwFtnBossFrm *pBs, const SwTwips nDeadLine ) :
3164cdf0e10cSrcweir     pBoss( pBs ),
3165cdf0e10cSrcweir     nOldHeight( pBs->GetMaxFtnHeight() )
3166cdf0e10cSrcweir {
3167cdf0e10cSrcweir     pBoss->SetFtnDeadLine( nDeadLine );
3168cdf0e10cSrcweir     nNewHeight = pBoss->GetMaxFtnHeight();
3169cdf0e10cSrcweir }
3170cdf0e10cSrcweir 
3171cdf0e10cSrcweir 
3172cdf0e10cSrcweir 
~SwSaveFtnHeight()3173cdf0e10cSrcweir SwSaveFtnHeight::~SwSaveFtnHeight()
3174cdf0e10cSrcweir {
3175cdf0e10cSrcweir     //Wenn zwischendurch jemand an der DeadLine gedreht hat, so lassen wir
3176cdf0e10cSrcweir     //ihm seinen Spass!
3177cdf0e10cSrcweir     if ( nNewHeight == pBoss->GetMaxFtnHeight() )
3178cdf0e10cSrcweir         pBoss->nMaxFtnHeight = nOldHeight;
3179cdf0e10cSrcweir }
3180cdf0e10cSrcweir 
3181cdf0e10cSrcweir 
3182cdf0e10cSrcweir #ifdef DBG_UTIL
3183cdf0e10cSrcweir //JP 15.10.2001: in a non pro version test if the attribute has the same
3184cdf0e10cSrcweir //              meaning which his reference is
3185cdf0e10cSrcweir 
3186cdf0e10cSrcweir // Normally, the pRef member and the GetRefFromAttr() result has to be
3187cdf0e10cSrcweir // identically. Sometimes footnote will be moved from a master to its follow,
3188cdf0e10cSrcweir // but the GetRef() is called first, so we have to ignore a master/follow
3189cdf0e10cSrcweir // mismatch.
3190cdf0e10cSrcweir 
GetRef() const3191cdf0e10cSrcweir const SwCntntFrm* SwFtnFrm::GetRef() const
3192cdf0e10cSrcweir {
3193cdf0e10cSrcweir     const SwCntntFrm* pRefAttr = GetRefFromAttr();
3194cdf0e10cSrcweir     ASSERT( pRef == pRefAttr || pRef->IsAnFollow( pRefAttr )
3195cdf0e10cSrcweir             || pRefAttr->IsAnFollow( pRef ),
3196cdf0e10cSrcweir             "access to deleted Frame? pRef != pAttr->GetRef()" );
3197cdf0e10cSrcweir     return pRef;
3198cdf0e10cSrcweir }
3199cdf0e10cSrcweir 
GetRef()3200cdf0e10cSrcweir SwCntntFrm* SwFtnFrm::GetRef()
3201cdf0e10cSrcweir {
3202cdf0e10cSrcweir     const SwCntntFrm* pRefAttr = GetRefFromAttr();
3203cdf0e10cSrcweir     ASSERT( pRef == pRefAttr || pRef->IsAnFollow( pRefAttr )
3204cdf0e10cSrcweir             || pRefAttr->IsAnFollow( pRef ),
3205cdf0e10cSrcweir             "access to deleted Frame? pRef != pAttr->GetRef()" );
3206cdf0e10cSrcweir     return pRef;
3207cdf0e10cSrcweir }
3208cdf0e10cSrcweir 
3209cdf0e10cSrcweir #endif
3210cdf0e10cSrcweir 
GetRefFromAttr() const3211cdf0e10cSrcweir const SwCntntFrm* SwFtnFrm::GetRefFromAttr()  const
3212cdf0e10cSrcweir {
3213cdf0e10cSrcweir     SwFtnFrm* pThis = (SwFtnFrm*)this;
3214cdf0e10cSrcweir     return pThis->GetRefFromAttr();
3215cdf0e10cSrcweir }
3216cdf0e10cSrcweir 
GetRefFromAttr()3217cdf0e10cSrcweir SwCntntFrm* SwFtnFrm::GetRefFromAttr()
3218cdf0e10cSrcweir {
3219cdf0e10cSrcweir     ASSERT( pAttr, "invalid Attribute" );
3220cdf0e10cSrcweir     SwTxtNode& rTNd = (SwTxtNode&)pAttr->GetTxtNode();
3221cdf0e10cSrcweir     SwPosition aPos( rTNd, SwIndex( &rTNd, *pAttr->GetStart() ));
3222cdf0e10cSrcweir     SwCntntFrm* pCFrm = rTNd.getLayoutFrm( getRootFrm(), 0, &aPos, sal_False );
3223cdf0e10cSrcweir     return pCFrm;
3224cdf0e10cSrcweir }
3225cdf0e10cSrcweir 
3226cdf0e10cSrcweir /** search for last content in the current footnote frame
3227cdf0e10cSrcweir 
3228cdf0e10cSrcweir     OD 2005-12-02 #i27138#
3229cdf0e10cSrcweir 
3230cdf0e10cSrcweir     @author OD
3231cdf0e10cSrcweir */
FindLastCntnt()3232cdf0e10cSrcweir SwCntntFrm* SwFtnFrm::FindLastCntnt()
3233cdf0e10cSrcweir {
3234cdf0e10cSrcweir     SwCntntFrm* pLastCntntFrm( 0L );
3235cdf0e10cSrcweir 
3236cdf0e10cSrcweir     // find last lower, which is a content frame or contains content.
3237cdf0e10cSrcweir     // hidden text frames, empty sections and empty tables have to be skipped.
3238cdf0e10cSrcweir     SwFrm* pLastLowerOfFtn( GetLower() );
3239cdf0e10cSrcweir     SwFrm* pTmpLastLower( pLastLowerOfFtn );
3240cdf0e10cSrcweir     while ( pTmpLastLower && pTmpLastLower->GetNext() )
3241cdf0e10cSrcweir     {
3242cdf0e10cSrcweir         pTmpLastLower = pTmpLastLower->GetNext();
3243cdf0e10cSrcweir         if ( ( pTmpLastLower->IsTxtFrm() &&
3244cdf0e10cSrcweir                !static_cast<SwTxtFrm*>(pTmpLastLower)->IsHiddenNow() ) ||
3245cdf0e10cSrcweir              ( pTmpLastLower->IsSctFrm() &&
3246cdf0e10cSrcweir                static_cast<SwSectionFrm*>(pTmpLastLower)->GetSection() &&
3247cdf0e10cSrcweir                static_cast<SwSectionFrm*>(pTmpLastLower)->ContainsCntnt() ) ||
3248cdf0e10cSrcweir              ( pTmpLastLower->IsTabFrm() &&
3249cdf0e10cSrcweir                static_cast<SwTabFrm*>(pTmpLastLower)->ContainsCntnt() ) )
3250cdf0e10cSrcweir         {
3251cdf0e10cSrcweir             pLastLowerOfFtn = pTmpLastLower;
3252cdf0e10cSrcweir         }
3253cdf0e10cSrcweir     }
3254cdf0e10cSrcweir 
3255cdf0e10cSrcweir     // determine last content frame depending on type of found last lower.
3256cdf0e10cSrcweir     if ( pLastLowerOfFtn && pLastLowerOfFtn->IsTabFrm() )
3257cdf0e10cSrcweir     {
3258cdf0e10cSrcweir         pLastCntntFrm = static_cast<SwTabFrm*>(pLastLowerOfFtn)->FindLastCntnt();
3259cdf0e10cSrcweir     }
3260cdf0e10cSrcweir     else if ( pLastLowerOfFtn && pLastLowerOfFtn->IsSctFrm() )
3261cdf0e10cSrcweir     {
3262cdf0e10cSrcweir         pLastCntntFrm = static_cast<SwSectionFrm*>(pLastLowerOfFtn)->FindLastCntnt();
3263cdf0e10cSrcweir     }
3264cdf0e10cSrcweir     else
3265cdf0e10cSrcweir     {
3266cdf0e10cSrcweir         pLastCntntFrm = dynamic_cast<SwCntntFrm*>(pLastLowerOfFtn);
3267cdf0e10cSrcweir     }
3268cdf0e10cSrcweir 
3269cdf0e10cSrcweir     return pLastCntntFrm;
3270cdf0e10cSrcweir }
3271