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 #include "viewsh.hxx"
27cdf0e10cSrcweir #include "doc.hxx"
28cdf0e10cSrcweir #include "pagefrm.hxx"
29cdf0e10cSrcweir #include "rootfrm.hxx"
30cdf0e10cSrcweir #include "ndtxt.hxx"
31cdf0e10cSrcweir #include "txtatr.hxx"
32cdf0e10cSrcweir #include <SwPortionHandler.hxx>
33cdf0e10cSrcweir #include <txtftn.hxx>
34cdf0e10cSrcweir #include <flyfrm.hxx>
35cdf0e10cSrcweir #include <fmtftn.hxx>
36cdf0e10cSrcweir #include <ftninfo.hxx>
37cdf0e10cSrcweir #include <charfmt.hxx>
38cdf0e10cSrcweir #include <dflyobj.hxx>
39cdf0e10cSrcweir #include <rowfrm.hxx>
40cdf0e10cSrcweir #include <editeng/brshitem.hxx>
41cdf0e10cSrcweir #include <editeng/charrotateitem.hxx>
42cdf0e10cSrcweir #include <breakit.hxx>
43cdf0e10cSrcweir #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
44cdf0e10cSrcweir #include <com/sun/star/i18n/ScriptType.hdl>
45cdf0e10cSrcweir #endif
46cdf0e10cSrcweir #include <tabfrm.hxx>
47cdf0e10cSrcweir // OD 2004-05-24 #i28701#
48cdf0e10cSrcweir #include <sortedobjs.hxx>
49cdf0e10cSrcweir
50cdf0e10cSrcweir #include "txtcfg.hxx"
51cdf0e10cSrcweir #include "swfont.hxx" // new SwFont
52cdf0e10cSrcweir #include "porftn.hxx"
53cdf0e10cSrcweir #include "porfly.hxx"
54cdf0e10cSrcweir #include "porlay.hxx"
55cdf0e10cSrcweir #include "txtfrm.hxx"
56cdf0e10cSrcweir #include "itrform2.hxx"
57cdf0e10cSrcweir #include "ftnfrm.hxx" // FindQuoVadisFrm(),
58cdf0e10cSrcweir #include "pagedesc.hxx"
59cdf0e10cSrcweir #include "redlnitr.hxx" // SwRedlnItr
60cdf0e10cSrcweir #include "sectfrm.hxx" // SwSectionFrm
61cdf0e10cSrcweir #include "layouter.hxx" // Endnote-Collection
62cdf0e10cSrcweir #include "frmtool.hxx"
63cdf0e10cSrcweir #include "ndindex.hxx"
64cdf0e10cSrcweir
65cdf0e10cSrcweir using namespace ::com::sun::star;
66cdf0e10cSrcweir
67cdf0e10cSrcweir /*************************************************************************
68cdf0e10cSrcweir * _IsFtnNumFrm()
69cdf0e10cSrcweir *************************************************************************/
70cdf0e10cSrcweir
_IsFtnNumFrm() const71cdf0e10cSrcweir sal_Bool SwTxtFrm::_IsFtnNumFrm() const
72cdf0e10cSrcweir {
73cdf0e10cSrcweir const SwFtnFrm* pFtn = FindFtnFrm()->GetMaster();
74cdf0e10cSrcweir while( pFtn && !pFtn->ContainsCntnt() )
75cdf0e10cSrcweir pFtn = pFtn->GetMaster();
76cdf0e10cSrcweir return !pFtn;
77cdf0e10cSrcweir }
78cdf0e10cSrcweir
79cdf0e10cSrcweir /*************************************************************************
80cdf0e10cSrcweir * FindFtn()
81cdf0e10cSrcweir *************************************************************************/
82cdf0e10cSrcweir
83cdf0e10cSrcweir // Sucht innerhalb einer Master-Follow-Kette den richtigen TxtFrm zum SwTxtFtn
84cdf0e10cSrcweir
FindFtnRef(const SwTxtFtn * pFtn)85cdf0e10cSrcweir SwTxtFrm *SwTxtFrm::FindFtnRef( const SwTxtFtn *pFtn )
86cdf0e10cSrcweir {
87cdf0e10cSrcweir SwTxtFrm *pFrm = this;
88cdf0e10cSrcweir const sal_Bool bFwd = *pFtn->GetStart() >= GetOfst();
89cdf0e10cSrcweir while( pFrm )
90cdf0e10cSrcweir {
91cdf0e10cSrcweir if( SwFtnBossFrm::FindFtn( pFrm, pFtn ) )
92cdf0e10cSrcweir return pFrm;
93cdf0e10cSrcweir pFrm = bFwd ? pFrm->GetFollow() :
94cdf0e10cSrcweir pFrm->IsFollow() ? pFrm->FindMaster() : 0;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir return pFrm;
97cdf0e10cSrcweir }
98cdf0e10cSrcweir
99cdf0e10cSrcweir /*************************************************************************
100cdf0e10cSrcweir * CalcFtnFlag()
101cdf0e10cSrcweir *************************************************************************/
102cdf0e10cSrcweir
103cdf0e10cSrcweir #ifndef DBG_UTIL
CalcFtnFlag()104cdf0e10cSrcweir void SwTxtFrm::CalcFtnFlag()
105cdf0e10cSrcweir #else
106cdf0e10cSrcweir void SwTxtFrm::CalcFtnFlag( xub_StrLen nStop )//Fuer den Test von SplitFrm
107cdf0e10cSrcweir #endif
108cdf0e10cSrcweir {
109cdf0e10cSrcweir bFtn = sal_False;
110cdf0e10cSrcweir
111cdf0e10cSrcweir const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
112cdf0e10cSrcweir if( !pHints )
113cdf0e10cSrcweir return;
114cdf0e10cSrcweir
115cdf0e10cSrcweir const sal_uInt16 nSize = pHints->Count();
116cdf0e10cSrcweir
117cdf0e10cSrcweir #ifndef DBG_UTIL
118cdf0e10cSrcweir const xub_StrLen nEnd = GetFollow() ? GetFollow()->GetOfst() : STRING_LEN;
119cdf0e10cSrcweir #else
120cdf0e10cSrcweir const xub_StrLen nEnd = nStop != STRING_LEN ? nStop
121cdf0e10cSrcweir : GetFollow() ? GetFollow()->GetOfst() : STRING_LEN;
122cdf0e10cSrcweir #endif
123cdf0e10cSrcweir
124cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nSize; ++i )
125cdf0e10cSrcweir {
126cdf0e10cSrcweir const SwTxtAttr *pHt = (*pHints)[i];
127cdf0e10cSrcweir if ( pHt->Which() == RES_TXTATR_FTN )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir const xub_StrLen nIdx = *pHt->GetStart();
130cdf0e10cSrcweir if ( nEnd < nIdx )
131cdf0e10cSrcweir break;
132cdf0e10cSrcweir if( GetOfst() <= nIdx )
133cdf0e10cSrcweir {
134cdf0e10cSrcweir bFtn = sal_True;
135cdf0e10cSrcweir break;
136cdf0e10cSrcweir }
137cdf0e10cSrcweir }
138cdf0e10cSrcweir }
139cdf0e10cSrcweir }
140cdf0e10cSrcweir
141cdf0e10cSrcweir /*************************************************************************
142cdf0e10cSrcweir * CalcPrepFtnAdjust()
143cdf0e10cSrcweir *************************************************************************/
144cdf0e10cSrcweir
CalcPrepFtnAdjust()145cdf0e10cSrcweir sal_Bool SwTxtFrm::CalcPrepFtnAdjust()
146cdf0e10cSrcweir {
147cdf0e10cSrcweir ASSERT( HasFtn(), "Wer ruft mich da?" );
148cdf0e10cSrcweir SwFtnBossFrm *pBoss = FindFtnBossFrm( sal_True );
149cdf0e10cSrcweir const SwFtnFrm *pFtn = pBoss->FindFirstFtn( this );
150cdf0e10cSrcweir if( pFtn && FTNPOS_CHAPTER != GetNode()->GetDoc()->GetFtnInfo().ePos &&
151cdf0e10cSrcweir ( !pBoss->GetUpper()->IsSctFrm() ||
152cdf0e10cSrcweir !((SwSectionFrm*)pBoss->GetUpper())->IsFtnAtEnd() ) )
153cdf0e10cSrcweir {
154cdf0e10cSrcweir const SwFtnContFrm *pCont = pBoss->FindFtnCont();
155cdf0e10cSrcweir sal_Bool bReArrange = sal_True;
156cdf0e10cSrcweir
157cdf0e10cSrcweir SWRECTFN( this )
158cdf0e10cSrcweir if ( pCont && (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(),
159cdf0e10cSrcweir (Frm().*fnRect->fnGetBottom)() ) > 0 )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir pBoss->RearrangeFtns( (Frm().*fnRect->fnGetBottom)(), sal_False,
162cdf0e10cSrcweir pFtn->GetAttr() );
163cdf0e10cSrcweir ValidateBodyFrm();
164cdf0e10cSrcweir ValidateFrm();
165cdf0e10cSrcweir pFtn = pBoss->FindFirstFtn( this );
166cdf0e10cSrcweir }
167cdf0e10cSrcweir else
168cdf0e10cSrcweir bReArrange = sal_False;
169cdf0e10cSrcweir if( !pCont || !pFtn || bReArrange != (pFtn->FindFtnBossFrm() == pBoss) )
170cdf0e10cSrcweir {
171cdf0e10cSrcweir SwTxtFormatInfo aInf( this );
172cdf0e10cSrcweir SwTxtFormatter aLine( this, &aInf );
173cdf0e10cSrcweir aLine.TruncLines();
174cdf0e10cSrcweir SetPara( 0 ); //Wird ggf. geloescht!
175cdf0e10cSrcweir ResetPreps();
176cdf0e10cSrcweir return sal_False;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir }
179cdf0e10cSrcweir return sal_True;
180cdf0e10cSrcweir }
181cdf0e10cSrcweir
182cdf0e10cSrcweir
183cdf0e10cSrcweir /*************************************************************************
184cdf0e10cSrcweir * lcl_GetFtnLower()
185cdf0e10cSrcweir *
186cdf0e10cSrcweir * Local helper function. Checks if nLower should be taken as the boundary
187cdf0e10cSrcweir * for the footnote.
188cdf0e10cSrcweir *************************************************************************/
189cdf0e10cSrcweir
lcl_GetFtnLower(const SwTxtFrm * pFrm,SwTwips nLower)190cdf0e10cSrcweir SwTwips lcl_GetFtnLower( const SwTxtFrm* pFrm, SwTwips nLower )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir // nLower is an absolute value. It denotes the bottom of the line
193cdf0e10cSrcweir // containing the footnote.
194cdf0e10cSrcweir SWRECTFN( pFrm )
195cdf0e10cSrcweir
196cdf0e10cSrcweir ASSERT( !pFrm->IsVertical() || !pFrm->IsSwapped(),
197cdf0e10cSrcweir "lcl_GetFtnLower with swapped frame" );
198cdf0e10cSrcweir
199cdf0e10cSrcweir SwTwips nAdd;
200cdf0e10cSrcweir SwTwips nRet = nLower;
201cdf0e10cSrcweir
202cdf0e10cSrcweir //
203cdf0e10cSrcweir // Check if text is inside a table.
204cdf0e10cSrcweir //
205cdf0e10cSrcweir if ( pFrm->IsInTab() )
206cdf0e10cSrcweir {
207cdf0e10cSrcweir //
208cdf0e10cSrcweir // If pFrm is inside a table, we have to check if
209cdf0e10cSrcweir // a) The table is not allowed to split or
210cdf0e10cSrcweir // b) The table row is not allowed to split
211cdf0e10cSrcweir //
212cdf0e10cSrcweir // Inside a table, there are no footnotes,
213cdf0e10cSrcweir // see SwFrm::FindFtnBossFrm. So we don't have to check
214cdf0e10cSrcweir // the case that pFrm is inside a (footnote collecting) section
215cdf0e10cSrcweir // within the table.
216cdf0e10cSrcweir //
217cdf0e10cSrcweir const SwFrm* pRow = pFrm;
218cdf0e10cSrcweir while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
219cdf0e10cSrcweir pRow = pRow->GetUpper();
220cdf0e10cSrcweir const SwTabFrm* pTabFrm = (SwTabFrm*)pRow->GetUpper();
221cdf0e10cSrcweir
222cdf0e10cSrcweir ASSERT( pTabFrm && pRow &&
223cdf0e10cSrcweir pRow->GetUpper()->IsTabFrm(), "Upper of row should be tab" )
224cdf0e10cSrcweir
225cdf0e10cSrcweir const sal_Bool bDontSplit = !pTabFrm->IsFollow() &&
226cdf0e10cSrcweir !pTabFrm->IsLayoutSplitAllowed();
227cdf0e10cSrcweir
228cdf0e10cSrcweir SwTwips nMin = 0;
229cdf0e10cSrcweir if ( bDontSplit )
230cdf0e10cSrcweir nMin = (pTabFrm->Frm().*fnRect->fnGetBottom)();
231cdf0e10cSrcweir else if ( !((SwRowFrm*)pRow)->IsRowSplitAllowed() )
232cdf0e10cSrcweir nMin = (pRow->Frm().*fnRect->fnGetBottom)();
233cdf0e10cSrcweir
234cdf0e10cSrcweir if ( nMin && (*fnRect->fnYDiff)( nMin, nLower ) > 0 )
235cdf0e10cSrcweir nRet = nMin;
236cdf0e10cSrcweir
237cdf0e10cSrcweir nAdd = (pRow->GetUpper()->*fnRect->fnGetBottomMargin)();
238cdf0e10cSrcweir }
239cdf0e10cSrcweir else
240cdf0e10cSrcweir nAdd = (pFrm->*fnRect->fnGetBottomMargin)();
241cdf0e10cSrcweir
242cdf0e10cSrcweir if( nAdd > 0 )
243cdf0e10cSrcweir {
244cdf0e10cSrcweir if ( bVert )
245cdf0e10cSrcweir nRet -= nAdd;
246cdf0e10cSrcweir else
247cdf0e10cSrcweir nRet += nAdd;
248cdf0e10cSrcweir }
249cdf0e10cSrcweir
250cdf0e10cSrcweir // #i10770#: If there are fly frames anchored at previous paragraphs,
251cdf0e10cSrcweir // the deadline should consider their lower borders.
252cdf0e10cSrcweir const SwFrm* pStartFrm = pFrm->GetUpper()->GetLower();
253cdf0e10cSrcweir ASSERT( pStartFrm, "Upper has no lower" )
254cdf0e10cSrcweir SwTwips nFlyLower = bVert ? LONG_MAX : 0;
255cdf0e10cSrcweir while ( pStartFrm != pFrm )
256cdf0e10cSrcweir {
257cdf0e10cSrcweir ASSERT( pStartFrm, "Frame chain is broken" )
258cdf0e10cSrcweir if ( pStartFrm->GetDrawObjs() )
259cdf0e10cSrcweir {
260cdf0e10cSrcweir const SwSortedObjs &rObjs = *pStartFrm->GetDrawObjs();
261cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
262cdf0e10cSrcweir {
263cdf0e10cSrcweir SwAnchoredObject* pAnchoredObj = rObjs[i];
264cdf0e10cSrcweir SwRect aRect( pAnchoredObj->GetObjRect() );
265cdf0e10cSrcweir
266cdf0e10cSrcweir if ( !pAnchoredObj->ISA(SwFlyFrm) ||
267cdf0e10cSrcweir static_cast<SwFlyFrm*>(pAnchoredObj)->IsValid() )
268cdf0e10cSrcweir {
269cdf0e10cSrcweir const SwTwips nBottom = (aRect.*fnRect->fnGetBottom)();
270cdf0e10cSrcweir if ( (*fnRect->fnYDiff)( nBottom, nFlyLower ) > 0 )
271cdf0e10cSrcweir nFlyLower = nBottom;
272cdf0e10cSrcweir }
273cdf0e10cSrcweir }
274cdf0e10cSrcweir }
275cdf0e10cSrcweir
276cdf0e10cSrcweir pStartFrm = pStartFrm->GetNext();
277cdf0e10cSrcweir }
278cdf0e10cSrcweir
279cdf0e10cSrcweir if ( bVert )
280cdf0e10cSrcweir nRet = Min( nRet, nFlyLower );
281cdf0e10cSrcweir else
282cdf0e10cSrcweir nRet = Max( nRet, nFlyLower );
283cdf0e10cSrcweir
284cdf0e10cSrcweir return nRet;
285cdf0e10cSrcweir }
286cdf0e10cSrcweir
287cdf0e10cSrcweir
288cdf0e10cSrcweir /*************************************************************************
289cdf0e10cSrcweir * SwTxtFrm::GetFtnLine()
290cdf0e10cSrcweir *************************************************************************/
291cdf0e10cSrcweir
GetFtnLine(const SwTxtFtn * pFtn) const292cdf0e10cSrcweir SwTwips SwTxtFrm::GetFtnLine( const SwTxtFtn *pFtn ) const
293cdf0e10cSrcweir {
294cdf0e10cSrcweir ASSERT( ! IsVertical() || ! IsSwapped(),
295cdf0e10cSrcweir "SwTxtFrm::GetFtnLine with swapped frame" )
296cdf0e10cSrcweir
297cdf0e10cSrcweir SwTxtFrm *pThis = (SwTxtFrm*)this;
298cdf0e10cSrcweir
299cdf0e10cSrcweir if( !HasPara() )
300cdf0e10cSrcweir {
301cdf0e10cSrcweir // #109071# GetFormatted() does not work here, bacause most probably
302cdf0e10cSrcweir // the frame is currently locked. We return the previous value.
303cdf0e10cSrcweir return pThis->mnFtnLine > 0 ?
304cdf0e10cSrcweir pThis->mnFtnLine :
305cdf0e10cSrcweir IsVertical() ? Frm().Left() : Frm().Bottom();
306cdf0e10cSrcweir }
307cdf0e10cSrcweir
308cdf0e10cSrcweir SWAP_IF_NOT_SWAPPED( this )
309cdf0e10cSrcweir
310cdf0e10cSrcweir SwTxtInfo aInf( pThis );
311cdf0e10cSrcweir SwTxtIter aLine( pThis, &aInf );
312cdf0e10cSrcweir const xub_StrLen nPos = *pFtn->GetStart();
313cdf0e10cSrcweir aLine.CharToLine( nPos );
314cdf0e10cSrcweir
315cdf0e10cSrcweir SwTwips nRet = aLine.Y() + SwTwips(aLine.GetLineHeight());
316cdf0e10cSrcweir if( IsVertical() )
317cdf0e10cSrcweir nRet = SwitchHorizontalToVertical( nRet );
318cdf0e10cSrcweir
319cdf0e10cSrcweir UNDO_SWAP( this )
320cdf0e10cSrcweir
321cdf0e10cSrcweir nRet = lcl_GetFtnLower( pThis, nRet );
322cdf0e10cSrcweir
323cdf0e10cSrcweir pThis->mnFtnLine = nRet;
324cdf0e10cSrcweir return nRet;
325cdf0e10cSrcweir }
326cdf0e10cSrcweir
327cdf0e10cSrcweir /*************************************************************************
328cdf0e10cSrcweir * SwTxtFrm::GetFtnRstHeight()
329cdf0e10cSrcweir *************************************************************************/
330cdf0e10cSrcweir
331cdf0e10cSrcweir // Ermittelt die max. erreichbare Hoehe des TxtFrm im Ftn-Bereich.
332cdf0e10cSrcweir // Sie wird eingeschraenkt durch den unteren Rand der Zeile mit
333cdf0e10cSrcweir // der Ftn-Referenz.
334cdf0e10cSrcweir
_GetFtnFrmHeight() const335cdf0e10cSrcweir SwTwips SwTxtFrm::_GetFtnFrmHeight() const
336cdf0e10cSrcweir {
337cdf0e10cSrcweir ASSERT( !IsFollow() && IsInFtn(), "SwTxtFrm::SetFtnLine: moon walk" );
338cdf0e10cSrcweir
339cdf0e10cSrcweir const SwFtnFrm *pFtnFrm = FindFtnFrm();
340cdf0e10cSrcweir const SwTxtFrm *pRef = (const SwTxtFrm *)pFtnFrm->GetRef();
341cdf0e10cSrcweir const SwFtnBossFrm *pBoss = FindFtnBossFrm();
342cdf0e10cSrcweir if( pBoss != pRef->FindFtnBossFrm( !pFtnFrm->GetAttr()->
343cdf0e10cSrcweir GetFtn().IsEndNote() ) )
344cdf0e10cSrcweir return 0;
345cdf0e10cSrcweir
346cdf0e10cSrcweir SWAP_IF_SWAPPED( this )
347cdf0e10cSrcweir
348cdf0e10cSrcweir SwTwips nHeight = pRef->IsInFtnConnect() ?
349cdf0e10cSrcweir 1 : pRef->GetFtnLine( pFtnFrm->GetAttr() );
350cdf0e10cSrcweir if( nHeight )
351cdf0e10cSrcweir {
352cdf0e10cSrcweir // So komisch es aussehen mag: Die erste Ftn auf der Seite darf sich
353cdf0e10cSrcweir // nicht mit der Ftn-Referenz beruehren, wenn wir im Ftn-Bereich Text
354cdf0e10cSrcweir // eingeben.
355cdf0e10cSrcweir const SwFrm *pCont = pFtnFrm->GetUpper();
356cdf0e10cSrcweir //Hoehe innerhalb des Cont, die ich mir 'eh noch genehmigen darf.
357cdf0e10cSrcweir SWRECTFN( pCont )
358cdf0e10cSrcweir SwTwips nTmp = (*fnRect->fnYDiff)( (pCont->*fnRect->fnGetPrtBottom)(),
359cdf0e10cSrcweir (Frm().*fnRect->fnGetTop)() );
360cdf0e10cSrcweir
361cdf0e10cSrcweir #ifdef DBG_UTIL
362cdf0e10cSrcweir if( nTmp < 0 )
363cdf0e10cSrcweir {
364cdf0e10cSrcweir sal_Bool bInvalidPos = sal_False;
365cdf0e10cSrcweir const SwLayoutFrm* pTmp = GetUpper();
366cdf0e10cSrcweir while( !bInvalidPos && pTmp )
367cdf0e10cSrcweir {
368cdf0e10cSrcweir bInvalidPos = !pTmp->GetValidPosFlag() ||
369cdf0e10cSrcweir !pTmp->Lower()->GetValidPosFlag();
370cdf0e10cSrcweir if( pTmp == pCont )
371cdf0e10cSrcweir break;
372cdf0e10cSrcweir pTmp = pTmp->GetUpper();
373cdf0e10cSrcweir }
374cdf0e10cSrcweir ASSERT( bInvalidPos, "Hanging below FtnCont" );
375cdf0e10cSrcweir }
376cdf0e10cSrcweir #endif
377cdf0e10cSrcweir
378cdf0e10cSrcweir if ( (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), nHeight) > 0 )
379cdf0e10cSrcweir {
380cdf0e10cSrcweir //Wachstumspotential den Containers.
381cdf0e10cSrcweir if ( !pRef->IsInFtnConnect() )
382cdf0e10cSrcweir {
383cdf0e10cSrcweir SwSaveFtnHeight aSave( (SwFtnBossFrm*)pBoss, nHeight );
384cdf0e10cSrcweir nHeight = ((SwFtnContFrm*)pCont)->Grow( LONG_MAX, sal_True );
385cdf0e10cSrcweir }
386cdf0e10cSrcweir else
387cdf0e10cSrcweir nHeight = ((SwFtnContFrm*)pCont)->Grow( LONG_MAX, sal_True );
388cdf0e10cSrcweir
389cdf0e10cSrcweir nHeight += nTmp;
390cdf0e10cSrcweir if( nHeight < 0 )
391cdf0e10cSrcweir nHeight = 0;
392cdf0e10cSrcweir }
393cdf0e10cSrcweir else
394cdf0e10cSrcweir { // The container has to shrink
395cdf0e10cSrcweir nTmp += (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), nHeight);
396cdf0e10cSrcweir if( nTmp > 0 )
397cdf0e10cSrcweir nHeight = nTmp;
398cdf0e10cSrcweir else
399cdf0e10cSrcweir nHeight = 0;
400cdf0e10cSrcweir }
401cdf0e10cSrcweir }
402cdf0e10cSrcweir
403cdf0e10cSrcweir UNDO_SWAP( this )
404cdf0e10cSrcweir
405cdf0e10cSrcweir return nHeight;
406cdf0e10cSrcweir }
407cdf0e10cSrcweir
408cdf0e10cSrcweir /*************************************************************************
409cdf0e10cSrcweir * SwTxtFrm::FindQuoVadisFrm()
410cdf0e10cSrcweir *************************************************************************/
411cdf0e10cSrcweir
FindQuoVadisFrm()412cdf0e10cSrcweir SwTxtFrm *SwTxtFrm::FindQuoVadisFrm()
413cdf0e10cSrcweir {
414cdf0e10cSrcweir // Erstmal feststellen, ob wir in einem FtnFrm stehen:
415cdf0e10cSrcweir if( GetIndPrev() || !IsInFtn() )
416cdf0e10cSrcweir return 0;
417cdf0e10cSrcweir
418cdf0e10cSrcweir // Zum Vorgaenger-FtnFrm
419cdf0e10cSrcweir SwFtnFrm *pFtnFrm = FindFtnFrm()->GetMaster();
420cdf0e10cSrcweir if( !pFtnFrm )
421cdf0e10cSrcweir return 0;
422cdf0e10cSrcweir
423cdf0e10cSrcweir // Nun den letzten Cntnt:
424cdf0e10cSrcweir const SwCntntFrm *pCnt = pFtnFrm->ContainsCntnt();
425cdf0e10cSrcweir if( !pCnt )
426cdf0e10cSrcweir return NULL;
427cdf0e10cSrcweir const SwCntntFrm *pLast;
428cdf0e10cSrcweir do
429cdf0e10cSrcweir { pLast = pCnt;
430cdf0e10cSrcweir pCnt = pCnt->GetNextCntntFrm();
431cdf0e10cSrcweir } while( pCnt && pFtnFrm->IsAnLower( pCnt ) );
432cdf0e10cSrcweir return (SwTxtFrm*)pLast;
433cdf0e10cSrcweir }
434cdf0e10cSrcweir
435cdf0e10cSrcweir /*************************************************************************
436cdf0e10cSrcweir * SwTxtFrm::RemoveFtn()
437cdf0e10cSrcweir *************************************************************************/
438cdf0e10cSrcweir
RemoveFtn(const xub_StrLen nStart,const xub_StrLen nLen)439cdf0e10cSrcweir void SwTxtFrm::RemoveFtn( const xub_StrLen nStart, const xub_StrLen nLen )
440cdf0e10cSrcweir {
441cdf0e10cSrcweir if ( !IsFtnAllowed() )
442cdf0e10cSrcweir return;
443cdf0e10cSrcweir
444cdf0e10cSrcweir SwpHints *pHints = GetTxtNode()->GetpSwpHints();
445cdf0e10cSrcweir if( !pHints )
446cdf0e10cSrcweir return;
447cdf0e10cSrcweir
448cdf0e10cSrcweir sal_Bool bRollBack = nLen != STRING_LEN;
449cdf0e10cSrcweir sal_uInt16 nSize = pHints->Count();
450cdf0e10cSrcweir xub_StrLen nEnd;
451cdf0e10cSrcweir SwTxtFrm* pSource;
452cdf0e10cSrcweir if( bRollBack )
453cdf0e10cSrcweir {
454cdf0e10cSrcweir nEnd = nStart + nLen;
455cdf0e10cSrcweir pSource = GetFollow();
456cdf0e10cSrcweir if( !pSource )
457cdf0e10cSrcweir return;
458cdf0e10cSrcweir }
459cdf0e10cSrcweir else
460cdf0e10cSrcweir {
461cdf0e10cSrcweir nEnd = STRING_LEN;
462cdf0e10cSrcweir pSource = this;
463cdf0e10cSrcweir }
464cdf0e10cSrcweir
465cdf0e10cSrcweir if( nSize )
466cdf0e10cSrcweir {
467cdf0e10cSrcweir SwPageFrm* pUpdate = NULL;
468cdf0e10cSrcweir sal_Bool bRemove = sal_False;
469cdf0e10cSrcweir SwFtnBossFrm *pFtnBoss = 0;
470cdf0e10cSrcweir SwFtnBossFrm *pEndBoss = 0;
471cdf0e10cSrcweir sal_Bool bFtnEndDoc
472cdf0e10cSrcweir = FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFtnInfo().ePos;
473cdf0e10cSrcweir for ( sal_uInt16 i = nSize; i; )
474cdf0e10cSrcweir {
475cdf0e10cSrcweir SwTxtAttr *pHt = pHints->GetTextHint(--i);
476cdf0e10cSrcweir if ( RES_TXTATR_FTN != pHt->Which() )
477cdf0e10cSrcweir continue;
478cdf0e10cSrcweir
479cdf0e10cSrcweir const xub_StrLen nIdx = *pHt->GetStart();
480cdf0e10cSrcweir if( nStart > nIdx )
481cdf0e10cSrcweir break;
482cdf0e10cSrcweir
483cdf0e10cSrcweir if( nEnd >= nIdx )
484cdf0e10cSrcweir {
485cdf0e10cSrcweir SwTxtFtn *pFtn = (SwTxtFtn*)pHt;
486cdf0e10cSrcweir sal_Bool bEndn = pFtn->GetFtn().IsEndNote();
487cdf0e10cSrcweir
488cdf0e10cSrcweir if( bEndn )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir if( !pEndBoss )
491cdf0e10cSrcweir pEndBoss = pSource->FindFtnBossFrm();
492cdf0e10cSrcweir }
493cdf0e10cSrcweir else
494cdf0e10cSrcweir {
495cdf0e10cSrcweir if( !pFtnBoss )
496cdf0e10cSrcweir {
497cdf0e10cSrcweir pFtnBoss = pSource->FindFtnBossFrm( sal_True );
498cdf0e10cSrcweir if( pFtnBoss->GetUpper()->IsSctFrm() )
499cdf0e10cSrcweir {
500cdf0e10cSrcweir SwSectionFrm* pSect = (SwSectionFrm*)
501cdf0e10cSrcweir pFtnBoss->GetUpper();
502cdf0e10cSrcweir if( pSect->IsFtnAtEnd() )
503cdf0e10cSrcweir bFtnEndDoc = sal_False;
504cdf0e10cSrcweir }
505cdf0e10cSrcweir }
506cdf0e10cSrcweir }
507cdf0e10cSrcweir
508cdf0e10cSrcweir // Wir loeschen nicht, sondern wollen die Ftn verschieben.
509cdf0e10cSrcweir // Drei Faelle koennen auftreten:
510cdf0e10cSrcweir // 1) Es gibt weder Follow noch PrevFollow
511cdf0e10cSrcweir // -> RemoveFtn() (vielleicht sogar ein ASSERT wert)
512cdf0e10cSrcweir // 2) nStart > GetOfst, ich habe einen Follow
513cdf0e10cSrcweir // -> Ftn wandert in den Follow
514cdf0e10cSrcweir // 3) nStart < GetOfst, ich bin ein Follow
515cdf0e10cSrcweir // -> Ftn wandert in den PrevFollow
516cdf0e10cSrcweir // beide muessen auf einer Seite/in einer Spalte stehen.
517cdf0e10cSrcweir
518cdf0e10cSrcweir SwFtnFrm *pFtnFrm = bEndn ? pEndBoss->FindFtn( pSource, pFtn ) :
519cdf0e10cSrcweir pFtnBoss->FindFtn( pSource, pFtn );
520cdf0e10cSrcweir
521cdf0e10cSrcweir if( pFtnFrm )
522cdf0e10cSrcweir {
523cdf0e10cSrcweir const sal_Bool bEndDoc = bEndn ? sal_True : bFtnEndDoc;
524cdf0e10cSrcweir if( bRollBack )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir while ( pFtnFrm )
527cdf0e10cSrcweir {
528cdf0e10cSrcweir pFtnFrm->SetRef( this );
529cdf0e10cSrcweir pFtnFrm = pFtnFrm->GetFollow();
530cdf0e10cSrcweir SetFtn( sal_True );
531cdf0e10cSrcweir }
532cdf0e10cSrcweir }
533cdf0e10cSrcweir else if( GetFollow() )
534cdf0e10cSrcweir {
535cdf0e10cSrcweir SwCntntFrm *pDest = GetFollow();
536cdf0e10cSrcweir while( pDest->GetFollow() && ((SwTxtFrm*)pDest->
537cdf0e10cSrcweir GetFollow())->GetOfst() <= nIdx )
538cdf0e10cSrcweir pDest = pDest->GetFollow();
539cdf0e10cSrcweir ASSERT( !pDest->FindFtnBossFrm( !bEndn )->FindFtn(
540cdf0e10cSrcweir pDest,pFtn),"SwTxtFrm::RemoveFtn: footnote exists");
541cdf0e10cSrcweir
542cdf0e10cSrcweir //Nicht ummelden sondern immer Moven.
543cdf0e10cSrcweir // OD 08.11.2002 #104840# - use <SwlayoutFrm::IsBefore(::)>
544cdf0e10cSrcweir if ( bEndDoc ||
545cdf0e10cSrcweir !pFtnFrm->FindFtnBossFrm()->IsBefore( pDest->FindFtnBossFrm( !bEndn ) )
546cdf0e10cSrcweir )
547cdf0e10cSrcweir {
548cdf0e10cSrcweir SwPageFrm* pTmp = pFtnFrm->FindPageFrm();
549cdf0e10cSrcweir if( pUpdate && pUpdate != pTmp )
550cdf0e10cSrcweir pUpdate->UpdateFtnNum();
551cdf0e10cSrcweir pUpdate = pTmp;
552cdf0e10cSrcweir while ( pFtnFrm )
553cdf0e10cSrcweir {
554cdf0e10cSrcweir pFtnFrm->SetRef( pDest );
555cdf0e10cSrcweir pFtnFrm = pFtnFrm->GetFollow();
556cdf0e10cSrcweir }
557cdf0e10cSrcweir }
558cdf0e10cSrcweir else
559cdf0e10cSrcweir {
560cdf0e10cSrcweir if( bEndn )
561cdf0e10cSrcweir pEndBoss->MoveFtns( this, pDest, pFtn );
562cdf0e10cSrcweir else
563cdf0e10cSrcweir pFtnBoss->MoveFtns( this, pDest, pFtn );
564cdf0e10cSrcweir bRemove = sal_True;
565cdf0e10cSrcweir }
566cdf0e10cSrcweir ((SwTxtFrm*)pDest)->SetFtn( sal_True );
567cdf0e10cSrcweir
568cdf0e10cSrcweir ASSERT( pDest->FindFtnBossFrm( !bEndn )->FindFtn( pDest,
569cdf0e10cSrcweir pFtn),"SwTxtFrm::RemoveFtn: footnote ChgRef failed");
570cdf0e10cSrcweir }
571cdf0e10cSrcweir else
572cdf0e10cSrcweir {
573cdf0e10cSrcweir if( !bEndDoc || ( bEndn && pEndBoss->IsInSct() &&
574cdf0e10cSrcweir !SwLayouter::Collecting( GetNode()->GetDoc(),
575cdf0e10cSrcweir pEndBoss->FindSctFrm(), NULL ) ) )
576cdf0e10cSrcweir {
577cdf0e10cSrcweir if( bEndn )
578cdf0e10cSrcweir pEndBoss->RemoveFtn( this, pFtn );
579cdf0e10cSrcweir else
580cdf0e10cSrcweir pFtnBoss->RemoveFtn( this, pFtn );
581cdf0e10cSrcweir bRemove = bRemove || !bEndDoc;
582cdf0e10cSrcweir ASSERT( bEndn ? !pEndBoss->FindFtn( this, pFtn ) :
583cdf0e10cSrcweir !pFtnBoss->FindFtn( this, pFtn ),
584cdf0e10cSrcweir "SwTxtFrm::RemoveFtn: can't get off that footnote" );
585cdf0e10cSrcweir }
586cdf0e10cSrcweir }
587cdf0e10cSrcweir }
588cdf0e10cSrcweir }
589cdf0e10cSrcweir }
590cdf0e10cSrcweir if( pUpdate )
591cdf0e10cSrcweir pUpdate->UpdateFtnNum();
592cdf0e10cSrcweir // Wir bringen die Oszillation zum stehen:
593cdf0e10cSrcweir if( bRemove && !bFtnEndDoc && HasPara() )
594cdf0e10cSrcweir {
595cdf0e10cSrcweir ValidateBodyFrm();
596cdf0e10cSrcweir ValidateFrm();
597cdf0e10cSrcweir }
598cdf0e10cSrcweir }
599cdf0e10cSrcweir // Folgendes Problem: Aus dem FindBreak heraus wird das RemoveFtn aufgerufen,
600cdf0e10cSrcweir // weil die letzte Zeile an den Follow abgegeben werden soll. Der Offset
601cdf0e10cSrcweir // des Follows ist aber veraltet, er wird demnaechst gesetzt. CalcFntFlag ist
602cdf0e10cSrcweir // auf einen richtigen Follow-Offset angewiesen. Deshalb wird hier kurzfristig
603cdf0e10cSrcweir // der Follow-Offset manipuliert.
604cdf0e10cSrcweir xub_StrLen nOldOfst = STRING_LEN;
605cdf0e10cSrcweir if( HasFollow() && nStart > GetOfst() )
606cdf0e10cSrcweir {
607cdf0e10cSrcweir nOldOfst = GetFollow()->GetOfst();
608cdf0e10cSrcweir GetFollow()->ManipOfst( nStart + ( bRollBack ? nLen : 0 ) );
609cdf0e10cSrcweir }
610cdf0e10cSrcweir pSource->CalcFtnFlag();
611cdf0e10cSrcweir if( nOldOfst < STRING_LEN )
612cdf0e10cSrcweir GetFollow()->ManipOfst( nOldOfst );
613cdf0e10cSrcweir }
614cdf0e10cSrcweir
615cdf0e10cSrcweir /*************************************************************************
616cdf0e10cSrcweir * SwTxtFormatter::ConnectFtn()
617cdf0e10cSrcweir *************************************************************************/
618cdf0e10cSrcweir // sal_False, wenn irgendetwas schief gegangen ist.
619cdf0e10cSrcweir // Es gibt eigentlich nur zwei Moeglichkeiten:
620cdf0e10cSrcweir // a) Die Ftn ist bereits vorhanden
621cdf0e10cSrcweir // => dann wird sie gemoved, wenn ein anderer pSrcFrm gefunden wurde
622cdf0e10cSrcweir // b) Die Ftn ist nicht vorhanden
623cdf0e10cSrcweir // => dann wird sie fuer uns angelegt.
624cdf0e10cSrcweir // Ob die Ftn schliesslich auf unserer Spalte/Seite landet oder nicht,
625cdf0e10cSrcweir // spielt in diesem Zusammenhang keine Rolle.
626cdf0e10cSrcweir // Optimierungen bei Endnoten.
627cdf0e10cSrcweir // Noch ein Problem: wenn die Deadline im Ftn-Bereich liegt, muss die
628cdf0e10cSrcweir // Ftn verschoben werden.
629cdf0e10cSrcweir
ConnectFtn(SwTxtFtn * pFtn,const SwTwips nDeadLine)630cdf0e10cSrcweir void SwTxtFrm::ConnectFtn( SwTxtFtn *pFtn, const SwTwips nDeadLine )
631cdf0e10cSrcweir {
632cdf0e10cSrcweir ASSERT( !IsVertical() || !IsSwapped(),
633cdf0e10cSrcweir "SwTxtFrm::ConnectFtn with swapped frame" );
634cdf0e10cSrcweir
635cdf0e10cSrcweir bFtn = sal_True;
636cdf0e10cSrcweir bInFtnConnect = sal_True; //Bloss zuruecksetzen!
637cdf0e10cSrcweir sal_Bool bEnd = pFtn->GetFtn().IsEndNote();
638cdf0e10cSrcweir
639cdf0e10cSrcweir //
640cdf0e10cSrcweir // We want to store this value, because it is needed as a fallback
641cdf0e10cSrcweir // in GetFtnLine(), if there is no paragraph information available
642cdf0e10cSrcweir //
643cdf0e10cSrcweir mnFtnLine = nDeadLine;
644cdf0e10cSrcweir
645cdf0e10cSrcweir // Wir brauchen immer einen Boss (Spalte/Seite)
646cdf0e10cSrcweir SwSectionFrm *pSect;
647cdf0e10cSrcweir SwCntntFrm *pCntnt = this;
648cdf0e10cSrcweir if( bEnd && IsInSct() )
649cdf0e10cSrcweir {
650cdf0e10cSrcweir pSect = FindSctFrm();
651cdf0e10cSrcweir if( pSect->IsEndnAtEnd() )
652cdf0e10cSrcweir pCntnt = pSect->FindLastCntnt( FINDMODE_ENDNOTE );
653cdf0e10cSrcweir if( !pCntnt )
654cdf0e10cSrcweir pCntnt = this;
655cdf0e10cSrcweir }
656cdf0e10cSrcweir
657cdf0e10cSrcweir SwFtnBossFrm *pBoss = pCntnt->FindFtnBossFrm( !bEnd );
658cdf0e10cSrcweir
659cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
660cdf0e10cSrcweir SwTwips nRstHeight = GetRstHeight();
661cdf0e10cSrcweir #endif
662cdf0e10cSrcweir
663cdf0e10cSrcweir pSect = pBoss->FindSctFrm();
664cdf0e10cSrcweir sal_Bool bDocEnd = bEnd ? !( pSect && pSect->IsEndnAtEnd() ) :
665cdf0e10cSrcweir ( !( pSect && pSect->IsFtnAtEnd() ) &&
666cdf0e10cSrcweir FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFtnInfo().ePos );
667cdf0e10cSrcweir //Ftn kann beim Follow angemeldet sein.
668cdf0e10cSrcweir SwCntntFrm *pSrcFrm = FindFtnRef( pFtn );
669cdf0e10cSrcweir
670cdf0e10cSrcweir if( bDocEnd )
671cdf0e10cSrcweir {
672cdf0e10cSrcweir if( pSect && pSrcFrm )
673cdf0e10cSrcweir {
674cdf0e10cSrcweir SwFtnFrm *pFtnFrm = pBoss->FindFtn( pSrcFrm, pFtn );
675cdf0e10cSrcweir if( pFtnFrm && pFtnFrm->IsInSct() )
676cdf0e10cSrcweir {
677cdf0e10cSrcweir pBoss->RemoveFtn( pSrcFrm, pFtn );
678cdf0e10cSrcweir pSrcFrm = 0;
679cdf0e10cSrcweir }
680cdf0e10cSrcweir }
681cdf0e10cSrcweir }
682cdf0e10cSrcweir else if( bEnd && pSect )
683cdf0e10cSrcweir {
684cdf0e10cSrcweir SwFtnFrm *pFtnFrm = pSrcFrm ? pBoss->FindFtn( pSrcFrm, pFtn ) : NULL;
685cdf0e10cSrcweir if( pFtnFrm && !pFtnFrm->GetUpper() )
686cdf0e10cSrcweir pFtnFrm = NULL;
687cdf0e10cSrcweir SwDoc *pDoc = GetNode()->GetDoc();
688cdf0e10cSrcweir if( SwLayouter::Collecting( pDoc, pSect, pFtnFrm ) )
689cdf0e10cSrcweir {
690cdf0e10cSrcweir if( !pSrcFrm )
691cdf0e10cSrcweir {
692cdf0e10cSrcweir SwFtnFrm *pNew = new SwFtnFrm(pDoc->GetDfltFrmFmt(),this,this,pFtn);
693cdf0e10cSrcweir SwNodeIndex aIdx( *pFtn->GetStartNode(), 1 );
694cdf0e10cSrcweir ::_InsertCnt( pNew, pDoc, aIdx.GetIndex() );
695cdf0e10cSrcweir GetNode()->getIDocumentLayoutAccess()->GetLayouter()->CollectEndnote( pNew );
696cdf0e10cSrcweir }
697cdf0e10cSrcweir else if( pSrcFrm != this )
698cdf0e10cSrcweir pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
699cdf0e10cSrcweir bInFtnConnect = sal_False;
700cdf0e10cSrcweir return;
701cdf0e10cSrcweir }
702cdf0e10cSrcweir else if( pSrcFrm )
703cdf0e10cSrcweir {
704cdf0e10cSrcweir SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm();
705cdf0e10cSrcweir if( !pFtnBoss->IsInSct() ||
706cdf0e10cSrcweir pFtnBoss->ImplFindSctFrm()->GetSection()!=pSect->GetSection() )
707cdf0e10cSrcweir {
708cdf0e10cSrcweir pBoss->RemoveFtn( pSrcFrm, pFtn );
709cdf0e10cSrcweir pSrcFrm = 0;
710cdf0e10cSrcweir }
711cdf0e10cSrcweir }
712cdf0e10cSrcweir }
713cdf0e10cSrcweir
714cdf0e10cSrcweir if( bDocEnd || bEnd )
715cdf0e10cSrcweir {
716cdf0e10cSrcweir if( !pSrcFrm )
717cdf0e10cSrcweir pBoss->AppendFtn( this, pFtn );
718cdf0e10cSrcweir else if( pSrcFrm != this )
719cdf0e10cSrcweir pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
720cdf0e10cSrcweir bInFtnConnect = sal_False;
721cdf0e10cSrcweir return;
722cdf0e10cSrcweir }
723cdf0e10cSrcweir
724cdf0e10cSrcweir SwSaveFtnHeight aHeight( pBoss, nDeadLine );
725cdf0e10cSrcweir
726cdf0e10cSrcweir if( !pSrcFrm ) // Es wurde ueberhaupt keine Ftn gefunden.
727cdf0e10cSrcweir pBoss->AppendFtn( this, pFtn );
728cdf0e10cSrcweir else
729cdf0e10cSrcweir {
730cdf0e10cSrcweir SwFtnFrm *pFtnFrm = pBoss->FindFtn( pSrcFrm, pFtn );
731cdf0e10cSrcweir SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm();
732cdf0e10cSrcweir
733cdf0e10cSrcweir sal_Bool bBrutal = sal_False;
734cdf0e10cSrcweir
735cdf0e10cSrcweir if( pFtnBoss == pBoss ) // Ref und Ftn sind auf der selben Seite/Spalte.
736cdf0e10cSrcweir {
737cdf0e10cSrcweir SwFrm *pCont = pFtnFrm->GetUpper();
738cdf0e10cSrcweir
739cdf0e10cSrcweir SWRECTFN ( pCont )
740cdf0e10cSrcweir long nDiff = (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(),
741cdf0e10cSrcweir nDeadLine );
742cdf0e10cSrcweir
743cdf0e10cSrcweir if( nDiff >= 0 )
744cdf0e10cSrcweir {
745cdf0e10cSrcweir //Wenn die Fussnote bei einem Follow angemeldet ist, so ist
746cdf0e10cSrcweir //es jetzt an der Zeit sie umzumelden.
747cdf0e10cSrcweir if ( pSrcFrm != this )
748cdf0e10cSrcweir pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
749cdf0e10cSrcweir //Es steht Platz zur Verfuegung, also kann die Fussnote evtl.
750cdf0e10cSrcweir //wachsen.
751cdf0e10cSrcweir if ( pFtnFrm->GetFollow() && nDiff > 0 )
752cdf0e10cSrcweir {
753cdf0e10cSrcweir SwTwips nHeight = (pCont->Frm().*fnRect->fnGetHeight)();
754cdf0e10cSrcweir pBoss->RearrangeFtns( nDeadLine, sal_False, pFtn );
755cdf0e10cSrcweir ValidateBodyFrm();
756cdf0e10cSrcweir ValidateFrm();
757cdf0e10cSrcweir ViewShell *pSh = getRootFrm()->GetCurrShell();
758cdf0e10cSrcweir if ( pSh && nHeight == (pCont->Frm().*fnRect->fnGetHeight)() )
759cdf0e10cSrcweir //Damit uns nix durch die Lappen geht.
760cdf0e10cSrcweir pSh->InvalidateWindows( pCont->Frm() );
761cdf0e10cSrcweir }
762cdf0e10cSrcweir bInFtnConnect = sal_False;
763cdf0e10cSrcweir return;
764cdf0e10cSrcweir }
765cdf0e10cSrcweir else
766cdf0e10cSrcweir bBrutal = sal_True;
767cdf0e10cSrcweir }
768cdf0e10cSrcweir else
769cdf0e10cSrcweir {
770cdf0e10cSrcweir // Ref und Ftn sind nicht auf einer Seite, Move-Versuch ist noetig.
771cdf0e10cSrcweir SwFrm* pTmp = this;
772cdf0e10cSrcweir while( pTmp->GetNext() && pSrcFrm != pTmp )
773cdf0e10cSrcweir pTmp = pTmp->GetNext();
774cdf0e10cSrcweir if( pSrcFrm == pTmp )
775cdf0e10cSrcweir bBrutal = sal_True;
776cdf0e10cSrcweir else
777cdf0e10cSrcweir { // Wenn unser Boss in einem spaltigen Bereich sitzt, es aber auf
778cdf0e10cSrcweir // der Seite schon einen FtnContainer gibt, hilft nur die brutale
779cdf0e10cSrcweir // Methode
780cdf0e10cSrcweir if( pSect && pSect->FindFtnBossFrm( !bEnd )->FindFtnCont() )
781cdf0e10cSrcweir bBrutal = sal_True;
782cdf0e10cSrcweir // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
783cdf0e10cSrcweir else if ( !pFtnFrm->GetPrev() ||
784cdf0e10cSrcweir pFtnBoss->IsBefore( pBoss )
785cdf0e10cSrcweir )
786cdf0e10cSrcweir {
787cdf0e10cSrcweir SwFtnBossFrm *pSrcBoss = pSrcFrm->FindFtnBossFrm( !bEnd );
788cdf0e10cSrcweir pSrcBoss->MoveFtns( pSrcFrm, this, pFtn );
789cdf0e10cSrcweir }
790cdf0e10cSrcweir else
791cdf0e10cSrcweir pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
792cdf0e10cSrcweir }
793cdf0e10cSrcweir }
794cdf0e10cSrcweir
795cdf0e10cSrcweir // Die brutale Loesung: Fussnote entfernen und appenden.
796cdf0e10cSrcweir // Es muss SetFtnDeadLine() gerufen werden, weil nach
797cdf0e10cSrcweir // RemoveFtn die nMaxFtnHeight evtl. besser auf unsere Wuensche
798cdf0e10cSrcweir // eingestellt werden kann.
799cdf0e10cSrcweir if( bBrutal )
800cdf0e10cSrcweir {
801cdf0e10cSrcweir pBoss->RemoveFtn( pSrcFrm, pFtn, sal_False );
802cdf0e10cSrcweir SwSaveFtnHeight *pHeight = bEnd ? NULL :
803cdf0e10cSrcweir new SwSaveFtnHeight( pBoss, nDeadLine );
804cdf0e10cSrcweir pBoss->AppendFtn( this, pFtn );
805cdf0e10cSrcweir delete pHeight;
806cdf0e10cSrcweir }
807cdf0e10cSrcweir }
808cdf0e10cSrcweir
809cdf0e10cSrcweir // In spaltigen Bereichen, die noch nicht bis zum Seitenrand gehen,
810cdf0e10cSrcweir // ist kein RearrangeFtns sinnvoll, da der Fussnotencontainer noch
811cdf0e10cSrcweir // nicht kalkuliert worden ist.
812cdf0e10cSrcweir if( !pSect || !pSect->Growable() )
813cdf0e10cSrcweir {
814cdf0e10cSrcweir // Umgebung validieren, um Oszillationen zu verhindern.
815cdf0e10cSrcweir SwSaveFtnHeight aNochmal( pBoss, nDeadLine );
816cdf0e10cSrcweir ValidateBodyFrm();
817cdf0e10cSrcweir pBoss->RearrangeFtns( nDeadLine, sal_True );
818cdf0e10cSrcweir ValidateFrm();
819cdf0e10cSrcweir }
820cdf0e10cSrcweir else if( pSect->IsFtnAtEnd() )
821cdf0e10cSrcweir {
822cdf0e10cSrcweir ValidateBodyFrm();
823cdf0e10cSrcweir ValidateFrm();
824cdf0e10cSrcweir }
825cdf0e10cSrcweir
826cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
827cdf0e10cSrcweir // pFtnFrm kann sich durch Calc veraendert haben ...
828cdf0e10cSrcweir SwFtnFrm *pFtnFrm = pBoss->FindFtn( this, pFtn );
829cdf0e10cSrcweir if( pFtnFrm && pBoss != pFtnFrm->FindFtnBossFrm( !bEnd ) )
830cdf0e10cSrcweir {
831cdf0e10cSrcweir int bla = 5;
832cdf0e10cSrcweir (void)bla;
833cdf0e10cSrcweir }
834cdf0e10cSrcweir nRstHeight = GetRstHeight();
835cdf0e10cSrcweir #endif
836cdf0e10cSrcweir bInFtnConnect = sal_False;
837cdf0e10cSrcweir return;
838cdf0e10cSrcweir }
839cdf0e10cSrcweir
840cdf0e10cSrcweir
841cdf0e10cSrcweir
842cdf0e10cSrcweir /*************************************************************************
843cdf0e10cSrcweir * SwTxtFormatter::NewFtnPortion()
844cdf0e10cSrcweir *************************************************************************/
845cdf0e10cSrcweir
846cdf0e10cSrcweir // Die Portion fuer die Ftn-Referenz im Text
NewFtnPortion(SwTxtFormatInfo & rInf,SwTxtAttr * pHint)847cdf0e10cSrcweir SwFtnPortion *SwTxtFormatter::NewFtnPortion( SwTxtFormatInfo &rInf,
848cdf0e10cSrcweir SwTxtAttr *pHint )
849cdf0e10cSrcweir {
850cdf0e10cSrcweir ASSERT( ! pFrm->IsVertical() || pFrm->IsSwapped(),
851cdf0e10cSrcweir "NewFtnPortion with unswapped frame" );
852cdf0e10cSrcweir
853cdf0e10cSrcweir if( !pFrm->IsFtnAllowed() )
854cdf0e10cSrcweir return 0;
855cdf0e10cSrcweir
856cdf0e10cSrcweir SwTxtFtn *pFtn = (SwTxtFtn*)pHint;
857cdf0e10cSrcweir SwFmtFtn& rFtn = (SwFmtFtn&)pFtn->GetFtn();
858cdf0e10cSrcweir SwDoc *pDoc = pFrm->GetNode()->GetDoc();
859cdf0e10cSrcweir
860cdf0e10cSrcweir if( rInf.IsTest() )
861cdf0e10cSrcweir return new SwFtnPortion( rFtn.GetViewNumStr( *pDoc ), pFrm, pFtn );
862cdf0e10cSrcweir
863cdf0e10cSrcweir SWAP_IF_SWAPPED( pFrm )
864cdf0e10cSrcweir
865cdf0e10cSrcweir KSHORT nReal;
866cdf0e10cSrcweir {
867cdf0e10cSrcweir KSHORT nOldReal = pCurr->GetRealHeight();
868cdf0e10cSrcweir KSHORT nOldAscent = pCurr->GetAscent();
869cdf0e10cSrcweir KSHORT nOldHeight = pCurr->Height();
870cdf0e10cSrcweir ((SwTxtFormatter*)this)->CalcRealHeight();
871cdf0e10cSrcweir nReal = pCurr->GetRealHeight();
872cdf0e10cSrcweir if( nReal < nOldReal )
873cdf0e10cSrcweir nReal = nOldReal;
874cdf0e10cSrcweir pCurr->SetRealHeight( nOldReal );
875cdf0e10cSrcweir pCurr->Height( nOldHeight );
876cdf0e10cSrcweir pCurr->SetAscent( nOldAscent );
877cdf0e10cSrcweir }
878cdf0e10cSrcweir
879cdf0e10cSrcweir SwTwips nLower = Y() + nReal;
880cdf0e10cSrcweir
881cdf0e10cSrcweir const bool bVertical = pFrm->IsVertical();
882cdf0e10cSrcweir if( bVertical )
883cdf0e10cSrcweir nLower = pFrm->SwitchHorizontalToVertical( nLower );
884cdf0e10cSrcweir
885cdf0e10cSrcweir nLower = lcl_GetFtnLower( pFrm, nLower );
886cdf0e10cSrcweir
887cdf0e10cSrcweir //6995: Wir frischen nur auf. Das Connect tut fuer diesen Fall nix
888cdf0e10cSrcweir //Brauchbares, sondern wuerde stattdessen fuer diesen Fall meist die
889cdf0e10cSrcweir //Ftn wegwerfen und neu erzeugen.
890cdf0e10cSrcweir
891cdf0e10cSrcweir if( !rInf.IsQuick() )
892cdf0e10cSrcweir pFrm->ConnectFtn( pFtn, nLower );
893cdf0e10cSrcweir
894cdf0e10cSrcweir SwTxtFrm *pScrFrm = pFrm->FindFtnRef( pFtn );
895cdf0e10cSrcweir SwFtnBossFrm *pBoss = pFrm->FindFtnBossFrm( !rFtn.IsEndNote() );
896cdf0e10cSrcweir SwFtnFrm *pFtnFrm = NULL;
897cdf0e10cSrcweir if( pScrFrm )
898cdf0e10cSrcweir pFtnFrm = pBoss->FindFtn( pScrFrm, pFtn );
899cdf0e10cSrcweir
900cdf0e10cSrcweir // Wir erkundigen uns, ob durch unser Append irgendeine
901cdf0e10cSrcweir // Fussnote noch auf der Seite/Spalte steht. Wenn nicht verschwindet
902cdf0e10cSrcweir // auch unsere Zeile. Dies fuehrt zu folgendem erwuenschten
903cdf0e10cSrcweir // Verhalten: Ftn1 pass noch auf die Seite/Spalte, Ftn2 nicht mehr.
904cdf0e10cSrcweir // Also bleibt die Ftn2-Referenz auf der Seite/Spalte stehen. Die
905cdf0e10cSrcweir // Fussnote selbst folgt aber erst auf der naechsten Seite/Spalte.
906cdf0e10cSrcweir // Ausnahme: Wenn keine weitere Zeile auf diese Seite/Spalte passt,
907cdf0e10cSrcweir // so sollte die Ftn2-Referenz auch auf die naechste wandern.
908cdf0e10cSrcweir if( !rFtn.IsEndNote() )
909cdf0e10cSrcweir {
910cdf0e10cSrcweir SwSectionFrm *pSct = pBoss->FindSctFrm();
911cdf0e10cSrcweir sal_Bool bAtSctEnd = pSct && pSct->IsFtnAtEnd();
912cdf0e10cSrcweir if( FTNPOS_CHAPTER != pDoc->GetFtnInfo().ePos || bAtSctEnd )
913cdf0e10cSrcweir {
914cdf0e10cSrcweir SwFrm* pFtnCont = pBoss->FindFtnCont();
915cdf0e10cSrcweir // Wenn der Boss in einem Bereich liegt, kann es sich nur um eine
916cdf0e10cSrcweir // Spalte dieses Bereichs handeln. Wenn dies nicht die erste Spalte
917cdf0e10cSrcweir // ist, duerfen wir ausweichen
918cdf0e10cSrcweir if( !pFrm->IsInTab() && ( GetLineNr() > 1 || pFrm->GetPrev() ||
919cdf0e10cSrcweir ( !bAtSctEnd && pFrm->GetIndPrev() ) ||
920cdf0e10cSrcweir ( pSct && pBoss->GetPrev() ) ) )
921cdf0e10cSrcweir {
922cdf0e10cSrcweir if( !pFtnCont )
923cdf0e10cSrcweir {
924cdf0e10cSrcweir rInf.SetStop( sal_True );
925cdf0e10cSrcweir UNDO_SWAP( pFrm )
926cdf0e10cSrcweir return 0;
927cdf0e10cSrcweir }
928cdf0e10cSrcweir else
929cdf0e10cSrcweir {
930cdf0e10cSrcweir // Es darf keine Fussnotencontainer in spaltigen Bereichen und
931cdf0e10cSrcweir // gleichzeitig auf der Seite/Seitenspalte geben
932cdf0e10cSrcweir if( pSct && !bAtSctEnd ) // liegt unser Container in einem (spaltigen) Bereich?
933cdf0e10cSrcweir {
934cdf0e10cSrcweir SwFtnBossFrm* pTmp = pBoss->FindSctFrm()->FindFtnBossFrm( sal_True );
935cdf0e10cSrcweir SwFtnContFrm* pFtnC = pTmp->FindFtnCont();
936cdf0e10cSrcweir if( pFtnC )
937cdf0e10cSrcweir {
938cdf0e10cSrcweir SwFtnFrm* pTmpFrm = (SwFtnFrm*)pFtnC->Lower();
939cdf0e10cSrcweir if( pTmpFrm && *pTmpFrm < pFtn )
940cdf0e10cSrcweir {
941cdf0e10cSrcweir rInf.SetStop( sal_True );
942cdf0e10cSrcweir UNDO_SWAP( pFrm )
943cdf0e10cSrcweir return 0;
944cdf0e10cSrcweir }
945cdf0e10cSrcweir }
946cdf0e10cSrcweir }
947cdf0e10cSrcweir // Ist dies die letzte passende Zeile?
948cdf0e10cSrcweir SwTwips nTmpBot = Y() + nReal * 2;
949cdf0e10cSrcweir
950cdf0e10cSrcweir if( bVertical )
951cdf0e10cSrcweir nTmpBot = pFrm->SwitchHorizontalToVertical( nTmpBot );
952cdf0e10cSrcweir
953cdf0e10cSrcweir SWRECTFN( pFtnCont )
954cdf0e10cSrcweir
955cdf0e10cSrcweir const long nDiff = (*fnRect->fnYDiff)(
956cdf0e10cSrcweir (pFtnCont->Frm().*fnRect->fnGetTop)(),
957cdf0e10cSrcweir nTmpBot );
958cdf0e10cSrcweir
959cdf0e10cSrcweir if( pScrFrm && nDiff < 0 )
960cdf0e10cSrcweir {
961cdf0e10cSrcweir if( pFtnFrm )
962cdf0e10cSrcweir {
963cdf0e10cSrcweir SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm();
964cdf0e10cSrcweir if( pFtnBoss != pBoss )
965cdf0e10cSrcweir {
966cdf0e10cSrcweir // Wir sind in der letzte Zeile und die Fussnote
967cdf0e10cSrcweir // ist auf eine andere Seite gewandert, dann wollen
968cdf0e10cSrcweir // wir mit ...
969cdf0e10cSrcweir rInf.SetStop( sal_True );
970cdf0e10cSrcweir UNDO_SWAP( pFrm )
971cdf0e10cSrcweir return 0;
972cdf0e10cSrcweir }
973cdf0e10cSrcweir }
974cdf0e10cSrcweir }
975cdf0e10cSrcweir }
976cdf0e10cSrcweir }
977cdf0e10cSrcweir }
978cdf0e10cSrcweir }
979cdf0e10cSrcweir // Endlich: FtnPortion anlegen und raus hier...
980cdf0e10cSrcweir SwFtnPortion *pRet = new SwFtnPortion( rFtn.GetViewNumStr( *pDoc ),
981cdf0e10cSrcweir pFrm, pFtn, nReal );
982cdf0e10cSrcweir rInf.SetFtnInside( sal_True );
983cdf0e10cSrcweir
984cdf0e10cSrcweir UNDO_SWAP( pFrm )
985cdf0e10cSrcweir
986cdf0e10cSrcweir return pRet;
987cdf0e10cSrcweir }
988cdf0e10cSrcweir
989cdf0e10cSrcweir /*************************************************************************
990cdf0e10cSrcweir * SwTxtFormatter::NewFtnNumPortion()
991cdf0e10cSrcweir *************************************************************************/
992cdf0e10cSrcweir
993cdf0e10cSrcweir // Die Portion fuer die Ftn-Nummerierung im Ftn-Bereich
994cdf0e10cSrcweir
NewFtnNumPortion(SwTxtFormatInfo & rInf) const995cdf0e10cSrcweir SwNumberPortion *SwTxtFormatter::NewFtnNumPortion( SwTxtFormatInfo &rInf ) const
996cdf0e10cSrcweir {
997cdf0e10cSrcweir ASSERT( pFrm->IsInFtn() && !pFrm->GetIndPrev() && !rInf.IsFtnDone(),
998cdf0e10cSrcweir "This is the wrong place for a ftnnumber" );
999cdf0e10cSrcweir if( rInf.GetTxtStart() != nStart ||
1000cdf0e10cSrcweir rInf.GetTxtStart() != rInf.GetIdx() )
1001cdf0e10cSrcweir return 0;
1002cdf0e10cSrcweir
1003cdf0e10cSrcweir const SwFtnFrm* pFtnFrm = pFrm->FindFtnFrm();
1004cdf0e10cSrcweir const SwTxtFtn* pFtn = pFtnFrm->GetAttr();
1005cdf0e10cSrcweir
1006cdf0e10cSrcweir // Aha, wir sind also im Fussnotenbereich
1007cdf0e10cSrcweir SwFmtFtn& rFtn = (SwFmtFtn&)pFtn->GetFtn();
1008cdf0e10cSrcweir
1009cdf0e10cSrcweir SwDoc *pDoc = pFrm->GetNode()->GetDoc();
1010cdf0e10cSrcweir XubString aFtnTxt( rFtn.GetViewNumStr( *pDoc, sal_True ));
1011cdf0e10cSrcweir
1012cdf0e10cSrcweir const SwEndNoteInfo* pInfo;
1013cdf0e10cSrcweir if( rFtn.IsEndNote() )
1014cdf0e10cSrcweir pInfo = &pDoc->GetEndNoteInfo();
1015cdf0e10cSrcweir else
1016cdf0e10cSrcweir pInfo = &pDoc->GetFtnInfo();
1017cdf0e10cSrcweir const SwAttrSet& rSet = pInfo->GetCharFmt(*pDoc)->GetAttrSet();
1018cdf0e10cSrcweir
1019cdf0e10cSrcweir const SwAttrSet* pParSet = &rInf.GetCharAttr();
1020cdf0e10cSrcweir const IDocumentSettingAccess* pIDSA = pFrm->GetTxtNode()->getIDocumentSettingAccess();
1021cdf0e10cSrcweir SwFont *pNumFnt = new SwFont( pParSet, pIDSA );
1022cdf0e10cSrcweir
1023cdf0e10cSrcweir // --> FME 2005-02-17 #i37142#
1024cdf0e10cSrcweir // Underline style of paragraph font should not be considered
1025cdf0e10cSrcweir // Overline style of paragraph font should not be considered
1026cdf0e10cSrcweir // Weight style of paragraph font should not be considered
1027cdf0e10cSrcweir // Posture style of paragraph font should not be considered
1028cdf0e10cSrcweir // See also #i18463# and SwTxtFormatter::NewNumberPortion()
1029cdf0e10cSrcweir pNumFnt->SetUnderline( UNDERLINE_NONE );
1030cdf0e10cSrcweir pNumFnt->SetOverline( UNDERLINE_NONE );
1031cdf0e10cSrcweir pNumFnt->SetItalic( ITALIC_NONE, SW_LATIN );
1032cdf0e10cSrcweir pNumFnt->SetItalic( ITALIC_NONE, SW_CJK );
1033cdf0e10cSrcweir pNumFnt->SetItalic( ITALIC_NONE, SW_CTL );
1034cdf0e10cSrcweir pNumFnt->SetWeight( WEIGHT_NORMAL, SW_LATIN );
1035cdf0e10cSrcweir pNumFnt->SetWeight( WEIGHT_NORMAL, SW_CJK );
1036cdf0e10cSrcweir pNumFnt->SetWeight( WEIGHT_NORMAL, SW_CTL );
1037cdf0e10cSrcweir // <--
1038cdf0e10cSrcweir
1039cdf0e10cSrcweir pNumFnt->SetDiffFnt(&rSet, pIDSA );
1040cdf0e10cSrcweir pNumFnt->SetVertical( pNumFnt->GetOrientation(), pFrm->IsVertical() );
1041cdf0e10cSrcweir
1042cdf0e10cSrcweir SwFtnNumPortion* pNewPor = new SwFtnNumPortion( aFtnTxt, pNumFnt );
1043cdf0e10cSrcweir pNewPor->SetLeft( !pFrm->IsRightToLeft() );
1044cdf0e10cSrcweir return pNewPor;
1045cdf0e10cSrcweir }
1046cdf0e10cSrcweir
1047cdf0e10cSrcweir /*************************************************************************
1048cdf0e10cSrcweir * SwTxtFormatter::NewErgoSumPortion()
1049cdf0e10cSrcweir *************************************************************************/
1050cdf0e10cSrcweir
lcl_GetPageNumber(const SwPageFrm * pPage)1051cdf0e10cSrcweir XubString lcl_GetPageNumber( const SwPageFrm* pPage )
1052cdf0e10cSrcweir {
1053cdf0e10cSrcweir ASSERT( pPage, "GetPageNumber: Homeless TxtFrm" );
1054cdf0e10cSrcweir MSHORT nVirtNum = pPage->GetVirtPageNum();
1055cdf0e10cSrcweir const SvxNumberType& rNum = pPage->GetPageDesc()->GetNumType();
1056cdf0e10cSrcweir return rNum.GetNumStr( nVirtNum );
1057cdf0e10cSrcweir }
1058cdf0e10cSrcweir
NewErgoSumPortion(SwTxtFormatInfo & rInf) const1059cdf0e10cSrcweir SwErgoSumPortion *SwTxtFormatter::NewErgoSumPortion( SwTxtFormatInfo &rInf ) const
1060cdf0e10cSrcweir {
1061cdf0e10cSrcweir // Wir koennen nicht davon ausgehen, dass wir ein Follow sind
1062cdf0e10cSrcweir // 7983: GetIdx() nicht nStart
1063cdf0e10cSrcweir if( !pFrm->IsInFtn() || pFrm->GetPrev() ||
1064cdf0e10cSrcweir rInf.IsErgoDone() || rInf.GetIdx() != pFrm->GetOfst() ||
1065cdf0e10cSrcweir pFrm->ImplFindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
1066cdf0e10cSrcweir return 0;
1067cdf0e10cSrcweir
1068cdf0e10cSrcweir // Aha, wir sind also im Fussnotenbereich
1069cdf0e10cSrcweir const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
1070cdf0e10cSrcweir SwTxtFrm *pQuoFrm = pFrm->FindQuoVadisFrm();
1071cdf0e10cSrcweir if( !pQuoFrm )
1072cdf0e10cSrcweir return 0;
1073cdf0e10cSrcweir const SwPageFrm* pPage = pFrm->FindPageFrm();
1074cdf0e10cSrcweir const SwPageFrm* pQuoPage = pQuoFrm->FindPageFrm();
1075cdf0e10cSrcweir if( pPage == pQuoFrm->FindPageFrm() )
1076cdf0e10cSrcweir return 0; // Wenn der QuoVadis auf der selben (spaltigen) Seite steht
1077cdf0e10cSrcweir const XubString aPage = lcl_GetPageNumber( pPage );
1078cdf0e10cSrcweir SwParaPortion *pPara = pQuoFrm->GetPara();
1079cdf0e10cSrcweir if( pPara )
1080cdf0e10cSrcweir pPara->SetErgoSumNum( aPage );
1081cdf0e10cSrcweir if( !rFtnInfo.aErgoSum.Len() )
1082cdf0e10cSrcweir return 0;
1083cdf0e10cSrcweir SwErgoSumPortion *pErgo = new SwErgoSumPortion( rFtnInfo.aErgoSum,
1084cdf0e10cSrcweir lcl_GetPageNumber( pQuoPage ) );
1085cdf0e10cSrcweir return pErgo;
1086cdf0e10cSrcweir }
1087cdf0e10cSrcweir
1088cdf0e10cSrcweir /*************************************************************************
1089cdf0e10cSrcweir * SwTxtFormatter::FormatQuoVadis()
1090cdf0e10cSrcweir *************************************************************************/
1091cdf0e10cSrcweir
FormatQuoVadis(const xub_StrLen nOffset)1092cdf0e10cSrcweir xub_StrLen SwTxtFormatter::FormatQuoVadis( const xub_StrLen nOffset )
1093cdf0e10cSrcweir {
1094cdf0e10cSrcweir ASSERT( ! pFrm->IsVertical() || ! pFrm->IsSwapped(),
1095cdf0e10cSrcweir "SwTxtFormatter::FormatQuoVadis with swapped frame" );
1096cdf0e10cSrcweir
1097cdf0e10cSrcweir if( !pFrm->IsInFtn() || pFrm->ImplFindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
1098cdf0e10cSrcweir return nOffset;
1099cdf0e10cSrcweir
1100cdf0e10cSrcweir const SwFrm* pErgoFrm = pFrm->FindFtnFrm()->GetFollow();
1101cdf0e10cSrcweir if( !pErgoFrm && pFrm->HasFollow() )
1102cdf0e10cSrcweir pErgoFrm = pFrm->GetFollow();
1103cdf0e10cSrcweir if( !pErgoFrm )
1104cdf0e10cSrcweir return nOffset;
1105cdf0e10cSrcweir
1106cdf0e10cSrcweir if( pErgoFrm == pFrm->GetNext() )
1107cdf0e10cSrcweir {
1108cdf0e10cSrcweir SwFrm *pCol = pFrm->FindColFrm();
1109cdf0e10cSrcweir while( pCol && !pCol->GetNext() )
1110cdf0e10cSrcweir pCol = pCol->GetUpper()->FindColFrm();
1111cdf0e10cSrcweir if( pCol )
1112cdf0e10cSrcweir return nOffset;
1113cdf0e10cSrcweir }
1114cdf0e10cSrcweir else
1115cdf0e10cSrcweir {
1116cdf0e10cSrcweir const SwPageFrm* pPage = pFrm->FindPageFrm();
1117cdf0e10cSrcweir const SwPageFrm* pErgoPage = pErgoFrm->FindPageFrm();
1118cdf0e10cSrcweir if( pPage == pErgoPage )
1119cdf0e10cSrcweir return nOffset; // Wenn der ErgoSum auf der selben Seite steht
1120cdf0e10cSrcweir }
1121cdf0e10cSrcweir
1122cdf0e10cSrcweir SwTxtFormatInfo &rInf = GetInfo();
1123cdf0e10cSrcweir const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
1124cdf0e10cSrcweir if( !rFtnInfo.aQuoVadis.Len() )
1125cdf0e10cSrcweir return nOffset;
1126cdf0e10cSrcweir
1127cdf0e10cSrcweir // Ein Wort zu QuoVadis/ErgoSum:
1128cdf0e10cSrcweir // Fuer diese Texte wird der am Absatz eingestellte Font verwendet.
1129cdf0e10cSrcweir // Wir initialisieren uns also:
1130cdf0e10cSrcweir // ResetFont();
1131cdf0e10cSrcweir FeedInf( rInf );
1132cdf0e10cSrcweir SeekStartAndChg( rInf, sal_True );
1133cdf0e10cSrcweir if( GetRedln() && pCurr->HasRedline() )
1134cdf0e10cSrcweir GetRedln()->Seek( *pFnt, nOffset, 0 );
1135cdf0e10cSrcweir
1136cdf0e10cSrcweir // Ein fieser Sonderfall: Flyfrms reichen in die Zeile und stehen
1137cdf0e10cSrcweir // natuerlich da, wo wir unseren Quovadis Text reinsetzen wollen.
1138cdf0e10cSrcweir // Erst mal sehen, ob es so schlimm ist:
1139cdf0e10cSrcweir SwLinePortion *pPor = pCurr->GetFirstPortion();
1140cdf0e10cSrcweir KSHORT nLastLeft = 0;
1141cdf0e10cSrcweir while( pPor )
1142cdf0e10cSrcweir {
1143cdf0e10cSrcweir if ( pPor->IsFlyPortion() )
1144cdf0e10cSrcweir nLastLeft = ( (SwFlyPortion*) pPor)->Fix() +
1145cdf0e10cSrcweir ( (SwFlyPortion*) pPor)->Width();
1146cdf0e10cSrcweir pPor = pPor->GetPortion();
1147cdf0e10cSrcweir }
1148cdf0e10cSrcweir // Das alte Spiel: wir wollen, dass die Zeile an einer bestimmten
1149cdf0e10cSrcweir // Stelle umbricht, also beeinflussen wir die Width.
1150cdf0e10cSrcweir // nLastLeft ist jetzt quasi der rechte Rand.
1151cdf0e10cSrcweir const KSHORT nOldRealWidth = rInf.RealWidth();
1152cdf0e10cSrcweir rInf.RealWidth( nOldRealWidth - nLastLeft );
1153cdf0e10cSrcweir
1154cdf0e10cSrcweir XubString aErgo = lcl_GetPageNumber( pErgoFrm->FindPageFrm() );
1155cdf0e10cSrcweir SwQuoVadisPortion *pQuo = new SwQuoVadisPortion(rFtnInfo.aQuoVadis, aErgo );
1156cdf0e10cSrcweir pQuo->SetAscent( rInf.GetAscent() );
1157cdf0e10cSrcweir pQuo->Height( rInf.GetTxtHeight() );
1158cdf0e10cSrcweir pQuo->Format( rInf );
1159cdf0e10cSrcweir sal_uInt16 nQuoWidth = pQuo->Width();
1160cdf0e10cSrcweir SwLinePortion* pCurrPor = pQuo;
1161cdf0e10cSrcweir
1162cdf0e10cSrcweir while ( rInf.GetRest() )
1163cdf0e10cSrcweir {
1164cdf0e10cSrcweir SwLinePortion* pFollow = rInf.GetRest();
1165cdf0e10cSrcweir rInf.SetRest( 0 );
1166cdf0e10cSrcweir pCurrPor->Move( rInf );
1167cdf0e10cSrcweir
1168cdf0e10cSrcweir ASSERT( pFollow->IsQuoVadisPortion(),
1169cdf0e10cSrcweir "Quo Vadis, rest of QuoVadisPortion" )
1170cdf0e10cSrcweir
1171cdf0e10cSrcweir // format the rest and append it to the other QuoVadis parts
1172cdf0e10cSrcweir pFollow->Format( rInf );
1173cdf0e10cSrcweir nQuoWidth = nQuoWidth + pFollow->Width();
1174cdf0e10cSrcweir
1175cdf0e10cSrcweir pCurrPor->Append( pFollow );
1176cdf0e10cSrcweir pCurrPor = pFollow;
1177cdf0e10cSrcweir }
1178cdf0e10cSrcweir
1179cdf0e10cSrcweir nLastLeft = nOldRealWidth - nQuoWidth;
1180cdf0e10cSrcweir Right( Right() - nQuoWidth );
1181cdf0e10cSrcweir
1182cdf0e10cSrcweir SWAP_IF_NOT_SWAPPED( pFrm )
1183cdf0e10cSrcweir
1184cdf0e10cSrcweir const xub_StrLen nRet = FormatLine( nStart );
1185cdf0e10cSrcweir
1186cdf0e10cSrcweir UNDO_SWAP( pFrm )
1187cdf0e10cSrcweir
1188cdf0e10cSrcweir Right( rInf.Left() + nOldRealWidth - 1 );
1189cdf0e10cSrcweir
1190cdf0e10cSrcweir nLastLeft = nOldRealWidth - pCurr->Width();
1191cdf0e10cSrcweir FeedInf( rInf );
1192cdf0e10cSrcweir
1193cdf0e10cSrcweir // Es kann durchaus sein, dass am Ende eine Marginportion steht,
1194cdf0e10cSrcweir // die beim erneuten Aufspannen nur Aerger bereiten wuerde.
1195cdf0e10cSrcweir pPor = pCurr->FindLastPortion();
1196cdf0e10cSrcweir SwGluePortion *pGlue = pPor->IsMarginPortion() ?
1197cdf0e10cSrcweir (SwMarginPortion*) pPor : 0;
1198cdf0e10cSrcweir if( pGlue )
1199cdf0e10cSrcweir {
1200cdf0e10cSrcweir pGlue->Height( 0 );
1201cdf0e10cSrcweir pGlue->Width( 0 );
1202cdf0e10cSrcweir pGlue->SetLen( 0 );
1203cdf0e10cSrcweir pGlue->SetAscent( 0 );
1204cdf0e10cSrcweir pGlue->SetPortion( NULL );
1205cdf0e10cSrcweir pGlue->SetFixWidth(0);
1206cdf0e10cSrcweir }
1207cdf0e10cSrcweir
1208cdf0e10cSrcweir // Luxus: Wir sorgen durch das Aufspannen von Glues dafuer,
1209cdf0e10cSrcweir // dass der QuoVadis-Text rechts erscheint:
1210cdf0e10cSrcweir nLastLeft = nLastLeft - nQuoWidth;
1211cdf0e10cSrcweir if( nLastLeft )
1212cdf0e10cSrcweir {
1213cdf0e10cSrcweir if( nLastLeft > pQuo->GetAscent() ) // Mindestabstand
1214cdf0e10cSrcweir {
1215cdf0e10cSrcweir switch( GetAdjust() )
1216cdf0e10cSrcweir {
1217cdf0e10cSrcweir case SVX_ADJUST_BLOCK:
1218cdf0e10cSrcweir {
1219cdf0e10cSrcweir if( !pCurr->GetLen() ||
1220cdf0e10cSrcweir CH_BREAK != GetInfo().GetChar(nStart+pCurr->GetLen()-1))
1221cdf0e10cSrcweir nLastLeft = pQuo->GetAscent();
1222cdf0e10cSrcweir nQuoWidth = nQuoWidth + nLastLeft;
1223cdf0e10cSrcweir break;
1224cdf0e10cSrcweir }
1225cdf0e10cSrcweir case SVX_ADJUST_RIGHT:
1226cdf0e10cSrcweir {
1227cdf0e10cSrcweir nLastLeft = pQuo->GetAscent();
1228cdf0e10cSrcweir nQuoWidth = nQuoWidth + nLastLeft;
1229cdf0e10cSrcweir break;
1230cdf0e10cSrcweir }
1231cdf0e10cSrcweir case SVX_ADJUST_CENTER:
1232cdf0e10cSrcweir {
1233cdf0e10cSrcweir nQuoWidth = nQuoWidth + pQuo->GetAscent();
1234cdf0e10cSrcweir long nDiff = nLastLeft - nQuoWidth;
1235cdf0e10cSrcweir if( nDiff < 0 )
1236cdf0e10cSrcweir {
1237cdf0e10cSrcweir nLastLeft = pQuo->GetAscent();
1238cdf0e10cSrcweir nQuoWidth = (sal_uInt16)(-nDiff + nLastLeft);
1239cdf0e10cSrcweir }
1240cdf0e10cSrcweir else
1241cdf0e10cSrcweir {
1242cdf0e10cSrcweir nQuoWidth = 0;
1243cdf0e10cSrcweir nLastLeft = sal_uInt16(( pQuo->GetAscent() + nDiff ) / 2);
1244cdf0e10cSrcweir }
1245cdf0e10cSrcweir break;
1246cdf0e10cSrcweir }
1247cdf0e10cSrcweir default:
1248cdf0e10cSrcweir nQuoWidth = nQuoWidth + nLastLeft;
1249cdf0e10cSrcweir }
1250cdf0e10cSrcweir }
1251cdf0e10cSrcweir else
1252cdf0e10cSrcweir nQuoWidth = nQuoWidth + nLastLeft;
1253cdf0e10cSrcweir if( nLastLeft )
1254cdf0e10cSrcweir {
1255cdf0e10cSrcweir pGlue = new SwGluePortion(0);
1256cdf0e10cSrcweir pGlue->Width( nLastLeft );
1257cdf0e10cSrcweir pPor->Append( pGlue );
1258cdf0e10cSrcweir pPor = pPor->GetPortion();
1259cdf0e10cSrcweir }
1260cdf0e10cSrcweir }
1261cdf0e10cSrcweir
1262cdf0e10cSrcweir // Jetzt aber: die QuoVadis-Portion wird angedockt:
1263cdf0e10cSrcweir pCurrPor = pQuo;
1264cdf0e10cSrcweir while ( pCurrPor )
1265cdf0e10cSrcweir {
1266cdf0e10cSrcweir // pPor->Append deletes the pPortoin pointer of pPor. Therefore
1267cdf0e10cSrcweir // we have to keep a pointer to the next portion
1268cdf0e10cSrcweir pQuo = (SwQuoVadisPortion*)pCurrPor->GetPortion();
1269cdf0e10cSrcweir pPor->Append( pCurrPor );
1270cdf0e10cSrcweir pPor = pPor->GetPortion();
1271cdf0e10cSrcweir pCurrPor = pQuo;
1272cdf0e10cSrcweir }
1273cdf0e10cSrcweir
1274cdf0e10cSrcweir pCurr->Width( pCurr->Width() + KSHORT( nQuoWidth ) );
1275cdf0e10cSrcweir
1276cdf0e10cSrcweir // Und noch einmal adjustieren wegen des Adjustment und nicht zu Letzt
1277cdf0e10cSrcweir // wegen folgendem Sonderfall: In der Zeile hat der DummUser durchgaengig
1278cdf0e10cSrcweir // einen kleineren Font eingestellt als der vom QuoVadis-Text ...
1279cdf0e10cSrcweir CalcAdjustLine( pCurr );
1280cdf0e10cSrcweir
1281cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1282cdf0e10cSrcweir if( OPTDBG( rInf ) )
1283cdf0e10cSrcweir {
1284cdf0e10cSrcweir // aDbstream << "FormatQuoVadis:" << endl;
1285cdf0e10cSrcweir // pCurr->DebugPortions( aDbstream, rInf.GetTxt(), nStart );
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir #endif
1288cdf0e10cSrcweir
1289cdf0e10cSrcweir // Uff...
1290cdf0e10cSrcweir return nRet;
1291cdf0e10cSrcweir }
1292cdf0e10cSrcweir
1293cdf0e10cSrcweir
1294cdf0e10cSrcweir /*************************************************************************
1295cdf0e10cSrcweir * SwTxtFormatter::MakeDummyLine()
1296cdf0e10cSrcweir *************************************************************************/
1297cdf0e10cSrcweir
1298cdf0e10cSrcweir // MakeDummyLine() erzeugt eine Line, die bis zum unteren Seitenrand
1299cdf0e10cSrcweir // reicht. DummyLines bzw. DummyPortions sorgen dafuer, dass Oszillationen
1300cdf0e10cSrcweir // zum stehen kommen, weil Rueckflussmoeglichkeiten genommen werden.
1301cdf0e10cSrcweir // Sie werden bei absatzgebundenen Frames in Fussnoten und bei Ftn-
1302cdf0e10cSrcweir // Oszillationen verwendet.
1303cdf0e10cSrcweir
MakeDummyLine()1304cdf0e10cSrcweir void SwTxtFormatter::MakeDummyLine()
1305cdf0e10cSrcweir {
1306cdf0e10cSrcweir KSHORT nRstHeight = GetFrmRstHeight();
1307cdf0e10cSrcweir if( pCurr && nRstHeight > pCurr->Height() )
1308cdf0e10cSrcweir {
1309cdf0e10cSrcweir SwLineLayout *pLay = new SwLineLayout;
1310cdf0e10cSrcweir nRstHeight = nRstHeight - pCurr->Height();
1311cdf0e10cSrcweir pLay->Height( nRstHeight );
1312cdf0e10cSrcweir pLay->SetAscent( nRstHeight );
1313cdf0e10cSrcweir Insert( pLay );
1314cdf0e10cSrcweir Next();
1315cdf0e10cSrcweir }
1316cdf0e10cSrcweir }
1317cdf0e10cSrcweir
1318cdf0e10cSrcweir /*************************************************************************
1319cdf0e10cSrcweir * class SwFtnSave
1320cdf0e10cSrcweir *************************************************************************/
1321cdf0e10cSrcweir class SwFtnSave
1322cdf0e10cSrcweir {
1323cdf0e10cSrcweir SwTxtSizeInfo *pInf;
1324cdf0e10cSrcweir SwFont *pFnt;
1325cdf0e10cSrcweir SwFont *pOld;
1326cdf0e10cSrcweir public:
1327cdf0e10cSrcweir SwFtnSave( const SwTxtSizeInfo &rInf,
1328cdf0e10cSrcweir const SwTxtFtn *pTxtFtn,
1329cdf0e10cSrcweir const bool bApplyGivenScriptType,
1330cdf0e10cSrcweir const sal_uInt8 nGivenScriptType );
1331cdf0e10cSrcweir ~SwFtnSave();
1332cdf0e10cSrcweir };
1333cdf0e10cSrcweir
1334cdf0e10cSrcweir /*************************************************************************
1335cdf0e10cSrcweir * SwFtnSave::SwFtnSave()
1336cdf0e10cSrcweir *************************************************************************/
1337cdf0e10cSrcweir
SwFtnSave(const SwTxtSizeInfo & rInf,const SwTxtFtn * pTxtFtn,const bool bApplyGivenScriptType,const sal_uInt8 nGivenScriptType)1338cdf0e10cSrcweir SwFtnSave::SwFtnSave( const SwTxtSizeInfo &rInf,
1339cdf0e10cSrcweir const SwTxtFtn* pTxtFtn,
1340cdf0e10cSrcweir const bool bApplyGivenScriptType,
1341cdf0e10cSrcweir const sal_uInt8 nGivenScriptType )
1342cdf0e10cSrcweir : pInf( &((SwTxtSizeInfo&)rInf) )
1343cdf0e10cSrcweir , pFnt( 0 )
1344cdf0e10cSrcweir , pOld( 0 )
1345cdf0e10cSrcweir {
1346cdf0e10cSrcweir if( pTxtFtn && rInf.GetTxtFrm() )
1347cdf0e10cSrcweir {
1348cdf0e10cSrcweir pFnt = ((SwTxtSizeInfo&)rInf).GetFont();
1349cdf0e10cSrcweir pOld = new SwFont( *pFnt );
1350cdf0e10cSrcweir pOld->GetTox() = pFnt->GetTox();
1351cdf0e10cSrcweir pFnt->GetTox() = 0;
1352cdf0e10cSrcweir SwFmtFtn& rFtn = (SwFmtFtn&)pTxtFtn->GetFtn();
1353cdf0e10cSrcweir const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc();
1354cdf0e10cSrcweir
1355cdf0e10cSrcweir // --> OD 2009-01-29 #i98418#
1356cdf0e10cSrcweir if ( bApplyGivenScriptType )
1357cdf0e10cSrcweir {
1358cdf0e10cSrcweir pFnt->SetActual( nGivenScriptType );
1359cdf0e10cSrcweir }
1360cdf0e10cSrcweir else
1361cdf0e10cSrcweir {
1362cdf0e10cSrcweir // examine text and set script
1363cdf0e10cSrcweir String aTmpStr( rFtn.GetViewNumStr( *pDoc ) );
1364cdf0e10cSrcweir pFnt->SetActual( SwScriptInfo::WhichFont( 0, &aTmpStr, 0 ) );
1365cdf0e10cSrcweir }
1366cdf0e10cSrcweir // <--
1367cdf0e10cSrcweir
1368cdf0e10cSrcweir const SwEndNoteInfo* pInfo;
1369cdf0e10cSrcweir if( rFtn.IsEndNote() )
1370cdf0e10cSrcweir pInfo = &pDoc->GetEndNoteInfo();
1371cdf0e10cSrcweir else
1372cdf0e10cSrcweir pInfo = &pDoc->GetFtnInfo();
1373cdf0e10cSrcweir const SwAttrSet& rSet = pInfo->GetAnchorCharFmt((SwDoc&)*pDoc)->GetAttrSet();
1374cdf0e10cSrcweir pFnt->SetDiffFnt( &rSet, rInf.GetTxtFrm()->GetNode()->getIDocumentSettingAccess() );
1375cdf0e10cSrcweir
1376cdf0e10cSrcweir // we reduce footnote size, if we are inside a double line portion
1377cdf0e10cSrcweir if ( ! pOld->GetEscapement() && 50 == pOld->GetPropr() )
1378cdf0e10cSrcweir {
1379cdf0e10cSrcweir Size aSize = pFnt->GetSize( pFnt->GetActual() );
1380cdf0e10cSrcweir pFnt->SetSize( Size( (long)aSize.Width() / 2,
1381cdf0e10cSrcweir (long)aSize.Height() / 2 ),
1382cdf0e10cSrcweir pFnt->GetActual() );
1383cdf0e10cSrcweir }
1384cdf0e10cSrcweir
1385cdf0e10cSrcweir // set the correct rotation at the footnote font
1386cdf0e10cSrcweir const SfxPoolItem* pItem;
1387cdf0e10cSrcweir if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ROTATE,
1388cdf0e10cSrcweir sal_True, &pItem ))
1389cdf0e10cSrcweir pFnt->SetVertical( ((SvxCharRotateItem*)pItem)->GetValue(),
1390cdf0e10cSrcweir rInf.GetTxtFrm()->IsVertical() );
1391cdf0e10cSrcweir
1392cdf0e10cSrcweir pFnt->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() );
1393cdf0e10cSrcweir
1394cdf0e10cSrcweir if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_BACKGROUND,
1395cdf0e10cSrcweir sal_True, &pItem ))
1396cdf0e10cSrcweir pFnt->SetBackColor( new Color( ((SvxBrushItem*)pItem)->GetColor() ) );
1397cdf0e10cSrcweir }
1398cdf0e10cSrcweir else
1399cdf0e10cSrcweir pFnt = NULL;
1400cdf0e10cSrcweir }
1401cdf0e10cSrcweir
1402cdf0e10cSrcweir /*************************************************************************
1403cdf0e10cSrcweir * SwFtnSave::~SwFtnSave()
1404cdf0e10cSrcweir *************************************************************************/
1405cdf0e10cSrcweir
~SwFtnSave()1406cdf0e10cSrcweir SwFtnSave::~SwFtnSave()
1407cdf0e10cSrcweir {
1408cdf0e10cSrcweir if( pFnt )
1409cdf0e10cSrcweir {
1410cdf0e10cSrcweir // SwFont zurueckstellen
1411cdf0e10cSrcweir *pFnt = *pOld;
1412cdf0e10cSrcweir pFnt->GetTox() = pOld->GetTox();
1413cdf0e10cSrcweir pFnt->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() );
1414cdf0e10cSrcweir delete pOld;
1415cdf0e10cSrcweir }
1416cdf0e10cSrcweir }
1417cdf0e10cSrcweir
1418cdf0e10cSrcweir /*************************************************************************
1419cdf0e10cSrcweir * SwFtnPortion::SwFtnPortion()
1420cdf0e10cSrcweir *************************************************************************/
1421cdf0e10cSrcweir
SwFtnPortion(const XubString & rExpand,SwTxtFrm * pFrame,SwTxtFtn * pFootn,KSHORT nReal)1422cdf0e10cSrcweir SwFtnPortion::SwFtnPortion( const XubString &rExpand, SwTxtFrm *pFrame,
1423cdf0e10cSrcweir SwTxtFtn *pFootn, KSHORT nReal )
1424cdf0e10cSrcweir : SwFldPortion( rExpand, 0 )
1425cdf0e10cSrcweir , pFrm(pFrame)
1426cdf0e10cSrcweir , pFtn(pFootn)
1427cdf0e10cSrcweir , nOrigHeight( nReal )
1428cdf0e10cSrcweir // --> OD 2009-01-29 #i98418#
1429cdf0e10cSrcweir , mbPreferredScriptTypeSet( false )
1430cdf0e10cSrcweir , mnPreferredScriptType( SW_LATIN )
1431cdf0e10cSrcweir // <--
1432cdf0e10cSrcweir {
1433cdf0e10cSrcweir SetLen(1);
1434cdf0e10cSrcweir SetWhichPor( POR_FTN );
1435cdf0e10cSrcweir }
1436cdf0e10cSrcweir
1437cdf0e10cSrcweir /*************************************************************************
1438cdf0e10cSrcweir * SwFtnPortion::GetExpTxt()
1439cdf0e10cSrcweir *************************************************************************/
1440cdf0e10cSrcweir
GetExpTxt(const SwTxtSizeInfo &,XubString & rTxt) const1441cdf0e10cSrcweir sal_Bool SwFtnPortion::GetExpTxt( const SwTxtSizeInfo &, XubString &rTxt ) const
1442cdf0e10cSrcweir {
1443cdf0e10cSrcweir rTxt = aExpand;
1444cdf0e10cSrcweir return sal_True;
1445cdf0e10cSrcweir }
1446cdf0e10cSrcweir
1447cdf0e10cSrcweir /*************************************************************************
1448cdf0e10cSrcweir * virtual SwFtnPortion::Format()
1449cdf0e10cSrcweir *************************************************************************/
1450cdf0e10cSrcweir
Format(SwTxtFormatInfo & rInf)1451cdf0e10cSrcweir sal_Bool SwFtnPortion::Format( SwTxtFormatInfo &rInf )
1452cdf0e10cSrcweir {
1453cdf0e10cSrcweir // --> OD 2009-01-29 #i98418#
1454cdf0e10cSrcweir // SwFtnSave aFtnSave( rInf, pFtn );
1455cdf0e10cSrcweir SwFtnSave aFtnSave( rInf, pFtn, mbPreferredScriptTypeSet, mnPreferredScriptType );
1456cdf0e10cSrcweir // <--
1457cdf0e10cSrcweir // the idx is manipulated in SwExpandPortion::Format
1458cdf0e10cSrcweir // this flag indicates, that a footnote is allowed to trigger
1459cdf0e10cSrcweir // an underflow during SwTxtGuess::Guess
1460cdf0e10cSrcweir rInf.SetFakeLineStart( rInf.GetIdx() > rInf.GetLineStart() );
1461cdf0e10cSrcweir sal_Bool bFull = SwFldPortion::Format( rInf );
1462cdf0e10cSrcweir rInf.SetFakeLineStart( sal_False );
1463cdf0e10cSrcweir SetAscent( rInf.GetAscent() );
1464cdf0e10cSrcweir Height( rInf.GetTxtHeight() );
1465cdf0e10cSrcweir rInf.SetFtnDone( !bFull );
1466cdf0e10cSrcweir if( !bFull )
1467cdf0e10cSrcweir rInf.SetParaFtn();
1468cdf0e10cSrcweir return bFull;
1469cdf0e10cSrcweir }
1470cdf0e10cSrcweir
1471cdf0e10cSrcweir /*************************************************************************
1472cdf0e10cSrcweir * virtual SwFtnPortion::Paint()
1473cdf0e10cSrcweir *************************************************************************/
1474cdf0e10cSrcweir
Paint(const SwTxtPaintInfo & rInf) const1475cdf0e10cSrcweir void SwFtnPortion::Paint( const SwTxtPaintInfo &rInf ) const
1476cdf0e10cSrcweir {
1477cdf0e10cSrcweir // --> OD 2009-01-29 #i98418#
1478cdf0e10cSrcweir // SwFtnSave aFtnSave( rInf, pFtn );
1479cdf0e10cSrcweir SwFtnSave aFtnSave( rInf, pFtn, mbPreferredScriptTypeSet, mnPreferredScriptType );
1480cdf0e10cSrcweir // <--
1481cdf0e10cSrcweir rInf.DrawViewOpt( *this, POR_FTN );
1482cdf0e10cSrcweir SwExpandPortion::Paint( rInf );
1483cdf0e10cSrcweir }
1484cdf0e10cSrcweir
1485cdf0e10cSrcweir /*************************************************************************
1486cdf0e10cSrcweir * virtual SwFtnPortion::GetTxtSize()
1487cdf0e10cSrcweir *************************************************************************/
1488cdf0e10cSrcweir
GetTxtSize(const SwTxtSizeInfo & rInfo) const1489cdf0e10cSrcweir SwPosSize SwFtnPortion::GetTxtSize( const SwTxtSizeInfo &rInfo ) const
1490cdf0e10cSrcweir {
1491cdf0e10cSrcweir // --> OD 2009-01-29 #i98418#
1492cdf0e10cSrcweir // SwFtnSave aFtnSave( rInfo, pFtn );
1493cdf0e10cSrcweir SwFtnSave aFtnSave( rInfo, pFtn, mbPreferredScriptTypeSet, mnPreferredScriptType );
1494cdf0e10cSrcweir // <--
1495cdf0e10cSrcweir return SwExpandPortion::GetTxtSize( rInfo );
1496cdf0e10cSrcweir }
1497cdf0e10cSrcweir
1498cdf0e10cSrcweir // --> OD 2009-01-29 #i98418#
SetPreferredScriptType(sal_uInt8 nPreferredScriptType)1499cdf0e10cSrcweir void SwFtnPortion::SetPreferredScriptType( sal_uInt8 nPreferredScriptType )
1500cdf0e10cSrcweir {
1501cdf0e10cSrcweir mbPreferredScriptTypeSet = true;
1502cdf0e10cSrcweir mnPreferredScriptType = nPreferredScriptType;
1503cdf0e10cSrcweir }
1504cdf0e10cSrcweir // <--
1505cdf0e10cSrcweir
1506cdf0e10cSrcweir /*************************************************************************
1507cdf0e10cSrcweir * class SwQuoVadisPortion
1508cdf0e10cSrcweir *************************************************************************/
1509cdf0e10cSrcweir
Clone(const XubString & rExpand) const1510cdf0e10cSrcweir SwFldPortion *SwQuoVadisPortion::Clone( const XubString &rExpand ) const
1511cdf0e10cSrcweir { return new SwQuoVadisPortion( rExpand, aErgo ); }
1512cdf0e10cSrcweir
SwQuoVadisPortion(const XubString & rExp,const XubString & rStr)1513cdf0e10cSrcweir SwQuoVadisPortion::SwQuoVadisPortion( const XubString &rExp, const XubString& rStr )
1514cdf0e10cSrcweir : SwFldPortion( rExp ), aErgo(rStr)
1515cdf0e10cSrcweir {
1516cdf0e10cSrcweir SetLen(0);
1517cdf0e10cSrcweir SetWhichPor( POR_QUOVADIS );
1518cdf0e10cSrcweir }
1519cdf0e10cSrcweir
1520cdf0e10cSrcweir /*************************************************************************
1521cdf0e10cSrcweir * virtual SwQuoVadisPortion::Format()
1522cdf0e10cSrcweir *************************************************************************/
1523cdf0e10cSrcweir
Format(SwTxtFormatInfo & rInf)1524cdf0e10cSrcweir sal_Bool SwQuoVadisPortion::Format( SwTxtFormatInfo &rInf )
1525cdf0e10cSrcweir {
1526cdf0e10cSrcweir // erster Versuch, vielleicht passt der Text
1527cdf0e10cSrcweir CheckScript( rInf );
1528cdf0e10cSrcweir sal_Bool bFull = SwFldPortion::Format( rInf );
1529cdf0e10cSrcweir SetLen( 0 );
1530cdf0e10cSrcweir
1531cdf0e10cSrcweir if( bFull )
1532cdf0e10cSrcweir {
1533cdf0e10cSrcweir // zweiter Versuch, wir kuerzen den String:
1534cdf0e10cSrcweir aExpand = XubString( "...", RTL_TEXTENCODING_MS_1252 );
1535cdf0e10cSrcweir bFull = SwFldPortion::Format( rInf );
1536cdf0e10cSrcweir SetLen( 0 );
1537cdf0e10cSrcweir if( bFull )
1538cdf0e10cSrcweir // dritter Versuch, es langt: jetzt wird gestaucht:
1539cdf0e10cSrcweir Width( sal_uInt16(rInf.Width() - rInf.X()) );
1540cdf0e10cSrcweir
1541cdf0e10cSrcweir // 8317: keine mehrzeiligen Felder bei QuoVadis und ErgoSum
1542cdf0e10cSrcweir if( rInf.GetRest() )
1543cdf0e10cSrcweir {
1544cdf0e10cSrcweir delete rInf.GetRest();
1545cdf0e10cSrcweir rInf.SetRest( 0 );
1546cdf0e10cSrcweir }
1547cdf0e10cSrcweir }
1548cdf0e10cSrcweir return bFull;
1549cdf0e10cSrcweir }
1550cdf0e10cSrcweir
1551cdf0e10cSrcweir /*************************************************************************
1552cdf0e10cSrcweir * virtual SwQuoVadisPortion::GetExpTxt()
1553cdf0e10cSrcweir *************************************************************************/
1554cdf0e10cSrcweir
GetExpTxt(const SwTxtSizeInfo &,XubString & rTxt) const1555cdf0e10cSrcweir sal_Bool SwQuoVadisPortion::GetExpTxt( const SwTxtSizeInfo &, XubString &rTxt ) const
1556cdf0e10cSrcweir {
1557cdf0e10cSrcweir rTxt = aExpand;
1558cdf0e10cSrcweir // if this QuoVadisPortion has a follow, the follow is responsible for
1559cdf0e10cSrcweir // the ergo text.
1560cdf0e10cSrcweir if ( ! HasFollow() )
1561cdf0e10cSrcweir rTxt += aErgo;
1562cdf0e10cSrcweir return sal_True;
1563cdf0e10cSrcweir }
1564cdf0e10cSrcweir
1565cdf0e10cSrcweir /*************************************************************************
1566cdf0e10cSrcweir * virtual SwQuoVadisPortion::HandlePortion()
1567cdf0e10cSrcweir *************************************************************************/
1568cdf0e10cSrcweir
HandlePortion(SwPortionHandler & rPH) const1569cdf0e10cSrcweir void SwQuoVadisPortion::HandlePortion( SwPortionHandler& rPH ) const
1570cdf0e10cSrcweir {
1571cdf0e10cSrcweir String aString( aExpand );
1572cdf0e10cSrcweir aString += aErgo;
1573cdf0e10cSrcweir rPH.Special( GetLen(), aString, GetWhichPor() );
1574cdf0e10cSrcweir }
1575cdf0e10cSrcweir
1576cdf0e10cSrcweir /*************************************************************************
1577cdf0e10cSrcweir * virtual SwQuoVadisPortion::Paint()
1578cdf0e10cSrcweir *************************************************************************/
1579cdf0e10cSrcweir
Paint(const SwTxtPaintInfo & rInf) const1580cdf0e10cSrcweir void SwQuoVadisPortion::Paint( const SwTxtPaintInfo &rInf ) const
1581cdf0e10cSrcweir {
1582cdf0e10cSrcweir // Wir wollen _immer_ per DrawStretchText ausgeben,
1583cdf0e10cSrcweir // weil nErgo schnell mal wechseln kann.
1584cdf0e10cSrcweir if( PrtWidth() )
1585cdf0e10cSrcweir {
1586cdf0e10cSrcweir rInf.DrawViewOpt( *this, POR_QUOVADIS );
1587cdf0e10cSrcweir SwTxtSlot aDiffTxt( &rInf, this, true, false );
1588cdf0e10cSrcweir SwFontSave aSave( rInf, pFnt );
1589cdf0e10cSrcweir rInf.DrawText( *this, rInf.GetLen(), sal_True );
1590cdf0e10cSrcweir }
1591cdf0e10cSrcweir }
1592cdf0e10cSrcweir
1593cdf0e10cSrcweir /*************************************************************************
1594cdf0e10cSrcweir * class SwErgoSumPortion
1595cdf0e10cSrcweir *************************************************************************/
1596cdf0e10cSrcweir
Clone(const XubString & rExpand) const1597cdf0e10cSrcweir SwFldPortion *SwErgoSumPortion::Clone( const XubString &rExpand ) const
1598cdf0e10cSrcweir {
1599cdf0e10cSrcweir UniString aTmp; // = UniString::CreateFromInt32( 0 );
1600cdf0e10cSrcweir return new SwErgoSumPortion( rExpand, aTmp );
1601cdf0e10cSrcweir }
1602cdf0e10cSrcweir
SwErgoSumPortion(const XubString & rExp,const XubString & rStr)1603cdf0e10cSrcweir SwErgoSumPortion::SwErgoSumPortion( const XubString &rExp, const XubString& rStr )
1604cdf0e10cSrcweir : SwFldPortion( rExp )
1605cdf0e10cSrcweir {
1606cdf0e10cSrcweir SetLen(0);
1607cdf0e10cSrcweir aExpand += rStr;
1608cdf0e10cSrcweir
1609cdf0e10cSrcweir // 7773: sinnvolle Massnahme: ein Blank Abstand zum Text
1610cdf0e10cSrcweir aExpand += ' ';
1611cdf0e10cSrcweir SetWhichPor( POR_ERGOSUM );
1612cdf0e10cSrcweir }
1613cdf0e10cSrcweir
GetCrsrOfst(const KSHORT) const1614cdf0e10cSrcweir xub_StrLen SwErgoSumPortion::GetCrsrOfst( const KSHORT ) const
1615cdf0e10cSrcweir {
1616cdf0e10cSrcweir return 0;
1617cdf0e10cSrcweir }
1618cdf0e10cSrcweir
1619cdf0e10cSrcweir /*************************************************************************
1620cdf0e10cSrcweir * virtual SwErgoSumPortion::Format()
1621cdf0e10cSrcweir *************************************************************************/
1622cdf0e10cSrcweir
Format(SwTxtFormatInfo & rInf)1623cdf0e10cSrcweir sal_Bool SwErgoSumPortion::Format( SwTxtFormatInfo &rInf )
1624cdf0e10cSrcweir {
1625cdf0e10cSrcweir sal_Bool bFull = SwFldPortion::Format( rInf );
1626cdf0e10cSrcweir SetLen( 0 );
1627cdf0e10cSrcweir rInf.SetErgoDone( sal_True );
1628cdf0e10cSrcweir
1629cdf0e10cSrcweir // 8317: keine mehrzeiligen Felder bei QuoVadis und ErgoSum
1630cdf0e10cSrcweir if( bFull && rInf.GetRest() )
1631cdf0e10cSrcweir {
1632cdf0e10cSrcweir delete rInf.GetRest();
1633cdf0e10cSrcweir rInf.SetRest( 0 );
1634cdf0e10cSrcweir }
1635cdf0e10cSrcweir
1636cdf0e10cSrcweir // We return false in order to get some text into the current line,
1637cdf0e10cSrcweir // even if it's full (better than looping)
1638cdf0e10cSrcweir return sal_False;
1639cdf0e10cSrcweir }
1640cdf0e10cSrcweir
1641cdf0e10cSrcweir
1642cdf0e10cSrcweir /*************************************************************************
1643cdf0e10cSrcweir * SwParaPortion::SetErgoSumNum()
1644cdf0e10cSrcweir *************************************************************************/
1645cdf0e10cSrcweir
SetErgoSumNum(const XubString & rErgo)1646cdf0e10cSrcweir void SwParaPortion::SetErgoSumNum( const XubString& rErgo )
1647cdf0e10cSrcweir {
1648cdf0e10cSrcweir SwLineLayout *pLay = this;
1649cdf0e10cSrcweir while( pLay->GetNext() )
1650cdf0e10cSrcweir {
1651cdf0e10cSrcweir DBG_LOOP;
1652cdf0e10cSrcweir pLay = pLay->GetNext();
1653cdf0e10cSrcweir }
1654cdf0e10cSrcweir SwLinePortion *pPor = pLay;
1655cdf0e10cSrcweir SwQuoVadisPortion *pQuo = 0;
1656cdf0e10cSrcweir while( pPor && !pQuo )
1657cdf0e10cSrcweir {
1658cdf0e10cSrcweir if ( pPor->IsQuoVadisPortion() )
1659cdf0e10cSrcweir pQuo = (SwQuoVadisPortion*)pPor;
1660cdf0e10cSrcweir pPor = pPor->GetPortion();
1661cdf0e10cSrcweir }
1662cdf0e10cSrcweir if( pQuo )
1663cdf0e10cSrcweir pQuo->SetNumber( rErgo );
1664cdf0e10cSrcweir }
1665cdf0e10cSrcweir
1666cdf0e10cSrcweir /*************************************************************************
1667cdf0e10cSrcweir * SwParaPortion::UpdateQuoVadis()
1668cdf0e10cSrcweir *
1669cdf0e10cSrcweir * Wird im SwTxtFrm::Prepare() gerufen
1670cdf0e10cSrcweir *************************************************************************/
1671cdf0e10cSrcweir
UpdateQuoVadis(const XubString & rQuo)1672cdf0e10cSrcweir sal_Bool SwParaPortion::UpdateQuoVadis( const XubString &rQuo )
1673cdf0e10cSrcweir {
1674cdf0e10cSrcweir SwLineLayout *pLay = this;
1675cdf0e10cSrcweir while( pLay->GetNext() )
1676cdf0e10cSrcweir {
1677cdf0e10cSrcweir DBG_LOOP;
1678cdf0e10cSrcweir pLay = pLay->GetNext();
1679cdf0e10cSrcweir }
1680cdf0e10cSrcweir SwLinePortion *pPor = pLay;
1681cdf0e10cSrcweir SwQuoVadisPortion *pQuo = 0;
1682cdf0e10cSrcweir while( pPor && !pQuo )
1683cdf0e10cSrcweir {
1684cdf0e10cSrcweir if ( pPor->IsQuoVadisPortion() )
1685cdf0e10cSrcweir pQuo = (SwQuoVadisPortion*)pPor;
1686cdf0e10cSrcweir pPor = pPor->GetPortion();
1687cdf0e10cSrcweir }
1688cdf0e10cSrcweir
1689cdf0e10cSrcweir if( !pQuo )
1690cdf0e10cSrcweir return sal_False;
1691cdf0e10cSrcweir
1692cdf0e10cSrcweir return pQuo->GetQuoTxt() == rQuo;
1693cdf0e10cSrcweir }
1694cdf0e10cSrcweir
1695cdf0e10cSrcweir
1696cdf0e10cSrcweir
1697