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: flowfrm.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"
34 #include "swtable.hxx"
36 #include "pagefrm.hxx"
40 #include "viewimp.hxx"
41 #include "dflyobj.hxx"
42 #include "frmtool.hxx"
43 #include "dcontact.hxx"
44 #include <svx/brkitem.hxx>
45 #include <svx/keepitem.hxx>
46 #include <fmtsrnd.hxx>
47 #include <fmtanchr.hxx>
48 #include <fmtpdsc.hxx>
49 #include <svx/ulspitem.hxx>
50 #include <tgrditem.hxx>
53 #include <svx/pgrditem.hxx>
59 #include "pagedesc.hxx"
61 #include "fmtornt.hxx"
62 #include "flyfrms.hxx"
63 #include "sectfrm.hxx"
64 #include "section.hxx"
65 #include "dbg_lay.hxx"
66 #include "lineinfo.hxx"
67 // OD 2004-03-02 #106629#
68 #include <fmtclbl.hxx>
69 // --> OD 2004-06-23 #i28701#
70 #include <sortedobjs.hxx>
71 #include <layouter.hxx>
73 // --> OD 2004-10-15 #i26945#
74 #include <fmtfollowtextflow.hxx>
77 BOOL
SwFlowFrm::bMoveBwdJump
= FALSE
;
80 /*************************************************************************
82 |* SwFlowFrm::SwFlowFrm()
84 |* Ersterstellung MA 26. Apr. 95
85 |* Letzte Aenderung MA 26. Apr. 95
87 |*************************************************************************/
90 SwFlowFrm::SwFlowFrm( SwFrm
&rFrm
) :
94 bLockJoin
= bIsFollow
= bCntntLock
= bOwnFtnNum
=
95 bFtnLock
= bFlyLock
= FALSE
;
99 /*************************************************************************
101 |* SwFlowFrm::IsFollowLocked()
102 |* return TRUE if any follow has the JoinLocked flag
104 |*************************************************************************/
106 sal_Bool
SwFlowFrm::HasLockedFollow() const
108 const SwFlowFrm
* pFrm
= GetFollow();
111 if( pFrm
->IsJoinLocked() )
113 pFrm
= pFrm
->GetFollow();
118 /*************************************************************************
120 |* SwFlowFrm::IsKeepFwdMoveAllowed()
122 |* Ersterstellung MA 20. Jul. 94
123 |* Letzte Aenderung MA 16. May. 95
125 |*************************************************************************/
128 BOOL
SwFlowFrm::IsKeepFwdMoveAllowed()
130 //Wenn der Vorgaenger das KeepAttribut traegt und auch dessen
131 //Vorgaenger usw. bis zum ersten der Kette und fuer diesen das
132 //IsFwdMoveAllowed ein FALSE liefert, so ist das Moven eben nicht erlaubt.
133 SwFrm
*pFrm
= &rThis
;
134 if ( !pFrm
->IsInFtn() )
136 { if ( pFrm
->GetAttrSet()->GetKeep().GetValue() )
137 pFrm
= pFrm
->GetIndPrev();
142 //Siehe IsFwdMoveAllowed()
144 if ( pFrm
&& pFrm
->GetIndPrev() )
149 /*************************************************************************
151 |* SwFlowFrm::CheckKeep()
154 |* Ersterstellung MA 20. Jun. 95
155 |* Letzte Aenderung MA 09. Apr. 97
157 |*************************************************************************/
160 void SwFlowFrm::CheckKeep()
162 //Den 'letzten' Vorgaenger mit KeepAttribut anstossen, denn
163 //die ganze Truppe koennte zuruckrutschen.
164 SwFrm
*pPre
= rThis
.GetIndPrev();
165 if( pPre
->IsSctFrm() )
167 SwFrm
*pLast
= ((SwSectionFrm
*)pPre
)->FindLastCntnt();
168 if( pLast
&& pLast
->FindSctFrm() == pPre
)
175 while ( TRUE
== (bKeep
= pPre
->GetAttrSet()->GetKeep().GetValue()) &&
176 0 != ( pTmp
= pPre
->GetIndPrev() ) )
178 if( pTmp
->IsSctFrm() )
180 SwFrm
*pLast
= ((SwSectionFrm
*)pTmp
)->FindLastCntnt();
181 if( pLast
&& pLast
->FindSctFrm() == pTmp
)
189 pPre
->InvalidatePos();
192 /*************************************************************************
194 |* SwFlowFrm::IsKeep()
196 |* Ersterstellung MA 09. Apr. 97
197 |* Letzte Aenderung MA 09. Apr. 97
199 |*************************************************************************/
201 BOOL
SwFlowFrm::IsKeep( const SwAttrSet
& rAttrs
, bool bCheckIfLastRowShouldKeep
) const
203 // 1. The keep attribute is ignored inside footnotes
204 // 2. For compatibility reasons, the keep attribute is
205 // ignored for frames inside table cells
206 // 3. If bBreakCheck is set to true, this function only checks
207 // if there are any break after attributes set at rAttrs
208 // or break before attributes set for the next content (or next table)
209 BOOL bKeep
= bCheckIfLastRowShouldKeep
||
210 ( !rThis
.IsInFtn() &&
211 ( !rThis
.IsInTab() || rThis
.IsTabFrm() ) &&
212 rAttrs
.GetKeep().GetValue() );
214 ASSERT( !bCheckIfLastRowShouldKeep
|| rThis
.IsTabFrm(),
215 "IsKeep with bCheckIfLastRowShouldKeep should only be used for tabfrms" )
217 // Ignore keep attribute if there are break situations:
220 switch ( rAttrs
.GetBreak().GetBreak() )
222 case SVX_BREAK_COLUMN_AFTER
:
223 case SVX_BREAK_COLUMN_BOTH
:
224 case SVX_BREAK_PAGE_AFTER
:
225 case SVX_BREAK_PAGE_BOTH
:
234 if( 0 != (pNxt
= rThis
.FindNextCnt()) &&
235 (!pFollow
|| pNxt
!= pFollow
->GetFrm()))
237 // --> FME 2006-05-15 #135914#
238 // The last row of a table only keeps with the next content
239 // it they are in the same section:
240 if ( bCheckIfLastRowShouldKeep
)
242 const SwSection
* pThisSection
= 0;
243 const SwSection
* pNextSection
= 0;
244 const SwSectionFrm
* pThisSectionFrm
= rThis
.FindSctFrm();
245 const SwSectionFrm
* pNextSectionFrm
= pNxt
->FindSctFrm();
247 if ( pThisSectionFrm
)
248 pThisSection
= pThisSectionFrm
->GetSection();
250 if ( pNextSectionFrm
)
251 pNextSection
= pNextSectionFrm
->GetSection();
253 if ( pThisSection
!= pNextSection
)
260 const SwAttrSet
* pSet
= NULL
;
262 if ( pNxt
->IsInTab() )
264 SwTabFrm
* pTab
= pNxt
->FindTabFrm();
265 if ( ! rThis
.IsInTab() || rThis
.FindTabFrm() != pTab
)
266 pSet
= &pTab
->GetFmt()->GetAttrSet();
270 pSet
= pNxt
->GetAttrSet();
272 ASSERT( pSet
, "No AttrSet to check keep attribute" )
274 if ( pSet
->GetPageDesc().GetPageDesc() )
276 else switch ( pSet
->GetBreak().GetBreak() )
278 case SVX_BREAK_COLUMN_BEFORE
:
279 case SVX_BREAK_COLUMN_BOTH
:
280 case SVX_BREAK_PAGE_BEFORE
:
281 case SVX_BREAK_PAGE_BOTH
:
292 /*************************************************************************
294 |* SwFlowFrm::BwdMoveNecessary()
296 |* Ersterstellung MA 20. Jul. 94
297 |* Letzte Aenderung MA 02. May. 96
299 |*************************************************************************/
302 BYTE
SwFlowFrm::BwdMoveNecessary( const SwPageFrm
*pPage
, const SwRect
&rRect
)
304 // Der return-Wert entscheidet mit,
305 // ob auf Zurueckgeflossen werden muss, (3)
306 // ob das gute alte WouldFit gerufen werden kann (0, 1)
307 // oder ob ein Umhaengen und eine Probeformatierung sinnvoll ist (2)
308 // dabei bedeutet Bit 1, dass Objekte an mir selbst verankert sind
309 // und Bit 2, dass ich anderen Objekten ausweichen muss.
311 //Wenn ein SurroundObj, dass einen Umfluss wuenscht mit dem Rect ueberlappt
312 //ist der Fluss notwendig (weil die Verhaeltnisse nicht geschaetzt werden
313 //koennen), es kann allerdings ggf. eine TestFormatierung stattfinden.
314 //Wenn das SurroundObj ein Fly ist und ich selbst ein Lower bin oder der Fly
315 //Lower von mir ist, so spielt er keine Rolle.
316 //Wenn das SurroundObj in einem zeichengebunden Fly verankert ist, und ich
317 //selbst nicht Lower dieses Zeichengebundenen Flys bin, so spielt der Fly
319 //#32639# Wenn das Objekt bei mir verankert ist kann ich es
320 //vernachlaessigen, weil es hoechstwahrscheinlich (!?) mitfliesst,
321 //eine TestFormatierung ist dann allerdings nicht erlaubt!
323 SwFlowFrm
*pTmp
= this;
325 { // Wenn an uns oder einem Follow Objekte haengen, so
326 // kann keine ProbeFormatierung stattfinden, da absatzgebundene
327 // nicht richtig beruecksichtigt wuerden und zeichengebundene sollten
328 // gar nicht zur Probe formatiert werden.
329 if( pTmp
->GetFrm()->GetDrawObjs() )
331 pTmp
= pTmp
->GetFollow();
332 } while ( !nRet
&& pTmp
);
333 if ( pPage
->GetSortedObjs() )
335 // --> OD 2004-07-01 #i28701# - new type <SwSortedObjs>
336 const SwSortedObjs
&rObjs
= *pPage
->GetSortedObjs();
337 ULONG nIndex
= ULONG_MAX
;
338 for ( USHORT i
= 0; nRet
< 3 && i
< rObjs
.Count(); ++i
)
340 // --> OD 2004-07-01 #i28701# - consider changed type of
341 // <SwSortedObjs> entries.
342 SwAnchoredObject
* pObj
= rObjs
[i
];
343 const SwFrmFmt
& rFmt
= pObj
->GetFrmFmt();
344 const SwRect
aRect( pObj
->GetObjRect() );
345 if ( aRect
.IsOver( rRect
) &&
346 rFmt
.GetSurround().GetSurround() != SURROUND_THROUGHT
)
348 if( rThis
.IsLayoutFrm() && //Fly Lower von This?
349 Is_Lower_Of( &rThis
, pObj
->GetDrawObj() ) )
351 if( pObj
->ISA(SwFlyFrm
) )
353 const SwFlyFrm
*pFly
= static_cast<const SwFlyFrm
*>(pObj
);
354 if ( pFly
->IsAnLower( &rThis
) )//This Lower vom Fly?
358 const SwFrm
* pAnchor
= pObj
->GetAnchorFrm();
359 if ( pAnchor
== &rThis
)
365 //Nicht wenn das Objekt im Textfluss hinter mir verankert ist,
366 //denn dann weiche ich ihm nicht aus.
367 if ( ::IsFrmInSameKontext( pAnchor
, &rThis
) )
369 if ( rFmt
.GetAnchor().GetAnchorId() == FLY_AT_CNTNT
)
371 // Den Index des anderen erhalten wir immer ueber das Ankerattr.
372 ULONG nTmpIndex
= rFmt
.GetAnchor().GetCntntAnchor()->nNode
.GetIndex();
373 // Jetzt wird noch ueberprueft, ob der aktuelle Absatz vor dem
374 // Anker des verdraengenden Objekts im Text steht, dann wird
375 // nicht ausgewichen.
376 // Der Index wird moeglichst ueber einen SwFmtAnchor ermittelt,
377 // da sonst recht teuer.
378 if( ULONG_MAX
== nIndex
)
381 if ( rThis
.IsCntntFrm() )
382 pNode
= ((SwCntntFrm
&)rThis
).GetNode();
383 else if( rThis
.IsSctFrm() )
384 pNode
= ((SwSectionFmt
*)((SwSectionFrm
&)rThis
).
385 GetFmt())->GetSectionNode();
388 ASSERT( rThis
.IsTabFrm(), "new FowFrm?" );
389 pNode
= ((SwTabFrm
&)rThis
).GetTable()->
390 GetTabSortBoxes()[0]->GetSttNd()->FindTableNode();
392 nIndex
= pNode
->GetIndex();
394 if( nIndex
< nTmpIndex
)
408 /*************************************************************************
410 |* SwFlowFrm::CutTree(), PasteTree(), MoveSubTree()
412 |* Beschreibung Eine Spezialisierte Form des Cut() und Paste(), die
413 |* eine ganze Kette umhaengt (naehmlich this und folgende). Dabei werden
414 |* nur minimale Operationen und Benachrichtigungen ausgefuehrt.
415 |* Ersterstellung MA 18. Mar. 93
416 |* Letzte Aenderung MA 18. May. 95
418 |*************************************************************************/
421 SwLayoutFrm
*SwFlowFrm::CutTree( SwFrm
*pStart
)
423 //Der Start und alle Nachbarn werden ausgeschnitten, sie werden aneinander-
424 //gereiht und ein Henkel auf den ersten wird zurueckgeliefert.
425 //Zurueckbleibende werden geeignet invalidiert.
427 SwLayoutFrm
*pLay
= pStart
->GetUpper();
428 if ( pLay
->IsInFtn() )
429 pLay
= pLay
->FindFtnFrm();
431 // --> OD 2006-05-08 #i58846#
432 // <pPrepare( PREP_QUOVADIS )> only for frames in footnotes
433 if( pStart
->IsInFtn() )
435 SwFrm
* pTmp
= pStart
->GetIndPrev();
437 pTmp
->Prepare( PREP_QUOVADIS
);
441 //Nur fix auschneiden und zwar so, dass klare Verhaeltnisse bei den
442 //Verlassenen herrschen. Die Pointer der ausgeschnittenen Kette zeigen
443 //noch wer weiss wo hin.
444 if ( pStart
== pStart
->GetUpper()->Lower() )
445 pStart
->GetUpper()->pLower
= 0;
446 if ( pStart
->GetPrev() )
448 pStart
->GetPrev()->pNext
= 0;
452 if ( pLay
->IsFtnFrm() )
454 if ( !pLay
->Lower() && !pLay
->IsColLocked() &&
455 !((SwFtnFrm
*)pLay
)->IsBackMoveLocked() )
462 BOOL bUnlock
= !((SwFtnFrm
*)pLay
)->IsBackMoveLocked();
463 ((SwFtnFrm
*)pLay
)->LockBackMove();
464 pLay
->InvalidateSize();
466 SwCntntFrm
*pCnt
= pLay
->ContainsCntnt();
467 while ( pCnt
&& pLay
->IsAnLower( pCnt
) )
469 //Kann sein, dass der CntFrm gelockt ist, wir wollen hier nicht
470 //in eine endlose Seitenwanderung hineinlaufen und rufen das
471 //Calc garnicht erst!
472 ASSERT( pCnt
->IsTxtFrm(), "Die Graphic ist gelandet." );
473 if ( ((SwTxtFrm
*)pCnt
)->IsLocked() ||
474 ((SwTxtFrm
*)pCnt
)->GetFollow() == pStart
)
477 pCnt
= pCnt
->GetNextCntntFrm();
480 ((SwFtnFrm
*)pLay
)->UnlockBackMove();
489 BOOL
SwFlowFrm::PasteTree( SwFrm
*pStart
, SwLayoutFrm
*pParent
, SwFrm
*pSibling
,
492 //returnt TRUE wenn in der Kette ein LayoutFrm steht.
495 //Die mit pStart beginnende Kette wird vor den Sibling unter den Parent
496 //gehaengt. Fuer geeignete Invalidierung wird ebenfalls gesorgt.
498 //Ich bekomme eine fertige Kette. Der Anfang der Kette muss verpointert
499 //werden, dann alle Upper fuer die Kette und schliesslich dass Ende.
500 //Unterwegs werden alle geeignet invalidiert.
503 if ( 0 != (pStart
->pPrev
= pSibling
->GetPrev()) )
504 pStart
->GetPrev()->pNext
= pStart
;
506 pParent
->pLower
= pStart
;
507 pSibling
->_InvalidatePos();
508 pSibling
->_InvalidatePrt();
512 if ( 0 == (pStart
->pPrev
= pParent
->Lower()) )
513 pParent
->pLower
= pStart
;
515 //Modified for #i100782#,04/03/2009
516 //If the pParent has more than 1 child nodes, former design will
517 //ignore them directly without any collection work. It will make some
518 //dangling pointers. This lead the crash...
519 //The new design will find the last child of pParent in loop way, and
520 //add the pStart after the last child.
521 // pParent->Lower()->pNext = pStart;
523 SwFrm
* pTemp
= pParent
->pLower
;
527 pTemp
= pTemp
->pNext
;
530 pStart
->pPrev
= pTemp
;
531 pTemp
->pNext
= pStart
;
536 //End modification for #i100782#,04/03/2009
539 if ( pParent
->IsSctFrm() )
541 // We have no sibling because pParent is a section frame and
542 // has just been created to contain some content. The printing
543 // area of the frame behind pParent has to be invalidated, so
544 // that the correct distance between pParent and the next frame
545 // can be calculated.
546 pParent
->InvalidateNextPrtArea();
549 SwFrm
*pFloat
= pStart
;
552 SwTwips nGrowVal
= 0;
554 { pFloat
->pUpper
= pParent
;
555 pFloat
->_InvalidateAll();
556 pFloat
->CheckDirChange();
558 //Ich bin Freund des TxtFrm und darf deshalb so einiges. Das mit
559 //dem CacheIdx scheint etwas riskant!
560 if ( pFloat
->IsTxtFrm() )
562 if ( ((SwTxtFrm
*)pFloat
)->GetCacheIdx() != USHRT_MAX
)
563 ((SwTxtFrm
*)pFloat
)->Init(); //Ich bin sein Freund.
568 nGrowVal
+= (pFloat
->Frm().*fnRect
->fnGetHeight
)();
569 if ( pFloat
->GetNext() )
570 pFloat
= pFloat
->GetNext();
580 pLst
->pNext
= pSibling
;
581 pSibling
->pPrev
= pLst
;
582 if( pSibling
->IsInFtn() )
584 if( pSibling
->IsSctFrm() )
585 pSibling
= ((SwSectionFrm
*)pSibling
)->ContainsAny();
587 pSibling
->Prepare( PREP_ERGOSUM
);
592 if ( pOldParent
&& pOldParent
->IsBodyFrm() ) //Fuer variable Seitenhoehe beim Browsen
593 pOldParent
->Shrink( nGrowVal
);
594 pParent
->Grow( nGrowVal
);
597 if ( pParent
->IsFtnFrm() )
598 ((SwFtnFrm
*)pParent
)->InvalidateNxtFtnCnts( pParent
->FindPageFrm() );
604 void SwFlowFrm::MoveSubTree( SwLayoutFrm
* pParent
, SwFrm
* pSibling
)
606 ASSERT( pParent
, "Kein Parent uebergeben." );
607 ASSERT( rThis
.GetUpper(), "Wo kommen wir denn her?" );
609 //Sparsamer benachrichtigen wenn eine Action laeuft.
610 ViewShell
*pSh
= rThis
.GetShell();
611 const SwViewImp
*pImp
= pSh
? pSh
->Imp() : 0;
612 const BOOL bComplete
= pImp
&& pImp
->IsAction() && pImp
->GetLayAction().IsComplete();
616 SwFrm
*pPre
= rThis
.GetIndPrev();
620 // --> OD 2004-11-23 #115759# - follow-up of #i26250#
621 // invalidate printing area of previous frame, if it's in a table
622 if ( pPre
->GetUpper()->IsInTab() )
624 pPre
->_InvalidatePrt();
627 pPre
->InvalidatePage();
630 { rThis
.GetUpper()->SetCompletePaint();
631 rThis
.GetUpper()->InvalidatePage();
635 SwPageFrm
*pOldPage
= rThis
.FindPageFrm();
637 SwLayoutFrm
*pOldParent
= CutTree( &rThis
);
638 const BOOL bInvaLay
= PasteTree( &rThis
, pParent
, pSibling
, pOldParent
);
640 // Wenn durch das Cut&Paste ein leerer SectionFrm entstanden ist, sollte
641 // dieser automatisch verschwinden.
643 // --> OD 2006-01-04 #126020# - adjust check for empty section
644 // --> OD 2006-02-01 #130797# - correct fix #126020#
645 if ( pOldParent
&& !pOldParent
->Lower() &&
646 ( pOldParent
->IsInSct() &&
647 !(pSct
= pOldParent
->FindSctFrm())->ContainsCntnt() &&
648 !pSct
->ContainsAny( true ) ) )
651 pSct
->DelEmpty( FALSE
);
654 // In einem spaltigen Bereich rufen wir lieber kein Calc "von unten"
655 if( !rThis
.IsInSct() &&
656 ( !rThis
.IsInTab() || ( rThis
.IsTabFrm() && !rThis
.GetUpper()->IsInTab() ) ) )
657 rThis
.GetUpper()->Calc();
658 else if( rThis
.GetUpper()->IsSctFrm() )
660 SwSectionFrm
* pTmpSct
= (SwSectionFrm
*)rThis
.GetUpper();
661 BOOL bOld
= pTmpSct
->IsCntntLocked();
662 pTmpSct
->SetCntntLock( TRUE
);
665 pTmpSct
->SetCntntLock( FALSE
);
667 SwPageFrm
*pPage
= rThis
.FindPageFrm();
669 if ( pOldPage
!= pPage
)
671 rThis
.InvalidatePage( pPage
);
672 if ( rThis
.IsLayoutFrm() )
674 SwCntntFrm
*pCnt
= ((SwLayoutFrm
*)&rThis
)->ContainsCntnt();
676 pCnt
->InvalidatePage( pPage
);
678 else if ( pSh
&& pSh
->GetDoc()->GetLineNumberInfo().IsRestartEachPage()
679 && pPage
->FindFirstBodyCntnt() == &rThis
)
681 rThis
._InvalidateLineNum();
684 if ( bInvaLay
|| (pSibling
&& pSibling
->IsLayoutFrm()) )
685 rThis
.GetUpper()->InvalidatePage( pPage
);
688 /*************************************************************************
690 |* SwFlowFrm::IsAnFollow()
692 |* Ersterstellung MA 26. Apr. 95
693 |* Letzte Aenderung MA 26. Apr. 95
695 |*************************************************************************/
698 BOOL
SwFlowFrm::IsAnFollow( const SwFlowFrm
*pAssumed
) const
700 const SwFlowFrm
*pFoll
= this;
702 { if ( pAssumed
== pFoll
)
704 pFoll
= pFoll
->GetFollow();
710 /*************************************************************************
712 |* SwFlowFrm::FindMaster()
714 |* Ersterstellung MA 26. Apr. 95
715 |* Letzte Aenderung MA 26. Apr. 95
717 |*************************************************************************/
719 SwTxtFrm
* SwCntntFrm::FindMaster() const
721 ASSERT( IsFollow(), "SwCntntFrm::FindMaster(): !IsFollow" );
723 const SwCntntFrm
* pCnt
= GetPrevCntntFrm();
727 if ( pCnt
->HasFollow() && pCnt
->GetFollow() == this )
729 ASSERT( pCnt
->IsTxtFrm(), "NoTxtFrm with follow found" )
730 return (SwTxtFrm
*)pCnt
;
732 pCnt
= pCnt
->GetPrevCntntFrm();
735 ASSERT( FALSE
, "Follow ist lost in Space." );
739 SwSectionFrm
* SwSectionFrm::FindMaster() const
741 ASSERT( IsFollow(), "SwSectionFrm::FindMaster(): !IsFollow" );
743 SwClientIter
aIter( *pSection
->GetFmt() );
744 SwClient
*pLast
= aIter
.GoStart();
748 if ( pLast
->ISA( SwFrm
) )
750 ASSERT( ((SwFrm
*)pLast
)->IsSctFrm(),
751 "Non-section frame registered in section format" )
752 SwSectionFrm
* pSect
= (SwSectionFrm
*)pLast
;
753 if( pSect
->GetFollow() == this )
759 ASSERT( FALSE
, "Follow ist lost in Space." );
763 SwTabFrm
* SwTabFrm::FindMaster( bool bFirstMaster
) const
765 ASSERT( IsFollow(), "SwTabFrm::FindMaster(): !IsFollow" );
767 SwClientIter
aIter( *GetTable()->GetFrmFmt() );
768 SwClient
* pLast
= aIter
.GoStart();
772 if ( pLast
->ISA( SwFrm
) )
774 ASSERT( ((SwFrm
*)pLast
)->IsTabFrm(),
775 "Non-table frame registered in table format" )
776 SwTabFrm
* pTab
= (SwTabFrm
*)pLast
;
781 // Optimization. This makes code like this obsolete:
782 // while ( pTab->IsFollow() )
783 // pTab = pTab->FindMaster();
785 if ( !pTab
->IsFollow() )
787 SwTabFrm
* pNxt
= pTab
;
790 if ( pNxt
->GetFollow() == this )
792 pNxt
= pNxt
->GetFollow();
798 if ( pTab
->GetFollow() == this )
805 ASSERT( FALSE
, "Follow ist lost in Space." );
809 /*************************************************************************
813 |* Beschreibung Liefert das naechste/vorhergehende LayoutBlatt,
814 |* das _nicht_ unterhalb von this liegt (oder gar this selbst ist).
815 |* Ausserdem muss dieses LayoutBlatt im gleichen Textfluss wie
816 |* pAnch Ausgangsfrm liegen (Body, Ftn)
817 |* Ersterstellung MA 25. Nov. 92
818 |* Letzte Aenderung MA 25. Apr. 95
820 |*************************************************************************/
823 const SwLayoutFrm
*SwFrm::GetLeaf( MakePageType eMakePage
, BOOL bFwd
,
824 const SwFrm
*pAnch
) const
826 //Ohne Fluss kein genuss...
827 if ( !(IsInDocBody() || IsInFtn() || IsInFly()) )
830 const SwFrm
*pLeaf
= this;
834 { pLeaf
= ((SwFrm
*)pLeaf
)->GetLeaf( eMakePage
, bFwd
);
837 (!IsLayoutFrm() || !((SwLayoutFrm
*)this)->IsAnLower( pLeaf
)))
839 if ( pAnch
->IsInDocBody() == pLeaf
->IsInDocBody() &&
840 pAnch
->IsInFtn() == pLeaf
->IsInFtn() )
845 } while ( !bFound
&& pLeaf
);
847 return (const SwLayoutFrm
*)pLeaf
;
850 /*************************************************************************
854 |* Beschreibung Ruft Get[Next|Prev]Leaf
856 |* Ersterstellung MA 20. Mar. 93
857 |* Letzte Aenderung MA 25. Apr. 95
859 |*************************************************************************/
862 SwLayoutFrm
*SwFrm::GetLeaf( MakePageType eMakePage
, BOOL bFwd
)
865 return bFwd
? GetNextFtnLeaf( eMakePage
) : GetPrevFtnLeaf( eMakePage
);
867 // --> OD 2005-08-16 #i53323#
868 // A frame could be inside a table AND inside a section.
869 // Thus, it has to be determined, which is the first parent.
870 bool bInTab( IsInTab() );
871 bool bInSct( IsInSct() );
872 if ( bInTab
&& bInSct
)
874 const SwFrm
* pUpperFrm( GetUpper() );
877 if ( pUpperFrm
->IsTabFrm() )
879 // the table is the first.
883 else if ( pUpperFrm
->IsSctFrm() )
885 // the section is the first.
890 pUpperFrm
= pUpperFrm
->GetUpper();
894 if ( bInTab
&& ( !IsTabFrm() || GetUpper()->IsCellFrm() ) ) // TABLE IN TABLE
895 return bFwd
? GetNextCellLeaf( eMakePage
) : GetPrevCellLeaf( eMakePage
);
898 return bFwd
? GetNextSctLeaf( eMakePage
) : GetPrevSctLeaf( eMakePage
);
901 return bFwd
? GetNextLeaf( eMakePage
) : GetPrevLeaf( eMakePage
);
906 BOOL
SwFrm::WrongPageDesc( SwPageFrm
* pNew
)
908 //Jetzt wirds leider etwas kompliziert:
909 //Ich bringe ich evtl. selbst
910 //einen Pagedesc mit; der der Folgeseite muss dann damit
912 //Anderfalls muss ich mir etwas genauer ansehen wo der
913 //Folgepagedesc herkam.
914 //Wenn die Folgeseite selbst schon sagt, dass ihr
915 //Pagedesc nicht stimmt so kann ich das Teil bedenkenlos
917 //Wenn die Seite meint, dass ihr Pagedesc stimmt, so heisst
918 //das leider noch immer nicht, dass ich damit etwas anfangen
919 //kann: Wenn der erste BodyCntnt einen PageDesc oder einen
920 //PageBreak wuenscht, so muss ich ebenfalls eine neue
921 //Seite einfuegen; es sein denn die gewuenschte Seite ist
923 //Wenn ich einen neue Seite eingefuegt habe, so fangen die
924 //Probleme leider erst an, denn wahrscheinlich wird die dann
925 //folgende Seite verkehrt gewesen und ausgewechselt worden
926 //sein. Das hat zur Folge, dass ich zwar eine neue (und
927 //jetzt richtige) Seite habe, die Bedingungen zum auswechseln
928 //aber leider noch immer stimmen.
929 //Ausweg: Vorlaeufiger Versuch, nur einmal eine neue Seite
930 //einsetzen (Leerseiten werden noetigenfalls bereits von
931 //InsertPage() eingefuegt.
932 const SwFmtPageDesc
&rFmtDesc
= GetAttrSet()->GetPageDesc();
934 //Mein Pagedesc zaehlt nicht, wenn ich ein Follow bin!
935 SwPageDesc
*pDesc
= 0;
937 SwFlowFrm
*pFlow
= SwFlowFrm::CastFlowFrm( this );
938 if ( !pFlow
|| !pFlow
->IsFollow() )
940 pDesc
= (SwPageDesc
*)rFmtDesc
.GetPageDesc();
943 if( !pDesc
->GetRightFmt() )
945 else if( !pDesc
->GetLeftFmt() )
947 else if( rFmtDesc
.GetNumOffset() )
948 nTmp
= rFmtDesc
.GetNumOffset();
952 //Bringt der Cntnt einen Pagedesc mit oder muss zaehlt die
953 //virtuelle Seitennummer des neuen Layoutleafs?
954 // Bei Follows zaehlt der PageDesc nicht
955 const BOOL bOdd
= nTmp
? ( nTmp
% 2 ? TRUE
: FALSE
)
956 : pNew
->OnRightPage();
958 pDesc
= pNew
->FindPageDesc();
959 const SwFlowFrm
*pNewFlow
= pNew
->FindFirstBodyCntnt();
960 // Haben wir uns selbst gefunden?
961 if( pNewFlow
== pFlow
)
963 if ( pNewFlow
&& pNewFlow
->GetFrm()->IsInTab() )
964 pNewFlow
= pNewFlow
->GetFrm()->FindTabFrm();
965 const SwPageDesc
*pNewDesc
= ( pNewFlow
&& !pNewFlow
->IsFollow() )
966 ? pNewFlow
->GetFrm()->GetAttrSet()->GetPageDesc().GetPageDesc():0;
968 return ( pNew
->GetPageDesc() != pDesc
|| // own desc ?
969 pNew
->GetFmt() != (bOdd
? pDesc
->GetRightFmt() : pDesc
->GetLeftFmt()) ||
970 ( pNewDesc
&& pNewDesc
== pDesc
) );
974 /*************************************************************************
976 |* SwFrm::GetNextLeaf()
978 |* Beschreibung Liefert das naechste LayoutBlatt in den das
979 |* Frame gemoved werden kann.
981 |* Ersterstellung MA 16. Nov. 92
982 |* Letzte Aenderung MA 05. Dec. 96
984 |*************************************************************************/
986 SwLayoutFrm
*SwFrm::GetNextLeaf( MakePageType eMakePage
)
988 ASSERT( !IsInFtn(), "GetNextLeaf(), don't call me for Ftn." );
989 ASSERT( !IsInSct(), "GetNextLeaf(), don't call me for Sections." );
991 const BOOL bBody
= IsInDocBody(); //Wenn ich aus dem DocBody komme
992 //Will ich auch im Body landen.
994 // Bei Flys macht es keinen Sinn, Seiten einzufuegen, wir wollen lediglich
995 // die Verkettung absuchen.
997 eMakePage
= MAKEPAGE_NONE
;
999 //Bei Tabellen gleich den grossen Sprung wagen, ein einfaches GetNext...
1000 //wuerde die erste Zellen und in der Folge alle weiteren Zellen nacheinander
1002 SwLayoutFrm
*pLayLeaf
= 0;
1005 SwCntntFrm
* pTmp
= ((SwTabFrm
*)this)->FindLastCntnt();
1007 pLayLeaf
= pTmp
->GetUpper();
1010 pLayLeaf
= GetNextLayoutLeaf();
1012 SwLayoutFrm
*pOldLayLeaf
= 0; //Damit bei neu erzeugten Seiten
1013 //nicht wieder vom Anfang gesucht
1015 BOOL bNewPg
= FALSE
; //nur einmal eine neue Seite einfuegen.
1021 //Es gibt noch einen weiteren LayoutFrm, mal sehen,
1022 //ob er bereit ist mich aufzunehmen.
1023 //Dazu braucht er nur von der gleichen Art wie mein Ausgangspunkt
1024 //sein (DocBody bzw. Footnote.)
1025 if ( pLayLeaf
->FindPageFrm()->IsFtnPage() )
1026 { //Wenn ich bei den Endnotenseiten angelangt bin hat sichs.
1030 if ( (bBody
&& !pLayLeaf
->IsInDocBody()) || pLayLeaf
->IsInTab()
1031 || pLayLeaf
->IsInSct() )
1033 //Er will mich nicht; neuer Versuch, neues Glueck
1034 pOldLayLeaf
= pLayLeaf
;
1035 pLayLeaf
= pLayLeaf
->GetNextLayoutLeaf();
1038 //Er will mich, also ist er der gesuchte und ich bin fertig.
1039 //Bei einem Seitenwechsel kann es allerdings noch sein, dass
1040 //Der Seitentyp nicht der gewuenschte ist, in diesem Fall muessen
1041 //wir eine Seite des richtigen Typs einfuegen.
1043 if( !IsFlowFrm() && ( eMakePage
== MAKEPAGE_NONE
||
1044 eMakePage
==MAKEPAGE_APPEND
|| eMakePage
==MAKEPAGE_NOSECTION
) )
1047 SwPageFrm
*pNew
= pLayLeaf
->FindPageFrm();
1048 // #111704# The pagedesc check does not make sense for frames in fly frames
1049 if ( pNew
!= FindPageFrm() && !bNewPg
&& !IsInFly() &&
1050 // --> FME 2005-05-10 #i46683#
1051 // Do not consider page descriptions in browse mode (since
1052 // MoveBwd ignored them)
1053 !pNew
->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
1056 if( WrongPageDesc( pNew
) )
1058 SwFtnContFrm
*pCont
= pNew
->FindFtnCont();
1061 // Falls die Referenz der ersten Fussnote dieser Seite
1062 // vor der Seite liegt, fuegen wir lieber keine neue Seite
1063 // ein (Bug #55620#)
1064 SwFtnFrm
*pFtn
= (SwFtnFrm
*)pCont
->Lower();
1065 if( pFtn
&& pFtn
->GetRef() )
1067 const USHORT nRefNum
= pNew
->GetPhyPageNum();
1068 if( pFtn
->GetRef()->GetPhyPageNum() < nRefNum
)
1072 //Erwischt, die folgende Seite ist verkehrt, also
1073 //muss eine neue eingefuegt werden.
1074 if ( eMakePage
== MAKEPAGE_INSERT
)
1078 SwPageFrm
*pPg
= pOldLayLeaf
?
1079 pOldLayLeaf
->FindPageFrm() : 0;
1080 if ( pPg
&& pPg
->IsEmptyPage() )
1081 //Nicht hinter, sondern vor der EmptyPage einfuegen.
1082 pPg
= (SwPageFrm
*)pPg
->GetPrev();
1084 if ( !pPg
|| pPg
== pNew
)
1085 pPg
= FindPageFrm();
1087 InsertPage( pPg
, FALSE
);
1088 pLayLeaf
= GetNextLayoutLeaf();
1100 //Es gibt keinen passenden weiteren LayoutFrm, also muss eine
1102 if ( eMakePage
== MAKEPAGE_APPEND
|| eMakePage
== MAKEPAGE_INSERT
)
1105 pOldLayLeaf
? pOldLayLeaf
->FindPageFrm() : FindPageFrm(),
1108 //und nochmal das ganze
1109 pLayLeaf
= pOldLayLeaf
? pOldLayLeaf
: GetNextLayoutLeaf();
1118 /*************************************************************************
1120 |* SwFrm::GetPrevLeaf()
1122 |* Beschreibung Liefert das vorhergehende LayoutBlatt in das der
1123 |* Frame gemoved werden kann.
1124 |* Ersterstellung MA 16. Nov. 92
1125 |* Letzte Aenderung MA 25. Apr. 95
1127 |*************************************************************************/
1130 SwLayoutFrm
*SwFrm::GetPrevLeaf( MakePageType
)
1132 ASSERT( !IsInFtn(), "GetPrevLeaf(), don't call me for Ftn." );
1134 const BOOL bBody
= IsInDocBody(); //Wenn ich aus dem DocBody komme
1135 //will ich auch im Body landen.
1136 const BOOL bFly
= IsInFly();
1138 SwLayoutFrm
*pLayLeaf
= GetPrevLayoutLeaf();
1139 SwLayoutFrm
*pPrevLeaf
= 0;
1143 if ( pLayLeaf
->IsInTab() || //In Tabellen geht's niemals hinein.
1144 pLayLeaf
->IsInSct() ) //In Bereiche natuerlich auch nicht!
1145 pLayLeaf
= pLayLeaf
->GetPrevLayoutLeaf();
1146 else if ( bBody
&& pLayLeaf
->IsInDocBody() )
1148 if ( pLayLeaf
->Lower() )
1150 pPrevLeaf
= pLayLeaf
;
1151 pLayLeaf
= pLayLeaf
->GetPrevLayoutLeaf();
1153 SwFlowFrm::SetMoveBwdJump( TRUE
);
1156 break; //Cntnts in Flys sollte jedes Layout-Blatt recht sein.
1158 pLayLeaf
= pLayLeaf
->GetPrevLayoutLeaf();
1160 return pLayLeaf
? pLayLeaf
: pPrevLeaf
;
1163 /*************************************************************************
1165 |* SwFlowFrm::IsPrevObjMove()
1167 |* Ersterstellung MA 20. Feb. 96
1168 |* Letzte Aenderung MA 22. Feb. 96
1170 |*************************************************************************/
1173 BOOL
SwFlowFrm::IsPrevObjMove() const
1175 //TRUE der FlowFrm soll auf einen Rahmen des Vorgaengers Ruecksicht nehmen
1176 // und fuer diesen ggf. Umbrechen.
1178 //!!!!!!!!!!!Hack!!!!!!!!!!!
1179 if ( rThis
.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
1182 SwFrm
*pPre
= rThis
.FindPrev();
1184 if ( pPre
&& pPre
->GetDrawObjs() )
1186 ASSERT( SwFlowFrm::CastFlowFrm( pPre
), "new flowfrm?" );
1187 if( SwFlowFrm::CastFlowFrm( pPre
)->IsAnFollow( this ) )
1189 SwLayoutFrm
* pPreUp
= pPre
->GetUpper();
1190 // Wenn der Upper ein SectionFrm oder die Spalte eines SectionFrms ist,
1191 // duerfen wir aus diesem durchaus heraushaengen,
1192 // es muss stattdessen der Upper des SectionFrms beruecksichtigt werden.
1193 if( pPreUp
->IsInSct() )
1195 if( pPreUp
->IsSctFrm() )
1196 pPreUp
= pPreUp
->GetUpper();
1197 else if( pPreUp
->IsColBodyFrm() &&
1198 pPreUp
->GetUpper()->GetUpper()->IsSctFrm() )
1199 pPreUp
= pPreUp
->GetUpper()->GetUpper()->GetUpper();
1201 // --> OD 2004-10-15 #i26945# - re-factoring:
1202 // use <GetVertPosOrientFrm()> to determine, if object has followed the
1203 // text flow to the next layout frame
1204 for ( USHORT i
= 0; i
< pPre
->GetDrawObjs()->Count(); ++i
)
1206 // --> OD 2004-07-01 #i28701# - consider changed type of
1207 // <SwSortedObjs> entries.
1208 const SwAnchoredObject
* pObj
= (*pPre
->GetDrawObjs())[i
];
1209 // OD 2004-01-20 #110582# - do not consider hidden objects
1210 // --> OD 2004-10-15 #i26945# - do not consider object, which
1211 // doesn't follow the text flow.
1212 if ( pObj
->GetFrmFmt().GetDoc()->IsVisibleLayerId(
1213 pObj
->GetDrawObj()->GetLayer() ) &&
1214 pObj
->GetFrmFmt().GetFollowTextFlow().GetValue() )
1217 const SwLayoutFrm
* pVertPosOrientFrm
= pObj
->GetVertPosOrientFrm();
1218 if ( pVertPosOrientFrm
&&
1219 pPreUp
!= pVertPosOrientFrm
&&
1220 !pPreUp
->IsAnLower( pVertPosOrientFrm
) )
1231 /*************************************************************************
1233 |* BOOL SwFlowFrm::IsPageBreak()
1235 |* Beschreibung Wenn vor dem Frm ein harter Seitenumbruch steht UND
1236 |* es einen Vorgaenger auf der gleichen Seite gibt, wird TRUE
1237 |* zurueckgeliefert (es muss ein PageBreak erzeugt werden) FALSE sonst.
1238 |* Wenn in bAct TRUE uebergeben wird, gibt die Funktion dann TRUE
1239 |* zurueck, wenn ein PageBreak besteht.
1240 |* Fuer Follows wird der harte Seitenumbruch natuerlich nicht
1242 |* Der Seitenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt
1243 |* des Vorgaengers (AFTER). Wenn es keinen Vorgaenger auf der Seite
1244 |* gibt ist jede weitere Ueberlegung ueberfluessig.
1245 |* Ein Seitenumbruch (oder der Bedarf) liegt auch dann vor, wenn
1246 |* im FrmFmt ein PageDesc angegeben wird.
1247 |* Die Implementierung arbeitet zuaechst nur auf CntntFrms!
1248 |* -->Fuer LayoutFrms ist die Definition des Vorgaengers unklar.
1249 |* Ersterstellung MA ??
1250 |* Letzte Aenderung MA 21. Mar. 95
1252 |*************************************************************************/
1255 BOOL
SwFlowFrm::IsPageBreak( BOOL bAct
) const
1257 if ( !IsFollow() && rThis
.IsInDocBody() &&
1258 ( !rThis
.IsInTab() || ( rThis
.IsTabFrm() && !rThis
.GetUpper()->IsInTab() ) ) && // i66968
1259 !rThis
.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
1261 const SwAttrSet
*pSet
= rThis
.GetAttrSet();
1263 //Vorgaenger ermitteln
1264 const SwFrm
*pPrev
= rThis
.FindPrev();
1265 while ( pPrev
&& ( !pPrev
->IsInDocBody() ||
1266 ( pPrev
->IsTxtFrm() && ((SwTxtFrm
*)pPrev
)->IsHiddenNow() ) ) )
1267 pPrev
= pPrev
->FindPrev();
1271 ASSERT( pPrev
->IsInDocBody(), "IsPageBreak: Not in DocBody?" );
1273 { if ( rThis
.FindPageFrm() == pPrev
->FindPageFrm() )
1277 { if ( rThis
.FindPageFrm() != pPrev
->FindPageFrm() )
1281 const SvxBreak eBreak
= pSet
->GetBreak().GetBreak();
1282 if ( eBreak
== SVX_BREAK_PAGE_BEFORE
|| eBreak
== SVX_BREAK_PAGE_BOTH
)
1286 const SvxBreak
&ePrB
= pPrev
->GetAttrSet()->GetBreak().GetBreak();
1287 if ( ePrB
== SVX_BREAK_PAGE_AFTER
||
1288 ePrB
== SVX_BREAK_PAGE_BOTH
||
1289 pSet
->GetPageDesc().GetPageDesc() )
1297 /*************************************************************************
1299 |* BOOL SwFlowFrm::IsColBreak()
1301 |* Beschreibung Wenn vor dem Frm ein harter Spaltenumbruch steht UND
1302 |* es einen Vorgaenger in der gleichen Spalte gibt, wird TRUE
1303 |* zurueckgeliefert (es muss ein PageBreak erzeugt werden) FALSE sonst.
1304 |* Wenn in bAct TRUE uebergeben wird, gibt die Funktion dann TRUE
1305 |* zurueck, wenn ein ColBreak besteht.
1306 |* Fuer Follows wird der harte Spaltenumbruch natuerlich nicht
1308 |* Der Spaltenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt
1309 |* des Vorgaengers (AFTER). Wenn es keinen Vorgaenger in der Spalte
1310 |* gibt ist jede weitere Ueberlegung ueberfluessig.
1311 |* Die Implementierung arbeitet zuaechst nur auf CntntFrms!
1312 |* -->Fuer LayoutFrms ist die Definition des Vorgaengers unklar.
1313 |* Ersterstellung MA 11. Jun. 93
1314 |* Letzte Aenderung MA 21. Mar. 95
1316 |*************************************************************************/
1318 BOOL
SwFlowFrm::IsColBreak( BOOL bAct
) const
1320 if ( !IsFollow() && (rThis
.IsMoveable() || bAct
) )
1322 const SwFrm
*pCol
= rThis
.FindColFrm();
1325 //Vorgaenger ermitteln
1326 const SwFrm
*pPrev
= rThis
.FindPrev();
1327 while( pPrev
&& ( ( !pPrev
->IsInDocBody() && !rThis
.IsInFly() ) ||
1328 ( pPrev
->IsTxtFrm() && ((SwTxtFrm
*)pPrev
)->IsHiddenNow() ) ) )
1329 pPrev
= pPrev
->FindPrev();
1334 { if ( pCol
== pPrev
->FindColFrm() )
1338 { if ( pCol
!= pPrev
->FindColFrm() )
1342 const SvxBreak eBreak
= rThis
.GetAttrSet()->GetBreak().GetBreak();
1343 if ( eBreak
== SVX_BREAK_COLUMN_BEFORE
||
1344 eBreak
== SVX_BREAK_COLUMN_BOTH
)
1348 const SvxBreak
&ePrB
= pPrev
->GetAttrSet()->GetBreak().GetBreak();
1349 if ( ePrB
== SVX_BREAK_COLUMN_AFTER
||
1350 ePrB
== SVX_BREAK_COLUMN_BOTH
)
1359 BOOL
SwFlowFrm::HasParaSpaceAtPages( BOOL bSct
) const
1361 if( rThis
.IsInSct() )
1363 const SwFrm
* pTmp
= rThis
.GetUpper();
1366 if( pTmp
->IsCellFrm() || pTmp
->IsFlyFrm() ||
1367 pTmp
->IsFooterFrm() || pTmp
->IsHeaderFrm() ||
1368 ( pTmp
->IsFtnFrm() && !((SwFtnFrm
*)pTmp
)->GetMaster() ) )
1370 if( pTmp
->IsPageFrm() )
1371 return ( pTmp
->GetPrev() && !IsPageBreak(TRUE
) ) ? FALSE
: TRUE
;
1372 if( pTmp
->IsColumnFrm() && pTmp
->GetPrev() )
1373 return IsColBreak( TRUE
);
1374 if( pTmp
->IsSctFrm() && ( !bSct
|| pTmp
->GetPrev() ) )
1376 pTmp
= pTmp
->GetUpper();
1378 ASSERT( FALSE
, "HasParaSpaceAtPages: Where's my page?" );
1381 if( !rThis
.IsInDocBody() || ( rThis
.IsInTab() && !rThis
.IsTabFrm()) ||
1382 IsPageBreak( TRUE
) || ( rThis
.FindColFrm() && IsColBreak( TRUE
) ) )
1384 const SwFrm
* pTmp
= rThis
.FindColFrm();
1387 if( pTmp
->GetPrev() )
1392 pTmp
= pTmp
->FindPageFrm();
1393 return pTmp
&& !pTmp
->GetPrev();
1396 /** helper method to determine previous frame for calculation of the
1399 OD 2004-03-10 #i11860#
1403 const SwFrm
* SwFlowFrm::_GetPrevFrmForUpperSpaceCalc( const SwFrm
* _pProposedPrevFrm
) const
1405 const SwFrm
* pPrevFrm
= _pProposedPrevFrm
1409 // Skip hidden paragraphs and empty sections
1411 ( ( pPrevFrm
->IsTxtFrm() &&
1412 static_cast<const SwTxtFrm
*>(pPrevFrm
)->IsHiddenNow() ) ||
1413 ( pPrevFrm
->IsSctFrm() &&
1414 !static_cast<const SwSectionFrm
*>(pPrevFrm
)->GetSection() ) ) )
1416 pPrevFrm
= pPrevFrm
->GetPrev();
1419 // Special case: no direct previous frame is found but frame is in footnote
1420 // Search for a previous frame in previous footnote,
1421 // if frame isn't in a section, which is also in the footnote
1422 if ( !pPrevFrm
&& rThis
.IsInFtn() &&
1423 ( rThis
.IsSctFrm() ||
1424 !rThis
.IsInSct() || !rThis
.FindSctFrm()->IsInFtn() ) )
1426 const SwFtnFrm
* pPrevFtnFrm
=
1427 static_cast<const SwFtnFrm
*>(rThis
.FindFtnFrm()->GetPrev());
1430 pPrevFrm
= pPrevFtnFrm
->GetLastLower();
1432 // Skip hidden paragraphs and empty sections
1434 ( ( pPrevFrm
->IsTxtFrm() &&
1435 static_cast<const SwTxtFrm
*>(pPrevFrm
)->IsHiddenNow() ) ||
1436 ( pPrevFrm
->IsSctFrm() &&
1437 !static_cast<const SwSectionFrm
*>(pPrevFrm
)->GetSection() ) ) )
1439 pPrevFrm
= pPrevFrm
->GetPrev();
1443 // Special case: found previous frame is a section
1444 // Search for the last content in the section
1445 if( pPrevFrm
&& pPrevFrm
->IsSctFrm() )
1447 const SwSectionFrm
* pPrevSectFrm
=
1448 static_cast<const SwSectionFrm
*>(pPrevFrm
);
1449 pPrevFrm
= pPrevSectFrm
->FindLastCntnt();
1450 // If the last content is in a table _inside_ the section,
1451 // take the table herself.
1452 // OD 2004-02-18 #106629# - correction:
1453 // Check directly, if table is inside table, instead of indirectly
1454 // by checking, if section isn't inside a table
1455 if ( pPrevFrm
&& pPrevFrm
->IsInTab() )
1457 const SwTabFrm
* pTableFrm
= pPrevFrm
->FindTabFrm();
1458 if ( pPrevSectFrm
->IsAnLower( pTableFrm
) )
1460 pPrevFrm
= pTableFrm
;
1463 // OD 2004-02-18 #106629# correction: skip hidden text frames
1465 pPrevFrm
->IsTxtFrm() &&
1466 static_cast<const SwTxtFrm
*>(pPrevFrm
)->IsHiddenNow() )
1468 pPrevFrm
= pPrevFrm
->GetPrev();
1475 // OD 2004-03-12 #i11860# - add 3rd parameter <_bConsiderGrid>
1476 SwTwips
SwFlowFrm::CalcUpperSpace( const SwBorderAttrs
*pAttrs
,
1478 const bool _bConsiderGrid
) const
1480 // OD 2004-03-10 #i11860# - use new method <GetPrevFrmForUpperSpaceCalc(..)>
1481 const SwFrm
* pPrevFrm
= _GetPrevFrmForUpperSpaceCalc( pPr
);
1483 SwBorderAttrAccess
*pAccess
;
1487 if( rThis
.IsSctFrm() )
1489 SwSectionFrm
* pFoll
= &((SwSectionFrm
&)rThis
);
1491 pOwn
= pFoll
->ContainsAny();
1492 while( !pOwn
&& 0 != ( pFoll
= pFoll
->GetFollow() ) );
1498 pAccess
= new SwBorderAttrAccess( SwFrm::GetCache(), pOwn
);
1499 pAttrs
= pAccess
->Get();
1507 // OD 06.01.2004 #i11859#
1509 const IDocumentSettingAccess
* pIDSA
= rThis
.GetUpper()->GetFmt()->getIDocumentSettingAccess();
1510 const bool bUseFormerLineSpacing
= pIDSA
->get(IDocumentSettingAccess::OLD_LINE_SPACING
);
1513 // OD 2004-03-10 #i11860# - use new method to determine needed spacing
1514 // values of found previous frame and use these values.
1515 SwTwips nPrevLowerSpace
= 0;
1516 SwTwips nPrevLineSpacing
= 0;
1517 // --> OD 2009-08-28 #i102458#
1518 bool bPrevLineSpacingPorportional
= false;
1519 GetSpacingValuesOfFrm( (*pPrevFrm
),
1520 nPrevLowerSpace
, nPrevLineSpacing
,
1521 bPrevLineSpacingPorportional
);
1523 if( pIDSA
->get(IDocumentSettingAccess::PARA_SPACE_MAX
) )
1525 nUpper
= nPrevLowerSpace
+ pAttrs
->GetULSpace().GetUpper();
1526 SwTwips nAdd
= nPrevLineSpacing
;
1527 // OD 07.01.2004 #i11859# - consideration of the line spacing
1528 // for the upper spacing of a text frame
1529 if ( bUseFormerLineSpacing
)
1531 // former consideration
1532 if ( pOwn
->IsTxtFrm() )
1534 nAdd
= Max( nAdd
, static_cast<SwTxtFrm
&>(rThis
).GetLineSpace() );
1540 // new consideration:
1541 // Only the proportional line spacing of the previous
1542 // text frame is considered for the upper spacing and
1543 // the line spacing values are add up instead of
1544 // building its maximum.
1545 if ( pOwn
->IsTxtFrm() )
1547 // --> OD 2009-08-28 #i102458#
1549 // A proportional line spacing of the previous text frame
1550 // is added up to a own leading line spacing.
1551 // Otherwise, the maximum of the leading line spacing
1552 // of the previous text frame and the own leading line
1553 // spacing is built.
1554 if ( bPrevLineSpacingPorportional
)
1556 nAdd
+= static_cast<SwTxtFrm
&>(rThis
).GetLineSpace( true );
1560 nAdd
= Max( nAdd
, static_cast<SwTxtFrm
&>(rThis
).GetLineSpace( true ) );
1569 nUpper
= Max( static_cast<long>(nPrevLowerSpace
),
1570 static_cast<long>(pAttrs
->GetULSpace().GetUpper()) );
1571 // OD 07.01.2004 #i11859# - consideration of the line spacing
1572 // for the upper spacing of a text frame
1573 if ( bUseFormerLineSpacing
)
1575 // former consideration
1576 if ( pOwn
->IsTxtFrm() )
1577 nUpper
= Max( nUpper
, ((SwTxtFrm
*)pOwn
)->GetLineSpace() );
1578 if ( nPrevLineSpacing
!= 0 )
1580 nUpper
= Max( nUpper
, nPrevLineSpacing
);
1585 // new consideration:
1586 // Only the proportional line spacing of the previous
1587 // text frame is considered for the upper spacing and
1588 // the line spacing values are add up and added to
1589 // the paragraph spacing instead of building the
1590 // maximum of the line spacings and the paragraph spacing.
1591 SwTwips nAdd
= nPrevLineSpacing
;
1592 if ( pOwn
->IsTxtFrm() )
1594 // --> OD 2009-08-28 #i102458#
1596 // A proportional line spacing of the previous text frame
1597 // is added up to a own leading line spacing.
1598 // Otherwise, the maximum of the leading line spacing
1599 // of the previous text frame and the own leading line
1600 // spacing is built.
1601 if ( bPrevLineSpacingPorportional
)
1603 nAdd
+= static_cast<SwTxtFrm
&>(rThis
).GetLineSpace( true );
1607 nAdd
= Max( nAdd
, static_cast<SwTxtFrm
&>(rThis
).GetLineSpace( true ) );
1615 else if ( pIDSA
->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES
) &&
1616 CastFlowFrm( pOwn
)->HasParaSpaceAtPages( rThis
.IsSctFrm() ) )
1618 nUpper
= pAttrs
->GetULSpace().GetUpper();
1622 // OD 2004-02-26 #i25029# - pass previous frame <pPrevFrm>
1623 // to method <GetTopLine(..)>, if parameter <pPr> is set.
1624 // Note: parameter <pPr> is set, if method is called from <SwTxtFrm::WouldFit(..)>
1625 nUpper
+= pAttrs
->GetTopLine( rThis
, (pPr
? pPrevFrm
: 0L) );
1627 // OD 2004-03-12 #i11860# - consider value of new parameter <_bConsiderGrid>
1628 // and use new method <GetUpperSpaceAmountConsideredForPageGrid(..)>
1630 //consider grid in square page mode
1631 if ( _bConsiderGrid
&& rThis
.GetUpper()->GetFmt()->GetDoc()->IsSquaredPageMode() )
1633 nUpper
+= _GetUpperSpaceAmountConsideredForPageGrid( nUpper
);
1640 /** method to detemine the upper space amount, which is considered for
1643 OD 2004-03-12 #i11860#
1644 Precondition: Position of frame is valid.
1648 SwTwips
SwFlowFrm::_GetUpperSpaceAmountConsideredForPageGrid(
1649 const SwTwips _nUpperSpaceWithoutGrid
) const
1651 SwTwips nUpperSpaceAmountConsideredForPageGrid
= 0;
1653 if ( rThis
.IsInDocBody() && rThis
.GetAttrSet()->GetParaGrid().GetValue() )
1655 const SwPageFrm
* pPageFrm
= rThis
.FindPageFrm();
1659 const SwFrm
* pBodyFrm
= pPageFrm
->FindBodyCont();
1662 const long nGridLineHeight
=
1663 pGrid
->GetBaseHeight() + pGrid
->GetRubyHeight();
1665 SWRECTFN( (&rThis
) )
1666 const SwTwips nBodyPrtTop
= (pBodyFrm
->*fnRect
->fnGetPrtTop
)();
1667 const SwTwips nProposedPrtTop
=
1668 (*fnRect
->fnYInc
)( (rThis
.Frm().*fnRect
->fnGetTop
)(),
1669 _nUpperSpaceWithoutGrid
);
1671 const SwTwips nSpaceAbovePrtTop
=
1672 (*fnRect
->fnYDiff
)( nProposedPrtTop
, nBodyPrtTop
);
1673 const SwTwips nSpaceOfCompleteLinesAbove
=
1674 nGridLineHeight
* ( nSpaceAbovePrtTop
/ nGridLineHeight
);
1675 SwTwips nNewPrtTop
=
1676 (*fnRect
->fnYInc
)( nBodyPrtTop
, nSpaceOfCompleteLinesAbove
);
1677 if ( (*fnRect
->fnYDiff
)( nProposedPrtTop
, nNewPrtTop
) > 0 )
1679 nNewPrtTop
= (*fnRect
->fnYInc
)( nNewPrtTop
, nGridLineHeight
);
1682 const SwTwips nNewUpperSpace
=
1683 (*fnRect
->fnYDiff
)( nNewPrtTop
,
1684 (rThis
.Frm().*fnRect
->fnGetTop
)() );
1686 nUpperSpaceAmountConsideredForPageGrid
=
1687 nNewUpperSpace
- _nUpperSpaceWithoutGrid
;
1689 ASSERT( nUpperSpaceAmountConsideredForPageGrid
>= 0,
1690 "<SwFlowFrm::GetUpperSpaceAmountConsideredForPageGrid(..)> - negative space considered for page grid!" );
1694 return nUpperSpaceAmountConsideredForPageGrid
;
1697 /** method to determent the upper space amount, which is considered for
1700 OD 2004-03-11 #i11860#
1704 SwTwips
SwFlowFrm::_GetUpperSpaceAmountConsideredForPrevFrm() const
1706 SwTwips nUpperSpaceAmountOfPrevFrm
= 0;
1708 const SwFrm
* pPrevFrm
= _GetPrevFrmForUpperSpaceCalc();
1711 SwTwips nPrevLowerSpace
= 0;
1712 SwTwips nPrevLineSpacing
= 0;
1713 // --> OD 2009-08-28 #i102458#
1714 bool bDummy
= false;
1715 GetSpacingValuesOfFrm( (*pPrevFrm
), nPrevLowerSpace
, nPrevLineSpacing
, bDummy
);
1717 if ( nPrevLowerSpace
> 0 || nPrevLineSpacing
> 0 )
1719 const IDocumentSettingAccess
* pIDSA
= rThis
.GetUpper()->GetFmt()->getIDocumentSettingAccess();
1720 if ( pIDSA
->get(IDocumentSettingAccess::PARA_SPACE_MAX
) ||
1721 !pIDSA
->get(IDocumentSettingAccess::OLD_LINE_SPACING
) )
1723 nUpperSpaceAmountOfPrevFrm
= nPrevLowerSpace
+ nPrevLineSpacing
;
1727 nUpperSpaceAmountOfPrevFrm
= Max( nPrevLowerSpace
, nPrevLineSpacing
);
1732 return nUpperSpaceAmountOfPrevFrm
;
1735 /** method to determine the upper space amount, which is considered for
1736 the previous frame and the page grid, if option 'Use former object
1739 OD 2004-03-18 #i11860#
1743 SwTwips
SwFlowFrm::GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() const
1745 SwTwips nUpperSpaceAmountConsideredForPrevFrmAndPageGrid
= 0;
1747 if ( !rThis
.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS
) )
1749 nUpperSpaceAmountConsideredForPrevFrmAndPageGrid
=
1750 _GetUpperSpaceAmountConsideredForPrevFrm() +
1751 _GetUpperSpaceAmountConsideredForPageGrid( CalcUpperSpace( 0L, 0L, false ) );
1754 return nUpperSpaceAmountConsideredForPrevFrmAndPageGrid
;
1757 /** calculation of lower space
1759 OD 2004-03-02 #106629#
1763 SwTwips
SwFlowFrm::CalcLowerSpace( const SwBorderAttrs
* _pAttrs
) const
1765 SwTwips nLowerSpace
= 0;
1767 SwBorderAttrAccess
* pAttrAccess
= 0L;
1770 pAttrAccess
= new SwBorderAttrAccess( SwFrm::GetCache(), &rThis
);
1771 _pAttrs
= pAttrAccess
->Get();
1774 sal_Bool bCommonBorder
= sal_True
;
1775 if ( rThis
.IsInSct() && rThis
.GetUpper()->IsColBodyFrm() )
1777 const SwSectionFrm
* pSectFrm
= rThis
.FindSctFrm();
1778 bCommonBorder
= pSectFrm
->GetFmt()->GetBalancedColumns().GetValue();
1780 nLowerSpace
= bCommonBorder
?
1781 _pAttrs
->GetBottomLine( rThis
) :
1782 _pAttrs
->CalcBottomLine();
1784 // --> OD 2004-07-16 #i26250#
1785 // - correct consideration of table frames
1786 // - use new method <CalcAddLowerSpaceAsLastInTableCell(..)>
1787 if ( ( ( rThis
.IsTabFrm() && rThis
.GetUpper()->IsInTab() ) ||
1788 // --> OD 2004-11-16 #115759# - no lower spacing, if frame has a follow
1789 ( rThis
.IsInTab() && !GetFollow() ) ) &&
1791 !rThis
.GetIndNext() )
1793 nLowerSpace
+= CalcAddLowerSpaceAsLastInTableCell( _pAttrs
);
1802 /** calculation of the additional space to be considered, if flow frame
1803 is the last inside a table cell
1805 OD 2004-07-16 #i26250#
1809 SwTwips
SwFlowFrm::CalcAddLowerSpaceAsLastInTableCell(
1810 const SwBorderAttrs
* _pAttrs
) const
1812 SwTwips nAdditionalLowerSpace
= 0;
1814 if ( rThis
.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS
) )
1816 const SwFrm
* pFrm
= &rThis
;
1817 if ( pFrm
->IsSctFrm() )
1819 const SwSectionFrm
* pSectFrm
= static_cast<const SwSectionFrm
*>(pFrm
);
1820 pFrm
= pSectFrm
->FindLastCntnt();
1821 if ( pFrm
&& pFrm
->IsInTab() )
1823 const SwTabFrm
* pTableFrm
= pFrm
->FindTabFrm();
1824 if ( pSectFrm
->IsAnLower( pTableFrm
) )
1831 SwBorderAttrAccess
* pAttrAccess
= 0L;
1832 if ( !_pAttrs
|| pFrm
!= &rThis
)
1834 pAttrAccess
= new SwBorderAttrAccess( SwFrm::GetCache(), pFrm
);
1835 _pAttrs
= pAttrAccess
->Get();
1838 nAdditionalLowerSpace
+= _pAttrs
->GetULSpace().GetLower();
1843 return nAdditionalLowerSpace
;
1846 /*************************************************************************
1848 |* BOOL SwFlowFrm::CheckMoveFwd()
1850 |* Beschreibung Moved den Frm vorwaerts wenn es durch die aktuellen
1851 |* Bedingungen und Attribute notwendig erscheint.
1852 |* Ersterstellung MA 05. Dec. 96
1853 |* Letzte Aenderung MA 09. Mar. 98
1855 |*************************************************************************/
1858 BOOL
SwFlowFrm::CheckMoveFwd( BOOL
&rbMakePage
, BOOL bKeep
, BOOL
)
1860 const SwFrm
* pNxt
= rThis
.GetIndNext();
1862 if ( bKeep
&& //!bMovedBwd &&
1863 ( !pNxt
|| ( pNxt
->IsTxtFrm() && ((SwTxtFrm
*)pNxt
)->IsEmptyMaster() ) ) &&
1864 ( 0 != (pNxt
= rThis
.FindNext()) ) && IsKeepFwdMoveAllowed() )
1866 if( pNxt
->IsSctFrm() )
1867 { // Nicht auf leere SectionFrms hereinfallen
1868 const SwFrm
* pTmp
= NULL
;
1869 while( pNxt
&& pNxt
->IsSctFrm() &&
1870 ( !((SwSectionFrm
*)pNxt
)->GetSection() ||
1871 0 == ( pTmp
= ((SwSectionFrm
*)pNxt
)->ContainsAny() ) ) )
1873 pNxt
= pNxt
->FindNext();
1877 pNxt
= pTmp
; // the content of the next notempty sectionfrm
1879 if( pNxt
&& pNxt
->GetValidPosFlag() )
1882 const SwSectionFrm
*pSct
= rThis
.FindSctFrm();
1883 if( pSct
&& !pSct
->GetValidSizeFlag() )
1885 const SwSectionFrm
* pNxtSct
= pNxt
->FindSctFrm();
1886 if( pNxtSct
&& pSct
->IsAnFollow( pNxtSct
) )
1893 //Keep together with the following frame
1894 MoveFwd( rbMakePage
, FALSE
);
1900 BOOL bMovedFwd
= FALSE
;
1902 if ( rThis
.GetIndPrev() )
1904 if ( IsPrevObjMove() ) //Auf Objekte des Prev Ruecksicht nehmen?
1907 if ( !MoveFwd( rbMakePage
, FALSE
) )
1912 if ( IsPageBreak( FALSE
) )
1914 while ( MoveFwd( rbMakePage
, TRUE
) )
1919 else if ( IsColBreak ( FALSE
) )
1921 const SwPageFrm
*pPage
= rThis
.FindPageFrm();
1922 SwFrm
*pCol
= rThis
.FindColFrm();
1924 { MoveFwd( rbMakePage
, FALSE
);
1925 SwFrm
*pTmp
= rThis
.FindColFrm();
1933 } while ( IsColBreak( FALSE
) );
1934 if ( pPage
!= rThis
.FindPageFrm() )
1942 /*************************************************************************
1944 |* BOOL SwFlowFrm::MoveFwd()
1946 |* Beschreibung Returnwert sagt, ob der Frm die Seite gewechselt hat.
1947 |* Ersterstellung MA 05. Dec. 96
1948 |* Letzte Aenderung MA 05. Dec. 96
1950 |*************************************************************************/
1953 BOOL
SwFlowFrm::MoveFwd( BOOL bMakePage
, BOOL bPageBreak
, BOOL bMoveAlways
)
1955 //!!!!MoveFtnCntFwd muss ggf. mitgepflegt werden.
1956 SwFtnBossFrm
*pOldBoss
= rThis
.FindFtnBossFrm();
1957 if ( rThis
.IsInFtn() )
1958 return ((SwCntntFrm
&)rThis
).MoveFtnCntFwd( bMakePage
, pOldBoss
);
1960 if( !IsFwdMoveAllowed() && !bMoveAlways
)
1963 if( rThis
.IsInSct() )
1965 SwFtnBossFrm
* pBoss
= rThis
.FindFtnBossFrm();
1966 bNoFwd
= !pBoss
->IsInSct() || ( !pBoss
->Lower()->GetNext() &&
1967 !pBoss
->GetPrev() );
1970 // Allow the MoveFwd even if we do not have an IndPrev in these cases:
1971 if ( rThis
.IsInTab() &&
1972 ( !rThis
.IsTabFrm() ||
1973 ( rThis
.GetUpper()->IsInTab() &&
1974 rThis
.GetUpper()->FindTabFrm()->IsFwdMoveAllowed() ) ) &&
1975 0 != const_cast<SwFrm
&>(rThis
).GetNextCellLeaf( MAKEPAGE_NONE
) )
1979 // Have a look at our main competitor: We don't move inside row span cells:
1980 ( !rThis.GetUpper()->IsCellFrm() || !rThis.GetUpper()->IsLeaveUpperAllowed() ) )*/
1987 //Fuer PageBreak ist das Moven erlaubt, wenn der Frm nicht
1988 //bereits der erste der Seite ist.
1992 const SwFrm
*pCol
= rThis
.FindColFrm();
1993 if ( !pCol
|| !pCol
->GetPrev() )
1998 BOOL bSamePage
= TRUE
;
1999 SwLayoutFrm
*pNewUpper
=
2000 rThis
.GetLeaf( bMakePage
? MAKEPAGE_INSERT
: MAKEPAGE_NONE
, TRUE
);
2004 PROTOCOL_ENTER( &rThis
, PROT_MOVE_FWD
, 0, 0 );
2005 SwPageFrm
*pOldPage
= pOldBoss
->FindPageFrm();
2006 //Wir moven uns und alle direkten Nachfolger vor den ersten
2007 //CntntFrm unterhalb des neuen Uppers.
2009 // Wenn unser NewUpper in einem SectionFrm liegt, muessen wir
2010 // verhindern, dass sich dieser im Calc selbst zerstoert
2011 SwSectionFrm
* pSect
= pNewUpper
->FindSctFrm();
2012 BOOL bUnlock
= FALSE
;
2015 // Wenn wir nur innerhalb unseres SectionFrms die Spalte wechseln,
2016 // rufen wir lieber kein Calc, sonst wird noch der SectionFrm
2017 // formatiert, der wiederum uns ruft etc.
2018 if( pSect
!= rThis
.FindSctFrm() )
2020 bUnlock
= !pSect
->IsColLocked();
2027 // Do not calculate split cell frames.
2028 else if ( !pNewUpper
->IsCellFrm() || ((SwLayoutFrm
*)pNewUpper
)->Lower() )
2031 SwFtnBossFrm
*pNewBoss
= pNewUpper
->FindFtnBossFrm();
2032 BOOL bBossChg
= pNewBoss
!= pOldBoss
;
2033 pNewBoss
= pNewBoss
->FindFtnBossFrm( TRUE
);
2034 pOldBoss
= pOldBoss
->FindFtnBossFrm( TRUE
);
2035 SwPageFrm
* pNewPage
= pOldPage
;
2037 // First, we move the footnotes.
2038 BOOL bFtnMoved
= FALSE
;
2040 // --> FME 2004-07-15 #i26831#
2041 // If pSect has just been created, the printing area of pSect has
2042 // been calculated based on the first content of its follow.
2043 // In this case we prefer to call a SimpleFormat for this new
2044 // section after we inserted the contents. Otherwise the section
2045 // frame will invalidate its lowers, if its printing area changes
2046 // in SwSectionFrm::Format, which can cause loops.
2047 const bool bForceSimpleFormat
= pSect
&& pSect
->HasFollow() &&
2048 !pSect
->ContainsAny();
2051 if ( pNewBoss
!= pOldBoss
)
2053 pNewPage
= pNewBoss
->FindPageFrm();
2054 bSamePage
= pNewPage
== pOldPage
;
2055 //Damit die Fussnoten nicht auf dumme Gedanken kommen
2056 //setzen wir hier die Deadline.
2057 SWRECTFN( pOldBoss
)
2058 SwSaveFtnHeight
aHeight( pOldBoss
,
2059 (pOldBoss
->Frm().*fnRect
->fnGetBottom
)() );
2060 SwCntntFrm
* pStart
= rThis
.IsCntntFrm() ?
2061 (SwCntntFrm
*)&rThis
: ((SwLayoutFrm
&)rThis
).ContainsCntnt();
2062 ASSERT( pStart
|| ( rThis
.IsTabFrm() && !((SwTabFrm
&)rThis
).Lower() ),
2063 "MoveFwd: Missing Content" );
2064 SwLayoutFrm
* pBody
= pStart
? ( pStart
->IsTxtFrm() ?
2065 (SwLayoutFrm
*)((SwTxtFrm
*)pStart
)->FindBodyFrm() : 0 ) : 0;
2067 bFtnMoved
= pBody
->MoveLowerFtns( pStart
, pOldBoss
, pNewBoss
,
2070 // Bei SectionFrms ist es moeglich, dass wir selbst durch pNewUpper->Calc()
2071 // bewegt wurden, z. B. in den pNewUpper.
2072 // MoveSubTree bzw. PasteTree ist auf so etwas nicht vorbereitet.
2073 if( pNewUpper
!= rThis
.GetUpper() )
2075 // --> FME 2004-04-19 #i27145#
2076 SwSectionFrm
* pOldSct
= 0;
2077 if ( rThis
.GetUpper()->IsSctFrm() )
2079 pOldSct
= static_cast<SwSectionFrm
*>(rThis
.GetUpper());
2083 MoveSubTree( pNewUpper
, pNewUpper
->Lower() );
2085 // --> FME 2004-04-19 #i27145#
2086 if ( pOldSct
&& pOldSct
->GetSection() )
2088 // Prevent loops by setting the new height at
2089 // the section frame if footnotes have been moved.
2090 // Otherwise the call of SwLayNotify::~SwLayNotify() for
2091 // the (invalid) section frame will invalidate the first
2092 // lower of its follow, because it grows due to the removed
2094 // Note: If pOldSct has become empty during MoveSubTree, it
2095 // has already been scheduled for removal. No SimpleFormat
2097 pOldSct
->SimpleFormat();
2101 // --> FME 2004-07-15 #i26831#
2102 if ( bForceSimpleFormat
)
2104 pSect
->SimpleFormat();
2108 if ( bFtnMoved
&& !bSamePage
)
2110 pOldPage
->UpdateFtnNum();
2111 pNewPage
->UpdateFtnNum();
2116 rThis
.Prepare( PREP_BOSS_CHGD
, 0, FALSE
);
2119 ViewShell
*pSh
= rThis
.GetShell();
2120 if ( pSh
&& !pSh
->Imp()->IsUpdateExpFlds() )
2121 pSh
->GetDoc()->SetNewFldLst(true); //Wird von CalcLayout() hinterher erledigt!
2123 pNewPage
->InvalidateSpelling();
2124 pNewPage
->InvalidateSmartTags(); // SMARTTAGS
2125 pNewPage
->InvalidateAutoCompleteWords();
2126 pNewPage
->InvalidateWordCount();
2130 // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
2131 if ( !pNewPage
->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
2133 //Bei Sections kann es passieren, das wir gleich in den Follow geflutscht
2134 //sind. Dadurch wird nicht vom GetLeaf fuer die richtige Seite gesorgt.
2135 //Das muessen wir fuer diesen Fall pruefen.
2136 if ( !bSamePage
&& pNewUpper
->IsInSct() &&
2137 ( rThis
.GetAttrSet()->GetPageDesc().GetPageDesc() ||
2138 pOldPage
->GetPageDesc()->GetFollow() != pNewPage
->GetPageDesc() ) )
2139 SwFrm::CheckPageDescs( pNewPage
, FALSE
);
2146 /*************************************************************************
2148 |* BOOL SwFlowFrm::MoveBwd()
2150 |* Beschreibung Returnwert sagt, ob der Frm die Seite wechseln soll.
2151 |* Sollte von abgeleiteten Klassen gerufen werden.
2152 |* Das moven selbst muessen die abgeleiteten uebernehmen.
2153 |* Ersterstellung MA 05. Dec. 96
2154 |* Letzte Aenderung MA 05. Dec. 96
2156 |*************************************************************************/
2158 BOOL
SwFlowFrm::MoveBwd( BOOL
&rbReformat
)
2160 SwFlowFrm::SetMoveBwdJump( FALSE
);
2162 SwFtnFrm
* pFtn
= rThis
.FindFtnFrm();
2163 if ( pFtn
&& pFtn
->IsBackMoveLocked() )
2166 // --> OD 2004-11-29 #115759# - text frames, which are directly inside
2167 // tables aren't allowed to move backward.
2168 if ( rThis
.IsTxtFrm() && rThis
.IsInTab() )
2170 const SwLayoutFrm
* pUpperFrm
= rThis
.GetUpper();
2173 if ( pUpperFrm
->IsTabFrm() )
2177 else if ( pUpperFrm
->IsColumnFrm() && pUpperFrm
->IsInSct() )
2181 pUpperFrm
= pUpperFrm
->GetUpper();
2186 SwFtnBossFrm
* pOldBoss
= rThis
.FindFtnBossFrm();
2187 SwPageFrm
* const pOldPage
= pOldBoss
->FindPageFrm();
2188 SwLayoutFrm
*pNewUpper
= 0;
2189 BOOL bCheckPageDescs
= FALSE
;
2190 bool bCheckPageDescOfNextPage
= false;
2194 //Wenn die Fussnote bereits auf der gleichen Seite/Spalte wie die Referenz
2195 //steht, ist nix mit zurueckfliessen. Die breaks brauche fuer die
2196 //Fussnoten nicht geprueft zu werden.
2198 // --> FME 2004-11-15 #i37084# FindLastCntnt does not necessarily
2199 // have to have a result != 0
2201 const bool bEndnote
= pFtn
->GetAttr()->GetFtn().IsEndNote();
2202 if( bEndnote
&& pFtn
->IsInSct() )
2204 SwSectionFrm
* pSect
= pFtn
->FindSctFrm();
2205 if( pSect
->IsEndnAtEnd() )
2206 pRef
= pSect
->FindLastCntnt( FINDMODE_LASTCNT
);
2209 pRef
= pFtn
->GetRef();
2212 ASSERT( pRef
, "MoveBwd: Endnote for an empty section?" );
2215 pOldBoss
= pOldBoss
->FindFtnBossFrm( TRUE
);
2216 SwFtnBossFrm
*pRefBoss
= pRef
->FindFtnBossFrm( !bEndnote
);
2217 if ( pOldBoss
!= pRefBoss
&&
2218 // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
2220 pRefBoss
->IsBefore( pOldBoss
) )
2222 pNewUpper
= rThis
.GetLeaf( MAKEPAGE_FTN
, FALSE
);
2224 else if ( IsPageBreak( TRUE
) ) //PageBreak zu beachten?
2226 //Wenn auf der vorhergehenden Seite kein Frm im Body steht,
2227 //so ist das Zurueckfliessen trotz Pagebreak sinnvoll
2228 //(sonst: leere Seite).
2229 //Natuerlich muessen Leereseiten geflissentlich uebersehen werden!
2230 const SwFrm
*pFlow
= &rThis
;
2233 pFlow
= pFlow
->FindPrev();
2235 ( pFlow
->FindPageFrm() == pOldPage
||
2236 !pFlow
->IsInDocBody() ) );
2239 long nDiff
= pOldPage
->GetPhyPageNum() - pFlow
->GetPhyPageNum();
2242 if ( ((SwPageFrm
*)pOldPage
->GetPrev())->IsEmptyPage() )
2246 pNewUpper
= rThis
.GetLeaf( MAKEPAGE_NONE
, FALSE
);
2247 // --> OD 2006-05-08 #i53139#
2248 // Now <pNewUpper> is a previous layout frame, which contains
2249 // content. But the new upper layout frame has to be the next one.
2250 // Thus, hack for issue i14206 no longer needed, but fix for issue 114442
2251 // --> OD 2006-05-17 #136024# - correct fix for i53139:
2252 // Check for wrong page description before using next new upper.
2253 // --> OD 2006-06-06 #i66051# - further correction of fix for i53139
2254 // Check for correct type of new next upper layout frame
2255 // --> OD 2006-06-08 #136538# - another correction of fix for i53139
2256 // Assumption, that in all cases <pNewUpper> is a previous
2257 // layout frame, which contains content, is wrong.
2258 // --> OD 2006-07-05 #136538# - another correction of fix for i53139
2259 // Beside type check, check also, if proposed new next upper
2260 // frame is inside the same frame types.
2261 // --> OD 2007-01-10 #i73194# - and yet another correction
2262 // of fix for i53139:
2263 // Assure that the new next upper layout frame doesn't
2264 // equal the current one.
2265 // E.g.: content is on page 3, on page 2 is only a 'ghost'
2266 // section and on page 1 is normal content. Method <FindPrev(..)>
2267 // will find the last content of page 1, but <GetLeaf(..)>
2268 // returns new upper on page 2.
2269 if ( pNewUpper
->Lower() )
2271 SwLayoutFrm
* pNewNextUpper
= pNewUpper
->GetLeaf( MAKEPAGE_NONE
, TRUE
);
2272 if ( pNewNextUpper
&&
2273 pNewNextUpper
!= rThis
.GetUpper() &&
2274 pNewNextUpper
->GetType() == pNewUpper
->GetType() &&
2275 pNewNextUpper
->IsInDocBody() == pNewUpper
->IsInDocBody() &&
2276 pNewNextUpper
->IsInFtn() == pNewUpper
->IsInFtn() &&
2277 pNewNextUpper
->IsInTab() == pNewUpper
->IsInTab() &&
2278 pNewNextUpper
->IsInSct() == pNewUpper
->IsInSct() &&
2279 !rThis
.WrongPageDesc( pNewNextUpper
->FindPageFrm() ) )
2281 pNewUpper
= pNewNextUpper
;
2282 bCheckPageDescOfNextPage
= true;
2287 bCheckPageDescs
= TRUE
;
2292 else if ( IsColBreak( TRUE
) )
2294 //Wenn in der vorhergehenden Spalte kein CntntFrm steht, so ist
2295 //das Zurueckfliessen trotz ColumnBreak sinnvoll
2296 //(sonst: leere Spalte).
2297 if( rThis
.IsInSct() )
2299 pNewUpper
= rThis
.GetLeaf( MAKEPAGE_NONE
, FALSE
);
2300 if( pNewUpper
&& !SwFlowFrm::IsMoveBwdJump() &&
2301 ( pNewUpper
->ContainsCntnt() ||
2302 ( ( !pNewUpper
->IsColBodyFrm() ||
2303 !pNewUpper
->GetUpper()->GetPrev() ) &&
2304 !pNewUpper
->FindSctFrm()->GetPrev() ) ) )
2308 // --> OD 2006-05-08 #i53139#
2309 // --> OD 2006-09-11 #i69409# - check <pNewUpper>
2310 // --> OD 2006-11-02 #i71065# - check <SwFlowFrm::IsMoveBwdJump()>
2311 else if ( pNewUpper
&& !SwFlowFrm::IsMoveBwdJump() )
2314 // Now <pNewUpper> is a previous layout frame, which
2315 // contains content. But the new upper layout frame
2316 // has to be the next one.
2317 // --> OD 2006-05-17 #136024# - correct fix for i53139
2318 // Check for wrong page description before using next new upper.
2319 // --> OD 2006-06-06 #i66051# - further correction of fix for i53139
2320 // Check for correct type of new next upper layout frame
2321 // --> OD 2006-07-05 #136538# - another correction of fix for i53139
2322 // Beside type check, check also, if proposed new next upper
2323 // frame is inside the same frame types.
2324 SwLayoutFrm
* pNewNextUpper
= pNewUpper
->GetLeaf( MAKEPAGE_NOSECTION
, TRUE
);
2325 if ( pNewNextUpper
&&
2326 pNewNextUpper
->GetType() == pNewUpper
->GetType() &&
2327 pNewNextUpper
->IsInDocBody() == pNewUpper
->IsInDocBody() &&
2328 pNewNextUpper
->IsInFtn() == pNewUpper
->IsInFtn() &&
2329 pNewNextUpper
->IsInTab() == pNewUpper
->IsInTab() &&
2330 pNewNextUpper
->IsInSct() == pNewUpper
->IsInSct() &&
2331 !rThis
.WrongPageDesc( pNewNextUpper
->FindPageFrm() ) )
2333 pNewUpper
= pNewNextUpper
;
2340 const SwFrm
*pCol
= rThis
.FindColFrm();
2345 if ( pCol
->GetPrev() )
2346 pCol
= pCol
->GetPrev();
2350 pCol
= rThis
.GetLeaf( MAKEPAGE_NONE
, FALSE
);
2354 // ColumnFrms jetzt mit BodyFrm
2355 SwLayoutFrm
* pColBody
= pCol
->IsColumnFrm() ?
2356 (SwLayoutFrm
*)((SwLayoutFrm
*)pCol
)->Lower() :
2358 if ( pColBody
->ContainsCntnt() )
2360 bGoOn
= FALSE
; // Hier gibt's Inhalt, wir akzeptieren diese
2361 // nur, wenn GetLeaf() das MoveBwdJump-Flag gesetzt hat.
2362 if( SwFlowFrm::IsMoveBwdJump() )
2364 pNewUpper
= pColBody
;
2365 // --> OD 2006-05-08 #i53139#
2366 // Now <pNewUpper> is a previous layout frame, which
2367 // contains content. But the new upper layout frame
2368 // has to be the next one.
2369 // --> OD 2006-05-17 #136024# - correct fix for i53139
2370 // Check for wrong page description before using next new upper.
2371 // --> OD 2006-06-06 #i66051# - further correction of fix for i53139
2372 // Check for correct type of new next upper layout frame
2373 // --> OD 2006-07-05 #136538# - another correction of fix for i53139
2374 // Beside type check, check also, if proposed new next upper
2375 // frame is inside the same frame types.
2376 // --> OD 2006-11-02 #i71065#
2377 // Check that the proposed new next upper layout
2378 // frame isn't the current one.
2379 SwLayoutFrm
* pNewNextUpper
= pNewUpper
->GetLeaf( MAKEPAGE_NONE
, TRUE
);
2380 if ( pNewNextUpper
&&
2381 pNewNextUpper
!= rThis
.GetUpper() &&
2382 pNewNextUpper
->GetType() == pNewUpper
->GetType() &&
2383 pNewNextUpper
->IsInDocBody() == pNewUpper
->IsInDocBody() &&
2384 pNewNextUpper
->IsInFtn() == pNewUpper
->IsInFtn() &&
2385 pNewNextUpper
->IsInTab() == pNewUpper
->IsInTab() &&
2386 pNewNextUpper
->IsInSct() == pNewUpper
->IsInSct() &&
2387 !rThis
.WrongPageDesc( pNewNextUpper
->FindPageFrm() ) )
2389 pNewUpper
= pNewNextUpper
;
2396 if( pNewUpper
) // Wir hatten schon eine leere Spalte, haben
2397 bJump
= TRUE
; // also eine uebersprungen
2398 pNewUpper
= pColBody
; // Diese leere Spalte kommt in Frage,
2399 // trotzdem weitersuchen
2404 SwFlowFrm::SetMoveBwdJump( TRUE
);
2407 else //Keine Breaks also kann ich zurueckfliessen
2408 pNewUpper
= rThis
.GetLeaf( MAKEPAGE_NONE
, FALSE
);
2410 // --> OD 2004-06-23 #i27801# - no move backward of 'master' text frame,
2411 // if - due to its object positioning - it isn't allowed to be on the new page frame
2412 // --> OD 2005-03-07 #i44049# - add another condition for not moving backward:
2413 // If one of its objects has restarted the layout process, moving backward
2414 // isn't sensible either.
2415 // --> OD 2005-04-19 #i47697# - refine condition made for issue i44049:
2416 // - allow move backward as long as the anchored object is only temporarily
2417 // positions considering its wrapping style.
2419 rThis
.IsTxtFrm() && !IsFollow() )
2421 sal_uInt32
nToPageNum( 0L );
2422 const bool bMoveFwdByObjPos
= SwLayouter::FrmMovedFwdByObjPos(
2423 *(pOldPage
->GetFmt()->GetDoc()),
2424 static_cast<SwTxtFrm
&>(rThis
),
2426 if ( bMoveFwdByObjPos
&&
2427 pNewUpper
->FindPageFrm()->GetPhyPageNum() < nToPageNum
)
2431 // --> OD 2005-03-07 #i44049# - check, if one of its anchored objects
2432 // has restarted the layout process.
2433 else if ( rThis
.GetDrawObjs() )
2436 for ( ; i
< rThis
.GetDrawObjs()->Count(); ++i
)
2438 SwAnchoredObject
* pAnchoredObj
= (*rThis
.GetDrawObjs())[i
];
2439 // --> OD 2005-04-19 #i47697# - refine condition - see above
2440 if ( pAnchoredObj
->RestartLayoutProcess() &&
2441 !pAnchoredObj
->IsTmpConsiderWrapInfluence() )
2453 //Fuer Follows ist das zurueckfliessen nur dann erlaubt wenn in der
2454 //neuen Umgebung kein Nachbar existiert (denn dieses waere der Master).
2455 //(6677)Wenn allerdings leere Blaetter uebersprungen wurden wird doch gemoved.
2456 if ( pNewUpper
&& IsFollow() && pNewUpper
->Lower() )
2458 // --> OD 2007-09-05 #i79774#, #b6596954#
2459 // neglect empty sections in proposed new upper frame
2460 bool bProposedNewUpperContainsOnlyEmptySections( true );
2462 const SwFrm
* pLower( pNewUpper
->Lower() );
2465 if ( pLower
->IsSctFrm() &&
2466 !dynamic_cast<const SwSectionFrm
*>(pLower
)->GetSection() )
2468 pLower
= pLower
->GetNext();
2473 bProposedNewUpperContainsOnlyEmptySections
= false;
2478 if ( !bProposedNewUpperContainsOnlyEmptySections
)
2480 if ( SwFlowFrm::IsMoveBwdJump() )
2482 //Nicht hinter den Master sondern in das naechstfolgende leere
2484 SwFrm
*pFrm
= pNewUpper
->Lower();
2485 while ( pFrm
->GetNext() )
2486 pFrm
= pFrm
->GetNext();
2487 pNewUpper
= pFrm
->GetLeaf( MAKEPAGE_INSERT
, TRUE
);
2488 if( pNewUpper
== rThis
.GetUpper() ) //Landen wir wieder an der gleichen Stelle?
2489 pNewUpper
= NULL
; //dann eruebrigt sich das Moven
2496 if ( pNewUpper
&& !ShouldBwdMoved( pNewUpper
, TRUE
, rbReformat
) )
2498 if( !pNewUpper
->Lower() )
2500 if( pNewUpper
->IsFtnContFrm() )
2507 SwSectionFrm
* pSectFrm
= pNewUpper
->FindSctFrm();
2508 // --> OD 2006-01-04 #126020# - adjust check for empty section
2509 // --> OD 2006-02-01 #130797# - correct fix #126020#
2510 if ( pSectFrm
&& !pSectFrm
->IsColLocked() &&
2511 !pSectFrm
->ContainsCntnt() && !pSectFrm
->ContainsAny( true ) )
2514 pSectFrm
->DelEmpty( TRUE
);
2516 rThis
.bValidPos
= TRUE
;
2523 // OD 2004-05-26 #i21478# - don't move backward, if flow frame wants to
2524 // keep with next frame and next frame is locked.
2525 // --> OD 2004-12-08 #i38232# - If next frame is a table, do *not* check,
2527 if ( pNewUpper
&& !IsFollow() &&
2528 rThis
.GetAttrSet()->GetKeep().GetValue() && rThis
.GetIndNext() )
2530 SwFrm
* pIndNext
= rThis
.GetIndNext();
2531 // --> OD 2004-12-08 #i38232#
2532 if ( !pIndNext
->IsTabFrm() )
2534 // get first content of section, while empty sections are skipped
2535 while ( pIndNext
&& pIndNext
->IsSctFrm() )
2537 if( static_cast<SwSectionFrm
*>(pIndNext
)->GetSection() )
2539 SwFrm
* pTmp
= static_cast<SwSectionFrm
*>(pIndNext
)->ContainsAny();
2546 pIndNext
= pIndNext
->GetIndNext();
2548 ASSERT( !pIndNext
|| pIndNext
->ISA(SwTxtFrm
),
2549 "<SwFlowFrm::MovedBwd(..)> - incorrect next found." );
2550 if ( pIndNext
&& pIndNext
->IsFlowFrm() &&
2551 SwFlowFrm::CastFlowFrm(pIndNext
)->IsJoinLocked() )
2559 // --> OD 2006-05-10 #i65250#
2560 // layout loop control for flowing content again and again moving
2561 // backward under the same layout condition.
2562 if ( pNewUpper
&& !IsFollow() &&
2563 pNewUpper
!= rThis
.GetUpper() &&
2564 SwLayouter::MoveBwdSuppressed( *(pOldPage
->GetFmt()->GetDoc()),
2565 *this, *pNewUpper
) )
2567 SwLayoutFrm
* pNextNewUpper
= pNewUpper
->GetLeaf(
2568 ( !rThis
.IsSctFrm() && rThis
.IsInSct() )
2569 ? MAKEPAGE_NOSECTION
2572 // --> OD 2007-01-10 #i73194# - make code robust
2573 ASSERT( pNextNewUpper
, "<SwFlowFrm::MoveBwd(..)> - missing next new upper" );
2574 if ( pNextNewUpper
&&
2575 ( pNextNewUpper
== rThis
.GetUpper() ||
2576 pNextNewUpper
->GetType() != rThis
.GetUpper()->GetType() ) )
2580 #if OSL_DEBUG_LEVEL > 1
2582 "<SwFlowFrm::MoveBwd(..)> - layout loop control for layout action <Move Backward> applied!" );
2588 ASSERT( pNewUpper
!= rThis
.GetUpper(),
2589 "<SwFlowFrm::MoveBwd(..)> - moving backward to the current upper frame!? -> Please inform OD." );
2592 PROTOCOL_ENTER( &rThis
, PROT_MOVE_BWD
, 0, 0 );
2593 if ( pNewUpper
->IsFtnContFrm() )
2595 //Kann sein, dass ich einen Container bekam.
2596 SwFtnFrm
*pOld
= rThis
.FindFtnFrm();
2597 SwFtnFrm
*pNew
= new SwFtnFrm( pOld
->GetFmt(),
2598 pOld
->GetRef(), pOld
->GetAttr() );
2599 if ( pOld
->GetMaster() )
2601 pNew
->SetMaster( pOld
->GetMaster() );
2602 pOld
->GetMaster()->SetFollow( pNew
);
2604 pNew
->SetFollow( pOld
);
2605 pOld
->SetMaster( pNew
);
2606 pNew
->Paste( pNewUpper
);
2609 if( pNewUpper
->IsFtnFrm() && rThis
.IsInSct() )
2611 SwSectionFrm
* pSct
= rThis
.FindSctFrm();
2612 //Wenn wir in einem Bereich in einer Fussnote stecken, muss im
2613 //neuen Upper ggf. ein SwSectionFrm angelegt werden
2614 if( pSct
->IsInFtn() )
2616 SwFrm
* pTmp
= pNewUpper
->Lower();
2619 while( pTmp
->GetNext() )
2620 pTmp
= pTmp
->GetNext();
2621 if( !pTmp
->IsSctFrm() ||
2622 ((SwSectionFrm
*)pTmp
)->GetFollow() != pSct
)
2626 pNewUpper
= (SwSectionFrm
*)pTmp
;
2629 pSct
= new SwSectionFrm( *pSct
, TRUE
);
2630 pSct
->Paste( pNewUpper
);
2633 pSct
->SimpleFormat();
2637 BOOL bUnlock
= FALSE
;
2638 BOOL bFollow
= FALSE
;
2639 //Section locken, sonst kann sie bei Fluss des einzigen Cntnt etwa
2640 //von zweiter in die erste Spalte zerstoert werden.
2641 SwSectionFrm
* pSect
= pNewUpper
->FindSctFrm();
2644 bUnlock
= !pSect
->IsColLocked();
2646 bFollow
= pSect
->HasFollow();
2650 // --> OD 2005-02-23 #b6229852#
2651 // optimization: format section, if its size is invalidated and if it's
2652 // the new parent of moved backward frame.
2653 bool bFormatSect( false );
2658 if( pSect
->HasFollow() != bFollow
)
2660 pSect
->InvalidateSize();
2661 // --> OD 2005-02-23 #b6229852# - optimization
2662 if ( pSect
== pNewUpper
)
2668 rThis
.Paste( pNewUpper
);
2669 // --> OD 2005-02-23 #b6229852# - optimization
2674 SwPageFrm
*pNewPage
= rThis
.FindPageFrm();
2675 if( pNewPage
!= pOldPage
)
2677 rThis
.Prepare( PREP_BOSS_CHGD
, (const void*)pOldPage
, FALSE
);
2678 ViewShell
*pSh
= rThis
.GetShell();
2679 if ( pSh
&& !pSh
->Imp()->IsUpdateExpFlds() )
2680 pSh
->GetDoc()->SetNewFldLst(true); //Wird von CalcLayout() hinterher eledigt!
2682 pNewPage
->InvalidateSpelling();
2683 pNewPage
->InvalidateSmartTags(); // SMARTTAGS
2684 pNewPage
->InvalidateAutoCompleteWords();
2685 pNewPage
->InvalidateWordCount();
2687 // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
2688 if ( !pNewPage
->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
2690 if ( bCheckPageDescs
&& pNewPage
->GetNext() )
2692 SwPageFrm
* pStartPage
= bCheckPageDescOfNextPage
?
2694 (SwPageFrm
*)pNewPage
->GetNext();
2695 SwFrm::CheckPageDescs( pStartPage
, FALSE
);
2697 else if ( rThis
.GetAttrSet()->GetPageDesc().GetPageDesc() )
2699 //Erste Seite wird etwa durch Ausblenden eines Bereiches leer
2700 SwFrm::CheckPageDescs( (SwPageFrm
*)pNewPage
, FALSE
);
2705 return pNewUpper
!= 0;
2708 /*************************************************************************
2710 |* SwFlowFrm::CastFlowFrm
2712 |* Ersterstellung MA 03. May. 95
2713 |* Letzte Aenderung AMA 02. Dec. 97
2715 |*************************************************************************/
2717 SwFlowFrm
*SwFlowFrm::CastFlowFrm( SwFrm
*pFrm
)
2719 if ( pFrm
->IsCntntFrm() )
2720 return (SwCntntFrm
*)pFrm
;
2721 if ( pFrm
->IsTabFrm() )
2722 return (SwTabFrm
*)pFrm
;
2723 if ( pFrm
->IsSctFrm() )
2724 return (SwSectionFrm
*)pFrm
;
2728 const SwFlowFrm
*SwFlowFrm::CastFlowFrm( const SwFrm
*pFrm
)
2730 if ( pFrm
->IsCntntFrm() )
2731 return (SwCntntFrm
*)pFrm
;
2732 if ( pFrm
->IsTabFrm() )
2733 return (SwTabFrm
*)pFrm
;
2734 if ( pFrm
->IsSctFrm() )
2735 return (SwSectionFrm
*)pFrm
;