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