Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "rootfrm.hxx"
30 : : #include "pagefrm.hxx"
31 : : #include "cntfrm.hxx"
32 : : #include "viewsh.hxx"
33 : : #include "doc.hxx"
34 : : #include "viewimp.hxx"
35 : : #include "viewopt.hxx"
36 : : #include "swtypes.hxx"
37 : : #include "dflyobj.hxx"
38 : : #include "dcontact.hxx"
39 : : #include "flyfrm.hxx"
40 : : #include "frmtool.hxx"
41 : : #include "txtftn.hxx"
42 : : #include "fmtftn.hxx"
43 : : #include <editeng/ulspitem.hxx>
44 : : #include <editeng/keepitem.hxx>
45 : :
46 : : #include <vcl/outdev.hxx>
47 : : #include <fmtfsize.hxx>
48 : : #include <fmtanchr.hxx>
49 : : #include <fmtclbl.hxx>
50 : :
51 : : #include "tabfrm.hxx"
52 : : #include "ftnfrm.hxx"
53 : : #include "txtfrm.hxx"
54 : : #include "pagedesc.hxx"
55 : : #include "ftninfo.hxx"
56 : : #include "sectfrm.hxx"
57 : : #include "dbg_lay.hxx"
58 : :
59 : : // #i28701#
60 : : #include <sortedobjs.hxx>
61 : : #include <layouter.hxx>
62 : : // #i36347#
63 : : #include <flyfrms.hxx>
64 : :
65 : : #include <ndtxt.hxx>
66 : :
67 : : //------------------------------------------------------------------------
68 : : // Move methods
69 : : //------------------------------------------------------------------------
70 : :
71 : : /*************************************************************************
72 : : |*
73 : : |* SwCntntFrm::ShouldBwdMoved()
74 : : |*
75 : : |* Description Return value tells whether the Frm should be moved.
76 : : |*
77 : : |*************************************************************************/
78 : :
79 : :
80 : 88 : sal_Bool SwCntntFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, sal_Bool, sal_Bool & )
81 : : {
82 [ + + ][ + - ]: 88 : if ( (SwFlowFrm::IsMoveBwdJump() || !IsPrevObjMove()))
[ + - ]
83 : : {
84 : : // Floating back a frm uses a bit of time unfortunately.
85 : : // The most common case is the following: The Frm wants to float to
86 : : // somewhere where the FixSize is the same that the Frm itself has already.
87 : : // In that case it's pretty easy to check if the Frm has enough space
88 : : // for it's VarSize. If this is NOT the case, we already know that
89 : : // we don't need to move.
90 : : // The Frm checks itself whether it has enough space - respecting the fact
91 : : // that it could probably split itself if needed.
92 : : // If, however, the FixSize differs from the Frm or there are Flys involved
93 : : // (either in the old or the new position), we don't need to check anything,
94 : : // and we have to move the Frm just to see what happens - if there's
95 : : // some space available to do it, that is.
96 : :
97 : : // The FixSize of the surroundings of Cntnts is always the width.
98 : :
99 : : // If we moved more than one sheet back (for example jumping over empty
100 : : // pages), we have to move either way. Otherwise, if the Frm doesn't fit
101 : : // into the page, empty pages wouldn't be respected anymore.
102 : 88 : sal_uInt8 nMoveAnyway = 0;
103 : 88 : SwPageFrm * const pNewPage = pNewUpper->FindPageFrm();
104 : 88 : SwPageFrm *pOldPage = FindPageFrm();
105 : :
106 [ + + ]: 88 : if ( SwFlowFrm::IsMoveBwdJump() )
107 : 28 : return sal_True;
108 : :
109 [ - + ][ # # ]: 60 : if( IsInFtn() && IsInSct() )
[ - + ]
110 : : {
111 : 0 : SwFtnFrm* pFtn = FindFtnFrm();
112 : 0 : SwSectionFrm* pMySect = pFtn->FindSctFrm();
113 [ # # ][ # # ]: 0 : if( pMySect && pMySect->IsFtnLock() )
[ # # ]
114 : : {
115 : 0 : SwSectionFrm *pSect = pNewUpper->FindSctFrm();
116 [ # # ][ # # ]: 0 : while( pSect && pSect->IsInFtn() )
[ # # ]
117 : 0 : pSect = pSect->GetUpper()->FindSctFrm();
118 : : OSL_ENSURE( pSect, "Escaping footnote" );
119 [ # # ]: 0 : if( pSect != pMySect )
120 : 0 : return sal_False;
121 : : }
122 : : }
123 [ - + ][ # # ]: 60 : SWRECTFN( this )
[ # # ][ - + ]
124 [ - + ][ # # ]: 60 : SWRECTFNX( pNewUpper )
[ # # ][ - + ]
125 [ + - ][ + + ]: 120 : if( Abs( (pNewUpper->Prt().*fnRectX->fnGetWidth)() -
126 [ + - ]: 60 : (GetUpper()->Prt().*fnRect->fnGetWidth)() ) > 1 ) {
127 : : // In this case, only a _WouldFit with relocating is possible
128 : : // TODO after translating the comment: what did the original german "umhaengen"
129 : : // mean? What does actually make sense in context of the code here?
130 : 2 : nMoveAnyway = 2;
131 : : }
132 : :
133 : : // OD 2004-05-26 #i25904# - do *not* move backward,
134 : : // if <nMoveAnyway> equals 3 and no space is left in new upper.
135 : 60 : nMoveAnyway |= BwdMoveNecessary( pOldPage, Frm() );
136 : : {
137 [ + - ][ + - ]: 60 : const IDocumentSettingAccess* pIDSA = pNewPage->GetFmt()->getIDocumentSettingAccess();
138 : 60 : SwTwips nSpace = 0;
139 : 60 : SwRect aRect( pNewUpper->Prt() );
140 : 60 : aRect.Pos() += pNewUpper->Frm().Pos();
141 : 60 : const SwFrm *pPrevFrm = pNewUpper->Lower();
142 [ + + ]: 526 : while ( pPrevFrm )
143 : : {
144 [ + - ][ + - ]: 466 : SwTwips nNewTop = (pPrevFrm->Frm().*fnRectX->fnGetBottom)();
145 : : // OD 2004-03-01 #106629#:
146 : : // consider lower spacing of last frame in a table cell
147 : : {
148 : : // check, if last frame is inside table and if it includes
149 : : // its lower spacing.
150 [ + + ][ + - ]: 466 : if ( !pPrevFrm->GetNext() && pPrevFrm->IsInTab() &&
[ - + ][ # # ]
[ - + ]
151 [ # # ]: 0 : pIDSA->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) )
152 : : {
153 : 0 : const SwFrm* pLastFrm = pPrevFrm;
154 : : // if last frame is a section, take its last content
155 [ # # ]: 0 : if ( pPrevFrm->IsSctFrm() )
156 : : {
157 [ # # ]: 0 : pLastFrm = static_cast<const SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
158 [ # # ][ # # ]: 0 : if ( pLastFrm &&
[ # # ]
159 [ # # ][ # # ]: 0 : pLastFrm->FindTabFrm() != pPrevFrm->FindTabFrm() )
160 : : {
161 [ # # ]: 0 : pLastFrm = pLastFrm->FindTabFrm();
162 : : }
163 : : }
164 : :
165 [ # # ]: 0 : if ( pLastFrm )
166 : : {
167 [ # # ]: 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pLastFrm );
168 [ # # ]: 0 : const SwBorderAttrs& rAttrs = *aAccess.Get();
169 [ # # ]: 0 : nNewTop -= rAttrs.GetULSpace().GetLower();
170 : : }
171 : : }
172 : : }
173 [ + - ][ + - ]: 466 : (aRect.*fnRectX->fnSetTop)( nNewTop );
174 : :
175 : 466 : pPrevFrm = pPrevFrm->GetNext();
176 : : }
177 : :
178 [ + - ]: 60 : nMoveAnyway |= BwdMoveNecessary( pNewPage, aRect);
179 : :
180 : : //determine space left in new upper frame
181 [ + - ][ + - ]: 60 : nSpace = (aRect.*fnRectX->fnGetHeight)();
182 : 60 : const ViewShell *pSh = pNewUpper->getRootFrm()->GetCurrShell();
183 [ + - ][ + - : 262 : if ( IsInFtn() ||
+ - + - ]
[ + + + +
+ - + - -
+ ][ + + ]
[ + - ]
184 : 60 : (pSh && pSh->GetViewOptions()->getBrowseMode()) ||
185 : 60 : pNewUpper->IsCellFrm() ||
186 [ + - ]: 76 : ( pNewUpper->IsInSct() && ( pNewUpper->IsSctFrm() ||
187 : 2 : ( pNewUpper->IsColBodyFrm() &&
188 : 2 : !pNewUpper->GetUpper()->GetPrev() &&
189 : 2 : !pNewUpper->GetUpper()->GetNext() ) ) ) )
190 [ + - ]: 14 : nSpace += pNewUpper->Grow( LONG_MAX, sal_True );
191 : :
192 [ + - ]: 60 : if ( nMoveAnyway < 3 )
193 : : {
194 [ + - ]: 60 : if ( nSpace )
195 : : {
196 : : // Not respecting footnotes which are stuck to the paragraph:
197 : : // This would require extremely confusing code, regarding the widths
198 : : // and Flys, that in turn influence the footnotes, ...
199 : :
200 : : // _WouldFit can only be used if the width is the same and ONLY
201 : : // with self-anchored Flys.
202 : :
203 : : // _WouldFit can also be used if ONLY Flys anchored somewhere else are present.
204 : : // In this case, the width doesn't even matter, because we're running a TestFormat
205 : : // in the new surrounding.
206 : : const sal_uInt8 nBwdMoveNecessaryResult =
207 [ + - ]: 60 : BwdMoveNecessary( pNewPage, aRect);
208 : : const bool bObjsInNewUpper( nBwdMoveNecessaryResult == 2 ||
209 [ + - ][ - + ]: 60 : nBwdMoveNecessaryResult == 3 );
210 : :
211 : : return _WouldFit( nSpace, pNewUpper, nMoveAnyway == 2,
212 [ + - ]: 60 : bObjsInNewUpper );
213 : : }
214 : : // It's impossible for _WouldFit to return a usable result if
215 : : // we have a fresh multi-column section - so we really have to
216 : : // float back
217 [ # # ][ # # ]: 0 : else if( pNewUpper->IsInSct() && pNewUpper->IsColBodyFrm() &&
[ # # ][ # #
# # # # ]
[ # # ]
218 [ # # ][ # # ]: 0 : !(pNewUpper->Prt().*fnRectX->fnGetWidth)() &&
219 : 0 : ( pNewUpper->GetUpper()->GetPrev() ||
220 : 0 : pNewUpper->GetUpper()->GetNext() ) )
221 : 0 : return sal_True;
222 : : else
223 : 0 : return sal_False; // No space. No sense in floating back
224 : : }
225 : : else
226 : : {
227 : : // OD 2004-05-26 #i25904# - check for space left in new upper
228 [ # # ]: 0 : if ( nSpace )
229 : 0 : return sal_True;
230 : : else
231 : 60 : return sal_False;
232 : : }
233 : : }
234 : : }
235 : 88 : return sal_False;
236 : : }
237 : :
238 : : //------------------------------------------------------------------------
239 : : // Calc methods
240 : : //------------------------------------------------------------------------
241 : :
242 : : /*************************************************************************
243 : : |*
244 : : |* SwFrm::Prepare()
245 : : |*
246 : : |* Description: Prepares the Frm for "formatting" (MakeAll()).
247 : : |* This method serves to save stack space: To calculate the position
248 : : |* of the Frm we have to make sure that the positions of Upper and Prev
249 : : |* respectively are valid. This may require a recursive call (a loop
250 : : |* would be quite expensive, as it's not required very often).
251 : : |* Every call of MakeAll requires around 500 bytes on the stack - you
252 : : |* easily see where this leads. _Prepare requires only a little bit of
253 : : |* stack space, so the recursive call should not be a problem here.
254 : : |* Another advantage is that one nice day, _Prepare and with it
255 : : |* the formatting of predecessors could be avoided. Then it could
256 : : |* probably be possible to jump "quickly" to the document's end.
257 : : |*
258 : : |*************************************************************************/
259 : : // Two little friendships form a secret society
260 : 2043 : inline void PrepareLock( SwFlowFrm *pTab )
261 : : {
262 : 2043 : pTab->LockJoin();
263 : 2043 : }
264 : 1039 : inline void PrepareUnlock( SwFlowFrm *pTab )
265 : : {
266 : 1039 : pTab->UnlockJoin();
267 : :
268 : 1039 : }
269 : :
270 : : // hopefully, one day this function simply will return 'false'
271 : 52821 : bool lcl_IsCalcUpperAllowed( const SwFrm& rFrm )
272 : : {
273 : 52821 : return !rFrm.GetUpper()->IsSctFrm() &&
274 : 51889 : !rFrm.GetUpper()->IsFooterFrm() &&
275 : : // #i23129#, #i36347# - no format of upper Writer fly frame
276 : 51795 : !rFrm.GetUpper()->IsFlyFrm() &&
277 [ + - ]: 54527 : !( rFrm.GetUpper()->IsTabFrm() && rFrm.GetUpper()->GetUpper()->IsInTab() ) &&
278 [ + + ][ + - ]: 211032 : !( rFrm.IsTabFrm() && rFrm.GetUpper()->IsInTab() );
[ + + + +
+ + + + ]
279 : : }
280 : :
281 : 32739 : void SwFrm::PrepareMake()
282 : : {
283 : 32739 : StackHack aHack;
284 [ + + ]: 32739 : if ( GetUpper() )
285 : : {
286 [ + - ][ + + ]: 26442 : if ( lcl_IsCalcUpperAllowed( *this ) )
287 [ + - ]: 25746 : GetUpper()->Calc();
288 : : OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
289 [ - + ]: 26442 : if ( !GetUpper() )
290 : : return;
291 : :
292 : 26442 : const sal_Bool bCnt = IsCntntFrm();
293 : 26442 : const sal_Bool bTab = IsTabFrm();
294 [ + - ]: 26442 : sal_Bool bNoSect = IsInSct();
295 : 26442 : sal_Bool bOldTabLock = sal_False, bFoll = sal_False;
296 [ + + ][ + - ]: 26442 : SwFlowFrm* pThis = bCnt ? (SwCntntFrm*)this : NULL;
[ + - ]
297 : :
298 [ + + ]: 26442 : if ( bTab )
299 : : {
300 : 2043 : pThis = (SwTabFrm*)this;
301 : 2043 : bOldTabLock = ((SwTabFrm*)this)->IsJoinLocked();
302 : 2043 : ::PrepareLock( (SwTabFrm*)this );
303 : 2043 : bFoll = pThis->IsFollow();
304 : : }
305 [ + + ]: 24399 : else if( IsSctFrm() )
306 : : {
307 : 225 : pThis = (SwSectionFrm*)this;
308 : 225 : bFoll = pThis->IsFollow();
309 : 225 : bNoSect = sal_False;
310 : : }
311 [ + + ]: 25804 : else if ( bCnt && sal_True == (bFoll = pThis->IsFollow()) &&
[ + + + + ]
[ + + ]
312 : 1630 : GetPrev() )
313 : : {
314 : : //Do not follow the chain when we need only one instance
315 [ + - ]: 63 : const SwTxtFrm* pMaster = ((SwCntntFrm*)this)->FindMaster();
316 [ + - ][ + - ]: 63 : if ( pMaster && pMaster->IsLocked() )
[ + - ]
317 : : {
318 [ + - ]: 63 : MakeAll();
319 : : return;
320 : : }
321 : : }
322 : :
323 : : // #i44049# - no format of previous frame, if current
324 : : // frame is a table frame and its previous frame wants to keep with it.
325 : : const bool bFormatPrev = !bTab ||
326 : 2043 : !GetPrev() ||
327 [ + + + + ]: 28422 : !GetPrev()->GetAttrSet()->GetKeep().GetValue();
[ + - ][ + - ]
[ + - ]
328 [ + - ]: 26379 : if ( bFormatPrev )
329 : : {
330 : 26379 : SwFrm *pFrm = GetUpper()->Lower();
331 [ + + ]: 44886 : while ( pFrm != this )
332 : : {
333 : : OSL_ENSURE( pFrm, ":-( Layout unstable (this not found)." );
334 [ - + ]: 18507 : if ( !pFrm )
335 : : return; //Oioioioi ...
336 : :
337 [ + + ]: 18507 : if ( !pFrm->IsValid() )
338 : : {
339 : : // A small interference that hopefully improves on the stability:
340 : : // If I'm Follow AND neighbor of a Frm before me, it would delete
341 : : // me when formatting. This as you can see could easily become a
342 : : // confusing situation that we want to avoid.
343 [ - + ][ # # ]: 693 : if ( bFoll && pFrm->IsFlowFrm() &&
[ # # ][ - + ]
344 [ # # ][ # # ]: 0 : (SwFlowFrm::CastFlowFrm(pFrm))->IsAnFollow( pThis ) )
345 : 0 : break;
346 : :
347 : : //MA: 24. Mar. 94, Calc would run into a _Prepare again and cause the whole chain to
348 : : // be run again.
349 : : // pFrm->Calc();
350 [ + - ]: 693 : pFrm->MakeAll();
351 [ + + ][ - + ]: 693 : if( IsSctFrm() && !((SwSectionFrm*)this)->GetSection() )
[ - + ]
352 : 0 : break;
353 : : }
354 : : // With CntntFrms, the chain may be broken while walking through
355 : : // it. Therefore we have to figure out the follower in a bit more
356 : : // complicated way. However, I'll HAVE to get back to myself
357 : : // sometime again.
358 [ + - ]: 18507 : pFrm = pFrm->FindNext();
359 : :
360 : : // If we started out in a SectionFrm, it might have happened that
361 : : // we landed in a Section Follow via the MakeAll calls.
362 : : // FindNext only gives us the SectionFrm, not it's content - we
363 : : // won't find ourselves anymore!
364 [ + + ][ + - ]: 18507 : if( bNoSect && pFrm && pFrm->IsSctFrm() )
[ - + ][ - + ]
365 : : {
366 [ # # ]: 0 : SwFrm* pCnt = ((SwSectionFrm*)pFrm)->ContainsAny();
367 [ # # ]: 0 : if( pCnt )
368 : 0 : pFrm = pCnt;
369 : : }
370 : : }
371 : : OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone II)." );
372 [ - + ]: 26379 : if ( !GetUpper() )
373 : : return;
374 : :
375 [ + - ][ + + ]: 26379 : if ( lcl_IsCalcUpperAllowed( *this ) )
376 [ + - ]: 25683 : GetUpper()->Calc();
377 : :
378 : : OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone III)." );
379 : : }
380 : :
381 [ + + ][ + + ]: 26379 : if ( bTab && !bOldTabLock )
382 : 1039 : ::PrepareUnlock( (SwTabFrm*)this );
383 : : }
384 [ + - ][ + + ]: 32739 : MakeAll();
385 : : }
386 : :
387 : 10486 : void SwFrm::OptPrepareMake()
388 : : {
389 : : // #i23129#, #i36347# - no format of upper Writer fly frame
390 [ + - ]: 20951 : if ( GetUpper() && !GetUpper()->IsFooterFrm() &&
[ + + + + ]
[ + + ]
391 : 10465 : !GetUpper()->IsFlyFrm() )
392 : : {
393 : 9304 : GetUpper()->Calc();
394 : : OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
395 [ - + ]: 9304 : if ( !GetUpper() )
396 : 10486 : return;
397 : : }
398 [ + + ][ + + ]: 10486 : if ( GetPrev() && !GetPrev()->IsValid() )
[ + + ]
399 : 24 : PrepareMake();
400 : : else
401 : : {
402 : 10462 : StackHack aHack;
403 [ + - ]: 10462 : MakeAll();
404 : : }
405 : : }
406 : :
407 : :
408 : :
409 : 696 : void SwFrm::PrepareCrsr()
410 : : {
411 : 696 : StackHack aHack;
412 [ + - ][ + + ]: 696 : if( GetUpper() && !GetUpper()->IsSctFrm() )
[ + + ]
413 : : {
414 [ + - ]: 522 : GetUpper()->PrepareCrsr();
415 [ + - ]: 522 : GetUpper()->Calc();
416 : :
417 : : OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
418 [ - + ]: 522 : if ( !GetUpper() )
419 : : return;
420 : :
421 : 522 : const sal_Bool bCnt = IsCntntFrm();
422 : 522 : const sal_Bool bTab = IsTabFrm();
423 [ + - ]: 522 : sal_Bool bNoSect = IsInSct();
424 : :
425 : 522 : sal_Bool bOldTabLock = sal_False, bFoll;
426 [ + + ][ + - ]: 522 : SwFlowFrm* pThis = bCnt ? (SwCntntFrm*)this : NULL;
[ + - ]
427 : :
428 [ - + ]: 522 : if ( bTab )
429 : : {
430 : 0 : bOldTabLock = ((SwTabFrm*)this)->IsJoinLocked();
431 : 0 : ::PrepareLock( (SwTabFrm*)this );
432 : 0 : pThis = (SwTabFrm*)this;
433 : : }
434 [ - + ]: 522 : else if( IsSctFrm() )
435 : : {
436 : 0 : pThis = (SwSectionFrm*)this;
437 : 0 : bNoSect = sal_False;
438 : : }
439 [ + + ][ + + ]: 522 : bFoll = pThis && pThis->IsFollow();
440 : :
441 : 522 : SwFrm *pFrm = GetUpper()->Lower();
442 [ + + ]: 1023 : while ( pFrm != this )
443 : : {
444 : : OSL_ENSURE( pFrm, ":-( Layout unstable (this not found)." );
445 [ - + ]: 501 : if ( !pFrm )
446 : : return; //Oioioioi ...
447 : :
448 [ - + ]: 501 : if ( !pFrm->IsValid() )
449 : : {
450 : : // A small interference that hopefully improves on the stability:
451 : : // If I'm Follow AND neighbor of a Frm before me, it would delete
452 : : // me when formatting. This as you can see could easily become a
453 : : // confusing situation that we want to avoid.
454 [ # # ][ # # ]: 0 : if ( bFoll && pFrm->IsFlowFrm() &&
[ # # ][ # # ]
455 [ # # ][ # # ]: 0 : (SwFlowFrm::CastFlowFrm(pFrm))->IsAnFollow( pThis ) )
456 : 0 : break;
457 : :
458 [ # # ]: 0 : pFrm->MakeAll();
459 : : }
460 : : // With CntntFrms, the chain may be broken while walking through
461 : : // it. Therefore we have to figure out the follower in a bit more
462 : : // complicated way. However, I'll HAVE to get back to myself
463 : : // sometime again.
464 [ + - ]: 501 : pFrm = pFrm->FindNext();
465 [ - + ][ # # ]: 501 : if( bNoSect && pFrm && pFrm->IsSctFrm() )
[ # # ][ - + ]
466 : : {
467 [ # # ]: 0 : SwFrm* pCnt = ((SwSectionFrm*)pFrm)->ContainsAny();
468 [ # # ]: 0 : if( pCnt )
469 : 0 : pFrm = pCnt;
470 : : }
471 : : }
472 : : OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone II)." );
473 [ - + ]: 522 : if ( !GetUpper() )
474 : : return;
475 : :
476 [ + - ]: 522 : GetUpper()->Calc();
477 : :
478 : : OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone III)." );
479 : :
480 [ - + ][ # # ]: 522 : if ( bTab && !bOldTabLock )
481 : 0 : ::PrepareUnlock( (SwTabFrm*)this );
482 : : }
483 [ + - ][ + - ]: 696 : Calc();
484 : : }
485 : :
486 : : /*************************************************************************
487 : : |*
488 : : |* SwFrm::MakePos()
489 : : |*
490 : : |*************************************************************************/
491 : :
492 : : // Here we return GetPrev(); however we will overlook empty SectionFrms
493 : 110705 : SwFrm* lcl_Prev( SwFrm* pFrm, sal_Bool bSectPrv = sal_True )
494 : : {
495 : 110705 : SwFrm* pRet = pFrm->GetPrev();
496 [ + - ][ + + ]: 111563 : if( !pRet && pFrm->GetUpper() && pFrm->GetUpper()->IsSctFrm() &&
[ + + + + ]
[ + + ][ + + ]
497 : 858 : bSectPrv && !pFrm->IsColumnFrm() )
498 : 658 : pRet = pFrm->GetUpper()->GetPrev();
499 [ + + ]: 112003 : while( pRet && pRet->IsSctFrm() &&
[ + + + + ]
[ + + ]
500 : 1046 : !((SwSectionFrm*)pRet)->GetSection() )
501 : 252 : pRet = pRet->GetPrev();
502 : 110705 : return pRet;
503 : : }
504 : :
505 : 0 : SwFrm* lcl_NotHiddenPrev( SwFrm* pFrm )
506 : : {
507 : 0 : SwFrm *pRet = pFrm;
508 [ # # ][ # # : 0 : do
# # # # ]
509 : : {
510 : 0 : pRet = lcl_Prev( pRet );
511 : 0 : } while ( pRet && pRet->IsTxtFrm() && ((SwTxtFrm*)pRet)->IsHiddenNow() );
512 : 0 : return pRet;
513 : : }
514 : :
515 : 22870 : void SwFrm::MakePos()
516 : : {
517 [ + + ]: 22870 : if ( !bValidPos )
518 : : {
519 : 22773 : bValidPos = sal_True;
520 : 22773 : sal_Bool bUseUpper = sal_False;
521 : 22773 : SwFrm* pPrv = lcl_Prev( this );
522 [ + + ][ + + : 34946 : if ( pPrv &&
+ + + - ]
523 : 8552 : ( !pPrv->IsCntntFrm() ||
524 : 3621 : ( ((SwCntntFrm*)pPrv)->GetFollow() != this ) )
525 : : )
526 : : {
527 [ + - + + : 33840 : if ( !StackHack::IsLocked() &&
+ + + + +
+ ][ + + ]
528 : 8986 : ( !IsInSct() || IsSctFrm() ) &&
529 : 8254 : !pPrv->IsSctFrm() &&
530 : 8048 : !pPrv->GetAttrSet()->GetKeep().GetValue()
531 : : )
532 : : {
533 : 7956 : pPrv->Calc(); // This may cause Prev to vanish!
534 : : }
535 [ - + ]: 596 : else if ( pPrv->Frm().Top() == 0 )
536 : : {
537 : 0 : bUseUpper = sal_True;
538 : : }
539 : : }
540 : :
541 : 22773 : pPrv = lcl_Prev( this, sal_False );
542 : 22773 : sal_uInt16 nMyType = GetType();
543 [ + - ][ + + ]: 22773 : SWRECTFN( ( IsCellFrm() && GetUpper() ? GetUpper() : this ) )
[ + - ][ + + ]
[ + - ][ + + ]
[ + - ][ - + ]
[ - + ][ + + ]
544 [ + - ][ + + ]: 22773 : if ( !bUseUpper && pPrv )
545 : : {
546 : 8454 : aFrm.Pos( pPrv->Frm().Pos() );
547 [ + + ]: 8454 : if( FRM_NEIGHBOUR & nMyType )
548 : : {
549 : 2724 : sal_Bool bR2L = IsRightToLeft();
550 [ - + ]: 2724 : if( bR2L )
551 [ # # ]: 0 : (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() -
552 [ # # ][ # # ]: 0 : (aFrm.*fnRect->fnGetWidth)() );
553 : : else
554 [ + - ]: 2724 : (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() +
555 [ + - ][ + - ]: 5448 : (pPrv->Frm().*fnRect->fnGetWidth)() );
556 : :
557 : : // cells may now leave their uppers
558 [ - + ][ # # ]: 2724 : if( bVert && FRM_CELL & nMyType && !bReverse )
[ # # ]
559 : 0 : aFrm.Pos().X() -= aFrm.Width() -pPrv->Frm().Width();
560 : : }
561 [ - + ][ # # ]: 5730 : else if( bVert && FRM_NOTE_VERT & nMyType )
562 : : {
563 [ # # ]: 0 : if( bReverse )
564 : 0 : aFrm.Pos().X() += pPrv->Frm().Width();
565 : : else
566 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
567 : : {
568 [ # # ]: 0 : if ( bVertL2R )
569 : 0 : aFrm.Pos().X() += pPrv->Frm().Width();
570 : : else
571 : 0 : aFrm.Pos().X() -= aFrm.Width();
572 : : }
573 : : }
574 : : else
575 : 8454 : aFrm.Pos().Y() += pPrv->Frm().Height();
576 : : }
577 [ + - ]: 14319 : else if ( GetUpper() )
578 : : {
579 : : // OD 15.10.2002 #103517# - add safeguard for <SwFooterFrm::Calc()>
580 : : // If parent frame is a footer frame and its <ColLocked()>, then
581 : : // do *not* calculate it.
582 : : // NOTE: Footer frame is <ColLocked()> during its
583 : : // <FormatSize(..)>, which is called from <Format(..)>, which
584 : : // is called from <MakeAll()>, which is called from <Calc()>.
585 : : // #i56850#
586 : : // - no format of upper Writer fly frame, which is anchored
587 : : // at-paragraph or at-character.
588 [ + + + + : 68273 : if ( !GetUpper()->IsTabFrm() &&
+ + + - +
+ ][ + + ]
589 [ + - ]: 14679 : !( IsTabFrm() && GetUpper()->IsInTab() ) &&
590 : 13656 : !GetUpper()->IsSctFrm() &&
591 [ + + ]: 26574 : !dynamic_cast<SwFlyAtCntFrm*>(GetUpper()) &&
592 : 13088 : !( GetUpper()->IsFooterFrm() &&
593 [ + + ]: 68 : GetUpper()->IsColLocked() )
594 : : )
595 : : {
596 : 13041 : GetUpper()->Calc();
597 : : }
598 : 14319 : pPrv = lcl_Prev( this, sal_False );
599 [ - + ][ + - ]: 14319 : if ( !bUseUpper && pPrv )
600 : : {
601 : 0 : aFrm.Pos( pPrv->Frm().Pos() );
602 [ # # ]: 0 : if( FRM_NEIGHBOUR & nMyType )
603 : : {
604 : 0 : sal_Bool bR2L = IsRightToLeft();
605 [ # # ]: 0 : if( bR2L )
606 [ # # ]: 0 : (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() -
607 [ # # ][ # # ]: 0 : (aFrm.*fnRect->fnGetWidth)() );
608 : : else
609 [ # # ]: 0 : (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() +
610 [ # # ][ # # ]: 0 : (pPrv->Frm().*fnRect->fnGetWidth)() );
611 : :
612 : : // cells may now leave their uppers
613 [ # # ][ # # ]: 0 : if( bVert && FRM_CELL & nMyType && !bReverse )
[ # # ]
614 : 0 : aFrm.Pos().X() -= aFrm.Width() -pPrv->Frm().Width();
615 : : }
616 [ # # ][ # # ]: 0 : else if( bVert && FRM_NOTE_VERT & nMyType )
617 : : {
618 [ # # ]: 0 : if( bReverse )
619 : 0 : aFrm.Pos().X() += pPrv->Frm().Width();
620 : : else
621 : 0 : aFrm.Pos().X() -= aFrm.Width();
622 : : }
623 : : else
624 : 0 : aFrm.Pos().Y() += pPrv->Frm().Height();
625 : : }
626 : : else
627 : : {
628 : 14319 : aFrm.Pos( GetUpper()->Frm().Pos() );
629 : 14319 : aFrm.Pos() += GetUpper()->Prt().Pos();
630 [ - + ][ - + ]: 14319 : if( FRM_NEIGHBOUR & nMyType && IsRightToLeft() )
[ + + ]
631 : : {
632 [ # # ]: 0 : if( bVert )
633 : 0 : aFrm.Pos().Y() += GetUpper()->Prt().Height()
634 : 0 : - aFrm.Height();
635 : : else
636 : 0 : aFrm.Pos().X() += GetUpper()->Prt().Width()
637 : 0 : - aFrm.Width();
638 : : }
639 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
640 [ + + ][ + - ]: 14319 : else if( bVert && !bVertL2R && FRM_NOTE_VERT & nMyType && !bReverse )
[ + + ][ + - ]
641 : 14319 : aFrm.Pos().X() -= aFrm.Width() - GetUpper()->Prt().Width();
642 : : }
643 : : }
644 : : else
645 : 0 : aFrm.Pos().X() = aFrm.Pos().Y() = 0;
646 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
647 [ + + ][ + + ]: 22773 : if( IsBodyFrm() && bVert && !bVertL2R && !bReverse && GetUpper() )
[ + - ][ + - ]
[ + - ][ + + ]
648 : 2 : aFrm.Pos().X() += GetUpper()->Prt().Width() - aFrm.Width();
649 : 22773 : bValidPos = sal_True;
650 : : }
651 : 22870 : }
652 : :
653 : : /*************************************************************************
654 : : |*
655 : : |* SwPageFrm::MakeAll()
656 : : |*
657 : : |*************************************************************************/
658 : : // #i28701# - new type <SwSortedObjs>
659 : 0 : void lcl_CheckObjects( SwSortedObjs* pSortedObjs, SwFrm* pFrm, long& rBot )
660 : : {
661 : : // And then there can be paragraph anchored frames that sit below their paragraph.
662 : 0 : long nMax = 0;
663 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < pSortedObjs->Count(); ++i )
664 : : {
665 : : // #i28701# - consider changed type of <SwSortedObjs>
666 : : // entries.
667 : 0 : SwAnchoredObject* pObj = (*pSortedObjs)[i];
668 : 0 : long nTmp = 0;
669 [ # # ]: 0 : if ( pObj->ISA(SwFlyFrm) )
670 : : {
671 [ # # ]: 0 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
672 [ # # # # : 0 : if( pFly->Frm().Top() != FAR_AWAY &&
# # # # ]
[ # # ]
673 : 0 : ( pFrm->IsPageFrm() ? pFly->IsFlyLayFrm() :
674 : 0 : ( pFly->IsFlyAtCntFrm() &&
675 : 0 : ( pFrm->IsBodyFrm() ? pFly->GetAnchorFrm()->IsInDocBody() :
676 [ # # ]: 0 : pFly->GetAnchorFrm()->IsInFtn() ) ) ) )
[ # # # # ]
677 : : {
678 : 0 : nTmp = pFly->Frm().Bottom();
679 : : }
680 : : }
681 : : else
682 : 0 : nTmp = pObj->GetObjRect().Bottom();
683 : 0 : nMax = Max( nTmp, nMax );
684 : : }
685 : 0 : ++nMax; // Lower edge vs. height!
686 : 0 : rBot = Max( rBot, nMax );
687 : 0 : }
688 : :
689 : 3069 : void SwPageFrm::MakeAll()
690 : : {
691 : : PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
692 : :
693 : 3069 : const SwRect aOldRect( Frm() ); // Adjust root size
694 [ + - ]: 3069 : const SwLayNotify aNotify( this ); // takes care of the notification in the dtor
695 : 3069 : SwBorderAttrAccess *pAccess = 0;
696 : 3069 : const SwBorderAttrs*pAttrs = 0;
697 : :
698 [ + + ][ + + ]: 6138 : while ( !bValidPos || !bValidSize || !bValidPrtArea )
[ + + ][ + + ]
699 : : {
700 [ + + ]: 3069 : if ( !bValidPos )
701 : : {
702 : : // PAGES01
703 : 2887 : bValidPos = sal_True; // positioning of the pages is taken care of by the root frame
704 : : }
705 : :
706 [ + + ][ + + ]: 3069 : if ( !bValidSize || !bValidPrtArea )
707 : : {
708 [ + + ]: 2971 : if ( IsEmptyPage() )
709 : : {
710 : 3 : Frm().Width( 0 ); Prt().Width( 0 );
711 : 3 : Frm().Height( 0 ); Prt().Height( 0 );
712 : 3 : Prt().Left( 0 ); Prt().Top( 0 );
713 : 3 : bValidSize = bValidPrtArea = sal_True;
714 : : }
715 : : else
716 : : {
717 [ + - ]: 2968 : if ( !pAccess )
718 : : {
719 [ + - ][ + - ]: 2968 : pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this );
720 [ + - ]: 2968 : pAttrs = pAccess->Get();
721 : : }
722 : : // In BrowseView, we use fixed settings
723 : 2968 : ViewShell *pSh = getRootFrm()->GetCurrShell();
724 [ + + ][ + + ]: 2968 : if ( pSh && pSh->GetViewOptions()->getBrowseMode() )
[ + - ]
725 : : {
726 [ + - ][ + - ]: 190 : const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
727 [ + - ]: 190 : const long nTop = pAttrs->CalcTopLine() + aBorder.Height();
728 [ + - ]: 190 : const long nBottom = pAttrs->CalcBottomLine()+ aBorder.Height();
729 : :
730 [ + - ][ + + ]: 190 : long nWidth = GetUpper() ? ((SwRootFrm*)GetUpper())->GetBrowseWidth() : 0;
731 [ + - ][ + + ]: 190 : if ( nWidth < pSh->GetBrowseWidth() )
732 [ + - ]: 182 : nWidth = pSh->GetBrowseWidth();
733 : 190 : nWidth += + 2 * aBorder.Width();
734 : :
735 : 190 : nWidth = Max( nWidth, 2L * aBorder.Width() + 4L*MM50 );
736 : 190 : Frm().Width( nWidth );
737 : :
738 [ + - ]: 190 : SwLayoutFrm *pBody = FindBodyCont();
739 [ + + ][ + + ]: 190 : if ( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
[ - + ][ - + ]
740 : : {
741 : : // Columns have a fixed height
742 : 0 : Frm().Height( pAttrs->GetSize().Height() );
743 : : }
744 : : else
745 : : {
746 : : // In pages without columns, the content defines the size.
747 : 190 : long nBot = Frm().Top() + nTop;
748 : 190 : SwFrm *pFrm = Lower();
749 [ + + ]: 376 : while ( pFrm )
750 : : {
751 : 186 : long nTmp = 0;
752 [ + - ]: 186 : SwFrm *pCnt = ((SwLayoutFrm*)pFrm)->ContainsAny();
753 [ + + ][ - + ]: 368 : while ( pCnt && (pCnt->GetUpper() == pFrm ||
[ # # ][ + + ]
754 [ # # ]: 0 : ((SwLayoutFrm*)pFrm)->IsAnLower( pCnt )))
755 : : {
756 : 182 : nTmp += pCnt->Frm().Height();
757 [ - + ]: 364 : if( pCnt->IsTxtFrm() &&
[ + - - + ]
758 : 182 : ((SwTxtFrm*)pCnt)->IsUndersized() )
759 [ # # ]: 0 : nTmp += ((SwTxtFrm*)pCnt)->GetParHeight()
760 : 0 : - pCnt->Prt().Height();
761 [ - + # # ]: 182 : else if( pCnt->IsSctFrm() &&
[ - + ]
762 : 0 : ((SwSectionFrm*)pCnt)->IsUndersized() )
763 [ # # ]: 0 : nTmp += ((SwSectionFrm*)pCnt)->Undersize();
764 [ + - ]: 182 : pCnt = pCnt->FindNext();
765 : : }
766 : : // OD 29.10.2002 #97265# - consider invalid body frame properties
767 [ + - + - : 558 : if ( pFrm->IsBodyFrm() &&
- + # # ]
[ - + ]
768 : 186 : ( !pFrm->GetValidSizeFlag() ||
769 : 186 : !pFrm->GetValidPrtAreaFlag() ) &&
770 : 0 : ( pFrm->Frm().Height() < pFrm->Prt().Height() )
771 : : )
772 : : {
773 : 0 : nTmp = Min( nTmp, pFrm->Frm().Height() );
774 : : }
775 : : else
776 : : {
777 : : // OD 30.10.2002 #97265# - assert invalid lower property
778 : : OSL_ENSURE( !(pFrm->Frm().Height() < pFrm->Prt().Height()),
779 : : "SwPageFrm::MakeAll(): Lower with frame height < printing height" );
780 : 186 : nTmp += pFrm->Frm().Height() - pFrm->Prt().Height();
781 : : }
782 [ - + ]: 186 : if ( !pFrm->IsBodyFrm() )
783 : 0 : nTmp = Min( nTmp, pFrm->Frm().Height() );
784 : 186 : nBot += nTmp;
785 : : // Here we check whether paragraph anchored objects
786 : : // protrude outside the Body/FtnCont.
787 [ - + ]: 186 : if( pSortedObjs && !pFrm->IsHeaderFrm() &&
[ # # # # ]
[ - + ]
788 : 0 : !pFrm->IsFooterFrm() )
789 [ # # ]: 0 : lcl_CheckObjects( pSortedObjs, pFrm, nBot );
790 : 186 : pFrm = pFrm->GetNext();
791 : : }
792 : 190 : nBot += nBottom;
793 : : // And the page anchored ones
794 [ - + ]: 190 : if ( pSortedObjs )
795 [ # # ]: 0 : lcl_CheckObjects( pSortedObjs, this, nBot );
796 : 190 : nBot -= Frm().Top();
797 : : // #i35143# - If second page frame
798 : : // exists, the first page doesn't have to fulfill the
799 : : // visible area.
800 [ + - ][ + - ]: 190 : if ( !GetPrev() && !GetNext() )
[ + - ]
801 : : {
802 : 190 : nBot = Max( nBot, pSh->VisArea().Height() );
803 : : }
804 : : // #i35143# - Assure, that the page
805 : : // doesn't exceed the defined browse height.
806 : 190 : Frm().Height( Min( nBot, BROWSE_HEIGHT ) );
807 : : }
808 [ + - ]: 190 : Prt().Left ( pAttrs->CalcLeftLine() + aBorder.Width() );
809 : 190 : Prt().Top ( nTop );
810 : 380 : Prt().Width( Frm().Width() - ( Prt().Left()
811 [ + - ]: 380 : + pAttrs->CalcRightLine() + aBorder.Width() ) );
812 : 190 : Prt().Height( Frm().Height() - (nTop + nBottom) );
813 : 190 : bValidSize = bValidPrtArea = sal_True;
814 : : }
815 : : else
816 : : { // Set FixSize. For pages, this is not done from Upper, but from
817 : : // the attribute.
818 : 2778 : Frm().SSize( pAttrs->GetSize() );
819 [ + - ]: 2778 : Format( pAttrs );
820 : : }
821 : : }
822 : : }
823 : : } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
824 [ + + ][ + - ]: 3069 : delete pAccess;
825 : :
826 : : // PAGES01
827 [ + + ][ + + ]: 3069 : if ( Frm() != aOldRect && GetUpper() )
[ + + ]
828 [ + - ]: 28 : static_cast<SwRootFrm*>(GetUpper())->CheckViewLayout( 0, 0 );
829 : :
830 : : OSL_ENSURE( !GetUpper() || GetUpper()->Prt().Width() >= aFrm.Width(),
831 [ + - ]: 3069 : "Upper (Root) must be wide enough to contain the widest page");
832 : 3069 : }
833 : :
834 : : /*************************************************************************
835 : : |*
836 : : |* SwLayoutFrm::MakeAll()
837 : : |*
838 : : |*************************************************************************/
839 : :
840 : :
841 : 10325 : void SwLayoutFrm::MakeAll()
842 : : {
843 : : PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
844 : :
845 : : // takes care of the notification in the dtor
846 [ + - ]: 10325 : const SwLayNotify aNotify( this );
847 [ + - ]: 10325 : sal_Bool bVert = IsVertical();
848 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
849 [ + + ][ - + ]: 10325 : SwRectFn fnRect = ( IsNeighbourFrm() == bVert )? fnRectHori : ( IsVertLR() ? fnRectVertL2R : fnRectVert );
850 : :
851 : 10325 : SwBorderAttrAccess *pAccess = 0;
852 : 10325 : const SwBorderAttrs*pAttrs = 0;
853 : :
854 [ + + ][ + + ]: 21202 : while ( !bValidPos || !bValidSize || !bValidPrtArea )
[ + + ][ + + ]
855 : : {
856 [ + + ]: 10877 : if ( !bValidPos )
857 [ + - ]: 10251 : MakePos();
858 : :
859 [ + - ]: 10877 : if ( GetUpper() )
860 : : {
861 : : // NEW TABLES
862 [ + - ][ - + ]: 10877 : if ( IsLeaveUpperAllowed() )
863 : : {
864 [ # # ]: 0 : if ( !bValidSize )
865 : 0 : bValidPrtArea = sal_False;
866 : : }
867 : : else
868 : : {
869 [ + + ]: 10877 : if ( !bValidSize )
870 : : {
871 : : // Set FixSize; VarSize is set by Format() after calculating the PrtArea
872 : 7085 : bValidPrtArea = sal_False;
873 : :
874 [ + - ][ + - ]: 7085 : SwTwips nPrtWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
875 [ + + ][ - + ]: 7085 : if( bVert && ( IsBodyFrm() || IsFtnContFrm() ) )
[ # # ][ + + ]
876 : : {
877 : 2 : SwFrm* pNxt = GetPrev();
878 [ - + ][ # # ]: 2 : while( pNxt && !pNxt->IsHeaderFrm() )
[ - + ]
879 : 0 : pNxt = pNxt->GetPrev();
880 [ - + ]: 2 : if( pNxt )
881 : 0 : nPrtWidth -= pNxt->Frm().Height();
882 : 2 : pNxt = GetNext();
883 [ - + ][ # # ]: 2 : while( pNxt && !pNxt->IsFooterFrm() )
[ - + ]
884 : 0 : pNxt = pNxt->GetNext();
885 [ - + ]: 2 : if( pNxt )
886 : 0 : nPrtWidth -= pNxt->Frm().Height();
887 : : }
888 : :
889 [ + - ][ + - ]: 7085 : const long nDiff = nPrtWidth - (Frm().*fnRect->fnGetWidth)();
890 : :
891 [ + + ][ + - ]: 7085 : if( IsNeighbourFrm() && IsRightToLeft() )
[ - + ][ - + ]
892 [ # # ][ # # ]: 0 : (Frm().*fnRect->fnSubLeft)( nDiff );
893 : : else
894 [ + - ][ + - ]: 7085 : (Frm().*fnRect->fnAddRight)( nDiff );
895 : : }
896 : : else
897 : : {
898 : : // Don't leave your upper
899 [ + - ][ + - ]: 3792 : const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
900 [ + - ][ + - ]: 3792 : if( (Frm().*fnRect->fnOverStep)( nDeadLine ) )
[ - + ]
901 : 0 : bValidSize = sal_False;
902 : : }
903 : : }
904 : : }
905 [ + + ][ + + ]: 10877 : if ( !bValidSize || !bValidPrtArea )
906 : : {
907 [ + + ]: 8964 : if ( !pAccess )
908 : : {
909 [ + - ][ + - ]: 8462 : pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this );
910 [ + - ]: 8462 : pAttrs = pAccess->Get();
911 : : }
912 [ + - ]: 8964 : Format( pAttrs );
913 : : }
914 : : } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
915 [ + + ][ + - ]: 10325 : delete pAccess;
[ + - ]
916 : 10325 : }
917 : :
918 : : /*************************************************************************
919 : : |*
920 : : |* SwCntntFrm::MakePrtArea()
921 : : |*
922 : : |*************************************************************************/
923 : 24341 : bool SwTxtNode::IsCollapse() const
924 : : {
925 [ + - ][ + + ]: 24341 : if ( GetDoc()->get( IDocumentSettingAccess::COLLAPSE_EMPTY_CELL_PARA ) && GetTxt().Len()==0 ) {
[ + + ]
926 : 18537 : sal_uLong nIdx=GetIndex();
927 : 18537 : const SwEndNode *pNdBefore=GetNodes()[nIdx-1]->GetEndNode();
928 : 18537 : const SwEndNode *pNdAfter=GetNodes()[nIdx+1]->GetEndNode();
929 : :
930 : : // The paragraph is collapsed only if the NdAfter is the end of a cell
931 : 18537 : bool bInTable = this->FindTableNode( ) != NULL;
932 : :
933 : 18537 : SwSortedObjs* pObjs = this->getLayoutFrm( GetDoc()->GetCurrentLayout() )->GetDrawObjs( );
934 [ + + ]: 18537 : sal_uInt32 nObjs = ( pObjs != NULL ) ? pObjs->Count( ) : 0;
935 : :
936 [ + + ][ + + ]: 18537 : if ( pNdBefore!=NULL && pNdAfter!=NULL && nObjs == 0 && bInTable ) {
[ + - ][ - + ]
937 : 0 : return true;
938 : : } else {
939 : 18537 : return false;
940 : : }
941 : : } else
942 : 24341 : return false;
943 : : }
944 : :
945 : 24857 : bool SwFrm::IsCollapse() const
946 : : {
947 [ + + ]: 24857 : if (IsTxtFrm()) {
948 : 24341 : const SwTxtFrm *pTxtFrm=(SwTxtFrm*)this;
949 : 24341 : const SwTxtNode *pTxtNode=pTxtFrm->GetTxtNode();
950 [ - + ][ - + ]: 24341 : if (pTxtNode && pTxtNode->IsCollapse()) {
[ + - ]
951 : 0 : return true;
952 : : } else {
953 : 24341 : return false;
954 : : }
955 : : } else {
956 : 24857 : return false;
957 : : }
958 : : }
959 : :
960 : 16158 : sal_Bool SwCntntFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
961 : : {
962 : 16158 : sal_Bool bSizeChgd = sal_False;
963 : :
964 [ + + ]: 16158 : if ( !bValidPrtArea )
965 : : {
966 : 15711 : bValidPrtArea = sal_True;
967 : :
968 [ + + ][ + - ]: 15711 : SWRECTFN( this )
[ - + ][ - + ]
969 : 15711 : const sal_Bool bTxtFrm = IsTxtFrm();
970 : 15711 : SwTwips nUpper = 0;
971 [ + + ][ + + ]: 15711 : if ( bTxtFrm && ((SwTxtFrm*)this)->IsHiddenNow() )
[ + + ]
972 : : {
973 [ - + ]: 260 : if ( ((SwTxtFrm*)this)->HasFollow() )
974 : 0 : ((SwTxtFrm*)this)->JoinFrm();
975 : :
976 [ + - ][ + + ]: 260 : if( (Prt().*fnRect->fnGetHeight)() )
977 : 42 : ((SwTxtFrm*)this)->HideHidden();
978 : 260 : Prt().Pos().X() = Prt().Pos().Y() = 0;
979 [ + - ][ + - ]: 260 : (Prt().*fnRect->fnSetWidth)( (Frm().*fnRect->fnGetWidth)() );
980 [ + - ]: 260 : (Prt().*fnRect->fnSetHeight)( 0 );
981 [ + - ]: 260 : nUpper = -( (Frm().*fnRect->fnGetHeight)() );
982 : : }
983 : : else
984 : : {
985 : : // Simplification: CntntFrms are always variable in height!
986 : :
987 : : // At the FixSize, the surrounding Frame enforces the size;
988 : : // the borders are simply subtracted.
989 : 15451 : const long nLeft = rAttrs.CalcLeft( this );
990 : 15451 : const long nRight = ((SwBorderAttrs&)rAttrs).CalcRight( this );
991 [ + - ]: 15451 : (this->*fnRect->fnSetXMargins)( nLeft, nRight );
992 : :
993 : 15451 : ViewShell *pSh = getRootFrm()->GetCurrShell();
994 : : SwTwips nWidthArea;
995 [ + - ][ + + : 33255 : if( pSh && 0!=(nWidthArea=(pSh->VisArea().*fnRect->fnGetWidth)()) &&
+ + + + ]
[ + + ][ + - ]
996 : 12782 : GetUpper()->IsPageBodyFrm() && // Not against for BodyFrms in Columns
997 : 5022 : pSh->GetViewOptions()->getBrowseMode() )
998 : : {
999 : : // Do not protrude the edge of the visible area. The page may be
1000 : : // wider, because there may be objects with excess width
1001 : : // (RootFrm::ImplCalcBrowseWidth())
1002 : 60 : long nMinWidth = 0;
1003 : :
1004 [ - + ][ # # ]: 60 : for (sal_uInt16 i = 0; GetDrawObjs() && i < GetDrawObjs()->Count();++i)
[ # # ][ - + ]
1005 : : {
1006 : : // #i28701# - consider changed type of
1007 : : // <SwSortedObjs> entries
1008 [ # # ]: 0 : SwAnchoredObject* pObj = (*GetDrawObjs())[i];
1009 [ # # ]: 0 : const SwFrmFmt& rFmt = pObj->GetFrmFmt();
1010 [ # # ][ # # ]: 0 : const sal_Bool bFly = pObj->ISA(SwFlyFrm);
1011 [ # # ][ # # ]: 0 : if ((bFly && (FAR_AWAY == pObj->GetObjRect().Width()))
[ # # # # ]
[ # # ]
[ # # # # ]
1012 [ # # ]: 0 : || rFmt.GetFrmSize().GetWidthPercent())
1013 : : {
1014 : 0 : continue;
1015 : : }
1016 : :
1017 [ # # ][ # # ]: 0 : if ( FLY_AS_CHAR == rFmt.GetAnchor().GetAnchorId() )
1018 : : {
1019 : : nMinWidth = Max( nMinWidth,
1020 [ # # ]: 0 : bFly ? rFmt.GetFrmSize().GetWidth()
1021 [ # # ][ # # ]: 0 : : pObj->GetObjRect().Width() );
[ # # ][ # # ]
1022 : : }
1023 : : }
1024 : :
1025 [ + - ][ + - ]: 60 : const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
1026 [ + - ][ - + ]: 60 : long nWidth = nWidthArea - 2 * ( IsVertical() ? aBorder.Height() : aBorder.Width() );
1027 [ + - ][ + - ]: 60 : nWidth -= (Prt().*fnRect->fnGetLeft)();
1028 [ + - ]: 60 : nWidth -= rAttrs.CalcRightLine();
1029 : 60 : nWidth = Max( nMinWidth, nWidth );
1030 : 60 : (Prt().*fnRect->fnSetWidth)( Min( nWidth,
1031 [ + - ][ + - ]: 60 : (Prt().*fnRect->fnGetWidth)() ) );
[ + - ][ + - ]
1032 : : }
1033 : :
1034 [ + - ][ + + ]: 15451 : if ( (Prt().*fnRect->fnGetWidth)() <= MINLAY )
1035 : : {
1036 : : // The PrtArea should already be at least MINLAY wide, matching the
1037 : : // minimal values of the UI
1038 : 116 : (Prt().*fnRect->fnSetWidth)( Min( long(MINLAY),
1039 [ + - ][ + - ]: 116 : (Frm().*fnRect->fnGetWidth)() ) );
1040 [ + - ]: 116 : SwTwips nTmp = (Frm().*fnRect->fnGetWidth)() -
1041 [ + - ]: 116 : (Prt().*fnRect->fnGetWidth)();
1042 [ - + ][ + - ]: 116 : if( (Prt().*fnRect->fnGetLeft)() > nTmp )
1043 [ # # ]: 0 : (Prt().*fnRect->fnSetLeft)( nTmp );
1044 : : }
1045 : :
1046 : : // The following rules apply for VarSize:
1047 : : // 1. The first entry of a chain has no top border
1048 : : // 2. There is never a bottom border
1049 : : // 3. The top border is the maximum of the distance
1050 : : // of Prev downwards and our own distance upwards
1051 : : // Those three rules apply when calculating spacings
1052 : : // that are given by UL- and LRSpace. There might be a spacing
1053 : : // in all directions however; this may be caused by borders
1054 : : // and / or shadows.
1055 : : // 4. The spacing for TextFrms corresponds to the interline lead,
1056 : : // at a minimum.
1057 : :
1058 : 15451 : nUpper = CalcUpperSpace( &rAttrs, NULL );
1059 : :
1060 : 15451 : SwTwips nLower = CalcLowerSpace( &rAttrs );
1061 [ - + ]: 15451 : if (IsCollapse()) {
1062 : 0 : nUpper=0;
1063 : 0 : nLower=0;
1064 : : }
1065 : :
1066 [ + - ][ + + ]: 15451 : (Prt().*fnRect->fnSetPosY)( (!bVert || bReverse) ? nUpper : nLower);
[ - + ]
1067 : 15451 : nUpper += nLower;
1068 [ + - ]: 15451 : nUpper -= (Frm().*fnRect->fnGetHeight)() -
1069 [ + - ]: 15451 : (Prt().*fnRect->fnGetHeight)();
1070 : : }
1071 : : // If there's a difference between old and new size, call Grow() or
1072 : : // Shrink() respectively.
1073 [ + + ]: 15711 : if ( nUpper )
1074 : : {
1075 [ + + ]: 355 : if ( nUpper > 0 )
1076 : 251 : GrowFrm( nUpper );
1077 : : else
1078 : 104 : ShrinkFrm( -nUpper );
1079 : 355 : bSizeChgd = sal_True;
1080 : : }
1081 : : }
1082 : 16158 : return bSizeChgd;
1083 : : }
1084 : :
1085 : : /*************************************************************************
1086 : : |*
1087 : : |* SwCntntFrm::MakeAll()
1088 : : |*
1089 : : |*************************************************************************/
1090 : :
1091 : : #define STOP_FLY_FORMAT 10
1092 : : // - loop prevention
1093 : : const int cnStopFormat = 15;
1094 : :
1095 : 0 : inline void ValidateSz( SwFrm *pFrm )
1096 : : {
1097 [ # # ]: 0 : if ( pFrm )
1098 : : {
1099 : 0 : pFrm->bValidSize = sal_True;
1100 : 0 : pFrm->bValidPrtArea = sal_True;
1101 : : }
1102 : 0 : }
1103 : :
1104 : 22553 : void SwCntntFrm::MakeAll()
1105 : : {
1106 : : OSL_ENSURE( GetUpper(), "no Upper?" );
1107 : : OSL_ENSURE( IsTxtFrm(), "MakeAll(), NoTxt" );
1108 : :
1109 [ + + ][ - + ]: 22553 : if ( !IsFollow() && StackHack::IsLocked() )
[ + - ]
1110 : : return;
1111 : :
1112 [ + - ]: 22553 : if ( IsJoinLocked() )
1113 : : return;
1114 : :
1115 : : OSL_ENSURE( !((SwTxtFrm*)this)->IsSwapped(), "Calculation of a swapped frame" );
1116 : :
1117 : 22553 : StackHack aHack;
1118 : :
1119 [ - + ]: 22553 : if ( ((SwTxtFrm*)this)->IsLocked() )
1120 : : {
1121 : : OSL_FAIL( "Format for locked TxtFrm." );
1122 : : return;
1123 : : }
1124 : :
1125 : 22553 : LockJoin();
1126 : 22553 : long nFormatCount = 0;
1127 : : // - loop prevention
1128 : 22553 : int nConsequetiveFormatsWithoutChange = 0;
1129 : : PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
1130 : :
1131 : : #ifdef DBG_UTIL
1132 : : const SwDoc *pDoc = GetAttrSet()->GetDoc();
1133 : : if( pDoc )
1134 : : {
1135 : : static sal_Bool bWarned = sal_False;
1136 : : if( pDoc->InXMLExport() )
1137 : : {
1138 : : SAL_WARN_IF( !bWarned, "sw", "Formatting during XML-export!" );
1139 : : bWarned = sal_True;
1140 : : }
1141 : : else
1142 : : bWarned = sal_False;
1143 : : }
1144 : : #endif
1145 : :
1146 : : // takes care of the notification in the dtor
1147 [ + - ][ + - ]: 22553 : SwCntntNotify *pNotify = new SwCntntNotify( this );
1148 : :
1149 : : // as long as bMakePage is true, a new page can be created (exactly once)
1150 : 22553 : bool bMakePage = true;
1151 : : // bMovedBwd gets set to true when the frame flows backwards
1152 : 22553 : bool bMovedBwd = false;
1153 : : // as long as bMovedFwd is false, the Frm may flow backwards (until
1154 : : // it has been moved forward once)
1155 : 22553 : bool bMovedFwd = false;
1156 : 22553 : sal_Bool bFormatted = sal_False; // For the widow/orphan rules, we encourage the
1157 : : // last CntntFrm of a chain to format. This only
1158 : : // needs to happen once. Every time the Frm is
1159 : : // moved, the flag will have to be reset.
1160 : 22553 : sal_Bool bMustFit = sal_False; // Once the emergency brake is pulled,
1161 : : // no other prepares will be triggered
1162 : 22553 : sal_Bool bFitPromise = sal_False; // If a paragraph didn't fit, but promises
1163 : : // with WouldFit that it would adjust accordingly,
1164 : : // this flag is set. If it turns out that it
1165 : : // didn't keep it's promise, we can act in a
1166 : : // controlled fashion.
1167 : : sal_Bool bMoveable;
1168 [ + - ]: 22553 : const sal_Bool bFly = IsInFly();
1169 [ + - ]: 22553 : const sal_Bool bTab = IsInTab();
1170 [ + - ]: 22553 : const sal_Bool bFtn = IsInFtn();
1171 [ + - ]: 22553 : const sal_Bool bSct = IsInSct();
1172 : 22553 : Point aOldFrmPos; // This is so we can compare with the last pos
1173 : 22553 : Point aOldPrtPos; // and determine whether it makes sense to Prepare
1174 : :
1175 [ + - ]: 22553 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
1176 [ + - ]: 22553 : const SwBorderAttrs &rAttrs = *aAccess.Get();
1177 : :
1178 : : // OD 2004-02-26 #i25029#
1179 [ + + ][ + - ]: 22553 : if ( !IsFollow() && rAttrs.JoinedWithPrev( *(this) ) )
[ + + ][ + + ]
1180 : : {
1181 : 5761 : pNotify->SetBordersJoinedWithPrev();
1182 : : }
1183 : :
1184 [ + - ]: 22553 : const sal_Bool bKeep = IsKeep( rAttrs.GetAttrSet() );
1185 : :
1186 : 22553 : SwSaveFtnHeight *pSaveFtn = 0;
1187 [ + + ]: 22553 : if ( bFtn )
1188 : : {
1189 [ + - ]: 257 : SwFtnFrm *pFtn = FindFtnFrm();
1190 [ + - ]: 257 : SwSectionFrm* pSct = pFtn->FindSctFrm();
1191 [ + + ]: 257 : if ( !((SwTxtFrm*)pFtn->GetRef())->IsLocked() )
1192 : : {
1193 : 81 : SwFtnBossFrm* pBoss = pFtn->GetRef()->FindFtnBossFrm(
1194 [ + - ]: 162 : pFtn->GetAttr()->GetFtn().IsEndNote() );
1195 [ - + ][ # # ]: 81 : if( !pSct || pSct->IsColLocked() || !pSct->Growable() )
[ # # ][ # # ]
[ + - ]
1196 : : pSaveFtn = new SwSaveFtnHeight( pBoss,
1197 [ + - ][ + - ]: 81 : ((SwTxtFrm*)pFtn->GetRef())->GetFtnLine( pFtn->GetAttr() ) );
[ + - ]
1198 : : }
1199 : : }
1200 : :
1201 : : //
1202 [ + + - + : 22774 : if ( GetUpper()->IsSctFrm() &&
# # ][ - + ]
1203 : 221 : HasFollow() &&
1204 : 0 : GetFollow()->GetFrm() == GetNext() )
1205 : : {
1206 [ # # ][ # # ]: 0 : dynamic_cast<SwTxtFrm*>(this)->JoinFrm();
1207 : : }
1208 : :
1209 : : // #i28701# - move master forward, if it has to move,
1210 : : // because of its object positioning.
1211 [ + + ]: 22553 : if ( !static_cast<SwTxtFrm*>(this)->IsFollow() )
1212 : : {
1213 : 20586 : sal_uInt32 nToPageNum = 0L;
1214 : : const bool bMoveFwdByObjPos = SwLayouter::FrmMovedFwdByObjPos(
1215 [ + - ]: 20586 : *(GetAttrSet()->GetDoc()),
1216 : : *(static_cast<SwTxtFrm*>(this)),
1217 [ + - ]: 20586 : nToPageNum );
1218 : : // #i58182#
1219 : : // Also move a paragraph forward, which is the first one inside a table cell.
1220 [ - + # # : 20586 : if ( bMoveFwdByObjPos &&
# # # # #
# # # ]
[ # # ][ - + ]
1221 [ # # ]: 0 : FindPageFrm()->GetPhyPageNum() < nToPageNum &&
1222 : 0 : ( lcl_Prev( this ) ||
1223 : 0 : GetUpper()->IsCellFrm() ||
1224 : 0 : ( GetUpper()->IsSctFrm() &&
1225 : 0 : GetUpper()->GetUpper()->IsCellFrm() ) ) &&
1226 [ # # ]: 0 : IsMoveable() )
1227 : : {
1228 : 0 : bMovedFwd = true;
1229 [ # # ]: 20586 : MoveFwd( bMakePage, sal_False );
1230 : : }
1231 : : }
1232 : :
1233 : : // If a Follow sits next to it's Master and doesn't fit, we know it can
1234 : : // be moved right now.
1235 [ + + ][ + + ]: 22553 : if ( lcl_Prev( this ) && ((SwTxtFrm*)this)->IsFollow() && IsMoveable() )
[ + - ][ + - ]
[ + + ]
1236 : : {
1237 : 63 : bMovedFwd = true;
1238 : : // OD 2004-03-02 #106629# - If follow frame is in table, it's master
1239 : : // will be the last in the current table cell. Thus, invalidate the
1240 : : // printing area of the master,
1241 [ + - ][ - + ]: 63 : if ( IsInTab() )
1242 : : {
1243 [ # # ]: 0 : lcl_Prev( this )->InvalidatePrt();
1244 : : }
1245 [ + - ]: 63 : MoveFwd( bMakePage, sal_False );
1246 : : }
1247 : :
1248 : : // OD 08.11.2002 #104840# - check footnote content for forward move.
1249 : : // If a content of a footnote is on a prior page/column as its invalid
1250 : : // reference, it can be moved forward.
1251 [ + + ][ + + ]: 22553 : if ( bFtn && !bValidPos )
1252 : : {
1253 [ + - ]: 214 : SwFtnFrm* pFtn = FindFtnFrm();
1254 [ + - ]: 214 : SwCntntFrm* pRefCnt = pFtn ? pFtn->GetRef() : 0;
1255 [ + - ][ + + ]: 214 : if ( pRefCnt && !pRefCnt->IsValid() )
[ + + ]
1256 : : {
1257 [ + - ]: 114 : SwFtnBossFrm* pFtnBossOfFtn = pFtn->FindFtnBossFrm();
1258 [ + - ]: 114 : SwFtnBossFrm* pFtnBossOfRef = pRefCnt->FindFtnBossFrm();
1259 : : //<loop of movefwd until condition held or no move>
1260 [ + - ][ + - ]: 114 : if ( pFtnBossOfFtn && pFtnBossOfRef &&
[ - + ][ # # ]
[ - + ]
1261 : : pFtnBossOfFtn != pFtnBossOfRef &&
1262 [ # # ]: 0 : pFtnBossOfFtn->IsBefore( pFtnBossOfRef ) )
1263 : : {
1264 : 0 : bMovedFwd = true;
1265 [ # # ]: 0 : MoveFwd( bMakePage, sal_False );
1266 : : }
1267 : : }
1268 : : }
1269 : :
1270 [ + - ][ + + ]: 22553 : SWRECTFN( this )
[ + - ][ - + ]
[ - + ]
1271 : :
1272 [ + + ][ + + ]: 50813 : while ( !bValidPos || !bValidSize || !bValidPrtArea )
[ + + ][ + + ]
1273 : : {
1274 : : // - loop prevention
1275 : 28287 : SwRect aOldFrm_StopFormat( Frm() );
1276 : 28287 : SwRect aOldPrt_StopFormat( Prt() );
1277 [ + + ][ + - ]: 28287 : if ( sal_True == (bMoveable = IsMoveable()) )
1278 : : {
1279 [ + - ]: 19550 : SwFrm *pPre = GetIndPrev();
1280 [ + - ][ + + ]: 19550 : if ( CheckMoveFwd( bMakePage, bKeep, bMovedBwd ) )
1281 : : {
1282 [ + - ][ + - ]: 6 : SWREFRESHFN( this )
[ - + ][ - + ]
[ # # ][ - + ]
[ # # ][ # # ]
[ - + ]
1283 : 6 : bMovedFwd = true;
1284 [ - + ]: 6 : if ( bMovedBwd )
1285 : : {
1286 : : // while floating back, the Upper was encouraged to completely
1287 : : // re-paint itself. We can skip this now after floating sideways.
1288 : 0 : GetUpper()->ResetCompletePaint();
1289 : : // The predecessor was invalidated, so this is obsolete as well now.
1290 : : OSL_ENSURE( pPre, "missing old Prev" );
1291 [ # # ]: 0 : if( !pPre->IsSctFrm() )
1292 : 0 : ::ValidateSz( pPre );
1293 : : }
1294 [ + - ]: 6 : bMoveable = IsMoveable();
1295 : : }
1296 : : }
1297 : :
1298 [ + - ][ + - ]: 28287 : aOldFrmPos = (Frm().*fnRect->fnGetPos)();
1299 [ + - ][ + - ]: 28287 : aOldPrtPos = (Prt().*fnRect->fnGetPos)();
1300 : :
1301 [ + + ]: 28287 : if ( !bValidPos )
1302 [ + - ]: 9815 : MakePos();
1303 : :
1304 : : //Set FixSize. VarSize is being adjusted by Format().
1305 [ + + ]: 28287 : if ( !bValidSize )
1306 : : {
1307 : : // #125452#
1308 : : // invalidate printing area flag, if the following conditions are hold:
1309 : : // - current frame width is 0.
1310 : : // - current printing area width is 0.
1311 : : // - frame width is adjusted to a value greater than 0.
1312 : : // - printing area flag is sal_True.
1313 : : // Thus, it's assured that the printing area is adjusted, if the
1314 : : // frame area width changes its width from 0 to something greater
1315 : : // than 0.
1316 : : // Note: A text frame can be in such a situation, if the format is
1317 : : // triggered by method call <SwCrsrShell::SetCrsr()> after
1318 : : // loading the document.
1319 [ + - ][ + - ]: 20033 : const SwTwips nNewFrmWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
1320 [ + + ][ + + ]: 30299 : if ( bValidPrtArea && nNewFrmWidth > 0 &&
[ - + ][ # # ]
[ - + ]
1321 [ + - ][ + - ]: 10266 : (Frm().*fnRect->fnGetWidth)() == 0 &&
1322 [ # # ][ # # ]: 0 : (Prt().*fnRect->fnGetWidth)() == 0 )
1323 : : {
1324 : 0 : bValidPrtArea = sal_False;
1325 : : }
1326 : :
1327 [ + - ][ + - ]: 20033 : (Frm().*fnRect->fnSetWidth)( nNewFrmWidth );
1328 : : }
1329 [ + + ]: 28287 : if ( !bValidPrtArea )
1330 : : {
1331 [ + - ][ + - ]: 15181 : const long nOldW = (Prt().*fnRect->fnGetWidth)();
1332 : : // #i34730# - keep current frame height
1333 [ + - ][ + - ]: 15181 : const SwTwips nOldH = (Frm().*fnRect->fnGetHeight)();
1334 [ + - ]: 15181 : MakePrtArea( rAttrs );
1335 [ + - ][ + - ]: 15181 : if ( nOldW != (Prt().*fnRect->fnGetWidth)() )
[ + + ]
1336 [ + - ]: 5310 : Prepare( PREP_FIXSIZE_CHG );
1337 : : // #i34730# - check, if frame height has changed.
1338 : : // If yes, send a PREP_ADJUST_FRM and invalidate the size flag to
1339 : : // force a format. The format will check in its method
1340 : : // <SwTxtFrm::CalcPreps()>, if the already formatted lines still
1341 : : // fit and if not, performs necessary actions.
1342 : : // #i40150# - no check, if frame is undersized.
1343 [ + + ][ + + ]: 20506 : if ( bValidSize && !IsUndersized() &&
[ + + ][ + + ]
1344 [ + - ][ + - ]: 5325 : nOldH != (Frm().*fnRect->fnGetHeight)() )
1345 : : {
1346 : : // #115759# - no PREP_ADJUST_FRM and size
1347 : : // invalidation, if height decreases only by the additional
1348 : : // lower space as last content of a table cell and an existing
1349 : : // follow containing one line exists.
1350 [ + - ][ + - ]: 8 : const SwTwips nHDiff = nOldH - (Frm().*fnRect->fnGetHeight)();
1351 : : const bool bNoPrepAdjustFrm =
1352 [ + - ]: 2 : nHDiff > 0 && IsInTab() && GetFollow() &&
1353 [ # # ][ # # ]: 0 : ( 1 == static_cast<SwTxtFrm*>(GetFollow())->GetLineCount( STRING_LEN ) || (static_cast<SwTxtFrm*>(GetFollow())->Frm().*fnRect->fnGetWidth)() < 0 ) &&
[ # # ]
1354 [ + + ]: 10 : GetFollow()->CalcAddLowerSpaceAsLastInTableCell() == nHDiff;
[ - + # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1355 [ + - ]: 8 : if ( !bNoPrepAdjustFrm )
1356 : : {
1357 [ + - ]: 8 : Prepare( PREP_ADJUST_FRM );
1358 : 8 : bValidSize = sal_False;
1359 : : }
1360 : : }
1361 : : }
1362 : :
1363 : : // To make the widow and orphan rules work, we need to notify the CntntFrm.
1364 : : // Criteria:
1365 : : // - It needs to be movable (otherwise, splitting doesn't make sense)
1366 : : // - It needs to overlap with the lower edge of the PrtArea of the Upper
1367 [ + + ]: 28287 : if ( !bMustFit )
1368 : : {
1369 : 28133 : sal_Bool bWidow = sal_True;
1370 [ + - ][ + - ]: 28133 : const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
1371 [ + + ][ + + ]: 43717 : if ( bMoveable && !bFormatted && ( GetFollow() ||
[ + + ][ + + ]
[ + + ]
1372 [ + - ][ + - ]: 15584 : ( (Frm().*fnRect->fnOverStep)( nDeadLine ) ) ) )
1373 : : {
1374 [ + - ]: 810 : Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False );
1375 : 810 : bValidSize = bWidow = sal_False;
1376 : : }
1377 [ + - ][ + - ]: 76315 : if( (Frm().*fnRect->fnGetPos)() != aOldFrmPos ||
[ + + + + ]
[ + - ]
[ + + # # ]
1378 [ + - ][ + - ]: 48182 : (Prt().*fnRect->fnGetPos)() != aOldPrtPos )
[ + + ][ # # ]
1379 : : {
1380 : : // In this Prepare, an _InvalidateSize() might happen.
1381 : : // bValidSize becomes sal_False and Format() gets called.
1382 [ + - ]: 8087 : Prepare( PREP_POS_CHGD, (const void*)&bFormatted, sal_False );
1383 [ + + ][ - + ]: 8087 : if ( bWidow && GetFollow() )
[ - + ]
1384 [ # # ]: 0 : { Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False );
1385 : 0 : bValidSize = sal_False;
1386 : : }
1387 : : }
1388 : : }
1389 [ + + ]: 28287 : if ( !bValidSize )
1390 : : {
1391 : 20388 : bValidSize = bFormatted = sal_True;
1392 : 20388 : ++nFormatCount;
1393 [ - + ]: 20388 : if( nFormatCount > STOP_FLY_FORMAT )
1394 : 0 : SetFlyLock( sal_True );
1395 : : // - loop prevention
1396 : : // No format any longer, if <cnStopFormat> consequetive formats
1397 : : // without change occur.
1398 [ + - ]: 20388 : if ( nConsequetiveFormatsWithoutChange <= cnStopFormat )
1399 : : {
1400 [ + - ]: 20388 : Format();
1401 : : }
1402 : : #if OSL_DEBUG_LEVEL > 0
1403 : : else
1404 : : {
1405 : : OSL_FAIL( "debug assertion: <SwCntntFrm::MakeAll()> - format of text frame suppressed by fix b6448963" );
1406 : : }
1407 : : #endif
1408 : : }
1409 : :
1410 : : // If this is the first one in a chain, check if this can flow
1411 : : // backwards (if this is movable at all).
1412 : : // To prevent oscillations/loops, check that this has not just
1413 : : // flowed forwards.
1414 : : sal_Bool bDummy;
1415 [ + + ][ + + ]: 40466 : if ( !lcl_Prev( this ) &&
[ + + ][ + + ]
[ + + ]
[ + + + + ]
[ + + ][ + + ]
1416 : 20538 : !bMovedFwd &&
1417 : : ( bMoveable || ( bFly && !bTab ) ) &&
1418 [ + - ]: 302 : ( !bFtn || !GetUpper()->FindFtnFrm()->GetPrev() )
1419 [ + - ]: 11877 : && MoveBwd( bDummy ) )
1420 : : {
1421 [ + - ][ + - ]: 74 : SWREFRESHFN( this )
[ - + ][ - + ]
[ # # ][ - + ]
[ # # ][ # # ]
[ - + ]
1422 : 74 : bMovedBwd = true;
1423 : 74 : bFormatted = sal_False;
1424 [ + + ][ + - ]: 74 : if ( bKeep && bMoveable )
1425 : : {
1426 [ + - ][ - + ]: 14 : if( CheckMoveFwd( bMakePage, sal_False, bMovedBwd ) )
1427 : : {
1428 : 0 : bMovedFwd = true;
1429 [ # # ]: 0 : bMoveable = IsMoveable();
1430 [ # # ][ # # ]: 0 : SWREFRESHFN( this )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1431 : : }
1432 [ + - ][ + - ]: 14 : Point aOldPos = (Frm().*fnRect->fnGetPos)();
1433 [ + - ]: 14 : MakePos();
1434 [ + - ][ + - ]: 14 : if( aOldPos != (Frm().*fnRect->fnGetPos)() )
[ + - ]
1435 : : {
1436 [ + - ]: 14 : Prepare( PREP_POS_CHGD, (const void*)&bFormatted, sal_False );
1437 [ + - ]: 14 : if ( !bValidSize )
1438 : : {
1439 : 28 : (Frm().*fnRect->fnSetWidth)( (GetUpper()->
1440 [ + - ][ + - ]: 28 : Prt().*fnRect->fnGetWidth)() );
[ + - ][ + - ]
1441 [ + - ]: 14 : if ( !bValidPrtArea )
1442 : : {
1443 [ + - ][ + - ]: 14 : const long nOldW = (Prt().*fnRect->fnGetWidth)();
1444 [ + - ]: 14 : MakePrtArea( rAttrs );
1445 [ + - ][ + - ]: 14 : if( nOldW != (Prt().*fnRect->fnGetWidth)() )
[ - + ]
1446 [ # # ]: 0 : Prepare( PREP_FIXSIZE_CHG, 0, sal_False );
1447 : : }
1448 [ - + ]: 14 : if( GetFollow() )
1449 [ # # ]: 0 : Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False );
1450 : 14 : bValidSize = bFormatted = sal_True;
1451 [ + - ]: 14 : Format();
1452 : : }
1453 : : }
1454 [ + - ][ + - ]: 14 : SwFrm *pNxt = HasFollow() ? NULL : FindNext();
1455 [ + - ][ + + ]: 42 : while( pNxt && pNxt->IsSctFrm() )
[ + + ]
1456 : : { // Leave empty sections out, go into the other ones.
1457 [ + + ]: 28 : if( ((SwSectionFrm*)pNxt)->GetSection() )
1458 : : {
1459 [ + - ]: 14 : SwFrm* pTmp = ((SwSectionFrm*)pNxt)->ContainsAny();
1460 [ - + ]: 14 : if( pTmp )
1461 : : {
1462 : 0 : pNxt = pTmp;
1463 : 0 : break;
1464 : : }
1465 : : }
1466 [ + - ]: 28 : pNxt = pNxt->FindNext();
1467 : : }
1468 [ + - ]: 14 : if ( pNxt )
1469 : : {
1470 [ + - ]: 14 : pNxt->Calc();
1471 [ + - ][ + - ]: 14 : if( bValidPos && !GetIndNext() )
[ - + ][ - + ]
1472 : : {
1473 [ # # ]: 0 : SwSectionFrm *pSct = FindSctFrm();
1474 [ # # ][ # # ]: 0 : if( pSct && !pSct->GetValidSizeFlag() )
[ # # ]
1475 : : {
1476 [ # # ]: 0 : SwSectionFrm* pNxtSct = pNxt->FindSctFrm();
1477 [ # # ][ # # ]: 0 : if( pNxtSct && pSct->IsAnFollow( pNxtSct ) )
[ # # ][ # # ]
[ # # ]
1478 : 0 : bValidPos = sal_False;
1479 : : }
1480 : : else
1481 : 14 : bValidPos = sal_False;
1482 : : }
1483 : : }
1484 : : }
1485 : : }
1486 : :
1487 : : // In footnotes, the TxtFrm may validate itself, which can lead to the
1488 : : // situation that it's position is wrong despite being "valid".
1489 [ + + ]: 28287 : if ( bValidPos )
1490 : : {
1491 : : // #i59341#
1492 : : // Workaround for inadequate layout algorithm:
1493 : : // suppress invalidation and calculation of position, if paragraph
1494 : : // has formatted itself at least STOP_FLY_FORMAT times and
1495 : : // has anchored objects.
1496 : : // Thus, the anchored objects get the possibility to format itself
1497 : : // and this probably solve the layout loop.
1498 [ + + ]: 28549 : if ( bFtn &&
[ + - + - ]
[ + + ]
1499 : : nFormatCount <= STOP_FLY_FORMAT &&
1500 : 334 : !GetDrawObjs() )
1501 : : {
1502 : 334 : bValidPos = sal_False;
1503 [ + - ]: 334 : MakePos();
1504 [ + - ][ + - ]: 334 : aOldFrmPos = (Frm().*fnRect->fnGetPos)();
1505 [ + - ][ + - ]: 334 : aOldPrtPos = (Prt().*fnRect->fnGetPos)();
1506 : : }
1507 : : }
1508 : :
1509 : : // - loop prevention
1510 : : {
1511 [ + + + - ]: 46163 : if ( aOldFrm_StopFormat == Frm() &&
[ + + ]
1512 : 17876 : aOldPrt_StopFormat == Prt() )
1513 : : {
1514 : 17876 : ++nConsequetiveFormatsWithoutChange;
1515 : : }
1516 : : else
1517 : : {
1518 : 10411 : nConsequetiveFormatsWithoutChange = 0;
1519 : : }
1520 : : }
1521 : :
1522 : : // Yet again an invalid value? Repeat from the start...
1523 [ + + ][ + + ]: 28287 : if ( !bValidPos || !bValidSize || !bValidPrtArea )
[ + + ]
1524 : 5541 : continue;
1525 : :
1526 : : // Done?
1527 : : // Attention: because height == 0, it's better to use Top()+Height() instead of
1528 : : // Bottom(). This might happen with undersized TextFrms on the lower edge of a
1529 : : // multi-column section
1530 [ + - ][ + - ]: 22746 : const long nPrtBottom = (GetUpper()->*fnRect->fnGetPrtBottom)();
1531 [ + - ][ + - ]: 22746 : const long nBottomDist = (Frm().*fnRect->fnBottomDist)( nPrtBottom );
1532 [ + + ]: 22746 : if( nBottomDist >= 0 )
1533 : : {
1534 [ + + ][ + + ]: 22538 : if ( bKeep && bMoveable )
1535 : : {
1536 : : // We make sure the successor will be formatted the same.
1537 : : // This way, we keep control until (almost) everything is stable,
1538 : : // allowing us to avoid endless loops caused by ever repeating
1539 : : // retries.
1540 : : //
1541 : : // bMoveFwdInvalid is required for #38407#. This was originally solved
1542 : : // in flowfrm.cxx rev 1.38, but broke the above schema and
1543 : : // preferred to play towers of hanoi (#43669#).
1544 [ + - ][ + - ]: 126 : SwFrm *pNxt = HasFollow() ? NULL : FindNext();
1545 : : // For sections we prefer the content, because it can change
1546 : : // the page if required.
1547 [ + + ][ + + ]: 126 : while( pNxt && pNxt->IsSctFrm() )
[ + + ]
1548 : : {
1549 [ + - ]: 4 : if( ((SwSectionFrm*)pNxt)->GetSection() )
1550 : : {
1551 [ + - ]: 4 : pNxt = ((SwSectionFrm*)pNxt)->ContainsAny();
1552 : 4 : break;
1553 : : }
1554 [ # # ]: 0 : pNxt = pNxt->FindNext();
1555 : : }
1556 [ + + ]: 126 : if ( pNxt )
1557 : : {
1558 [ + - ]: 108 : const sal_Bool bMoveFwdInvalid = 0 != GetIndNext();
1559 : : const sal_Bool bNxtNew =
1560 [ + - ][ + - ]: 108 : ( 0 == (pNxt->Prt().*fnRect->fnGetHeight)() ) &&
1561 [ + + ][ + - ]: 108 : (!pNxt->IsTxtFrm() ||!((SwTxtFrm*)pNxt)->IsHiddenNow());
[ + - ][ + - ]
1562 : :
1563 [ + - ]: 108 : pNxt->Calc();
1564 : :
1565 [ + + ][ + - ]: 202 : if ( !bMovedBwd &&
[ + - ][ + + ]
[ + + ]
1566 [ + - ]: 94 : ((bMoveFwdInvalid && !GetIndNext()) ||
1567 : : bNxtNew) )
1568 : : {
1569 [ - + ]: 50 : if( bMovedFwd )
1570 : 0 : pNotify->SetInvaKeep();
1571 : 50 : bMovedFwd = false;
1572 : : }
1573 : : }
1574 : : }
1575 : 22538 : continue;
1576 : : }
1577 : :
1578 : : // I don't fit into my parents, so it's time to make changes
1579 : : // as constructively as possible.
1580 : :
1581 : : //If I'm NOT allowed to leave the parent Frm, I've got a problem.
1582 : : // Following Arthur Dent, we do the only thing that you can do with
1583 : : // an unsolvable problem: We ignore it with all our power.
1584 [ + + ][ - + ]: 208 : if ( !bMoveable || IsUndersized() )
[ + + ]
1585 : : {
1586 [ + - ][ + - ]: 29 : if( !bMoveable && IsInTab() )
[ + + ][ + + ]
1587 : : {
1588 : 17 : long nDiff = -(Frm().*fnRect->fnBottomDist)(
1589 [ + - ][ + - ]: 17 : (GetUpper()->*fnRect->fnGetPrtBottom)() );
[ + - ][ + - ]
1590 [ + - ]: 17 : long nReal = GetUpper()->Grow( nDiff );
1591 [ + + ]: 17 : if( nReal )
1592 : 2 : continue;
1593 : : }
1594 : : break;
1595 : : }
1596 : :
1597 : : // If there's no way I can make myself fit into my Upper, the situation
1598 : : // could still probably be mitigated by splitting up.
1599 : : // This situation arises with freshly created Follows that had been moved
1600 : : // to the next page but is still too big for it - ie. needs to be split
1601 : : // as well.
1602 : : //
1603 : : // If I'm unable to split (WouldFit()) and can't be fitted, I'm going
1604 : : // to tell my TxtFrm part that, if possible, we still need to split despite
1605 : : // the "don't split" attribute.
1606 : 179 : sal_Bool bMoveOrFit = sal_False;
1607 [ + - ]: 179 : sal_Bool bDontMoveMe = !GetIndPrev();
1608 [ + + ][ + - ]: 179 : if( bDontMoveMe && IsInSct() )
[ + + ][ + + ]
1609 : : {
1610 [ + - ]: 26 : SwFtnBossFrm* pBoss = FindFtnBossFrm();
1611 [ + - ]: 26 : bDontMoveMe = !pBoss->IsInSct() ||
1612 [ + - ][ + - ]: 26 : ( !pBoss->Lower()->GetNext() && !pBoss->GetPrev() );
[ + - ]
1613 : : }
1614 : :
1615 : : // Finally, we are able to split table rows. Therefore, bDontMoveMe
1616 : : // can be set to sal_False:
1617 [ + + ][ + - ]: 179 : if( bDontMoveMe && IsInTab() &&
[ - + ][ # # ]
[ - + ]
1618 [ # # ]: 0 : 0 != const_cast<SwCntntFrm*>(this)->GetNextCellLeaf( MAKEPAGE_NONE ) )
1619 : 0 : bDontMoveMe = sal_False;
1620 : :
1621 [ + + ][ + - ]: 257 : if ( bDontMoveMe && (Frm().*fnRect->fnGetHeight)() >
[ + - ][ + - ]
[ + + ]
1622 [ + - ][ + - ]: 78 : (GetUpper()->Prt().*fnRect->fnGetHeight)() )
1623 : : {
1624 [ + - ]: 78 : if ( !bFitPromise )
1625 : : {
1626 [ + - ][ + - ]: 78 : SwTwips nTmp = (GetUpper()->Prt().*fnRect->fnGetHeight)() -
1627 [ + - ][ + - ]: 78 : (Prt().*fnRect->fnGetTop)();
1628 [ + - ]: 78 : sal_Bool bSplit = !IsFwdMoveAllowed();
1629 [ + + ][ + - ]: 78 : if ( nTmp > 0 && WouldFit( nTmp, bSplit, sal_False ) )
[ - + ][ - + ]
1630 : : {
1631 [ # # ]: 0 : Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False );
1632 : 0 : bValidSize = sal_False;
1633 : 0 : bFitPromise = sal_True;
1634 : 0 : continue;
1635 : : }
1636 : : /* --------------------------------------------------
1637 : : * In earlier days, we never tried to fit TextFrms in
1638 : : * frames and sections using bMoveOrFit by setting aside
1639 : : * the attributes (Widows, Keep).
1640 : : * This should have been done at least for column frames;
1641 : : * as it must be tried anyway with linked frames and sections.
1642 : : * Exception: If we sit in FormatWidthCols, we may not ignore
1643 : : * the attributes.
1644 : : * --------------------------------------------------*/
1645 [ + - ][ + - ]: 104 : else if ( !bFtn && bMoveable &&
[ - + # # ]
[ + + + - ]
[ + - ]
1646 [ # # ]: 0 : ( !bFly || !FindFlyFrm()->IsColLocked() ) &&
1647 [ + - ]: 26 : ( !bSct || !FindSctFrm()->IsColLocked() ) )
1648 : 78 : bMoveOrFit = sal_True;
1649 : : }
1650 : : #if OSL_DEBUG_LEVEL > 0
1651 : : else
1652 : : {
1653 : : OSL_FAIL( "+TxtFrm didn't respect WouldFit promise." );
1654 : : }
1655 : : #endif
1656 : : }
1657 : :
1658 : : // Let's see if I can find some space somewhere...
1659 : : // footnotes in the neighbourhood are moved into _MoveFtnCntFwd
1660 [ + - ]: 179 : SwFrm *pPre = GetIndPrev();
1661 : 179 : SwFrm *pOldUp = GetUpper();
1662 : :
1663 : : /* MA 13. Oct. 98: What is this supposed to be!?
1664 : : * AMA 14. Dec 98: If a column section can't find any space for its first ContentFrm, it should be
1665 : : * moved not only to the next column, but probably even to the next page, creating
1666 : : * a section-follow there.
1667 : : */
1668 [ + + ][ + + ]: 279 : if( IsInSct() && bMovedFwd && bMakePage && pOldUp->IsColBodyFrm() &&
[ + + ]
[ + - + - ]
[ - + # # ]
[ + - ][ + + ]
[ + - ]
1669 : 50 : pOldUp->GetUpper()->GetUpper()->IsSctFrm() &&
1670 : 0 : ( pPre || pOldUp->GetUpper()->GetPrev() ) &&
1671 [ + - ]: 50 : ((SwSectionFrm*)pOldUp->GetUpper()->GetUpper())->MoveAllowed(this) )
1672 : : {
1673 : 50 : bMovedFwd = false;
1674 : : }
1675 : :
1676 : 179 : const sal_Bool bCheckForGrownBody = pOldUp->IsBodyFrm();
1677 [ + - ][ + - ]: 179 : const long nOldBodyHeight = (pOldUp->Frm().*fnRect->fnGetHeight)();
1678 : :
1679 [ + + ][ + - ]: 179 : if ( !bMovedFwd && !MoveFwd( bMakePage, sal_False ) )
[ + + ][ + + ]
1680 : 103 : bMakePage = false;
1681 [ + - ][ + - ]: 179 : SWREFRESHFN( this )
[ - + ][ - + ]
[ # # ][ + + ]
[ + - ][ - + ]
[ - + ]
1682 : :
1683 : : // If MoveFwd moves the paragraph to the next page, a following
1684 : : // paragraph, which contains footnotes can can cause the old upper
1685 : : // frame to grow. In this case we explicitly allow a new check
1686 : : // for MoveBwd. Robust: We also check the bMovedBwd flag again.
1687 : : // If pOldUp was a footnote frame, it has been deleted inside MoveFwd.
1688 : : // Therefore we only check for growing body frames.
1689 [ + + ][ + - ]: 277 : if ( bCheckForGrownBody && ! bMovedBwd && pOldUp != GetUpper() &&
[ + + ][ - + ]
[ - + ]
1690 [ + - ][ + - ]: 98 : (pOldUp->Frm().*fnRect->fnGetHeight)() > nOldBodyHeight )
1691 : : {
1692 : 0 : bMovedFwd = false;
1693 : : }
1694 : : else
1695 : : {
1696 : 179 : bMovedFwd = true;
1697 : : }
1698 : :
1699 : 179 : bFormatted = sal_False;
1700 [ + + ][ + - ]: 179 : if ( bMoveOrFit && GetUpper() == pOldUp )
[ + + ]
1701 : : {
1702 : : // FME 2007-08-30 #i81146# new loop control
1703 [ + - ]: 78 : if ( nConsequetiveFormatsWithoutChange <= cnStopFormat )
1704 : : {
1705 [ + - ]: 78 : Prepare( PREP_MUST_FIT, 0, sal_False );
1706 : 78 : bValidSize = sal_False;
1707 : 78 : bMustFit = sal_True;
1708 : 78 : continue;
1709 : : }
1710 : :
1711 : : #if OSL_DEBUG_LEVEL > 0
1712 : : OSL_FAIL( "LoopControl in SwCntntFrm::MakeAll" );
1713 : : #endif
1714 : : }
1715 [ - + ][ # # ]: 101 : if ( bMovedBwd && GetUpper() )
[ - + ]
1716 : : { // Retire invalidations that have become useless.
1717 : 0 : GetUpper()->ResetCompletePaint();
1718 [ # # ][ # # ]: 0 : if( pPre && !pPre->IsSctFrm() )
[ # # ]
1719 : 28287 : ::ValidateSz( pPre );
1720 : : }
1721 : :
1722 : : } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
1723 : :
1724 : :
1725 : : // NEW: Looping Louie (Light). Should not be applied in balanced sections.
1726 : : // Should only be applied if there is no better solution!
1727 [ # # ]: 0 : LOOPING_LOUIE_LIGHT( bMovedFwd && bMovedBwd && !IsInBalancedSection() &&
1728 : : (
1729 : :
1730 : : // #118572#
1731 [ # # ][ # # ]: 0 : ( bFtn && !FindFtnFrm()->GetRef()->IsInSct() ) ||
1732 : :
1733 : : // #i33887#
1734 [ # # ]: 0 : ( IsInSct() && bKeep )
1735 : :
1736 : : // ... add your conditions here ...
1737 : :
1738 : : ),
1739 [ + + ][ - + ]: 22553 : static_cast<SwTxtFrm&>(*this) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ + - ]
1740 : :
1741 : :
1742 [ + + ][ + - ]: 22553 : delete pSaveFtn;
1743 : :
1744 : 22553 : UnlockJoin();
1745 [ + + ][ + + ]: 22553 : if ( bMovedFwd || bMovedBwd )
1746 : 246 : pNotify->SetInvaKeep();
1747 : : // OD 2004-02-26 #i25029#
1748 [ + + ]: 22553 : if ( bMovedFwd )
1749 : : {
1750 : 172 : pNotify->SetInvalidatePrevPrtArea();
1751 : : }
1752 [ + - ][ + - ]: 22553 : delete pNotify;
1753 [ + - ][ + - ]: 22553 : SetFlyLock( sal_False );
1754 : : }
1755 : :
1756 : : /*************************************************************************
1757 : : |*
1758 : : |* SwCntntFrm::_WouldFit()
1759 : : |*
1760 : : |*************************************************************************/
1761 : :
1762 : :
1763 : :
1764 : :
1765 : 0 : void MakeNxt( SwFrm *pFrm, SwFrm *pNxt )
1766 : : {
1767 : : // fix(25455): Validate, otherwise this leads to a recursion.
1768 : : // The first try, cancelling with pFrm = 0 if !Valid, leads to a problem, as
1769 : : // the Keep may not be considered properly anymore (27417).
1770 : 0 : const sal_Bool bOldPos = pFrm->GetValidPosFlag();
1771 : 0 : const sal_Bool bOldSz = pFrm->GetValidSizeFlag();
1772 : 0 : const sal_Bool bOldPrt = pFrm->GetValidPrtAreaFlag();
1773 : 0 : pFrm->bValidPos = pFrm->bValidPrtArea = pFrm->bValidSize = sal_True;
1774 : :
1775 : : // fix(29272): Don't call MakeAll - there, pFrm might be invalidated again, and
1776 : : // we recursively end up in here again.
1777 [ # # ]: 0 : if ( pNxt->IsCntntFrm() )
1778 : : {
1779 [ # # ]: 0 : SwCntntNotify aNotify( (SwCntntFrm*)pNxt );
1780 [ # # ]: 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt );
1781 [ # # ]: 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
1782 [ # # ]: 0 : if ( !pNxt->GetValidSizeFlag() )
1783 : : {
1784 [ # # ][ # # ]: 0 : if( pNxt->IsVertical() )
1785 : 0 : pNxt->Frm().Height( pNxt->GetUpper()->Prt().Height() );
1786 : : else
1787 : 0 : pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() );
1788 : : }
1789 [ # # ]: 0 : ((SwCntntFrm*)pNxt)->MakePrtArea( rAttrs );
1790 [ # # ][ # # ]: 0 : pNxt->Format( &rAttrs );
[ # # ]
1791 : : }
1792 : : else
1793 : : {
1794 [ # # ]: 0 : SwLayNotify aNotify( (SwLayoutFrm*)pNxt );
1795 [ # # ]: 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt );
1796 [ # # ]: 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
1797 [ # # ]: 0 : if ( !pNxt->GetValidSizeFlag() )
1798 : : {
1799 [ # # ][ # # ]: 0 : if( pNxt->IsVertical() )
1800 : 0 : pNxt->Frm().Height( pNxt->GetUpper()->Prt().Height() );
1801 : : else
1802 : 0 : pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() );
1803 : : }
1804 [ # # ][ # # ]: 0 : pNxt->Format( &rAttrs );
[ # # ]
1805 : : }
1806 : :
1807 : 0 : pFrm->bValidPos = bOldPos;
1808 : 0 : pFrm->bValidSize = bOldSz;
1809 : 0 : pFrm->bValidPrtArea = bOldPrt;
1810 : 0 : }
1811 : :
1812 : : // This routine checks whether there are no other FtnBosses
1813 : : // between the pFrm's FtnBoss and the pNxt's FtnBoss.
1814 : :
1815 : 0 : sal_Bool lcl_IsNextFtnBoss( const SwFrm *pFrm, const SwFrm* pNxt )
1816 : : {
1817 : : OSL_ENSURE( pFrm && pNxt, "lcl_IsNextFtnBoss: No Frames?" );
1818 : 0 : pFrm = pFrm->FindFtnBossFrm();
1819 : 0 : pNxt = pNxt->FindFtnBossFrm();
1820 : : // If pFrm is a last column, we use the page instead.
1821 [ # # ][ # # ]: 0 : while( pFrm && pFrm->IsColumnFrm() && !pFrm->GetNext() )
[ # # ][ # # ]
1822 : 0 : pFrm = pFrm->GetUpper()->FindFtnBossFrm();
1823 : : // If pNxt is a first column, we use the page instead.
1824 [ # # ][ # # ]: 0 : while( pNxt && pNxt->IsColumnFrm() && !pNxt->GetPrev() )
[ # # ][ # # ]
1825 : 0 : pNxt = pNxt->GetUpper()->FindFtnBossFrm();
1826 : : // So.. now pFrm and pNxt are either two adjacent pages or columns.
1827 [ # # ][ # # ]: 0 : return ( pFrm && pNxt && pFrm->GetNext() == pNxt );
[ # # ]
1828 : : }
1829 : :
1830 : : //
1831 : 60 : sal_Bool SwCntntFrm::_WouldFit( SwTwips nSpace,
1832 : : SwLayoutFrm *pNewUpper,
1833 : : sal_Bool bTstMove,
1834 : : const bool bObjsInNewUpper )
1835 : : {
1836 : : // To have the footnote select it's place carefully, it needs
1837 : : // to be moved in any case if there is at least one page/column
1838 : : // between the footnote and the new Upper.
1839 : 60 : SwFtnFrm* pFtnFrm = 0;
1840 [ + - ][ - + ]: 60 : if ( IsInFtn() )
1841 : : {
1842 [ # # ][ # # ]: 0 : if( !lcl_IsNextFtnBoss( pNewUpper, this ) )
1843 : 0 : return sal_True;
1844 [ # # ]: 0 : pFtnFrm = FindFtnFrm();
1845 : : }
1846 : :
1847 : : sal_Bool bRet;
1848 : 60 : sal_Bool bSplit = !pNewUpper->Lower();
1849 : 60 : SwCntntFrm *pFrm = this;
1850 : 60 : const SwFrm *pTmpPrev = pNewUpper->Lower();
1851 [ - + ][ - + ]: 60 : if( pTmpPrev && pTmpPrev->IsFtnFrm() )
[ + + ]
1852 : 0 : pTmpPrev = ((SwFtnFrm*)pTmpPrev)->Lower();
1853 [ + + ][ + + ]: 482 : while ( pTmpPrev && pTmpPrev->GetNext() )
[ + + ]
1854 : 422 : pTmpPrev = pTmpPrev->GetNext();
1855 [ + + ][ - + ]: 60 : do
[ - + ]
1856 : : {
1857 : : // #i46181#
1858 : 60 : SwTwips nSecondCheck = 0;
1859 : 60 : SwTwips nOldSpace = nSpace;
1860 : 60 : sal_Bool bOldSplit = bSplit;
1861 : :
1862 [ + + ][ + - ]: 76 : if ( bTstMove || IsInFly() || ( IsInSct() &&
[ + - ][ + - ]
[ + + + + ]
[ - + # # ]
[ + + ]
1863 : 16 : ( pFrm->GetUpper()->IsColBodyFrm() || ( pFtnFrm &&
1864 : 0 : pFtnFrm->GetUpper()->GetUpper()->IsColumnFrm() ) ) ) )
1865 : : {
1866 : : // This is going to get a bit insidious now. If you're faint of heart,
1867 : : // you'd better look away here. If a Fly contains columns, then the Cntnts
1868 : : // are movable, except the one in the last column (see SwFrm::IsMoveable()).
1869 : : // Of course they're allowed to float back. WouldFit() only returns a usable
1870 : : // value if the Frm is movable. To fool WouldFit() into believing there's
1871 : : // a movable Frm, I'm just going to hang it somewhere else for the time.
1872 : : // The same procedure applies for column sections to make SwSectionFrm::Growable()
1873 : : // return the proper value.
1874 : : // Within footnotes, we may even need to put the SwFtnFrm somewhere else, if
1875 : : // there's no SwFtnFrm there.
1876 [ + - ][ # # ]: 4 : SwFrm* pTmpFrm = pFrm->IsInFtn() && !pNewUpper->FindFtnFrm() ?
1877 [ - + ][ # # ]: 4 : (SwFrm*)pFrm->FindFtnFrm() : pFrm;
[ # # ]
1878 : 4 : SwLayoutFrm *pUp = pTmpFrm->GetUpper();
1879 : 4 : SwFrm *pOldNext = pTmpFrm->GetNext();
1880 [ + - ]: 4 : pTmpFrm->Remove();
1881 [ + - ]: 4 : pTmpFrm->InsertBefore( pNewUpper, 0 );
1882 [ + - ]: 10 : if ( pFrm->IsTxtFrm() &&
[ + + + - ]
[ + - - + ]
[ + + ]
1883 : : ( bTstMove ||
1884 : 2 : ((SwTxtFrm*)pFrm)->HasFollow() ||
1885 [ + - ]: 2 : ( !((SwTxtFrm*)pFrm)->HasPara() &&
1886 : 2 : !((SwTxtFrm*)pFrm)->IsEmpty()
1887 : : )
1888 : : )
1889 : : )
1890 : : {
1891 : 2 : bTstMove = sal_True;
1892 [ + - ]: 2 : bRet = ((SwTxtFrm*)pFrm)->TestFormat( pTmpPrev, nSpace, bSplit );
1893 : : }
1894 : : else
1895 [ + - ]: 2 : bRet = pFrm->WouldFit( nSpace, bSplit, sal_False );
1896 : :
1897 [ + - ]: 4 : pTmpFrm->Remove();
1898 [ + - ]: 4 : pTmpFrm->InsertBefore( pUp, pOldNext );
1899 : : }
1900 : : else
1901 : : {
1902 [ + - ]: 56 : bRet = pFrm->WouldFit( nSpace, bSplit, sal_False );
1903 [ + + ]: 56 : nSecondCheck = !bSplit ? 1 : 0;
1904 : : }
1905 : :
1906 [ + - ]: 60 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
1907 [ + - ]: 60 : const SwBorderAttrs &rAttrs = *aAccess.Get();
1908 : :
1909 : : // Sad but true: We need to consider the spacing in our calculation.
1910 : : // This already happened in TestFormat.
1911 [ + + ][ + + ]: 60 : if ( bRet && !bTstMove )
1912 : : {
1913 : : SwTwips nUpper;
1914 : :
1915 [ + + ]: 50 : if ( pTmpPrev )
1916 : : {
1917 [ + - ]: 34 : nUpper = CalcUpperSpace( NULL, pTmpPrev );
1918 : :
1919 : : // in balanced columned section frames we do not want the
1920 : : // common border
1921 : 34 : sal_Bool bCommonBorder = sal_True;
1922 [ + - ][ - + ]: 34 : if ( pFrm->IsInSct() && pFrm->GetUpper()->IsColBodyFrm() )
[ # # ][ - + ]
1923 : : {
1924 [ # # ]: 0 : const SwSectionFrm* pSct = pFrm->FindSctFrm();
1925 [ # # ][ # # ]: 0 : bCommonBorder = pSct->GetFmt()->GetBalancedColumns().GetValue();
1926 : : }
1927 : :
1928 : : // #i46181#
1929 : : nSecondCheck = ( 1 == nSecondCheck &&
1930 : : pFrm == this &&
1931 : 30 : IsTxtFrm() &&
1932 : : bCommonBorder &&
1933 : 30 : !static_cast<const SwTxtFrm*>(this)->IsEmpty() ) ?
1934 : : nUpper :
1935 [ + + ]: 94 : 0;
[ + - + - ]
[ + - + + ]
1936 : :
1937 : : nUpper += bCommonBorder ?
1938 : 34 : rAttrs.GetBottomLine( *(pFrm) ) :
1939 [ + - ][ + - ]: 34 : rAttrs.CalcBottomLine();
[ # # ]
1940 : :
1941 : : }
1942 : : else
1943 : : {
1944 : : // #i46181#
1945 : 16 : nSecondCheck = 0;
1946 : :
1947 [ + - ][ - + ]: 16 : if( pFrm->IsVertical() )
1948 : 0 : nUpper = pFrm->Frm().Width() - pFrm->Prt().Width();
1949 : : else
1950 : 16 : nUpper = pFrm->Frm().Height() - pFrm->Prt().Height();
1951 : : }
1952 : :
1953 : 50 : nSpace -= nUpper;
1954 : :
1955 [ + + ]: 50 : if ( nSpace < 0 )
1956 : : {
1957 : 6 : bRet = sal_False;
1958 : :
1959 : : // #i46181#
1960 [ + - ]: 6 : if ( nSecondCheck > 0 )
1961 : : {
1962 : : // The following code is intended to solve a (rare) problem
1963 : : // causing some frames not to move backward:
1964 : : // SwTxtFrm::WouldFit() claims that the whole paragraph
1965 : : // fits into the given space and subtracts the height of
1966 : : // all lines from nSpace. nSpace - nUpper is not a valid
1967 : : // indicator if the frame should be allowed to move backward.
1968 : : // We do a second check with the original remaining space
1969 : : // reduced by the required upper space:
1970 : 6 : nOldSpace -= nSecondCheck;
1971 [ - + ][ # # ]: 6 : const bool bSecondRet = nOldSpace >= 0 && pFrm->WouldFit( nOldSpace, bOldSplit, sal_False );
[ # # ]
1972 [ - + ][ # # ]: 6 : if ( bSecondRet && bOldSplit && nOldSpace >= 0 )
[ # # ]
1973 : : {
1974 : 0 : bRet = sal_True;
1975 : 0 : bSplit = sal_True;
1976 : : }
1977 : : }
1978 : : }
1979 : : }
1980 : :
1981 : : // OD 2004-03-01 #106629# - also consider lower spacing in table cells
1982 [ + + ][ + - ]: 60 : if ( bRet && IsInTab() &&
[ - + ][ # # ]
[ - + ]
1983 [ # # ][ # # ]: 0 : pNewUpper->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) )
[ # # ]
1984 : : {
1985 : 0 : nSpace -= rAttrs.GetULSpace().GetLower();
1986 [ # # ]: 0 : if ( nSpace < 0 )
1987 : : {
1988 : 0 : bRet = sal_False;
1989 : : }
1990 : : }
1991 : :
1992 [ + + ][ + + ]: 60 : if ( bRet && !bSplit && pFrm->IsKeep( rAttrs.GetAttrSet() ) )
[ + - ][ + + ]
[ + + ]
1993 : : {
1994 [ - + ]: 14 : if( bTstMove )
1995 : : {
1996 [ # # ][ # # ]: 0 : while( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() )
[ # # ]
1997 : : {
1998 : 0 : pFrm = ((SwTxtFrm*)pFrm)->GetFollow();
1999 : : }
2000 : : // OD 11.04.2003 #108824# - If last follow frame of <this> text
2001 : : // frame isn't valid, a formatting of the next content frame
2002 : : // doesn't makes sense. Thus, return sal_True.
2003 [ # # ][ # # ]: 0 : if ( IsAnFollow( pFrm ) && !pFrm->IsValid() )
[ # # ][ # # ]
[ # # ]
2004 : : {
2005 : : OSL_FAIL( "Only a warning for task 108824:/n<SwCntntFrm::_WouldFit(..) - follow not valid!" );
2006 : 0 : return sal_True;
2007 : : }
2008 : : }
2009 : : SwFrm *pNxt;
2010 [ + - ][ + - ]: 14 : if( 0 != (pNxt = pFrm->FindNext()) && pNxt->IsCntntFrm() &&
[ - + ][ # # ]
[ # # # # ]
[ - + ]
2011 [ # # ]: 0 : ( !pFtnFrm || ( pNxt->IsInFtn() &&
2012 [ # # ]: 0 : pNxt->FindFtnFrm()->GetAttr() == pFtnFrm->GetAttr() ) ) )
2013 : : {
2014 : : // TestFormat(?) does not like paragraph- or character anchored objects.
2015 : : //
2016 : : // current solution for the test formatting doesn't work, if
2017 : : // objects are present in the remaining area of the new upper
2018 [ # # # # ]: 0 : if ( bTstMove &&
[ # # ][ # # ]
2019 : 0 : ( pNxt->GetDrawObjs() || bObjsInNewUpper ) )
2020 : : {
2021 : 0 : return sal_True;
2022 : : }
2023 : :
2024 [ # # ]: 0 : if ( !pNxt->IsValid() )
2025 [ # # ]: 0 : MakeNxt( pFrm, pNxt );
2026 : :
2027 : : // Little trick: if the next has a predecessor, then the paragraph
2028 : : // spacing has been calculated already, and we don't need to re-calculate
2029 : : // it in an expensive way.
2030 [ # # ][ # # ]: 0 : if( lcl_NotHiddenPrev( pNxt ) )
2031 : 0 : pTmpPrev = 0;
2032 : : else
2033 : : {
2034 [ # # ][ # # ]: 0 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow() )
[ # # ][ # # ]
2035 [ # # ]: 0 : pTmpPrev = lcl_NotHiddenPrev( pFrm );
2036 : : else
2037 : 0 : pTmpPrev = pFrm;
2038 : : }
2039 : 0 : pFrm = (SwCntntFrm*)pNxt;
2040 : : }
2041 : : else
2042 : 14 : pFrm = 0;
2043 : : }
2044 : : else
2045 [ + - ][ + - ]: 60 : pFrm = 0;
2046 : :
2047 : : } while ( bRet && pFrm );
2048 : :
2049 : 60 : return bRet;
2050 : : }
2051 : :
2052 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|