1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sectfrm.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <svtools/itemiter.hxx>
39 #include <fmtclbl.hxx>
40 #include "sectfrm.hxx"
41 #include "section.hxx" // SwSection
42 #include "frmtool.hxx" // StackHack
43 #include "doc.hxx" // SwDoc
44 #include "cntfrm.hxx" // SwCntntFrm
45 #include "rootfrm.hxx" // SwRootFrm
46 #include "pagefrm.hxx" // SwPageFrm
47 #include "fmtpdsc.hxx" // SwFmtPageDesc
48 #include "fmtcntnt.hxx" // SwFmtCntnt
49 #include "ndindex.hxx" // SwNodeIndex
51 #include "txtfrm.hxx" // SwTxtFrm
52 #include "fmtclds.hxx" // SwFmtCol
53 #include "colfrm.hxx" // SwColumnFrm
54 #include "tabfrm.hxx" // SwTabFrm
55 #include "flyfrm.hxx" // SwFlyFrm
56 #include "ftnfrm.hxx" // SwFtnFrm
57 #include "layouter.hxx" // SwLayouter
58 #include "dbg_lay.hxx"
60 #include "viewimp.hxx"
61 #include <svx/ulspitem.hxx>
62 #include <svx/lrspitem.hxx>
63 #include <svx/brshitem.hxx>
64 #include <fmtftntx.hxx>
65 // OD 2004-05-24 #i28701#
66 #include <dflyobj.hxx>
67 #include <flyfrms.hxx>
68 #include <sortedobjs.hxx>
70 SV_IMPL_PTRARR_SORT( SwDestroyList
, SwSectionFrmPtr
)
72 /*************************************************************************
74 |* SwSectionFrm::SwSectionFrm(), ~SwSectionFrm()
76 |* Ersterstellung AMA 26. Nov. 97
77 |* Letzte Aenderung AMA 26. Nov. 97
79 |*************************************************************************/
80 SwSectionFrm::SwSectionFrm( SwSection
&rSect
) :
81 SwLayoutFrm( rSect
.GetFmt() ),
82 SwFlowFrm( (SwFrm
&)*this ),
91 SwSectionFrm::SwSectionFrm( SwSectionFrm
&rSect
, BOOL bMaster
) :
92 SwLayoutFrm( rSect
.GetFmt() ),
93 SwFlowFrm( (SwFrm
&)*this ),
94 pSection( rSect
.GetSection() )
96 bFtnAtEnd
= rSect
.IsFtnAtEnd();
97 bEndnAtEnd
= rSect
.IsEndnAtEnd();
101 PROTOCOL( this, PROT_SECTION
, bMaster
? ACT_CREATE_MASTER
: ACT_CREATE_FOLLOW
, &rSect
)
105 if( rSect
.IsFollow() )
107 SwSectionFrm
* pMaster
= rSect
.FindMaster();
108 pMaster
->SetFollow( this );
112 rSect
.bIsFollow
= TRUE
;
118 SetFollow( rSect
.GetFollow() );
119 rSect
.SetFollow( this );
121 rSect
.SimpleFormat();
122 if( !rSect
.IsColLocked() )
123 rSect
.InvalidateSize();
127 // NOTE: call <SwSectionFrm::Init()> directly after creation of a new section
128 // frame and its insert in the layout.
129 void SwSectionFrm::Init()
131 ASSERT( GetUpper(), "SwSectionFrm::Init before insertion?!" );
133 long nWidth
= (GetUpper()->Prt().*fnRect
->fnGetWidth
)();
134 (Frm().*fnRect
->fnSetWidth
)( nWidth
);
135 (Frm().*fnRect
->fnSetHeight
)( 0 );
137 // #109700# LRSpace for sections
138 const SvxLRSpaceItem
& rLRSpace
= GetFmt()->GetLRSpace();
139 (Prt().*fnRect
->fnSetLeft
)( rLRSpace
.GetLeft() );
140 (Prt().*fnRect
->fnSetWidth
)( nWidth
- rLRSpace
.GetLeft() -
141 rLRSpace
.GetRight() );
142 (Prt().*fnRect
->fnSetHeight
)( 0 );
144 const SwFmtCol
&rCol
= GetFmt()->GetCol();
145 if( ( rCol
.GetNumCols() > 1 || IsAnyNoteAtEnd() ) && !IsInFtn() )
147 const SwFmtCol
*pOld
= Lower() ? &rCol
: new SwFmtCol
;
148 ChgColumns( *pOld
, rCol
, IsAnyNoteAtEnd() );
154 SwSectionFrm::~SwSectionFrm()
156 if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
158 SwRootFrm
*pRootFrm
= GetFmt()->GetDoc()->GetRootFrm();
160 pRootFrm
->RemoveFromList( this );
163 SwSectionFrm
*pMaster
= FindMaster();
166 PROTOCOL( this, PROT_SECTION
, ACT_DEL_FOLLOW
, pMaster
)
167 pMaster
->SetFollow( GetFollow() );
168 // Ein Master greift sich immer den Platz bis zur Unterkante seines
169 // Uppers. Wenn er keinen Follow mehr hat, kann er diesen ggf. wieder
170 // freigeben, deshalb wird die Size des Masters invalidiert.
172 pMaster
->InvalidateSize();
175 else if( HasFollow() )
177 PROTOCOL( this, PROT_SECTION
, ACT_DEL_MASTER
, GetFollow() )
178 GetFollow()->bIsFollow
= FALSE
;
184 /*************************************************************************
186 |* SwSectionFrm::DelEmpty()
188 |* Ersterstellung AMA 17. Dec. 97
189 |* Letzte Aenderung AMA 17. Dec. 97
191 |*************************************************************************/
192 void SwSectionFrm::DelEmpty( BOOL bRemove
)
196 ASSERT( !bRemove
, "Don't delete locked SectionFrms" );
199 SwFrm
* pUp
= GetUpper();
202 // --> OD 2005-12-01 #i27138#
203 // notify accessibility paragraphs objects about changed
204 // CONTENT_FLOWS_FROM/_TO relation.
205 // Relation CONTENT_FLOWS_FROM for current next paragraph will change
206 // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
208 ViewShell
* pViewShell( GetShell() );
209 if ( pViewShell
&& pViewShell
->GetLayout() &&
210 pViewShell
->GetLayout()->IsAnyShellAccessible() )
212 pViewShell
->InvalidateAccessibleParaFlowRelation(
213 dynamic_cast<SwTxtFrm
*>(FindNextCnt( true )),
214 dynamic_cast<SwTxtFrm
*>(FindPrevCnt( true )) );
222 SwSectionFrm
*pMaster
= FindMaster();
223 pMaster
->SetFollow( GetFollow() );
224 // Ein Master greift sich immer den Platz bis zur Unterkante seines
225 // Uppers. Wenn er keinen Follow mehr hat, kann er diesen ggf. wieder
226 // freigeben, deshalb wird die Size des Masters invalidiert.
227 if( !GetFollow() && !pMaster
->IsColLocked() )
228 pMaster
->InvalidateSize();
231 else if( HasFollow() )
232 GetFollow()->bIsFollow
= FALSE
;
237 // Wenn wir sowieso sofort zerstoert werden, brauchen/duerfen wir
238 // uns gar nicht erst in die Liste eintragen
240 { // Wenn wir bereits halbtot waren vor diesem DelEmpty, so
241 // stehen wir vermutlich auch in der Liste und muessen uns
244 GetFmt()->GetDoc()->GetRootFrm()->RemoveFromList( this );
247 GetFmt()->GetDoc()->GetRootFrm()->InsertEmptySct( this );
248 pSection
= NULL
; // damit ist allerdings eine Reanimierung quasi ausgeschlossen
252 /*************************************************************************
254 |* SwSectionFrm::Cut()
256 |* Ersterstellung AMA 02. Dec. 97
257 |* Letzte Aenderung AMA 02. Dec. 97
259 |*************************************************************************/
260 void SwSectionFrm::Cut()
265 void SwSectionFrm::_Cut( BOOL bRemove
)
267 ASSERT( GetUpper(), "Cut ohne Upper()." );
269 PROTOCOL( this, PROT_CUT
, 0, GetUpper() )
271 SwPageFrm
*pPage
= FindPageFrm();
272 InvalidatePage( pPage
);
273 SwFrm
*pFrm
= GetNext();
274 SwFrm
* pPrepFrm
= NULL
;
275 while( pFrm
&& pFrm
->IsSctFrm() && !((SwSectionFrm
*)pFrm
)->GetSection() )
276 pFrm
= pFrm
->GetNext();
278 { //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger
279 //berechnet der ist jetzt wo er der erste wird obsolete
280 pFrm
->_InvalidatePrt();
281 pFrm
->_InvalidatePos();
282 if( pFrm
->IsSctFrm() )
283 pFrm
= ((SwSectionFrm
*)pFrm
)->ContainsAny();
284 if ( pFrm
&& pFrm
->IsCntntFrm() )
286 pFrm
->InvalidatePage( pPage
);
287 if( IsInFtn() && !GetIndPrev() )
294 //Einer muss die Retusche uebernehmen: Vorgaenger oder Upper
295 if ( 0 != (pFrm
= GetPrev()) )
296 { pFrm
->SetRetouche();
297 pFrm
->Prepare( PREP_WIDOWS_ORPHANS
);
298 if ( pFrm
->IsCntntFrm() )
299 pFrm
->InvalidatePage( pPage
);
301 //Wenn ich der einzige FlowFrm in meinem Upper bin (war), so muss
302 //er die Retouche uebernehmen.
303 //Ausserdem kann eine Leerseite entstanden sein.
305 { SwRootFrm
*pRoot
= (SwRootFrm
*)pPage
->GetUpper();
306 pRoot
->SetSuperfluous();
307 GetUpper()->SetCompletePaint();
310 //Erst removen, dann Upper Shrinken.
311 SwLayoutFrm
*pUp
= GetUpper();
315 if( pUp
&& !pUp
->Lower() && pUp
->IsFtnFrm() && !pUp
->IsColLocked() &&
324 pPrepFrm
->Prepare( PREP_FTN
);
328 SwTwips nFrmHeight
= (Frm().*fnRect
->fnGetHeight
)();
333 (Frm().*fnRect
->fnSetHeight
)( 0 );
334 (Prt().*fnRect
->fnSetHeight
)( 0 );
336 pUp
->Shrink( nFrmHeight
);
341 /*************************************************************************
343 |* SwSectionFrm::Paste()
345 |* Ersterstellung AMA 04. Dec. 97
346 |* Letzte Aenderung AMA 04. Dec. 97
348 |*************************************************************************/
350 void SwSectionFrm::Paste( SwFrm
* pParent
, SwFrm
* pSibling
)
352 ASSERT( pParent
, "Kein Parent fuer Paste." );
353 ASSERT( pParent
->IsLayoutFrm(), "Parent ist CntntFrm." );
354 ASSERT( pParent
!= this, "Bin selbst der Parent." );
355 ASSERT( pSibling
!= this, "Bin mein eigener Nachbar." );
356 ASSERT( !GetPrev() && !GetUpper(),
357 "Bin noch irgendwo angemeldet." );
359 PROTOCOL( this, PROT_PASTE
, 0, GetUpper() )
361 //In den Baum einhaengen.
362 SwSectionFrm
* pSect
= pParent
->FindSctFrm();
363 // --> OD 2008-06-23 #156927#
364 // Assure that parent is not inside a table frame, which is inside the found section frame.
367 SwTabFrm
* pTableFrm
= pParent
->FindTabFrm();
369 pSect
->IsAnLower( pTableFrm
) )
377 if( pSect
&& HasToBreak( pSect
) )
379 if( pParent
->IsColBodyFrm() ) // handelt es sich um einen spaltigen Bereich
381 // Falls wir zufaellig am Ende einer Spalte stehen, muss pSibling
382 // auf den ersten Frame der naechsten Spalte zeigen, damit
383 // der Inhalt der naechsten Spalte von InsertGroup richtig in den
384 // neu angelegten pSect umgehaengt wird.
385 SwColumnFrm
*pCol
= (SwColumnFrm
*)pParent
->GetUpper();
386 while( !pSibling
&& 0 != ( pCol
= (SwColumnFrm
*)pCol
->GetNext() ) )
387 pSibling
= ((SwLayoutFrm
*)((SwColumnFrm
*)pCol
)->Lower())->Lower();
390 // Schlimmer noch: alle folgenden Spalteninhalte muessen
391 // an die pSibling-Kette angehaengt werden, damit sie
392 // mitgenommen werden.
393 SwFrm
*pTmp
= pSibling
;
394 while ( 0 != ( pCol
= (SwColumnFrm
*)pCol
->GetNext() ) )
396 while ( pTmp
->GetNext() )
397 pTmp
= pTmp
->GetNext();
398 SwFrm
* pSave
= ::SaveCntnt( pCol
);
399 ::RestoreCntnt( pSave
, pSibling
->GetUpper(), pTmp
, true );
404 pSect
= new SwSectionFrm( *((SwSectionFrm
*)pParent
)->GetSection() );
405 // Wenn pParent in zwei Teile zerlegt wird, so muss sein Follow am
406 // neuen, zweiten Teil angebracht werden.
407 pSect
->SetFollow( ((SwSectionFrm
*)pParent
)->GetFollow() );
408 ((SwSectionFrm
*)pParent
)->SetFollow( NULL
);
409 if( pSect
->GetFollow() )
410 pParent
->_InvalidateSize();
412 InsertGroupBefore( pParent
, pSibling
, pSect
);
414 (pSect
->*fnRect
->fnMakePos
)( pSect
->GetUpper(), pSect
->GetPrev(), TRUE
);
415 if( !((SwLayoutFrm
*)pParent
)->Lower() )
417 SwSectionFrm::MoveCntntAndDelete( (SwSectionFrm
*)pParent
, FALSE
);
422 InsertGroupBefore( pParent
, pSibling
, NULL
);
425 SwPageFrm
*pPage
= FindPageFrm();
426 InvalidatePage( pPage
);
430 pSibling
->_InvalidatePos();
431 pSibling
->_InvalidatePrt();
432 if ( pSibling
->IsCntntFrm() )
433 pSibling
->InvalidatePage( pPage
);
436 SwTwips nFrmHeight
= (Frm().*fnRect
->fnGetHeight
)();
438 pParent
->Grow( nFrmHeight
);
444 GetPrev()->InvalidateSize();
445 if ( GetPrev()->IsCntntFrm() )
446 GetPrev()->InvalidatePage( pPage
);
452 /*************************************************************************
454 |* SwSectionFrm::HasToBreak()
456 |* Hier wird entschieden, ob der this-SectionFrm den uebergebenen
457 |* (Section)Frm aufbrechen soll oder nicht.
458 |* Zunaechst werden uebergeordnete Bereiche immer aufgebrochen,
459 |* spaeter koennte man es einstellbar machen.
461 |* Ersterstellung AMA 12. Dec. 97
462 |* Letzte Aenderung AMA 12. Dec. 97
464 |*************************************************************************/
466 BOOL
SwSectionFrm::HasToBreak( const SwFrm
* pFrm
) const
468 if( !pFrm
->IsSctFrm() )
471 SwSectionFmt
*pTmp
= (SwSectionFmt
*)GetFmt();
472 // if( !pTmp->GetSect().GetValue() )
475 const SwFrmFmt
*pOtherFmt
= ((SwSectionFrm
*)pFrm
)->GetFmt();
478 pTmp
= pTmp
->GetParent();
481 if( pTmp
== pOtherFmt
)
483 } while( TRUE
); // ( pTmp->GetSect().GetValue() );
486 /*************************************************************************
488 |* SwSectionFrm::MergeNext()
490 |* Ersterstellung AMA 04. Dec. 97
491 |* Letzte Aenderung AMA 04. Dec. 97
493 |* Verschmilzt zwei SectionFrms, falls es sich um den
494 |* gleichen Bereich handelt.
495 |* Notwendig kann dies sein, wenn ein (Unter-)Bereich geloescht wird, der
496 |* einen anderen in zwei Teile zerlegt hatte.
498 |*************************************************************************/
500 void SwSectionFrm::MergeNext( SwSectionFrm
* pNxt
)
502 if( !pNxt
->IsJoinLocked() && GetSection() == pNxt
->GetSection() )
504 PROTOCOL( this, PROT_SECTION
, ACT_MERGE
, pNxt
)
506 SwFrm
* pTmp
= ::SaveCntnt( pNxt
);
509 SwFrm
* pLast
= Lower();
510 SwLayoutFrm
* pLay
= this;
513 while( pLast
->GetNext() )
514 pLast
= pLast
->GetNext();
515 if( pLast
->IsColumnFrm() )
516 { // Spalten jetzt mit BodyFrm
517 pLay
= (SwLayoutFrm
*)((SwLayoutFrm
*)pLast
)->Lower();
518 pLast
= pLay
->Lower();
520 while( pLast
->GetNext() )
521 pLast
= pLast
->GetNext();
524 ::RestoreCntnt( pTmp
, pLay
, pLast
, true );
526 SetFollow( pNxt
->GetFollow() );
527 pNxt
->SetFollow( NULL
);
528 pNxt
->bIsFollow
= FALSE
;
535 /*************************************************************************
537 |* SwSectionFrm::SplitSect()
539 |* Ersterstellung AMA 29. Apr. 99
540 |* Letzte Aenderung AMA 29. Apr. 99
542 |* Zerteilt einen SectionFrm in zwei Teile, der zweite Teil beginnt mit dem
543 |* uebergebenen Frame.
544 |* Benoetigt wird dies beim Einfuegen eines inneren Bereichs, weil innerhalb
545 |* von Rahmen oder Tabellenzellen das MoveFwd nicht den erwuenschten Effekt
548 |*************************************************************************/
550 BOOL
SwSectionFrm::SplitSect( SwFrm
* pFrm
, BOOL bApres
)
552 ASSERT( pFrm
, "SplitSect: Why?" );
553 SwFrm
* pOther
= bApres
? pFrm
->FindNext() : pFrm
->FindPrev();
556 SwSectionFrm
* pSect
= pOther
->FindSctFrm();
559 // Den Inhalt zur Seite stellen
560 SwFrm
* pSav
= ::SaveCntnt( this, bApres
? pOther
: pFrm
);
561 ASSERT( pSav
, "SplitSect: What's on?" );
563 { // Einen neuen SctFrm anlegen, nicht als Follow/Master
564 SwSectionFrm
* pNew
= new SwSectionFrm( *pSect
->GetSection() );
565 pNew
->InsertBehind( pSect
->GetUpper(), pSect
);
568 (pNew
->*fnRect
->fnMakePos
)( NULL
, pSect
, TRUE
);
569 // OD 25.03.2003 #108339# - restore content:
570 // determine layout frame for restoring content after the initialization
571 // of the section frame. In the section initialization the columns are
574 SwLayoutFrm
* pLay
= pNew
;
575 // Search for last layout frame, e.g. for columned sections.
576 while( pLay
->Lower() && pLay
->Lower()->IsLayoutFrm() )
577 pLay
= (SwLayoutFrm
*)pLay
->Lower();
578 ::RestoreCntnt( pSav
, pLay
, NULL
, true );
583 pNew
->SetFollow( GetFollow() );
591 /*************************************************************************
593 |* SwSectionFrm::MoveCntntAndDelete()
595 |* Ersterstellung AMA 29. Jan 99
596 |* Letzte Aenderung AMA 29. Jan 99
598 |* MoveCntnt wird zur Zerstoerung eines SectionFrms wg. Aufhebung oder
599 |* Verstecken des Bereichs gerufen, um den Inhalt umzuhaengen.
600 |* Wenn der SectionFrm keinen anderen aufbrach, so wird der Inhalt in
601 |* den Upper bewegt. Anderfalls wird der Inhalt in den anderen SectionFrm
602 |* umgehaengt, dieser muss ggf. gemergt werden.
604 |*************************************************************************/
605 // Wenn ein mehrspaltiger Bereich aufgehoben wird, muessen die ContentFrms
606 // invalidiert werden
608 void lcl_InvalidateInfFlags( SwFrm
* pFrm
, BOOL bInva
)
612 pFrm
->InvalidateInfFlags();
615 pFrm
->_InvalidatePos();
616 pFrm
->_InvalidateSize();
617 pFrm
->_InvalidatePrt();
619 if( pFrm
->IsLayoutFrm() )
620 lcl_InvalidateInfFlags( ((SwLayoutFrm
*)pFrm
)->GetLower(), FALSE
);
621 pFrm
= pFrm
->GetNext();
627 // Works like SwCntntFrm::ImplGetNextCntntFrm, but starts with a LayoutFrm
629 SwCntntFrm
* lcl_GetNextCntntFrm( const SwLayoutFrm
* pLay
, bool bFwd
)
633 if ( pLay
->GetNext() && pLay
->GetNext()->IsCntntFrm() )
634 return (SwCntntFrm
*)pLay
->GetNext();
638 if ( pLay
->GetPrev() && pLay
->GetPrev()->IsCntntFrm() )
639 return (SwCntntFrm
*)pLay
->GetPrev();
643 const SwFrm
* pFrm
= pLay
;
644 SwCntntFrm
*pCntntFrm
= 0;
645 BOOL bGoingUp
= TRUE
;
648 BOOL bGoingFwdOrBwd
= FALSE
, bGoingDown
= FALSE
;
650 bGoingDown
= !bGoingUp
&& ( 0 != ( p
= pFrm
->IsLayoutFrm() ? ((SwLayoutFrm
*)pFrm
)->Lower() : 0 ) );
653 bGoingFwdOrBwd
= ( 0 != ( p
= pFrm
->IsFlyFrm() ?
654 ( bFwd
? ((SwFlyFrm
*)pFrm
)->GetNextLink() : ((SwFlyFrm
*)pFrm
)->GetPrevLink() ) :
655 ( bFwd
? pFrm
->GetNext() :pFrm
->GetPrev() ) ) );
656 if ( !bGoingFwdOrBwd
)
658 bGoingUp
= (0 != (p
= pFrm
->GetUpper() ) );
664 bGoingUp
= !( bGoingFwdOrBwd
|| bGoingDown
);
666 if( !bFwd
&& bGoingDown
&& p
)
667 while ( p
->GetNext() )
671 } while ( 0 == (pCntntFrm
= (pFrm
->IsCntntFrm() ? (SwCntntFrm
*)pFrm
:0) ));
676 #define FIRSTLEAF( pLayFrm ) ( ( pLayFrm->Lower() && pLayFrm->Lower()->IsColumnFrm() )\
677 ? pLayFrm->GetNextLayoutLeaf() \
680 void SwSectionFrm::MoveCntntAndDelete( SwSectionFrm
* pDel
, BOOL bSave
)
682 BOOL bSize
= pDel
->Lower() && pDel
->Lower()->IsColumnFrm();
683 SwFrm
* pPrv
= pDel
->GetPrev();
684 SwLayoutFrm
* pUp
= pDel
->GetUpper();
685 // OD 27.03.2003 #i12711# - initialize local pointer variables.
686 SwSectionFrm
* pPrvSct
= NULL
;
687 SwSectionFrm
* pNxtSct
= NULL
;
688 SwSectionFmt
* pParent
= static_cast<SwSectionFmt
*>(pDel
->GetFmt())->GetParent();
689 if( pDel
->IsInTab() && pParent
)
691 SwTabFrm
*pTab
= pDel
->FindTabFrm();
692 // Wenn wir innerhalb einer Tabelle liegen, koennen wir nur Bereiche
693 // aufgebrochen haben, die ebenfalls innerhalb liegen, nicht etwa
694 // einen Bereich, der die gesamte Tabelle umfasst.
695 if( pTab
->IsInSct() && pParent
== pTab
->FindSctFrm()->GetFmt() )
698 // Wenn unser Format einen Parent besitzt, so haben wir vermutlich
699 // einen anderen SectionFrm aufgebrochen, dies muss geprueft werden,
700 // dazu besorgen wir uns zunaechst den vorhergehende und den nach-
701 // folgenden CntntFrm, mal sehen, ob diese in SectionFrms liegen.
702 // OD 27.03.2003 #i12711# - check, if previous and next section belonging
703 // together and can be joined, *not* only if deleted section contains content.
706 SwFrm
* pPrvCntnt
= lcl_GetNextCntntFrm( pDel
, false );
707 pPrvSct
= pPrvCntnt
? pPrvCntnt
->FindSctFrm() : NULL
;
708 SwFrm
* pNxtCntnt
= lcl_GetNextCntntFrm( pDel
, true );
709 pNxtSct
= pNxtCntnt
? pNxtCntnt
->FindSctFrm() : NULL
;
714 pPrvSct
= pNxtSct
= NULL
;
717 // Jetzt wird der Inhalt beseite gestellt und der Frame zerstoert
718 SwFrm
*pSave
= bSave
? ::SaveCntnt( pDel
) : NULL
;
720 if( pSave
&& pUp
->IsFtnFrm() )
722 bOldFtn
= ((SwFtnFrm
*)pUp
)->IsColLocked();
723 ((SwFtnFrm
*)pUp
)->ColLock();
725 pDel
->DelEmpty( TRUE
);
728 { // Hier wird die geeignete Einfuegeposition gesucht
729 if( pNxtSct
&& pNxtSct
->GetFmt() == pParent
)
730 { // Hier koennen wir uns am Anfang einfuegen
731 pUp
= FIRSTLEAF( pNxtSct
);
733 if( pPrvSct
&& !( pPrvSct
->GetFmt() == pParent
) )
734 pPrvSct
= NULL
; // damit nicht gemergt wird
736 else if( pPrvSct
&& pPrvSct
->GetFmt() == pParent
)
737 { // Wunderbar, hier koennen wir uns am Ende einfuegen
739 if( pUp
->Lower() && pUp
->Lower()->IsColumnFrm() )
741 pUp
= static_cast<SwLayoutFrm
*>(pUp
->GetLastLower());
742 // Der Body der letzten Spalte
743 pUp
= static_cast<SwLayoutFrm
*>(pUp
->Lower());
745 // damit hinter dem letzten eingefuegt wird
746 pPrv
= pUp
->GetLastLower();
747 pPrvSct
= NULL
; // damit nicht gemergt wird
752 { // Folgende Situationen: Vor und hinter dem zu loeschenden Bereich
753 // ist entweder die Bereichsgrenze des umfassenden Bereichs oder
754 // es schliesst ein anderer (Geschwister-)Bereich direkt an, der
755 // vom gleichen Parent abgeleitet ist.
756 // Dann gibt es (noch) keinen Teil unseres Parents, der den Inhalt
757 // aufnehmen kann,also bauen wir ihn uns.
758 pPrvSct
= new SwSectionFrm( *pParent
->GetSection() );
759 pPrvSct
->InsertBehind( pUp
, pPrv
);
762 (pPrvSct
->*fnRect
->fnMakePos
)( pUp
, pPrv
, TRUE
);
763 pUp
= FIRSTLEAF( pPrvSct
);
766 pPrvSct
= NULL
; // damit nicht gemergt wird
769 // Der Inhalt wird eingefuegt..
772 lcl_InvalidateInfFlags( pSave
, bSize
);
773 ::RestoreCntnt( pSave
, pUp
, pPrv
, true );
774 pUp
->FindPageFrm()->InvalidateCntnt();
776 ((SwFtnFrm
*)pUp
)->ColUnlock();
778 // jetzt koennen eventuell zwei Teile des uebergeordneten Bereich verschmelzen
779 if( pPrvSct
&& !pPrvSct
->IsJoinLocked() )
781 ASSERT( pNxtSct
, "MoveCntnt: No Merge" );
782 pPrvSct
->MergeNext( pNxtSct
);
786 void SwSectionFrm::MakeAll()
788 if ( IsJoinLocked() || IsColLocked() || StackHack::IsLocked() || StackHack::Count() > 50 )
790 if( !pSection
) // Durch DelEmpty
792 ASSERT( GetFmt()->GetDoc()->GetRootFrm()->IsInDelList( this ), "SectionFrm without Section" );
797 SWRECTFN( GetUpper() )
798 (this->*fnRect
->fnMakePos
)( GetUpper(), GetPrev(), FALSE
);
801 bValidSize
= bValidPos
= bValidPrtArea
= TRUE
;
804 LockJoin(); //Ich lass mich nicht unterwegs vernichten.
806 while( GetNext() && GetNext() == GetFollow() )
808 const SwFrm
* pFoll
= GetFollow();
809 MergeNext( (SwSectionFrm
*)GetNext() );
810 if( pFoll
== GetFollow() )
814 // OD 2004-03-15 #116561# - In online layout join the follows, if section
816 if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) &&
817 ( Grow( LONG_MAX
, true ) > 0 ) )
821 const SwFrm
* pFoll
= GetFollow();
822 MergeNext( GetFollow() );
823 if( pFoll
== GetFollow() )
828 // Ein Bereich mit Follow nimmt allen Platz bis zur Unterkante des Uppers
829 // in Anspruch. Bewegt er sich, so kann seine Groesse zu- oder abnehmen...
830 if( !bValidPos
&& ToMaximize( FALSE
) )
833 #if OSL_DEBUG_LEVEL > 1
834 const SwFmtCol
&rCol
= GetFmt()->GetCol();
837 SwLayoutFrm::MakeAll();
839 if( pSection
&& IsSuperfluous() )
843 BOOL
SwSectionFrm::ShouldBwdMoved( SwLayoutFrm
*, BOOL
, BOOL
& )
845 ASSERT( FALSE
, "Hups, wo ist meine Tarnkappe?" );
849 const SwSectionFmt
* SwSectionFrm::_GetEndSectFmt() const
851 const SwSectionFmt
*pFmt
= pSection
->GetFmt();
852 while( !pFmt
->GetEndAtTxtEnd().IsAtEnd() )
854 if( pFmt
->GetRegisteredIn()->ISA( SwSectionFmt
) )
855 pFmt
= (SwSectionFmt
*)pFmt
->GetRegisteredIn();
862 void lcl_FindCntntFrm( SwCntntFrm
* &rpCntntFrm
, SwFtnFrm
* &rpFtnFrm
,
863 SwFrm
* pFrm
, BOOL
&rbChkFtn
)
867 while( pFrm
->GetNext() )
868 pFrm
= pFrm
->GetNext();
869 while( !rpCntntFrm
&& pFrm
)
871 if( pFrm
->IsCntntFrm() )
872 rpCntntFrm
= (SwCntntFrm
*)pFrm
;
873 else if( pFrm
->IsLayoutFrm() )
875 if( pFrm
->IsFtnFrm() )
879 rpFtnFrm
= (SwFtnFrm
*)pFrm
;
880 rbChkFtn
= rpFtnFrm
->GetAttr()->GetFtn().IsEndNote();
884 lcl_FindCntntFrm( rpCntntFrm
, rpFtnFrm
,
885 ((SwLayoutFrm
*)pFrm
)->Lower(), rbChkFtn
);
887 pFrm
= pFrm
->GetPrev();
892 SwCntntFrm
*SwSectionFrm::FindLastCntnt( BYTE nMode
)
894 SwCntntFrm
*pRet
= NULL
;
895 SwFtnFrm
*pFtnFrm
= NULL
;
896 SwSectionFrm
*pSect
= this;
899 const SwSectionFmt
*pFmt
= IsEndnAtEnd() ? GetEndSectFmt() :
902 while( pSect
->HasFollow() )
903 pSect
= pSect
->GetFollow();
904 SwFrm
* pTmp
= pSect
->FindNext();
905 while( pTmp
&& pTmp
->IsSctFrm() &&
906 !((SwSectionFrm
*)pTmp
)->GetSection() )
907 pTmp
= pTmp
->FindNext();
908 if( pTmp
&& pTmp
->IsSctFrm() &&
909 ((SwSectionFrm
*)pTmp
)->IsDescendantFrom( pFmt
) )
910 pSect
= (SwSectionFrm
*)pTmp
;
915 BOOL bFtnFound
= nMode
== FINDMODE_ENDNOTE
;
918 lcl_FindCntntFrm( pRet
, pFtnFrm
, pSect
->Lower(), bFtnFound
);
919 if( pRet
|| !pSect
->IsFollow() || !nMode
||
920 ( FINDMODE_MYLAST
== nMode
&& this == pSect
) )
922 pSect
= pSect
->FindMaster();
924 if( ( nMode
== FINDMODE_ENDNOTE
) && pFtnFrm
)
925 pRet
= pFtnFrm
->ContainsCntnt();
929 BOOL
SwSectionFrm::CalcMinDiff( SwTwips
& rMinDiff
) const
931 if( ToMaximize( TRUE
) )
934 rMinDiff
= (GetUpper()->*fnRect
->fnGetPrtBottom
)();
935 rMinDiff
= (Frm().*fnRect
->fnBottomDist
)( rMinDiff
);
941 /*************************************************************************
943 * SwSectionFrm::CollectEndnotes( )
945 * Ersterstellung AMA 03. Nov 99
946 * Letzte Aenderung AMA 03. Nov 99
948 * CollectEndnotes looks for endnotes in the sectionfrm and his follows,
949 * the endnotes will cut off the layout and put into the array.
950 * If the first endnote is not a master-SwFtnFrm, the whole sectionfrm
951 * contains only endnotes and it is not necessary to collect them.
953 *************************************************************************/
955 SwFtnFrm
* lcl_FindEndnote( SwSectionFrm
* &rpSect
, BOOL
&rbEmpty
,
956 SwLayouter
*pLayouter
)
958 // if rEmpty is set, the rpSect is already searched
959 SwSectionFrm
* pSect
= rbEmpty
? rpSect
->GetFollow() : rpSect
;
962 ASSERT( (pSect
->Lower() && pSect
->Lower()->IsColumnFrm()) || pSect
->GetUpper()->IsFtnFrm(),
963 "InsertEndnotes: Where's my column?" );
965 // i73332: Columned section in endnote
966 SwColumnFrm
* pCol
= 0;
967 if(pSect
->Lower() && pSect
->Lower()->IsColumnFrm())
968 pCol
= (SwColumnFrm
*)pSect
->Lower();
970 while( pCol
) // check all columns
972 SwFtnContFrm
* pFtnCont
= pCol
->FindFtnCont();
975 SwFtnFrm
* pRet
= (SwFtnFrm
*)pFtnCont
->Lower();
976 while( pRet
) // look for endnotes
978 if( pRet
->GetAttr()->GetFtn().IsEndNote() )
980 if( pRet
->GetMaster() )
983 pLayouter
->CollectEndnote( pRet
);
988 return pRet
; // Found
990 pRet
= (SwFtnFrm
*)pRet
->GetNext();
993 pCol
= (SwColumnFrm
*)pCol
->GetNext();
996 pSect
= pLayouter
? pSect
->GetFollow() : NULL
;
1002 void lcl_ColumnRefresh( SwSectionFrm
* pSect
, BOOL bFollow
)
1006 BOOL bOldLock
= pSect
->IsColLocked();
1008 if( pSect
->Lower() && pSect
->Lower()->IsColumnFrm() )
1010 SwColumnFrm
*pCol
= (SwColumnFrm
*)pSect
->Lower();
1012 { pCol
->_InvalidateSize();
1013 pCol
->_InvalidatePos();
1014 ((SwLayoutFrm
*)pCol
)->Lower()->_InvalidateSize();
1015 pCol
->Calc(); // calculation of column and
1016 ((SwLayoutFrm
*)pCol
)->Lower()->Calc(); // body
1017 pCol
= (SwColumnFrm
*)pCol
->GetNext();
1023 pSect
= pSect
->GetFollow();
1029 void SwSectionFrm::CollectEndnotes( SwLayouter
* pLayouter
)
1031 ASSERT( IsColLocked(), "CollectEndnotes: You love the risk?" );
1032 // i73332: Section in footnode does not have columns!
1033 ASSERT( (Lower() && Lower()->IsColumnFrm()) || GetUpper()->IsFtnFrm(), "Where's my column?" );
1035 SwSectionFrm
* pSect
= this;
1037 BOOL bEmpty
= FALSE
;
1038 // pSect is the last sectionfrm without endnotes or the this-pointer
1039 // the first sectionfrm with endnotes may be destroyed, when the endnotes
1041 while( 0 != (pFtn
= lcl_FindEndnote( pSect
, bEmpty
, pLayouter
)) )
1042 pLayouter
->CollectEndnote( pFtn
);
1043 if( pLayouter
->HasEndnotes() )
1044 lcl_ColumnRefresh( this, TRUE
);
1047 /*************************************************************************
1049 |* SwSectionFrm::_CheckClipping( BOOL bGrow, BOOL bMaximize )
1051 |* Beschreibung: Passt die Groesse an die Umgebung an.
1052 |* Wer einen Follow oder Fussnoten besitzt, soll bis zur Unterkante
1053 |* des Uppers gehen (bMaximize).
1054 |* Niemand darf ueber den Upper hinausgehen, ggf. darf man versuchen (bGrow)
1055 |* seinen Upper zu growen.
1056 |* Wenn die Groesse veraendert werden musste, wird der Inhalt kalkuliert.
1058 |*************************************************************************/
1060 /// OD 18.09.2002 #100522#
1061 /// perform calculation of content, only if height has changed.
1062 void SwSectionFrm::_CheckClipping( BOOL bGrow
, BOOL bMaximize
)
1066 SwTwips nDeadLine
= (GetUpper()->*fnRect
->fnGetPrtBottom
)();
1067 if( bGrow
&& ( !IsInFly() || !GetUpper()->IsColBodyFrm() ||
1068 !FindFlyFrm()->IsLocked() ) )
1070 nDiff
= -(Frm().*fnRect
->fnBottomDist
)( nDeadLine
);
1072 nDiff
+= Undersize();
1075 long nAdd
= GetUpper()->Grow( nDiff
);
1076 if( bVert
&& !bRev
)
1082 nDiff
= -(Frm().*fnRect
->fnBottomDist
)( nDeadLine
);
1083 SetUndersized( !bMaximize
&& nDiff
>= 0 );
1084 const bool bCalc
= ( IsUndersized() || bMaximize
) &&
1086 (Prt().*fnRect
->fnGetTop
)() > (Frm().*fnRect
->fnGetHeight
)() );
1087 // OD 03.11.2003 #i19737# - introduce local variable <bExtraCalc> to indicate
1088 // that a calculation has to be done beside the value of <bCalc>.
1089 bool bExtraCalc
= false;
1090 if( !bCalc
&& !bGrow
&& IsAnyNoteAtEnd() && !IsInFtn() )
1092 SwSectionFrm
*pSect
= this;
1093 BOOL bEmpty
= FALSE
;
1094 SwLayoutFrm
* pFtn
= IsEndnAtEnd() ?
1095 lcl_FindEndnote( pSect
, bEmpty
, NULL
) : NULL
;
1098 pFtn
= pFtn
->FindFtnBossFrm();
1099 SwFrm
* pTmp
= FindLastCntnt( FINDMODE_LASTCNT
);
1100 // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
1101 if ( pTmp
&& pFtn
->IsBefore( pTmp
->FindFtnBossFrm() ) )
1104 else if( GetFollow() && !GetFollow()->ContainsAny() )
1107 if ( bCalc
|| bExtraCalc
)
1109 nDiff
= (*fnRect
->fnYDiff
)( nDeadLine
, (Frm().*fnRect
->fnGetTop
)() );
1113 nDeadLine
= (Frm().*fnRect
->fnGetTop
)();
1115 const Size
aOldSz( Prt().SSize() );
1116 long nTop
= (this->*fnRect
->fnGetTopMargin
)();
1117 (Frm().*fnRect
->fnSetBottom
)( nDeadLine
);
1118 nDiff
= (Frm().*fnRect
->fnGetHeight
)();
1121 (this->*fnRect
->fnSetYMargins
)( nTop
, 0 );
1123 // OD 18.09.2002 #100522#
1124 // Determine, if height has changed.
1125 // Note: In vertical layout the height equals the width value.
1126 bool bHeightChanged
= bVert
?
1127 (aOldSz
.Width() != Prt().Width()) :
1128 (aOldSz
.Height() != Prt().Height());
1129 // Wir haben zu guter Letzt noch einmal die Hoehe geaendert,
1130 // dann wird das innere Layout (Columns) kalkuliert und
1131 // der Inhalt ebenfalls.
1132 // OD 18.09.2002 #100522#
1133 // calculate content, only if height has changed.
1134 // OD 03.11.2003 #i19737# - restriction of content calculation too strong.
1135 // If an endnote has an incorrect position or a follow section contains
1136 // no content except footnotes/endnotes, the content has also been calculated.
1137 if ( ( bHeightChanged
|| bExtraCalc
) && Lower() )
1139 if( Lower()->IsColumnFrm() )
1141 lcl_ColumnRefresh( this, FALSE
);
1142 ::CalcCntnt( this );
1146 ChgLowersProp( aOldSz
);
1147 if( !bMaximize
&& !IsCntntLocked() )
1148 ::CalcCntnt( this );
1154 void SwSectionFrm::SimpleFormat()
1156 if ( IsJoinLocked() || IsColLocked() )
1158 // ASSERT( pFollow, "SimpleFormat: Follow required" );
1161 if( GetPrev() || GetUpper() )
1163 (this->*fnRect
->fnMakePos
)( GetUpper(), GetPrev(), FALSE
);
1166 SwTwips nDeadLine
= (GetUpper()->*fnRect
->fnGetPrtBottom
)();
1167 // OD 22.10.2002 #97265# - call always method <lcl_ColumnRefresh(..)>, in
1168 // order to get calculated lowers, not only if there space left in its upper.
1169 if( (Frm().*fnRect
->fnBottomDist
)( nDeadLine
) >= 0 )
1171 (Frm().*fnRect
->fnSetBottom
)( nDeadLine
);
1172 long nHeight
= (Frm().*fnRect
->fnGetHeight
)();
1173 long nTop
= CalcUpperSpace();
1174 if( nTop
> nHeight
)
1176 (this->*fnRect
->fnSetYMargins
)( nTop
, 0 );
1178 lcl_ColumnRefresh( this, FALSE
);
1182 // --> OD 2005-01-11 #i40147# - helper class to perform extra section format
1183 // to position anchored objects and to keep the position of whose objects locked.
1184 class ExtraFormatToPositionObjs
1187 SwSectionFrm
* mpSectFrm
;
1188 bool mbExtraFormatPerformed
;
1191 ExtraFormatToPositionObjs( SwSectionFrm
& _rSectFrm
)
1192 : mpSectFrm( &_rSectFrm
),
1193 mbExtraFormatPerformed( false )
1196 ~ExtraFormatToPositionObjs()
1198 if ( mbExtraFormatPerformed
)
1200 // release keep locked position of lower floating screen objects
1201 SwPageFrm
* pPageFrm
= mpSectFrm
->FindPageFrm();
1202 SwSortedObjs
* pObjs
= pPageFrm
? pPageFrm
->GetSortedObjs() : 0L;
1206 for ( i
= 0; i
< pObjs
->Count(); ++i
)
1208 SwAnchoredObject
* pAnchoredObj
= (*pObjs
)[i
];
1210 if ( mpSectFrm
->IsAnLower( pAnchoredObj
->GetAnchorFrm() ) )
1212 pAnchoredObj
->SetKeepPosLocked( false );
1219 // --> OD 2008-06-20 #i81555#
1220 void InitObjs( SwFrm
& rFrm
)
1222 SwSortedObjs
* pObjs
= rFrm
.GetDrawObjs();
1226 for ( i
= 0; i
< pObjs
->Count(); ++i
)
1228 SwAnchoredObject
* pAnchoredObj
= (*pObjs
)[i
];
1230 pAnchoredObj
->UnlockPosition();
1231 pAnchoredObj
->SetClearedEnvironment( false );
1234 SwLayoutFrm
* pLayoutFrm
= dynamic_cast<SwLayoutFrm
*>(&rFrm
);
1235 if ( pLayoutFrm
!= 0 )
1237 SwFrm
* pLowerFrm
= pLayoutFrm
->GetLower();
1238 while ( pLowerFrm
!= 0 )
1240 InitObjs( *pLowerFrm
);
1242 pLowerFrm
= pLowerFrm
->GetNext();
1248 void FormatSectionToPositionObjs()
1250 // perform extra format for multi-columned section.
1251 if ( mpSectFrm
->Lower() && mpSectFrm
->Lower()->IsColumnFrm() &&
1252 mpSectFrm
->Lower()->GetNext() )
1254 // grow section till bottom of printing area of upper frame
1255 SWRECTFN( mpSectFrm
);
1256 SwTwips nTopMargin
= (mpSectFrm
->*fnRect
->fnGetTopMargin
)();
1257 Size
aOldSectPrtSize( mpSectFrm
->Prt().SSize() );
1258 SwTwips nDiff
= (mpSectFrm
->Frm().*fnRect
->fnBottomDist
)(
1259 (mpSectFrm
->GetUpper()->*fnRect
->fnGetPrtBottom
)() );
1260 (mpSectFrm
->Frm().*fnRect
->fnAddBottom
)( nDiff
);
1261 (mpSectFrm
->*fnRect
->fnSetYMargins
)( nTopMargin
, 0 );
1262 // --> OD 2006-05-08 #i59789#
1263 // suppress formatting, if printing area of section is too narrow
1264 if ( (mpSectFrm
->Prt().*fnRect
->fnGetHeight
)() <= 0 )
1269 mpSectFrm
->ChgLowersProp( aOldSectPrtSize
);
1271 // format column frames and its body and footnote container
1272 SwColumnFrm
* pColFrm
= static_cast<SwColumnFrm
*>(mpSectFrm
->Lower());
1276 pColFrm
->Lower()->Calc();
1277 if ( pColFrm
->Lower()->GetNext() )
1279 pColFrm
->Lower()->GetNext()->Calc();
1282 pColFrm
= static_cast<SwColumnFrm
*>(pColFrm
->GetNext());
1285 // unlock position of lower floating screen objects for the extra format
1286 // --> OD 2008-06-20 #i81555#
1287 // Section frame can already have changed the page and its content
1288 // can still be on the former page.
1289 // Thus, initialize objects via lower-relationship
1290 InitObjs( *mpSectFrm
);
1293 // format content - first with collecting its foot-/endnotes before content
1294 // format, second without collecting its foot-/endnotes.
1295 ::CalcCntnt( mpSectFrm
);
1296 ::CalcCntnt( mpSectFrm
, true );
1298 // keep locked position of lower floating screen objects
1299 SwPageFrm
* pPageFrm
= mpSectFrm
->FindPageFrm();
1300 SwSortedObjs
* pObjs
= pPageFrm
? pPageFrm
->GetSortedObjs() : 0L;
1304 for ( i
= 0; i
< pObjs
->Count(); ++i
)
1306 SwAnchoredObject
* pAnchoredObj
= (*pObjs
)[i
];
1308 if ( mpSectFrm
->IsAnLower( pAnchoredObj
->GetAnchorFrm() ) )
1310 pAnchoredObj
->SetKeepPosLocked( true );
1315 mbExtraFormatPerformed
= true;
1320 /*************************************************************************
1322 |* SwSectionFrm::Format()
1324 |* Beschreibung: "Formatiert" den Frame; Frm und PrtArea.
1325 |* Ersterstellung AMA 03. Dec. 97
1326 |* Letzte Aenderung MA 09. Oct. 98
1328 |*************************************************************************/
1330 void SwSectionFrm::Format( const SwBorderAttrs
*pAttr
)
1332 if( !pSection
) // Durch DelEmpty
1334 ASSERT( GetFmt()->GetDoc()->GetRootFrm()->IsInDelList( this ),
1335 "SectionFrm without Section" );
1336 bValidSize
= bValidPos
= bValidPrtArea
= TRUE
;
1340 if ( !bValidPrtArea
)
1342 PROTOCOL( this, PROT_PRTAREA
, 0, 0 )
1343 bValidPrtArea
= TRUE
;
1344 SwTwips nUpper
= CalcUpperSpace();
1346 // #109700# LRSpace for sections
1347 const SvxLRSpaceItem
& rLRSpace
= GetFmt()->GetLRSpace();
1348 (this->*fnRect
->fnSetXMargins
)( rLRSpace
.GetLeft(), rLRSpace
.GetRight() );
1350 if( nUpper
!= (this->*fnRect
->fnGetTopMargin
)() )
1353 SwFrm
* pOwn
= ContainsAny();
1355 pOwn
->_InvalidatePos();
1357 (this->*fnRect
->fnSetYMargins
)( nUpper
, 0 );
1362 PROTOCOL_ENTER( this, PROT_SIZE
, 0, 0 )
1363 const long nOldHeight
= (Frm().*fnRect
->fnGetHeight
)();
1364 BOOL bOldLock
= IsColLocked();
1369 //die Groesse wird nur dann vom Inhalt bestimmt, wenn der SectFrm
1370 //keinen Follow hat. Anderfalls fuellt er immer den Upper bis
1371 //zur Unterkante aus. Fuer den Textfluss ist nicht er, sondern sein
1372 //Inhalt selbst verantwortlich.
1373 BOOL bMaximize
= ToMaximize( FALSE
);
1375 // OD 2004-05-17 #i28701# - If the wrapping style has to be considered
1376 // on object positioning, an extra formatting has to be performed
1377 // to determine the correct positions the floating screen objects.
1378 // --> OD 2005-01-11 #i40147#
1379 // use new helper class <ExtraFormatToPositionObjs>.
1380 // This class additionally keep the locked position of the objects
1381 // and releases this position lock keeping on destruction.
1382 ExtraFormatToPositionObjs
aExtraFormatToPosObjs( *this );
1384 GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION
) &&
1385 !GetFmt()->GetBalancedColumns().GetValue() )
1387 aExtraFormatToPosObjs
.FormatSectionToPositionObjs();
1391 // Column widths have to be adjusted before calling _CheckClipping.
1392 // _CheckClipping can cause the formatting of the lower frames
1393 // which still have a width of 0.
1394 const sal_Bool bHasColumns
= Lower() && Lower()->IsColumnFrm();
1395 if ( bHasColumns
&& Lower()->GetNext() )
1396 AdjustColumns( 0, FALSE
);
1400 long nWidth
= (GetUpper()->Prt().*fnRect
->fnGetWidth
)();
1401 (aFrm
.*fnRect
->fnSetWidth
)( nWidth
);
1403 // #109700# LRSpace for sections
1404 const SvxLRSpaceItem
& rLRSpace
= GetFmt()->GetLRSpace();
1405 (aPrt
.*fnRect
->fnSetWidth
)( nWidth
- rLRSpace
.GetLeft() -
1406 rLRSpace
.GetRight() );
1408 // OD 15.10.2002 #103517# - allow grow in online layout
1409 // Thus, set <..IsBrowseMode()> as parameter <bGrow> on calling
1410 // method <_CheckClipping(..)>.
1411 _CheckClipping( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
), bMaximize
);
1412 bMaximize
= ToMaximize( FALSE
);
1416 //Breite der Spalten pruefen und ggf. einstellen.
1417 if ( bHasColumns
&& ! Lower()->GetNext() && bMaximize
)
1418 ((SwColumnFrm
*)Lower())->Lower()->Calc();
1422 SwTwips nRemaining
= (this->*fnRect
->fnGetTopMargin
)();
1423 SwFrm
*pFrm
= pLower
;
1426 if( pFrm
->IsColumnFrm() && pFrm
->GetNext() )
1428 // --> OD 2006-05-08 #i61435#
1429 // suppress formatting, if upper frame has height <= 0
1430 if ( (GetUpper()->Frm().*fnRect
->fnGetHeight
)() > 0 )
1432 FormatWidthCols( *pAttr
, nRemaining
, MINLAY
);
1435 // --> OD 2006-01-04 #126020# - adjust check for empty section
1436 // --> OD 2006-02-01 #130797# - correct fix #126020#
1437 while( HasFollow() && !GetFollow()->ContainsCntnt() &&
1438 !GetFollow()->ContainsAny( true ) )
1441 SwFrm
* pOld
= GetFollow();
1442 GetFollow()->DelEmpty( FALSE
);
1443 if( pOld
== GetFollow() )
1446 bMaximize
= ToMaximize( FALSE
);
1447 nRemaining
+= (pFrm
->Frm().*fnRect
->fnGetHeight
)();
1451 if( pFrm
->IsColumnFrm() )
1454 pFrm
= ((SwColumnFrm
*)pFrm
)->Lower();
1456 pFrm
= ((SwLayoutFrm
*)pFrm
)->Lower();
1459 // Wenn wir in einem spaltigen Rahmen stehen und dieser
1460 // gerade im FormatWidthCols ein CalcCntnt ruft, muss
1461 // unser Inhalt ggf. kalkuliert werden.
1462 if( pFrm
&& !pFrm
->IsValid() && IsInFly() &&
1463 FindFlyFrm()->IsColLocked() )
1464 ::CalcCntnt( this );
1465 nRemaining
+= InnerHeight();
1466 bMaximize
= HasFollow();
1470 SwTwips nDiff
= (Frm().*fnRect
->fnGetHeight
)() - nRemaining
;
1473 SwTwips nDeadLine
= (GetUpper()->*fnRect
->fnGetPrtBottom
)();
1475 long nBottom
= (Frm().*fnRect
->fnGetBottom
)();
1476 nBottom
= (*fnRect
->fnYInc
)( nBottom
, -nDiff
);
1477 long nTmpDiff
= (*fnRect
->fnYDiff
)( nBottom
, nDeadLine
);
1480 nTmpDiff
= GetUpper()->Grow( nTmpDiff
, TRUE
);
1481 nDeadLine
= (*fnRect
->fnYInc
)( nDeadLine
, nTmpDiff
);
1482 nTmpDiff
= (*fnRect
->fnYDiff
)( nBottom
, nDeadLine
);
1492 long nTmp
= nRemaining
- (Frm().*fnRect
->fnGetHeight
)();
1493 long nTop
= (this->*fnRect
->fnGetTopMargin
)();
1494 (Frm().*fnRect
->fnAddBottom
)( nTmp
);
1495 (this->*fnRect
->fnSetYMargins
)( nTop
, 0 );
1496 InvalidateNextPos();
1497 if( pLower
&& ( !pLower
->IsColumnFrm() || !pLower
->GetNext() ) )
1499 // Wenn ein einspaltiger Bereich gerade den Platz geschaffen
1500 // hat, den sich die "undersized" Absaetze gewuenscht haben,
1501 // muessen diese invalidiert und kalkuliert werden, damit
1502 // sie diesen ausfuellen.
1504 if( pFrm
->IsColumnFrm() )
1506 pFrm
->_InvalidateSize();
1507 pFrm
->_InvalidatePos();
1509 pFrm
= ((SwColumnFrm
*)pFrm
)->Lower();
1511 pFrm
= ((SwLayoutFrm
*)pFrm
)->Lower();
1514 BOOL bUnderSz
= FALSE
;
1517 if( pFrm
->IsTxtFrm() && ((SwTxtFrm
*)pFrm
)->IsUndersized() )
1519 pFrm
->Prepare( PREP_ADJUST_FRM
);
1522 pFrm
= pFrm
->GetNext();
1524 if( bUnderSz
&& !IsCntntLocked() )
1525 ::CalcCntnt( this );
1530 //Unterkante des Uppers nicht ueberschreiten. Fuer Sections mit
1531 //Follows die Unterkante auch nicht unterschreiten.
1533 _CheckClipping( TRUE
, bMaximize
);
1536 long nDiff
= nOldHeight
- (Frm().*fnRect
->fnGetHeight
)();
1540 SetRetouche(); // Dann muessen wir die Retusche selbst uebernehmen
1541 if( GetUpper() && !GetUpper()->IsFooterFrm() )
1542 GetUpper()->Shrink( nDiff
);
1544 if( IsUndersized() )
1545 bValidPrtArea
= TRUE
;
1549 /*************************************************************************
1551 |* SwFrm::GetNextSctLeaf()
1553 |* Beschreibung Liefert das naechste Layoutblatt in das der Frame
1554 |* gemoved werden kann.
1555 |* Neue Seiten werden nur dann erzeugt, wenn der Parameter TRUE ist.
1556 |* Ersterstellung AMA 07. Jan. 98
1557 |* Letzte Aenderung AMA 07. Jan. 98
1559 |*************************************************************************/
1562 SwLayoutFrm
*SwFrm::GetNextSctLeaf( MakePageType eMakePage
)
1564 //Achtung: Geschachtelte Bereiche werden zur Zeit nicht unterstuetzt.
1566 PROTOCOL_ENTER( this, PROT_LEAF
, ACT_NEXT_SECT
, GetUpper()->FindSctFrm() )
1568 // Abkuerzungen fuer spaltige Bereiche, wenn wir noch nicht in der letzten Spalte sind.
1569 // Koennen wir in die naechste Spalte des Bereichs rutschen?
1570 if( IsColBodyFrm() && GetUpper()->GetNext() )
1571 return (SwLayoutFrm
*)((SwLayoutFrm
*)GetUpper()->GetNext())->Lower();
1572 if( GetUpper()->IsColBodyFrm() && GetUpper()->GetUpper()->GetNext() )
1573 return (SwLayoutFrm
*)((SwLayoutFrm
*)GetUpper()->GetUpper()->GetNext())->Lower();
1574 // Innerhalb von Bereichen in Tabellen oder Bereichen in Kopf/Fusszeilen kann
1575 // nur ein Spaltenwechsel erfolgen, eine der oberen Abkuerzungen haette zuschlagen muessen
1576 if( GetUpper()->IsInTab() || FindFooterOrHeader() )
1579 //MA 03. Feb. 99: Warum GetUpper()? Das knallt mit Buch.sgl weil im
1580 //FlyAtCnt::MakeFlyPos ein Orient der SectionFrm ist und auf diesen ein
1581 //GetLeaf gerufen wird.
1582 // SwSectionFrm *pSect = GetUpper()->FindSctFrm();
1583 SwSectionFrm
*pSect
= FindSctFrm();
1584 BOOL bWrongPage
= FALSE
;
1585 ASSERT( pSect
, "GetNextSctLeaf: Missing SectionFrm" );
1587 // Hier eine Abkuerzung fuer Bereiche mit Follows,
1588 // dieser kann akzeptiert werden, wenn keine Spalten oder Seiten (ausser Dummyseiten)
1589 // dazwischen liegen.
1590 // Bei verketteten Rahmen und ind Fussnoten wuerde die Abkuerzung noch aufwendiger
1591 if( pSect
->HasFollow() && pSect
->IsInDocBody() )
1593 if( pSect
->GetFollow() == pSect
->GetNext() )
1595 SwPageFrm
*pPg
= pSect
->GetFollow()->FindPageFrm();
1596 if( WrongPageDesc( pPg
) )
1599 return FIRSTLEAF( pSect
->GetFollow() );
1604 if( !pSect
->GetUpper()->IsColBodyFrm() ||
1605 0 == ( pTmp
= pSect
->GetUpper()->GetUpper()->GetNext() ) )
1606 pTmp
= pSect
->FindPageFrm()->GetNext();
1607 if( pTmp
) // ist jetzt die naechste Spalte oder Seite
1609 SwFrm
* pTmpX
= pTmp
;
1610 if( pTmp
->IsPageFrm() && ((SwPageFrm
*)pTmp
)->IsEmptyPage() )
1611 pTmp
= pTmp
->GetNext(); // Dummyseiten ueberspringen
1612 SwFrm
*pUp
= pSect
->GetFollow()->GetUpper();
1613 // pUp wird die Spalte, wenn der Follow in einer "nicht ersten" Spalte
1614 // liegt, ansonsten die Seite:
1615 if( !pUp
->IsColBodyFrm() ||
1616 !( pUp
= pUp
->GetUpper() )->GetPrev() )
1617 pUp
= pUp
->FindPageFrm();
1618 // Jetzt muessen pUp und pTmp die gleiche Seite/Spalte sein,
1619 // sonst liegen Seiten oder Spalten zwischen Master und Follow.
1620 if( pUp
== pTmp
|| pUp
->GetNext() == pTmpX
)
1622 SwPageFrm
* pNxtPg
= pUp
->IsPageFrm() ?
1623 (SwPageFrm
*)pUp
: pUp
->FindPageFrm();
1624 if( WrongPageDesc( pNxtPg
) )
1627 return FIRSTLEAF( pSect
->GetFollow() );
1633 // Immer im gleichen Bereich landen: Body wieder in Body etc.
1634 const BOOL bBody
= IsInDocBody();
1635 const BOOL bFtnPage
= FindPageFrm()->IsFtnPage();
1637 SwLayoutFrm
*pLayLeaf
;
1638 // Eine Abkuerzung fuer TabFrms, damit nicht alle Zellen abgehuehnert werden
1641 else if( IsTabFrm() )
1643 SwCntntFrm
* pTmpCnt
= ((SwTabFrm
*)this)->FindLastCntnt();
1644 pLayLeaf
= pTmpCnt
? pTmpCnt
->GetUpper() : 0;
1648 pLayLeaf
= GetNextLayoutLeaf();
1651 while( pLayLeaf
&& ((SwColumnFrm
*)this)->IsAnLower( pLayLeaf
) )
1652 pLayLeaf
= pLayLeaf
->GetNextLayoutLeaf();
1656 SwLayoutFrm
*pOldLayLeaf
= 0; //Damit bei neu erzeugten Seiten
1657 //nicht wieder vom Anfang gesucht
1664 // Ein Layoutblatt wurde gefunden, mal sehen, ob er mich aufnehmen kann,
1665 // ob hier ein weiterer SectionFrm eingefuegt werden kann
1666 // oder ob wir weitersuchen muessen.
1667 SwPageFrm
* pNxtPg
= pLayLeaf
->FindPageFrm();
1668 if ( !bFtnPage
&& pNxtPg
->IsFtnPage() )
1669 { //Wenn ich bei den Endnotenseiten angelangt bin hat sichs.
1673 // Einmal InBody, immer InBody, nicht in Tabellen hinein
1674 // und nicht in fremde Bereiche hinein
1675 if ( (bBody
&& !pLayLeaf
->IsInDocBody()) ||
1676 (IsInFtn() != pLayLeaf
->IsInFtn() ) ||
1677 pLayLeaf
->IsInTab() ||
1678 ( pLayLeaf
->IsInSct() && ( !pSect
->HasFollow()
1679 || pSect
->GetFollow() != pLayLeaf
->FindSctFrm() ) ) )
1681 //Er will mich nicht; neuer Versuch, neues Glueck
1682 pOldLayLeaf
= pLayLeaf
;
1683 pLayLeaf
= pLayLeaf
->GetNextLayoutLeaf();
1686 if( WrongPageDesc( pNxtPg
) )
1689 break; // there's a column between me and my right page
1696 //Es gibt keinen passenden weiteren LayoutFrm, also muss eine
1697 //neue Seite her, allerdings nuetzen uns innerhalb eines Rahmens
1698 //neue Seiten nichts.
1699 else if( !pSect
->IsInFly() &&
1700 ( eMakePage
== MAKEPAGE_APPEND
|| eMakePage
== MAKEPAGE_INSERT
) )
1702 InsertPage(pOldLayLeaf
? pOldLayLeaf
->FindPageFrm() : FindPageFrm(),
1704 //und nochmal das ganze
1705 pLayLeaf
= pOldLayLeaf
? pOldLayLeaf
: GetNextLayoutLeaf();
1713 // Das passende Layoutblatt haben wir gefunden, wenn es dort bereits einen
1714 // Follow unseres Bereichs gibt, nehmen wir dessen erstes Layoutblatt,
1715 // andernfalls wird es Zeit, einen Bereichsfollow zu erzeugen
1718 //Dies kann entfallen, wenn bei existierenden Follows bereits abgekuerzt wurde
1719 SwFrm
* pFirst
= pLayLeaf
->Lower();
1720 // Auch hier muessen zum Loeschen angemeldete SectionFrms ignoriert werden
1721 while( pFirst
&& pFirst
->IsSctFrm() && !((SwSectionFrm
*)pFirst
)->GetSection() )
1722 pFirst
= pFirst
->GetNext();
1723 if( pFirst
&& pFirst
->IsSctFrm() && pSect
->GetFollow() == pFirst
)
1724 pNew
= pSect
->GetFollow();
1725 else if( MAKEPAGE_NOSECTION
== eMakePage
)
1729 pNew
= new SwSectionFrm( *pSect
, FALSE
);
1730 pNew
->InsertBefore( pLayLeaf
, pLayLeaf
->Lower() );
1733 (pNew
->*fnRect
->fnMakePos
)( pLayLeaf
, NULL
, TRUE
);
1735 // Wenn unser Bereichsframe einen Nachfolger hat, so muss dieser
1736 // umgehaengt werden hinter den neuen Follow der Bereichsframes.
1737 SwFrm
* pTmp
= pSect
->GetNext();
1738 if( pTmp
&& pTmp
!= pSect
->GetFollow() )
1741 SwCntntFrm
* pNxtCntnt
= NULL
;
1742 if( pTmp
->IsCntntFrm() )
1744 pNxt
= (SwCntntFrm
*)pTmp
;
1745 pNxtCntnt
= (SwCntntFrm
*)pTmp
;
1749 pNxtCntnt
= ((SwLayoutFrm
*)pTmp
)->ContainsCntnt();
1750 if( pTmp
->IsSctFrm() )
1751 pNxt
= (SwSectionFrm
*)pTmp
;
1754 ASSERT( pTmp
->IsTabFrm(), "GetNextSctLeaf: Wrong Type" );
1755 pNxt
= (SwTabFrm
*)pTmp
;
1757 while( !pNxtCntnt
&& 0 != ( pTmp
= pTmp
->GetNext() ) )
1759 if( pTmp
->IsCntntFrm() )
1760 pNxtCntnt
= (SwCntntFrm
*)pTmp
;
1762 pNxtCntnt
= ((SwLayoutFrm
*)pTmp
)->ContainsCntnt();
1767 SwFtnBossFrm
* pOldBoss
= pSect
->FindFtnBossFrm( TRUE
);
1768 if( pOldBoss
== pNxtCntnt
->FindFtnBossFrm( TRUE
) )
1770 SwSaveFtnHeight
aHeight( pOldBoss
,
1771 pOldBoss
->Frm().Top() + pOldBoss
->Frm().Height() );
1772 pSect
->GetUpper()->MoveLowerFtns( pNxtCntnt
, pOldBoss
,
1773 pLayLeaf
->FindFtnBossFrm( TRUE
), FALSE
);
1776 ((SwFlowFrm
*)pNxt
)->MoveSubTree( pLayLeaf
, pNew
->GetNext() );
1778 if( pNew
->GetFollow() )
1779 pNew
->SimpleFormat();
1781 // Das gesuchte Layoutblatt ist jetzt das erste des ermittelten SctFrms:
1782 pLayLeaf
= FIRSTLEAF( pNew
);
1787 /*************************************************************************
1789 |* SwFrm::GetPrevSctLeaf()
1791 |* Beschreibung Liefert das vorhergehende LayoutBlatt in das der
1792 |* Frame gemoved werden kann.
1793 |* Ersterstellung AMA 07. Jan. 98
1794 |* Letzte Aenderung AMA 07. Jan. 98
1796 |*************************************************************************/
1799 SwLayoutFrm
*SwFrm::GetPrevSctLeaf( MakePageType
)
1801 PROTOCOL_ENTER( this, PROT_LEAF
, ACT_PREV_SECT
, GetUpper()->FindSctFrm() )
1804 // ColumnFrm beinhalten jetzt stets einen BodyFrm
1805 if( IsColBodyFrm() )
1807 else if( GetUpper()->IsColBodyFrm() )
1808 pCol
= GetUpper()->GetUpper();
1814 if( pCol
->GetPrev() )
1818 pCol
= (SwLayoutFrm
*)pCol
->GetPrev();
1819 // Gibt es dort Inhalt?
1820 if( ((SwLayoutFrm
*)pCol
->Lower())->Lower() )
1822 if( bJump
) // Haben wir eine leere Spalte uebersprungen?
1823 SwFlowFrm::SetMoveBwdJump( TRUE
);
1824 return (SwLayoutFrm
*)pCol
->Lower(); // Der Spaltenbody
1827 } while( pCol
->GetPrev() );
1829 // Hier landen wir, wenn alle Spalten leer sind,
1830 // pCol ist jetzt die erste Spalte, wir brauchen aber den Body:
1831 pCol
= (SwLayoutFrm
*)pCol
->Lower();
1837 if( bJump
) // Haben wir eine leere Spalte uebersprungen?
1838 SwFlowFrm::SetMoveBwdJump( TRUE
);
1840 // Innerhalb von Bereichen in Tabellen oder Bereichen in Kopf/Fusszeilen kann
1841 // nur ein Spaltenwechsel erfolgen, eine der oberen Abkuerzungen haette
1842 // zuschlagen muessen, ebenso wenn der Bereich einen pPrev hat.
1843 // Jetzt ziehen wir sogar eine leere Spalte in Betracht...
1844 ASSERT( FindSctFrm(), "GetNextSctLeaf: Missing SectionFrm" );
1845 if( ( IsInTab() && !IsTabFrm() ) || FindFooterOrHeader() )
1848 // === IMPORTANT ===
1849 // Precondition, which needs to be hold, is that the <this> frame can be
1850 // inside a table, but then the found section frame <pSect> is also inside
1852 SwSectionFrm
*pSect
= FindSctFrm();
1854 // --> OD 2009-01-16 #i95698#
1855 // A table cell containing directly a section does not break - see lcl_FindSectionsInRow(..)
1856 // Thus, a table inside a section, which is inside another table can only
1857 // flow backward in the columns of its section.
1858 // Note: The table cell, which contains the section, can not have a master table cell.
1859 if ( IsTabFrm() && pSect
->IsInTab() )
1867 if( 0 != ( pPrv
= pSect
->GetIndPrev() ) )
1869 // Herumlungernde, halbtote SectionFrms sollen uns nicht beirren
1870 while( pPrv
&& pPrv
->IsSctFrm() && !((SwSectionFrm
*)pPrv
)->GetSection() )
1871 pPrv
= pPrv
->GetPrev();
1877 const BOOL bBody
= IsInDocBody();
1878 const BOOL bFly
= IsInFly();
1880 SwLayoutFrm
*pLayLeaf
= GetPrevLayoutLeaf();
1881 SwLayoutFrm
*pPrevLeaf
= 0;
1885 //In Tabellen oder Bereiche geht's niemals hinein.
1886 if ( pLayLeaf
->IsInTab() || pLayLeaf
->IsInSct() )
1888 pLayLeaf
= pLayLeaf
->GetPrevLayoutLeaf();
1890 else if ( bBody
&& pLayLeaf
->IsInDocBody() )
1892 // If there is a pLayLeaf has a lower pLayLeaf is the frame we are looking for.
1893 // Exception: pLayLeaf->Lower() is a zombie section frame
1894 const SwFrm
* pTmp
= pLayLeaf
->Lower();
1895 // OD 11.04.2003 #108824# - consider, that the zombie section frame
1896 // can have frame below it in the found layout leaf.
1897 // Thus, skipping zombie section frame, if possible.
1898 while ( pTmp
&& pTmp
->IsSctFrm() &&
1899 !( static_cast<const SwSectionFrm
*>(pTmp
)->GetSection() ) &&
1903 pTmp
= pTmp
->GetNext();
1906 ( !pTmp
->IsSctFrm() ||
1907 ( static_cast<const SwSectionFrm
*>(pTmp
)->GetSection() )
1913 pPrevLeaf
= pLayLeaf
;
1914 pLayLeaf
= pLayLeaf
->GetPrevLayoutLeaf();
1916 SwFlowFrm::SetMoveBwdJump( TRUE
);
1919 break; //Cntnts in Flys sollte jedes Layout-Blatt recht sein. Warum?
1921 pLayLeaf
= pLayLeaf
->GetPrevLayoutLeaf();
1927 pLayLeaf
= pPrevLeaf
;
1930 SwSectionFrm
* pNew
= NULL
;
1931 // Zunaechst einmal an das Ende des Layoutblatts gehen
1932 SwFrm
*pTmp
= pLayLeaf
->Lower();
1935 while( pTmp
->GetNext() )
1936 pTmp
= pTmp
->GetNext();
1937 if( pTmp
->IsSctFrm() )
1939 // Halbtote stoeren hier nur...
1940 while( !((SwSectionFrm
*)pTmp
)->GetSection() && pTmp
->GetPrev() &&
1941 pTmp
->GetPrev()->IsSctFrm() )
1942 pTmp
= pTmp
->GetPrev();
1943 if( ((SwSectionFrm
*)pTmp
)->GetFollow() == pSect
)
1944 pNew
= (SwSectionFrm
*)pTmp
;
1949 pNew
= new SwSectionFrm( *pSect
, TRUE
);
1950 pNew
->InsertBefore( pLayLeaf
, NULL
);
1953 (pNew
->*fnRect
->fnMakePos
)( pLayLeaf
, pNew
->GetPrev(), TRUE
);
1955 pLayLeaf
= FIRSTLEAF( pNew
);
1956 if( !pNew
->Lower() ) // einspaltige Bereiche formatieren
1959 pLayLeaf
->Format(); // damit die PrtArea fuers MoveBwd stimmt
1962 pNew
->SimpleFormat();
1966 pLayLeaf
= FIRSTLEAF( pNew
);
1967 if( pLayLeaf
->IsColBodyFrm() )
1969 // In existent section columns we're looking for the last not empty
1971 SwLayoutFrm
*pTmpLay
= pLayLeaf
;
1972 while( pLayLeaf
->GetUpper()->GetNext() )
1974 pLayLeaf
= (SwLayoutFrm
*)((SwLayoutFrm
*)pLayLeaf
->GetUpper()->GetNext())->Lower();
1975 if( pLayLeaf
->Lower() )
1978 // If we skipped an empty column, we've to set the jump-flag
1979 if( pLayLeaf
!= pTmpLay
)
1982 SwFlowFrm::SetMoveBwdJump( TRUE
);
1989 SwTwips
lcl_DeadLine( const SwFrm
* pFrm
)
1991 const SwLayoutFrm
* pUp
= pFrm
->GetUpper();
1992 while( pUp
&& pUp
->IsInSct() )
1994 if( pUp
->IsSctFrm() )
1995 pUp
= pUp
->GetUpper();
1996 // Spalten jetzt mit BodyFrm
1997 else if( pUp
->IsColBodyFrm() && pUp
->GetUpper()->GetUpper()->IsSctFrm() )
1998 pUp
= pUp
->GetUpper()->GetUpper();
2003 return pUp
? (pUp
->*fnRect
->fnGetPrtBottom
)() :
2004 (pFrm
->Frm().*fnRect
->fnGetBottom
)();
2007 // SwSectionFrm::Growable(..) prueft, ob der SectionFrm noch wachsen kann,
2008 // ggf. muss die Umgebung gefragt werden
2010 BOOL
SwSectionFrm::Growable() const
2013 if( (*fnRect
->fnYDiff
)( lcl_DeadLine( this ),
2014 (Frm().*fnRect
->fnGetBottom
)() ) > 0 )
2017 return ( GetUpper() && ((SwFrm
*)GetUpper())->Grow( LONG_MAX
, TRUE
) );
2020 /*************************************************************************
2022 |* SwSectionFrm::_Grow(), _Shrink()
2024 |* Ersterstellung AMA 14. Jan. 98
2025 |* Letzte Aenderung AMA 14. Jan. 98
2027 |*************************************************************************/
2029 SwTwips
SwSectionFrm::_Grow( SwTwips nDist
, BOOL bTst
)
2031 if ( !IsColLocked() && !HasFixSize() )
2034 long nFrmHeight
= (Frm().*fnRect
->fnGetHeight
)();
2035 if( nFrmHeight
> 0 && nDist
> (LONG_MAX
- nFrmHeight
) )
2036 nDist
= LONG_MAX
- nFrmHeight
;
2041 BOOL bInCalcCntnt
= GetUpper() && IsInFly() && FindFlyFrm()->IsLocked();
2042 // OD 2004-03-15 #116561# - allow grow in online layout
2043 if ( !Lower() || !Lower()->IsColumnFrm() || !Lower()->GetNext() ||
2044 GetSection()->GetFmt()->GetBalancedColumns().GetValue() ||
2045 GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
2052 nGrow
= lcl_DeadLine( this );
2053 nGrow
= (*fnRect
->fnYDiff
)( nGrow
,
2054 (Frm().*fnRect
->fnGetBottom
)() );
2056 SwTwips nSpace
= nGrow
;
2057 if( !bInCalcCntnt
&& nGrow
< nDist
&& GetUpper() )
2058 nGrow
+= GetUpper()->Grow( LONG_MAX
, TRUE
);
2065 if( nDist
&& !bTst
)
2077 else if( nSpace
< nGrow
&& nDist
!= nSpace
+ GetUpper()->
2078 Grow( nGrow
- nSpace
, FALSE
) )
2082 const SvxGraphicPosition ePos
=
2083 GetAttrSet()->GetBackground().GetGraphicPos();
2084 if ( GPOS_RT
< ePos
&& GPOS_TILED
!= ePos
)
2089 if( GetUpper() && GetUpper()->IsHeaderFrm() )
2090 GetUpper()->InvalidateSize();
2092 (Frm().*fnRect
->fnAddBottom
)( nGrow
);
2093 long nPrtHeight
= (Prt().*fnRect
->fnGetHeight
)() + nGrow
;
2094 (Prt().*fnRect
->fnSetHeight
)( nPrtHeight
);
2096 if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
2098 SwFrm
* pTmp
= Lower();
2101 pTmp
->_InvalidateSize();
2102 pTmp
= pTmp
->GetNext();
2108 SwFrm
*pFrm
= GetNext();
2109 while( pFrm
&& pFrm
->IsSctFrm() && !((SwSectionFrm
*)pFrm
)->GetSection() )
2110 pFrm
= pFrm
->GetNext();
2114 pFrm
->_InvalidatePos();
2116 pFrm
->InvalidatePos();
2119 // --> OD 2004-07-05 #i28701# - Due to the new object positioning
2120 // the frame on the next page/column can flow backward (e.g. it
2121 // was moved forward due to the positioning of its objects ).
2122 // Thus, invalivate this next frame, if document compatibility
2123 // option 'Consider wrapping style influence on object positioning' is ON.
2124 else if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION
) )
2126 InvalidateNextPos();
2143 SwTwips
SwSectionFrm::_Shrink( SwTwips nDist
, BOOL bTst
)
2145 if ( Lower() && !IsColLocked() && !HasFixSize() )
2147 if( ToMaximize( FALSE
) )
2155 long nFrmHeight
= (Frm().*fnRect
->fnGetHeight
)();
2156 if ( nDist
> nFrmHeight
)
2159 if ( Lower()->IsColumnFrm() && Lower()->GetNext() && // FtnAtEnd
2160 !GetSection()->GetFmt()->GetBalancedColumns().GetValue() )
2161 { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
2162 //das Wachstum (wg. des Ausgleichs).
2169 const SvxGraphicPosition ePos
=
2170 GetAttrSet()->GetBackground().GetGraphicPos();
2171 if ( GPOS_RT
< ePos
&& GPOS_TILED
!= ePos
)
2176 (Frm().*fnRect
->fnAddBottom
)( -nDist
);
2177 long nPrtHeight
= (Prt().*fnRect
->fnGetHeight
)() - nDist
;
2178 (Prt().*fnRect
->fnSetHeight
)( nPrtHeight
);
2181 // We do not allow a section frame to shrink the its upper
2182 // footer frame. This is because in the calculation of a
2183 // footer frame, the content of the section frame is _not_
2184 // calculated. If there is a fly frame overlapping with the
2185 // footer frame, the section frame is not affected by this
2186 // during the calculation of the footer frame size.
2187 // The footer frame does not grow in its FormatSize function
2188 // but during the calculation of the content of the section
2189 // frame. The section frame grows until some of its text is
2190 // located on top of the fly frame. The next call of CalcCntnt
2191 // tries to shrink the section and here it would also shrink
2192 // the footer. This may not happen, because shrinking the footer
2193 // would cause the top of the section frame to overlap with the
2194 // fly frame again, this would result in a perfect loop.
2195 if( GetUpper() && !GetUpper()->IsFooterFrm() )
2196 nReal
= GetUpper()->Shrink( nDist
, bTst
);
2198 if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
2200 SwFrm
* pTmp
= Lower();
2203 pTmp
->_InvalidateSize();
2204 pTmp
= pTmp
->GetNext();
2209 SwFrm
* pFrm
= GetNext();
2210 while( pFrm
&& pFrm
->IsSctFrm() && !((SwSectionFrm
*)pFrm
)->GetSection() )
2211 pFrm
= pFrm
->GetNext();
2213 pFrm
->InvalidatePos();
2226 /*************************************************************************
2228 |* SwSectionFrm::MoveAllowed()
2230 |* Ersterstellung MA 08. Oct. 98
2231 |* Letzte Aenderung MA 08. Oct. 98
2233 |* Wann sind Frms innerhalb eines SectionFrms moveable?
2234 |* Wenn sie noch nicht in der letzten Spalte des SectionFrms sind,
2235 |* wenn es einen Follow gibt,
2236 |* wenn der SectionFrm nicht mehr wachsen kann, wird es komplizierter,
2237 |* dann kommt es darauf an, ob der SectionFrm ein naechstes Layoutblatt
2238 |* finden kann. In (spaltigen/verketteten) Flys wird dies via GetNextLayout
2239 |* geprueft, in Tabellen und in Kopf/Fusszeilen gibt es keins, im DocBody
2240 |* und auch im Fussnoten dagegen immer.
2242 |* Benutzt wird diese Routine im TxtFormatter, um zu entscheiden, ob ein
2243 |* (Absatz-)Follow erzeugt werden darf oder ob der Absatz zusammenhalten muss.
2245 |*************************************************************************/
2247 BOOL
SwSectionFrm::MoveAllowed( const SwFrm
* pFrm
) const
2249 // Gibt es einen Follow oder ist der Frame nicht in der letzten Spalte?
2250 if( HasFollow() || ( pFrm
->GetUpper()->IsColBodyFrm() &&
2251 pFrm
->GetUpper()->GetUpper()->GetNext() ) )
2253 if( pFrm
->IsInFtn() )
2257 if( GetUpper()->IsInSct() )
2261 return GetUpper()->FindSctFrm()->MoveAllowed( this );
2266 // The content of footnote inside a columned sectionfrm is moveable
2267 // except in the last column
2268 const SwLayoutFrm
*pLay
= pFrm
->FindFtnFrm()->GetUpper()->GetUpper();
2269 if( pLay
->IsColumnFrm() && pLay
->GetNext() )
2271 // The first paragraph in the first footnote in the first column
2272 // in the sectionfrm at the top of the page is not moveable,
2273 // if the columnbody is empty.
2275 if( pLay
->GetIndPrev() || pFrm
->GetIndPrev() ||
2276 pFrm
->FindFtnFrm()->GetPrev() )
2280 SwLayoutFrm
* pBody
= ((SwColumnFrm
*)pLay
)->FindBodyCont();
2281 if( pBody
&& pBody
->Lower() )
2284 if( bRet
&& ( IsFtnAtEnd() || !Growable() ) )
2288 // Oder kann der Bereich noch wachsen?
2289 if( !IsColLocked() && Growable() )
2291 // Jetzt muss untersucht werden, ob es ein Layoutblatt gibt, in dem
2292 // ein Bereichsfollow erzeugt werden kann.
2293 if( IsInTab() || ( !IsInDocBody() && FindFooterOrHeader() ) )
2294 return FALSE
; // In Tabellen/Kopf/Fusszeilen geht es nicht
2295 if( IsInFly() ) // Bei spaltigen oder verketteten Rahmen
2296 return 0 != ((SwFrm
*)GetUpper())->GetNextLeaf( MAKEPAGE_NONE
);
2300 /** Called for a frame inside a section with no direct previous frame (or only
2301 previous empty section frames) the previous frame of the outer section is
2302 returned, if the frame is the first flowing content of this section.
2304 Note: For a frame inside a table frame, which is inside a section frame,
2307 SwFrm
* SwFrm::_GetIndPrev() const
2310 // --> OD 2007-09-04 #i79774#, #b659654#
2311 // Do not assert, if the frame has a direct previous frame, because it
2312 // could be an empty section frame. The caller has to assure, that the
2313 // frame has no direct previous frame or only empty section frames as
2315 ASSERT( /*!pPrev &&*/ IsInSct(), "Why?" );
2317 const SwFrm
* pSct
= GetUpper();
2320 if( pSct
->IsSctFrm() )
2321 pRet
= pSct
->GetIndPrev();
2322 else if( pSct
->IsColBodyFrm() && (pSct
= pSct
->GetUpper()->GetUpper())->IsSctFrm() )
2324 // Do not return the previous frame of the outer section, if in one
2325 // of the previous columns is content.
2326 const SwFrm
* pCol
= GetUpper()->GetUpper()->GetPrev();
2329 ASSERT( pCol
->IsColumnFrm(), "GetIndPrev(): ColumnFrm expected" );
2330 ASSERT( pCol
->GetLower() && pCol
->GetLower()->IsBodyFrm(),
2331 "GetIndPrev(): Where's the body?");
2332 if( ((SwLayoutFrm
*)((SwLayoutFrm
*)pCol
)->Lower())->Lower() )
2334 pCol
= pCol
->GetPrev();
2336 pRet
= pSct
->GetIndPrev();
2339 // skip empty section frames
2340 while( pRet
&& pRet
->IsSctFrm() && !((SwSectionFrm
*)pRet
)->GetSection() )
2341 pRet
= pRet
->GetIndPrev();
2345 SwFrm
* SwFrm::_GetIndNext()
2347 ASSERT( !pNext
&& IsInSct(), "Why?" );
2348 SwFrm
* pSct
= GetUpper();
2351 if( pSct
->IsSctFrm() )
2352 return pSct
->GetIndNext();
2353 if( pSct
->IsColBodyFrm() && (pSct
= pSct
->GetUpper()->GetUpper())->IsSctFrm() )
2354 { // Wir duerfen nur den Nachfolger des SectionFrms zurueckliefern,
2355 // wenn in keiner folgenden Spalte mehr Inhalt ist
2356 SwFrm
* pCol
= GetUpper()->GetUpper()->GetNext();
2359 ASSERT( pCol
->IsColumnFrm(), "GetIndNext(): ColumnFrm expected" );
2360 ASSERT( pCol
->GetLower() && pCol
->GetLower()->IsBodyFrm(),
2361 "GetIndNext(): Where's the body?");
2362 if( ((SwLayoutFrm
*)((SwLayoutFrm
*)pCol
)->Lower())->Lower() )
2364 pCol
= pCol
->GetNext();
2366 return pSct
->GetIndNext();
2371 BOOL
SwSectionFrm::IsDescendantFrom( const SwSectionFmt
* pFmt
) const
2373 if( !pSection
|| !pFmt
)
2375 const SwSectionFmt
*pMyFmt
= pSection
->GetFmt();
2376 while( pFmt
!= pMyFmt
)
2378 if( pMyFmt
->GetRegisteredIn()->ISA( SwSectionFmt
) )
2379 pMyFmt
= (SwSectionFmt
*)pMyFmt
->GetRegisteredIn();
2386 void SwSectionFrm::CalcFtnAtEndFlag()
2388 SwSectionFmt
*pFmt
= GetSection()->GetFmt();
2389 USHORT nVal
= pFmt
->GetFtnAtTxtEnd( FALSE
).GetValue();
2390 bFtnAtEnd
= FTNEND_ATPGORDOCEND
!= nVal
;
2391 bOwnFtnNum
= FTNEND_ATTXTEND_OWNNUMSEQ
== nVal
||
2392 FTNEND_ATTXTEND_OWNNUMANDFMT
== nVal
;
2393 while( !bFtnAtEnd
&& !bOwnFtnNum
)
2395 if( pFmt
->GetRegisteredIn()->ISA( SwSectionFmt
) )
2396 pFmt
= (SwSectionFmt
*)pFmt
->GetRegisteredIn();
2399 nVal
= pFmt
->GetFtnAtTxtEnd( FALSE
).GetValue();
2400 if( FTNEND_ATPGORDOCEND
!= nVal
)
2403 bOwnFtnNum
= bOwnFtnNum
||FTNEND_ATTXTEND_OWNNUMSEQ
== nVal
||
2404 FTNEND_ATTXTEND_OWNNUMANDFMT
== nVal
;
2409 BOOL
SwSectionFrm::IsEndnoteAtMyEnd() const
2411 return pSection
->GetFmt()->GetEndAtTxtEnd( FALSE
).IsAtEnd();
2414 void SwSectionFrm::CalcEndAtEndFlag()
2416 SwSectionFmt
*pFmt
= GetSection()->GetFmt();
2417 bEndnAtEnd
= pFmt
->GetEndAtTxtEnd( FALSE
).IsAtEnd();
2418 while( !bEndnAtEnd
)
2420 if( pFmt
->GetRegisteredIn()->ISA( SwSectionFmt
) )
2421 pFmt
= (SwSectionFmt
*)pFmt
->GetRegisteredIn();
2424 bEndnAtEnd
= pFmt
->GetEndAtTxtEnd( FALSE
).IsAtEnd();
2428 /*************************************************************************
2430 |* SwSectionFrm::Modify()
2432 |* Ersterstellung MA 08. Oct. 98
2433 |* Letzte Aenderung MA 08. Oct. 98
2435 |*************************************************************************/
2437 void SwSectionFrm::Modify( SfxPoolItem
* pOld
, SfxPoolItem
* pNew
)
2441 if( pNew
&& RES_ATTRSET_CHG
== pNew
->Which() )
2443 SfxItemIter
aNIter( *((SwAttrSetChg
*)pNew
)->GetChgSet() );
2444 SfxItemIter
aOIter( *((SwAttrSetChg
*)pOld
)->GetChgSet() );
2445 SwAttrSetChg
aOldSet( *(SwAttrSetChg
*)pOld
);
2446 SwAttrSetChg
aNewSet( *(SwAttrSetChg
*)pNew
);
2449 _UpdateAttr( (SfxPoolItem
*)aOIter
.GetCurItem(),
2450 (SfxPoolItem
*)aNIter
.GetCurItem(), nInvFlags
,
2451 &aOldSet
, &aNewSet
);
2452 if( aNIter
.IsAtEnd() )
2457 if ( aOldSet
.Count() || aNewSet
.Count() )
2458 SwLayoutFrm::Modify( &aOldSet
, &aNewSet
);
2461 _UpdateAttr( pOld
, pNew
, nInvFlags
);
2463 if ( nInvFlags
!= 0 )
2465 if ( nInvFlags
& 0x01 )
2467 if ( nInvFlags
& 0x10 )
2472 void SwSectionFrm::_UpdateAttr( SfxPoolItem
*pOld
, SfxPoolItem
*pNew
,
2474 SwAttrSetChg
*pOldSet
, SwAttrSetChg
*pNewSet
)
2477 const USHORT nWhich
= pOld
? pOld
->Which() : pNew
? pNew
->Which() : 0;
2479 { // Mehrspaltigkeit in Fussnoten unterdruecken...
2482 const SwFmtCol
& rNewCol
= GetFmt()->GetCol();
2485 //Dummer Fall. Bei der Zuweisung einer Vorlage k?nnen wir uns
2486 //nicht auf das alte Spaltenattribut verlassen. Da diese
2487 //wenigstens anzahlgemass fuer ChgColumns vorliegen muessen,
2488 //bleibt uns nur einen temporaeres Attribut zu basteln.
2490 if ( Lower() && Lower()->IsColumnFrm() )
2493 SwFrm
*pTmp
= Lower();
2496 pTmp
= pTmp
->GetNext();
2498 aCol
.Init( nCol
, 0, 1000 );
2500 BOOL bChgFtn
= IsFtnAtEnd();
2501 BOOL bChgEndn
= IsEndnAtEnd();
2502 BOOL bChgMyEndn
= IsEndnoteAtMyEnd();
2505 bChgFtn
= ( bChgFtn
!= IsFtnAtEnd() ) ||
2506 ( bChgEndn
!= IsEndnAtEnd() ) ||
2507 ( bChgMyEndn
!= IsEndnoteAtMyEnd() );
2508 ChgColumns( aCol
, rNewCol
, bChgFtn
);
2519 ChgColumns( *(const SwFmtCol
*)pOld
, *(const SwFmtCol
*)pNew
);
2524 case RES_FTN_AT_TXTEND
:
2527 BOOL bOld
= IsFtnAtEnd();
2529 if( bOld
!= IsFtnAtEnd() )
2531 const SwFmtCol
& rNewCol
= GetFmt()->GetCol();
2532 ChgColumns( rNewCol
, rNewCol
, TRUE
);
2538 case RES_END_AT_TXTEND
:
2541 BOOL bOld
= IsEndnAtEnd();
2542 BOOL bMyOld
= IsEndnoteAtMyEnd();
2544 if( bOld
!= IsEndnAtEnd() || bMyOld
!= IsEndnoteAtMyEnd())
2546 const SwFmtCol
& rNewCol
= GetFmt()->GetCol();
2547 ChgColumns( rNewCol
, rNewCol
, TRUE
);
2552 case RES_COLUMNBALANCE
:
2557 SetDerivedR2L( sal_False
);
2563 ViewShell
*pSh
= GetShell();
2564 if( pSh
&& pSh
->GetLayout()->IsAnyShellAccessible() )
2565 pSh
->Imp()->InvalidateAccessibleEditableState( sal_True
, this );
2574 if ( pOldSet
|| pNewSet
)
2577 pOldSet
->ClearItem( nWhich
);
2579 pNewSet
->ClearItem( nWhich
);
2582 SwLayoutFrm::Modify( pOld
, pNew
);
2586 /*-----------------09.06.99 14:58-------------------
2587 * SwSectionFrm::ToMaximize(..): A follow or a ftncontainer at the end of the
2588 * page causes a maximal Size of the sectionframe.
2589 * --------------------------------------------------*/
2591 BOOL
SwSectionFrm::ToMaximize( BOOL bCheckFollow
) const
2595 if( !bCheckFollow
) // Don't check superfluous follows
2597 const SwSectionFrm
* pFoll
= GetFollow();
2598 while( pFoll
&& pFoll
->IsSuperfluous() )
2599 pFoll
= pFoll
->GetFollow();
2605 const SwFtnContFrm
* pCont
= ContainsFtnCont();
2606 if( !IsEndnAtEnd() )
2609 while( pCont
&& !bRet
)
2611 if( pCont
->FindFootNote() )
2614 pCont
= ContainsFtnCont( pCont
);
2619 /*-----------------09.06.99 15:07-------------------
2620 * BOOL SwSectionFrm::ContainsFtnCont()
2621 * checks every Column for FtnContFrms.
2622 * --------------------------------------------------*/
2624 SwFtnContFrm
* SwSectionFrm::ContainsFtnCont( const SwFtnContFrm
* pCont
) const
2626 SwFtnContFrm
* pRet
= NULL
;
2627 const SwLayoutFrm
* pLay
;
2630 pLay
= pCont
->FindFtnBossFrm( 0 );
2631 ASSERT( IsAnLower( pLay
), "ConatainsFtnCont: Wrong FtnContainer" );
2632 pLay
= (SwLayoutFrm
*)pLay
->GetNext();
2634 else if( Lower() && Lower()->IsColumnFrm() )
2635 pLay
= (SwLayoutFrm
*)Lower();
2638 while ( !pRet
&& pLay
)
2640 if( pLay
->Lower() && pLay
->Lower()->GetNext() )
2642 ASSERT( pLay
->Lower()->GetNext()->IsFtnContFrm(),
2643 "ToMaximize: Unexspected Frame" );
2644 pRet
= (SwFtnContFrm
*)pLay
->Lower()->GetNext();
2646 ASSERT( !pLay
->GetNext() || pLay
->GetNext()->IsLayoutFrm(),
2647 "ToMaximize: ColFrm exspected" );
2648 pLay
= (SwLayoutFrm
*)pLay
->GetNext();
2653 void SwSectionFrm::InvalidateFtnPos()
2655 SwFtnContFrm
* pCont
= ContainsFtnCont( NULL
);
2658 SwFrm
*pTmp
= pCont
->ContainsCntnt();
2660 pTmp
->_InvalidatePos();
2664 /*-----------------18.03.99 10:37-------------------
2665 * SwSectionFrm::Undersize() liefert den Betrag, um den der Bereich gern
2666 * groesser waere, wenn in ihm Undersized TxtFrms liegen, ansonsten Null.
2667 * Das Undersized-Flag wird ggf. korrigiert.
2668 * --------------------------------------------------*/
2670 long SwSectionFrm::Undersize( BOOL bOverSize
)
2672 bUndersized
= FALSE
;
2674 long nRet
= InnerHeight() - (Prt().*fnRect
->fnGetHeight
)();
2677 else if( !bOverSize
)
2682 /// OD 01.04.2003 #108446# - determine next frame for footnote/endnote formatting
2683 /// before format of current one, because current one can move backward.
2684 /// After moving backward to a previous page method <FindNext()> will return
2685 /// the text frame presenting the first page footnote, if it exists. Thus, the
2686 /// rest of the footnote/endnote container would not be formatted.
2687 void SwSectionFrm::CalcFtnCntnt()
2689 SwFtnContFrm
* pCont
= ContainsFtnCont();
2692 SwFrm
* pFrm
= pCont
->ContainsAny();
2695 while( pFrm
&& IsAnLower( pFrm
) )
2697 SwFtnFrm
* pFtn
= pFrm
->FindFtnFrm();
2700 // OD 01.04.2003 #108446# - determine next frame before format current frame.
2701 SwFrm
* pNextFrm
= 0;
2703 if( pFrm
->IsSctFrm() )
2705 pNextFrm
= static_cast<SwSectionFrm
*>(pFrm
)->ContainsAny();
2709 pNextFrm
= pFrm
->FindNext();
2718 /* -----------------09.02.99 14:26-------------------
2719 * Wenn ein SectionFrm leerlaeuft, z.B. weil sein Inhalt die Seite/Spalte wechselt,
2720 * so wird er nicht sofort zerstoert (es koennte noch jemand auf dem Stack einen Pointer
2721 * auf ihn halten), sondern er traegt sich in eine Liste am RootFrm ein, die spaeter
2722 * abgearbeitet wird (in LayAction::Action u.a.). Seine Groesse wird auf Null gesetzt und
2723 * sein Zeiger auf seine Section ebenfalls. Solche zum Loeschen vorgesehene SectionFrms
2724 * muessen vom Layout/beim Formatieren ignoriert werden.
2726 * Mit InsertEmptySct nimmt der RootFrm einen SectionFrm in die Liste auf,
2727 * mit RemoveFromList kann ein SectionFrm wieder aus der Liste entfernt werden (Dtor),
2728 * mit DeleteEmptySct wird die Liste abgearbeitet und die SectionFrms zerstoert
2729 * --------------------------------------------------*/
2731 void SwRootFrm::InsertEmptySct( SwSectionFrm
* pDel
)
2734 pDestroy
= new SwDestroyList
;
2736 if( !pDestroy
->Seek_Entry( pDel
, &nPos
) )
2737 pDestroy
->Insert( pDel
);
2740 void SwRootFrm::_DeleteEmptySct()
2742 ASSERT( pDestroy
, "Keine Liste, keine Kekse" );
2743 while( pDestroy
->Count() )
2745 SwSectionFrm
* pSect
= (*pDestroy
)[0];
2746 pDestroy
->Remove( USHORT(0) );
2747 ASSERT( !pSect
->IsColLocked() && !pSect
->IsJoinLocked(),
2748 "DeleteEmptySct: Locked SectionFrm" );
2749 if( !pSect
->Frm().HasArea() && !pSect
->ContainsCntnt() )
2751 SwLayoutFrm
* pUp
= pSect
->GetUpper();
2754 if( pUp
&& !pUp
->Lower() )
2756 if( pUp
->IsPageBodyFrm() )
2757 pUp
->FindRootFrm()->SetSuperfluous();
2758 else if( pUp
->IsFtnFrm() && !pUp
->IsColLocked() &&
2767 ASSERT( pSect
->GetSection(), "DeleteEmptySct: Halbtoter SectionFrm?!" );
2772 void SwRootFrm::_RemoveFromList( SwSectionFrm
* pSct
)
2774 ASSERT( pDestroy
, "Where's my list?" );
2776 if( pDestroy
->Seek_Entry( pSct
, &nPos
) )
2777 pDestroy
->Remove( nPos
);
2782 BOOL
SwRootFrm::IsInDelList( SwSectionFrm
* pSct
) const
2785 return ( pDestroy
&& pDestroy
->Seek_Entry( pSct
, &nPos
) );
2790 bool SwSectionFrm::IsBalancedSection() const
2793 if ( GetSection() && Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
2795 bRet
= !GetSection()->GetFmt()->GetBalancedColumns().GetValue();