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