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