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