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 554 : static SwTwips lcl_GetFrmMinHeight(const SwLayoutFrm & rFrm)
46 : {
47 554 : const SwFmtFrmSize &rSz = rFrm.GetFmt()->GetFrmSize();
48 : SwTwips nMinHeight;
49 :
50 554 : switch (rSz.GetHeightSizeType())
51 : {
52 : case ATT_MIN_SIZE:
53 554 : nMinHeight = rSz.GetHeight();
54 :
55 554 : break;
56 :
57 : default:
58 0 : nMinHeight = 0;
59 : }
60 :
61 :
62 554 : return nMinHeight;
63 : }
64 :
65 :
66 100 : static SwTwips lcl_CalcContentHeight(SwLayoutFrm & frm)
67 : {
68 100 : SwTwips nRemaining = 0;
69 100 : sal_uInt16 nNum = 0;
70 100 : SwFrm* pFrm = frm.Lower();
71 :
72 312 : while ( pFrm )
73 : {
74 : SwTwips nTmp;
75 :
76 112 : nTmp = pFrm->Frm().Height();
77 112 : nRemaining += nTmp;
78 112 : 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 112 : else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
86 : {
87 0 : nTmp = ((SwSectionFrm*)pFrm)->Undersize();
88 0 : nRemaining += nTmp;
89 : }
90 112 : pFrm = pFrm->GetNext();
91 :
92 112 : nNum++;
93 : }
94 :
95 100 : return nRemaining;
96 : }
97 :
98 128 : static void lcl_LayoutFrmEnsureMinHeight(SwLayoutFrm & rFrm,
99 : const SwBorderAttrs * )
100 : {
101 128 : SwTwips nMinHeight = lcl_GetFrmMinHeight(rFrm);
102 :
103 128 : if (rFrm.Frm().Height() < nMinHeight)
104 : {
105 126 : rFrm.Grow(nMinHeight - rFrm.Frm().Height());
106 : }
107 128 : }
108 :
109 152 : SwHeadFootFrm::SwHeadFootFrm( SwFrmFmt * pFmt, SwFrm* pSib, sal_uInt16 nTypeIn)
110 152 : : SwLayoutFrm( pFmt, pSib )
111 : {
112 152 : nType = nTypeIn;
113 152 : SetDerivedVert( sal_False );
114 :
115 152 : 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 152 : bool bOld = bObjsDirect;
121 152 : bObjsDirect = true;
122 152 : sal_uLong nIndex = rCnt.GetCntntIdx()->GetIndex();
123 152 : ::_InsertCnt( this, pFmt->GetDoc(), ++nIndex );
124 152 : bObjsDirect = bOld;
125 152 : }
126 :
127 128 : void SwHeadFootFrm::FormatPrt(SwTwips & nUL, const SwBorderAttrs * pAttrs)
128 : {
129 128 : 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 100 : SwTwips nMinHeight = lcl_GetFrmMinHeight(*this);
134 :
135 100 : nMinHeight -= pAttrs->CalcTop();
136 100 : nMinHeight -= pAttrs->CalcBottom();
137 :
138 : /* If the minimal height of the print area is negative, try to
139 : compensate by overlapping */
140 100 : SwTwips nOverlap = 0;
141 100 : 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 100 : if ( ! HasFixSize() )
152 100 : nHeight = lcl_CalcContentHeight(*this);
153 : else
154 0 : nHeight = nMinHeight;
155 :
156 100 : if (nHeight < nMinHeight)
157 98 : nHeight = nMinHeight;
158 :
159 : /* calculate initial spacing/line space */
160 : SwTwips nSpace, nLine;
161 :
162 100 : if (IsHeaderFrm())
163 : {
164 56 : nSpace = pAttrs->CalcBottom();
165 56 : nLine = pAttrs->CalcBottomLine();
166 : }
167 : else
168 : {
169 44 : nSpace = pAttrs->CalcTop();
170 44 : nLine = pAttrs->CalcTopLine();
171 : }
172 :
173 : /* calculate overlap and correct spacing */
174 100 : nOverlap += nHeight - nMinHeight;
175 100 : if (nOverlap < nSpace - nLine)
176 88 : nSpace -= nOverlap;
177 : else
178 12 : nSpace = nLine;
179 :
180 : /* calculate real vertical space between frame and print area */
181 100 : if (IsHeaderFrm())
182 56 : nUL = pAttrs->CalcTop() + nSpace;
183 : else
184 44 : nUL = pAttrs->CalcBottom() + nSpace;
185 :
186 : /* set print area */
187 : // OD 23.01.2003 #106895# - add first parameter to <SwBorderAttrs::CalcRight(..)>
188 100 : SwTwips nLR = pAttrs->CalcLeft( this ) + pAttrs->CalcRight( this );
189 :
190 100 : aPrt.Left(pAttrs->CalcLeft(this));
191 :
192 100 : if (IsHeaderFrm())
193 56 : aPrt.Top(pAttrs->CalcTop());
194 : else
195 44 : aPrt.Top(nSpace);
196 :
197 100 : aPrt.Width(aFrm.Width() - nLR);
198 :
199 : SwTwips nNewHeight;
200 :
201 100 : if (nUL < aFrm.Height())
202 100 : nNewHeight = aFrm.Height() - nUL;
203 : else
204 0 : nNewHeight = 0;
205 :
206 100 : aPrt.Height(nNewHeight);
207 :
208 : }
209 : else
210 : {
211 : // Set position
212 28 : aPrt.Left( pAttrs->CalcLeft( this ) );
213 28 : aPrt.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 28 : SwTwips nLR = pAttrs->CalcLeft( this ) + pAttrs->CalcRight( this );
219 28 : aPrt.Width ( aFrm.Width() - nLR );
220 28 : aPrt.Height( aFrm.Height()- nUL );
221 :
222 : }
223 :
224 128 : bValidPrtArea = sal_True;
225 128 : }
226 :
227 128 : void SwHeadFootFrm::FormatSize(SwTwips nUL, const SwBorderAttrs * pAttrs)
228 : {
229 128 : if ( !HasFixSize() )
230 : {
231 128 : if( !IsColLocked() )
232 : {
233 128 : bValidSize = bValidPrtArea = sal_True;
234 :
235 128 : const SwTwips nBorder = nUL;
236 128 : SwTwips nMinHeight = lcl_GetFrmMinHeight(*this);
237 128 : nMinHeight -= pAttrs->CalcTop();
238 128 : nMinHeight -= pAttrs->CalcBottom();
239 :
240 128 : if (nMinHeight < 0)
241 0 : nMinHeight = 0;
242 :
243 128 : ColLock();
244 :
245 128 : 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 128 : Point aOldFooterPrtPos;
251 :
252 196 : do
253 : {
254 226 : nOldHeight = Prt().Height();
255 226 : SwFrm* pFrm = Lower();
256 : // #i64301#
257 904 : if ( pFrm &&
258 678 : aOldFooterPrtPos != ( Frm().Pos() + Prt().Pos() ) )
259 : {
260 172 : pFrm->_InvalidatePos();
261 172 : aOldFooterPrtPos = Frm().Pos() + Prt().Pos();
262 : }
263 700 : while( pFrm )
264 : {
265 248 : 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 248 : if ( pFrm->IsTxtFrm() && pFrm->IsValid() )
276 : {
277 242 : if ( !SwObjectFormatter::FormatObjsAtFrm( *pFrm,
278 242 : *(pFrm->FindPageFrm()) ) )
279 : {
280 : // restart format with first content
281 0 : pFrm = Lower();
282 0 : continue;
283 : }
284 : }
285 248 : pFrm = pFrm->GetNext();
286 : }
287 226 : nRemaining = 0;
288 226 : pFrm = Lower();
289 :
290 700 : while ( pFrm )
291 : {
292 248 : nRemaining += pFrm->Frm().Height();
293 :
294 490 : if( pFrm->IsTxtFrm() &&
295 242 : ((SwTxtFrm*)pFrm)->IsUndersized() )
296 : // This TxtFrm would like to be a bit bigger
297 106 : nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
298 106 : - pFrm->Prt().Height();
299 142 : else if( pFrm->IsSctFrm() &&
300 0 : ((SwSectionFrm*)pFrm)->IsUndersized() )
301 0 : nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
302 248 : pFrm = pFrm->GetNext();
303 : }
304 226 : if ( nRemaining < nMinHeight )
305 28 : nRemaining = nMinHeight;
306 :
307 226 : SwTwips nDiff = nRemaining - nOldHeight;
308 :
309 226 : if( !nDiff )
310 128 : break;
311 98 : 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 98 : if (nOldHeight > nMinHeight)
321 0 : nMinHeight = nOldHeight;
322 :
323 98 : if( nRemaining >= nMaxHeight )
324 0 : nRemaining = ( nMaxHeight + nMinHeight + 1 ) / 2;
325 : }
326 :
327 98 : nDiff = nRemaining - nOldHeight;
328 :
329 98 : if ( nDiff )
330 : {
331 98 : ColUnlock();
332 98 : if ( nDiff > 0 )
333 : {
334 98 : if ( Grow( nDiff ) )
335 : {
336 98 : pFrm = Lower();
337 :
338 304 : while ( pFrm )
339 : {
340 108 : if( pFrm->IsTxtFrm())
341 : {
342 106 : SwTxtFrm * pTmpFrm = (SwTxtFrm*) pFrm;
343 106 : if (pTmpFrm->IsUndersized() )
344 : {
345 106 : pTmpFrm->InvalidateSize();
346 106 : pTmpFrm->Prepare(PREP_ADJUST_FRM);
347 : }
348 : }
349 : /* #i3568# Undersized sections need to be
350 : invalidated too. */
351 2 : 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 108 : pFrm = pFrm->GetNext();
362 : }
363 : }
364 : }
365 : else
366 0 : Shrink( -nDiff );
367 : // Quickly update the position
368 :
369 98 : MakePos();
370 98 : ColLock();
371 : }
372 : else
373 0 : break;
374 : // Don't overwrite the lower edge of the upper
375 196 : if ( GetUpper() && Frm().Height() )
376 : {
377 98 : const SwTwips nDeadLine = GetUpper()->Frm().Top() +
378 98 : GetUpper()->Prt().Bottom();
379 98 : const SwTwips nBot = Frm().Bottom();
380 98 : if ( nBot > nDeadLine )
381 : {
382 0 : Frm().Bottom( nDeadLine );
383 0 : Prt().SSize().Height() = Frm().Height() - nBorder;
384 : }
385 : }
386 98 : bValidSize = bValidPrtArea = sal_True;
387 98 : } while( nRemaining<=nMaxHeight && nOldHeight!=Prt().Height() );
388 128 : ColUnlock();
389 : }
390 128 : bValidSize = bValidPrtArea = sal_True;
391 : }
392 : else //if ( GetType() & 0x0018 )
393 : {
394 0 : do
395 : {
396 0 : if ( Frm().Height() != pAttrs->GetSize().Height() )
397 0 : ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
398 0 : bValidSize = sal_True;
399 0 : MakePos();
400 0 : } while ( !bValidSize );
401 : }
402 128 : }
403 :
404 180 : void SwHeadFootFrm::Format(const SwBorderAttrs * pAttrs)
405 : {
406 : OSL_ENSURE( pAttrs, "SwFooterFrm::Format, pAttrs is 0." );
407 :
408 180 : if ( bValidPrtArea && bValidSize )
409 180 : return;
410 :
411 180 : if ( ! GetEatSpacing() && IsHeaderFrm())
412 : {
413 52 : SwLayoutFrm::Format(pAttrs);
414 : }
415 : else
416 : {
417 128 : lcl_LayoutFrmEnsureMinHeight(*this, pAttrs);
418 :
419 128 : long nUL = pAttrs->CalcTop() + pAttrs->CalcBottom();
420 :
421 128 : if ( !bValidPrtArea )
422 128 : FormatPrt(nUL, pAttrs);
423 :
424 128 : if ( !bValidSize )
425 128 : FormatSize(nUL, pAttrs);
426 : }
427 : }
428 :
429 450 : SwTwips SwHeadFootFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
430 : {
431 : SwTwips nResult;
432 :
433 450 : if ( IsColLocked() )
434 : {
435 198 : nResult = 0;
436 : }
437 252 : else if (!GetEatSpacing())
438 : {
439 54 : nResult = SwLayoutFrm::GrowFrm(nDist, bTst, bInfo);
440 : }
441 : else
442 : {
443 198 : nResult = 0;
444 :
445 : SwBorderAttrAccess * pAccess =
446 198 : new SwBorderAttrAccess( SwFrm::GetCache(), this );
447 : OSL_ENSURE(pAccess, "no border attributes");
448 :
449 198 : SwBorderAttrs * pAttrs = pAccess->Get();
450 :
451 : /* First assume the whole amount to grow can be provided by eating
452 : spacing. */
453 198 : SwTwips nEat = nDist;
454 : SwTwips nMaxEat;
455 :
456 : /* calculate maximum eatable spacing */
457 198 : if (IsHeaderFrm())
458 110 : nMaxEat = aFrm.Height() - aPrt.Top() - aPrt.Height() - pAttrs->CalcBottomLine();
459 : else
460 88 : nMaxEat = aPrt.Top() - pAttrs->CalcTopLine();
461 :
462 198 : delete pAccess;
463 :
464 198 : 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 198 : SwTwips nMinHeight = lcl_GetFrmMinHeight(*this);
470 198 : SwTwips nFrameTooSmall = nMinHeight - Frm().Height();
471 :
472 198 : if (nFrameTooSmall > 0)
473 98 : nEat -= nFrameTooSmall;
474 :
475 : /* No negative eating, not eating more than allowed. */
476 198 : if (nEat < 0)
477 0 : nEat = 0;
478 198 : else if (nEat > nMaxEat)
479 16 : 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 198 : sal_Bool bNotifyFlys = sal_False;
485 198 : if (nEat > 0)
486 : {
487 90 : if ( ! bTst)
488 : {
489 90 : if (! IsHeaderFrm())
490 : {
491 40 : aPrt.Top(aPrt.Top() - nEat);
492 40 : aPrt.Height(aPrt.Height() - nEat);
493 : }
494 :
495 90 : InvalidateAll();
496 : }
497 :
498 90 : nResult += nEat;
499 : // OD 14.04.2003 #108719# - trigger fly frame notify.
500 90 : if ( IsHeaderFrm() )
501 : {
502 50 : bNotifyFlys = sal_True;
503 : }
504 : }
505 :
506 198 : if (nDist - nEat > 0)
507 : {
508 : SwTwips nFrmGrow =
509 114 : SwLayoutFrm::GrowFrm( nDist - nEat, bTst, bInfo );
510 :
511 114 : nResult += nFrmGrow;
512 114 : if ( nFrmGrow > 0 )
513 : {
514 114 : bNotifyFlys = sal_False;
515 : }
516 : }
517 :
518 : // OD 10.04.2003 #108719# - notify fly frames, if necessary and triggered.
519 198 : if ( ( nResult > 0 ) && bNotifyFlys )
520 : {
521 44 : NotifyLowerObjs();
522 : }
523 : }
524 :
525 450 : if ( nResult && !bTst )
526 252 : SetCompletePaint();
527 :
528 450 : return nResult;
529 : }
530 :
531 0 : SwTwips SwHeadFootFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
532 : {
533 : SwTwips nResult;
534 :
535 0 : if ( IsColLocked() )
536 : {
537 0 : nResult = 0;
538 : }
539 0 : else if (! GetEatSpacing())
540 : {
541 0 : 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 = aPrt.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 : aPrt.Top(aPrt.Top() + nShrink);
612 0 : aPrt.Height(aPrt.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 0 : return nResult;
645 : }
646 :
647 560 : sal_Bool SwHeadFootFrm::GetEatSpacing() const
648 : {
649 560 : const SwFrmFmt * pFmt = GetFmt();
650 : OSL_ENSURE(pFmt, "SwHeadFootFrm: no format?");
651 :
652 560 : if (pFmt->GetHeaderAndFooterEatSpacing().GetValue())
653 398 : return sal_True;
654 :
655 162 : 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 80 : void SwPageFrm::PrepareHeader()
690 : {
691 80 : SwLayoutFrm *pLay = (SwLayoutFrm*)Lower();
692 80 : if ( !pLay )
693 0 : return;
694 :
695 80 : const SwFmtHeader &rH = ((SwFrmFmt*)GetRegisteredIn())->GetHeader();
696 :
697 80 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
698 80 : const sal_Bool bOn = !(pSh && pSh->GetViewOptions()->getBrowseMode());
699 :
700 80 : 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 80 : if ( pLay->GetFmt() == (SwFrmFmt*)rH.GetHeaderFmt() )
705 0 : return; // Header is already the correct one.
706 :
707 80 : 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 80 : SwHeaderFrm *pH = new SwHeaderFrm( (SwFrmFmt*)rH.GetHeaderFmt(), this );
716 80 : pH->Paste( this, pLay );
717 80 : if ( GetUpper() )
718 0 : ::RegistFlys( this, pH );
719 : }
720 0 : 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 72 : void SwPageFrm::PrepareFooter()
737 : {
738 72 : SwLayoutFrm *pLay = (SwLayoutFrm*)Lower();
739 72 : if ( !pLay )
740 0 : return;
741 :
742 72 : const SwFmtFooter &rF = ((SwFrmFmt*)GetRegisteredIn())->GetFooter();
743 210 : while ( pLay->GetNext() )
744 66 : pLay = (SwLayoutFrm*)pLay->GetNext();
745 :
746 72 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
747 72 : const sal_Bool bOn = !(pSh && pSh->GetViewOptions()->getBrowseMode());
748 :
749 72 : 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 72 : if ( pLay->GetFmt() == (SwFrmFmt*)rF.GetFooterFmt() )
754 0 : return; // Footer is already the correct one.
755 :
756 72 : if ( pLay->IsFooterFrm() )
757 0 : { ::DelFlys( pLay, this );
758 0 : pLay->Cut();
759 0 : delete pLay;
760 : }
761 72 : SwFooterFrm *pF = new SwFooterFrm( (SwFrmFmt*)rF.GetFooterFmt(), this );
762 72 : pF->Paste( this );
763 72 : if ( GetUpper() )
764 0 : ::RegistFlys( this, pF );
765 : }
766 0 : 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 : }
777 :
778 :
779 :
780 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|