/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include "rootfrm.hxx" #include "pagefrm.hxx" #include "cntfrm.hxx" #include "viewsh.hxx" #include "doc.hxx" #include "viewimp.hxx" #include "viewopt.hxx" #include "swtypes.hxx" #include "dflyobj.hxx" #include "dcontact.hxx" #include "flyfrm.hxx" #include "frmtool.hxx" #include "txtftn.hxx" #include "fmtftn.hxx" #include #include #include #include #include #include #include "tabfrm.hxx" #include "ftnfrm.hxx" #include "txtfrm.hxx" #include "pagedesc.hxx" #include "ftninfo.hxx" #include "sectfrm.hxx" #include "dbg_lay.hxx" // --> OD 2004-06-23 #i28701# #include #include // --> OD 2004-11-01 #i36347# #include // <-- //------------------------------------------------------------------------ // Move-Methoden //------------------------------------------------------------------------ /************************************************************************* |* |* SwCntntFrm::ShouldBwdMoved() |* |* Beschreibung Returnwert sagt, ob der Frm verschoben werden sollte. |* Ersterstellung MA 05. Dec. 96 |* Letzte Aenderung MA 05. Dec. 96 |* |*************************************************************************/ sal_Bool SwCntntFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, sal_Bool, sal_Bool & ) { if ( (SwFlowFrm::IsMoveBwdJump() || !IsPrevObjMove())) { //Das zurueckfliessen von Frm's ist leider etwas Zeitintensiv. //Der haufigste Fall ist der, dass dort wo der Frm hinfliessen //moechte die FixSize die gleiche ist, die der Frm selbst hat. //In diesem Fall kann einfach geprueft werden, ob der Frm genug //Platz fuer seine VarSize findet, ist dies nicht der Fall kann //gleich auf das Verschieben verzichtet werden. //Die Pruefung, ob der Frm genug Platz findet fuehrt er selbst //durch, dabei wird beruecksichtigt, dass er sich moeglicherweise //aufspalten kann. //Wenn jedoch die FixSize eine andere ist oder Flys im Spiel sind //(an der alten oder neuen Position) hat alle Prueferei keinen Sinn //der Frm muss dann halt Probehalber verschoben werden (Wenn ueberhaupt //etwas Platz zur Verfuegung steht). //Die FixSize der Umgebungen in denen Cntnts herumlungern ist immer //Die Breite. //Wenn mehr als ein Blatt zurueckgegangen wurde (z.B. ueberspringen //von Leerseiten), so muss in jedemfall gemoved werden - sonst wuerde, //falls der Frm nicht in das Blatt passt, nicht mehr auf die //dazwischenliegenden Blaetter geachtet werden. sal_uInt8 nMoveAnyway = 0; SwPageFrm * const pNewPage = pNewUpper->FindPageFrm(); SwPageFrm *pOldPage = FindPageFrm(); if ( SwFlowFrm::IsMoveBwdJump() ) return sal_True; if( IsInFtn() && IsInSct() ) { SwFtnFrm* pFtn = FindFtnFrm(); SwSectionFrm* pMySect = pFtn->FindSctFrm(); if( pMySect && pMySect->IsFtnLock() ) { SwSectionFrm *pSect = pNewUpper->FindSctFrm(); while( pSect && pSect->IsInFtn() ) pSect = pSect->GetUpper()->FindSctFrm(); ASSERT( pSect, "Escaping footnote" ); if( pSect != pMySect ) return sal_False; } } SWRECTFN( this ) SWRECTFNX( pNewUpper ) if( Abs( (pNewUpper->Prt().*fnRectX->fnGetWidth)() - (GetUpper()->Prt().*fnRect->fnGetWidth)() ) > 1 ) nMoveAnyway = 2; // Damit kommt nur noch ein _WouldFit mit Umhaengen in Frage // OD 2004-05-26 #i25904# - do *not* move backward, // if equals 3 and no space is left in new upper. nMoveAnyway |= BwdMoveNecessary( pOldPage, Frm() ); { const IDocumentSettingAccess* pIDSA = pNewPage->GetFmt()->getIDocumentSettingAccess(); SwTwips nSpace = 0; SwRect aRect( pNewUpper->Prt() ); aRect.Pos() += pNewUpper->Frm().Pos(); const SwFrm *pPrevFrm = pNewUpper->Lower(); while ( pPrevFrm ) { SwTwips nNewTop = (pPrevFrm->Frm().*fnRectX->fnGetBottom)(); // OD 2004-03-01 #106629#: // consider lower spacing of last frame in a table cell { // check, if last frame is inside table and if it includes // its lower spacing. if ( !pPrevFrm->GetNext() && pPrevFrm->IsInTab() && pIDSA->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) ) { const SwFrm* pLastFrm = pPrevFrm; // if last frame is a section, take its last content if ( pPrevFrm->IsSctFrm() ) { pLastFrm = static_cast(pPrevFrm)->FindLastCntnt(); if ( pLastFrm && pLastFrm->FindTabFrm() != pPrevFrm->FindTabFrm() ) { pLastFrm = pLastFrm->FindTabFrm(); } } if ( pLastFrm ) { SwBorderAttrAccess aAccess( SwFrm::GetCache(), pLastFrm ); const SwBorderAttrs& rAttrs = *aAccess.Get(); nNewTop -= rAttrs.GetULSpace().GetLower(); } } } (aRect.*fnRectX->fnSetTop)( nNewTop ); pPrevFrm = pPrevFrm->GetNext(); } nMoveAnyway |= BwdMoveNecessary( pNewPage, aRect); //determine space left in new upper frame nSpace = (aRect.*fnRectX->fnGetHeight)(); const ViewShell *pSh = pNewUpper->getRootFrm()->GetCurrShell(); if ( IsInFtn() || (pSh && pSh->GetViewOptions()->getBrowseMode()) || pNewUpper->IsCellFrm() || ( pNewUpper->IsInSct() && ( pNewUpper->IsSctFrm() || ( pNewUpper->IsColBodyFrm() && !pNewUpper->GetUpper()->GetPrev() && !pNewUpper->GetUpper()->GetNext() ) ) ) ) nSpace += pNewUpper->Grow( LONG_MAX, sal_True ); if ( nMoveAnyway < 3 ) { if ( nSpace ) { //Keine Beruecksichtigung der Fussnoten die an dem Absatz //kleben, denn dies wuerde extrem unuebersichtlichen Code //beduerfen (wg. Beruecksichtung der Breiten und vor allem //der Flys, die ja wieder Einfluss auf die Fussnoten nehmen...). // _WouldFit kann bei gleicher Breite und _nur_ selbst verankerten Flys // befragt werden. // _WouldFit kann auch gefragt werden, wenn _nur_ fremdverankerte Flys vorliegen, // dabei ist sogar die Breite egal, da ein TestFormat in der neuen Umgebung // vorgenommen wird. // --> OD 2007-11-26 #b6614158# const sal_uInt8 nBwdMoveNecessaryResult = BwdMoveNecessary( pNewPage, aRect); const bool bObjsInNewUpper( nBwdMoveNecessaryResult == 2 || nBwdMoveNecessaryResult == 3 ); return _WouldFit( nSpace, pNewUpper, nMoveAnyway == 2, bObjsInNewUpper ); // <-- } //Bei einem spaltigen Bereichsfrischling kann _WouldFit kein //brauchbares Ergebnis liefern, also muessen wir wirklich //zurueckfliessen else if( pNewUpper->IsInSct() && pNewUpper->IsColBodyFrm() && !(pNewUpper->Prt().*fnRectX->fnGetWidth)() && ( pNewUpper->GetUpper()->GetPrev() || pNewUpper->GetUpper()->GetNext() ) ) return sal_True; else return sal_False; // Kein Platz, dann ist es sinnlos, zurueckzufliessen } else { // OD 2004-05-26 #i25904# - check for space left in new upper if ( nSpace ) return sal_True; else return sal_False; } } } return sal_False; } //------------------------------------------------------------------------ // Calc-Methoden //------------------------------------------------------------------------ /************************************************************************* |* |* SwFrm::Prepare() |* |* Beschreibung Bereitet den Frm auf die 'Formatierung' (MakeAll()) |* vor. Diese Methode dient dazu auf dem Stack Platz einzusparen, |* denn zur Positionsberechnung des Frm muss sichergestellt sein, dass |* die Position von Upper und Prev gueltig sind, mithin also ein |* rekursiver Aufruf (Schleife waere relativ teuer, da selten notwendig). |* Jeder Aufruf von MakeAll verbraucht aber ca. 500Byte Stack - |* das Ende ist leicht abzusehen. _Prepare benoetigt nur wenig Stack, |* deshalb solle der Rekursive Aufruf hier kein Problem sein. |* Ein weiterer Vorteil ist, das eines schoenen Tages das _Prepare und |* damit die Formatierung von Vorgaengern umgangen werden kann. |* So kann evtl. mal 'schnell' an's Dokumentende gesprungen werden. |* Ersterstellung MA ?? |* Letzte Aenderung MA 13. Dec. 93 |* |*************************************************************************/ //Zwei kleine Freundschaften werden hier zu einem Geheimbund. inline void PrepareLock( SwFlowFrm *pTab ) { pTab->LockJoin(); } inline void PrepareUnlock( SwFlowFrm *pTab ) { pTab->UnlockJoin(); } // hopefully, one day this function simply will return 'false' bool lcl_IsCalcUpperAllowed( const SwFrm& rFrm ) { return !rFrm.GetUpper()->IsSctFrm() && !rFrm.GetUpper()->IsFooterFrm() && // --> OD 2004-11-02 #i23129#, #i36347# - no format of upper Writer fly frame !rFrm.GetUpper()->IsFlyFrm() && // <-- !( rFrm.GetUpper()->IsTabFrm() && rFrm.GetUpper()->GetUpper()->IsInTab() ) && !( rFrm.IsTabFrm() && rFrm.GetUpper()->IsInTab() ); } void SwFrm::PrepareMake() { StackHack aHack; if ( GetUpper() ) { if ( lcl_IsCalcUpperAllowed( *this ) ) GetUpper()->Calc(); ASSERT( GetUpper(), ":-( Layoutgeruest wackelig (Upper wech)." ); if ( !GetUpper() ) return; const sal_Bool bCnt = IsCntntFrm(); const sal_Bool bTab = IsTabFrm(); sal_Bool bNoSect = IsInSct(); sal_Bool bOldTabLock = sal_False, bFoll = sal_False; SwFlowFrm* pThis = bCnt ? (SwCntntFrm*)this : NULL; if ( bTab ) { pThis = (SwTabFrm*)this; bOldTabLock = ((SwTabFrm*)this)->IsJoinLocked(); ::PrepareLock( (SwTabFrm*)this ); bFoll = pThis->IsFollow(); } else if( IsSctFrm() ) { pThis = (SwSectionFrm*)this; bFoll = pThis->IsFollow(); bNoSect = sal_False; } else if ( bCnt && sal_True == (bFoll = pThis->IsFollow()) && GetPrev() ) { //Wenn der Master gereade ein CalcFollow ruft braucht die Kette //nicht durchlaufen werden. Das spart Zeit und vermeidet Probleme. if ( ((SwTxtFrm*)((SwTxtFrm*)this)->FindMaster())->IsLocked() ) { MakeAll(); return; } } // --> OD 2005-03-04 #i44049# - no format of previous frame, if current // frame is a table frame and its previous frame wants to keep with it. const bool bFormatPrev = !bTab || !GetPrev() || !GetPrev()->GetAttrSet()->GetKeep().GetValue(); if ( bFormatPrev ) { SwFrm *pFrm = GetUpper()->Lower(); while ( pFrm != this ) { ASSERT( pFrm, ":-( Layoutgeruest wackelig (this not found)." ); if ( !pFrm ) return; //Oioioioi ... if ( !pFrm->IsValid() ) { //Ein kleiner Eingriff der hoffentlich etwas zur Verbesserung //der Stabilitaet beitraegt: //Wenn ich Follow _und_ Nachbar eines Frms vor mir bin, //so wuerde dieser mich beim Formatieren deleten; wie jeder //leicht sehen kann waere dies eine etwas unuebersichtliche //Situation die es zu vermeiden gilt. if ( bFoll && pFrm->IsFlowFrm() && (SwFlowFrm::CastFlowFrm(pFrm))->IsAnFollow( pThis ) ) break; //MA: 24. Mar. 94, Calc wuerde doch nur wieder in ein _Prepare laufen und so //die ganze Kette nocheinmal abhuenern. // pFrm->Calc(); pFrm->MakeAll(); if( IsSctFrm() && !((SwSectionFrm*)this)->GetSection() ) break; } //Die Kette kann bei CntntFrms waehrend des durchlaufens //aufgebrochen werden, deshalb muss der Nachfolger etwas //umstaendlich ermittelt werden. However, irgendwann _muss_ //ich wieder bei mir selbst ankommen. pFrm = pFrm->FindNext(); //Wenn wir in einem SectionFrm gestartet sind, koennen wir durch die //MakeAll-Aufrufe in einen Section-Follow gewandert sein. //FindNext liefert allerdings den SectionFrm, nicht seinen Inhalt. // => wir finden uns selbst nicht mehr! if( bNoSect && pFrm && pFrm->IsSctFrm() ) { SwFrm* pCnt = ((SwSectionFrm*)pFrm)->ContainsAny(); if( pCnt ) pFrm = pCnt; } } ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech II)." ); if ( !GetUpper() ) return; if ( lcl_IsCalcUpperAllowed( *this ) ) GetUpper()->Calc(); ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech III)." ); } if ( bTab && !bOldTabLock ) ::PrepareUnlock( (SwTabFrm*)this ); } MakeAll(); } void SwFrm::OptPrepareMake() { // --> OD 2004-11-02 #i23129#, #i36347# - no format of upper Writer fly frame if ( GetUpper() && !GetUpper()->IsFooterFrm() && !GetUpper()->IsFlyFrm() ) // <-- { GetUpper()->Calc(); ASSERT( GetUpper(), ":-( Layoutgeruest wackelig (Upper wech)." ); if ( !GetUpper() ) return; } if ( GetPrev() && !GetPrev()->IsValid() ) PrepareMake(); else { StackHack aHack; MakeAll(); } } void SwFrm::PrepareCrsr() { StackHack aHack; if( GetUpper() && !GetUpper()->IsSctFrm() ) { GetUpper()->PrepareCrsr(); GetUpper()->Calc(); ASSERT( GetUpper(), ":-( Layoutgeruest wackelig (Upper wech)." ); if ( !GetUpper() ) return; const sal_Bool bCnt = IsCntntFrm(); const sal_Bool bTab = IsTabFrm(); sal_Bool bNoSect = IsInSct(); sal_Bool bOldTabLock = sal_False, bFoll; SwFlowFrm* pThis = bCnt ? (SwCntntFrm*)this : NULL; if ( bTab ) { bOldTabLock = ((SwTabFrm*)this)->IsJoinLocked(); ::PrepareLock( (SwTabFrm*)this ); pThis = (SwTabFrm*)this; } else if( IsSctFrm() ) { pThis = (SwSectionFrm*)this; bNoSect = sal_False; } bFoll = pThis && pThis->IsFollow(); SwFrm *pFrm = GetUpper()->Lower(); while ( pFrm != this ) { ASSERT( pFrm, ":-( Layoutgeruest wackelig (this not found)." ); if ( !pFrm ) return; //Oioioioi ... if ( !pFrm->IsValid() ) { //Ein kleiner Eingriff der hoffentlich etwas zur Verbesserung //der Stabilitaet beitraegt: //Wenn ich Follow _und_ Nachbar eines Frms vor mir bin, //so wuerde dieser mich beim Formatieren deleten; wie jeder //leicht sehen kann waere dies eine etwas unuebersichtliche //Situation die es zu vermeiden gilt. if ( bFoll && pFrm->IsFlowFrm() && (SwFlowFrm::CastFlowFrm(pFrm))->IsAnFollow( pThis ) ) break; pFrm->MakeAll(); } //Die Kette kann bei CntntFrms waehrend des durchlaufens //aufgebrochen werden, deshalb muss der Nachfolger etwas //umstaendlich ermittelt werden. However, irgendwann _muss_ //ich wieder bei mir selbst ankommen. pFrm = pFrm->FindNext(); if( bNoSect && pFrm && pFrm->IsSctFrm() ) { SwFrm* pCnt = ((SwSectionFrm*)pFrm)->ContainsAny(); if( pCnt ) pFrm = pCnt; } } ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech II)." ); if ( !GetUpper() ) return; GetUpper()->Calc(); ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech III)." ); if ( bTab && !bOldTabLock ) ::PrepareUnlock( (SwTabFrm*)this ); } Calc(); } /************************************************************************* |* |* SwFrm::MakePos() |* |* Ersterstellung MA ?? |* Letzte Aenderung MA 24. May. 93 |* |*************************************************************************/ // Hier wird GetPrev() zurueckgegeben, allerdings werden // dabei leere SectionFrms ueberlesen SwFrm* lcl_Prev( SwFrm* pFrm, sal_Bool bSectPrv = sal_True ) { SwFrm* pRet = pFrm->GetPrev(); if( !pRet && pFrm->GetUpper() && pFrm->GetUpper()->IsSctFrm() && bSectPrv && !pFrm->IsColumnFrm() ) pRet = pFrm->GetUpper()->GetPrev(); while( pRet && pRet->IsSctFrm() && !((SwSectionFrm*)pRet)->GetSection() ) pRet = pRet->GetPrev(); return pRet; } SwFrm* lcl_NotHiddenPrev( SwFrm* pFrm ) { SwFrm *pRet = pFrm; do { pRet = lcl_Prev( pRet ); } while ( pRet && pRet->IsTxtFrm() && ((SwTxtFrm*)pRet)->IsHiddenNow() ); return pRet; } void SwFrm::MakePos() { if ( !bValidPos ) { bValidPos = sal_True; sal_Bool bUseUpper = sal_False; SwFrm* pPrv = lcl_Prev( this ); if ( pPrv && ( !pPrv->IsCntntFrm() || ( ((SwCntntFrm*)pPrv)->GetFollow() != this ) ) ) { if ( !StackHack::IsLocked() && ( !IsInSct() || IsSctFrm() ) && !pPrv->IsSctFrm() && !pPrv->GetAttrSet()->GetKeep().GetValue() ) { pPrv->Calc(); //hierbei kann der Prev verschwinden! } else if ( pPrv->Frm().Top() == 0 ) { bUseUpper = sal_True; } } pPrv = lcl_Prev( this, sal_False ); sal_uInt16 nMyType = GetType(); SWRECTFN( ( IsCellFrm() && GetUpper() ? GetUpper() : this ) ) if ( !bUseUpper && pPrv ) { aFrm.Pos( pPrv->Frm().Pos() ); if( FRM_NEIGHBOUR & nMyType ) { sal_Bool bR2L = IsRightToLeft(); if( bR2L ) (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() - (aFrm.*fnRect->fnGetWidth)() ); else (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() + (pPrv->Frm().*fnRect->fnGetWidth)() ); // cells may now leave their uppers if( bVert && FRM_CELL & nMyType && !bReverse ) aFrm.Pos().X() -= aFrm.Width() -pPrv->Frm().Width(); } else if( bVert && FRM_NOTE_VERT & nMyType ) { if( bReverse ) aFrm.Pos().X() += pPrv->Frm().Width(); else //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin { if ( bVertL2R ) aFrm.Pos().X() += pPrv->Frm().Width(); else aFrm.Pos().X() -= aFrm.Width(); } } else aFrm.Pos().Y() += pPrv->Frm().Height(); } else if ( GetUpper() ) { // OD 15.10.2002 #103517# - add safeguard for // If parent frame is a footer frame and its , then // do *not* calculate it. // NOTE: Footer frame is during its // , which is called from , which // is called from , which is called from . // --> OD 2005-11-17 #i56850# // - no format of upper Writer fly frame, which is anchored // at-paragraph or at-character. if ( !GetUpper()->IsTabFrm() && !( IsTabFrm() && GetUpper()->IsInTab() ) && !GetUpper()->IsSctFrm() && !dynamic_cast(GetUpper()) && !( GetUpper()->IsFooterFrm() && GetUpper()->IsColLocked() ) ) { GetUpper()->Calc(); } // <-- pPrv = lcl_Prev( this, sal_False ); if ( !bUseUpper && pPrv ) { aFrm.Pos( pPrv->Frm().Pos() ); if( FRM_NEIGHBOUR & nMyType ) { sal_Bool bR2L = IsRightToLeft(); if( bR2L ) (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() - (aFrm.*fnRect->fnGetWidth)() ); else (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() + (pPrv->Frm().*fnRect->fnGetWidth)() ); // cells may now leave their uppers if( bVert && FRM_CELL & nMyType && !bReverse ) aFrm.Pos().X() -= aFrm.Width() -pPrv->Frm().Width(); } else if( bVert && FRM_NOTE_VERT & nMyType ) { if( bReverse ) aFrm.Pos().X() += pPrv->Frm().Width(); else aFrm.Pos().X() -= aFrm.Width(); } else aFrm.Pos().Y() += pPrv->Frm().Height(); } else { aFrm.Pos( GetUpper()->Frm().Pos() ); aFrm.Pos() += GetUpper()->Prt().Pos(); if( FRM_NEIGHBOUR & nMyType && IsRightToLeft() ) { if( bVert ) aFrm.Pos().Y() += GetUpper()->Prt().Height() - aFrm.Height(); else aFrm.Pos().X() += GetUpper()->Prt().Width() - aFrm.Width(); } //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin else if( bVert && !bVertL2R && FRM_NOTE_VERT & nMyType && !bReverse ) aFrm.Pos().X() -= aFrm.Width() - GetUpper()->Prt().Width(); } } else aFrm.Pos().X() = aFrm.Pos().Y() = 0; //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin if( IsBodyFrm() && bVert && !bVertL2R && !bReverse && GetUpper() ) aFrm.Pos().X() += GetUpper()->Prt().Width() - aFrm.Width(); bValidPos = sal_True; } } /************************************************************************* |* |* SwPageFrm::MakeAll() |* |* Ersterstellung MA 23. Feb. 93 |* Letzte Aenderung MA 20. Jul. 98 |* |*************************************************************************/ // --> OD 2004-07-01 #i28701# - new type void lcl_CheckObjects( SwSortedObjs* pSortedObjs, SwFrm* pFrm, long& rBot ) { //Und dann kann es natuerlich noch Absatzgebundene //Rahmen geben, die unterhalb ihres Absatzes stehen. long nMax = 0; for ( sal_uInt16 i = 0; i < pSortedObjs->Count(); ++i ) { // --> OD 2004-07-01 #i28701# - consider changed type of // entries. SwAnchoredObject* pObj = (*pSortedObjs)[i]; long nTmp = 0; if ( pObj->ISA(SwFlyFrm) ) { SwFlyFrm *pFly = static_cast(pObj); if( pFly->Frm().Top() != WEIT_WECH && ( pFrm->IsPageFrm() ? pFly->IsFlyLayFrm() : ( pFly->IsFlyAtCntFrm() && ( pFrm->IsBodyFrm() ? pFly->GetAnchorFrm()->IsInDocBody() : pFly->GetAnchorFrm()->IsInFtn() ) ) ) ) { nTmp = pFly->Frm().Bottom(); } } else nTmp = pObj->GetObjRect().Bottom(); nMax = Max( nTmp, nMax ); // <-- } ++nMax; //Unterkante vs. Hoehe! rBot = Max( rBot, nMax ); } void SwPageFrm::MakeAll() { PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 ) const SwRect aOldRect( Frm() ); //Anpassung der Root-Groesse const SwLayNotify aNotify( this ); //uebernimmt im DTor die Benachrichtigung SwBorderAttrAccess *pAccess = 0; const SwBorderAttrs*pAttrs = 0; while ( !bValidPos || !bValidSize || !bValidPrtArea ) { if ( !bValidPos ) { // PAGES01 bValidPos = sal_True; // positioning of the pages is taken care of by the root frame } if ( !bValidSize || !bValidPrtArea ) { if ( IsEmptyPage() ) { Frm().Width( 0 ); Prt().Width( 0 ); Frm().Height( 0 ); Prt().Height( 0 ); Prt().Left( 0 ); Prt().Top( 0 ); bValidSize = bValidPrtArea = sal_True; } else { if ( !pAccess ) { pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this ); pAttrs = pAccess->Get(); } //Bei der BrowseView gelten feste Einstellungen. ViewShell *pSh = getRootFrm()->GetCurrShell(); if ( pSh && pSh->GetViewOptions()->getBrowseMode() ) { const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() ); const long nTop = pAttrs->CalcTopLine() + aBorder.Height(); const long nBottom = pAttrs->CalcBottomLine()+ aBorder.Height(); long nWidth = GetUpper() ? ((SwRootFrm*)GetUpper())->GetBrowseWidth() : 0; if ( nWidth < pSh->GetBrowseWidth() ) nWidth = pSh->GetBrowseWidth(); nWidth += + 2 * aBorder.Width(); /* long nWidth = GetUpper() ? ((SwRootFrm*)GetUpper())->GetBrowseWidth() + 2 * aBorder.Width() : 0; if ( nWidth < pSh->VisArea().Width() ) nWidth = pSh->VisArea().Width(); */ nWidth = Max( nWidth, 2L * aBorder.Width() + 4L*MM50 ); Frm().Width( nWidth ); SwLayoutFrm *pBody = FindBodyCont(); if ( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() ) { //Fuer Spalten gilt eine feste Hoehe Frm().Height( pAttrs->GetSize().Height() ); } else { //Fuer Seiten ohne Spalten bestimmt der Inhalt die //Groesse. long nBot = Frm().Top() + nTop; SwFrm *pFrm = Lower(); while ( pFrm ) { long nTmp = 0; SwFrm *pCnt = ((SwLayoutFrm*)pFrm)->ContainsAny(); while ( pCnt && (pCnt->GetUpper() == pFrm || ((SwLayoutFrm*)pFrm)->IsAnLower( pCnt ))) { nTmp += pCnt->Frm().Height(); if( pCnt->IsTxtFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() ) nTmp += ((SwTxtFrm*)pCnt)->GetParHeight() - pCnt->Prt().Height(); else if( pCnt->IsSctFrm() && ((SwSectionFrm*)pCnt)->IsUndersized() ) nTmp += ((SwSectionFrm*)pCnt)->Undersize(); pCnt = pCnt->FindNext(); } // OD 29.10.2002 #97265# - consider invalid body frame properties if ( pFrm->IsBodyFrm() && ( !pFrm->GetValidSizeFlag() || !pFrm->GetValidPrtAreaFlag() ) && ( pFrm->Frm().Height() < pFrm->Prt().Height() ) ) { nTmp = Min( nTmp, pFrm->Frm().Height() ); } else { // OD 30.10.2002 #97265# - assert invalid lower property ASSERT( !(pFrm->Frm().Height() < pFrm->Prt().Height()), "SwPageFrm::MakeAll(): Lower with frame height < printing height" ); nTmp += pFrm->Frm().Height() - pFrm->Prt().Height(); } if ( !pFrm->IsBodyFrm() ) nTmp = Min( nTmp, pFrm->Frm().Height() ); nBot += nTmp; // Hier werden die absatzgebundenen Objekte ueberprueft, // ob sie ueber den Body/FtnCont hinausragen. if( pSortedObjs && !pFrm->IsHeaderFrm() && !pFrm->IsFooterFrm() ) lcl_CheckObjects( pSortedObjs, pFrm, nBot ); pFrm = pFrm->GetNext(); } nBot += nBottom; //Und die Seitengebundenen if ( pSortedObjs ) lcl_CheckObjects( pSortedObjs, this, nBot ); nBot -= Frm().Top(); // --> OD 2004-11-10 #i35143# - If second page frame // exists, the first page doesn't have to fulfill the // visible area. if ( !GetPrev() && !GetNext() ) // <-- { nBot = Max( nBot, pSh->VisArea().Height() ); } // --> OD 2004-11-10 #i35143# - Assure, that the page // doesn't exceed the defined browse height. Frm().Height( Min( nBot, BROWSE_HEIGHT ) ); // <-- } Prt().Left ( pAttrs->CalcLeftLine() + aBorder.Width() ); Prt().Top ( nTop ); Prt().Width( Frm().Width() - ( Prt().Left() + pAttrs->CalcRightLine() + aBorder.Width() ) ); Prt().Height( Frm().Height() - (nTop + nBottom) ); bValidSize = bValidPrtArea = sal_True; } else { //FixSize einstellen, bei Seiten nicht vom Upper sondern vom //Attribut vorgegeben. Frm().SSize( pAttrs->GetSize() ); Format( pAttrs ); } } } } //while ( !bValidPos || !bValidSize || !bValidPrtArea ) delete pAccess; // PAGES01 if ( Frm() != aOldRect && GetUpper() ) static_cast(GetUpper())->CheckViewLayout( 0, 0 ); #ifdef DBG_UTIL //Der Upper (Root) muss mindestens so breit //sein, dass er die breiteste Seite aufnehmen kann. if ( GetUpper() ) { ASSERT( GetUpper()->Prt().Width() >= aFrm.Width(), "Rootsize" ); } #endif } /************************************************************************* |* |* SwLayoutFrm::MakeAll() |* |* Ersterstellung MA ?? |* Letzte Aenderung MA 28. Nov. 95 |* |*************************************************************************/ void SwLayoutFrm::MakeAll() { PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 ) //uebernimmt im DTor die Benachrichtigung const SwLayNotify aNotify( this ); sal_Bool bVert = IsVertical(); //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin SwRectFn fnRect = ( IsNeighbourFrm() == bVert )? fnRectHori : ( IsVertLR() ? fnRectVertL2R : fnRectVert ); SwBorderAttrAccess *pAccess = 0; const SwBorderAttrs*pAttrs = 0; while ( !bValidPos || !bValidSize || !bValidPrtArea ) { if ( !bValidPos ) MakePos(); if ( GetUpper() ) { // NEW TABLES if ( IsLeaveUpperAllowed() ) { if ( !bValidSize ) bValidPrtArea = sal_False; } else { if ( !bValidSize ) { //FixSize einstellen, die VarSize wird von Format() nach //Berechnung der PrtArea eingestellt. bValidPrtArea = sal_False; SwTwips nPrtWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)(); if( bVert && ( IsBodyFrm() || IsFtnContFrm() ) ) { SwFrm* pNxt = GetPrev(); while( pNxt && !pNxt->IsHeaderFrm() ) pNxt = pNxt->GetPrev(); if( pNxt ) nPrtWidth -= pNxt->Frm().Height(); pNxt = GetNext(); while( pNxt && !pNxt->IsFooterFrm() ) pNxt = pNxt->GetNext(); if( pNxt ) nPrtWidth -= pNxt->Frm().Height(); } const long nDiff = nPrtWidth - (Frm().*fnRect->fnGetWidth)(); if( IsNeighbourFrm() && IsRightToLeft() ) (Frm().*fnRect->fnSubLeft)( nDiff ); else (Frm().*fnRect->fnAddRight)( nDiff ); } else { // Don't leave your upper const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)(); if( (Frm().*fnRect->fnOverStep)( nDeadLine ) ) bValidSize = sal_False; } } } if ( !bValidSize || !bValidPrtArea ) { if ( !pAccess ) { pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this ); pAttrs = pAccess->Get(); } Format( pAttrs ); } } //while ( !bValidPos || !bValidSize || !bValidPrtArea ) if ( pAccess ) delete pAccess; } /************************************************************************* |* |* SwCntntFrm::MakePrtArea() |* |* Ersterstellung MA 17. Nov. 92 |* Letzte Aenderung MA 03. Mar. 96 |* |*************************************************************************/ sal_Bool SwCntntFrm::MakePrtArea( const SwBorderAttrs &rAttrs ) { sal_Bool bSizeChgd = sal_False; if ( !bValidPrtArea ) { bValidPrtArea = sal_True; SWRECTFN( this ) const sal_Bool bTxtFrm = IsTxtFrm(); SwTwips nUpper = 0; if ( bTxtFrm && ((SwTxtFrm*)this)->IsHiddenNow() ) { if ( ((SwTxtFrm*)this)->HasFollow() ) ((SwTxtFrm*)this)->JoinFrm(); if( (Prt().*fnRect->fnGetHeight)() ) ((SwTxtFrm*)this)->HideHidden(); Prt().Pos().X() = Prt().Pos().Y() = 0; (Prt().*fnRect->fnSetWidth)( (Frm().*fnRect->fnGetWidth)() ); (Prt().*fnRect->fnSetHeight)( 0 ); nUpper = -( (Frm().*fnRect->fnGetHeight)() ); } else { //Vereinfachung: CntntFrms sind immer in der Hoehe Variabel! //An der FixSize gibt der umgebende Frame die Groesse vor, die //Raender werden einfach abgezogen. const long nLeft = rAttrs.CalcLeft( this ); const long nRight = ((SwBorderAttrs&)rAttrs).CalcRight( this ); (this->*fnRect->fnSetXMargins)( nLeft, nRight ); ViewShell *pSh = getRootFrm()->GetCurrShell(); SwTwips nWidthArea; if( pSh && 0!=(nWidthArea=(pSh->VisArea().*fnRect->fnGetWidth)()) && GetUpper()->IsPageBodyFrm() && // nicht dagegen bei BodyFrms in Columns pSh->GetViewOptions()->getBrowseMode() ) { //Nicht ueber die Kante des sichbaren Bereiches hinausragen. //Die Seite kann breiter sein, weil es Objekte mit "ueberbreite" //geben kann (RootFrm::ImplCalcBrowseWidth()) long nMinWidth = 0; for (sal_uInt16 i = 0; GetDrawObjs() && i < GetDrawObjs()->Count();++i) { // --> OD 2004-07-01 #i28701# - consider changed type of // entries SwAnchoredObject* pObj = (*GetDrawObjs())[i]; const SwFrmFmt& rFmt = pObj->GetFrmFmt(); const sal_Bool bFly = pObj->ISA(SwFlyFrm); if ((bFly && (WEIT_WECH == pObj->GetObjRect().Width())) || rFmt.GetFrmSize().GetWidthPercent()) { continue; } if ( FLY_AS_CHAR == rFmt.GetAnchor().GetAnchorId() ) { nMinWidth = Max( nMinWidth, bFly ? rFmt.GetFrmSize().GetWidth() : pObj->GetObjRect().Width() ); } // <-- } const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() ); long nWidth = nWidthArea - 2 * ( IsVertical() ? aBorder.Height() : aBorder.Width() ); nWidth -= (Prt().*fnRect->fnGetLeft)(); nWidth -= rAttrs.CalcRightLine(); nWidth = Max( nMinWidth, nWidth ); (Prt().*fnRect->fnSetWidth)( Min( nWidth, (Prt().*fnRect->fnGetWidth)() ) ); } if ( (Prt().*fnRect->fnGetWidth)() <= MINLAY ) { //Die PrtArea sollte schon wenigstens MINLAY breit sein, passend //zu den Minimalwerten des UI (Prt().*fnRect->fnSetWidth)( Min( long(MINLAY), (Frm().*fnRect->fnGetWidth)() ) ); SwTwips nTmp = (Frm().*fnRect->fnGetWidth)() - (Prt().*fnRect->fnGetWidth)(); if( (Prt().*fnRect->fnGetLeft)() > nTmp ) (Prt().*fnRect->fnSetLeft)( nTmp ); } //Fuer die VarSize gelten folgende Regeln: //1. Der erste einer Kette hat keinen Rand nach oben //2. Nach unten gibt es nie einen Rand //3. Der Rand nach oben ist das Maximum aus dem Abstand des // Prev nach unten und dem eigenen Abstand nach oben. //Die drei Regeln werden auf die Berechnung der Freiraeume, die von //UL- bzw. LRSpace vorgegeben werden, angewand. Es gibt in alle //Richtungen jedoch ggf. trotzdem einen Abstand; dieser wird durch //Umrandung und/oder Schatten vorgegeben. //4. Der Abstand fuer TextFrms entspricht mindestens dem Durchschuss nUpper = CalcUpperSpace( &rAttrs, NULL ); // OD 2004-03-02 #106629# - use new method SwTwips nLower = CalcLowerSpace( &rAttrs ); // // in balanced columned section frames we do not want the // // common border // sal_Bool bCommonBorder = sal_True; // if ( IsInSct() && GetUpper()->IsColBodyFrm() ) // { // const SwSectionFrm* pSct = FindSctFrm(); // bCommonBorder = pSct->GetFmt()->GetBalancedColumns().GetValue(); // } // SwTwips nLower = bCommonBorder ? // rAttrs.GetBottomLine( this ) : // rAttrs.CalcBottomLine(); (Prt().*fnRect->fnSetPosY)( (!bVert || bReverse) ? nUpper : nLower); nUpper += nLower; nUpper -= (Frm().*fnRect->fnGetHeight)() - (Prt().*fnRect->fnGetHeight)(); } //Wenn Unterschiede zwischen Alter und neuer Groesse, //Grow() oder Shrink() rufen if ( nUpper ) { if ( nUpper > 0 ) GrowFrm( nUpper ); else ShrinkFrm( -nUpper ); bSizeChgd = sal_True; } } return bSizeChgd; } /************************************************************************* |* |* SwCntntFrm::MakeAll() |* |* Ersterstellung MA ?? |* Letzte Aenderung MA 16. Dec. 96 |* |*************************************************************************/ #define STOP_FLY_FORMAT 10 // --> OD 2006-09-25 #b6448963# - loop prevention const int cnStopFormat = 15; // <-- inline void ValidateSz( SwFrm *pFrm ) { if ( pFrm ) { pFrm->bValidSize = sal_True; pFrm->bValidPrtArea = sal_True; } } void SwCntntFrm::MakeAll() { ASSERT( GetUpper(), "keinen Upper?" ); ASSERT( IsTxtFrm(), "MakeAll(), NoTxt" ); if ( !IsFollow() && StackHack::IsLocked() ) return; if ( IsJoinLocked() ) return; ASSERT( !((SwTxtFrm*)this)->IsSwapped(), "Calculation of a swapped frame" ); StackHack aHack; if ( ((SwTxtFrm*)this)->IsLocked() ) { ASSERT( sal_False, "Format fuer gelockten TxtFrm." ); return; } LockJoin(); long nFormatCount = 0; // --> OD 2006-09-25 #b6448963# - loop prevention int nConsequetiveFormatsWithoutChange = 0; // <-- PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 ) #ifdef DBG_UTIL const SwDoc *pDoc = GetAttrSet()->GetDoc(); if( pDoc ) { static sal_Bool bWarn = sal_False; if( pDoc->InXMLExport() ) { ASSERT( bWarn, "Formatting during XML-export!" ); bWarn = sal_True; } else bWarn = sal_False; } #endif //uebernimmt im DTor die Benachrichtigung SwCntntNotify *pNotify = new SwCntntNotify( this ); sal_Bool bMakePage = sal_True; //solange sal_True kann eine neue Seite //angelegt werden (genau einmal) sal_Bool bMovedBwd = sal_False; //Wird sal_True wenn der Frame zurueckfliesst sal_Bool bMovedFwd = sal_False; //solange sal_False kann der Frm zurueck- //fliessen (solange, bis er einmal //vorwaerts ge'moved wurde). sal_Bool bFormatted = sal_False; //Fuer die Witwen und Waisen Regelung //wird der letzte CntntFrm einer Kette //u.U. zum Formatieren angeregt, dies //braucht nur einmal zu passieren. //Immer wenn der Frm gemoved wird muss //das Flag zurueckgesetzt werden. sal_Bool bMustFit = sal_False; //Wenn einmal die Notbremse gezogen wurde, //werden keine anderen Prepares mehr //abgesetzt. sal_Bool bFitPromise = sal_False; //Wenn ein Absatz nicht passte, mit WouldFit //aber verspricht, dass er sich passend //einstellt wird dieses Flag gesetzt. //Wenn er dann sein Versprechen nicht haelt, //kann kontrolliert verfahren werden. sal_Bool bMoveable; const sal_Bool bFly = IsInFly(); const sal_Bool bTab = IsInTab(); const sal_Bool bFtn = IsInFtn(); const sal_Bool bSct = IsInSct(); Point aOldFrmPos; //Damit bei Turnarounds jew. mit der Point aOldPrtPos; //letzten Pos verglichen und geprueft //werden kann, ob ein Prepare sinnvoll ist. SwBorderAttrAccess aAccess( SwFrm::GetCache(), this ); const SwBorderAttrs &rAttrs = *aAccess.Get(); // OD 2004-02-26 #i25029# if ( !IsFollow() && rAttrs.JoinedWithPrev( *(this) ) ) { pNotify->SetBordersJoinedWithPrev(); } const sal_Bool bKeep = IsKeep( rAttrs.GetAttrSet() ); SwSaveFtnHeight *pSaveFtn = 0; if ( bFtn ) { SwFtnFrm *pFtn = FindFtnFrm(); SwSectionFrm* pSct = pFtn->FindSctFrm(); if ( !((SwTxtFrm*)pFtn->GetRef())->IsLocked() ) { SwFtnBossFrm* pBoss = pFtn->GetRef()->FindFtnBossFrm( pFtn->GetAttr()->GetFtn().IsEndNote() ); if( !pSct || pSct->IsColLocked() || !pSct->Growable() ) pSaveFtn = new SwSaveFtnHeight( pBoss, ((SwTxtFrm*)pFtn->GetRef())->GetFtnLine( pFtn->GetAttr() ) ); } } // --> OD 2008-08-12 #b6732519# if ( GetUpper()->IsSctFrm() && HasFollow() && GetFollow()->GetFrm() == GetNext() ) { dynamic_cast(this)->JoinFrm(); } // <-- // --> OD 2004-06-23 #i28701# - move master forward, if it has to move, // because of its object positioning. if ( !static_cast(this)->IsFollow() ) { sal_uInt32 nToPageNum = 0L; const bool bMoveFwdByObjPos = SwLayouter::FrmMovedFwdByObjPos( *(GetAttrSet()->GetDoc()), *(static_cast(this)), nToPageNum ); // --> OD 2006-01-27 #i58182# // Also move a paragraph forward, which is the first one inside a table cell. if ( bMoveFwdByObjPos && FindPageFrm()->GetPhyPageNum() < nToPageNum && ( lcl_Prev( this ) || GetUpper()->IsCellFrm() || ( GetUpper()->IsSctFrm() && GetUpper()->GetUpper()->IsCellFrm() ) ) && IsMoveable() ) { bMovedFwd = sal_True; MoveFwd( bMakePage, sal_False ); } // <-- } // <-- //Wenn ein Follow neben seinem Master steht und nicht passt, kann er //gleich verschoben werden. if ( lcl_Prev( this ) && ((SwTxtFrm*)this)->IsFollow() && IsMoveable() ) { bMovedFwd = sal_True; // OD 2004-03-02 #106629# - If follow frame is in table, it's master // will be the last in the current table cell. Thus, invalidate the // printing area of the master, if ( IsInTab() ) { lcl_Prev( this )->InvalidatePrt(); } MoveFwd( bMakePage, sal_False ); } // OD 08.11.2002 #104840# - check footnote content for forward move. // If a content of a footnote is on a prior page/column as its invalid // reference, it can be moved forward. if ( bFtn && !bValidPos ) { SwFtnFrm* pFtn = FindFtnFrm(); SwCntntFrm* pRefCnt = pFtn ? pFtn->GetRef() : 0; if ( pRefCnt && !pRefCnt->IsValid() ) { SwFtnBossFrm* pFtnBossOfFtn = pFtn->FindFtnBossFrm(); SwFtnBossFrm* pFtnBossOfRef = pRefCnt->FindFtnBossFrm(); // if ( pFtnBossOfFtn && pFtnBossOfRef && pFtnBossOfFtn != pFtnBossOfRef && pFtnBossOfFtn->IsBefore( pFtnBossOfRef ) ) { bMovedFwd = sal_True; MoveFwd( bMakePage, sal_False ); } } } SWRECTFN( this ) while ( !bValidPos || !bValidSize || !bValidPrtArea ) { // --> OD 2006-09-25 #b6448963# - loop prevention SwRect aOldFrm_StopFormat( Frm() ); SwRect aOldPrt_StopFormat( Prt() ); // <-- if ( sal_True == (bMoveable = IsMoveable()) ) { SwFrm *pPre = GetIndPrev(); if ( CheckMoveFwd( bMakePage, bKeep, bMovedBwd ) ) { SWREFRESHFN( this ) bMovedFwd = sal_True; if ( bMovedBwd ) { //Beim zurueckfliessen wurde der Upper angeregt sich //vollstaendig zu Painten, dass koennen wir uns jetzt //nach dem hin und her fliessen sparen. GetUpper()->ResetCompletePaint(); //Der Vorgaenger wurde Invalidiert, das ist jetzt auch obsolete. ASSERT( pPre, "missing old Prev" ); if( !pPre->IsSctFrm() ) ::ValidateSz( pPre ); } bMoveable = IsMoveable(); } } aOldFrmPos = (Frm().*fnRect->fnGetPos)(); aOldPrtPos = (Prt().*fnRect->fnGetPos)(); if ( !bValidPos ) MakePos(); //FixSize einstellen, die VarSize wird von Format() justiert. if ( !bValidSize ) { // --> OD 2006-01-03 #125452# // invalidate printing area flag, if the following conditions are hold: // - current frame width is 0. // - current printing area width is 0. // - frame width is adjusted to a value greater than 0. // - printing area flag is sal_True. // Thus, it's assured that the printing area is adjusted, if the // frame area width changes its width from 0 to something greater // than 0. // Note: A text frame can be in such a situation, if the format is // triggered by method call after // loading the document. const SwTwips nNewFrmWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)(); if ( bValidPrtArea && nNewFrmWidth > 0 && (Frm().*fnRect->fnGetWidth)() == 0 && (Prt().*fnRect->fnGetWidth)() == 0 ) { bValidPrtArea = sal_False; } (Frm().*fnRect->fnSetWidth)( nNewFrmWidth ); // <-- } if ( !bValidPrtArea ) { const long nOldW = (Prt().*fnRect->fnGetWidth)(); // --> OD 2004-09-28 #i34730# - keep current frame height const SwTwips nOldH = (Frm().*fnRect->fnGetHeight)(); // <-- MakePrtArea( rAttrs ); if ( nOldW != (Prt().*fnRect->fnGetWidth)() ) Prepare( PREP_FIXSIZE_CHG ); // --> OD 2004-09-28 #i34730# - check, if frame height has changed. // If yes, send a PREP_ADJUST_FRM and invalidate the size flag to // force a format. The format will check in its method // , if the already formatted lines still // fit and if not, performs necessary actions. // --> OD 2005-01-10 #i40150# - no check, if frame is undersized. if ( bValidSize && !IsUndersized() && nOldH != (Frm().*fnRect->fnGetHeight)() ) { // --> OD 2004-11-25 #115759# - no PREP_ADJUST_FRM and size // invalidation, if height decreases only by the additional // lower space as last content of a table cell and an existing // follow containing one line exists. const SwTwips nHDiff = nOldH - (Frm().*fnRect->fnGetHeight)(); const bool bNoPrepAdjustFrm = nHDiff > 0 && IsInTab() && GetFollow() && ( 1 == static_cast(GetFollow())->GetLineCount( STRING_LEN ) || (static_cast(GetFollow())->Frm().*fnRect->fnGetWidth)() < 0 ) && GetFollow()->CalcAddLowerSpaceAsLastInTableCell() == nHDiff; if ( !bNoPrepAdjustFrm ) { Prepare( PREP_ADJUST_FRM ); bValidSize = sal_False; } // <-- } // <-- } //Damit die Witwen- und Waisen-Regelung eine Change bekommt muss der //CntntFrm benachrichtigt werden. //Kriterium: //- Er muss Moveable sein (sonst mach das Spalten keinen Sinn.) //- Er muss mit der Unterkante der PrtArea des Upper ueberlappen. if ( !bMustFit ) { sal_Bool bWidow = sal_True; const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)(); if ( bMoveable && !bFormatted && ( GetFollow() || ( (Frm().*fnRect->fnOverStep)( nDeadLine ) ) ) ) { Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False ); bValidSize = bWidow = sal_False; } if( (Frm().*fnRect->fnGetPos)() != aOldFrmPos || (Prt().*fnRect->fnGetPos)() != aOldPrtPos ) { // In diesem Prepare erfolgt ggf. ein _InvalidateSize(). // bValidSize wird sal_False und das Format() wird gerufen. Prepare( PREP_POS_CHGD, (const void*)&bFormatted, sal_False ); if ( bWidow && GetFollow() ) { Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False ); bValidSize = sal_False; } } } if ( !bValidSize ) { bValidSize = bFormatted = sal_True; ++nFormatCount; if( nFormatCount > STOP_FLY_FORMAT ) SetFlyLock( sal_True ); // --> OD 2006-09-25 #b6448963# - loop prevention // No format any longer, if consequetive formats // without change occur. if ( nConsequetiveFormatsWithoutChange <= cnStopFormat ) { Format(); } #if OSL_DEBUG_LEVEL > 1 else { ASSERT( false, "debug assertion: - format of text frame suppressed by fix b6448963" ); } #endif // <-- } // FME 16.07.2003 #i16930# - removed this code because it did not work // OD 04.04.2003 #108446# - react on the situation detected in the text // formatting - see : // text frame has to move forward, because its text formatting stopped, // created a follow and detected, that it contains no content. /* if ( IsTxtFrm() && bValidPos && bValidSize && bValidPrtArea && (Frm().*fnRect->fnGetHeight)() == 0 && HasFollow() ) { SwFrm* pOldUpper = GetUpper(); MoveFwd( sal_True, sal_False ); if ( GetUpper() != pOldUpper ) { bMovedFwd = sal_True; SWREFRESHFN( this ) continue; } } */ //Wenn ich der erste einer Kette bin koennte ich mal sehen ob //ich zurueckfliessen kann (wenn ich mich ueberhaupt bewegen soll). //Damit es keine Oszillation gibt, darf ich nicht gerade vorwaerts //geflossen sein. sal_Bool bDummy; if ( !lcl_Prev( this ) && !bMovedFwd && ( bMoveable || ( bFly && !bTab ) ) && ( !bFtn || !GetUpper()->FindFtnFrm()->GetPrev() ) && MoveBwd( bDummy ) ) { SWREFRESHFN( this ) bMovedBwd = sal_True; bFormatted = sal_False; if ( bKeep && bMoveable ) { if( CheckMoveFwd( bMakePage, sal_False, bMovedBwd ) ) { bMovedFwd = sal_True; bMoveable = IsMoveable(); SWREFRESHFN( this ) } Point aOldPos = (Frm().*fnRect->fnGetPos)(); MakePos(); if( aOldPos != (Frm().*fnRect->fnGetPos)() ) { Prepare( PREP_POS_CHGD, (const void*)&bFormatted, sal_False ); if ( !bValidSize ) { (Frm().*fnRect->fnSetWidth)( (GetUpper()-> Prt().*fnRect->fnGetWidth)() ); if ( !bValidPrtArea ) { const long nOldW = (Prt().*fnRect->fnGetWidth)(); MakePrtArea( rAttrs ); if( nOldW != (Prt().*fnRect->fnGetWidth)() ) Prepare( PREP_FIXSIZE_CHG, 0, sal_False ); } if( GetFollow() ) Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False ); bValidSize = bFormatted = sal_True; Format(); } } SwFrm *pNxt = HasFollow() ? NULL : FindNext(); while( pNxt && pNxt->IsSctFrm() ) { // Leere Bereiche auslassen, in die anderen hinein if( ((SwSectionFrm*)pNxt)->GetSection() ) { SwFrm* pTmp = ((SwSectionFrm*)pNxt)->ContainsAny(); if( pTmp ) { pNxt = pTmp; break; } } pNxt = pNxt->FindNext(); } if ( pNxt ) { pNxt->Calc(); if( bValidPos && !GetIndNext() ) { SwSectionFrm *pSct = FindSctFrm(); if( pSct && !pSct->GetValidSizeFlag() ) { SwSectionFrm* pNxtSct = pNxt->FindSctFrm(); if( pNxtSct && pSct->IsAnFollow( pNxtSct ) ) bValidPos = sal_False; } else bValidPos = sal_False; } } } } //Der TxtFrm Validiert sich bei Fussnoten ggf. selbst, dass kann leicht //dazu fuehren, dass seine Position obwohl unrichtig valide ist. if ( bValidPos ) { // --> OD 2006-01-23 #i59341# // Workaround for inadequate layout algorithm: // suppress invalidation and calculation of position, if paragraph // has formatted itself at least STOP_FLY_FORMAT times and // has anchored objects. // Thus, the anchored objects get the possibility to format itself // and this probably solve the layout loop. if ( bFtn && nFormatCount <= STOP_FLY_FORMAT && !GetDrawObjs() ) // <-- { bValidPos = sal_False; MakePos(); aOldFrmPos = (Frm().*fnRect->fnGetPos)(); aOldPrtPos = (Prt().*fnRect->fnGetPos)(); } } // --> OD 2006-09-25 #b6448963# - loop prevention { if ( aOldFrm_StopFormat == Frm() && aOldPrt_StopFormat == Prt() ) { ++nConsequetiveFormatsWithoutChange; } else { nConsequetiveFormatsWithoutChange = 0; } } // <-- //Wieder ein Wert ungueltig? - dann nochmal das ganze... if ( !bValidPos || !bValidSize || !bValidPrtArea ) continue; //Fertig? // Achtung, wg. Hoehe==0, ist es besser statt Bottom() Top()+Height() zu nehmen // (kommt bei Undersized TxtFrms an der Unterkante eines spaltigen Bereichs vor) const long nPrtBottom = (GetUpper()->*fnRect->fnGetPrtBottom)(); const long nBottomDist = (Frm().*fnRect->fnBottomDist)( nPrtBottom ); if( nBottomDist >= 0 ) { if ( bKeep && bMoveable ) { //Wir sorgen dafuer, dass der Nachfolger gleich mit formatiert //wird. Dadurch halten wir das Heft in der Hand, bis wirklich //(fast) alles stabil ist. So vermeiden wir Endlosschleifen, //die durch staendig wiederholte Versuche entstehen. //Das bMoveFwdInvalid ist fuer #38407# notwendig. War urspruenglich //in flowfrm.cxx rev 1.38 behoben, das unterbrach aber obiges //Schema und spielte lieber Tuerme von Hanoi (#43669#). SwFrm *pNxt = HasFollow() ? NULL : FindNext(); // Bei Bereichen nehmen wir lieber den Inhalt, denn nur // dieser kann ggf. die Seite wechseln while( pNxt && pNxt->IsSctFrm() ) { if( ((SwSectionFrm*)pNxt)->GetSection() ) { pNxt = ((SwSectionFrm*)pNxt)->ContainsAny(); break; } pNxt = pNxt->FindNext(); } if ( pNxt ) { const sal_Bool bMoveFwdInvalid = 0 != GetIndNext(); const sal_Bool bNxtNew = ( 0 == (pNxt->Prt().*fnRect->fnGetHeight)() ) && (!pNxt->IsTxtFrm() ||!((SwTxtFrm*)pNxt)->IsHiddenNow()); pNxt->Calc(); if ( !bMovedBwd && ((bMoveFwdInvalid && !GetIndNext()) || bNxtNew) ) { if( bMovedFwd ) pNotify->SetInvaKeep(); bMovedFwd = sal_False; } } } continue; } //Ich passe nicht mehr in meinen Uebergeordneten, also ist es jetzt //an der Zeit moeglichst konstruktive Veranderungen vorzunehmen //Wenn ich den uebergeordneten Frm nicht verlassen darf, habe //ich ein Problem; Frei nach Artur Dent tun wir das einzige das man //mit einen nicht loesbaren Problem tun kann: wir ignorieren es - und //zwar mit aller Kraft. if ( !bMoveable || IsUndersized() ) { if( !bMoveable && IsInTab() ) { long nDiff = -(Frm().*fnRect->fnBottomDist)( (GetUpper()->*fnRect->fnGetPrtBottom)() ); long nReal = GetUpper()->Grow( nDiff ); if( nReal ) continue; } break; } //Wenn ich nun ueberhaupt ganz und garnicht in meinen Upper passe //so kann die Situation vielleicht doch noch durch Aufbrechen //aufgeklart werden. Diese Situation tritt bei einem frisch //erzeugten Follow auf, der zwar auf die Folgeseite geschoben wurde //aber selbst noch zu gross fuer diese ist; also wiederum //aufgespalten werden muss. //Wenn ich nicht passe und nicht Spaltbar (WouldFit()) bin, so schicke //ich meinem TxtFrmanteil die Nachricht, dass eben falls moeglich //trotz des Attributes 'nicht aufspalten' aufgespalten werden muss. sal_Bool bMoveOrFit = sal_False; sal_Bool bDontMoveMe = !GetIndPrev(); if( bDontMoveMe && IsInSct() ) { SwFtnBossFrm* pBoss = FindFtnBossFrm(); bDontMoveMe = !pBoss->IsInSct() || ( !pBoss->Lower()->GetNext() && !pBoss->GetPrev() ); } // Finally, we are able to split table rows. Therefore, bDontMoveMe // can be set to sal_False: if( bDontMoveMe && IsInTab() && 0 != const_cast(this)->GetNextCellLeaf( MAKEPAGE_NONE ) ) bDontMoveMe = sal_False; if ( bDontMoveMe && (Frm().*fnRect->fnGetHeight)() > (GetUpper()->Prt().*fnRect->fnGetHeight)() ) { if ( !bFitPromise ) { SwTwips nTmp = (GetUpper()->Prt().*fnRect->fnGetHeight)() - (Prt().*fnRect->fnGetTop)(); sal_Bool bSplit = !IsFwdMoveAllowed(); if ( nTmp > 0 && WouldFit( nTmp, bSplit, sal_False ) ) { Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False ); bValidSize = sal_False; bFitPromise = sal_True; continue; } /* -----------------19.02.99 12:58------------------- * Frueher wurde in Rahmen und Bereichen niemals versucht, * durch bMoveOrFit den TxtFrm unter Verzicht auf seine * Attribute (Widows,Keep) doch noch passend zu bekommen. * Dies haette zumindest bei spaltigen Rahmen versucht * werden muessen, spaetestens bei verketteten Rahmen und * in Bereichen muss es versucht werden. * Ausnahme: Wenn wir im FormatWidthCols stehen, duerfen die * Attribute nicht ausser Acht gelassen werden. * --------------------------------------------------*/ else if ( !bFtn && bMoveable && ( !bFly || !FindFlyFrm()->IsColLocked() ) && ( !bSct || !FindSctFrm()->IsColLocked() ) ) bMoveOrFit = sal_True; } #ifdef DBG_UTIL else { ASSERT( sal_False, "+TxtFrm hat WouldFit-Versprechen nicht eingehalten." ); } #endif } //Mal sehen ob ich irgenwo Platz finde... //Benachbarte Fussnoten werden in _MoveFtnCntFwd 'vorgeschoben' SwFrm *pPre = GetIndPrev(); SwFrm *pOldUp = GetUpper(); /* MA 13. Oct. 98: Was soll das denn sein!? * AMA 14. Dec 98: Wenn ein spaltiger Bereich keinen Platz mehr fuer seinen ersten ContentFrm * bietet, so soll dieser nicht nur in die naechste Spalte, sondern ggf. bis zur naechsten * Seite wandern und dort einen Section-Follow erzeugen. */ if( IsInSct() && bMovedFwd && bMakePage && pOldUp->IsColBodyFrm() && pOldUp->GetUpper()->GetUpper()->IsSctFrm() && ( pPre || pOldUp->GetUpper()->GetPrev() ) && ((SwSectionFrm*)pOldUp->GetUpper()->GetUpper())->MoveAllowed(this) ) bMovedFwd = sal_False; const sal_Bool bCheckForGrownBody = pOldUp->IsBodyFrm(); const long nOldBodyHeight = (pOldUp->Frm().*fnRect->fnGetHeight)(); if ( !bMovedFwd && !MoveFwd( bMakePage, sal_False ) ) bMakePage = sal_False; SWREFRESHFN( this ) // If MoveFwd moves the paragraph to the next page, a following // paragraph, which contains footnotes can can cause the old upper // frame to grow. In this case we explicitly allow a new check // for MoveBwd. Robust: We also check the bMovedBwd flag again. // If pOldUp was a footnote frame, it has been deleted inside MoveFwd. // Therefore we only check for growing body frames. if ( bCheckForGrownBody && ! bMovedBwd && pOldUp != GetUpper() && (pOldUp->Frm().*fnRect->fnGetHeight)() > nOldBodyHeight ) bMovedFwd = sal_False; else bMovedFwd = sal_True; bFormatted = sal_False; if ( bMoveOrFit && GetUpper() == pOldUp ) { // FME 2007-08-30 #i81146# new loop control if ( nConsequetiveFormatsWithoutChange <= cnStopFormat ) { Prepare( PREP_MUST_FIT, 0, sal_False ); bValidSize = sal_False; bMustFit = sal_True; continue; } #if OSL_DEBUG_LEVEL > 1 ASSERT( false, "LoopControl in SwCntntFrm::MakeAll" ) #endif } if ( bMovedBwd && GetUpper() ) { //Unuetz gewordene Invalidierungen zuruecknehmen. GetUpper()->ResetCompletePaint(); if( pPre && !pPre->IsSctFrm() ) ::ValidateSz( pPre ); } } //while ( !bValidPos || !bValidSize || !bValidPrtArea ) // NEW: Looping Louie (Light). Should not be applied in balanced sections. // Should only be applied if there is no better solution! LOOPING_LOUIE_LIGHT( bMovedFwd && bMovedBwd && !IsInBalancedSection() && ( // --> FME 2005-01-26 #118572# ( bFtn && !FindFtnFrm()->GetRef()->IsInSct() ) || // <-- // --> FME 2005-01-27 #i33887# ( IsInSct() && bKeep ) // <-- // ... add your conditions here ... ), static_cast(*this) ); if ( pSaveFtn ) delete pSaveFtn; UnlockJoin(); if ( bMovedFwd || bMovedBwd ) pNotify->SetInvaKeep(); // OD 2004-02-26 #i25029# if ( bMovedFwd ) { pNotify->SetInvalidatePrevPrtArea(); } delete pNotify; SetFlyLock( sal_False ); } /************************************************************************* |* |* SwCntntFrm::_WouldFit() |* |* Ersterstellung MA 28. Feb. 95 |* Letzte Aenderung AMA 15. Feb. 99 |* |*************************************************************************/ void MakeNxt( SwFrm *pFrm, SwFrm *pNxt ) { //fix(25455): Validieren, sonst kommt es zu einer Rekursion. //Der erste Versuch, der Abbruch mit pFrm = 0 wenn !Valid, //fuehrt leider zu dem Problem, dass das Keep dann u.U. nicht mehr //korrekt beachtet wird (27417) const sal_Bool bOldPos = pFrm->GetValidPosFlag(); const sal_Bool bOldSz = pFrm->GetValidSizeFlag(); const sal_Bool bOldPrt = pFrm->GetValidPrtAreaFlag(); pFrm->bValidPos = pFrm->bValidPrtArea = pFrm->bValidSize = sal_True; //fix(29272): Nicht MakeAll rufen, dort wird evtl. pFrm wieder invalidert //und kommt rekursiv wieder herein. if ( pNxt->IsCntntFrm() ) { SwCntntNotify aNotify( (SwCntntFrm*)pNxt ); SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt ); const SwBorderAttrs &rAttrs = *aAccess.Get(); if ( !pNxt->GetValidSizeFlag() ) { if( pNxt->IsVertical() ) pNxt->Frm().Height( pNxt->GetUpper()->Prt().Height() ); else pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() ); } ((SwCntntFrm*)pNxt)->MakePrtArea( rAttrs ); pNxt->Format( &rAttrs ); } else { SwLayNotify aNotify( (SwLayoutFrm*)pNxt ); SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt ); const SwBorderAttrs &rAttrs = *aAccess.Get(); if ( !pNxt->GetValidSizeFlag() ) { if( pNxt->IsVertical() ) pNxt->Frm().Height( pNxt->GetUpper()->Prt().Height() ); else pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() ); } pNxt->Format( &rAttrs ); } pFrm->bValidPos = bOldPos; pFrm->bValidSize = bOldSz; pFrm->bValidPrtArea = bOldPrt; } // Diese Routine ueberprueft, ob zwischen dem FtnBoss von pFrm und dem // von pNxt keine anderen FtnBosse liegen sal_Bool lcl_IsNextFtnBoss( const SwFrm *pFrm, const SwFrm* pNxt ) { ASSERT( pFrm && pNxt, "lcl_IsNextFtnBoss: No Frames?" ); pFrm = pFrm->FindFtnBossFrm(); pNxt = pNxt->FindFtnBossFrm(); // Falls pFrm eine letzte Spalte ist, wird stattdessen die Seite genommen while( pFrm && pFrm->IsColumnFrm() && !pFrm->GetNext() ) pFrm = pFrm->GetUpper()->FindFtnBossFrm(); // Falls pNxt eine erste Spalte ist, wird stattdessen die Seite genommen while( pNxt && pNxt->IsColumnFrm() && !pNxt->GetPrev() ) pNxt = pNxt->GetUpper()->FindFtnBossFrm(); // So, jetzt muessen pFrm und pNxt entweder zwei benachbarte Seiten oder Spalten sein. return ( pFrm && pNxt && pFrm->GetNext() == pNxt ); } // --> OD 2007-11-26 #b6614158# sal_Bool SwCntntFrm::_WouldFit( SwTwips nSpace, SwLayoutFrm *pNewUpper, sal_Bool bTstMove, const bool bObjsInNewUpper ) // <-- { //Damit die Fussnote sich ihren Platz sorgsam waehlt, muss //sie in jedem Fall gemoved werden, wenn zwischen dem //neuen Upper und ihrer aktuellen Seite/Spalte mindestens eine //Seite/Spalte liegt. SwFtnFrm* pFtnFrm = 0; if ( IsInFtn() ) { if( !lcl_IsNextFtnBoss( pNewUpper, this ) ) return sal_True; pFtnFrm = FindFtnFrm(); } sal_Bool bRet; sal_Bool bSplit = !pNewUpper->Lower(); SwCntntFrm *pFrm = this; const SwFrm *pTmpPrev = pNewUpper->Lower(); if( pTmpPrev && pTmpPrev->IsFtnFrm() ) pTmpPrev = ((SwFtnFrm*)pTmpPrev)->Lower(); while ( pTmpPrev && pTmpPrev->GetNext() ) pTmpPrev = pTmpPrev->GetNext(); do { // --> FME 2005-03-31 #b6236853# #i46181# SwTwips nSecondCheck = 0; SwTwips nOldSpace = nSpace; sal_Bool bOldSplit = bSplit; // <-- if ( bTstMove || IsInFly() || ( IsInSct() && ( pFrm->GetUpper()->IsColBodyFrm() || ( pFtnFrm && pFtnFrm->GetUpper()->GetUpper()->IsColumnFrm() ) ) ) ) { //Jetzt wirds ein bischen hinterlistig; empfindliche Gemueter sollten //lieber wegsehen. Wenn ein Flys Spalten enthaelt so sind die Cntnts //moveable, mit Ausnahme der in der letzten Spalte (siehe //SwFrm::IsMoveable()). Zurueckfliessen duerfen sie aber natuerlich. //Das WouldFit() liefert leider nur dann einen vernueftigen Wert, wenn //der Frm moveable ist. Um dem WouldFit() einen Moveable Frm //vorzugaukeln haenge ich ihn einfach solange um. // Auch bei spaltigen Bereichen muss umgehaengt werden, damit // SwSectionFrm::Growable() den richtigen Wert liefert. // Innerhalb von Fussnoten muss ggf. sogar der SwFtnFrm umgehaengt werden, // falls es dort keinen SwFtnFrm gibt. SwFrm* pTmpFrm = pFrm->IsInFtn() && !pNewUpper->FindFtnFrm() ? (SwFrm*)pFrm->FindFtnFrm() : pFrm; SwLayoutFrm *pUp = pTmpFrm->GetUpper(); SwFrm *pOldNext = pTmpFrm->GetNext(); pTmpFrm->Remove(); pTmpFrm->InsertBefore( pNewUpper, 0 ); if ( pFrm->IsTxtFrm() && ( bTstMove || ((SwTxtFrm*)pFrm)->HasFollow() || ( !((SwTxtFrm*)pFrm)->HasPara() && !((SwTxtFrm*)pFrm)->IsEmpty() ) ) ) { bTstMove = sal_True; bRet = ((SwTxtFrm*)pFrm)->TestFormat( pTmpPrev, nSpace, bSplit ); } else bRet = pFrm->WouldFit( nSpace, bSplit, sal_False ); pTmpFrm->Remove(); pTmpFrm->InsertBefore( pUp, pOldNext ); } else { bRet = pFrm->WouldFit( nSpace, bSplit, sal_False ); nSecondCheck = !bSplit ? 1 : 0; } SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm ); const SwBorderAttrs &rAttrs = *aAccess.Get(); //Bitter aber wahr: Der Abstand muss auch noch mit einkalkuliert werden. //Bei TestFormatierung ist dies bereits geschehen. if ( bRet && !bTstMove ) { SwTwips nUpper; if ( pTmpPrev ) { nUpper = CalcUpperSpace( NULL, pTmpPrev ); // in balanced columned section frames we do not want the // common border sal_Bool bCommonBorder = sal_True; if ( pFrm->IsInSct() && pFrm->GetUpper()->IsColBodyFrm() ) { const SwSectionFrm* pSct = pFrm->FindSctFrm(); bCommonBorder = pSct->GetFmt()->GetBalancedColumns().GetValue(); } // --> FME 2005-03-31 #b6236853# #i46181# nSecondCheck = ( 1 == nSecondCheck && pFrm == this && IsTxtFrm() && bCommonBorder && !static_cast(this)->IsEmpty() ) ? nUpper : 0; // <-- nUpper += bCommonBorder ? rAttrs.GetBottomLine( *(pFrm) ) : rAttrs.CalcBottomLine(); } else { // --> FME 2005-03-31 #b6236853# #i46181# nSecondCheck = 0; // <-- if( pFrm->IsVertical() ) nUpper = pFrm->Frm().Width() - pFrm->Prt().Width(); else nUpper = pFrm->Frm().Height() - pFrm->Prt().Height(); } nSpace -= nUpper; if ( nSpace < 0 ) { bRet = sal_False; // --> FME 2005-03-31 #b6236853# #i46181# if ( nSecondCheck > 0 ) { // The following code is indented to solve a (rare) problem // causing some frames not to move backward: // SwTxtFrm::WouldFit() claims that the whole paragraph // fits into the given space and subtracts the height of // all lines from nSpace. nSpace - nUpper is not a valid // indicator if the frame should be allowed to move backward. // We do a second check with the original remaining space // reduced by the required upper space: nOldSpace -= nSecondCheck; const bool bSecondRet = nOldSpace >= 0 && pFrm->WouldFit( nOldSpace, bOldSplit, sal_False ); if ( bSecondRet && bOldSplit && nOldSpace >= 0 ) { bRet = sal_True; bSplit = sal_True; } } // <-- } } // OD 2004-03-01 #106629# - also consider lower spacing in table cells if ( bRet && IsInTab() && pNewUpper->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) ) { nSpace -= rAttrs.GetULSpace().GetLower(); if ( nSpace < 0 ) { bRet = sal_False; } } if ( bRet && !bSplit && pFrm->IsKeep( rAttrs.GetAttrSet() ) ) { if( bTstMove ) { while( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() ) { pFrm = ((SwTxtFrm*)pFrm)->GetFollow(); } // OD 11.04.2003 #108824# - If last follow frame of text // frame isn't valid, a formatting of the next content frame // doesn't makes sense. Thus, return sal_True. if ( IsAnFollow( pFrm ) && !pFrm->IsValid() ) { ASSERT( false, "Only a warning for task 108824:/nFindNext()) && pNxt->IsCntntFrm() && ( !pFtnFrm || ( pNxt->IsInFtn() && pNxt->FindFtnFrm()->GetAttr() == pFtnFrm->GetAttr() ) ) ) { // ProbeFormatierung vertraegt keine absatz- oder gar zeichengebundene Objekte // --> OD 2007-11-26 #b6614158# // current solution for the test formatting doesn't work, if // objects are present in the remaining area of the new upper if ( bTstMove && ( pNxt->GetDrawObjs() || bObjsInNewUpper ) ) { return sal_True; } // <-- if ( !pNxt->IsValid() ) MakeNxt( pFrm, pNxt ); //Kleiner Trick: Wenn der naechste einen Vorgaenger hat, so hat //er den Absatzabstand bereits berechnet. Er braucht dann nicht //teuer kalkuliert werden. if( lcl_NotHiddenPrev( pNxt ) ) pTmpPrev = 0; else { if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow() ) pTmpPrev = lcl_NotHiddenPrev( pFrm ); else pTmpPrev = pFrm; } pFrm = (SwCntntFrm*)pNxt; } else pFrm = 0; } else pFrm = 0; } while ( bRet && pFrm ); return bRet; }