1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3efeef26fSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist * or more contributor license agreements. See the NOTICE file
5efeef26fSAndrew Rist * distributed with this work for additional information
6efeef26fSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7efeef26fSAndrew Rist * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11efeef26fSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13efeef26fSAndrew Rist * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist * software distributed under the License is distributed on an
15efeef26fSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist * KIND, either express or implied. See the License for the
17efeef26fSAndrew Rist * specific language governing permissions and limitations
18efeef26fSAndrew Rist * under the License.
19cdf0e10cSrcweir *
20efeef26fSAndrew Rist *************************************************************/
21efeef26fSAndrew Rist
22efeef26fSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir #include <hintids.hxx>
29cdf0e10cSrcweir #include <editeng/keepitem.hxx>
30cdf0e10cSrcweir #include <editeng/hyznitem.hxx>
31cdf0e10cSrcweir #include <pagefrm.hxx> // ChangeFtnRef
32cdf0e10cSrcweir #include <ndtxt.hxx> // MakeFrm()
33cdf0e10cSrcweir #include <dcontact.hxx> // SwDrawContact
34cdf0e10cSrcweir #include <dflyobj.hxx> // SwVirtFlyDrawObj
35cdf0e10cSrcweir #include <flyfrm.hxx>
36cdf0e10cSrcweir #include <ftnfrm.hxx> // SwFtnFrm
37cdf0e10cSrcweir #include <txtftn.hxx>
38cdf0e10cSrcweir #include <fmtftn.hxx>
39cdf0e10cSrcweir #include <paratr.hxx>
40cdf0e10cSrcweir #include <viewopt.hxx> // SwViewOptions
41cdf0e10cSrcweir #include <viewsh.hxx> // ViewShell
42cdf0e10cSrcweir #include <frmatr.hxx>
43cdf0e10cSrcweir #include <pam.hxx>
44cdf0e10cSrcweir #include <flyfrms.hxx>
45cdf0e10cSrcweir #include <fmtanchr.hxx>
46cdf0e10cSrcweir #include <txtcfg.hxx>
47cdf0e10cSrcweir #include <itrform2.hxx> // SwTxtFormatter
48cdf0e10cSrcweir #include <widorp.hxx> // Widows and Orphans
49cdf0e10cSrcweir #include <txtcache.hxx>
50cdf0e10cSrcweir #include <porrst.hxx> // SwEmptyPortion
51cdf0e10cSrcweir #include <blink.hxx> // pBlink
52cdf0e10cSrcweir #include <porfld.hxx> // SwFldPortion
53cdf0e10cSrcweir #include <sectfrm.hxx> // SwSectionFrm
54cdf0e10cSrcweir #include <pormulti.hxx> // SwMultiPortion
55cdf0e10cSrcweir
56cdf0e10cSrcweir #include <rootfrm.hxx>
57cdf0e10cSrcweir #include <frmfmt.hxx> // SwFrmFmt
58cdf0e10cSrcweir // OD 2004-05-24 #i28701#
59cdf0e10cSrcweir #include <sortedobjs.hxx>
60*ca62e2c2SSteve Yin #include <portab.hxx>
61*ca62e2c2SSteve Yin #include <editeng/lrspitem.hxx>
62*ca62e2c2SSteve Yin #include <editeng/tstpitem.hxx>
63cdf0e10cSrcweir
64cdf0e10cSrcweir class FormatLevel
65cdf0e10cSrcweir {
66cdf0e10cSrcweir static MSHORT nLevel;
67cdf0e10cSrcweir public:
FormatLevel()68cdf0e10cSrcweir inline FormatLevel() { ++nLevel; }
~FormatLevel()69cdf0e10cSrcweir inline ~FormatLevel() { --nLevel; }
GetLevel() const70cdf0e10cSrcweir inline MSHORT GetLevel() const { return nLevel; }
LastLevel()71cdf0e10cSrcweir static sal_Bool LastLevel() { return 10 < nLevel; }
72cdf0e10cSrcweir };
73cdf0e10cSrcweir MSHORT FormatLevel::nLevel = 0;
74cdf0e10cSrcweir
75cdf0e10cSrcweir /*************************************************************************
76cdf0e10cSrcweir * ValidateTxt/Frm()
77cdf0e10cSrcweir *************************************************************************/
78cdf0e10cSrcweir
ValidateTxt(SwFrm * pFrm)79cdf0e10cSrcweir void ValidateTxt( SwFrm *pFrm ) // Freund vom Frame
80cdf0e10cSrcweir {
81cdf0e10cSrcweir if ( ( ! pFrm->IsVertical() &&
82cdf0e10cSrcweir pFrm->Frm().Width() == pFrm->GetUpper()->Prt().Width() ) ||
83cdf0e10cSrcweir ( pFrm->IsVertical() &&
84cdf0e10cSrcweir pFrm->Frm().Height() == pFrm->GetUpper()->Prt().Height() ) )
85cdf0e10cSrcweir pFrm->bValidSize = sal_True;
86cdf0e10cSrcweir /*
87cdf0e10cSrcweir pFrm->bValidPrtArea = sal_True;
88cdf0e10cSrcweir //Die Position validieren um nicht unnoetige (Test-)Moves zu provozieren.
89cdf0e10cSrcweir //Dabei darf allerdings nicht eine tatsaechlich falsche Coordinate
90cdf0e10cSrcweir //validiert werden.
91cdf0e10cSrcweir if ( !pFrm->bValidPos )
92cdf0e10cSrcweir {
93cdf0e10cSrcweir //Leider muessen wir dazu die korrekte Position berechnen.
94cdf0e10cSrcweir Point aOld( pFrm->Frm().Pos() );
95cdf0e10cSrcweir pFrm->MakePos();
96cdf0e10cSrcweir if ( aOld != pFrm->Pos() )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir pFrm->Frm().Pos( aOld );
99cdf0e10cSrcweir pFrm->bValidPos = sal_False;
100cdf0e10cSrcweir }
101cdf0e10cSrcweir }
102cdf0e10cSrcweir */
103cdf0e10cSrcweir }
104cdf0e10cSrcweir
ValidateFrm()105cdf0e10cSrcweir void SwTxtFrm::ValidateFrm()
106cdf0e10cSrcweir {
107cdf0e10cSrcweir // Umgebung validieren, um Oszillationen zu verhindern.
108cdf0e10cSrcweir SWAP_IF_SWAPPED( this )
109cdf0e10cSrcweir
110cdf0e10cSrcweir if ( !IsInFly() && !IsInTab() )
111cdf0e10cSrcweir { //Innerhalb eines Flys nur this validieren, der Rest sollte eigentlich
112cdf0e10cSrcweir //nur fuer Fussnoten notwendig sein und die gibt es innerhalb von
113cdf0e10cSrcweir //Flys nicht. Fix fuer 5544
114cdf0e10cSrcweir SwSectionFrm* pSct = FindSctFrm();
115cdf0e10cSrcweir if( pSct )
116cdf0e10cSrcweir {
117cdf0e10cSrcweir if( !pSct->IsColLocked() )
118cdf0e10cSrcweir pSct->ColLock();
119cdf0e10cSrcweir else
120cdf0e10cSrcweir pSct = NULL;
121cdf0e10cSrcweir }
122cdf0e10cSrcweir
123cdf0e10cSrcweir SwFrm *pUp = GetUpper();
124cdf0e10cSrcweir pUp->Calc();
125cdf0e10cSrcweir if( pSct )
126cdf0e10cSrcweir pSct->ColUnlock();
127cdf0e10cSrcweir }
128cdf0e10cSrcweir ValidateTxt( this );
129cdf0e10cSrcweir
130cdf0e10cSrcweir //MA: mindestens das MustFit-Flag muessen wir retten!
131cdf0e10cSrcweir ASSERT( HasPara(), "ResetPreps(), missing ParaPortion." );
132cdf0e10cSrcweir SwParaPortion *pPara = GetPara();
133cdf0e10cSrcweir const sal_Bool bMustFit = pPara->IsPrepMustFit();
134cdf0e10cSrcweir ResetPreps();
135cdf0e10cSrcweir pPara->SetPrepMustFit( bMustFit );
136cdf0e10cSrcweir
137cdf0e10cSrcweir UNDO_SWAP( this )
138cdf0e10cSrcweir }
139cdf0e10cSrcweir
140cdf0e10cSrcweir /*************************************************************************
141cdf0e10cSrcweir * ValidateBodyFrm()
142cdf0e10cSrcweir *************************************************************************/
143cdf0e10cSrcweir
144cdf0e10cSrcweir // nach einem RemoveFtn muss der BodyFrm und alle innenliegenden kalkuliert
145cdf0e10cSrcweir // werden, damit die DeadLine richtig sitzt.
146cdf0e10cSrcweir // Erst wird nach aussen hin gesucht, beim Rueckweg werden alle kalkuliert.
147cdf0e10cSrcweir
_ValidateBodyFrm(SwFrm * pFrm)148cdf0e10cSrcweir void _ValidateBodyFrm( SwFrm *pFrm )
149cdf0e10cSrcweir {
150cdf0e10cSrcweir if( pFrm && !pFrm->IsCellFrm() )
151cdf0e10cSrcweir {
152cdf0e10cSrcweir if( !pFrm->IsBodyFrm() && pFrm->GetUpper() )
153cdf0e10cSrcweir _ValidateBodyFrm( pFrm->GetUpper() );
154cdf0e10cSrcweir if( !pFrm->IsSctFrm() )
155cdf0e10cSrcweir pFrm->Calc();
156cdf0e10cSrcweir else
157cdf0e10cSrcweir {
158cdf0e10cSrcweir sal_Bool bOld = ((SwSectionFrm*)pFrm)->IsCntntLocked();
159cdf0e10cSrcweir ((SwSectionFrm*)pFrm)->SetCntntLock( sal_True );
160cdf0e10cSrcweir pFrm->Calc();
161cdf0e10cSrcweir if( !bOld )
162cdf0e10cSrcweir ((SwSectionFrm*)pFrm)->SetCntntLock( sal_False );
163cdf0e10cSrcweir }
164cdf0e10cSrcweir }
165cdf0e10cSrcweir }
166cdf0e10cSrcweir
ValidateBodyFrm()167cdf0e10cSrcweir void SwTxtFrm::ValidateBodyFrm()
168cdf0e10cSrcweir {
169cdf0e10cSrcweir SWAP_IF_SWAPPED( this )
170cdf0e10cSrcweir
171cdf0e10cSrcweir //siehe Kommtar in ValidateFrm()
172cdf0e10cSrcweir if ( !IsInFly() && !IsInTab() &&
173cdf0e10cSrcweir !( IsInSct() && FindSctFrm()->Lower()->IsColumnFrm() ) )
174cdf0e10cSrcweir _ValidateBodyFrm( GetUpper() );
175cdf0e10cSrcweir
176cdf0e10cSrcweir UNDO_SWAP( this )
177cdf0e10cSrcweir }
178cdf0e10cSrcweir
179cdf0e10cSrcweir /*************************************************************************
180cdf0e10cSrcweir * SwTxtFrm::FindBodyFrm()
181cdf0e10cSrcweir *************************************************************************/
182cdf0e10cSrcweir
_GetDropRect(SwRect & rRect) const183cdf0e10cSrcweir sal_Bool SwTxtFrm::_GetDropRect( SwRect &rRect ) const
184cdf0e10cSrcweir {
185cdf0e10cSrcweir SWAP_IF_NOT_SWAPPED( this )
186cdf0e10cSrcweir
187cdf0e10cSrcweir ASSERT( HasPara(), "SwTxtFrm::_GetDropRect: try again next year." );
188cdf0e10cSrcweir SwTxtSizeInfo aInf( (SwTxtFrm*)this );
189cdf0e10cSrcweir SwTxtMargin aLine( (SwTxtFrm*)this, &aInf );
190cdf0e10cSrcweir if( aLine.GetDropLines() )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir rRect.Top( aLine.Y() );
193cdf0e10cSrcweir rRect.Left( aLine.GetLineStart() );
194cdf0e10cSrcweir rRect.Height( aLine.GetDropHeight() );
195cdf0e10cSrcweir rRect.Width( aLine.GetDropLeft() );
196cdf0e10cSrcweir
197cdf0e10cSrcweir if ( IsRightToLeft() )
198cdf0e10cSrcweir SwitchLTRtoRTL( rRect );
199cdf0e10cSrcweir
200cdf0e10cSrcweir if ( IsVertical() )
201cdf0e10cSrcweir SwitchHorizontalToVertical( rRect );
202cdf0e10cSrcweir UNDO_SWAP( this )
203cdf0e10cSrcweir return sal_True;
204cdf0e10cSrcweir }
205cdf0e10cSrcweir
206cdf0e10cSrcweir UNDO_SWAP( this )
207cdf0e10cSrcweir
208cdf0e10cSrcweir return sal_False;
209cdf0e10cSrcweir }
210cdf0e10cSrcweir
211cdf0e10cSrcweir /*************************************************************************
212cdf0e10cSrcweir * SwTxtFrm::FindBodyFrm()
213cdf0e10cSrcweir *************************************************************************/
214cdf0e10cSrcweir
FindBodyFrm() const215cdf0e10cSrcweir const SwBodyFrm *SwTxtFrm::FindBodyFrm() const
216cdf0e10cSrcweir {
217cdf0e10cSrcweir if ( IsInDocBody() )
218cdf0e10cSrcweir {
219cdf0e10cSrcweir const SwFrm *pFrm = GetUpper();
220cdf0e10cSrcweir while( pFrm && !pFrm->IsBodyFrm() )
221cdf0e10cSrcweir pFrm = pFrm->GetUpper();
222cdf0e10cSrcweir return (const SwBodyFrm*)pFrm;
223cdf0e10cSrcweir }
224cdf0e10cSrcweir return 0;
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
227cdf0e10cSrcweir /*************************************************************************
228cdf0e10cSrcweir * SwTxtFrm::CalcFollow()
229cdf0e10cSrcweir *************************************************************************/
230cdf0e10cSrcweir
CalcFollow(const xub_StrLen nTxtOfst)231cdf0e10cSrcweir sal_Bool SwTxtFrm::CalcFollow( const xub_StrLen nTxtOfst )
232cdf0e10cSrcweir {
233cdf0e10cSrcweir SWAP_IF_SWAPPED( this )
234cdf0e10cSrcweir
235cdf0e10cSrcweir ASSERT( HasFollow(), "CalcFollow: missing Follow." );
236cdf0e10cSrcweir
237cdf0e10cSrcweir SwTxtFrm* pMyFollow = GetFollow();
238cdf0e10cSrcweir
239cdf0e10cSrcweir SwParaPortion *pPara = GetPara();
240cdf0e10cSrcweir sal_Bool bFollowFld = pPara ? pPara->IsFollowField() : sal_False;
241cdf0e10cSrcweir
242cdf0e10cSrcweir if( !pMyFollow->GetOfst() || pMyFollow->GetOfst() != nTxtOfst ||
243cdf0e10cSrcweir bFollowFld || pMyFollow->IsFieldFollow() ||
244cdf0e10cSrcweir ( pMyFollow->IsVertical() && !pMyFollow->Prt().Width() ) ||
245cdf0e10cSrcweir ( ! pMyFollow->IsVertical() && !pMyFollow->Prt().Height() ) )
246cdf0e10cSrcweir {
247cdf0e10cSrcweir #ifdef DBG_UTIL
248cdf0e10cSrcweir const SwFrm *pOldUp = GetUpper();
249cdf0e10cSrcweir #endif
250cdf0e10cSrcweir
251cdf0e10cSrcweir SWRECTFN ( this )
252cdf0e10cSrcweir SwTwips nOldBottom = (GetUpper()->Frm().*fnRect->fnGetBottom)();
253cdf0e10cSrcweir SwTwips nMyPos = (Frm().*fnRect->fnGetTop)();
254cdf0e10cSrcweir
255cdf0e10cSrcweir const SwPageFrm *pPage = 0;
256cdf0e10cSrcweir sal_Bool bOldInvaCntnt = sal_True;
257cdf0e10cSrcweir if ( !IsInFly() && GetNext() )
258cdf0e10cSrcweir {
259cdf0e10cSrcweir pPage = FindPageFrm();
260cdf0e10cSrcweir //Minimieren - sprich ggf. zuruecksetzen - der Invalidierungen s.u.
261cdf0e10cSrcweir bOldInvaCntnt = pPage->IsInvalidCntnt();
262cdf0e10cSrcweir }
263cdf0e10cSrcweir
264cdf0e10cSrcweir pMyFollow->_SetOfst( nTxtOfst );
265cdf0e10cSrcweir pMyFollow->SetFieldFollow( bFollowFld );
266cdf0e10cSrcweir if( HasFtn() || pMyFollow->HasFtn() )
267cdf0e10cSrcweir {
268cdf0e10cSrcweir ValidateFrm();
269cdf0e10cSrcweir ValidateBodyFrm();
270cdf0e10cSrcweir if( pPara )
271cdf0e10cSrcweir {
272cdf0e10cSrcweir *(pPara->GetReformat()) = SwCharRange();
273cdf0e10cSrcweir *(pPara->GetDelta()) = 0;
274cdf0e10cSrcweir }
275cdf0e10cSrcweir }
276cdf0e10cSrcweir
277cdf0e10cSrcweir //Der Fussnotenbereich darf sich keinesfalls vergrossern.
278cdf0e10cSrcweir SwSaveFtnHeight aSave( FindFtnBossFrm( sal_True ), LONG_MAX );
279cdf0e10cSrcweir
280cdf0e10cSrcweir pMyFollow->CalcFtnFlag();
281cdf0e10cSrcweir if ( !pMyFollow->GetNext() && !pMyFollow->HasFtn() )
282cdf0e10cSrcweir nOldBottom = bVert ? 0 : LONG_MAX;
283cdf0e10cSrcweir
284cdf0e10cSrcweir while( sal_True )
285cdf0e10cSrcweir {
286cdf0e10cSrcweir if( !FormatLevel::LastLevel() )
287cdf0e10cSrcweir {
288cdf0e10cSrcweir // Weenn der Follow in einem spaltigen Bereich oder einem
289cdf0e10cSrcweir // spaltigen Rahmen steckt, muss zunaechst dieser kalkuliert
290cdf0e10cSrcweir // werden, da das FormatWidthCols() nicht funktioniert, wenn
291cdf0e10cSrcweir // es aus dem MakeAll des _gelockten_ Follows heraus gerufen
292cdf0e10cSrcweir // wird.
293cdf0e10cSrcweir SwSectionFrm* pSct = pMyFollow->FindSctFrm();
294cdf0e10cSrcweir if( pSct && !pSct->IsAnLower( this ) )
295cdf0e10cSrcweir {
296cdf0e10cSrcweir if( pSct->GetFollow() )
297cdf0e10cSrcweir pSct->SimpleFormat();
298cdf0e10cSrcweir else if( ( pSct->IsVertical() && !pSct->Frm().Width() ) ||
299cdf0e10cSrcweir ( ! pSct->IsVertical() && !pSct->Frm().Height() ) )
300cdf0e10cSrcweir break;
301cdf0e10cSrcweir }
302cdf0e10cSrcweir // OD 14.03.2003 #i11760# - intrinsic format of follow is controlled.
303cdf0e10cSrcweir if ( FollowFormatAllowed() )
304cdf0e10cSrcweir {
305cdf0e10cSrcweir // OD 14.03.2003 #i11760# - no nested format of follows, if
306cdf0e10cSrcweir // text frame is contained in a column frame.
307cdf0e10cSrcweir // Thus, forbid intrinsic format of follow.
308cdf0e10cSrcweir {
309cdf0e10cSrcweir bool bIsFollowInColumn = false;
310cdf0e10cSrcweir SwFrm* pFollowUpper = pMyFollow->GetUpper();
311cdf0e10cSrcweir while ( pFollowUpper )
312cdf0e10cSrcweir {
313cdf0e10cSrcweir if ( pFollowUpper->IsColumnFrm() )
314cdf0e10cSrcweir {
315cdf0e10cSrcweir bIsFollowInColumn = true;
316cdf0e10cSrcweir break;
317cdf0e10cSrcweir }
318cdf0e10cSrcweir if ( pFollowUpper->IsPageFrm() ||
319cdf0e10cSrcweir pFollowUpper->IsFlyFrm() )
320cdf0e10cSrcweir {
321cdf0e10cSrcweir break;
322cdf0e10cSrcweir }
323cdf0e10cSrcweir pFollowUpper = pFollowUpper->GetUpper();
324cdf0e10cSrcweir }
325cdf0e10cSrcweir if ( bIsFollowInColumn )
326cdf0e10cSrcweir {
327cdf0e10cSrcweir pMyFollow->ForbidFollowFormat();
328cdf0e10cSrcweir }
329cdf0e10cSrcweir }
330cdf0e10cSrcweir
331cdf0e10cSrcweir pMyFollow->Calc();
332cdf0e10cSrcweir // Der Follow merkt anhand seiner Frm().Height(), dass was schief
333cdf0e10cSrcweir // gelaufen ist.
334cdf0e10cSrcweir ASSERT( !pMyFollow->GetPrev(), "SwTxtFrm::CalcFollow: cheesy follow" );
335cdf0e10cSrcweir if( pMyFollow->GetPrev() )
336cdf0e10cSrcweir {
337cdf0e10cSrcweir pMyFollow->Prepare( PREP_CLEAR );
338cdf0e10cSrcweir pMyFollow->Calc();
339cdf0e10cSrcweir ASSERT( !pMyFollow->GetPrev(), "SwTxtFrm::CalcFollow: very cheesy follow" );
340cdf0e10cSrcweir }
341cdf0e10cSrcweir
342cdf0e10cSrcweir // OD 14.03.2003 #i11760# - reset control flag for follow format.
343cdf0e10cSrcweir pMyFollow->AllowFollowFormat();
344cdf0e10cSrcweir }
345cdf0e10cSrcweir
346cdf0e10cSrcweir //Sicherstellen, dass der Follow gepaintet wird.
347cdf0e10cSrcweir pMyFollow->SetCompletePaint();
348cdf0e10cSrcweir }
349cdf0e10cSrcweir
350cdf0e10cSrcweir pPara = GetPara();
351cdf0e10cSrcweir //Solange der Follow wg. Orphans Zeilen angefordert, bekommt er
352cdf0e10cSrcweir //diese und wird erneut formatiert, falls moeglich.
353cdf0e10cSrcweir if( pPara && pPara->IsPrepWidows() )
354cdf0e10cSrcweir CalcPreps();
355cdf0e10cSrcweir else
356cdf0e10cSrcweir break;
357cdf0e10cSrcweir }
358cdf0e10cSrcweir
359cdf0e10cSrcweir if( HasFtn() || pMyFollow->HasFtn() )
360cdf0e10cSrcweir {
361cdf0e10cSrcweir ValidateBodyFrm();
362cdf0e10cSrcweir ValidateFrm();
363cdf0e10cSrcweir if( pPara )
364cdf0e10cSrcweir {
365cdf0e10cSrcweir *(pPara->GetReformat()) = SwCharRange();
366cdf0e10cSrcweir *(pPara->GetDelta()) = 0;
367cdf0e10cSrcweir }
368cdf0e10cSrcweir }
369cdf0e10cSrcweir
370cdf0e10cSrcweir if ( pPage )
371cdf0e10cSrcweir {
372cdf0e10cSrcweir if ( !bOldInvaCntnt )
373cdf0e10cSrcweir pPage->ValidateCntnt();
374cdf0e10cSrcweir }
375cdf0e10cSrcweir
376cdf0e10cSrcweir #ifdef DBG_UTIL
377cdf0e10cSrcweir ASSERT( pOldUp == GetUpper(), "SwTxtFrm::CalcFollow: heavy follow" );
378cdf0e10cSrcweir #endif
379cdf0e10cSrcweir
380cdf0e10cSrcweir const long nRemaining =
381cdf0e10cSrcweir - (GetUpper()->Frm().*fnRect->fnBottomDist)( nOldBottom );
382cdf0e10cSrcweir if ( nRemaining > 0 && !GetUpper()->IsSctFrm() &&
383cdf0e10cSrcweir nRemaining != ( bVert ?
384cdf0e10cSrcweir nMyPos - Frm().Right() :
385cdf0e10cSrcweir Frm().Top() - nMyPos ) )
386cdf0e10cSrcweir {
387cdf0e10cSrcweir UNDO_SWAP( this )
388cdf0e10cSrcweir return sal_True;
389cdf0e10cSrcweir }
390cdf0e10cSrcweir }
391cdf0e10cSrcweir
392cdf0e10cSrcweir UNDO_SWAP( this )
393cdf0e10cSrcweir
394cdf0e10cSrcweir return sal_False;
395cdf0e10cSrcweir }
396cdf0e10cSrcweir
397cdf0e10cSrcweir /*************************************************************************
398cdf0e10cSrcweir * SwTxtFrm::AdjustFrm()
399cdf0e10cSrcweir *************************************************************************/
400cdf0e10cSrcweir
AdjustFrm(const SwTwips nChgHght,sal_Bool bHasToFit)401cdf0e10cSrcweir void SwTxtFrm::AdjustFrm( const SwTwips nChgHght, sal_Bool bHasToFit )
402cdf0e10cSrcweir {
403cdf0e10cSrcweir if( IsUndersized() )
404cdf0e10cSrcweir {
405cdf0e10cSrcweir if( GetOfst() && !IsFollow() ) // ein gescrollter Absatz (undersized)
406cdf0e10cSrcweir return;
407cdf0e10cSrcweir SetUndersized( nChgHght == 0 || bHasToFit );
408cdf0e10cSrcweir }
409cdf0e10cSrcweir
410cdf0e10cSrcweir // AdjustFrm is called with a swapped frame during
411cdf0e10cSrcweir // formatting but the frame is not swapped during FormatEmpty
412cdf0e10cSrcweir SWAP_IF_SWAPPED( this )
413cdf0e10cSrcweir SWRECTFN ( this )
414cdf0e10cSrcweir
415cdf0e10cSrcweir // Die Size-Variable des Frames wird durch Grow inkrementiert
416cdf0e10cSrcweir // oder durch Shrink dekrementiert. Wenn die Groesse
417cdf0e10cSrcweir // unveraendert ist, soll nichts passieren!
418cdf0e10cSrcweir if( nChgHght >= 0)
419cdf0e10cSrcweir {
420cdf0e10cSrcweir SwTwips nChgHeight = nChgHght;
421cdf0e10cSrcweir if( nChgHght && !bHasToFit )
422cdf0e10cSrcweir {
423cdf0e10cSrcweir if( IsInFtn() && !IsInSct() )
424cdf0e10cSrcweir {
425cdf0e10cSrcweir SwTwips nReal = Grow( nChgHght, sal_True );
426cdf0e10cSrcweir if( nReal < nChgHght )
427cdf0e10cSrcweir {
428cdf0e10cSrcweir SwTwips nBot = (*fnRect->fnYInc)( (Frm().*fnRect->fnGetBottom)(),
429cdf0e10cSrcweir nChgHght - nReal );
430cdf0e10cSrcweir SwFrm* pCont = FindFtnFrm()->GetUpper();
431cdf0e10cSrcweir
432cdf0e10cSrcweir if( (pCont->Frm().*fnRect->fnBottomDist)( nBot ) > 0 )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir (Frm().*fnRect->fnAddBottom)( nChgHght );
435cdf0e10cSrcweir if( bVert )
436cdf0e10cSrcweir Prt().SSize().Width() += nChgHght;
437cdf0e10cSrcweir else
438cdf0e10cSrcweir Prt().SSize().Height() += nChgHght;
439cdf0e10cSrcweir UNDO_SWAP( this )
440cdf0e10cSrcweir return;
441cdf0e10cSrcweir }
442cdf0e10cSrcweir }
443cdf0e10cSrcweir }
444cdf0e10cSrcweir
445cdf0e10cSrcweir Grow( nChgHght );
446cdf0e10cSrcweir
447cdf0e10cSrcweir if ( IsInFly() )
448cdf0e10cSrcweir {
449cdf0e10cSrcweir //MA 06. May. 93: Wenn einer der Upper ein Fly ist, so ist es
450cdf0e10cSrcweir //sehr wahrscheinlich, dass dieser Fly durch das Grow seine
451cdf0e10cSrcweir //Position veraendert - also muss auch meine Position korrigiert
452cdf0e10cSrcweir //werden (sonst ist die Pruefung s.u. nicht aussagekraeftig).
453cdf0e10cSrcweir //Die Vorgaenger muessen berechnet werden, damit die Position
454cdf0e10cSrcweir //korrekt berechnet werden kann.
455cdf0e10cSrcweir if ( GetPrev() )
456cdf0e10cSrcweir {
457cdf0e10cSrcweir SwFrm *pPre = GetUpper()->Lower();
458cdf0e10cSrcweir do
459cdf0e10cSrcweir { pPre->Calc();
460cdf0e10cSrcweir pPre = pPre->GetNext();
461cdf0e10cSrcweir } while ( pPre && pPre != this );
462cdf0e10cSrcweir }
463cdf0e10cSrcweir const Point aOldPos( Frm().Pos() );
464cdf0e10cSrcweir MakePos();
465cdf0e10cSrcweir if ( aOldPos != Frm().Pos() )
466cdf0e10cSrcweir {
467cdf0e10cSrcweir // OD 2004-07-01 #i28701# - use new method <SwFrm::InvalidateObjs(..)>
468cdf0e10cSrcweir // No format is performed for the floating screen objects.
469cdf0e10cSrcweir InvalidateObjs( true );
470cdf0e10cSrcweir }
471cdf0e10cSrcweir }
472cdf0e10cSrcweir nChgHeight = 0;
473cdf0e10cSrcweir }
474cdf0e10cSrcweir // Ein Grow() wird von der Layout-Seite immer akzeptiert,
475cdf0e10cSrcweir // also auch, wenn die FixSize des umgebenden Layoutframes
476cdf0e10cSrcweir // dies nicht zulassen sollte. Wir ueberpruefen diesen
477cdf0e10cSrcweir // Fall und korrigieren die Werte.
478cdf0e10cSrcweir // MA 06. May. 93: Der Frm darf allerdings auch im Notfall nicht
479cdf0e10cSrcweir // weiter geschrumpft werden als es seine Groesse zulaesst.
480cdf0e10cSrcweir SwTwips nRstHeight;
481cdf0e10cSrcweir if ( IsVertical() )
482cdf0e10cSrcweir {
483cdf0e10cSrcweir ASSERT( ! IsSwapped(),"Swapped frame while calculating nRstHeight" );
484cdf0e10cSrcweir
485cdf0e10cSrcweir //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
486cdf0e10cSrcweir if ( IsVertLR() )
487cdf0e10cSrcweir nRstHeight = GetUpper()->Frm().Left()
488cdf0e10cSrcweir + GetUpper()->Prt().Left()
489cdf0e10cSrcweir + GetUpper()->Prt().Width()
490cdf0e10cSrcweir - Frm().Left();
491cdf0e10cSrcweir else
492cdf0e10cSrcweir nRstHeight = Frm().Left() + Frm().Width() -
493cdf0e10cSrcweir ( GetUpper()->Frm().Left() + GetUpper()->Prt().Left() );
494cdf0e10cSrcweir }
495cdf0e10cSrcweir else
496cdf0e10cSrcweir nRstHeight = GetUpper()->Frm().Top()
497cdf0e10cSrcweir + GetUpper()->Prt().Top()
498cdf0e10cSrcweir + GetUpper()->Prt().Height()
499cdf0e10cSrcweir - Frm().Top();
500cdf0e10cSrcweir
501cdf0e10cSrcweir //In Tabellenzellen kann ich mir evtl. noch ein wenig dazuholen, weil
502cdf0e10cSrcweir //durch eine vertikale Ausrichtung auch oben noch Raum sein kann.
503cdf0e10cSrcweir // --> OD 2004-11-25 #115759# - assure, that first lower in upper
504cdf0e10cSrcweir // is the current one or is valid.
505cdf0e10cSrcweir if ( IsInTab() &&
506cdf0e10cSrcweir ( GetUpper()->Lower() == this ||
507cdf0e10cSrcweir GetUpper()->Lower()->IsValid() ) )
508cdf0e10cSrcweir // <--
509cdf0e10cSrcweir {
510cdf0e10cSrcweir long nAdd = (*fnRect->fnYDiff)( (GetUpper()->Lower()->Frm().*fnRect->fnGetTop)(),
511cdf0e10cSrcweir (GetUpper()->*fnRect->fnGetPrtTop)() );
512cdf0e10cSrcweir ASSERT( nAdd >= 0, "Ey" );
513cdf0e10cSrcweir nRstHeight += nAdd;
514cdf0e10cSrcweir }
515cdf0e10cSrcweir
516cdf0e10cSrcweir /* ------------------------------------
517cdf0e10cSrcweir * #50964#: nRstHeight < 0 bedeutet, dass der TxtFrm komplett ausserhalb seines
518cdf0e10cSrcweir * Upper liegt. Dies kann passieren, wenn er innerhalb eines FlyAtCntFrm liegt, der
519cdf0e10cSrcweir * durch das Grow() die Seite gewechselt hat. In so einem Fall ist es falsch, der
520cdf0e10cSrcweir * folgenden Grow-Versuch durchzufuehren. Im Bugfall fuehrte dies sogar zur
521cdf0e10cSrcweir * Endlosschleife.
522cdf0e10cSrcweir * -----------------------------------*/
523cdf0e10cSrcweir SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
524cdf0e10cSrcweir SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
525cdf0e10cSrcweir
526cdf0e10cSrcweir if( nRstHeight < nFrmHeight )
527cdf0e10cSrcweir {
528cdf0e10cSrcweir //Kann sein, dass ich die richtige Grosse habe, der Upper aber zu
529cdf0e10cSrcweir //klein ist und der Upper noch Platz schaffen kann.
530cdf0e10cSrcweir if( ( nRstHeight >= 0 || ( IsInFtn() && IsInSct() ) ) && !bHasToFit )
531cdf0e10cSrcweir nRstHeight += GetUpper()->Grow( nFrmHeight - nRstHeight );
532cdf0e10cSrcweir // In spaltigen Bereichen wollen wir moeglichst nicht zu gross werden, damit
533cdf0e10cSrcweir // nicht ueber GetNextSctLeaf weitere Bereiche angelegt werden. Stattdessen
534cdf0e10cSrcweir // schrumpfen wir und notieren bUndersized, damit FormatWidthCols die richtige
535cdf0e10cSrcweir // Spaltengroesse ermitteln kann.
536cdf0e10cSrcweir if ( nRstHeight < nFrmHeight )
537cdf0e10cSrcweir {
538cdf0e10cSrcweir if( bHasToFit || !IsMoveable() ||
539cdf0e10cSrcweir ( IsInSct() && !FindSctFrm()->MoveAllowed(this) ) )
540cdf0e10cSrcweir {
541cdf0e10cSrcweir SetUndersized( sal_True );
542cdf0e10cSrcweir Shrink( Min( ( nFrmHeight - nRstHeight), nPrtHeight ) );
543cdf0e10cSrcweir }
544cdf0e10cSrcweir else
545cdf0e10cSrcweir SetUndersized( sal_False );
546cdf0e10cSrcweir }
547cdf0e10cSrcweir }
548cdf0e10cSrcweir else if( nChgHeight )
549cdf0e10cSrcweir {
550cdf0e10cSrcweir if( nRstHeight - nFrmHeight < nChgHeight )
551cdf0e10cSrcweir nChgHeight = nRstHeight - nFrmHeight;
552cdf0e10cSrcweir if( nChgHeight )
553cdf0e10cSrcweir Grow( nChgHeight );
554cdf0e10cSrcweir }
555cdf0e10cSrcweir }
556cdf0e10cSrcweir else
557cdf0e10cSrcweir Shrink( -nChgHght );
558cdf0e10cSrcweir
559cdf0e10cSrcweir UNDO_SWAP( this )
560cdf0e10cSrcweir }
561cdf0e10cSrcweir
GetTabStopInfo(SwTwips CurrentPos)562*ca62e2c2SSteve Yin com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > SwTxtFrm::GetTabStopInfo( SwTwips CurrentPos )
563*ca62e2c2SSteve Yin {
564*ca62e2c2SSteve Yin com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > tabs(1);
565*ca62e2c2SSteve Yin ::com::sun::star::style::TabStop ts;
566*ca62e2c2SSteve Yin
567*ca62e2c2SSteve Yin SwTxtFormatInfo aInf( this );
568*ca62e2c2SSteve Yin SwTxtFormatter aLine( this, &aInf );
569*ca62e2c2SSteve Yin SwTxtCursor TxtCursor( this, &aInf );
570*ca62e2c2SSteve Yin const Point aCharPos( TxtCursor.GetTopLeft() );
571*ca62e2c2SSteve Yin
572*ca62e2c2SSteve Yin
573*ca62e2c2SSteve Yin SwTwips nRight = aLine.Right();
574*ca62e2c2SSteve Yin CurrentPos -= aCharPos.X();
575*ca62e2c2SSteve Yin
576*ca62e2c2SSteve Yin // get current tab stop information stored in the Frm
577*ca62e2c2SSteve Yin const SvxTabStop *pTS = aLine.GetLineInfo().GetTabStop( CurrentPos, nRight );
578*ca62e2c2SSteve Yin
579*ca62e2c2SSteve Yin if( !pTS )
580*ca62e2c2SSteve Yin {
581*ca62e2c2SSteve Yin return com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop >();
582*ca62e2c2SSteve Yin }
583*ca62e2c2SSteve Yin
584*ca62e2c2SSteve Yin // copy tab stop information into a Sequence, which only contains one element.
585*ca62e2c2SSteve Yin ts.Position = pTS->GetTabPos();
586*ca62e2c2SSteve Yin ts.DecimalChar = pTS->GetDecimal();
587*ca62e2c2SSteve Yin ts.FillChar = pTS->GetFill();
588*ca62e2c2SSteve Yin switch( pTS->GetAdjustment() )
589*ca62e2c2SSteve Yin {
590*ca62e2c2SSteve Yin case SVX_TAB_ADJUST_LEFT : ts.Alignment = ::com::sun::star::style::TabAlign_LEFT; break;
591*ca62e2c2SSteve Yin case SVX_TAB_ADJUST_CENTER : ts.Alignment = ::com::sun::star::style::TabAlign_CENTER; break;
592*ca62e2c2SSteve Yin case SVX_TAB_ADJUST_RIGHT : ts.Alignment = ::com::sun::star::style::TabAlign_RIGHT; break;
593*ca62e2c2SSteve Yin case SVX_TAB_ADJUST_DECIMAL: ts.Alignment = ::com::sun::star::style::TabAlign_DECIMAL; break;
594*ca62e2c2SSteve Yin case SVX_TAB_ADJUST_DEFAULT: ts.Alignment = ::com::sun::star::style::TabAlign_DEFAULT; break;
595*ca62e2c2SSteve Yin default: break; // prevent warning
596*ca62e2c2SSteve Yin }
597*ca62e2c2SSteve Yin
598*ca62e2c2SSteve Yin tabs[0] = ts;
599*ca62e2c2SSteve Yin return tabs;
600*ca62e2c2SSteve Yin }
601cdf0e10cSrcweir /*************************************************************************
602cdf0e10cSrcweir * SwTxtFrm::AdjustFollow()
603cdf0e10cSrcweir *************************************************************************/
604cdf0e10cSrcweir
605cdf0e10cSrcweir /* AdjustFollow erwartet folgende Situation:
606cdf0e10cSrcweir * Der SwTxtIter steht am unteren Ende des Masters, der Offset wird
607cdf0e10cSrcweir * im Follow eingestellt.
608cdf0e10cSrcweir * nOffset haelt den Offset im Textstring, ab dem der Master abschliesst
609cdf0e10cSrcweir * und der Follow beginnt. Wenn er 0 ist, wird der FolgeFrame geloescht.
610cdf0e10cSrcweir */
611cdf0e10cSrcweir
_AdjustFollow(SwTxtFormatter & rLine,const xub_StrLen nOffset,const xub_StrLen nEnd,const sal_uInt8 nMode)612cdf0e10cSrcweir void SwTxtFrm::_AdjustFollow( SwTxtFormatter &rLine,
613cdf0e10cSrcweir const xub_StrLen nOffset, const xub_StrLen nEnd,
614cdf0e10cSrcweir const sal_uInt8 nMode )
615cdf0e10cSrcweir {
616cdf0e10cSrcweir SwFrmSwapper aSwapper( this, sal_False );
617cdf0e10cSrcweir
618cdf0e10cSrcweir // Wir haben den Rest der Textmasse: alle Follows loeschen
619cdf0e10cSrcweir // Sonderfall sind DummyPortions()
620cdf0e10cSrcweir // - special cases are controlled by parameter <nMode>.
621cdf0e10cSrcweir if( HasFollow() && !(nMode & 1) && nOffset == nEnd )
622cdf0e10cSrcweir {
623cdf0e10cSrcweir while( GetFollow() )
624cdf0e10cSrcweir {
625cdf0e10cSrcweir if( ((SwTxtFrm*)GetFollow())->IsLocked() )
626cdf0e10cSrcweir {
627cdf0e10cSrcweir ASSERT( sal_False, "+SwTxtFrm::JoinFrm: Follow ist locked." );
628cdf0e10cSrcweir return;
629cdf0e10cSrcweir }
630cdf0e10cSrcweir JoinFrm();
631cdf0e10cSrcweir }
632cdf0e10cSrcweir
633cdf0e10cSrcweir return;
634cdf0e10cSrcweir }
635cdf0e10cSrcweir
636cdf0e10cSrcweir // Tanz auf dem Vulkan: Wir formatieren eben schnell noch einmal
637cdf0e10cSrcweir // die letzte Zeile fuer das QuoVadis-Geraffel. Selbstverstaendlich
638cdf0e10cSrcweir // kann sich dadurch auch der Offset verschieben:
639cdf0e10cSrcweir const xub_StrLen nNewOfst = ( IsInFtn() && ( !GetIndNext() || HasFollow() ) ) ?
640cdf0e10cSrcweir rLine.FormatQuoVadis(nOffset) : nOffset;
641cdf0e10cSrcweir
642cdf0e10cSrcweir if( !(nMode & 1) )
643cdf0e10cSrcweir {
644cdf0e10cSrcweir // Wir klauen unseren Follows Textmasse, dabei kann es passieren,
645cdf0e10cSrcweir // dass wir einige Follows Joinen muessen.
646cdf0e10cSrcweir while( GetFollow() && GetFollow()->GetFollow() &&
647cdf0e10cSrcweir nNewOfst >= GetFollow()->GetFollow()->GetOfst() )
648cdf0e10cSrcweir {
649cdf0e10cSrcweir DBG_LOOP;
650cdf0e10cSrcweir JoinFrm();
651cdf0e10cSrcweir }
652cdf0e10cSrcweir }
653cdf0e10cSrcweir
654cdf0e10cSrcweir // Der Ofst hat sich verschoben.
655cdf0e10cSrcweir if( GetFollow() )
656cdf0e10cSrcweir {
657cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
658cdf0e10cSrcweir static sal_Bool bTest = sal_False;
659cdf0e10cSrcweir if( !bTest || ( nMode & 1 ) )
660cdf0e10cSrcweir #endif
661cdf0e10cSrcweir if ( nMode )
662cdf0e10cSrcweir GetFollow()->ManipOfst( 0 );
663cdf0e10cSrcweir
664cdf0e10cSrcweir if ( CalcFollow( nNewOfst ) ) // CalcFollow erst zum Schluss, dort erfolgt ein SetOfst
665cdf0e10cSrcweir rLine.SetOnceMore( sal_True );
666cdf0e10cSrcweir }
667cdf0e10cSrcweir }
668cdf0e10cSrcweir
669cdf0e10cSrcweir /*************************************************************************
670cdf0e10cSrcweir * SwTxtFrm::JoinFrm()
671cdf0e10cSrcweir *************************************************************************/
672cdf0e10cSrcweir
JoinFrm()673cdf0e10cSrcweir SwCntntFrm *SwTxtFrm::JoinFrm()
674cdf0e10cSrcweir {
675cdf0e10cSrcweir ASSERT( GetFollow(), "+SwTxtFrm::JoinFrm: no follow" );
676cdf0e10cSrcweir SwTxtFrm *pFoll = GetFollow();
677cdf0e10cSrcweir
678cdf0e10cSrcweir SwTxtFrm *pNxt = pFoll->GetFollow();
679cdf0e10cSrcweir
680cdf0e10cSrcweir // Alle Fussnoten des zu zerstoerenden Follows werden auf uns
681cdf0e10cSrcweir // umgehaengt.
682cdf0e10cSrcweir xub_StrLen nStart = pFoll->GetOfst();
683cdf0e10cSrcweir if ( pFoll->HasFtn() )
684cdf0e10cSrcweir {
685cdf0e10cSrcweir const SwpHints *pHints = pFoll->GetTxtNode()->GetpSwpHints();
686cdf0e10cSrcweir if( pHints )
687cdf0e10cSrcweir {
688cdf0e10cSrcweir SwFtnBossFrm *pFtnBoss = 0;
689cdf0e10cSrcweir SwFtnBossFrm *pEndBoss = 0;
690cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < pHints->Count(); ++i )
691cdf0e10cSrcweir {
692cdf0e10cSrcweir const SwTxtAttr *pHt = (*pHints)[i];
693cdf0e10cSrcweir if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nStart )
694cdf0e10cSrcweir {
695cdf0e10cSrcweir if( pHt->GetFtn().IsEndNote() )
696cdf0e10cSrcweir {
697cdf0e10cSrcweir if( !pEndBoss )
698cdf0e10cSrcweir pEndBoss = pFoll->FindFtnBossFrm();
699cdf0e10cSrcweir pEndBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
700cdf0e10cSrcweir }
701cdf0e10cSrcweir else
702cdf0e10cSrcweir {
703cdf0e10cSrcweir if( !pFtnBoss )
704cdf0e10cSrcweir pFtnBoss = pFoll->FindFtnBossFrm( sal_True );
705cdf0e10cSrcweir pFtnBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
706cdf0e10cSrcweir }
707cdf0e10cSrcweir SetFtn( sal_True );
708cdf0e10cSrcweir }
709cdf0e10cSrcweir }
710cdf0e10cSrcweir }
711cdf0e10cSrcweir }
712cdf0e10cSrcweir
713cdf0e10cSrcweir #ifdef DBG_UTIL
714cdf0e10cSrcweir else if ( pFoll->GetValidPrtAreaFlag() ||
715cdf0e10cSrcweir pFoll->GetValidSizeFlag() )
716cdf0e10cSrcweir {
717cdf0e10cSrcweir pFoll->CalcFtnFlag();
718cdf0e10cSrcweir ASSERT( !pFoll->HasFtn(), "Missing FtnFlag." );
719cdf0e10cSrcweir }
720cdf0e10cSrcweir #endif
721cdf0e10cSrcweir
722cdf0e10cSrcweir pFoll->MoveFlyInCnt( this, nStart, STRING_LEN );
723cdf0e10cSrcweir pFoll->SetFtn( sal_False );
724cdf0e10cSrcweir // --> OD 2005-12-01 #i27138#
725cdf0e10cSrcweir // notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
726cdf0e10cSrcweir // Relation CONTENT_FLOWS_FROM for current next paragraph will change
727cdf0e10cSrcweir // and relation CONTENT_FLOWS_TO for current previous paragraph, which
728cdf0e10cSrcweir // is <this>, will change.
729cdf0e10cSrcweir {
730cdf0e10cSrcweir ViewShell* pViewShell( pFoll->getRootFrm()->GetCurrShell() );
731cdf0e10cSrcweir if ( pViewShell && pViewShell->GetLayout() &&
732cdf0e10cSrcweir pViewShell->GetLayout()->IsAnyShellAccessible() )
733cdf0e10cSrcweir {
734cdf0e10cSrcweir pViewShell->InvalidateAccessibleParaFlowRelation(
735cdf0e10cSrcweir dynamic_cast<SwTxtFrm*>(pFoll->FindNextCnt( true )),
736cdf0e10cSrcweir this );
737cdf0e10cSrcweir }
738cdf0e10cSrcweir }
739cdf0e10cSrcweir // <--
740cdf0e10cSrcweir pFoll->Cut();
741cdf0e10cSrcweir delete pFoll;
742cdf0e10cSrcweir pFollow = pNxt;
743cdf0e10cSrcweir return pNxt;
744cdf0e10cSrcweir }
745cdf0e10cSrcweir
746cdf0e10cSrcweir /*************************************************************************
747cdf0e10cSrcweir * SwTxtFrm::SplitFrm()
748cdf0e10cSrcweir *************************************************************************/
749cdf0e10cSrcweir
SplitFrm(const xub_StrLen nTxtPos)750cdf0e10cSrcweir SwCntntFrm *SwTxtFrm::SplitFrm( const xub_StrLen nTxtPos )
751cdf0e10cSrcweir {
752cdf0e10cSrcweir SWAP_IF_SWAPPED( this )
753cdf0e10cSrcweir
754cdf0e10cSrcweir // Durch das Paste wird ein Modify() an mich verschickt.
755cdf0e10cSrcweir // Damit meine Daten nicht verschwinden, locke ich mich.
756cdf0e10cSrcweir SwTxtFrmLocker aLock( this );
757cdf0e10cSrcweir SwTxtFrm *pNew = (SwTxtFrm *)(GetTxtNode()->MakeFrm( this ));
758cdf0e10cSrcweir pNew->bIsFollow = sal_True;
759cdf0e10cSrcweir
760cdf0e10cSrcweir pNew->SetFollow( GetFollow() );
761cdf0e10cSrcweir SetFollow( pNew );
762cdf0e10cSrcweir
763cdf0e10cSrcweir pNew->Paste( GetUpper(), GetNext() );
764cdf0e10cSrcweir // --> OD 2005-12-01 #i27138#
765cdf0e10cSrcweir // notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
766cdf0e10cSrcweir // Relation CONTENT_FLOWS_FROM for current next paragraph will change
767cdf0e10cSrcweir // and relation CONTENT_FLOWS_TO for current previous paragraph, which
768cdf0e10cSrcweir // is <this>, will change.
769cdf0e10cSrcweir {
770cdf0e10cSrcweir ViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() );
771cdf0e10cSrcweir if ( pViewShell && pViewShell->GetLayout() &&
772cdf0e10cSrcweir pViewShell->GetLayout()->IsAnyShellAccessible() )
773cdf0e10cSrcweir {
774cdf0e10cSrcweir pViewShell->InvalidateAccessibleParaFlowRelation(
775cdf0e10cSrcweir dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
776cdf0e10cSrcweir this );
777cdf0e10cSrcweir }
778cdf0e10cSrcweir }
779cdf0e10cSrcweir // <--
780cdf0e10cSrcweir
781cdf0e10cSrcweir // Wenn durch unsere Aktionen Fussnoten in pNew landen,
782cdf0e10cSrcweir // so muessen sie umgemeldet werden.
783cdf0e10cSrcweir if ( HasFtn() )
784cdf0e10cSrcweir {
785cdf0e10cSrcweir const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
786cdf0e10cSrcweir if( pHints )
787cdf0e10cSrcweir {
788cdf0e10cSrcweir SwFtnBossFrm *pFtnBoss = 0;
789cdf0e10cSrcweir SwFtnBossFrm *pEndBoss = 0;
790cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < pHints->Count(); ++i )
791cdf0e10cSrcweir {
792cdf0e10cSrcweir const SwTxtAttr *pHt = (*pHints)[i];
793cdf0e10cSrcweir if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nTxtPos )
794cdf0e10cSrcweir {
795cdf0e10cSrcweir if( pHt->GetFtn().IsEndNote() )
796cdf0e10cSrcweir {
797cdf0e10cSrcweir if( !pEndBoss )
798cdf0e10cSrcweir pEndBoss = FindFtnBossFrm();
799cdf0e10cSrcweir pEndBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
800cdf0e10cSrcweir }
801cdf0e10cSrcweir else
802cdf0e10cSrcweir {
803cdf0e10cSrcweir if( !pFtnBoss )
804cdf0e10cSrcweir pFtnBoss = FindFtnBossFrm( sal_True );
805cdf0e10cSrcweir pFtnBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
806cdf0e10cSrcweir }
807cdf0e10cSrcweir pNew->SetFtn( sal_True );
808cdf0e10cSrcweir }
809cdf0e10cSrcweir }
810cdf0e10cSrcweir }
811cdf0e10cSrcweir }
812cdf0e10cSrcweir
813cdf0e10cSrcweir #ifdef DBG_UTIL
814cdf0e10cSrcweir else
815cdf0e10cSrcweir {
816cdf0e10cSrcweir CalcFtnFlag( nTxtPos-1 );
817cdf0e10cSrcweir ASSERT( !HasFtn(), "Missing FtnFlag." );
818cdf0e10cSrcweir }
819cdf0e10cSrcweir #endif
820cdf0e10cSrcweir
821cdf0e10cSrcweir MoveFlyInCnt( pNew, nTxtPos, STRING_LEN );
822cdf0e10cSrcweir
823cdf0e10cSrcweir // Kein SetOfst oder CalcFollow, weil gleich ohnehin ein AdjustFollow folgt.
824cdf0e10cSrcweir
825cdf0e10cSrcweir pNew->ManipOfst( nTxtPos );
826cdf0e10cSrcweir
827cdf0e10cSrcweir UNDO_SWAP( this )
828cdf0e10cSrcweir return pNew;
829cdf0e10cSrcweir }
830cdf0e10cSrcweir
831cdf0e10cSrcweir
832cdf0e10cSrcweir /*************************************************************************
833cdf0e10cSrcweir * virtual SwTxtFrm::SetOfst()
834cdf0e10cSrcweir *************************************************************************/
835cdf0e10cSrcweir
_SetOfst(const xub_StrLen nNewOfst)836cdf0e10cSrcweir void SwTxtFrm::_SetOfst( const xub_StrLen nNewOfst )
837cdf0e10cSrcweir {
838cdf0e10cSrcweir #ifdef DBGTXT
839cdf0e10cSrcweir // Es gibt tatsaechlich einen Sonderfall, in dem ein SetOfst(0)
840cdf0e10cSrcweir // zulaessig ist: bug 3496
841cdf0e10cSrcweir ASSERT( nNewOfst, "!SwTxtFrm::SetOfst: missing JoinFrm()." );
842cdf0e10cSrcweir #endif
843cdf0e10cSrcweir
844cdf0e10cSrcweir // Die Invalidierung unseres Follows ist nicht noetig.
845cdf0e10cSrcweir // Wir sind ein Follow, werden gleich formatiert und
846cdf0e10cSrcweir // rufen von dort aus das SetOfst() !
847cdf0e10cSrcweir nOfst = nNewOfst;
848cdf0e10cSrcweir SwParaPortion *pPara = GetPara();
849cdf0e10cSrcweir if( pPara )
850cdf0e10cSrcweir {
851cdf0e10cSrcweir SwCharRange &rReformat = *(pPara->GetReformat());
852cdf0e10cSrcweir rReformat.Start() = 0;
853cdf0e10cSrcweir rReformat.Len() = GetTxt().Len();
854cdf0e10cSrcweir *(pPara->GetDelta()) = rReformat.Len();
855cdf0e10cSrcweir }
856cdf0e10cSrcweir InvalidateSize();
857cdf0e10cSrcweir }
858cdf0e10cSrcweir
859cdf0e10cSrcweir /*************************************************************************
860cdf0e10cSrcweir * SwTxtFrm::CalcPreps
861cdf0e10cSrcweir *************************************************************************/
862cdf0e10cSrcweir
CalcPreps()863cdf0e10cSrcweir sal_Bool SwTxtFrm::CalcPreps()
864cdf0e10cSrcweir {
865cdf0e10cSrcweir ASSERT( ! IsVertical() || ! IsSwapped(), "SwTxtFrm::CalcPreps with swapped frame" );
866cdf0e10cSrcweir SWRECTFN( this );
867cdf0e10cSrcweir
868cdf0e10cSrcweir SwParaPortion *pPara = GetPara();
869cdf0e10cSrcweir if ( !pPara )
870cdf0e10cSrcweir return sal_False;
871cdf0e10cSrcweir sal_Bool bPrep = pPara->IsPrep();
872cdf0e10cSrcweir sal_Bool bPrepWidows = pPara->IsPrepWidows();
873cdf0e10cSrcweir sal_Bool bPrepAdjust = pPara->IsPrepAdjust();
874cdf0e10cSrcweir sal_Bool bPrepMustFit = pPara->IsPrepMustFit();
875cdf0e10cSrcweir ResetPreps();
876cdf0e10cSrcweir
877cdf0e10cSrcweir sal_Bool bRet = sal_False;
878cdf0e10cSrcweir if( bPrep && !pPara->GetReformat()->Len() )
879cdf0e10cSrcweir {
880cdf0e10cSrcweir // PREP_WIDOWS bedeutet, dass im Follow die Orphans-Regel
881cdf0e10cSrcweir // zuschlug.
882cdf0e10cSrcweir // Es kann in unguenstigen Faellen vorkommen, dass auch ein
883cdf0e10cSrcweir // PrepAdjust vorliegt (3680)!
884cdf0e10cSrcweir if( bPrepWidows )
885cdf0e10cSrcweir {
886cdf0e10cSrcweir if( !GetFollow() )
887cdf0e10cSrcweir {
888cdf0e10cSrcweir ASSERT( GetFollow(), "+SwTxtFrm::CalcPreps: no credits" );
889cdf0e10cSrcweir return sal_False;
890cdf0e10cSrcweir }
891cdf0e10cSrcweir
892cdf0e10cSrcweir // Wir muessen uns auf zwei Faelle einstellen:
893cdf0e10cSrcweir // Wir konnten dem Follow noch ein paar Zeilen abgeben,
894cdf0e10cSrcweir // -> dann muessen wir schrumpfen
895cdf0e10cSrcweir // oder wir muessen auf die naechste Seite
896cdf0e10cSrcweir // -> dann lassen wir unseren Frame zu gross werden.
897cdf0e10cSrcweir
898cdf0e10cSrcweir SwTwips nChgHeight = GetParHeight();
899cdf0e10cSrcweir if( nChgHeight >= (Prt().*fnRect->fnGetHeight)() )
900cdf0e10cSrcweir {
901cdf0e10cSrcweir if( bPrepMustFit )
902cdf0e10cSrcweir {
903cdf0e10cSrcweir GetFollow()->SetJustWidow( sal_True );
904cdf0e10cSrcweir GetFollow()->Prepare( PREP_CLEAR );
905cdf0e10cSrcweir }
906cdf0e10cSrcweir else if ( bVert )
907cdf0e10cSrcweir {
908cdf0e10cSrcweir Frm().Width( Frm().Width() + Frm().Left() );
909cdf0e10cSrcweir Prt().Width( Prt().Width() + Frm().Left() );
910cdf0e10cSrcweir Frm().Left( 0 );
911cdf0e10cSrcweir SetWidow( sal_True );
912cdf0e10cSrcweir }
913cdf0e10cSrcweir else
914cdf0e10cSrcweir {
915cdf0e10cSrcweir SwTwips nTmp = LONG_MAX - (Frm().Top()+10000);
916cdf0e10cSrcweir SwTwips nDiff = nTmp - Frm().Height();
917cdf0e10cSrcweir Frm().Height( nTmp );
918cdf0e10cSrcweir Prt().Height( Prt().Height() + nDiff );
919cdf0e10cSrcweir SetWidow( sal_True );
920cdf0e10cSrcweir }
921cdf0e10cSrcweir }
922cdf0e10cSrcweir else
923cdf0e10cSrcweir {
924cdf0e10cSrcweir ASSERT( nChgHeight < (Prt().*fnRect->fnGetHeight)(),
925cdf0e10cSrcweir "+SwTxtFrm::CalcPrep: wanna shrink" );
926cdf0e10cSrcweir
927cdf0e10cSrcweir nChgHeight = (Prt().*fnRect->fnGetHeight)() - nChgHeight;
928cdf0e10cSrcweir
929cdf0e10cSrcweir GetFollow()->SetJustWidow( sal_True );
930cdf0e10cSrcweir GetFollow()->Prepare( PREP_CLEAR );
931cdf0e10cSrcweir Shrink( nChgHeight );
932cdf0e10cSrcweir SwRect &rRepaint = *(pPara->GetRepaint());
933cdf0e10cSrcweir
934cdf0e10cSrcweir if ( bVert )
935cdf0e10cSrcweir {
936cdf0e10cSrcweir SwRect aRepaint( Frm().Pos() + Prt().Pos(), Prt().SSize() );
937cdf0e10cSrcweir SwitchVerticalToHorizontal( aRepaint );
938cdf0e10cSrcweir rRepaint.Chg( aRepaint.Pos(), aRepaint.SSize() );
939cdf0e10cSrcweir }
940cdf0e10cSrcweir else
941cdf0e10cSrcweir rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
942cdf0e10cSrcweir
943cdf0e10cSrcweir // 6792: Rrand < LRand und Repaint
944cdf0e10cSrcweir if( 0 >= rRepaint.Width() )
945cdf0e10cSrcweir rRepaint.Width(1);
946cdf0e10cSrcweir }
947cdf0e10cSrcweir bRet = sal_True;
948cdf0e10cSrcweir }
949cdf0e10cSrcweir
950cdf0e10cSrcweir else if ( bPrepAdjust )
951cdf0e10cSrcweir {
952cdf0e10cSrcweir if ( HasFtn() )
953cdf0e10cSrcweir {
954cdf0e10cSrcweir if( !CalcPrepFtnAdjust() )
955cdf0e10cSrcweir {
956cdf0e10cSrcweir if( bPrepMustFit )
957cdf0e10cSrcweir {
958cdf0e10cSrcweir SwTxtLineAccess aAccess( this );
959cdf0e10cSrcweir aAccess.GetPara()->SetPrepMustFit( sal_True );
960cdf0e10cSrcweir }
961cdf0e10cSrcweir return sal_False;
962cdf0e10cSrcweir }
963cdf0e10cSrcweir }
964cdf0e10cSrcweir
965cdf0e10cSrcweir SWAP_IF_NOT_SWAPPED( this )
966cdf0e10cSrcweir
967cdf0e10cSrcweir SwTxtFormatInfo aInf( this );
968cdf0e10cSrcweir SwTxtFormatter aLine( this, &aInf );
969cdf0e10cSrcweir
970cdf0e10cSrcweir WidowsAndOrphans aFrmBreak( this );
971cdf0e10cSrcweir // Egal was die Attribute meinen, bei MustFit wird
972cdf0e10cSrcweir // der Absatz im Notfall trotzdem gesplittet...
973cdf0e10cSrcweir if( bPrepMustFit )
974cdf0e10cSrcweir {
975cdf0e10cSrcweir aFrmBreak.SetKeep( sal_False );
976cdf0e10cSrcweir aFrmBreak.ClrOrphLines();
977cdf0e10cSrcweir }
978cdf0e10cSrcweir // Bevor wir FormatAdjust aufrufen muessen wir dafuer
979cdf0e10cSrcweir // sorgen, dass die Zeilen, die unten raushaengen
980cdf0e10cSrcweir // auch tatsaechlich abgeschnitten werden.
981cdf0e10cSrcweir // OD 2004-02-25 #i16128# - method renamed
982cdf0e10cSrcweir sal_Bool bBreak = aFrmBreak.IsBreakNowWidAndOrp( aLine );
983cdf0e10cSrcweir bRet = sal_True;
984cdf0e10cSrcweir while( !bBreak && aLine.Next() )
985cdf0e10cSrcweir {
986cdf0e10cSrcweir // OD 2004-02-25 #i16128# - method renamed
987cdf0e10cSrcweir bBreak = aFrmBreak.IsBreakNowWidAndOrp( aLine );
988cdf0e10cSrcweir }
989cdf0e10cSrcweir if( bBreak )
990cdf0e10cSrcweir {
991cdf0e10cSrcweir // Es gibt Komplikationen: wenn TruncLines gerufen wird,
992cdf0e10cSrcweir // veraendern sich ploetzlich die Bedingungen in
993cdf0e10cSrcweir // IsInside, so dass IsBreakNow andere Ergebnisse
994cdf0e10cSrcweir // liefern kann. Aus diesem Grund wird rFrmBreak bekannt
995cdf0e10cSrcweir // gegeben, dass da wo rLine steht, das Ende erreicht
996cdf0e10cSrcweir // ist. Mal sehen, ob's klappt ...
997cdf0e10cSrcweir aLine.TruncLines();
998cdf0e10cSrcweir aFrmBreak.SetRstHeight( aLine );
999cdf0e10cSrcweir FormatAdjust( aLine, aFrmBreak, aInf.GetTxt().Len(), aInf.IsStop() );
1000cdf0e10cSrcweir }
1001cdf0e10cSrcweir else
1002cdf0e10cSrcweir {
1003cdf0e10cSrcweir if( !GetFollow() )
1004cdf0e10cSrcweir {
1005cdf0e10cSrcweir FormatAdjust( aLine, aFrmBreak,
1006cdf0e10cSrcweir aInf.GetTxt().Len(), aInf.IsStop() );
1007cdf0e10cSrcweir }
1008cdf0e10cSrcweir else if ( !aFrmBreak.IsKeepAlways() )
1009cdf0e10cSrcweir {
1010cdf0e10cSrcweir // Siehe Bug: 2320
1011cdf0e10cSrcweir // Vor dem Master wird eine Zeile geloescht, der Follow
1012cdf0e10cSrcweir // koennte eine Zeile abgeben.
1013cdf0e10cSrcweir const SwCharRange aFollowRg( GetFollow()->GetOfst(), 1 );
1014cdf0e10cSrcweir *(pPara->GetReformat()) += aFollowRg;
1015cdf0e10cSrcweir // Es soll weitergehen!
1016cdf0e10cSrcweir bRet = sal_False;
1017cdf0e10cSrcweir }
1018cdf0e10cSrcweir }
1019cdf0e10cSrcweir
1020cdf0e10cSrcweir UNDO_SWAP( this )
1021cdf0e10cSrcweir // Eine letzte Ueberpruefung, falls das FormatAdjust() nichts
1022cdf0e10cSrcweir // brachte, muessen wir amputieren.
1023cdf0e10cSrcweir if( bPrepMustFit )
1024cdf0e10cSrcweir {
1025cdf0e10cSrcweir const SwTwips nMust = (GetUpper()->*fnRect->fnGetPrtBottom)();
1026cdf0e10cSrcweir const SwTwips nIs = (Frm().*fnRect->fnGetBottom)();
1027cdf0e10cSrcweir
1028cdf0e10cSrcweir if( bVert && nIs < nMust )
1029cdf0e10cSrcweir {
1030cdf0e10cSrcweir Shrink( nMust - nIs );
1031cdf0e10cSrcweir if( Prt().Width() < 0 )
1032cdf0e10cSrcweir Prt().Width( 0 );
1033cdf0e10cSrcweir SetUndersized( sal_True );
1034cdf0e10cSrcweir }
1035cdf0e10cSrcweir else if ( ! bVert && nIs > nMust )
1036cdf0e10cSrcweir {
1037cdf0e10cSrcweir Shrink( nIs - nMust );
1038cdf0e10cSrcweir if( Prt().Height() < 0 )
1039cdf0e10cSrcweir Prt().Height( 0 );
1040cdf0e10cSrcweir SetUndersized( sal_True );
1041cdf0e10cSrcweir }
1042cdf0e10cSrcweir }
1043cdf0e10cSrcweir }
1044cdf0e10cSrcweir }
1045cdf0e10cSrcweir pPara->SetPrepMustFit( bPrepMustFit );
1046cdf0e10cSrcweir return bRet;
1047cdf0e10cSrcweir }
1048cdf0e10cSrcweir
1049cdf0e10cSrcweir
1050cdf0e10cSrcweir /*************************************************************************
1051cdf0e10cSrcweir * SwTxtFrm::FormatAdjust()
1052cdf0e10cSrcweir *************************************************************************/
1053cdf0e10cSrcweir
1054cdf0e10cSrcweir // Hier werden die Fussnoten und "als Zeichen"-gebundenen Objekte umgehaengt
1055cdf0e10cSrcweir #define CHG_OFFSET( pFrm, nNew )\
1056cdf0e10cSrcweir {\
1057cdf0e10cSrcweir if( pFrm->GetOfst() < nNew )\
1058cdf0e10cSrcweir pFrm->MoveFlyInCnt( this, 0, nNew );\
1059cdf0e10cSrcweir else if( pFrm->GetOfst() > nNew )\
1060cdf0e10cSrcweir MoveFlyInCnt( pFrm, nNew, STRING_LEN );\
1061cdf0e10cSrcweir }
1062cdf0e10cSrcweir
FormatAdjust(SwTxtFormatter & rLine,WidowsAndOrphans & rFrmBreak,const xub_StrLen nStrLen,const sal_Bool bDummy)1063cdf0e10cSrcweir void SwTxtFrm::FormatAdjust( SwTxtFormatter &rLine,
1064cdf0e10cSrcweir WidowsAndOrphans &rFrmBreak,
1065cdf0e10cSrcweir const xub_StrLen nStrLen,
1066cdf0e10cSrcweir const sal_Bool bDummy )
1067cdf0e10cSrcweir {
1068cdf0e10cSrcweir SWAP_IF_NOT_SWAPPED( this )
1069cdf0e10cSrcweir
1070cdf0e10cSrcweir SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1071cdf0e10cSrcweir
1072cdf0e10cSrcweir xub_StrLen nEnd = rLine.GetStart();
1073cdf0e10cSrcweir
1074cdf0e10cSrcweir sal_Bool bHasToFit = pPara->IsPrepMustFit();
1075cdf0e10cSrcweir
1076cdf0e10cSrcweir // Das StopFlag wird durch Fussnoten gesetzt,
1077cdf0e10cSrcweir // die auf die naechste Seite wollen.
1078cdf0e10cSrcweir // OD, FME 2004-03-03 - call base class method <SwTxtFrmBreak::IsBreakNow(..)>
1079cdf0e10cSrcweir // instead of method <WidowsAndOrphans::IsBreakNow(..)> to get a break,
1080cdf0e10cSrcweir // even if due to widow rule no enough lines exists.
1081cdf0e10cSrcweir sal_uInt8 nNew = ( !GetFollow() &&
1082cdf0e10cSrcweir nEnd < nStrLen &&
1083cdf0e10cSrcweir ( rLine.IsStop() ||
1084cdf0e10cSrcweir ( bHasToFit
1085cdf0e10cSrcweir ? ( rLine.GetLineNr() > 1 &&
1086cdf0e10cSrcweir !rFrmBreak.IsInside( rLine ) )
1087cdf0e10cSrcweir : rFrmBreak.IsBreakNow( rLine ) ) ) )
1088cdf0e10cSrcweir ? 1 : 0;
1089cdf0e10cSrcweir // --> OD #i84870#
1090cdf0e10cSrcweir // no split of text frame, which only contains a as-character anchored object
1091cdf0e10cSrcweir const bool bOnlyContainsAsCharAnchoredObj =
1092cdf0e10cSrcweir !IsFollow() && nStrLen == 1 &&
1093cdf0e10cSrcweir GetDrawObjs() && GetDrawObjs()->Count() == 1 &&
1094cdf0e10cSrcweir (*GetDrawObjs())[0]->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR;
1095cdf0e10cSrcweir if ( nNew && bOnlyContainsAsCharAnchoredObj )
1096cdf0e10cSrcweir {
1097cdf0e10cSrcweir nNew = 0;
1098cdf0e10cSrcweir }
1099cdf0e10cSrcweir // <--
1100cdf0e10cSrcweir if ( nNew )
1101cdf0e10cSrcweir {
1102cdf0e10cSrcweir SplitFrm( nEnd );
1103cdf0e10cSrcweir }
1104cdf0e10cSrcweir
1105cdf0e10cSrcweir const SwFrm *pBodyFrm = (const SwFrm*)(FindBodyFrm());
1106cdf0e10cSrcweir
1107cdf0e10cSrcweir const long nBodyHeight = pBodyFrm ? ( IsVertical() ?
1108cdf0e10cSrcweir pBodyFrm->Frm().Width() :
1109cdf0e10cSrcweir pBodyFrm->Frm().Height() ) : 0;
1110cdf0e10cSrcweir
1111cdf0e10cSrcweir // Wenn die aktuellen Werte berechnet wurden, anzeigen, dass
1112cdf0e10cSrcweir // sie jetzt gueltig sind.
1113cdf0e10cSrcweir *(pPara->GetReformat()) = SwCharRange();
1114cdf0e10cSrcweir sal_Bool bDelta = *pPara->GetDelta() != 0;
1115cdf0e10cSrcweir *(pPara->GetDelta()) = 0;
1116cdf0e10cSrcweir
1117cdf0e10cSrcweir if( rLine.IsStop() )
1118cdf0e10cSrcweir {
1119cdf0e10cSrcweir rLine.TruncLines( sal_True );
1120cdf0e10cSrcweir nNew = 1;
1121cdf0e10cSrcweir }
1122cdf0e10cSrcweir
1123cdf0e10cSrcweir // FindBreak schneidet die letzte Zeile ab.
1124cdf0e10cSrcweir if( !rFrmBreak.FindBreak( this, rLine, bHasToFit ) )
1125cdf0e10cSrcweir {
1126cdf0e10cSrcweir // Wenn wir bis zum Ende durchformatiert haben, wird nEnd auf das Ende
1127cdf0e10cSrcweir // gesetzt. In AdjustFollow wird dadurch ggf. JoinFrm() ausgefuehrt.
1128cdf0e10cSrcweir // Ansonsten ist nEnd das Ende der letzten Zeile im Master.
1129cdf0e10cSrcweir xub_StrLen nOld = nEnd;
1130cdf0e10cSrcweir nEnd = rLine.GetEnd();
1131cdf0e10cSrcweir if( GetFollow() )
1132cdf0e10cSrcweir {
1133cdf0e10cSrcweir if( nNew && nOld < nEnd )
1134cdf0e10cSrcweir RemoveFtn( nOld, nEnd - nOld );
1135cdf0e10cSrcweir CHG_OFFSET( GetFollow(), nEnd )
1136cdf0e10cSrcweir if( !bDelta )
1137cdf0e10cSrcweir GetFollow()->ManipOfst( nEnd );
1138cdf0e10cSrcweir }
1139cdf0e10cSrcweir }
1140cdf0e10cSrcweir else
1141cdf0e10cSrcweir { // Wenn wir Zeilen abgeben, darf kein Join auf den Folows gerufen werden,
1142cdf0e10cSrcweir // im Gegenteil, es muss ggf. sogar ein Follow erzeugt werden.
1143cdf0e10cSrcweir // Dies muss auch geschehen, wenn die Textmasse komplett im Master
1144cdf0e10cSrcweir // bleibt, denn es k???nnte ja ein harter Zeilenumbruch noch eine weitere
1145cdf0e10cSrcweir // Zeile (ohne Textmassse) notwendig machen!
1146cdf0e10cSrcweir nEnd = rLine.GetEnd();
1147cdf0e10cSrcweir if( GetFollow() )
1148cdf0e10cSrcweir {
1149cdf0e10cSrcweir // OD 21.03.2003 #108121# - Another case for not joining the follow:
1150cdf0e10cSrcweir // Text frame has no content, but a numbering. Then, do *not* join.
1151cdf0e10cSrcweir // Example of this case: When an empty, but numbered paragraph
1152cdf0e10cSrcweir // at the end of page is completely displaced by a fly frame.
1153cdf0e10cSrcweir // Thus, the text frame introduced a follow by a
1154cdf0e10cSrcweir // <SwTxtFrm::SplitFrm(..)> - see below. The follow then shows
1155cdf0e10cSrcweir // the numbering and must stay.
1156cdf0e10cSrcweir if ( GetFollow()->GetOfst() != nEnd ||
1157cdf0e10cSrcweir GetFollow()->IsFieldFollow() ||
1158cdf0e10cSrcweir ( nStrLen == 0 && GetTxtNode()->GetNumRule() ) )
1159cdf0e10cSrcweir {
1160cdf0e10cSrcweir nNew |= 3;
1161cdf0e10cSrcweir }
1162cdf0e10cSrcweir CHG_OFFSET( GetFollow(), nEnd )
1163cdf0e10cSrcweir GetFollow()->ManipOfst( nEnd );
1164cdf0e10cSrcweir }
1165cdf0e10cSrcweir else
1166cdf0e10cSrcweir {
1167cdf0e10cSrcweir // OD 21.03.2003 #108121# - Only split frame, if the frame contains
1168cdf0e10cSrcweir // content or contains no content, but has a numbering.
1169cdf0e10cSrcweir // OD #i84870# - no split, if text frame only contains one
1170cdf0e10cSrcweir // as-character anchored object.
1171cdf0e10cSrcweir if ( !bOnlyContainsAsCharAnchoredObj &&
1172cdf0e10cSrcweir ( nStrLen > 0 ||
1173cdf0e10cSrcweir ( nStrLen == 0 && GetTxtNode()->GetNumRule() ) )
1174cdf0e10cSrcweir )
1175cdf0e10cSrcweir {
1176cdf0e10cSrcweir SplitFrm( nEnd );
1177cdf0e10cSrcweir nNew |= 3;
1178cdf0e10cSrcweir }
1179cdf0e10cSrcweir }
1180cdf0e10cSrcweir // Wenn sich die Resthoehe geaendert hat, z.B. durch RemoveFtn()
1181cdf0e10cSrcweir // dann muessen wir auffuellen, um Oszillationen zu vermeiden!
1182cdf0e10cSrcweir if( bDummy && pBodyFrm &&
1183cdf0e10cSrcweir nBodyHeight < ( IsVertical() ?
1184cdf0e10cSrcweir pBodyFrm->Frm().Width() :
1185cdf0e10cSrcweir pBodyFrm->Frm().Height() ) )
1186cdf0e10cSrcweir rLine.MakeDummyLine();
1187cdf0e10cSrcweir }
1188cdf0e10cSrcweir
1189cdf0e10cSrcweir // In AdjustFrm() stellen wir uns selbst per Grow/Shrink ein,
1190cdf0e10cSrcweir // in AdjustFollow() stellen wir unseren FolgeFrame ein.
1191cdf0e10cSrcweir
1192cdf0e10cSrcweir const SwTwips nDocPrtTop = Frm().Top() + Prt().Top();
1193cdf0e10cSrcweir const SwTwips nOldHeight = Prt().SSize().Height();
1194cdf0e10cSrcweir SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight;
1195cdf0e10cSrcweir // --> OD #i84870# - no shrink of text frame, if it only contains one
1196cdf0e10cSrcweir // as-character anchored object.
1197cdf0e10cSrcweir if ( nChg < 0 &&
1198cdf0e10cSrcweir bOnlyContainsAsCharAnchoredObj )
1199cdf0e10cSrcweir {
1200cdf0e10cSrcweir nChg = 0;
1201cdf0e10cSrcweir }
1202cdf0e10cSrcweir // <--
1203cdf0e10cSrcweir
1204cdf0e10cSrcweir // Vertical Formatting:
1205cdf0e10cSrcweir // The (rotated) repaint rectangle's x coordinate referes to the frame.
1206cdf0e10cSrcweir // If the frame grows (or shirks) the repaint rectangle cannot simply
1207cdf0e10cSrcweir // be rotated back after formatting, because we use the upper left point
1208cdf0e10cSrcweir // of the frame for rotation. This point changes when growing/shrinking.
1209cdf0e10cSrcweir
1210cdf0e10cSrcweir //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1211cdf0e10cSrcweir if ( IsVertical() && !IsVertLR() && nChg )
1212cdf0e10cSrcweir {
1213cdf0e10cSrcweir SwRect &rRepaint = *(pPara->GetRepaint());
1214cdf0e10cSrcweir rRepaint.Left( rRepaint.Left() - nChg );
1215cdf0e10cSrcweir rRepaint.Width( rRepaint.Width() - nChg );
1216cdf0e10cSrcweir }
1217cdf0e10cSrcweir
1218cdf0e10cSrcweir AdjustFrm( nChg, bHasToFit );
1219cdf0e10cSrcweir
1220cdf0e10cSrcweir /*
1221cdf0e10cSrcweir // FME 16.07.2003 #i16930# - removed this code because it did not
1222cdf0e10cSrcweir // work correctly. In SwCntntFrm::MakeAll, the frame did not move to the
1223cdf0e10cSrcweir // next page, instead the print area was recalculated and
1224cdf0e10cSrcweir // Prepare( PREP_POS_CHGD, (const void*)&bFormatted, sal_False ) invalidated
1225cdf0e10cSrcweir // the other flags => loop
1226cdf0e10cSrcweir
1227cdf0e10cSrcweir // OD 04.04.2003 #108446# - handle special case:
1228cdf0e10cSrcweir // If text frame contains no content and just has split, because of a
1229cdf0e10cSrcweir // line stop, it has to move forward. To force this forward move without
1230cdf0e10cSrcweir // unnecessary formatting of its footnotes and its follow, especially in
1231cdf0e10cSrcweir // columned sections, adjust frame height to zero (0) and do not perform
1232cdf0e10cSrcweir // the intrinsic format of the follow.
1233cdf0e10cSrcweir // The formating method <SwCntntFrm::MakeAll()> will initiate the move forward.
1234cdf0e10cSrcweir sal_Bool bForcedNoIntrinsicFollowCalc = sal_False;
1235cdf0e10cSrcweir if ( nEnd == 0 &&
1236cdf0e10cSrcweir rLine.IsStop() && HasFollow() && nNew == 1
1237cdf0e10cSrcweir )
1238cdf0e10cSrcweir {
1239cdf0e10cSrcweir AdjustFrm( -Frm().SSize().Height(), bHasToFit );
1240cdf0e10cSrcweir Prt().Pos().Y() = 0;
1241cdf0e10cSrcweir Prt().Height( Frm().Height() );
1242cdf0e10cSrcweir if ( FollowFormatAllowed() )
1243cdf0e10cSrcweir {
1244cdf0e10cSrcweir bForcedNoIntrinsicFollowCalc = sal_True;
1245cdf0e10cSrcweir ForbidFollowFormat();
1246cdf0e10cSrcweir }
1247cdf0e10cSrcweir }
1248cdf0e10cSrcweir else
1249cdf0e10cSrcweir {
1250cdf0e10cSrcweir AdjustFrm( nChg, bHasToFit );
1251cdf0e10cSrcweir }
1252cdf0e10cSrcweir */
1253cdf0e10cSrcweir
1254cdf0e10cSrcweir if( HasFollow() || IsInFtn() )
1255cdf0e10cSrcweir _AdjustFollow( rLine, nEnd, nStrLen, nNew );
1256cdf0e10cSrcweir
1257cdf0e10cSrcweir // FME 16.07.2003 #i16930# - removed this code because it did not work
1258cdf0e10cSrcweir // correctly
1259cdf0e10cSrcweir // OD 04.04.2003 #108446# - allow intrinsic format of follow, if above
1260cdf0e10cSrcweir // special case has forbit it.
1261cdf0e10cSrcweir /* if ( bForcedNoIntrinsicFollowCalc )
1262cdf0e10cSrcweir {
1263cdf0e10cSrcweir AllowFollowFormat();
1264cdf0e10cSrcweir }
1265cdf0e10cSrcweir */
1266cdf0e10cSrcweir
1267cdf0e10cSrcweir pPara->SetPrepMustFit( sal_False );
1268cdf0e10cSrcweir
1269cdf0e10cSrcweir UNDO_SWAP( this )
1270cdf0e10cSrcweir }
1271cdf0e10cSrcweir
1272cdf0e10cSrcweir /*************************************************************************
1273cdf0e10cSrcweir * SwTxtFrm::FormatLine()
1274cdf0e10cSrcweir *************************************************************************/
1275cdf0e10cSrcweir
1276cdf0e10cSrcweir // bPrev zeigt an, ob Reformat.Start() wegen Prev() vorgezogen wurde.
1277cdf0e10cSrcweir // Man weiss sonst nicht, ob man Repaint weiter einschraenken kann oder nicht.
1278cdf0e10cSrcweir
1279cdf0e10cSrcweir
FormatLine(SwTxtFormatter & rLine,const sal_Bool bPrev)1280cdf0e10cSrcweir sal_Bool SwTxtFrm::FormatLine( SwTxtFormatter &rLine, const sal_Bool bPrev )
1281cdf0e10cSrcweir {
1282cdf0e10cSrcweir ASSERT( ! IsVertical() || IsSwapped(),
1283cdf0e10cSrcweir "SwTxtFrm::FormatLine( rLine, bPrev) with unswapped frame" );
1284cdf0e10cSrcweir SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1285cdf0e10cSrcweir // Nach rLine.FormatLine() haelt nStart den neuen Wert,
1286cdf0e10cSrcweir // waehrend in pOldStart der alte Offset gepflegt wird.
1287cdf0e10cSrcweir // Ueber diesen Weg soll das nDelta ersetzt werden.
1288cdf0e10cSrcweir // *pOldStart += rLine.GetCurr()->GetLen();
1289cdf0e10cSrcweir const SwLineLayout *pOldCur = rLine.GetCurr();
1290cdf0e10cSrcweir const xub_StrLen nOldLen = pOldCur->GetLen();
1291cdf0e10cSrcweir const KSHORT nOldAscent = pOldCur->GetAscent();
1292cdf0e10cSrcweir const KSHORT nOldHeight = pOldCur->Height();
1293cdf0e10cSrcweir const SwTwips nOldWidth = pOldCur->Width() + pOldCur->GetHangingMargin();
1294cdf0e10cSrcweir const sal_Bool bOldHyph = pOldCur->IsEndHyph();
1295cdf0e10cSrcweir SwTwips nOldTop = 0;
1296cdf0e10cSrcweir SwTwips nOldBottom = 0;
1297cdf0e10cSrcweir if( rLine.GetCurr()->IsClipping() )
1298cdf0e10cSrcweir rLine.CalcUnclipped( nOldTop, nOldBottom );
1299cdf0e10cSrcweir
1300cdf0e10cSrcweir const xub_StrLen nNewStart = rLine.FormatLine( rLine.GetStart() );
1301cdf0e10cSrcweir
1302cdf0e10cSrcweir ASSERT( Frm().Pos().Y() + Prt().Pos().Y() == rLine.GetFirstPos(),
1303cdf0e10cSrcweir "SwTxtFrm::FormatLine: frame leaves orbit." );
1304cdf0e10cSrcweir ASSERT( rLine.GetCurr()->Height(),
1305cdf0e10cSrcweir "SwTxtFrm::FormatLine: line height is zero" );
1306cdf0e10cSrcweir
1307cdf0e10cSrcweir // Das aktuelle Zeilenumbruchobjekt.
1308cdf0e10cSrcweir const SwLineLayout *pNew = rLine.GetCurr();
1309cdf0e10cSrcweir
1310cdf0e10cSrcweir sal_Bool bUnChg = nOldLen == pNew->GetLen() &&
1311cdf0e10cSrcweir bOldHyph == pNew->IsEndHyph();
1312cdf0e10cSrcweir if ( bUnChg && !bPrev )
1313cdf0e10cSrcweir {
1314cdf0e10cSrcweir // 6672: Toleranz von SLOPPY_TWIPS (5 Twips); vgl. 6922
1315cdf0e10cSrcweir const long nWidthDiff = nOldWidth > pNew->Width()
1316cdf0e10cSrcweir ? nOldWidth - pNew->Width()
1317cdf0e10cSrcweir : pNew->Width() - nOldWidth;
1318cdf0e10cSrcweir
1319cdf0e10cSrcweir // we only declare a line as unchanged, if its main values have not
1320cdf0e10cSrcweir // changed and it is not the last line (!paragraph end symbol!)
1321cdf0e10cSrcweir bUnChg = nOldHeight == pNew->Height() &&
1322cdf0e10cSrcweir nOldAscent == pNew->GetAscent() &&
1323cdf0e10cSrcweir nWidthDiff <= SLOPPY_TWIPS &&
1324cdf0e10cSrcweir pOldCur->GetNext();
1325cdf0e10cSrcweir }
1326cdf0e10cSrcweir
1327cdf0e10cSrcweir // rRepaint wird berechnet:
1328cdf0e10cSrcweir const SwTwips nBottom = rLine.Y() + rLine.GetLineHeight();
1329cdf0e10cSrcweir SwRepaint &rRepaint = *(pPara->GetRepaint());
1330cdf0e10cSrcweir if( bUnChg && rRepaint.Top() == rLine.Y()
1331cdf0e10cSrcweir && (bPrev || nNewStart <= pPara->GetReformat()->Start())
1332cdf0e10cSrcweir && ( nNewStart < GetTxtNode()->GetTxt().Len() ) )
1333cdf0e10cSrcweir {
1334cdf0e10cSrcweir rRepaint.Top( nBottom );
1335cdf0e10cSrcweir rRepaint.Height( 0 );
1336cdf0e10cSrcweir }
1337cdf0e10cSrcweir else
1338cdf0e10cSrcweir {
1339cdf0e10cSrcweir if( nOldTop )
1340cdf0e10cSrcweir {
1341cdf0e10cSrcweir if( nOldTop < rRepaint.Top() )
1342cdf0e10cSrcweir rRepaint.Top( nOldTop );
1343cdf0e10cSrcweir if( !rLine.IsUnclipped() || nOldBottom > rRepaint.Bottom() )
1344cdf0e10cSrcweir {
1345cdf0e10cSrcweir rRepaint.Bottom( nOldBottom - 1 );
1346cdf0e10cSrcweir rLine.SetUnclipped( sal_True );
1347cdf0e10cSrcweir }
1348cdf0e10cSrcweir }
1349cdf0e10cSrcweir if( rLine.GetCurr()->IsClipping() && rLine.IsFlyInCntBase() )
1350cdf0e10cSrcweir {
1351cdf0e10cSrcweir SwTwips nTmpTop, nTmpBottom;
1352cdf0e10cSrcweir rLine.CalcUnclipped( nTmpTop, nTmpBottom );
1353cdf0e10cSrcweir if( nTmpTop < rRepaint.Top() )
1354cdf0e10cSrcweir rRepaint.Top( nTmpTop );
1355cdf0e10cSrcweir if( !rLine.IsUnclipped() || nTmpBottom > rRepaint.Bottom() )
1356cdf0e10cSrcweir {
1357cdf0e10cSrcweir rRepaint.Bottom( nTmpBottom - 1 );
1358cdf0e10cSrcweir rLine.SetUnclipped( sal_True );
1359cdf0e10cSrcweir }
1360cdf0e10cSrcweir }
1361cdf0e10cSrcweir else
1362cdf0e10cSrcweir {
1363cdf0e10cSrcweir if( !rLine.IsUnclipped() || nBottom > rRepaint.Bottom() )
1364cdf0e10cSrcweir {
1365cdf0e10cSrcweir rRepaint.Bottom( nBottom - 1 );
1366cdf0e10cSrcweir rLine.SetUnclipped( sal_False );
1367cdf0e10cSrcweir }
1368cdf0e10cSrcweir }
1369cdf0e10cSrcweir SwTwips nRght = Max( nOldWidth, pNew->Width() +
1370cdf0e10cSrcweir pNew->GetHangingMargin() );
1371cdf0e10cSrcweir ViewShell *pSh = getRootFrm()->GetCurrShell();
1372cdf0e10cSrcweir const SwViewOption *pOpt = pSh ? pSh->GetViewOptions() : 0;
1373cdf0e10cSrcweir if( pOpt && (pOpt->IsParagraph() || pOpt->IsLineBreak()) )
1374cdf0e10cSrcweir nRght += ( Max( nOldAscent, pNew->GetAscent() ) );
1375cdf0e10cSrcweir else
1376cdf0e10cSrcweir nRght += ( Max( nOldAscent, pNew->GetAscent() ) / 4);
1377cdf0e10cSrcweir nRght += rLine.GetLeftMargin();
1378cdf0e10cSrcweir if( rRepaint.GetOfst() || rRepaint.GetRightOfst() < nRght )
1379cdf0e10cSrcweir rRepaint.SetRightOfst( nRght );
1380cdf0e10cSrcweir
1381cdf0e10cSrcweir // Finally we enlarge the repaint rectangle if we found an underscore
1382cdf0e10cSrcweir // within our line. 40 Twips should be enough
1383cdf0e10cSrcweir const sal_Bool bHasUnderscore =
1384cdf0e10cSrcweir ( rLine.GetInfo().GetUnderScorePos() < nNewStart );
1385cdf0e10cSrcweir if ( bHasUnderscore || rLine.GetCurr()->HasUnderscore() )
1386cdf0e10cSrcweir rRepaint.Bottom( rRepaint.Bottom() + 40 );
1387cdf0e10cSrcweir
1388cdf0e10cSrcweir ((SwLineLayout*)rLine.GetCurr())->SetUnderscore( bHasUnderscore );
1389cdf0e10cSrcweir }
1390cdf0e10cSrcweir if( !bUnChg )
1391cdf0e10cSrcweir rLine.SetChanges();
1392cdf0e10cSrcweir
1393cdf0e10cSrcweir // Die gute, alte nDelta-Berechnung:
1394cdf0e10cSrcweir *(pPara->GetDelta()) -= long(pNew->GetLen()) - long(nOldLen);
1395cdf0e10cSrcweir
1396cdf0e10cSrcweir // Stop!
1397cdf0e10cSrcweir if( rLine.IsStop() )
1398cdf0e10cSrcweir return sal_False;
1399cdf0e10cSrcweir
1400cdf0e10cSrcweir // Unbedingt noch eine Zeile
1401cdf0e10cSrcweir if( rLine.IsNewLine() )
1402cdf0e10cSrcweir return sal_True;
1403cdf0e10cSrcweir
1404cdf0e10cSrcweir // bis zum Ende des Strings ?
1405cdf0e10cSrcweir if( nNewStart >= GetTxtNode()->GetTxt().Len() )
1406cdf0e10cSrcweir return sal_False;
1407cdf0e10cSrcweir
1408cdf0e10cSrcweir if( rLine.GetInfo().IsShift() )
1409cdf0e10cSrcweir return sal_True;
1410cdf0e10cSrcweir
1411cdf0e10cSrcweir // Ende des Reformats erreicht ?
1412cdf0e10cSrcweir const xub_StrLen nEnd = pPara->GetReformat()->Start() +
1413cdf0e10cSrcweir pPara->GetReformat()->Len();
1414cdf0e10cSrcweir
1415cdf0e10cSrcweir if( nNewStart <= nEnd )
1416cdf0e10cSrcweir return sal_True;
1417cdf0e10cSrcweir
1418cdf0e10cSrcweir return 0 != *(pPara->GetDelta());
1419cdf0e10cSrcweir }
1420cdf0e10cSrcweir
1421cdf0e10cSrcweir /*************************************************************************
1422cdf0e10cSrcweir * SwTxtFrm::_Format()
1423cdf0e10cSrcweir *************************************************************************/
1424cdf0e10cSrcweir
_Format(SwTxtFormatter & rLine,SwTxtFormatInfo & rInf,const sal_Bool bAdjust)1425cdf0e10cSrcweir void SwTxtFrm::_Format( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf,
1426cdf0e10cSrcweir const sal_Bool bAdjust )
1427cdf0e10cSrcweir {
1428cdf0e10cSrcweir ASSERT( ! IsVertical() || IsSwapped(),"SwTxtFrm::_Format with unswapped frame" );
1429cdf0e10cSrcweir
1430cdf0e10cSrcweir SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1431cdf0e10cSrcweir rLine.SetUnclipped( sal_False );
1432cdf0e10cSrcweir
1433cdf0e10cSrcweir // Das war dem C30 zu kompliziert: aString( GetTxt() );
1434cdf0e10cSrcweir const XubString &rString = GetTxtNode()->GetTxt();
1435cdf0e10cSrcweir const xub_StrLen nStrLen = rString.Len();
1436cdf0e10cSrcweir
1437cdf0e10cSrcweir SwCharRange &rReformat = *(pPara->GetReformat());
1438cdf0e10cSrcweir SwRepaint &rRepaint = *(pPara->GetRepaint());
1439cdf0e10cSrcweir SwRepaint *pFreeze = NULL;
1440cdf0e10cSrcweir
1441cdf0e10cSrcweir // Aus Performancegruenden wird in Init() rReformat auf STRING_LEN gesetzt.
1442cdf0e10cSrcweir // Fuer diesen Fall wird rReformat angepasst.
1443cdf0e10cSrcweir if( rReformat.Len() > nStrLen )
1444cdf0e10cSrcweir rReformat.Len() = nStrLen;
1445cdf0e10cSrcweir
1446cdf0e10cSrcweir // Optimiert:
1447cdf0e10cSrcweir xub_StrLen nEnd = rReformat.Start() + rReformat.Len();
1448cdf0e10cSrcweir if( nEnd > nStrLen )
1449cdf0e10cSrcweir {
1450cdf0e10cSrcweir rReformat.Len() = nStrLen - rReformat.Start();
1451cdf0e10cSrcweir nEnd = nStrLen;
1452cdf0e10cSrcweir }
1453cdf0e10cSrcweir
1454cdf0e10cSrcweir SwTwips nOldBottom;
1455cdf0e10cSrcweir if( GetOfst() && !IsFollow() )
1456cdf0e10cSrcweir {
1457cdf0e10cSrcweir rLine.Bottom();
1458cdf0e10cSrcweir nOldBottom = rLine.Y();
1459cdf0e10cSrcweir rLine.Top();
1460cdf0e10cSrcweir }
1461cdf0e10cSrcweir else
1462cdf0e10cSrcweir nOldBottom = 0;
1463cdf0e10cSrcweir rLine.CharToLine( rReformat.Start() );
1464cdf0e10cSrcweir
1465cdf0e10cSrcweir // Worte koennen durch Fortfall oder Einfuegen eines Space
1466cdf0e10cSrcweir // auf die Zeile vor der editierten hinausgezogen werden,
1467cdf0e10cSrcweir // deshalb muss diese ebenfalls formatiert werden.
1468cdf0e10cSrcweir // Optimierung: Wenn rReformat erst hinter dem ersten Wort der
1469cdf0e10cSrcweir // Zeile beginnt, so kann diese Zeile die vorige nicht mehr beeinflussen.
1470cdf0e10cSrcweir // AMA: Leider doch, Textgroessenaenderungen + FlyFrames, die Rueckwirkung
1471cdf0e10cSrcweir // kann im Extremfall mehrere Zeilen (Frames!!!) betreffen!
1472cdf0e10cSrcweir
1473cdf0e10cSrcweir // --> FME 2005-04-18 #i46560#
1474cdf0e10cSrcweir // FME: Yes, consider this case: (word ) has to go to the next line
1475cdf0e10cSrcweir // because ) is a forbidden character at the beginning of a line although
1476cdf0e10cSrcweir // (word would still fit on the previous line. Adding text right in front
1477cdf0e10cSrcweir // of ) would not trigger a reformatting of the previous line. Adding 1
1478cdf0e10cSrcweir // to the result of FindBrk() does not solve the problem in all cases,
1479cdf0e10cSrcweir // nevertheless it should be sufficient.
1480cdf0e10cSrcweir // <--
1481cdf0e10cSrcweir sal_Bool bPrev = rLine.GetPrev() &&
1482cdf0e10cSrcweir ( FindBrk( rString, rLine.GetStart(), rReformat.Start() + 1 )
1483cdf0e10cSrcweir // --> FME 2005-04-18 #i46560#
1484cdf0e10cSrcweir + 1
1485cdf0e10cSrcweir // <--
1486cdf0e10cSrcweir >= rReformat.Start() ||
1487cdf0e10cSrcweir rLine.GetCurr()->IsRest() );
1488cdf0e10cSrcweir if( bPrev )
1489cdf0e10cSrcweir {
1490cdf0e10cSrcweir while( rLine.Prev() )
1491cdf0e10cSrcweir if( rLine.GetCurr()->GetLen() && !rLine.GetCurr()->IsRest() )
1492cdf0e10cSrcweir {
1493cdf0e10cSrcweir if( !rLine.GetStart() )
1494cdf0e10cSrcweir rLine.Top(); // damit NumDone nicht durcheinander kommt
1495cdf0e10cSrcweir break;
1496cdf0e10cSrcweir }
1497cdf0e10cSrcweir xub_StrLen nNew = rLine.GetStart() + rLine.GetLength();
1498cdf0e10cSrcweir if( nNew )
1499cdf0e10cSrcweir {
1500cdf0e10cSrcweir --nNew;
1501cdf0e10cSrcweir if( CH_BREAK == rString.GetChar( nNew ) )
1502cdf0e10cSrcweir {
1503cdf0e10cSrcweir ++nNew;
1504cdf0e10cSrcweir rLine.Next();
1505cdf0e10cSrcweir bPrev = sal_False;
1506cdf0e10cSrcweir }
1507cdf0e10cSrcweir }
1508cdf0e10cSrcweir rReformat.Len() += rReformat.Start() - nNew;
1509cdf0e10cSrcweir rReformat.Start() = nNew;
1510cdf0e10cSrcweir }
1511cdf0e10cSrcweir
1512cdf0e10cSrcweir rRepaint.SetOfst( 0 );
1513cdf0e10cSrcweir rRepaint.SetRightOfst( 0 );
1514cdf0e10cSrcweir rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
1515cdf0e10cSrcweir if( pPara->IsMargin() )
1516cdf0e10cSrcweir rRepaint.Width( rRepaint.Width() + pPara->GetHangingMargin() );
1517cdf0e10cSrcweir rRepaint.Top( rLine.Y() );
1518cdf0e10cSrcweir // 6792: Rrand < LRand und Repaint
1519cdf0e10cSrcweir if( 0 >= rRepaint.Width() )
1520cdf0e10cSrcweir rRepaint.Width(1);
1521cdf0e10cSrcweir WidowsAndOrphans aFrmBreak( this, rInf.IsTest() ? 1 : 0 );
1522cdf0e10cSrcweir
1523cdf0e10cSrcweir // rLine steht jetzt auf der ersten Zeile, die formatiert werden
1524cdf0e10cSrcweir // muss. Das Flag bFirst sorgt dafuer, dass nicht Next() gerufen wird.
1525cdf0e10cSrcweir // Das ganze sieht verdreht aus, aber es muss sichergestellt werden,
1526cdf0e10cSrcweir // dass bei IsBreakNow rLine auf der Zeile zum stehen kommt, die
1527cdf0e10cSrcweir // nicht mehr passt.
1528cdf0e10cSrcweir sal_Bool bFirst = sal_True;
1529cdf0e10cSrcweir sal_Bool bFormat = sal_True;
1530cdf0e10cSrcweir
1531cdf0e10cSrcweir // 5383: Das CharToLine() kann uns auch in den roten Bereich fuehren.
1532cdf0e10cSrcweir // In diesem Fall muessen wir zurueckwandern, bis die Zeile, die
1533cdf0e10cSrcweir // nicht mehr passt in rLine eingestellt ist. Ansonsten geht Textmasse
1534cdf0e10cSrcweir // verloren, weil der Ofst im Follow falsch eingestellt wird.
1535cdf0e10cSrcweir
1536cdf0e10cSrcweir // OD 2004-02-25 #i16128# - method renamed
1537cdf0e10cSrcweir sal_Bool bBreak = ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 )
1538cdf0e10cSrcweir && aFrmBreak.IsBreakNowWidAndOrp( rLine );
1539cdf0e10cSrcweir if( bBreak )
1540cdf0e10cSrcweir {
1541cdf0e10cSrcweir sal_Bool bPrevDone = 0 != rLine.Prev();
1542cdf0e10cSrcweir // OD 2004-02-25 #i16128# - method renamed
1543cdf0e10cSrcweir while( bPrevDone && aFrmBreak.IsBreakNowWidAndOrp(rLine) )
1544cdf0e10cSrcweir bPrevDone = 0 != rLine.Prev();
1545cdf0e10cSrcweir if( bPrevDone )
1546cdf0e10cSrcweir {
1547cdf0e10cSrcweir aFrmBreak.SetKeep( sal_False );
1548cdf0e10cSrcweir rLine.Next();
1549cdf0e10cSrcweir }
1550cdf0e10cSrcweir rLine.TruncLines();
1551cdf0e10cSrcweir
1552cdf0e10cSrcweir // auf Nummer sicher:
1553cdf0e10cSrcweir // OD 2004-02-25 #i16128# - method renamed
1554cdf0e10cSrcweir bBreak = aFrmBreak.IsBreakNowWidAndOrp(rLine) &&
1555cdf0e10cSrcweir ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 );
1556cdf0e10cSrcweir }
1557cdf0e10cSrcweir
1558cdf0e10cSrcweir /* Bedeutung der folgenden Flags:
1559cdf0e10cSrcweir Ist das Watch(End/Mid)Hyph-Flag gesetzt, so muss formatiert werden, wenn
1560cdf0e10cSrcweir eine Trennung am (Zeilenende/Fly) vorliegt, sofern MaxHyph erreicht ist.
1561cdf0e10cSrcweir Das Jump(End/Mid)Flag bedeutet, dass die naechste Zeile, bei der keine
1562cdf0e10cSrcweir Trennung (Zeilenende/Fly) vorliegt, formatiert werden muss, da jetzt
1563cdf0e10cSrcweir umgebrochen werden koennte, was vorher moeglicherweise durch MaxHyph
1564cdf0e10cSrcweir verboten war.
1565cdf0e10cSrcweir Watch(End/Mid)Hyph wird gesetzt, wenn die letzte formatierte Zeile eine
1566cdf0e10cSrcweir Trennstelle erhalten hat, vorher aber keine hatte,
1567cdf0e10cSrcweir Jump(End/Mid)Hyph, wenn eine Trennstelle verschwindet.
1568cdf0e10cSrcweir */
1569cdf0e10cSrcweir sal_Bool bJumpEndHyph = sal_False,
1570cdf0e10cSrcweir bWatchEndHyph = sal_False,
1571cdf0e10cSrcweir bJumpMidHyph = sal_False,
1572cdf0e10cSrcweir bWatchMidHyph = sal_False;
1573cdf0e10cSrcweir
1574cdf0e10cSrcweir const SwAttrSet& rAttrSet = GetTxtNode()->GetSwAttrSet();
1575cdf0e10cSrcweir sal_Bool bMaxHyph = ( 0 !=
1576cdf0e10cSrcweir ( rInf.MaxHyph() = rAttrSet.GetHyphenZone().GetMaxHyphens() ) );
1577cdf0e10cSrcweir if ( bMaxHyph )
1578cdf0e10cSrcweir rLine.InitCntHyph();
1579cdf0e10cSrcweir
1580cdf0e10cSrcweir if( IsFollow() && IsFieldFollow() && rLine.GetStart() == GetOfst() )
1581cdf0e10cSrcweir {
1582cdf0e10cSrcweir const SwLineLayout* pLine;
1583cdf0e10cSrcweir {
1584cdf0e10cSrcweir SwTxtFrm *pMaster = FindMaster();
1585cdf0e10cSrcweir ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" );
1586cdf0e10cSrcweir if( !pMaster->HasPara() )
1587cdf0e10cSrcweir pMaster->GetFormatted();
1588cdf0e10cSrcweir SwTxtSizeInfo aInf( pMaster );
1589cdf0e10cSrcweir SwTxtIter aMasterLine( pMaster, &aInf );
1590cdf0e10cSrcweir aMasterLine.Bottom();
1591cdf0e10cSrcweir pLine = aMasterLine.GetCurr();
1592cdf0e10cSrcweir }
1593cdf0e10cSrcweir SwLinePortion* pRest =
1594cdf0e10cSrcweir rLine.MakeRestPortion( pLine, GetOfst() );
1595cdf0e10cSrcweir if( pRest )
1596cdf0e10cSrcweir rInf.SetRest( pRest );
1597cdf0e10cSrcweir else
1598cdf0e10cSrcweir SetFieldFollow( sal_False );
1599cdf0e10cSrcweir }
1600cdf0e10cSrcweir
1601cdf0e10cSrcweir /* Zum Abbruchkriterium:
1602cdf0e10cSrcweir * Um zu erkennen, dass eine Zeile nicht mehr auf die Seite passt,
1603cdf0e10cSrcweir * muss sie formatiert werden. Dieser Ueberhang wird z.B. in AdjustFollow
1604cdf0e10cSrcweir * wieder entfernt.
1605cdf0e10cSrcweir * Eine weitere Komplikation: wenn wir der Master sind, so muessen
1606cdf0e10cSrcweir * wir die Zeilen durchgehen, da es ja sein kann, dass eine Zeile
1607cdf0e10cSrcweir * vom Follow in den Master rutschen kann.
1608cdf0e10cSrcweir */
1609cdf0e10cSrcweir do
1610cdf0e10cSrcweir {
1611cdf0e10cSrcweir DBG_LOOP;
1612cdf0e10cSrcweir if( bFirst )
1613cdf0e10cSrcweir bFirst = sal_False;
1614cdf0e10cSrcweir else
1615cdf0e10cSrcweir {
1616cdf0e10cSrcweir if ( bMaxHyph )
1617cdf0e10cSrcweir {
1618cdf0e10cSrcweir if ( rLine.GetCurr()->IsEndHyph() )
1619cdf0e10cSrcweir rLine.CntEndHyph()++;
1620cdf0e10cSrcweir else
1621cdf0e10cSrcweir rLine.CntEndHyph() = 0;
1622cdf0e10cSrcweir if ( rLine.GetCurr()->IsMidHyph() )
1623cdf0e10cSrcweir rLine.CntMidHyph()++;
1624cdf0e10cSrcweir else
1625cdf0e10cSrcweir rLine.CntMidHyph() = 0;
1626cdf0e10cSrcweir }
1627cdf0e10cSrcweir if( !rLine.Next() )
1628cdf0e10cSrcweir {
1629cdf0e10cSrcweir if( !bFormat )
1630cdf0e10cSrcweir {
1631cdf0e10cSrcweir SwLinePortion* pRest =
1632cdf0e10cSrcweir rLine.MakeRestPortion( rLine.GetCurr(), rLine.GetEnd() );
1633cdf0e10cSrcweir if( pRest )
1634cdf0e10cSrcweir rInf.SetRest( pRest );
1635cdf0e10cSrcweir }
1636cdf0e10cSrcweir rLine.Insert( new SwLineLayout() );
1637cdf0e10cSrcweir rLine.Next();
1638cdf0e10cSrcweir bFormat = sal_True;
1639cdf0e10cSrcweir }
1640cdf0e10cSrcweir }
1641cdf0e10cSrcweir if ( !bFormat && bMaxHyph &&
1642cdf0e10cSrcweir (bWatchEndHyph || bJumpEndHyph || bWatchMidHyph || bJumpMidHyph) )
1643cdf0e10cSrcweir {
1644cdf0e10cSrcweir if ( rLine.GetCurr()->IsEndHyph() )
1645cdf0e10cSrcweir {
1646cdf0e10cSrcweir if ( bWatchEndHyph )
1647cdf0e10cSrcweir bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
1648cdf0e10cSrcweir }
1649cdf0e10cSrcweir else
1650cdf0e10cSrcweir {
1651cdf0e10cSrcweir bFormat = bJumpEndHyph;
1652cdf0e10cSrcweir bWatchEndHyph = sal_False;
1653cdf0e10cSrcweir bJumpEndHyph = sal_False;
1654cdf0e10cSrcweir }
1655cdf0e10cSrcweir if ( rLine.GetCurr()->IsMidHyph() )
1656cdf0e10cSrcweir {
1657cdf0e10cSrcweir if ( bWatchMidHyph && !bFormat )
1658cdf0e10cSrcweir bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
1659cdf0e10cSrcweir }
1660cdf0e10cSrcweir else
1661cdf0e10cSrcweir {
1662cdf0e10cSrcweir bFormat = bFormat || bJumpMidHyph;
1663cdf0e10cSrcweir bWatchMidHyph = sal_False;
1664cdf0e10cSrcweir bJumpMidHyph = sal_False;
1665cdf0e10cSrcweir }
1666cdf0e10cSrcweir }
1667cdf0e10cSrcweir if( bFormat )
1668cdf0e10cSrcweir {
1669cdf0e10cSrcweir sal_Bool bOldEndHyph = rLine.GetCurr()->IsEndHyph();
1670cdf0e10cSrcweir sal_Bool bOldMidHyph = rLine.GetCurr()->IsMidHyph();
1671cdf0e10cSrcweir bFormat = FormatLine( rLine, bPrev );
1672cdf0e10cSrcweir //9334: Es kann nur ein bPrev geben... (???)
1673cdf0e10cSrcweir bPrev = sal_False;
1674cdf0e10cSrcweir if ( bMaxHyph )
1675cdf0e10cSrcweir {
1676cdf0e10cSrcweir if ( rLine.GetCurr()->IsEndHyph() != bOldEndHyph )
1677cdf0e10cSrcweir {
1678cdf0e10cSrcweir bWatchEndHyph = !bOldEndHyph;
1679cdf0e10cSrcweir bJumpEndHyph = bOldEndHyph;
1680cdf0e10cSrcweir }
1681cdf0e10cSrcweir if ( rLine.GetCurr()->IsMidHyph() != bOldMidHyph )
1682cdf0e10cSrcweir {
1683cdf0e10cSrcweir bWatchMidHyph = !bOldMidHyph;
1684cdf0e10cSrcweir bJumpMidHyph = bOldMidHyph;
1685cdf0e10cSrcweir }
1686cdf0e10cSrcweir }
1687cdf0e10cSrcweir }
1688cdf0e10cSrcweir
1689cdf0e10cSrcweir if( !rInf.IsNewLine() )
1690cdf0e10cSrcweir {
1691cdf0e10cSrcweir if( !bFormat )
1692cdf0e10cSrcweir bFormat = 0 != rInf.GetRest();
1693cdf0e10cSrcweir if( rInf.IsStop() || rInf.GetIdx() >= nStrLen )
1694cdf0e10cSrcweir break;
1695cdf0e10cSrcweir if( !bFormat && ( !bMaxHyph || ( !bWatchEndHyph &&
1696cdf0e10cSrcweir !bJumpEndHyph && !bWatchMidHyph && !bJumpMidHyph ) ) )
1697cdf0e10cSrcweir {
1698cdf0e10cSrcweir if( GetFollow() )
1699cdf0e10cSrcweir {
1700cdf0e10cSrcweir while( rLine.Next() )
1701cdf0e10cSrcweir ; //Nothing
1702cdf0e10cSrcweir pFreeze = new SwRepaint( rRepaint ); // to minimize painting
1703cdf0e10cSrcweir }
1704cdf0e10cSrcweir else
1705cdf0e10cSrcweir break;
1706cdf0e10cSrcweir }
1707cdf0e10cSrcweir }
1708cdf0e10cSrcweir // OD 2004-02-25 #i16128# - method renamed
1709cdf0e10cSrcweir bBreak = aFrmBreak.IsBreakNowWidAndOrp(rLine);
1710cdf0e10cSrcweir }while( !bBreak );
1711cdf0e10cSrcweir
1712cdf0e10cSrcweir if( pFreeze )
1713cdf0e10cSrcweir {
1714cdf0e10cSrcweir rRepaint = *pFreeze;
1715cdf0e10cSrcweir delete pFreeze;
1716cdf0e10cSrcweir }
1717cdf0e10cSrcweir
1718cdf0e10cSrcweir if( !rLine.IsStop() )
1719cdf0e10cSrcweir {
1720cdf0e10cSrcweir // Wurde aller Text formatiert und gibt es noch weitere
1721cdf0e10cSrcweir // Zeilenobjekte, dann sind diese jetzt ueberfluessig,
1722cdf0e10cSrcweir // weil der Text kuerzer geworden ist.
1723cdf0e10cSrcweir if( rLine.GetStart() + rLine.GetLength() >= nStrLen &&
1724cdf0e10cSrcweir rLine.GetCurr()->GetNext() )
1725cdf0e10cSrcweir {
1726cdf0e10cSrcweir rLine.TruncLines();
1727cdf0e10cSrcweir rLine.SetTruncLines( sal_True );
1728cdf0e10cSrcweir }
1729cdf0e10cSrcweir }
1730cdf0e10cSrcweir
1731cdf0e10cSrcweir if( !rInf.IsTest() )
1732cdf0e10cSrcweir {
1733cdf0e10cSrcweir // Bei OnceMore lohnt sich kein FormatAdjust
1734cdf0e10cSrcweir if( bAdjust || !rLine.GetDropFmt() || !rLine.CalcOnceMore() )
1735cdf0e10cSrcweir {
1736cdf0e10cSrcweir FormatAdjust( rLine, aFrmBreak, nStrLen, rInf.IsStop() );
1737cdf0e10cSrcweir }
1738cdf0e10cSrcweir if( rRepaint.HasArea() )
1739cdf0e10cSrcweir SetRepaint();
1740cdf0e10cSrcweir rLine.SetTruncLines( sal_False );
1741cdf0e10cSrcweir if( nOldBottom ) // Bei "gescollten" Absaetzen wird
1742cdf0e10cSrcweir { // noch ueberprueft, ob durch Schrumpfen
1743cdf0e10cSrcweir rLine.Bottom(); // das Scrolling ueberfluessig wurde.
1744cdf0e10cSrcweir SwTwips nNewBottom = rLine.Y();
1745cdf0e10cSrcweir if( nNewBottom < nOldBottom )
1746cdf0e10cSrcweir _SetOfst( 0 );
1747cdf0e10cSrcweir }
1748cdf0e10cSrcweir }
1749cdf0e10cSrcweir }
1750cdf0e10cSrcweir
1751cdf0e10cSrcweir /*************************************************************************
1752cdf0e10cSrcweir * SwTxtFrm::Format()
1753cdf0e10cSrcweir *************************************************************************/
1754cdf0e10cSrcweir
FormatOnceMore(SwTxtFormatter & rLine,SwTxtFormatInfo & rInf)1755cdf0e10cSrcweir void SwTxtFrm::FormatOnceMore( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf )
1756cdf0e10cSrcweir {
1757cdf0e10cSrcweir ASSERT( ! IsVertical() || IsSwapped(),
1758cdf0e10cSrcweir "A frame is not swapped in SwTxtFrm::FormatOnceMore" );
1759cdf0e10cSrcweir
1760cdf0e10cSrcweir SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1761cdf0e10cSrcweir if( !pPara )
1762cdf0e10cSrcweir return;
1763cdf0e10cSrcweir
1764cdf0e10cSrcweir // ggf gegen pPara
1765cdf0e10cSrcweir KSHORT nOld = ((const SwTxtMargin&)rLine).GetDropHeight();
1766cdf0e10cSrcweir sal_Bool bShrink = sal_False,
1767cdf0e10cSrcweir bGrow = sal_False,
1768cdf0e10cSrcweir bGoOn = rLine.IsOnceMore();
1769cdf0e10cSrcweir sal_uInt8 nGo = 0;
1770cdf0e10cSrcweir while( bGoOn )
1771cdf0e10cSrcweir {
1772cdf0e10cSrcweir #ifdef DBGTXT
1773cdf0e10cSrcweir aDbstream << "OnceMore!" << endl;
1774cdf0e10cSrcweir #endif
1775cdf0e10cSrcweir ++nGo;
1776cdf0e10cSrcweir rInf.Init();
1777cdf0e10cSrcweir rLine.Top();
1778cdf0e10cSrcweir if( !rLine.GetDropFmt() )
1779cdf0e10cSrcweir rLine.SetOnceMore( sal_False );
1780cdf0e10cSrcweir SwCharRange aRange( 0, rInf.GetTxt().Len() );
1781cdf0e10cSrcweir *(pPara->GetReformat()) = aRange;
1782cdf0e10cSrcweir _Format( rLine, rInf );
1783cdf0e10cSrcweir
1784cdf0e10cSrcweir bGoOn = rLine.IsOnceMore();
1785cdf0e10cSrcweir if( bGoOn )
1786cdf0e10cSrcweir {
1787cdf0e10cSrcweir const KSHORT nNew = ((const SwTxtMargin&)rLine).GetDropHeight();
1788cdf0e10cSrcweir if( nOld == nNew )
1789cdf0e10cSrcweir bGoOn = sal_False;
1790cdf0e10cSrcweir else
1791cdf0e10cSrcweir {
1792cdf0e10cSrcweir if( nOld > nNew )
1793cdf0e10cSrcweir bShrink = sal_True;
1794cdf0e10cSrcweir else
1795cdf0e10cSrcweir bGrow = sal_True;
1796cdf0e10cSrcweir
1797cdf0e10cSrcweir if( bShrink == bGrow || 5 < nGo )
1798cdf0e10cSrcweir bGoOn = sal_False;
1799cdf0e10cSrcweir
1800cdf0e10cSrcweir nOld = nNew;
1801cdf0e10cSrcweir }
1802cdf0e10cSrcweir
1803cdf0e10cSrcweir // 6107: Wenn was schief ging, muss noch einmal formatiert werden.
1804cdf0e10cSrcweir if( !bGoOn )
1805cdf0e10cSrcweir {
1806cdf0e10cSrcweir rInf.CtorInitTxtFormatInfo( this );
1807cdf0e10cSrcweir rLine.CtorInitTxtFormatter( this, &rInf );
1808cdf0e10cSrcweir rLine.SetDropLines( 1 );
1809cdf0e10cSrcweir rLine.CalcDropHeight( 1 );
1810cdf0e10cSrcweir SwCharRange aTmpRange( 0, rInf.GetTxt().Len() );
1811cdf0e10cSrcweir *(pPara->GetReformat()) = aTmpRange;
1812cdf0e10cSrcweir _Format( rLine, rInf, sal_True );
1813cdf0e10cSrcweir // 8047: Wir painten alles...
1814cdf0e10cSrcweir SetCompletePaint();
1815cdf0e10cSrcweir }
1816cdf0e10cSrcweir }
1817cdf0e10cSrcweir }
1818cdf0e10cSrcweir }
1819cdf0e10cSrcweir
1820cdf0e10cSrcweir /*************************************************************************
1821cdf0e10cSrcweir * SwTxtFrm::_Format()
1822cdf0e10cSrcweir *************************************************************************/
1823cdf0e10cSrcweir
1824cdf0e10cSrcweir
_Format(SwParaPortion * pPara)1825cdf0e10cSrcweir void SwTxtFrm::_Format( SwParaPortion *pPara )
1826cdf0e10cSrcweir {
1827cdf0e10cSrcweir const xub_StrLen nStrLen = GetTxt().Len();
1828cdf0e10cSrcweir
1829cdf0e10cSrcweir // AMA: Wozu soll das gut sein? Scheint mir zuoft zu einem kompletten
1830cdf0e10cSrcweir // Formatieren und Repainten zu fuehren???
1831cdf0e10cSrcweir // if ( !(*pPara->GetDelta()) )
1832cdf0e10cSrcweir // *(pPara->GetDelta()) = nStrLen;
1833cdf0e10cSrcweir // else
1834cdf0e10cSrcweir if ( !nStrLen )
1835cdf0e10cSrcweir {
1836cdf0e10cSrcweir // Leere Zeilen werden nicht lange gequaelt:
1837cdf0e10cSrcweir // pPara wird blank geputzt
1838cdf0e10cSrcweir // entspricht *pPara = SwParaPortion;
1839cdf0e10cSrcweir sal_Bool bMustFit = pPara->IsPrepMustFit();
1840cdf0e10cSrcweir pPara->Truncate();
1841cdf0e10cSrcweir pPara->FormatReset();
1842cdf0e10cSrcweir if( pBlink && pPara->IsBlinking() )
1843cdf0e10cSrcweir pBlink->Delete( pPara );
1844cdf0e10cSrcweir
1845cdf0e10cSrcweir // delete pSpaceAdd und pKanaComp
1846cdf0e10cSrcweir pPara->FinishSpaceAdd();
1847cdf0e10cSrcweir pPara->FinishKanaComp();
1848cdf0e10cSrcweir pPara->ResetFlags();
1849cdf0e10cSrcweir pPara->SetPrepMustFit( bMustFit );
1850cdf0e10cSrcweir }
1851cdf0e10cSrcweir
1852cdf0e10cSrcweir ASSERT( ! IsSwapped(), "A frame is swapped before _Format" );
1853cdf0e10cSrcweir
1854cdf0e10cSrcweir if ( IsVertical() )
1855cdf0e10cSrcweir SwapWidthAndHeight();
1856cdf0e10cSrcweir
1857cdf0e10cSrcweir SwTxtFormatInfo aInf( this );
1858cdf0e10cSrcweir SwTxtFormatter aLine( this, &aInf );
1859cdf0e10cSrcweir
1860cdf0e10cSrcweir // OD 2004-01-15 #110582#
1861cdf0e10cSrcweir HideAndShowObjects();
1862cdf0e10cSrcweir
1863cdf0e10cSrcweir _Format( aLine, aInf );
1864cdf0e10cSrcweir
1865cdf0e10cSrcweir if( aLine.IsOnceMore() )
1866cdf0e10cSrcweir FormatOnceMore( aLine, aInf );
1867cdf0e10cSrcweir
1868cdf0e10cSrcweir if ( IsVertical() )
1869cdf0e10cSrcweir SwapWidthAndHeight();
1870cdf0e10cSrcweir
1871cdf0e10cSrcweir ASSERT( ! IsSwapped(), "A frame is swapped after _Format" );
1872cdf0e10cSrcweir
1873cdf0e10cSrcweir if( 1 < aLine.GetDropLines() )
1874cdf0e10cSrcweir {
1875cdf0e10cSrcweir if( SVX_ADJUST_LEFT != aLine.GetAdjust() &&
1876cdf0e10cSrcweir SVX_ADJUST_BLOCK != aLine.GetAdjust() )
1877cdf0e10cSrcweir {
1878cdf0e10cSrcweir aLine.CalcDropAdjust();
1879cdf0e10cSrcweir aLine.SetPaintDrop( sal_True );
1880cdf0e10cSrcweir }
1881cdf0e10cSrcweir
1882cdf0e10cSrcweir if( aLine.IsPaintDrop() )
1883cdf0e10cSrcweir {
1884cdf0e10cSrcweir aLine.CalcDropRepaint();
1885cdf0e10cSrcweir aLine.SetPaintDrop( sal_False );
1886cdf0e10cSrcweir }
1887cdf0e10cSrcweir }
1888cdf0e10cSrcweir }
1889cdf0e10cSrcweir
1890cdf0e10cSrcweir /*************************************************************************
1891cdf0e10cSrcweir * SwTxtFrm::Format()
1892cdf0e10cSrcweir *************************************************************************/
1893cdf0e10cSrcweir
1894cdf0e10cSrcweir /*
1895cdf0e10cSrcweir * Format berechnet die Groesse des Textframes und ruft, wenn
1896cdf0e10cSrcweir * diese feststeht, Shrink() oder Grow(), um die Framegroesse dem
1897cdf0e10cSrcweir * evtl. veraenderten Platzbedarf anzupassen.
1898cdf0e10cSrcweir */
1899cdf0e10cSrcweir
Format(const SwBorderAttrs *)1900cdf0e10cSrcweir void SwTxtFrm::Format( const SwBorderAttrs * )
1901cdf0e10cSrcweir {
1902cdf0e10cSrcweir DBG_LOOP;
1903cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1904cdf0e10cSrcweir const XubString aXXX = GetTxtNode()->GetTxt();
1905cdf0e10cSrcweir const SwTwips nDbgY = Frm().Top();
1906cdf0e10cSrcweir (void)nDbgY;
1907cdf0e10cSrcweir const SwPageFrm *pDbgPage = FindPageFrm();
1908cdf0e10cSrcweir const MSHORT nDbgPageNr = pDbgPage->GetPhyPageNum();
1909cdf0e10cSrcweir (void)nDbgPageNr;
1910cdf0e10cSrcweir // Um zu gucken, ob es einen Ftn-Bereich gibt.
1911cdf0e10cSrcweir const SwFrm *pDbgFtnCont = (const SwFrm*)(FindPageFrm()->FindFtnCont());
1912cdf0e10cSrcweir (void)pDbgFtnCont;
1913cdf0e10cSrcweir
1914cdf0e10cSrcweir #ifdef DBG_UTIL
1915cdf0e10cSrcweir // nStopAt laesst sich vom CV bearbeiten.
1916cdf0e10cSrcweir static MSHORT nStopAt = 0;
1917cdf0e10cSrcweir if( nStopAt == GetFrmId() )
1918cdf0e10cSrcweir {
1919cdf0e10cSrcweir int i = GetFrmId();
1920cdf0e10cSrcweir (void)i;
1921cdf0e10cSrcweir }
1922cdf0e10cSrcweir #endif
1923cdf0e10cSrcweir #endif
1924cdf0e10cSrcweir
1925cdf0e10cSrcweir #ifdef DEBUG_FTN
1926cdf0e10cSrcweir //Fussnote darf nicht auf einer Seite vor ihrer Referenz stehen.
1927cdf0e10cSrcweir if( IsInFtn() )
1928cdf0e10cSrcweir {
1929cdf0e10cSrcweir const SwFtnFrm *pFtn = (SwFtnFrm*)GetUpper();
1930cdf0e10cSrcweir const SwPageFrm *pFtnPage = pFtn->GetRef()->FindPageFrm();
1931cdf0e10cSrcweir const MSHORT nFtnPageNr = pFtnPage->GetPhyPageNum();
1932cdf0e10cSrcweir if( !IsLocked() )
1933cdf0e10cSrcweir {
1934cdf0e10cSrcweir if( nFtnPageNr > nDbgPageNr )
1935cdf0e10cSrcweir {
1936cdf0e10cSrcweir SwTxtFrmLocker aLock(this);
1937cdf0e10cSrcweir ASSERT( nFtnPageNr <= nDbgPageNr, "!Ftn steht vor der Referenz." );
1938cdf0e10cSrcweir MSHORT i = 0;
1939cdf0e10cSrcweir }
1940cdf0e10cSrcweir }
1941cdf0e10cSrcweir }
1942cdf0e10cSrcweir #endif
1943cdf0e10cSrcweir
1944cdf0e10cSrcweir SWRECTFN( this )
1945cdf0e10cSrcweir
1946cdf0e10cSrcweir // --> OD 2008-01-31 #newlistlevelattrs#
1947cdf0e10cSrcweir CalcAdditionalFirstLineOffset();
1948cdf0e10cSrcweir // <--
1949cdf0e10cSrcweir
1950cdf0e10cSrcweir // Vom Berichtsautopiloten oder ueber die BASIC-Schnittstelle kommen
1951cdf0e10cSrcweir // gelegentlich TxtFrms mit einer Breite <=0.
1952cdf0e10cSrcweir if( (Prt().*fnRect->fnGetWidth)() <= 0 )
1953cdf0e10cSrcweir {
1954cdf0e10cSrcweir // Wenn MustFit gesetzt ist, schrumpfen wir ggf. auf die Unterkante
1955cdf0e10cSrcweir // des Uppers, ansonsten nehmen wir einfach eine Standardgroesse
1956cdf0e10cSrcweir // von 12 Pt. ein (240 Twip).
1957cdf0e10cSrcweir SwTxtLineAccess aAccess( this );
1958cdf0e10cSrcweir long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1959cdf0e10cSrcweir if( aAccess.GetPara()->IsPrepMustFit() )
1960cdf0e10cSrcweir {
1961cdf0e10cSrcweir const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
1962cdf0e10cSrcweir const SwTwips nDiff = - (Frm().*fnRect->fnBottomDist)( nLimit );
1963cdf0e10cSrcweir if( nDiff > 0 )
1964cdf0e10cSrcweir Shrink( nDiff );
1965cdf0e10cSrcweir }
1966cdf0e10cSrcweir else if( 240 < nFrmHeight )
1967cdf0e10cSrcweir Shrink( nFrmHeight - 240 );
1968cdf0e10cSrcweir else if( 240 > nFrmHeight )
1969cdf0e10cSrcweir Grow( 240 - nFrmHeight );
1970cdf0e10cSrcweir nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1971cdf0e10cSrcweir
1972cdf0e10cSrcweir long nTop = (this->*fnRect->fnGetTopMargin)();
1973cdf0e10cSrcweir if( nTop > nFrmHeight )
1974cdf0e10cSrcweir (this->*fnRect->fnSetYMargins)( nFrmHeight, 0 );
1975cdf0e10cSrcweir else if( (Prt().*fnRect->fnGetHeight)() < 0 )
1976cdf0e10cSrcweir (Prt().*fnRect->fnSetHeight)( 0 );
1977cdf0e10cSrcweir return;
1978cdf0e10cSrcweir }
1979cdf0e10cSrcweir
1980cdf0e10cSrcweir const xub_StrLen nStrLen = GetTxtNode()->GetTxt().Len();
1981cdf0e10cSrcweir if ( nStrLen || !FormatEmpty() )
1982cdf0e10cSrcweir {
1983cdf0e10cSrcweir
1984cdf0e10cSrcweir SetEmpty( sal_False );
1985cdf0e10cSrcweir // Um nicht durch verschachtelte Formats irritiert zu werden.
1986cdf0e10cSrcweir FormatLevel aLevel;
1987cdf0e10cSrcweir if( 12 == aLevel.GetLevel() )
1988cdf0e10cSrcweir return;
1989cdf0e10cSrcweir
1990cdf0e10cSrcweir // Die Formatinformationen duerfen u.U. nicht veraendert werden.
1991cdf0e10cSrcweir if( IsLocked() )
1992cdf0e10cSrcweir return;
1993cdf0e10cSrcweir
1994cdf0e10cSrcweir // 8708: Vorsicht, das Format() kann auch durch GetFormatted()
1995cdf0e10cSrcweir // angestossen werden.
1996cdf0e10cSrcweir if( IsHiddenNow() )
1997cdf0e10cSrcweir {
1998cdf0e10cSrcweir long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1999cdf0e10cSrcweir if( nPrtHeight )
2000cdf0e10cSrcweir {
2001cdf0e10cSrcweir HideHidden();
2002cdf0e10cSrcweir Shrink( nPrtHeight );
2003cdf0e10cSrcweir }
2004cdf0e10cSrcweir else
2005cdf0e10cSrcweir {
2006cdf0e10cSrcweir // OD 2004-01-20 #110582# - assure that objects anchored
2007cdf0e10cSrcweir // at paragraph resp. at/as character inside paragraph
2008cdf0e10cSrcweir // are hidden.
2009cdf0e10cSrcweir HideAndShowObjects();
2010cdf0e10cSrcweir }
2011cdf0e10cSrcweir ChgThisLines();
2012cdf0e10cSrcweir return;
2013cdf0e10cSrcweir }
2014cdf0e10cSrcweir
2015cdf0e10cSrcweir // Waehrend wir formatieren, wollen wir nicht gestoert werden.
2016cdf0e10cSrcweir SwTxtFrmLocker aLock(this);
2017cdf0e10cSrcweir SwTxtLineAccess aAccess( this );
2018cdf0e10cSrcweir const sal_Bool bNew = !aAccess.SwTxtLineAccess::IsAvailable();
2019cdf0e10cSrcweir const sal_Bool bSetOfst = ( GetOfst() && GetOfst() > GetTxtNode()->GetTxt().Len() );
2020cdf0e10cSrcweir
2021cdf0e10cSrcweir if( CalcPreps() )
2022cdf0e10cSrcweir ; // nothing
2023cdf0e10cSrcweir // Wir returnen, wenn schon formatiert wurde, nicht aber, wenn
2024cdf0e10cSrcweir // der TxtFrm gerade erzeugt wurde und ueberhaupt keine Format-
2025cdf0e10cSrcweir // informationen vorliegen.
2026cdf0e10cSrcweir else if( !bNew && !aAccess.GetPara()->GetReformat()->Len() )
2027cdf0e10cSrcweir {
2028cdf0e10cSrcweir if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
2029cdf0e10cSrcweir {
2030cdf0e10cSrcweir aAccess.GetPara()->SetPrepAdjust( sal_True );
2031cdf0e10cSrcweir aAccess.GetPara()->SetPrep( sal_True );
2032cdf0e10cSrcweir CalcPreps();
2033cdf0e10cSrcweir }
2034cdf0e10cSrcweir SetWidow( sal_False );
2035cdf0e10cSrcweir }
2036cdf0e10cSrcweir else if( bSetOfst && IsFollow() )
2037cdf0e10cSrcweir {
2038cdf0e10cSrcweir SwTxtFrm *pMaster = FindMaster();
2039cdf0e10cSrcweir ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" );
2040cdf0e10cSrcweir if( pMaster )
2041cdf0e10cSrcweir pMaster->Prepare( PREP_FOLLOW_FOLLOWS );
2042cdf0e10cSrcweir SwTwips nMaxY = (GetUpper()->*fnRect->fnGetPrtBottom)();
2043cdf0e10cSrcweir if( (Frm().*fnRect->fnOverStep)( nMaxY ) )
2044cdf0e10cSrcweir (this->*fnRect->fnSetLimit)( nMaxY );
2045cdf0e10cSrcweir else if( (Frm().*fnRect->fnBottomDist)( nMaxY ) < 0 )
2046cdf0e10cSrcweir (Frm().*fnRect->fnAddBottom)( -(Frm().*fnRect->fnGetHeight)() );
2047cdf0e10cSrcweir }
2048cdf0e10cSrcweir else
2049cdf0e10cSrcweir {
2050cdf0e10cSrcweir // bSetOfst here means that we have the "red arrow situation"
2051cdf0e10cSrcweir if ( bSetOfst )
2052cdf0e10cSrcweir _SetOfst( 0 );
2053cdf0e10cSrcweir
2054cdf0e10cSrcweir const sal_Bool bOrphan = IsWidow();
2055cdf0e10cSrcweir const SwFtnBossFrm* pFtnBoss = HasFtn() ? FindFtnBossFrm() : 0;
2056cdf0e10cSrcweir SwTwips nFtnHeight = 0;
2057cdf0e10cSrcweir if( pFtnBoss )
2058cdf0e10cSrcweir {
2059cdf0e10cSrcweir const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont();
2060cdf0e10cSrcweir nFtnHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0;
2061cdf0e10cSrcweir }
2062cdf0e10cSrcweir do
2063cdf0e10cSrcweir {
2064cdf0e10cSrcweir _Format( aAccess.GetPara() );
2065cdf0e10cSrcweir if( pFtnBoss && nFtnHeight )
2066cdf0e10cSrcweir {
2067cdf0e10cSrcweir const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont();
2068cdf0e10cSrcweir SwTwips nNewHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0;
2069cdf0e10cSrcweir // If we lost some footnotes, we may have more space
2070cdf0e10cSrcweir // for our main text, so we have to format again ...
2071cdf0e10cSrcweir if( nNewHeight < nFtnHeight )
2072cdf0e10cSrcweir nFtnHeight = nNewHeight;
2073cdf0e10cSrcweir else
2074cdf0e10cSrcweir break;
2075cdf0e10cSrcweir }
2076cdf0e10cSrcweir else
2077cdf0e10cSrcweir break;
2078cdf0e10cSrcweir } while ( pFtnBoss );
2079cdf0e10cSrcweir if( bOrphan )
2080cdf0e10cSrcweir {
2081cdf0e10cSrcweir ValidateFrm();
2082cdf0e10cSrcweir SetWidow( sal_False );
2083cdf0e10cSrcweir }
2084cdf0e10cSrcweir }
2085cdf0e10cSrcweir if( IsEmptyMaster() )
2086cdf0e10cSrcweir {
2087cdf0e10cSrcweir SwFrm* pPre = GetPrev();
2088cdf0e10cSrcweir if( pPre &&
2089cdf0e10cSrcweir // --> FME 2004-07-22 #i10826# It's the first, it cannot keep!
2090cdf0e10cSrcweir pPre->GetIndPrev() &&
2091cdf0e10cSrcweir // <--
2092cdf0e10cSrcweir pPre->GetAttrSet()->GetKeep().GetValue() )
2093cdf0e10cSrcweir {
2094cdf0e10cSrcweir pPre->InvalidatePos();
2095cdf0e10cSrcweir }
2096cdf0e10cSrcweir }
2097cdf0e10cSrcweir }
2098cdf0e10cSrcweir
2099cdf0e10cSrcweir ChgThisLines();
2100cdf0e10cSrcweir
2101cdf0e10cSrcweir // the PrepMustFit should not survive a Format operation
2102cdf0e10cSrcweir SwParaPortion *pPara = GetPara();
2103cdf0e10cSrcweir if ( pPara )
2104cdf0e10cSrcweir pPara->SetPrepMustFit( sal_False );
2105cdf0e10cSrcweir
2106cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2107cdf0e10cSrcweir // Hier ein Instrumentarium, um ungewoehnlichen Master/Follow-Kombinationen,
2108cdf0e10cSrcweir // insbesondere bei Fussnoten, auf die Schliche zu kommen
2109cdf0e10cSrcweir if( IsFollow() || GetFollow() )
2110cdf0e10cSrcweir {
2111cdf0e10cSrcweir SwTxtFrm *pTmpFrm = IsFollow() ? FindMaster() : this;
2112cdf0e10cSrcweir const SwPageFrm *pTmpPage = pTmpFrm->FindPageFrm();
2113cdf0e10cSrcweir MSHORT nPgNr = pTmpPage->GetPhyPageNum();
2114cdf0e10cSrcweir MSHORT nLast;
2115cdf0e10cSrcweir MSHORT nDummy = 0; // nur zum Breakpoint setzen
2116cdf0e10cSrcweir while( pTmpFrm->GetFollow() )
2117cdf0e10cSrcweir {
2118cdf0e10cSrcweir pTmpFrm = pTmpFrm->GetFollow();
2119cdf0e10cSrcweir nLast = nPgNr;
2120cdf0e10cSrcweir pTmpPage = pTmpFrm->FindPageFrm();
2121cdf0e10cSrcweir nPgNr = pTmpPage->GetPhyPageNum();
2122cdf0e10cSrcweir if( nLast > nPgNr )
2123cdf0e10cSrcweir ++nDummy; // schon fast eine Assertion wert
2124cdf0e10cSrcweir else if( nLast == nPgNr )
2125cdf0e10cSrcweir ++nDummy; // bei Spalten voellig normal, aber sonst!?
2126cdf0e10cSrcweir else if( nLast < nPgNr - 1 )
2127cdf0e10cSrcweir ++nDummy; // kann schon mal temporaer vorkommen
2128cdf0e10cSrcweir }
2129cdf0e10cSrcweir }
2130cdf0e10cSrcweir #endif
2131cdf0e10cSrcweir
2132cdf0e10cSrcweir CalcBaseOfstForFly();
2133cdf0e10cSrcweir // OD 2004-03-17 #i11860#
2134cdf0e10cSrcweir _CalcHeightOfLastLine();
2135cdf0e10cSrcweir }
2136cdf0e10cSrcweir
2137cdf0e10cSrcweir /*************************************************************************
2138cdf0e10cSrcweir * SwTxtFrm::FormatQuick()
2139cdf0e10cSrcweir *
2140cdf0e10cSrcweir * bForceQuickFormat is set if GetFormatted() has been called during the
2141cdf0e10cSrcweir * painting process. Actually I cannot imagine a situation which requires
2142cdf0e10cSrcweir * a full formatting of the paragraph during painting, on the other hand
2143cdf0e10cSrcweir * a full formatting can cause the invalidation of other layout frames,
2144cdf0e10cSrcweir * e.g., if there are footnotes in this paragraph, and invalid layout
2145cdf0e10cSrcweir * frames will not calculated during the painting. So I actually want to
2146cdf0e10cSrcweir * avoid a formatting during painting, but since I'm a coward, I'll only
2147cdf0e10cSrcweir * force the quick formatting in the situation of issue i29062.
2148cdf0e10cSrcweir *************************************************************************/
2149cdf0e10cSrcweir
FormatQuick(bool bForceQuickFormat)2150cdf0e10cSrcweir sal_Bool SwTxtFrm::FormatQuick( bool bForceQuickFormat )
2151cdf0e10cSrcweir {
2152cdf0e10cSrcweir ASSERT( ! IsVertical() || ! IsSwapped(),
2153cdf0e10cSrcweir "SwTxtFrm::FormatQuick with swapped frame" );
2154cdf0e10cSrcweir
2155cdf0e10cSrcweir DBG_LOOP;
2156cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2157cdf0e10cSrcweir const XubString aXXX = GetTxtNode()->GetTxt();
2158cdf0e10cSrcweir const SwTwips nDbgY = Frm().Top();
2159cdf0e10cSrcweir (void)nDbgY;
2160cdf0e10cSrcweir #ifdef DBG_UTIL
2161cdf0e10cSrcweir // nStopAt laesst sich vom CV bearbeiten.
2162cdf0e10cSrcweir static MSHORT nStopAt = 0;
2163cdf0e10cSrcweir if( nStopAt == GetFrmId() )
2164cdf0e10cSrcweir {
2165cdf0e10cSrcweir int i = GetFrmId();
2166cdf0e10cSrcweir (void)i;
2167cdf0e10cSrcweir }
2168cdf0e10cSrcweir #endif
2169cdf0e10cSrcweir #endif
2170cdf0e10cSrcweir
2171cdf0e10cSrcweir if( IsEmpty() && FormatEmpty() )
2172cdf0e10cSrcweir return sal_True;
2173cdf0e10cSrcweir
2174cdf0e10cSrcweir // Wir sind sehr waehlerisch:
2175cdf0e10cSrcweir if( HasPara() || IsWidow() || IsLocked()
2176cdf0e10cSrcweir || !GetValidSizeFlag() ||
2177cdf0e10cSrcweir ( ( IsVertical() ? Prt().Width() : Prt().Height() ) && IsHiddenNow() ) )
2178cdf0e10cSrcweir return sal_False;
2179cdf0e10cSrcweir
2180cdf0e10cSrcweir SwTxtLineAccess aAccess( this );
2181cdf0e10cSrcweir SwParaPortion *pPara = aAccess.GetPara();
2182cdf0e10cSrcweir if( !pPara )
2183cdf0e10cSrcweir return sal_False;
2184cdf0e10cSrcweir
2185cdf0e10cSrcweir SwFrmSwapper aSwapper( this, sal_True );
2186cdf0e10cSrcweir
2187cdf0e10cSrcweir SwTxtFrmLocker aLock(this);
2188cdf0e10cSrcweir SwTxtFormatInfo aInf( this, sal_False, sal_True );
2189cdf0e10cSrcweir if( 0 != aInf.MaxHyph() ) // 27483: MaxHyphen beachten!
2190cdf0e10cSrcweir return sal_False;
2191cdf0e10cSrcweir
2192cdf0e10cSrcweir SwTxtFormatter aLine( this, &aInf );
2193cdf0e10cSrcweir
2194cdf0e10cSrcweir // DropCaps sind zu kompliziert...
2195cdf0e10cSrcweir if( aLine.GetDropFmt() )
2196cdf0e10cSrcweir return sal_False;
2197cdf0e10cSrcweir
2198cdf0e10cSrcweir xub_StrLen nStart = GetOfst();
2199cdf0e10cSrcweir const xub_StrLen nEnd = GetFollow()
2200cdf0e10cSrcweir ? GetFollow()->GetOfst() : aInf.GetTxt().Len();
2201cdf0e10cSrcweir do
2202cdf0e10cSrcweir {
2203cdf0e10cSrcweir //DBG_LOOP; shadows declaration above.
2204cdf0e10cSrcweir //resolved into:
2205cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2206cdf0e10cSrcweir #ifdef DBG_UTIL
2207cdf0e10cSrcweir DbgLoop aDbgLoop2( (const void*) this );
2208cdf0e10cSrcweir #endif
2209cdf0e10cSrcweir #endif
2210cdf0e10cSrcweir nStart = aLine.FormatLine( nStart );
2211cdf0e10cSrcweir if( aInf.IsNewLine() || (!aInf.IsStop() && nStart < nEnd) )
2212cdf0e10cSrcweir aLine.Insert( new SwLineLayout() );
2213cdf0e10cSrcweir } while( aLine.Next() );
2214cdf0e10cSrcweir
2215cdf0e10cSrcweir // Last exit: die Hoehen muessen uebereinstimmen.
2216cdf0e10cSrcweir Point aTopLeft( Frm().Pos() );
2217cdf0e10cSrcweir aTopLeft += Prt().Pos();
2218cdf0e10cSrcweir const SwTwips nNewHeight = aLine.Y() + aLine.GetLineHeight();
2219cdf0e10cSrcweir const SwTwips nOldHeight = aTopLeft.Y() + Prt().Height();
2220cdf0e10cSrcweir
2221cdf0e10cSrcweir if( !bForceQuickFormat && nNewHeight != nOldHeight && !IsUndersized() )
2222cdf0e10cSrcweir {
2223cdf0e10cSrcweir // Achtung: Durch FormatLevel==12 kann diese Situation auftreten, don't panic!
2224cdf0e10cSrcweir // ASSERT( nNewHeight == nOldHeight, "!FormatQuick: rosebud" );
2225cdf0e10cSrcweir const xub_StrLen nStrt = GetOfst();
2226cdf0e10cSrcweir _InvalidateRange( SwCharRange( nStrt, nEnd - nStrt) );
2227cdf0e10cSrcweir return sal_False;
2228cdf0e10cSrcweir }
2229cdf0e10cSrcweir
2230cdf0e10cSrcweir if( pFollow && nStart != ((SwTxtFrm*)pFollow)->GetOfst() )
2231cdf0e10cSrcweir return sal_False; // kann z.B. durch Orphans auftreten (35083,35081)
2232cdf0e10cSrcweir
2233cdf0e10cSrcweir // Geschafft, wir sind durch ...
2234cdf0e10cSrcweir
2235cdf0e10cSrcweir // Repaint setzen
2236cdf0e10cSrcweir pPara->GetRepaint()->Pos( aTopLeft );
2237cdf0e10cSrcweir pPara->GetRepaint()->SSize( Prt().SSize() );
2238cdf0e10cSrcweir
2239cdf0e10cSrcweir // Reformat loeschen
2240cdf0e10cSrcweir *(pPara->GetReformat()) = SwCharRange();
2241cdf0e10cSrcweir *(pPara->GetDelta()) = 0;
2242cdf0e10cSrcweir
2243cdf0e10cSrcweir return sal_True;
2244cdf0e10cSrcweir }
2245