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 : :
30 : : #include "pagefrm.hxx"
31 : : #include "viewsh.hxx"
32 : : #include "doc.hxx"
33 : : #include <fmtcntnt.hxx>
34 : : #include <fmthdft.hxx>
35 : : #include <fmtfsize.hxx>
36 : : #include "viewopt.hxx"
37 : : #include "hffrm.hxx"
38 : : #include "rootfrm.hxx"
39 : : #include "txtfrm.hxx"
40 : : #include "sectfrm.hxx"
41 : : #include "flyfrm.hxx"
42 : : #include "frmtool.hxx"
43 : : #include "dflyobj.hxx"
44 : : #include "frmfmt.hxx"
45 : : #include "ndindex.hxx"
46 : : #include "hfspacingitem.hxx"
47 : : // OD 2004-05-24 #i28701#
48 : : #include <sortedobjs.hxx>
49 : : // #i43771#
50 : : #include <objectformatter.hxx>
51 : :
52 : : extern sal_Bool bObjsDirect; //frmtool.cxx
53 : :
54 : 300 : static SwTwips lcl_GetFrmMinHeight(const SwLayoutFrm & rFrm)
55 : : {
56 : 300 : const SwFmtFrmSize &rSz = rFrm.GetFmt()->GetFrmSize();
57 : : SwTwips nMinHeight;
58 : :
59 [ + + ]: 300 : switch (rSz.GetHeightSizeType())
60 : : {
61 : : case ATT_MIN_SIZE:
62 : 292 : nMinHeight = rSz.GetHeight();
63 : :
64 : 292 : break;
65 : :
66 : : default:
67 : 8 : nMinHeight = 0;
68 : : }
69 : :
70 : :
71 : 300 : return nMinHeight;
72 : : }
73 : :
74 : :
75 : 57 : static SwTwips lcl_CalcContentHeight(SwLayoutFrm & frm)
76 : : {
77 : 57 : SwFrm* pFrm = frm.Lower();
78 : :
79 : 57 : SwTwips nRemaining = 0;
80 : 57 : sal_uInt16 nNum = 0;
81 : 57 : pFrm = frm.Lower();
82 [ + + ]: 132 : while ( pFrm )
83 : : {
84 : : SwTwips nTmp;
85 : :
86 : 75 : nTmp = pFrm->Frm().Height();
87 : 75 : nRemaining += nTmp;
88 [ - + ][ - + ]: 75 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
[ + + ]
89 : : {
90 : 0 : nTmp = ((SwTxtFrm*)pFrm)->GetParHeight()
91 : 0 : - pFrm->Prt().Height();
92 : : // This TxtFrm would like to be a bit bigger
93 : 0 : nRemaining += nTmp;
94 : : }
95 [ - + ][ # # ]: 75 : else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
[ - + ]
96 : : {
97 : 0 : nTmp = ((SwSectionFrm*)pFrm)->Undersize();
98 : 0 : nRemaining += nTmp;
99 : : }
100 : 75 : pFrm = pFrm->GetNext();
101 : :
102 : 75 : nNum++;
103 : : }
104 : :
105 : 57 : return nRemaining;
106 : : }
107 : :
108 : 70 : static void lcl_LayoutFrmEnsureMinHeight(SwLayoutFrm & rFrm,
109 : : const SwBorderAttrs * )
110 : : {
111 : 70 : SwTwips nMinHeight = lcl_GetFrmMinHeight(rFrm);
112 : :
113 [ + + ]: 70 : if (rFrm.Frm().Height() < nMinHeight)
114 : : {
115 : 59 : rFrm.Grow(nMinHeight - rFrm.Frm().Height());
116 : : }
117 : 70 : }
118 : :
119 : 68 : SwHeadFootFrm::SwHeadFootFrm( SwFrmFmt * pFmt, SwFrm* pSib, sal_uInt16 nTypeIn)
120 : 68 : : SwLayoutFrm( pFmt, pSib )
121 : : {
122 : 68 : nType = nTypeIn;
123 : 68 : SetDerivedVert( sal_False );
124 : :
125 [ + - ]: 68 : const SwFmtCntnt &rCnt = pFmt->GetCntnt();
126 : :
127 : : OSL_ENSURE( rCnt.GetCntntIdx(), "No content for Header." );
128 : :
129 : : // Have the objects created right now for header and footer
130 : 68 : sal_Bool bOld = bObjsDirect;
131 : 68 : bObjsDirect = sal_True;
132 : 68 : sal_uLong nIndex = rCnt.GetCntntIdx()->GetIndex();
133 [ + - ]: 68 : ::_InsertCnt( this, pFmt->GetDoc(), ++nIndex );
134 : 68 : bObjsDirect = bOld;
135 : 68 : }
136 : :
137 : 70 : void SwHeadFootFrm::FormatPrt(SwTwips & nUL, const SwBorderAttrs * pAttrs)
138 : : {
139 [ + + ]: 70 : if (GetEatSpacing())
140 : : {
141 : : /* The minimal height of the print area is the minimal height of the
142 : : frame without the height needed for borders and shadow. */
143 : 57 : SwTwips nMinHeight = lcl_GetFrmMinHeight(*this);
144 : :
145 : 57 : nMinHeight -= pAttrs->CalcTop();
146 : 57 : nMinHeight -= pAttrs->CalcBottom();
147 : :
148 : : /* If the minimal height of the print area is negative, try to
149 : : compensate by overlapping */
150 : 57 : SwTwips nOverlap = 0;
151 [ - + ]: 57 : if (nMinHeight < 0)
152 : : {
153 : 0 : nOverlap = -nMinHeight;
154 : 0 : nMinHeight = 0;
155 : : }
156 : :
157 : : /* Calculate desired height of content. The minimal height has to be
158 : : adhered. */
159 : : SwTwips nHeight;
160 : :
161 [ + - ]: 57 : if ( ! HasFixSize() )
162 : 57 : nHeight = lcl_CalcContentHeight(*this);
163 : : else
164 : 0 : nHeight = nMinHeight;
165 : :
166 [ + + ]: 57 : if (nHeight < nMinHeight)
167 : 54 : nHeight = nMinHeight;
168 : :
169 : : /* calculate initial spacing/line space */
170 : : SwTwips nSpace, nLine;
171 : :
172 [ + + ]: 57 : if (IsHeaderFrm())
173 : : {
174 : 36 : nSpace = pAttrs->CalcBottom();
175 : 36 : nLine = pAttrs->CalcBottomLine();
176 : : }
177 : : else
178 : : {
179 : 21 : nSpace = pAttrs->CalcTop();
180 : 21 : nLine = pAttrs->CalcTopLine();
181 : : }
182 : :
183 : : /* calculate overlap and correct spacing */
184 : 57 : nOverlap += nHeight - nMinHeight;
185 [ + + ]: 57 : if (nOverlap < nSpace - nLine)
186 : 51 : nSpace -= nOverlap;
187 : : else
188 : 6 : nSpace = nLine;
189 : :
190 : : /* calculate real vertical space between frame and print area */
191 [ + + ]: 57 : if (IsHeaderFrm())
192 : 36 : nUL = pAttrs->CalcTop() + nSpace;
193 : : else
194 : 21 : nUL = pAttrs->CalcBottom() + nSpace;
195 : :
196 : : /* set print area */
197 : : // OD 23.01.2003 #106895# - add first parameter to <SwBorderAttrs::CalcRight(..)>
198 : 57 : SwTwips nLR = pAttrs->CalcLeft( this ) + pAttrs->CalcRight( this );
199 : :
200 : 57 : aPrt.Left(pAttrs->CalcLeft(this));
201 : :
202 [ + + ]: 57 : if (IsHeaderFrm())
203 : 36 : aPrt.Top(pAttrs->CalcTop());
204 : : else
205 : 21 : aPrt.Top(nSpace);
206 : :
207 : 57 : aPrt.Width(aFrm.Width() - nLR);
208 : :
209 : : SwTwips nNewHeight;
210 : :
211 [ + - ]: 57 : if (nUL < aFrm.Height())
212 : 57 : nNewHeight = aFrm.Height() - nUL;
213 : : else
214 : 0 : nNewHeight = 0;
215 : :
216 : 57 : aPrt.Height(nNewHeight);
217 : :
218 : : }
219 : : else
220 : : {
221 : : // Set position
222 : 13 : aPrt.Left( pAttrs->CalcLeft( this ) );
223 : 13 : aPrt.Top ( pAttrs->CalcTop() );
224 : :
225 : : // Set sizes - the sizes are given by the surrounding Frm, just
226 : : // subtract the borders.
227 : : // OD 23.01.2003 #106895# - add first parameter to <SwBorderAttrs::CalcRight(..)>
228 : 13 : SwTwips nLR = pAttrs->CalcLeft( this ) + pAttrs->CalcRight( this );
229 : 13 : aPrt.Width ( aFrm.Width() - nLR );
230 : 13 : aPrt.Height( aFrm.Height()- nUL );
231 : :
232 : : }
233 : :
234 : 70 : bValidPrtArea = sal_True;
235 : 70 : }
236 : :
237 : 66 : void SwHeadFootFrm::FormatSize(SwTwips nUL, const SwBorderAttrs * pAttrs)
238 : : {
239 [ + + ]: 66 : if ( !HasFixSize() )
240 : : {
241 [ + - ]: 62 : if( !IsColLocked() )
242 : : {
243 : 62 : bValidSize = bValidPrtArea = sal_True;
244 : :
245 : 62 : const SwTwips nBorder = nUL;
246 [ + - ]: 62 : SwTwips nMinHeight = lcl_GetFrmMinHeight(*this);
247 [ + - ]: 62 : nMinHeight -= pAttrs->CalcTop();
248 [ + - ]: 62 : nMinHeight -= pAttrs->CalcBottom();
249 : :
250 [ - + ]: 62 : if (nMinHeight < 0)
251 : 0 : nMinHeight = 0;
252 : :
253 : 62 : ColLock();
254 : :
255 : 62 : SwTwips nMaxHeight = LONG_MAX;
256 : : SwTwips nRemaining, nOldHeight;
257 : : // #i64301#
258 : : // use the position of the footer printing area to control invalidation
259 : : // of the first footer content.
260 : 62 : Point aOldFooterPrtPos;
261 : :
262 [ + - + - ]: 108 : do
[ + - ]
263 : : {
264 : 116 : nOldHeight = Prt().Height();
265 : 116 : SwFrm* pFrm = Lower();
266 : : // #i64301#
267 [ + + ]: 348 : if ( pFrm &&
[ + - + + ]
268 [ + - ]: 232 : aOldFooterPrtPos != ( Frm().Pos() + Prt().Pos() ) )
269 : : {
270 [ + - ]: 83 : pFrm->_InvalidatePos();
271 : 83 : aOldFooterPrtPos = Frm().Pos() + Prt().Pos();
272 : : }
273 [ + + ]: 265 : while( pFrm )
274 : : {
275 [ + - ]: 149 : pFrm->Calc();
276 : : // #i43771# - format also object anchored
277 : : // at the frame
278 : : // #i46941# - frame has to be valid.
279 : : // Note: frame could be invalid after calling its format,
280 : : // if it's locked
281 : : OSL_ENSURE( StackHack::IsLocked() || !pFrm->IsTxtFrm() ||
282 : : pFrm->IsValid() ||
283 : : static_cast<SwTxtFrm*>(pFrm)->IsJoinLocked(),
284 : : "<SwHeadFootFrm::FormatSize(..)> - text frame invalid and not locked." );
285 [ + + ][ + - ]: 149 : if ( pFrm->IsTxtFrm() && pFrm->IsValid() )
[ + + ]
286 : : {
287 [ - + ]: 140 : if ( !SwObjectFormatter::FormatObjsAtFrm( *pFrm,
288 [ + - ][ + - ]: 140 : *(pFrm->FindPageFrm()) ) )
289 : : {
290 : : // restart format with first content
291 : 0 : pFrm = Lower();
292 : 0 : continue;
293 : : }
294 : : }
295 : 149 : pFrm = pFrm->GetNext();
296 : : }
297 : 116 : nRemaining = 0;
298 : 116 : pFrm = Lower();
299 : :
300 [ + + ]: 265 : while ( pFrm )
301 : : {
302 : 149 : nRemaining += pFrm->Frm().Height();
303 : :
304 [ + + ]: 289 : if( pFrm->IsTxtFrm() &&
[ + + + + ]
305 : 140 : ((SwTxtFrm*)pFrm)->IsUndersized() )
306 : : // This TxtFrm would like to be a bit bigger
307 [ + - ]: 66 : nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
308 : 66 : - pFrm->Prt().Height();
309 [ - + # # ]: 83 : else if( pFrm->IsSctFrm() &&
[ - + ]
310 : 0 : ((SwSectionFrm*)pFrm)->IsUndersized() )
311 [ # # ]: 0 : nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
312 : 149 : pFrm = pFrm->GetNext();
313 : : }
314 [ + + ]: 116 : if ( nRemaining < nMinHeight )
315 : 5 : nRemaining = nMinHeight;
316 : :
317 : 116 : SwTwips nDiff = nRemaining - nOldHeight;
318 : :
319 [ + + ]: 116 : if( !nDiff )
320 : 62 : break;
321 [ - + ]: 54 : if( nDiff < 0 )
322 : : {
323 : 0 : nMaxHeight = nOldHeight;
324 : :
325 [ # # ]: 0 : if( nRemaining <= nMinHeight )
326 : 0 : nRemaining = ( nMaxHeight + nMinHeight + 1 ) / 2;
327 : : }
328 : : else
329 : : {
330 [ - + ]: 54 : if (nOldHeight > nMinHeight)
331 : 0 : nMinHeight = nOldHeight;
332 : :
333 [ - + ]: 54 : if( nRemaining >= nMaxHeight )
334 : 0 : nRemaining = ( nMaxHeight + nMinHeight + 1 ) / 2;
335 : : }
336 : :
337 : 54 : nDiff = nRemaining - nOldHeight;
338 : :
339 [ + - ]: 54 : if ( nDiff )
340 : : {
341 : 54 : ColUnlock();
342 [ + - ]: 54 : if ( nDiff > 0 )
343 : : {
344 [ + - ][ + - ]: 54 : if ( Grow( nDiff ) )
345 : : {
346 : 54 : pFrm = Lower();
347 : :
348 [ + + ]: 123 : while ( pFrm )
349 : : {
350 [ + + ]: 69 : if( pFrm->IsTxtFrm())
351 : : {
352 : 66 : SwTxtFrm * pTmpFrm = (SwTxtFrm*) pFrm;
353 [ + - ]: 66 : if (pTmpFrm->IsUndersized() )
354 : : {
355 [ + - ]: 66 : pTmpFrm->InvalidateSize();
356 [ + - ]: 66 : pTmpFrm->Prepare(PREP_ADJUST_FRM);
357 : : }
358 : : }
359 : : /* #i3568# Undersized sections need to be
360 : : invalidated too. */
361 [ - + ]: 3 : else if (pFrm->IsSctFrm())
362 : : {
363 : : SwSectionFrm * pTmpFrm =
364 : 0 : (SwSectionFrm*) pFrm;
365 [ # # ]: 0 : if (pTmpFrm->IsUndersized() )
366 : : {
367 [ # # ]: 0 : pTmpFrm->InvalidateSize();
368 [ # # ]: 0 : pTmpFrm->Prepare(PREP_ADJUST_FRM);
369 : : }
370 : : }
371 : 69 : pFrm = pFrm->GetNext();
372 : : }
373 : : }
374 : : }
375 : : else
376 [ # # ]: 0 : Shrink( -nDiff );
377 : : // Quickly update the position
378 : :
379 [ + - ]: 54 : MakePos();
380 : 54 : ColLock();
381 : : }
382 : : else
383 : 0 : break;
384 : : // Don't overwrite the lower edge of the upper
385 [ + - ][ + - ]: 54 : if ( GetUpper() && Frm().Height() )
[ + - ]
386 : : {
387 : 54 : const SwTwips nDeadLine = GetUpper()->Frm().Top() +
388 : 54 : GetUpper()->Prt().Bottom();
389 : 54 : const SwTwips nBot = Frm().Bottom();
390 [ - + ]: 54 : if ( nBot > nDeadLine )
391 : : {
392 : 0 : Frm().Bottom( nDeadLine );
393 : 0 : Prt().SSize().Height() = Frm().Height() - nBorder;
394 : : }
395 : : }
396 : 54 : bValidSize = bValidPrtArea = sal_True;
397 : 54 : } while( nRemaining<=nMaxHeight && nOldHeight!=Prt().Height() );
398 : 62 : ColUnlock();
399 : : }
400 : 62 : bValidSize = bValidPrtArea = sal_True;
401 : : }
402 : : else //if ( GetType() & 0x0018 )
403 : : {
404 [ - + ]: 4 : do
405 : : {
406 [ + - ]: 4 : if ( Frm().Height() != pAttrs->GetSize().Height() )
407 [ + - ]: 4 : ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
408 : 4 : bValidSize = sal_True;
409 : 4 : MakePos();
410 : 4 : } while ( !bValidSize );
411 : : }
412 : 66 : }
413 : :
414 : 144 : void SwHeadFootFrm::Format(const SwBorderAttrs * pAttrs)
415 : : {
416 : : OSL_ENSURE( pAttrs, "SwFooterFrm::Format, pAttrs is 0." );
417 : :
418 [ - + ][ # # ]: 144 : if ( bValidPrtArea && bValidSize )
419 : 144 : return;
420 : :
421 [ + + ][ + + ]: 144 : if ( ! GetEatSpacing() && IsHeaderFrm())
[ + + ]
422 : : {
423 : 74 : SwLayoutFrm::Format(pAttrs);
424 : : }
425 : : else
426 : : {
427 [ + - ]: 70 : lcl_LayoutFrmEnsureMinHeight(*this, pAttrs);
428 : :
429 [ + - ][ + - ]: 70 : long nUL = pAttrs->CalcTop() + pAttrs->CalcBottom();
430 : :
431 [ + - ]: 70 : if ( !bValidPrtArea )
432 [ + - ]: 70 : FormatPrt(nUL, pAttrs);
433 : :
434 [ + + ]: 70 : if ( !bValidSize )
435 [ + - ]: 70 : FormatSize(nUL, pAttrs);
436 : : }
437 : : }
438 : :
439 : 326 : SwTwips SwHeadFootFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
440 : : {
441 : : SwTwips nResult;
442 : :
443 [ + + ]: 326 : if ( IsColLocked() )
444 : : {
445 : 141 : nResult = 0;
446 : : }
447 [ + + ]: 185 : else if (!GetEatSpacing())
448 : : {
449 : 74 : nResult = SwLayoutFrm::GrowFrm(nDist, bTst, bInfo);
450 : : }
451 : : else
452 : : {
453 : 111 : nResult = 0;
454 : :
455 : : SwBorderAttrAccess * pAccess =
456 [ + - ]: 111 : new SwBorderAttrAccess( SwFrm::GetCache(), this );
457 : : OSL_ENSURE(pAccess, "no border attributes");
458 : :
459 : 111 : SwBorderAttrs * pAttrs = pAccess->Get();
460 : :
461 : : /* First assume the whole amount to grow can be provided by eating
462 : : spacing. */
463 : 111 : SwTwips nEat = nDist;
464 : : SwTwips nMaxEat;
465 : :
466 : : /* calculate maximum eatable spacing */
467 [ + + ]: 111 : if (IsHeaderFrm())
468 : 69 : nMaxEat = aFrm.Height() - aPrt.Top() - aPrt.Height() - pAttrs->CalcBottomLine();
469 : : else
470 : 42 : nMaxEat = aPrt.Top() - pAttrs->CalcTopLine();
471 : :
472 [ + - ]: 111 : delete pAccess;
473 : :
474 [ - + ]: 111 : if (nMaxEat < 0)
475 : 0 : nMaxEat = 0;
476 : :
477 : : /* If the frame is too small, eat less spacing thus letting the frame
478 : : grow more. */
479 : 111 : SwTwips nMinHeight = lcl_GetFrmMinHeight(*this);
480 : 111 : SwTwips nFrameTooSmall = nMinHeight - Frm().Height();
481 : :
482 [ + + ]: 111 : if (nFrameTooSmall > 0)
483 : 54 : nEat -= nFrameTooSmall;
484 : :
485 : : /* No negative eating, not eating more than allowed. */
486 [ - + ]: 111 : if (nEat < 0)
487 : 0 : nEat = 0;
488 [ + + ]: 111 : else if (nEat > nMaxEat)
489 : 12 : nEat = nMaxEat;
490 : :
491 : : // OD 10.04.2003 #108719# - Notify fly frame, if header frame
492 : : // grows. Consider, that 'normal' grow of layout frame already notifys
493 : : // the fly frames.
494 : 111 : sal_Bool bNotifyFlys = sal_False;
495 [ + + ]: 111 : if (nEat > 0)
496 : : {
497 [ + - ]: 54 : if ( ! bTst)
498 : : {
499 [ + + ]: 54 : if (! IsHeaderFrm())
500 : : {
501 : 21 : aPrt.Top(aPrt.Top() - nEat);
502 : 21 : aPrt.Height(aPrt.Height() - nEat);
503 : : }
504 : :
505 : 54 : InvalidateAll();
506 : : }
507 : :
508 : 54 : nResult += nEat;
509 : : // OD 14.04.2003 #108719# - trigger fly frame notify.
510 [ + + ]: 54 : if ( IsHeaderFrm() )
511 : : {
512 : 33 : bNotifyFlys = sal_True;
513 : : }
514 : : }
515 : :
516 [ + + ]: 111 : if (nDist - nEat > 0)
517 : : {
518 : : SwTwips nFrmGrow =
519 : 66 : SwLayoutFrm::GrowFrm( nDist - nEat, bTst, bInfo );
520 : :
521 : 66 : nResult += nFrmGrow;
522 [ + - ]: 66 : if ( nFrmGrow > 0 )
523 : : {
524 : 66 : bNotifyFlys = sal_False;
525 : : }
526 : : }
527 : :
528 : : // OD 10.04.2003 #108719# - notify fly frames, if necessary and triggered.
529 [ + - ][ + + ]: 111 : if ( ( nResult > 0 ) && bNotifyFlys )
530 : : {
531 : 24 : NotifyLowerObjs();
532 : : }
533 : : }
534 : :
535 [ + + ][ + - ]: 326 : if ( nResult && !bTst )
536 : 185 : SetCompletePaint();
537 : :
538 : 326 : return nResult;
539 : : }
540 : :
541 : 4 : SwTwips SwHeadFootFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
542 : : {
543 : : SwTwips nResult;
544 : :
545 [ - + ]: 4 : if ( IsColLocked() )
546 : : {
547 : 0 : nResult = 0;
548 : : }
549 [ + - ]: 4 : else if (! GetEatSpacing())
550 : : {
551 : 4 : nResult = SwLayoutFrm::ShrinkFrm(nDist, bTst, bInfo);
552 : : }
553 : : else
554 : : {
555 : 0 : nResult = 0;
556 : :
557 : 0 : SwTwips nMinHeight = lcl_GetFrmMinHeight(*this);
558 : 0 : SwTwips nOldHeight = Frm().Height();
559 : 0 : SwTwips nRest = 0; // Amount to shrink by spitting out spacing
560 : :
561 [ # # ]: 0 : if ( nOldHeight >= nMinHeight )
562 : : {
563 : : /* If the frame's height is bigger than its minimum height, shrink
564 : : the frame towards its minimum height. If this is not sufficient
565 : : to provide the shrinking requested provide the rest by spitting
566 : : out spacing. */
567 : :
568 : 0 : SwTwips nBiggerThanMin = nOldHeight - nMinHeight;
569 : :
570 [ # # ]: 0 : if (nBiggerThanMin < nDist)
571 : : {
572 : 0 : nRest = nDist - nBiggerThanMin;
573 : : }
574 : : /* info: declaration of nRest -> else nRest = 0 */
575 : : }
576 : : else
577 : : /* The frame cannot shrink. Provide shrinking by spitting out
578 : : spacing. */
579 : 0 : nRest = nDist;
580 : :
581 : : // OD 10.04.2003 #108719# - Notify fly frame, if header/footer frame
582 : : // shrinks. Consider, that 'normal' shrink of layout frame already notifys
583 : : // the fly frames.
584 : 0 : sal_Bool bNotifyFlys = sal_False;
585 [ # # ]: 0 : if (nRest > 0)
586 : : {
587 : :
588 : : SwBorderAttrAccess * pAccess =
589 [ # # ]: 0 : new SwBorderAttrAccess( SwFrm::GetCache(), this );
590 : : OSL_ENSURE(pAccess, "no border attributes");
591 : :
592 : 0 : SwBorderAttrs * pAttrs = pAccess->Get();
593 : :
594 : : /* minimal height of print area */
595 : : SwTwips nMinPrtHeight = nMinHeight
596 : 0 : - pAttrs->CalcTop()
597 : 0 : - pAttrs->CalcBottom();
598 : :
599 [ # # ]: 0 : if (nMinPrtHeight < 0)
600 : 0 : nMinPrtHeight = 0;
601 : :
602 [ # # ]: 0 : delete pAccess;
603 : :
604 : : /* assume all shrinking can be provided */
605 : 0 : SwTwips nShrink = nRest;
606 : :
607 : : /* calculate maximum shrinking */
608 : 0 : SwTwips nMaxShrink = aPrt.Height() - nMinPrtHeight;
609 : :
610 : : /* shrink no more than maximum shrinking */
611 [ # # ]: 0 : if (nShrink > nMaxShrink)
612 : : {
613 : : //nRest -= nShrink - nMaxShrink;
614 : 0 : nShrink = nMaxShrink;
615 : : }
616 : :
617 [ # # ]: 0 : if (!bTst)
618 : : {
619 [ # # ]: 0 : if (! IsHeaderFrm() )
620 : : {
621 : 0 : aPrt.Top(aPrt.Top() + nShrink);
622 : 0 : aPrt.Height(aPrt.Height() - nShrink);
623 : : }
624 : :
625 : 0 : InvalidateAll();
626 : : }
627 : 0 : nResult += nShrink;
628 : : // OD 14.04.2003 #108719# - trigger fly frame notify.
629 [ # # ]: 0 : if ( IsHeaderFrm() )
630 : : {
631 : 0 : bNotifyFlys = sal_True;
632 : : }
633 : : }
634 : :
635 : : /* The shrinking not providable by spitting out spacing has to be done
636 : : by the frame. */
637 [ # # ]: 0 : if (nDist - nRest > 0)
638 : : {
639 : 0 : SwTwips nShrinkAmount = SwLayoutFrm::ShrinkFrm( nDist - nRest, bTst, bInfo );
640 : 0 : nResult += nShrinkAmount;
641 [ # # ]: 0 : if ( nShrinkAmount > 0 )
642 : : {
643 : 0 : bNotifyFlys = sal_False;
644 : : }
645 : : }
646 : :
647 : : // OD 10.04.2003 #108719# - notify fly frames, if necessary.
648 [ # # ][ # # ]: 0 : if ( ( nResult > 0 ) && bNotifyFlys )
649 : : {
650 : 0 : NotifyLowerObjs();
651 : : }
652 : : }
653 : :
654 : 4 : return nResult;
655 : : }
656 : :
657 : 403 : sal_Bool SwHeadFootFrm::GetEatSpacing() const
658 : : {
659 : 403 : const SwFrmFmt * pFmt = GetFmt();
660 : : OSL_ENSURE(pFmt, "SwHeadFootFrm: no format?");
661 : :
662 [ + + ]: 403 : if (pFmt->GetHeaderAndFooterEatSpacing().GetValue())
663 : 225 : return sal_True;
664 : :
665 : 403 : return sal_False;
666 : : }
667 : :
668 : :
669 : : /*************************************************************************
670 : : |*
671 : : |* SwPageFrm::PrepareHeader()
672 : : |*
673 : : |* Description Creates or removes headers
674 : : |*
675 : : |*************************************************************************/
676 : :
677 : :
678 : 0 : void DelFlys( SwLayoutFrm *pFrm, SwPageFrm *pPage )
679 : : {
680 [ # # # # : 0 : for ( int i = 0; pPage->GetSortedObjs() &&
# # ][ # # ]
681 : 0 : pPage->GetSortedObjs()->Count() &&
682 : 0 : i < (int)pPage->GetSortedObjs()->Count(); ++i )
683 : : {
684 : 0 : SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
685 [ # # ]: 0 : if ( pObj->ISA(SwFlyFrm) )
686 : : {
687 [ # # ]: 0 : SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
688 [ # # ]: 0 : if ( pFrm->IsAnLower( pFlyFrm ) )
689 : : {
690 [ # # ]: 0 : delete pFlyFrm;
691 : 0 : --i;
692 : : }
693 : : }
694 : : }
695 : 0 : }
696 : :
697 : :
698 : :
699 : 50 : void SwPageFrm::PrepareHeader()
700 : : {
701 : 50 : SwLayoutFrm *pLay = (SwLayoutFrm*)Lower();
702 [ - + ]: 50 : if ( !pLay )
703 : 0 : return;
704 : :
705 : 50 : const SwFmtHeader &rH = ((SwFrmFmt*)GetRegisteredIn())->GetHeader();
706 : :
707 : 50 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
708 [ + + ][ + - ]: 50 : const sal_Bool bOn = !(pSh && pSh->GetViewOptions()->getBrowseMode());
709 : :
710 [ + + ][ + + ]: 50 : if ( bOn && rH.IsActive() )
[ + + ]
711 : : { //Implant header, but remove first, if already present
712 : : OSL_ENSURE( rH.GetHeaderFmt(), "FrmFmt for Header not found." );
713 : :
714 [ - + ]: 38 : if ( pLay->GetFmt() == (SwFrmFmt*)rH.GetHeaderFmt() )
715 : 0 : return; // Header is already the correct one.
716 : :
717 [ - + ]: 38 : if ( pLay->IsHeaderFrm() )
718 : 0 : { SwLayoutFrm *pDel = pLay;
719 : 0 : pLay = (SwLayoutFrm*)pLay->GetNext();
720 : 0 : ::DelFlys( pDel, this );
721 : 0 : pDel->Cut();
722 [ # # ]: 0 : delete pDel;
723 : : }
724 : : OSL_ENSURE( pLay, "Where to with the Header?" );
725 [ + - ]: 38 : SwHeaderFrm *pH = new SwHeaderFrm( (SwFrmFmt*)rH.GetHeaderFmt(), this );
726 : 38 : pH->Paste( this, pLay );
727 [ + + ]: 38 : if ( GetUpper() )
728 : 2 : ::RegistFlys( this, pH );
729 : : }
730 [ + - ][ - + ]: 12 : else if ( pLay && pLay->IsHeaderFrm() )
[ - + ]
731 : : { // Remove header if present.
732 : 0 : ::DelFlys( pLay, this );
733 : 0 : pLay->Cut();
734 [ # # ]: 50 : delete pLay;
735 : : }
736 : : }
737 : : /*************************************************************************
738 : : |*
739 : : |* SwPageFrm::PrepareFooter()
740 : : |*
741 : : |* Description Creates or removes footer
742 : : |*
743 : : |*************************************************************************/
744 : :
745 : :
746 : 44 : void SwPageFrm::PrepareFooter()
747 : : {
748 : 44 : SwLayoutFrm *pLay = (SwLayoutFrm*)Lower();
749 [ - + ]: 44 : if ( !pLay )
750 : 0 : return;
751 : :
752 : 44 : const SwFmtFooter &rF = ((SwFrmFmt*)GetRegisteredIn())->GetFooter();
753 [ + + ]: 69 : while ( pLay->GetNext() )
754 : 25 : pLay = (SwLayoutFrm*)pLay->GetNext();
755 : :
756 : 44 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
757 [ + + ][ + - ]: 44 : const sal_Bool bOn = !(pSh && pSh->GetViewOptions()->getBrowseMode());
758 : :
759 [ + + ][ + + ]: 44 : if ( bOn && rF.IsActive() )
[ + + ]
760 : : { //Implant footer, but remove first, if already present
761 : : OSL_ENSURE( rF.GetFooterFmt(), "FrmFmt for Footer not found." );
762 : :
763 [ - + ]: 30 : if ( pLay->GetFmt() == (SwFrmFmt*)rF.GetFooterFmt() )
764 : 0 : return; // Footer is already the correct one.
765 : :
766 [ - + ]: 30 : if ( pLay->IsFooterFrm() )
767 : 0 : { ::DelFlys( pLay, this );
768 : 0 : pLay->Cut();
769 [ # # ]: 0 : delete pLay;
770 : : }
771 [ + - ]: 30 : SwFooterFrm *pF = new SwFooterFrm( (SwFrmFmt*)rF.GetFooterFmt(), this );
772 : 30 : pF->Paste( this );
773 [ + + ]: 30 : if ( GetUpper() )
774 : 2 : ::RegistFlys( this, pF );
775 : : }
776 [ + - ][ - + ]: 14 : else if ( pLay && pLay->IsFooterFrm() )
[ - + ]
777 : : { // Remove footer if already present
778 : 0 : ::DelFlys( pLay, this );
779 : : ViewShell *pShell;
780 [ # # # # ]: 0 : if ( pLay->GetPrev() && 0 != (pShell = getRootFrm()->GetCurrShell()) &&
[ # # ][ # # ]
781 : 0 : pShell->VisArea().HasArea() )
782 : 0 : pShell->InvalidateWindows( pShell->VisArea() );
783 : 0 : pLay->Cut();
784 [ # # ]: 44 : delete pLay;
785 : : }
786 : : }
787 : :
788 : :
789 : :
790 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|