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