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
28cdf0e10cSrcweir #include "pagefrm.hxx"
29cdf0e10cSrcweir #include "rootfrm.hxx"
30cdf0e10cSrcweir #include "cntfrm.hxx"
31cdf0e10cSrcweir #include "node.hxx"
32cdf0e10cSrcweir #include "doc.hxx"
33cdf0e10cSrcweir #include "frmtool.hxx"
34cdf0e10cSrcweir #include "flyfrm.hxx"
35cdf0e10cSrcweir #include <frmfmt.hxx>
36cdf0e10cSrcweir #include <cellfrm.hxx>
37cdf0e10cSrcweir #include <rowfrm.hxx>
38cdf0e10cSrcweir #include <swtable.hxx>
39cdf0e10cSrcweir
40cdf0e10cSrcweir #include "tabfrm.hxx"
41cdf0e10cSrcweir #include "sectfrm.hxx"
42cdf0e10cSrcweir #include "flyfrms.hxx"
43cdf0e10cSrcweir #include "ftnfrm.hxx"
44cdf0e10cSrcweir #include "txtftn.hxx"
45cdf0e10cSrcweir #include "fmtftn.hxx"
46cdf0e10cSrcweir #include <txtfrm.hxx> // SwTxtFrm
47cdf0e10cSrcweir #include <switerator.hxx>
48cdf0e10cSrcweir
49cdf0e10cSrcweir /*************************************************************************
50cdf0e10cSrcweir |*
51cdf0e10cSrcweir |* FindBodyCont, FindLastBodyCntnt()
52cdf0e10cSrcweir |*
53cdf0e10cSrcweir |* Beschreibung Sucht den ersten/letzten CntntFrm im BodyText unterhalb
54cdf0e10cSrcweir |* der Seite.
55cdf0e10cSrcweir |* Ersterstellung MA 15. Feb. 93
56cdf0e10cSrcweir |* Letzte Aenderung MA 18. Apr. 94
57cdf0e10cSrcweir |*
58cdf0e10cSrcweir |*************************************************************************/
FindBodyCont()59cdf0e10cSrcweir SwLayoutFrm *SwFtnBossFrm::FindBodyCont()
60cdf0e10cSrcweir {
61cdf0e10cSrcweir SwFrm *pLay = Lower();
62cdf0e10cSrcweir while ( pLay && !pLay->IsBodyFrm() )
63cdf0e10cSrcweir pLay = pLay->GetNext();
64cdf0e10cSrcweir return (SwLayoutFrm*)pLay;
65cdf0e10cSrcweir }
66cdf0e10cSrcweir
FindLastBodyCntnt()67cdf0e10cSrcweir SwCntntFrm *SwPageFrm::FindLastBodyCntnt()
68cdf0e10cSrcweir {
69cdf0e10cSrcweir SwCntntFrm *pRet = FindFirstBodyCntnt();
70cdf0e10cSrcweir SwCntntFrm *pNxt = pRet;
71cdf0e10cSrcweir while ( pNxt && pNxt->IsInDocBody() && IsAnLower( pNxt ) )
72cdf0e10cSrcweir { pRet = pNxt;
73cdf0e10cSrcweir pNxt = pNxt->FindNextCnt();
74cdf0e10cSrcweir }
75cdf0e10cSrcweir return pRet;
76cdf0e10cSrcweir }
77cdf0e10cSrcweir
78cdf0e10cSrcweir /*************************************************************************
79cdf0e10cSrcweir |*
80cdf0e10cSrcweir |* SwLayoutFrm::ContainsCntnt
81cdf0e10cSrcweir |*
82cdf0e10cSrcweir |* Beschreibung Prueft, ob der Frame irgendwo in seiner
83cdf0e10cSrcweir |* untergeordneten Struktur einen oder mehrere CntntFrm's enthaelt;
84cdf0e10cSrcweir |* Falls ja wird der erste gefundene CntntFrm zurueckgegeben.
85cdf0e10cSrcweir |*
86cdf0e10cSrcweir |* Ersterstellung MA 13. May. 92
87cdf0e10cSrcweir |* Letzte Aenderung MA 20. Apr. 94
88cdf0e10cSrcweir |*
89cdf0e10cSrcweir |*************************************************************************/
90cdf0e10cSrcweir
ContainsCntnt() const91cdf0e10cSrcweir const SwCntntFrm *SwLayoutFrm::ContainsCntnt() const
92cdf0e10cSrcweir {
93cdf0e10cSrcweir //LayoutBlatt nach unten hin suchen und wenn dieses keinen Inhalt hat
94cdf0e10cSrcweir //solange die weiteren Blatter abklappern bis Inhalt gefunden oder der
95cdf0e10cSrcweir //this verlassen wird.
96cdf0e10cSrcweir //Sections: Cntnt neben Sections wuerde so nicht gefunden (leere Section
97cdf0e10cSrcweir //direct neben CntntFrm), deshalb muss fuer diese Aufwendiger rekursiv gesucht
98cdf0e10cSrcweir //werden.
99cdf0e10cSrcweir
100cdf0e10cSrcweir const SwLayoutFrm *pLayLeaf = this;
101cdf0e10cSrcweir do
102cdf0e10cSrcweir {
103cdf0e10cSrcweir while ( (!pLayLeaf->IsSctFrm() || pLayLeaf == this ) &&
104cdf0e10cSrcweir pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
105cdf0e10cSrcweir pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
106cdf0e10cSrcweir
107cdf0e10cSrcweir if( pLayLeaf->IsSctFrm() && pLayLeaf != this )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir const SwCntntFrm *pCnt = pLayLeaf->ContainsCntnt();
110cdf0e10cSrcweir if( pCnt )
111cdf0e10cSrcweir return pCnt;
112cdf0e10cSrcweir if( pLayLeaf->GetNext() )
113cdf0e10cSrcweir {
114cdf0e10cSrcweir if( pLayLeaf->GetNext()->IsLayoutFrm() )
115cdf0e10cSrcweir {
116cdf0e10cSrcweir pLayLeaf = (SwLayoutFrm*)pLayLeaf->GetNext();
117cdf0e10cSrcweir continue;
118cdf0e10cSrcweir }
119cdf0e10cSrcweir else
120cdf0e10cSrcweir return (SwCntntFrm*)pLayLeaf->GetNext();
121cdf0e10cSrcweir }
122cdf0e10cSrcweir }
123cdf0e10cSrcweir else if ( pLayLeaf->Lower() )
124cdf0e10cSrcweir return (SwCntntFrm*)pLayLeaf->Lower();
125cdf0e10cSrcweir
126cdf0e10cSrcweir pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
127cdf0e10cSrcweir if( !IsAnLower( pLayLeaf) )
128cdf0e10cSrcweir return 0;
129cdf0e10cSrcweir } while( pLayLeaf );
130cdf0e10cSrcweir return 0;
131cdf0e10cSrcweir }
132cdf0e10cSrcweir
133cdf0e10cSrcweir /*************************************************************************
134cdf0e10cSrcweir |*
135cdf0e10cSrcweir |* SwLayoutFrm::FirstCell
136cdf0e10cSrcweir |*
137cdf0e10cSrcweir |* Beschreibung ruft zunaechst ContainsAny auf, um in die innerste Zelle
138cdf0e10cSrcweir |* hineinzukommen. Dort hangelt es sich wieder hoch zum
139cdf0e10cSrcweir |* ersten SwCellFrm, seit es SectionFrms gibt, reicht kein
140cdf0e10cSrcweir |* ContainsCntnt()->GetUpper() mehr...
141cdf0e10cSrcweir |* Ersterstellung AMA 17. Mar. 99
142cdf0e10cSrcweir |* Letzte Aenderung AMA 17. Mar. 99
143cdf0e10cSrcweir |*
144cdf0e10cSrcweir |*************************************************************************/
145cdf0e10cSrcweir
FirstCell() const146cdf0e10cSrcweir const SwCellFrm *SwLayoutFrm::FirstCell() const
147cdf0e10cSrcweir {
148cdf0e10cSrcweir const SwFrm* pCnt = ContainsAny();
149cdf0e10cSrcweir while( pCnt && !pCnt->IsCellFrm() )
150cdf0e10cSrcweir pCnt = pCnt->GetUpper();
151cdf0e10cSrcweir return (const SwCellFrm*)pCnt;
152cdf0e10cSrcweir }
153cdf0e10cSrcweir
154cdf0e10cSrcweir /*************************************************************************
155cdf0e10cSrcweir |*
156cdf0e10cSrcweir |* SwLayoutFrm::ContainsAny
157cdf0e10cSrcweir |*
158cdf0e10cSrcweir |* Beschreibung wie ContainsCntnt, nur dass nicht nur CntntFrms, sondern auch
159cdf0e10cSrcweir |* Bereiche und Tabellen zurueckgegeben werden.
160cdf0e10cSrcweir |* Ersterstellung AMA 10. Mar. 99
161cdf0e10cSrcweir |* Letzte Aenderung AMA 10. Mar. 99
162cdf0e10cSrcweir |*
163cdf0e10cSrcweir |*************************************************************************/
164cdf0e10cSrcweir
165cdf0e10cSrcweir // --> OD 2006-02-01 #130797#
166cdf0e10cSrcweir // New parameter <_bInvestigateFtnForSections> controls investigation of
167cdf0e10cSrcweir // content of footnotes for sections.
ContainsAny(const bool _bInvestigateFtnForSections) const168cdf0e10cSrcweir const SwFrm *SwLayoutFrm::ContainsAny( const bool _bInvestigateFtnForSections ) const
169cdf0e10cSrcweir {
170cdf0e10cSrcweir //LayoutBlatt nach unten hin suchen und wenn dieses keinen Inhalt hat
171cdf0e10cSrcweir //solange die weiteren Blatter abklappern bis Inhalt gefunden oder der
172cdf0e10cSrcweir //this verlassen wird.
173cdf0e10cSrcweir // Oder bis wir einen SectionFrm oder TabFrm gefunden haben
174cdf0e10cSrcweir
175cdf0e10cSrcweir const SwLayoutFrm *pLayLeaf = this;
176cdf0e10cSrcweir // --> OD 2006-02-01 #130797#
177cdf0e10cSrcweir const bool bNoFtn = IsSctFrm() && !_bInvestigateFtnForSections;
178cdf0e10cSrcweir // <--
179cdf0e10cSrcweir do
180cdf0e10cSrcweir {
181cdf0e10cSrcweir while ( ( (!pLayLeaf->IsSctFrm() && !pLayLeaf->IsTabFrm())
182cdf0e10cSrcweir || pLayLeaf == this ) &&
183cdf0e10cSrcweir pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
184cdf0e10cSrcweir pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
185cdf0e10cSrcweir
186cdf0e10cSrcweir if( ( pLayLeaf->IsTabFrm() || pLayLeaf->IsSctFrm() )
187cdf0e10cSrcweir && pLayLeaf != this )
188cdf0e10cSrcweir {
189cdf0e10cSrcweir // Wir liefern jetzt auch "geloeschte" SectionFrms zurueck,
190cdf0e10cSrcweir // damit diese beim SaveCntnt und RestoreCntnt mitgepflegt werden.
191cdf0e10cSrcweir return pLayLeaf;
192cdf0e10cSrcweir }
193cdf0e10cSrcweir else if ( pLayLeaf->Lower() )
194cdf0e10cSrcweir return (SwCntntFrm*)pLayLeaf->Lower();
195cdf0e10cSrcweir
196cdf0e10cSrcweir pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
197cdf0e10cSrcweir if( bNoFtn && pLayLeaf && pLayLeaf->IsInFtn() )
198cdf0e10cSrcweir {
199cdf0e10cSrcweir do
200cdf0e10cSrcweir {
201cdf0e10cSrcweir pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
202cdf0e10cSrcweir } while( pLayLeaf && pLayLeaf->IsInFtn() );
203cdf0e10cSrcweir }
204cdf0e10cSrcweir if( !IsAnLower( pLayLeaf) )
205cdf0e10cSrcweir return 0;
206cdf0e10cSrcweir } while( pLayLeaf );
207cdf0e10cSrcweir return 0;
208cdf0e10cSrcweir }
209cdf0e10cSrcweir
210cdf0e10cSrcweir
211cdf0e10cSrcweir /*************************************************************************
212cdf0e10cSrcweir |*
213cdf0e10cSrcweir |* SwFrm::GetLower()
214cdf0e10cSrcweir |*
215cdf0e10cSrcweir |* Ersterstellung MA 27. Jul. 92
216cdf0e10cSrcweir |* Letzte Aenderung MA 09. Oct. 97
217cdf0e10cSrcweir |*
218cdf0e10cSrcweir |*************************************************************************/
GetLower() const219cdf0e10cSrcweir const SwFrm* SwFrm::GetLower() const
220cdf0e10cSrcweir {
221cdf0e10cSrcweir return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
222cdf0e10cSrcweir }
223cdf0e10cSrcweir
GetLower()224cdf0e10cSrcweir SwFrm* SwFrm::GetLower()
225cdf0e10cSrcweir {
226cdf0e10cSrcweir return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
227cdf0e10cSrcweir }
228cdf0e10cSrcweir
229cdf0e10cSrcweir /*************************************************************************
230cdf0e10cSrcweir |*
231cdf0e10cSrcweir |* SwLayoutFrm::IsAnLower()
232cdf0e10cSrcweir |*
233cdf0e10cSrcweir |* Ersterstellung MA 18. Mar. 93
234cdf0e10cSrcweir |* Letzte Aenderung MA 18. Mar. 93
235cdf0e10cSrcweir |*
236cdf0e10cSrcweir |*************************************************************************/
IsAnLower(const SwFrm * pAssumed) const237cdf0e10cSrcweir sal_Bool SwLayoutFrm::IsAnLower( const SwFrm *pAssumed ) const
238cdf0e10cSrcweir {
239cdf0e10cSrcweir const SwFrm *pUp = pAssumed;
240cdf0e10cSrcweir while ( pUp )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir if ( pUp == this )
243cdf0e10cSrcweir return sal_True;
244cdf0e10cSrcweir if ( pUp->IsFlyFrm() )
245cdf0e10cSrcweir pUp = ((SwFlyFrm*)pUp)->GetAnchorFrm();
246cdf0e10cSrcweir else
247cdf0e10cSrcweir pUp = pUp->GetUpper();
248cdf0e10cSrcweir }
249cdf0e10cSrcweir return sal_False;
250cdf0e10cSrcweir }
251cdf0e10cSrcweir
252cdf0e10cSrcweir /** method to check relative position of layout frame to
253cdf0e10cSrcweir a given layout frame.
254cdf0e10cSrcweir
255cdf0e10cSrcweir OD 08.11.2002 - refactoring of pseudo-local method <lcl_Apres(..)> in
256cdf0e10cSrcweir <txtftn.cxx> for #104840#.
257cdf0e10cSrcweir
258cdf0e10cSrcweir @param _aCheckRefLayFrm
259cdf0e10cSrcweir constant reference of an instance of class <SwLayoutFrm> which
260cdf0e10cSrcweir is used as the reference for the relative position check.
261cdf0e10cSrcweir
262cdf0e10cSrcweir @author OD
263cdf0e10cSrcweir
264cdf0e10cSrcweir @return true, if <this> is positioned before the layout frame <p>
265cdf0e10cSrcweir */
IsBefore(const SwLayoutFrm * _pCheckRefLayFrm) const266cdf0e10cSrcweir bool SwLayoutFrm::IsBefore( const SwLayoutFrm* _pCheckRefLayFrm ) const
267cdf0e10cSrcweir {
268cdf0e10cSrcweir ASSERT( !IsRootFrm() , "<IsBefore> called at a <SwRootFrm>.");
269cdf0e10cSrcweir ASSERT( !_pCheckRefLayFrm->IsRootFrm() , "<IsBefore> called with a <SwRootFrm>.");
270cdf0e10cSrcweir
271cdf0e10cSrcweir bool bReturn;
272cdf0e10cSrcweir
273cdf0e10cSrcweir // check, if on different pages
274cdf0e10cSrcweir const SwPageFrm *pMyPage = FindPageFrm();
275cdf0e10cSrcweir const SwPageFrm *pCheckRefPage = _pCheckRefLayFrm->FindPageFrm();
276cdf0e10cSrcweir if( pMyPage != pCheckRefPage )
277cdf0e10cSrcweir {
278cdf0e10cSrcweir // being on different page as check reference
279cdf0e10cSrcweir bReturn = pMyPage->GetPhyPageNum() < pCheckRefPage->GetPhyPageNum();
280cdf0e10cSrcweir }
281cdf0e10cSrcweir else
282cdf0e10cSrcweir {
283cdf0e10cSrcweir // being on same page as check reference
284cdf0e10cSrcweir // --> search my supreme parent <pUp>, which doesn't contain check reference.
285cdf0e10cSrcweir const SwLayoutFrm* pUp = this;
286cdf0e10cSrcweir while ( pUp->GetUpper() &&
287cdf0e10cSrcweir !pUp->GetUpper()->IsAnLower( _pCheckRefLayFrm )
288cdf0e10cSrcweir )
289cdf0e10cSrcweir pUp = pUp->GetUpper();
290cdf0e10cSrcweir if( !pUp->GetUpper() )
291cdf0e10cSrcweir {
292cdf0e10cSrcweir // can occur, if <this> is a fly frm
293cdf0e10cSrcweir bReturn = false;
294cdf0e10cSrcweir }
295cdf0e10cSrcweir else
296cdf0e10cSrcweir {
297cdf0e10cSrcweir // travel through the next's of <pUp> and check if one of these
298cdf0e10cSrcweir // contain the check reference.
299cdf0e10cSrcweir SwLayoutFrm* pUpNext = (SwLayoutFrm*)pUp->GetNext();
300cdf0e10cSrcweir while ( pUpNext &&
301cdf0e10cSrcweir !pUpNext->IsAnLower( _pCheckRefLayFrm ) )
302cdf0e10cSrcweir {
303cdf0e10cSrcweir pUpNext = (SwLayoutFrm*)pUpNext->GetNext();
304cdf0e10cSrcweir }
305cdf0e10cSrcweir bReturn = pUpNext != 0;
306cdf0e10cSrcweir }
307cdf0e10cSrcweir }
308cdf0e10cSrcweir
309cdf0e10cSrcweir return bReturn;
310cdf0e10cSrcweir }
311cdf0e10cSrcweir
312cdf0e10cSrcweir //
313cdf0e10cSrcweir // Local helper functions for GetNextLayoutLeaf
314cdf0e10cSrcweir //
315cdf0e10cSrcweir
lcl_FindLayoutFrame(const SwFrm * pFrm,bool bNext)316cdf0e10cSrcweir const SwFrm* lcl_FindLayoutFrame( const SwFrm* pFrm, bool bNext )
317cdf0e10cSrcweir {
318cdf0e10cSrcweir const SwFrm* pRet = 0;
319cdf0e10cSrcweir if ( pFrm->IsFlyFrm() )
320cdf0e10cSrcweir pRet = bNext ? ((SwFlyFrm*)pFrm)->GetNextLink() : ((SwFlyFrm*)pFrm)->GetPrevLink();
321cdf0e10cSrcweir else
322cdf0e10cSrcweir pRet = bNext ? pFrm->GetNext() : pFrm->GetPrev();
323cdf0e10cSrcweir
324cdf0e10cSrcweir return pRet;
325cdf0e10cSrcweir }
326cdf0e10cSrcweir
lcl_GetLower(const SwFrm * pFrm,bool bFwd)327cdf0e10cSrcweir const SwFrm* lcl_GetLower( const SwFrm* pFrm, bool bFwd )
328cdf0e10cSrcweir {
329cdf0e10cSrcweir if ( !pFrm->IsLayoutFrm() )
330cdf0e10cSrcweir return 0;
331cdf0e10cSrcweir
332cdf0e10cSrcweir return bFwd ?
333cdf0e10cSrcweir static_cast<const SwLayoutFrm*>(pFrm)->Lower() :
334cdf0e10cSrcweir static_cast<const SwLayoutFrm*>(pFrm)->GetLastLower();
335cdf0e10cSrcweir }
336cdf0e10cSrcweir
337cdf0e10cSrcweir /*************************************************************************
338cdf0e10cSrcweir |*
339cdf0e10cSrcweir |* SwFrm::ImplGetNextLayoutLeaf
340cdf0e10cSrcweir |*
341cdf0e10cSrcweir |* Finds the next layout leaf. This is a layout frame, which does not
342cdf0e10cSrcweir * have a lower which is a LayoutFrame. That means, pLower can be 0 or a
343cdf0e10cSrcweir * content frame.
344cdf0e10cSrcweir *
345cdf0e10cSrcweir * However, pLower may be a TabFrm
346cdf0e10cSrcweir *
347cdf0e10cSrcweir |*************************************************************************/
348cdf0e10cSrcweir
ImplGetNextLayoutLeaf(bool bFwd) const349cdf0e10cSrcweir const SwLayoutFrm *SwFrm::ImplGetNextLayoutLeaf( bool bFwd ) const
350cdf0e10cSrcweir {
351cdf0e10cSrcweir const SwFrm *pFrm = this;
352cdf0e10cSrcweir const SwLayoutFrm *pLayoutFrm = 0;
353cdf0e10cSrcweir const SwFrm *p = 0;
354cdf0e10cSrcweir bool bGoingUp = !bFwd; // false for forward, true for backward
355cdf0e10cSrcweir do {
356cdf0e10cSrcweir
357cdf0e10cSrcweir bool bGoingFwdOrBwd = false, bGoingDown = false;
358cdf0e10cSrcweir
359cdf0e10cSrcweir bGoingDown = ( !bGoingUp && ( 0 != (p = lcl_GetLower( pFrm, bFwd ) ) ) );
360cdf0e10cSrcweir if ( !bGoingDown )
361cdf0e10cSrcweir {
362cdf0e10cSrcweir // I cannot go down, because either I'm currently going up or
363cdf0e10cSrcweir // because the is no lower.
364cdf0e10cSrcweir // I'll try to go forward:
365cdf0e10cSrcweir bGoingFwdOrBwd = (0 != (p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
366cdf0e10cSrcweir if ( !bGoingFwdOrBwd )
367cdf0e10cSrcweir {
368cdf0e10cSrcweir // I cannot go forward, because there is no next frame.
369cdf0e10cSrcweir // I'll try to go up:
370cdf0e10cSrcweir bGoingUp = (0 != (p = pFrm->GetUpper() ) );
371cdf0e10cSrcweir if ( !bGoingUp )
372cdf0e10cSrcweir {
373cdf0e10cSrcweir // I cannot go up, because there is no upper frame.
374cdf0e10cSrcweir return 0;
375cdf0e10cSrcweir }
376cdf0e10cSrcweir }
377cdf0e10cSrcweir }
378cdf0e10cSrcweir
379cdf0e10cSrcweir // If I could not go down or forward, I'll have to go up
380cdf0e10cSrcweir bGoingUp = !bGoingFwdOrBwd && !bGoingDown;
381cdf0e10cSrcweir
382cdf0e10cSrcweir pFrm = p;
383cdf0e10cSrcweir p = lcl_GetLower( pFrm, true );
384cdf0e10cSrcweir
385cdf0e10cSrcweir } while( ( p && !p->IsFlowFrm() ) ||
386cdf0e10cSrcweir pFrm == this ||
387cdf0e10cSrcweir 0 == ( pLayoutFrm = pFrm->IsLayoutFrm() ? (SwLayoutFrm*)pFrm : 0 ) ||
388cdf0e10cSrcweir pLayoutFrm->IsAnLower( this ) );
389cdf0e10cSrcweir
390cdf0e10cSrcweir return pLayoutFrm;
391cdf0e10cSrcweir }
392cdf0e10cSrcweir
393cdf0e10cSrcweir
394cdf0e10cSrcweir
395cdf0e10cSrcweir /*************************************************************************
396cdf0e10cSrcweir |*
397cdf0e10cSrcweir |* SwFrm::ImplGetNextCntntFrm( bool )
398cdf0e10cSrcweir |*
399cdf0e10cSrcweir |* Rueckwaertswandern im Baum: Den untergeordneten Frm greifen,
400cdf0e10cSrcweir |* wenn es einen gibt und nicht gerade zuvor um eine Ebene
401cdf0e10cSrcweir |* aufgestiegen wurde (das wuerde zu einem endlosen Auf und Ab
402cdf0e10cSrcweir |* fuehren!). Damit wird sichergestellt, dass beim
403cdf0e10cSrcweir |* Rueckwaertswandern alle Unterbaeume durchsucht werden. Wenn
404cdf0e10cSrcweir |* abgestiegen wurde, wird zuerst an das Ende der Kette gegangen,
405cdf0e10cSrcweir |* weil im weiteren ja vom letzten Frm innerhalb eines anderen
406cdf0e10cSrcweir |* Frms rueckwaerts gegangen wird.
407cdf0e10cSrcweir |* Vorwaetzwander funktioniert analog.
408cdf0e10cSrcweir |*
409cdf0e10cSrcweir |* Ersterstellung ??
410cdf0e10cSrcweir |* Letzte Aenderung MA 30. Oct. 97
411cdf0e10cSrcweir |*
412cdf0e10cSrcweir |*************************************************************************/
413cdf0e10cSrcweir
414cdf0e10cSrcweir // Achtung: Fixes in ImplGetNextCntntFrm() muessen moeglicherweise auch in
415cdf0e10cSrcweir // die weiter oben stehende Methode lcl_NextFrm(..) eingepflegt werden
ImplGetNextCntntFrm(bool bFwd) const416cdf0e10cSrcweir const SwCntntFrm* SwCntntFrm::ImplGetNextCntntFrm( bool bFwd ) const
417cdf0e10cSrcweir {
418cdf0e10cSrcweir const SwFrm *pFrm = this;
419cdf0e10cSrcweir // #100926#
420cdf0e10cSrcweir SwCntntFrm *pCntntFrm = 0;
421cdf0e10cSrcweir sal_Bool bGoingUp = sal_False;
422cdf0e10cSrcweir do {
423cdf0e10cSrcweir const SwFrm *p = 0;
424cdf0e10cSrcweir sal_Bool bGoingFwdOrBwd = sal_False, bGoingDown = sal_False;
425cdf0e10cSrcweir
426cdf0e10cSrcweir bGoingDown = ( !bGoingUp && ( 0 != ( p = lcl_GetLower( pFrm, true ) ) ) );
427cdf0e10cSrcweir if ( !bGoingDown )
428cdf0e10cSrcweir {
429cdf0e10cSrcweir bGoingFwdOrBwd = ( 0 != ( p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
430cdf0e10cSrcweir if ( !bGoingFwdOrBwd )
431cdf0e10cSrcweir {
432cdf0e10cSrcweir bGoingUp = ( 0 != ( p = pFrm->GetUpper() ) );
433cdf0e10cSrcweir if ( !bGoingUp )
434cdf0e10cSrcweir {
435cdf0e10cSrcweir return 0;
436cdf0e10cSrcweir }
437cdf0e10cSrcweir }
438cdf0e10cSrcweir }
439cdf0e10cSrcweir
440cdf0e10cSrcweir bGoingUp = !(bGoingFwdOrBwd || bGoingDown);
441cdf0e10cSrcweir
442cdf0e10cSrcweir if ( !bFwd )
443cdf0e10cSrcweir {
444cdf0e10cSrcweir if( bGoingDown && p )
445cdf0e10cSrcweir while ( p->GetNext() )
446cdf0e10cSrcweir p = p->GetNext();
447cdf0e10cSrcweir }
448cdf0e10cSrcweir
449cdf0e10cSrcweir pFrm = p;
450cdf0e10cSrcweir } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
451cdf0e10cSrcweir
452cdf0e10cSrcweir return pCntntFrm;
453cdf0e10cSrcweir }
454cdf0e10cSrcweir
455cdf0e10cSrcweir
456cdf0e10cSrcweir
457cdf0e10cSrcweir
458cdf0e10cSrcweir /*************************************************************************
459cdf0e10cSrcweir |*
460cdf0e10cSrcweir |* SwFrm::FindRootFrm(), FindTabFrm(), FindFtnFrm(), FindFlyFrm(),
461cdf0e10cSrcweir |* FindPageFrm(), FindColFrm()
462cdf0e10cSrcweir |*
463cdf0e10cSrcweir |* Ersterstellung ??
464cdf0e10cSrcweir |* Letzte Aenderung MA 05. Sep. 93
465cdf0e10cSrcweir |*
466cdf0e10cSrcweir |*************************************************************************/
FindPageFrm()467cdf0e10cSrcweir SwPageFrm* SwFrm::FindPageFrm()
468cdf0e10cSrcweir {
469cdf0e10cSrcweir SwFrm *pRet = this;
470cdf0e10cSrcweir while ( pRet && !pRet->IsPageFrm() )
471cdf0e10cSrcweir {
472cdf0e10cSrcweir if ( pRet->GetUpper() )
473cdf0e10cSrcweir pRet = pRet->GetUpper();
474cdf0e10cSrcweir else if ( pRet->IsFlyFrm() )
475cdf0e10cSrcweir {
476cdf0e10cSrcweir // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
477cdf0e10cSrcweir if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
478cdf0e10cSrcweir pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
479cdf0e10cSrcweir else
480cdf0e10cSrcweir pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
481cdf0e10cSrcweir }
482cdf0e10cSrcweir else
483cdf0e10cSrcweir return 0;
484cdf0e10cSrcweir }
485cdf0e10cSrcweir return (SwPageFrm*)pRet;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir
FindFtnBossFrm(sal_Bool bFootnotes)488cdf0e10cSrcweir SwFtnBossFrm* SwFrm::FindFtnBossFrm( sal_Bool bFootnotes )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir SwFrm *pRet = this;
491cdf0e10cSrcweir // Innerhalb einer Tabelle gibt es keine Fussnotenbosse, auch spaltige
492cdf0e10cSrcweir // Bereiche enthalten dort keine Fussnotentexte
493cdf0e10cSrcweir if( pRet->IsInTab() )
494cdf0e10cSrcweir pRet = pRet->FindTabFrm();
495cdf0e10cSrcweir while ( pRet && !pRet->IsFtnBossFrm() )
496cdf0e10cSrcweir {
497cdf0e10cSrcweir if ( pRet->GetUpper() )
498cdf0e10cSrcweir pRet = pRet->GetUpper();
499cdf0e10cSrcweir else if ( pRet->IsFlyFrm() )
500cdf0e10cSrcweir {
501cdf0e10cSrcweir // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
502cdf0e10cSrcweir if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
503cdf0e10cSrcweir pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
504cdf0e10cSrcweir else
505cdf0e10cSrcweir pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
506cdf0e10cSrcweir }
507cdf0e10cSrcweir else
508cdf0e10cSrcweir return 0;
509cdf0e10cSrcweir }
510cdf0e10cSrcweir if( bFootnotes && pRet && pRet->IsColumnFrm() &&
511cdf0e10cSrcweir !pRet->GetNext() && !pRet->GetPrev() )
512cdf0e10cSrcweir {
513cdf0e10cSrcweir SwSectionFrm* pSct = pRet->FindSctFrm();
514cdf0e10cSrcweir ASSERT( pSct, "FindFtnBossFrm: Single column outside section?" );
515cdf0e10cSrcweir if( !pSct->IsFtnAtEnd() )
516cdf0e10cSrcweir return pSct->FindFtnBossFrm( sal_True );
517cdf0e10cSrcweir }
518cdf0e10cSrcweir return (SwFtnBossFrm*)pRet;
519cdf0e10cSrcweir }
520cdf0e10cSrcweir
ImplFindTabFrm()521cdf0e10cSrcweir SwTabFrm* SwFrm::ImplFindTabFrm()
522cdf0e10cSrcweir {
523cdf0e10cSrcweir SwFrm *pRet = this;
524cdf0e10cSrcweir while ( !pRet->IsTabFrm() )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir pRet = pRet->GetUpper();
527cdf0e10cSrcweir if ( !pRet )
528cdf0e10cSrcweir return 0;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir return (SwTabFrm*)pRet;
531cdf0e10cSrcweir }
532cdf0e10cSrcweir
ImplFindSctFrm()533cdf0e10cSrcweir SwSectionFrm* SwFrm::ImplFindSctFrm()
534cdf0e10cSrcweir {
535cdf0e10cSrcweir SwFrm *pRet = this;
536cdf0e10cSrcweir while ( !pRet->IsSctFrm() )
537cdf0e10cSrcweir {
538cdf0e10cSrcweir pRet = pRet->GetUpper();
539cdf0e10cSrcweir if ( !pRet )
540cdf0e10cSrcweir return 0;
541cdf0e10cSrcweir }
542cdf0e10cSrcweir return (SwSectionFrm*)pRet;
543cdf0e10cSrcweir }
544cdf0e10cSrcweir
ImplFindFtnFrm()545cdf0e10cSrcweir SwFtnFrm *SwFrm::ImplFindFtnFrm()
546cdf0e10cSrcweir {
547cdf0e10cSrcweir SwFrm *pRet = this;
548cdf0e10cSrcweir while ( !pRet->IsFtnFrm() )
549cdf0e10cSrcweir {
550cdf0e10cSrcweir pRet = pRet->GetUpper();
551cdf0e10cSrcweir if ( !pRet )
552cdf0e10cSrcweir return 0;
553cdf0e10cSrcweir }
554cdf0e10cSrcweir return (SwFtnFrm*)pRet;
555cdf0e10cSrcweir }
556cdf0e10cSrcweir
ImplFindFlyFrm()557cdf0e10cSrcweir SwFlyFrm *SwFrm::ImplFindFlyFrm()
558cdf0e10cSrcweir {
559cdf0e10cSrcweir const SwFrm *pRet = this;
560cdf0e10cSrcweir do
561cdf0e10cSrcweir {
562cdf0e10cSrcweir if ( pRet->IsFlyFrm() )
563cdf0e10cSrcweir return (SwFlyFrm*)pRet;
564cdf0e10cSrcweir else
565cdf0e10cSrcweir pRet = pRet->GetUpper();
566cdf0e10cSrcweir } while ( pRet );
567cdf0e10cSrcweir return 0;
568cdf0e10cSrcweir }
569cdf0e10cSrcweir
FindColFrm()570cdf0e10cSrcweir SwFrm *SwFrm::FindColFrm()
571cdf0e10cSrcweir {
572cdf0e10cSrcweir SwFrm *pFrm = this;
573cdf0e10cSrcweir do
574cdf0e10cSrcweir { pFrm = pFrm->GetUpper();
575cdf0e10cSrcweir } while ( pFrm && !pFrm->IsColumnFrm() );
576cdf0e10cSrcweir return pFrm;
577cdf0e10cSrcweir }
578cdf0e10cSrcweir
FindFooterOrHeader()579cdf0e10cSrcweir SwFrm* SwFrm::FindFooterOrHeader()
580cdf0e10cSrcweir {
581cdf0e10cSrcweir SwFrm* pRet = this;
582cdf0e10cSrcweir do
583cdf0e10cSrcweir { if ( pRet->GetType() & 0x0018 ) //Header und Footer
584cdf0e10cSrcweir return pRet;
585cdf0e10cSrcweir else if ( pRet->GetUpper() )
586cdf0e10cSrcweir pRet = pRet->GetUpper();
587cdf0e10cSrcweir else if ( pRet->IsFlyFrm() )
588cdf0e10cSrcweir pRet = ((SwFlyFrm*)pRet)->AnchorFrm();
589cdf0e10cSrcweir else
590cdf0e10cSrcweir return 0;
591cdf0e10cSrcweir } while ( pRet );
592cdf0e10cSrcweir return pRet;
593cdf0e10cSrcweir }
594cdf0e10cSrcweir
FindFootNote() const595cdf0e10cSrcweir const SwFtnFrm* SwFtnContFrm::FindFootNote() const
596cdf0e10cSrcweir {
597cdf0e10cSrcweir const SwFtnFrm* pRet = (SwFtnFrm*)Lower();
598cdf0e10cSrcweir if( pRet && !pRet->GetAttr()->GetFtn().IsEndNote() )
599cdf0e10cSrcweir return pRet;
600cdf0e10cSrcweir return NULL;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir
GetPageAtPos(const Point & rPt,const Size * pSize,bool bExtend) const603cdf0e10cSrcweir const SwPageFrm* SwRootFrm::GetPageAtPos( const Point& rPt, const Size* pSize, bool bExtend ) const
604cdf0e10cSrcweir {
605cdf0e10cSrcweir const SwPageFrm* pRet = 0;
606cdf0e10cSrcweir
607cdf0e10cSrcweir SwRect aRect;
608cdf0e10cSrcweir if ( pSize )
609cdf0e10cSrcweir {
610cdf0e10cSrcweir aRect.Pos() = rPt;
611cdf0e10cSrcweir aRect.SSize() = *pSize;
612cdf0e10cSrcweir }
613cdf0e10cSrcweir
614cdf0e10cSrcweir const SwFrm* pPage = Lower();
615cdf0e10cSrcweir
616cdf0e10cSrcweir if ( !bExtend )
617cdf0e10cSrcweir {
618cdf0e10cSrcweir if( !Frm().IsInside( rPt ) )
619cdf0e10cSrcweir return 0;
620cdf0e10cSrcweir
621cdf0e10cSrcweir // skip pages above point:
622cdf0e10cSrcweir while( pPage && rPt.Y() > pPage->Frm().Bottom() )
623cdf0e10cSrcweir pPage = pPage->GetNext();
624cdf0e10cSrcweir }
625cdf0e10cSrcweir
626cdf0e10cSrcweir ASSERT( GetPageNum() <= maPageRects.size(), "number of pages differes from page rect array size" )
627cdf0e10cSrcweir sal_uInt16 nPageIdx = 0;
628cdf0e10cSrcweir
629cdf0e10cSrcweir while ( pPage && !pRet )
630cdf0e10cSrcweir {
631cdf0e10cSrcweir const SwRect& rBoundRect = bExtend ? maPageRects[ nPageIdx++ ] : pPage->Frm();
632cdf0e10cSrcweir
633cdf0e10cSrcweir if ( (!pSize && rBoundRect.IsInside(rPt)) ||
634cdf0e10cSrcweir (pSize && rBoundRect.IsOver(aRect)) )
635cdf0e10cSrcweir {
636cdf0e10cSrcweir pRet = static_cast<const SwPageFrm*>(pPage);
637cdf0e10cSrcweir }
638cdf0e10cSrcweir
639cdf0e10cSrcweir pPage = pPage->GetNext();
640cdf0e10cSrcweir }
641cdf0e10cSrcweir
642cdf0e10cSrcweir return pRet;
643cdf0e10cSrcweir }
644cdf0e10cSrcweir
645cdf0e10cSrcweir /*************************************************************************
646cdf0e10cSrcweir |*
647cdf0e10cSrcweir |* SwFrmFrm::GetAttrSet()
648cdf0e10cSrcweir |*
649cdf0e10cSrcweir |* Ersterstellung MA 02. Aug. 93
650cdf0e10cSrcweir |* Letzte Aenderung MA 02. Aug. 93
651cdf0e10cSrcweir |*
652cdf0e10cSrcweir |*************************************************************************/
GetAttrSet() const653cdf0e10cSrcweir const SwAttrSet* SwFrm::GetAttrSet() const
654cdf0e10cSrcweir {
655cdf0e10cSrcweir if ( IsCntntFrm() )
656cdf0e10cSrcweir return &((const SwCntntFrm*)this)->GetNode()->GetSwAttrSet();
657cdf0e10cSrcweir else
658cdf0e10cSrcweir return &((const SwLayoutFrm*)this)->GetFmt()->GetAttrSet();
659cdf0e10cSrcweir }
660cdf0e10cSrcweir
661cdf0e10cSrcweir /*************************************************************************
662cdf0e10cSrcweir |*
663cdf0e10cSrcweir |* SwFrm::_FindNext(), _FindPrev(), InvalidateNextPos()
664cdf0e10cSrcweir |* _FindNextCnt() geht in Tabellen und Bereiche hineinund liefert
665cdf0e10cSrcweir |* nur SwCntntFrms.
666cdf0e10cSrcweir |*
667cdf0e10cSrcweir |* Beschreibung Invalidiert die Position des Naechsten Frames.
668cdf0e10cSrcweir |* Dies ist der direkte Nachfolger, oder bei CntntFrm's der naechste
669cdf0e10cSrcweir |* CntntFrm der im gleichen Fluss liegt wie ich:
670cdf0e10cSrcweir |* - Body,
671cdf0e10cSrcweir |* - Fussnoten,
672cdf0e10cSrcweir |* - Bei Kopf-/Fussbereichen ist die Benachrichtigung nur innerhalb des
673cdf0e10cSrcweir |* Bereiches weiterzuleiten.
674cdf0e10cSrcweir |* - dito fuer Flys.
675cdf0e10cSrcweir |* - Cntnts in Tabs halten sich ausschliesslich innerhalb ihrer Zelle
676cdf0e10cSrcweir |* auf.
677cdf0e10cSrcweir |* - Tabellen verhalten sich prinzipiell analog zu den Cntnts
678cdf0e10cSrcweir |* - Bereiche ebenfalls
679cdf0e10cSrcweir |* Ersterstellung AK 14-Feb-1991
680cdf0e10cSrcweir |* Letzte Aenderung AMA 10. Mar. 99
681cdf0e10cSrcweir |*
682cdf0e10cSrcweir |*************************************************************************/
683cdf0e10cSrcweir
684cdf0e10cSrcweir // Diese Hilfsfunktion ist ein Aequivalent zur ImplGetNextCntntFrm()-Methode,
685cdf0e10cSrcweir // sie liefert allerdings neben ContentFrames auch TabFrms und SectionFrms.
lcl_NextFrm(SwFrm * pFrm)686cdf0e10cSrcweir SwFrm* lcl_NextFrm( SwFrm* pFrm )
687cdf0e10cSrcweir {
688cdf0e10cSrcweir SwFrm *pRet = 0;
689cdf0e10cSrcweir sal_Bool bGoingUp = sal_False;
690cdf0e10cSrcweir do {
691cdf0e10cSrcweir SwFrm *p = 0;
692cdf0e10cSrcweir
693cdf0e10cSrcweir sal_Bool bGoingFwd = sal_False;
694cdf0e10cSrcweir sal_Bool bGoingDown = (!bGoingUp && ( 0 != (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)));
695cdf0e10cSrcweir
696cdf0e10cSrcweir if( !bGoingDown )
697cdf0e10cSrcweir {
698cdf0e10cSrcweir bGoingFwd = (0 != (p = ( pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink() : pFrm->GetNext())));
699cdf0e10cSrcweir if ( !bGoingFwd )
700cdf0e10cSrcweir {
701cdf0e10cSrcweir bGoingUp = (0 != (p = pFrm->GetUpper()));
702cdf0e10cSrcweir if ( !bGoingUp )
703cdf0e10cSrcweir {
704cdf0e10cSrcweir return 0;
705cdf0e10cSrcweir }
706cdf0e10cSrcweir }
707cdf0e10cSrcweir }
708cdf0e10cSrcweir bGoingUp = !(bGoingFwd || bGoingDown);
709cdf0e10cSrcweir pFrm = p;
710cdf0e10cSrcweir } while ( 0 == (pRet = ( ( pFrm->IsCntntFrm() || ( !bGoingUp &&
711cdf0e10cSrcweir ( pFrm->IsTabFrm() || pFrm->IsSctFrm() ) ) )? pFrm : 0 ) ) );
712cdf0e10cSrcweir return pRet;
713cdf0e10cSrcweir }
714cdf0e10cSrcweir
_FindNext()715cdf0e10cSrcweir SwFrm *SwFrm::_FindNext()
716cdf0e10cSrcweir {
717cdf0e10cSrcweir sal_Bool bIgnoreTab = sal_False;
718cdf0e10cSrcweir SwFrm *pThis = this;
719cdf0e10cSrcweir
720cdf0e10cSrcweir if ( IsTabFrm() )
721cdf0e10cSrcweir {
722cdf0e10cSrcweir //Der letzte Cntnt der Tabelle wird
723cdf0e10cSrcweir //gegriffen und dessen Nachfolger geliefert. Um die Spezialbeh.
724cdf0e10cSrcweir //Fuer Tabellen (s.u.) auszuschalten wird bIgnoreTab gesetzt.
725cdf0e10cSrcweir if ( ((SwTabFrm*)this)->GetFollow() )
726cdf0e10cSrcweir return ((SwTabFrm*)this)->GetFollow();
727cdf0e10cSrcweir
728cdf0e10cSrcweir pThis = ((SwTabFrm*)this)->FindLastCntnt();
729cdf0e10cSrcweir if ( !pThis )
730cdf0e10cSrcweir pThis = this;
731cdf0e10cSrcweir bIgnoreTab = sal_True;
732cdf0e10cSrcweir }
733cdf0e10cSrcweir else if ( IsSctFrm() )
734cdf0e10cSrcweir {
735cdf0e10cSrcweir //Der letzte Cntnt des Bereichs wird gegriffen und dessen Nachfolger
736cdf0e10cSrcweir // geliefert.
737cdf0e10cSrcweir if ( ((SwSectionFrm*)this)->GetFollow() )
738cdf0e10cSrcweir return ((SwSectionFrm*)this)->GetFollow();
739cdf0e10cSrcweir
740cdf0e10cSrcweir pThis = ((SwSectionFrm*)this)->FindLastCntnt();
741cdf0e10cSrcweir if ( !pThis )
742cdf0e10cSrcweir pThis = this;
743cdf0e10cSrcweir }
744cdf0e10cSrcweir else if ( IsCntntFrm() )
745cdf0e10cSrcweir {
746cdf0e10cSrcweir if( ((SwCntntFrm*)this)->GetFollow() )
747cdf0e10cSrcweir return ((SwCntntFrm*)this)->GetFollow();
748cdf0e10cSrcweir }
749cdf0e10cSrcweir else if ( IsRowFrm() )
750cdf0e10cSrcweir {
751cdf0e10cSrcweir SwFrm* pMyUpper = GetUpper();
752cdf0e10cSrcweir if ( pMyUpper->IsTabFrm() && ((SwTabFrm*)pMyUpper)->GetFollow() )
753cdf0e10cSrcweir return ((SwTabFrm*)pMyUpper)->GetFollow()->GetLower();
754cdf0e10cSrcweir else return NULL;
755cdf0e10cSrcweir }
756cdf0e10cSrcweir else
757cdf0e10cSrcweir return NULL;
758cdf0e10cSrcweir
759cdf0e10cSrcweir SwFrm* pRet = NULL;
760cdf0e10cSrcweir const sal_Bool bFtn = pThis->IsInFtn();
761cdf0e10cSrcweir if ( !bIgnoreTab && pThis->IsInTab() )
762cdf0e10cSrcweir {
763cdf0e10cSrcweir SwLayoutFrm *pUp = pThis->GetUpper();
764cdf0e10cSrcweir while ( !pUp->IsCellFrm() )
765cdf0e10cSrcweir pUp = pUp->GetUpper();
766cdf0e10cSrcweir ASSERT( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
767cdf0e10cSrcweir SwFrm* pNxt = ((SwCellFrm*)pUp)->GetFollowCell();
768cdf0e10cSrcweir if ( pNxt )
769cdf0e10cSrcweir pNxt = ((SwCellFrm*)pNxt)->ContainsCntnt();
770cdf0e10cSrcweir if ( !pNxt )
771cdf0e10cSrcweir {
772cdf0e10cSrcweir pNxt = lcl_NextFrm( pThis );
773cdf0e10cSrcweir if ( pUp->IsAnLower( pNxt ) )
774cdf0e10cSrcweir pRet = pNxt;
775cdf0e10cSrcweir }
776cdf0e10cSrcweir else
777cdf0e10cSrcweir pRet = pNxt;
778cdf0e10cSrcweir }
779cdf0e10cSrcweir else
780cdf0e10cSrcweir {
781cdf0e10cSrcweir const sal_Bool bBody = pThis->IsInDocBody();
782cdf0e10cSrcweir SwFrm *pNxtCnt = lcl_NextFrm( pThis );
783cdf0e10cSrcweir if ( pNxtCnt )
784cdf0e10cSrcweir {
785cdf0e10cSrcweir if ( bBody || bFtn )
786cdf0e10cSrcweir {
787cdf0e10cSrcweir while ( pNxtCnt )
788cdf0e10cSrcweir {
789cdf0e10cSrcweir // OD 02.04.2003 #108446# - check for endnote, only if found
790cdf0e10cSrcweir // next content isn't contained in a section, that collect its
791cdf0e10cSrcweir // endnotes at its end.
792cdf0e10cSrcweir bool bEndn = IsInSct() && !IsSctFrm() &&
793cdf0e10cSrcweir ( !pNxtCnt->IsInSct() ||
794cdf0e10cSrcweir !pNxtCnt->FindSctFrm()->IsEndnAtEnd()
795cdf0e10cSrcweir );
796cdf0e10cSrcweir if ( ( bBody && pNxtCnt->IsInDocBody() ) ||
797cdf0e10cSrcweir ( pNxtCnt->IsInFtn() &&
798cdf0e10cSrcweir ( bFtn ||
799cdf0e10cSrcweir ( bEndn && pNxtCnt->FindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
800cdf0e10cSrcweir )
801cdf0e10cSrcweir )
802cdf0e10cSrcweir )
803cdf0e10cSrcweir {
804cdf0e10cSrcweir pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
805cdf0e10cSrcweir : (SwFrm*)pNxtCnt;
806cdf0e10cSrcweir break;
807cdf0e10cSrcweir }
808cdf0e10cSrcweir pNxtCnt = lcl_NextFrm( pNxtCnt );
809cdf0e10cSrcweir }
810cdf0e10cSrcweir }
811cdf0e10cSrcweir else if ( pThis->IsInFly() )
812cdf0e10cSrcweir {
813cdf0e10cSrcweir pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
814cdf0e10cSrcweir : (SwFrm*)pNxtCnt;
815cdf0e10cSrcweir }
816cdf0e10cSrcweir else //Fuss-/oder Kopfbereich
817cdf0e10cSrcweir {
818cdf0e10cSrcweir const SwFrm *pUp = pThis->GetUpper();
819cdf0e10cSrcweir const SwFrm *pCntUp = pNxtCnt->GetUpper();
820cdf0e10cSrcweir while ( pUp && pUp->GetUpper() &&
821cdf0e10cSrcweir !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
822cdf0e10cSrcweir pUp = pUp->GetUpper();
823cdf0e10cSrcweir while ( pCntUp && pCntUp->GetUpper() &&
824cdf0e10cSrcweir !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
825cdf0e10cSrcweir pCntUp = pCntUp->GetUpper();
826cdf0e10cSrcweir if ( pCntUp == pUp )
827cdf0e10cSrcweir {
828cdf0e10cSrcweir pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
829cdf0e10cSrcweir : (SwFrm*)pNxtCnt;
830cdf0e10cSrcweir }
831cdf0e10cSrcweir }
832cdf0e10cSrcweir }
833cdf0e10cSrcweir }
834cdf0e10cSrcweir if( pRet && pRet->IsInSct() )
835cdf0e10cSrcweir {
836cdf0e10cSrcweir SwSectionFrm* pSct = pRet->FindSctFrm();
837cdf0e10cSrcweir //Fussnoten in spaltigen Rahmen duerfen nicht den Bereich
838cdf0e10cSrcweir //liefern, der die Fussnoten umfasst
839cdf0e10cSrcweir if( !pSct->IsAnLower( this ) &&
840cdf0e10cSrcweir (!bFtn || pSct->IsInFtn() ) )
841cdf0e10cSrcweir return pSct;
842cdf0e10cSrcweir }
843cdf0e10cSrcweir return pRet;
844cdf0e10cSrcweir }
845cdf0e10cSrcweir
846cdf0e10cSrcweir // --> OD 2005-12-01 #i27138# - add parameter <_bInSameFtn>
_FindNextCnt(const bool _bInSameFtn)847cdf0e10cSrcweir SwCntntFrm *SwFrm::_FindNextCnt( const bool _bInSameFtn )
848cdf0e10cSrcweir {
849cdf0e10cSrcweir SwFrm *pThis = this;
850cdf0e10cSrcweir
851cdf0e10cSrcweir if ( IsTabFrm() )
852cdf0e10cSrcweir {
853cdf0e10cSrcweir if ( ((SwTabFrm*)this)->GetFollow() )
854cdf0e10cSrcweir {
855cdf0e10cSrcweir pThis = ((SwTabFrm*)this)->GetFollow()->ContainsCntnt();
856cdf0e10cSrcweir if( pThis )
857cdf0e10cSrcweir return (SwCntntFrm*)pThis;
858cdf0e10cSrcweir }
859cdf0e10cSrcweir pThis = ((SwTabFrm*)this)->FindLastCntnt();
860cdf0e10cSrcweir if ( !pThis )
861cdf0e10cSrcweir return 0;
862cdf0e10cSrcweir }
863cdf0e10cSrcweir else if ( IsSctFrm() )
864cdf0e10cSrcweir {
865cdf0e10cSrcweir if ( ((SwSectionFrm*)this)->GetFollow() )
866cdf0e10cSrcweir {
867cdf0e10cSrcweir pThis = ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
868cdf0e10cSrcweir if( pThis )
869cdf0e10cSrcweir return (SwCntntFrm*)pThis;
870cdf0e10cSrcweir }
871cdf0e10cSrcweir pThis = ((SwSectionFrm*)this)->FindLastCntnt();
872cdf0e10cSrcweir if ( !pThis )
873cdf0e10cSrcweir return 0;
874cdf0e10cSrcweir }
875cdf0e10cSrcweir else if ( IsCntntFrm() && ((SwCntntFrm*)this)->GetFollow() )
876cdf0e10cSrcweir return ((SwCntntFrm*)this)->GetFollow();
877cdf0e10cSrcweir
878cdf0e10cSrcweir if ( pThis->IsCntntFrm() )
879cdf0e10cSrcweir {
880cdf0e10cSrcweir const sal_Bool bBody = pThis->IsInDocBody();
881cdf0e10cSrcweir const sal_Bool bFtn = pThis->IsInFtn();
882cdf0e10cSrcweir SwCntntFrm *pNxtCnt = ((SwCntntFrm*)pThis)->GetNextCntntFrm();
883cdf0e10cSrcweir if ( pNxtCnt )
884cdf0e10cSrcweir {
885cdf0e10cSrcweir // --> OD 2005-12-01 #i27138#
886cdf0e10cSrcweir if ( bBody || ( bFtn && !_bInSameFtn ) )
887cdf0e10cSrcweir // <--
888cdf0e10cSrcweir {
889cdf0e10cSrcweir // handling for environments 'footnotes' and 'document body frames':
890cdf0e10cSrcweir while ( pNxtCnt )
891cdf0e10cSrcweir {
892cdf0e10cSrcweir if ( (bBody && pNxtCnt->IsInDocBody()) ||
893cdf0e10cSrcweir (bFtn && pNxtCnt->IsInFtn()) )
894cdf0e10cSrcweir return pNxtCnt;
895cdf0e10cSrcweir pNxtCnt = pNxtCnt->GetNextCntntFrm();
896cdf0e10cSrcweir }
897cdf0e10cSrcweir }
898cdf0e10cSrcweir // --> OD 2005-12-01 #i27138#
899cdf0e10cSrcweir else if ( bFtn && _bInSameFtn )
900cdf0e10cSrcweir {
901cdf0e10cSrcweir // handling for environments 'each footnote':
902cdf0e10cSrcweir // Assure that found next content frame belongs to the same footnotes
903cdf0e10cSrcweir const SwFtnFrm* pFtnFrmOfNext( pNxtCnt->FindFtnFrm() );
904cdf0e10cSrcweir const SwFtnFrm* pFtnFrmOfCurr( pThis->FindFtnFrm() );
905cdf0e10cSrcweir ASSERT( pFtnFrmOfCurr,
906cdf0e10cSrcweir "<SwFrm::_FindNextCnt() - unknown layout situation: current frame has to have an upper footnote frame." );
907cdf0e10cSrcweir if ( pFtnFrmOfNext == pFtnFrmOfCurr )
908cdf0e10cSrcweir {
909cdf0e10cSrcweir return pNxtCnt;
910cdf0e10cSrcweir }
911cdf0e10cSrcweir else if ( pFtnFrmOfCurr->GetFollow() )
912cdf0e10cSrcweir {
913cdf0e10cSrcweir // next content frame has to be the first content frame
914cdf0e10cSrcweir // in the follow footnote, which contains a content frame.
915cdf0e10cSrcweir SwFtnFrm* pFollowFtnFrmOfCurr(
916cdf0e10cSrcweir const_cast<SwFtnFrm*>(pFtnFrmOfCurr) );
917cdf0e10cSrcweir pNxtCnt = 0L;
918cdf0e10cSrcweir do {
919cdf0e10cSrcweir pFollowFtnFrmOfCurr = pFollowFtnFrmOfCurr->GetFollow();
920cdf0e10cSrcweir pNxtCnt = pFollowFtnFrmOfCurr->ContainsCntnt();
921cdf0e10cSrcweir } while ( !pNxtCnt && pFollowFtnFrmOfCurr->GetFollow() );
922cdf0e10cSrcweir return pNxtCnt;
923cdf0e10cSrcweir }
924cdf0e10cSrcweir else
925cdf0e10cSrcweir {
926cdf0e10cSrcweir // current content frame is the last content frame in the
927cdf0e10cSrcweir // footnote - no next content frame exists.
928cdf0e10cSrcweir return 0L;
929cdf0e10cSrcweir }
930cdf0e10cSrcweir }
931cdf0e10cSrcweir // <--
932cdf0e10cSrcweir else if ( pThis->IsInFly() )
933cdf0e10cSrcweir // handling for environments 'unlinked fly frame' and
934cdf0e10cSrcweir // 'group of linked fly frames':
935cdf0e10cSrcweir return pNxtCnt;
936cdf0e10cSrcweir else
937cdf0e10cSrcweir {
938cdf0e10cSrcweir // handling for environments 'page header' and 'page footer':
939cdf0e10cSrcweir const SwFrm *pUp = pThis->GetUpper();
940cdf0e10cSrcweir const SwFrm *pCntUp = pNxtCnt->GetUpper();
941cdf0e10cSrcweir while ( pUp && pUp->GetUpper() &&
942cdf0e10cSrcweir !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
943cdf0e10cSrcweir pUp = pUp->GetUpper();
944cdf0e10cSrcweir while ( pCntUp && pCntUp->GetUpper() &&
945cdf0e10cSrcweir !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
946cdf0e10cSrcweir pCntUp = pCntUp->GetUpper();
947cdf0e10cSrcweir if ( pCntUp == pUp )
948cdf0e10cSrcweir return pNxtCnt;
949cdf0e10cSrcweir }
950cdf0e10cSrcweir }
951cdf0e10cSrcweir }
952cdf0e10cSrcweir return 0;
953cdf0e10cSrcweir }
954cdf0e10cSrcweir
955cdf0e10cSrcweir /** method to determine previous content frame in the same environment
956cdf0e10cSrcweir for a flow frame (content frame, table frame, section frame)
957cdf0e10cSrcweir
958cdf0e10cSrcweir OD 2005-11-30 #i27138#
959cdf0e10cSrcweir
960cdf0e10cSrcweir @author OD
961cdf0e10cSrcweir */
_FindPrevCnt(const bool _bInSameFtn)962cdf0e10cSrcweir SwCntntFrm* SwFrm::_FindPrevCnt( const bool _bInSameFtn )
963cdf0e10cSrcweir {
964cdf0e10cSrcweir if ( !IsFlowFrm() )
965cdf0e10cSrcweir {
966cdf0e10cSrcweir // nothing to do, if current frame isn't a flow frame.
967cdf0e10cSrcweir return 0L;
968cdf0e10cSrcweir }
969cdf0e10cSrcweir
970cdf0e10cSrcweir SwCntntFrm* pPrevCntntFrm( 0L );
971cdf0e10cSrcweir
972cdf0e10cSrcweir // Because method <SwCntntFrm::GetPrevCntntFrm()> is used to travel
973cdf0e10cSrcweir // through the layout, a content frame, at which the travel starts, is needed.
974cdf0e10cSrcweir SwCntntFrm* pCurrCntntFrm = dynamic_cast<SwCntntFrm*>(this);
975cdf0e10cSrcweir
976cdf0e10cSrcweir // perform shortcut, if current frame is a follow, and
977cdf0e10cSrcweir // determine <pCurrCntntFrm>, if current frame is a table or section frame
978cdf0e10cSrcweir if ( pCurrCntntFrm && pCurrCntntFrm->IsFollow() )
979cdf0e10cSrcweir {
980cdf0e10cSrcweir // previous content frame is its master content frame
981cdf0e10cSrcweir pPrevCntntFrm = pCurrCntntFrm->FindMaster();
982cdf0e10cSrcweir }
983cdf0e10cSrcweir else if ( IsTabFrm() )
984cdf0e10cSrcweir {
985cdf0e10cSrcweir SwTabFrm* pTabFrm( static_cast<SwTabFrm*>(this) );
986cdf0e10cSrcweir if ( pTabFrm->IsFollow() )
987cdf0e10cSrcweir {
988cdf0e10cSrcweir // previous content frame is the last content of its master table frame
989cdf0e10cSrcweir pPrevCntntFrm = pTabFrm->FindMaster()->FindLastCntnt();
990cdf0e10cSrcweir }
991cdf0e10cSrcweir else
992cdf0e10cSrcweir {
993cdf0e10cSrcweir // start content frame for the search is the first content frame of
994cdf0e10cSrcweir // the table frame.
995cdf0e10cSrcweir pCurrCntntFrm = pTabFrm->ContainsCntnt();
996cdf0e10cSrcweir }
997cdf0e10cSrcweir }
998cdf0e10cSrcweir else if ( IsSctFrm() )
999cdf0e10cSrcweir {
1000cdf0e10cSrcweir SwSectionFrm* pSectFrm( static_cast<SwSectionFrm*>(this) );
1001cdf0e10cSrcweir if ( pSectFrm->IsFollow() )
1002cdf0e10cSrcweir {
1003cdf0e10cSrcweir // previous content frame is the last content of its master section frame
1004cdf0e10cSrcweir pPrevCntntFrm = pSectFrm->FindMaster()->FindLastCntnt();
1005cdf0e10cSrcweir }
1006cdf0e10cSrcweir else
1007cdf0e10cSrcweir {
1008cdf0e10cSrcweir // start content frame for the search is the first content frame of
1009cdf0e10cSrcweir // the section frame.
1010cdf0e10cSrcweir pCurrCntntFrm = pSectFrm->ContainsCntnt();
1011cdf0e10cSrcweir }
1012cdf0e10cSrcweir }
1013cdf0e10cSrcweir
1014cdf0e10cSrcweir // search for next content frame, depending on the environment, in which
1015cdf0e10cSrcweir // the current frame is in.
1016cdf0e10cSrcweir if ( !pPrevCntntFrm && pCurrCntntFrm )
1017cdf0e10cSrcweir {
1018cdf0e10cSrcweir pPrevCntntFrm = pCurrCntntFrm->GetPrevCntntFrm();
1019cdf0e10cSrcweir if ( pPrevCntntFrm )
1020cdf0e10cSrcweir {
1021cdf0e10cSrcweir if ( pCurrCntntFrm->IsInFly() )
1022cdf0e10cSrcweir {
1023cdf0e10cSrcweir // handling for environments 'unlinked fly frame' and
1024cdf0e10cSrcweir // 'group of linked fly frames':
1025cdf0e10cSrcweir // Nothing to do, <pPrevCntntFrm> is the one
1026cdf0e10cSrcweir }
1027cdf0e10cSrcweir else
1028cdf0e10cSrcweir {
1029cdf0e10cSrcweir const bool bInDocBody = pCurrCntntFrm->IsInDocBody();
1030cdf0e10cSrcweir const bool bInFtn = pCurrCntntFrm->IsInFtn();
1031cdf0e10cSrcweir if ( bInDocBody || ( bInFtn && !_bInSameFtn ) )
1032cdf0e10cSrcweir {
1033cdf0e10cSrcweir // handling for environments 'footnotes' and 'document body frames':
1034cdf0e10cSrcweir // Assure that found previous frame is also in one of these
1035cdf0e10cSrcweir // environments. Otherwise, travel further
1036cdf0e10cSrcweir while ( pPrevCntntFrm )
1037cdf0e10cSrcweir {
1038cdf0e10cSrcweir if ( ( bInDocBody && pPrevCntntFrm->IsInDocBody() ) ||
1039cdf0e10cSrcweir ( bInFtn && pPrevCntntFrm->IsInFtn() ) )
1040cdf0e10cSrcweir {
1041cdf0e10cSrcweir break;
1042cdf0e10cSrcweir }
1043cdf0e10cSrcweir pPrevCntntFrm = pPrevCntntFrm->GetPrevCntntFrm();
1044cdf0e10cSrcweir }
1045cdf0e10cSrcweir }
1046cdf0e10cSrcweir else if ( bInFtn && _bInSameFtn )
1047cdf0e10cSrcweir {
1048cdf0e10cSrcweir // handling for environments 'each footnote':
1049cdf0e10cSrcweir // Assure that found next content frame belongs to the same footnotes
1050cdf0e10cSrcweir const SwFtnFrm* pFtnFrmOfPrev( pPrevCntntFrm->FindFtnFrm() );
1051cdf0e10cSrcweir const SwFtnFrm* pFtnFrmOfCurr( pCurrCntntFrm->FindFtnFrm() );
1052cdf0e10cSrcweir if ( pFtnFrmOfPrev != pFtnFrmOfCurr )
1053cdf0e10cSrcweir {
1054cdf0e10cSrcweir if ( pFtnFrmOfCurr->GetMaster() )
1055cdf0e10cSrcweir {
1056cdf0e10cSrcweir SwFtnFrm* pMasterFtnFrmOfCurr(
1057cdf0e10cSrcweir const_cast<SwFtnFrm*>(pFtnFrmOfCurr) );
1058cdf0e10cSrcweir pPrevCntntFrm = 0L;
1059cdf0e10cSrcweir // --> OD 2007-07-05 #146872#
1060cdf0e10cSrcweir // correct wrong loop-condition
1061cdf0e10cSrcweir do {
1062cdf0e10cSrcweir pMasterFtnFrmOfCurr = pMasterFtnFrmOfCurr->GetMaster();
1063cdf0e10cSrcweir pPrevCntntFrm = pMasterFtnFrmOfCurr->FindLastCntnt();
1064cdf0e10cSrcweir } while ( !pPrevCntntFrm &&
1065cdf0e10cSrcweir pMasterFtnFrmOfCurr->GetMaster() );
1066cdf0e10cSrcweir // <--
1067cdf0e10cSrcweir }
1068cdf0e10cSrcweir else
1069cdf0e10cSrcweir {
1070cdf0e10cSrcweir // current content frame is the first content in the
1071cdf0e10cSrcweir // footnote - no previous content exists.
1072cdf0e10cSrcweir pPrevCntntFrm = 0L;;
1073cdf0e10cSrcweir }
1074cdf0e10cSrcweir }
1075cdf0e10cSrcweir }
1076cdf0e10cSrcweir else
1077cdf0e10cSrcweir {
1078cdf0e10cSrcweir // handling for environments 'page header' and 'page footer':
1079cdf0e10cSrcweir // Assure that found previous frame is also in the same
1080cdf0e10cSrcweir // page header respectively page footer as <pCurrCntntFrm>
1081cdf0e10cSrcweir // Note: At this point its clear, that <pCurrCntntFrm> has
1082cdf0e10cSrcweir // to be inside a page header or page footer and that
1083cdf0e10cSrcweir // neither <pCurrCntntFrm> nor <pPrevCntntFrm> are
1084cdf0e10cSrcweir // inside a fly frame.
1085cdf0e10cSrcweir // Thus, method <FindFooterOrHeader()> can be used.
1086cdf0e10cSrcweir ASSERT( pCurrCntntFrm->FindFooterOrHeader(),
1087cdf0e10cSrcweir "<SwFrm::_FindPrevCnt()> - unknown layout situation: current frame should be in page header or page footer" );
1088cdf0e10cSrcweir ASSERT( !pPrevCntntFrm->IsInFly(),
1089cdf0e10cSrcweir "<SwFrm::_FindPrevCnt()> - unknown layout situation: found previous frame should *not* be inside a fly frame." );
1090cdf0e10cSrcweir if ( pPrevCntntFrm->FindFooterOrHeader() !=
1091cdf0e10cSrcweir pCurrCntntFrm->FindFooterOrHeader() )
1092cdf0e10cSrcweir {
1093cdf0e10cSrcweir pPrevCntntFrm = 0L;
1094cdf0e10cSrcweir }
1095cdf0e10cSrcweir }
1096cdf0e10cSrcweir }
1097cdf0e10cSrcweir }
1098cdf0e10cSrcweir }
1099cdf0e10cSrcweir
1100cdf0e10cSrcweir return pPrevCntntFrm;
1101cdf0e10cSrcweir }
1102cdf0e10cSrcweir
_FindPrev()1103cdf0e10cSrcweir SwFrm *SwFrm::_FindPrev()
1104cdf0e10cSrcweir {
1105cdf0e10cSrcweir sal_Bool bIgnoreTab = sal_False;
1106cdf0e10cSrcweir SwFrm *pThis = this;
1107cdf0e10cSrcweir
1108cdf0e10cSrcweir if ( IsTabFrm() )
1109cdf0e10cSrcweir {
1110cdf0e10cSrcweir //Der erste Cntnt der Tabelle wird
1111cdf0e10cSrcweir //gegriffen und dessen Vorgaenger geliefert. Um die Spezialbeh.
1112cdf0e10cSrcweir //Fuer Tabellen (s.u.) auszuschalten wird bIgnoreTab gesetzt.
1113cdf0e10cSrcweir if ( ((SwTabFrm*)this)->IsFollow() )
1114cdf0e10cSrcweir return ((SwTabFrm*)this)->FindMaster();
1115cdf0e10cSrcweir else
1116cdf0e10cSrcweir pThis = ((SwTabFrm*)this)->ContainsCntnt();
1117cdf0e10cSrcweir bIgnoreTab = sal_True;
1118cdf0e10cSrcweir }
1119cdf0e10cSrcweir
1120cdf0e10cSrcweir if ( pThis && pThis->IsCntntFrm() )
1121cdf0e10cSrcweir {
1122cdf0e10cSrcweir SwCntntFrm *pPrvCnt = ((SwCntntFrm*)pThis)->GetPrevCntntFrm();
1123cdf0e10cSrcweir if( !pPrvCnt )
1124cdf0e10cSrcweir return 0;
1125cdf0e10cSrcweir if ( !bIgnoreTab && pThis->IsInTab() )
1126cdf0e10cSrcweir {
1127cdf0e10cSrcweir SwLayoutFrm *pUp = pThis->GetUpper();
1128cdf0e10cSrcweir while ( !pUp->IsCellFrm() )
1129cdf0e10cSrcweir pUp = pUp->GetUpper();
1130cdf0e10cSrcweir ASSERT( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
1131cdf0e10cSrcweir if ( pUp->IsAnLower( pPrvCnt ) )
1132cdf0e10cSrcweir return pPrvCnt;
1133cdf0e10cSrcweir }
1134cdf0e10cSrcweir else
1135cdf0e10cSrcweir {
1136cdf0e10cSrcweir SwFrm* pRet;
1137cdf0e10cSrcweir const sal_Bool bBody = pThis->IsInDocBody();
1138cdf0e10cSrcweir const sal_Bool bFtn = bBody ? sal_False : pThis->IsInFtn();
1139cdf0e10cSrcweir if ( bBody || bFtn )
1140cdf0e10cSrcweir {
1141cdf0e10cSrcweir while ( pPrvCnt )
1142cdf0e10cSrcweir {
1143cdf0e10cSrcweir if ( (bBody && pPrvCnt->IsInDocBody()) ||
1144cdf0e10cSrcweir (bFtn && pPrvCnt->IsInFtn()) )
1145cdf0e10cSrcweir {
1146cdf0e10cSrcweir pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1147cdf0e10cSrcweir : (SwFrm*)pPrvCnt;
1148cdf0e10cSrcweir return pRet;
1149cdf0e10cSrcweir }
1150cdf0e10cSrcweir pPrvCnt = pPrvCnt->GetPrevCntntFrm();
1151cdf0e10cSrcweir }
1152cdf0e10cSrcweir }
1153cdf0e10cSrcweir else if ( pThis->IsInFly() )
1154cdf0e10cSrcweir {
1155cdf0e10cSrcweir pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1156cdf0e10cSrcweir : (SwFrm*)pPrvCnt;
1157cdf0e10cSrcweir return pRet;
1158cdf0e10cSrcweir }
1159cdf0e10cSrcweir else //Fuss-/oder Kopfbereich oder Fly
1160cdf0e10cSrcweir {
1161cdf0e10cSrcweir const SwFrm *pUp = pThis->GetUpper();
1162cdf0e10cSrcweir const SwFrm *pCntUp = pPrvCnt->GetUpper();
1163cdf0e10cSrcweir while ( pUp && pUp->GetUpper() &&
1164cdf0e10cSrcweir !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
1165cdf0e10cSrcweir pUp = pUp->GetUpper();
1166cdf0e10cSrcweir while ( pCntUp && pCntUp->GetUpper() )
1167cdf0e10cSrcweir pCntUp = pCntUp->GetUpper();
1168cdf0e10cSrcweir if ( pCntUp == pUp )
1169cdf0e10cSrcweir {
1170cdf0e10cSrcweir pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1171cdf0e10cSrcweir : (SwFrm*)pPrvCnt;
1172cdf0e10cSrcweir return pRet;
1173cdf0e10cSrcweir }
1174cdf0e10cSrcweir }
1175cdf0e10cSrcweir }
1176cdf0e10cSrcweir }
1177cdf0e10cSrcweir return 0;
1178cdf0e10cSrcweir }
1179cdf0e10cSrcweir
ImplInvalidateNextPos(sal_Bool bNoFtn)1180cdf0e10cSrcweir void SwFrm::ImplInvalidateNextPos( sal_Bool bNoFtn )
1181cdf0e10cSrcweir {
1182cdf0e10cSrcweir SwFrm *pFrm;
1183cdf0e10cSrcweir if ( 0 != (pFrm = _FindNext()) )
1184cdf0e10cSrcweir {
1185cdf0e10cSrcweir if( pFrm->IsSctFrm() )
1186cdf0e10cSrcweir {
1187cdf0e10cSrcweir while( pFrm && pFrm->IsSctFrm() )
1188cdf0e10cSrcweir {
1189cdf0e10cSrcweir if( ((SwSectionFrm*)pFrm)->GetSection() )
1190cdf0e10cSrcweir {
1191cdf0e10cSrcweir SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
1192cdf0e10cSrcweir if( pTmp )
1193cdf0e10cSrcweir pTmp->InvalidatePos();
1194cdf0e10cSrcweir else if( !bNoFtn )
1195cdf0e10cSrcweir ((SwSectionFrm*)pFrm)->InvalidateFtnPos();
1196cdf0e10cSrcweir if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
1197cdf0e10cSrcweir pFrm->InvalidatePos();
1198cdf0e10cSrcweir return;
1199cdf0e10cSrcweir }
1200cdf0e10cSrcweir pFrm = pFrm->FindNext();
1201cdf0e10cSrcweir }
1202cdf0e10cSrcweir if( pFrm )
1203cdf0e10cSrcweir {
1204cdf0e10cSrcweir if ( pFrm->IsSctFrm())
1205cdf0e10cSrcweir { // Damit der Inhalt eines Bereichs die Chance erhaelt,
1206cdf0e10cSrcweir // die Seite zu wechseln, muss er ebenfalls invalidiert werden.
1207cdf0e10cSrcweir SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
1208cdf0e10cSrcweir if( pTmp )
1209cdf0e10cSrcweir pTmp->InvalidatePos();
1210cdf0e10cSrcweir if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
1211cdf0e10cSrcweir pFrm->InvalidatePos();
1212cdf0e10cSrcweir }
1213cdf0e10cSrcweir else
1214cdf0e10cSrcweir pFrm->InvalidatePos();
1215cdf0e10cSrcweir }
1216cdf0e10cSrcweir }
1217cdf0e10cSrcweir else
1218cdf0e10cSrcweir pFrm->InvalidatePos();
1219cdf0e10cSrcweir }
1220cdf0e10cSrcweir }
1221cdf0e10cSrcweir
1222cdf0e10cSrcweir /** method to invalidate printing area of next frame
1223cdf0e10cSrcweir
1224cdf0e10cSrcweir OD 09.01.2004 #i11859#
1225cdf0e10cSrcweir
1226cdf0e10cSrcweir @author OD
1227cdf0e10cSrcweir
1228cdf0e10cSrcweir FME 2004-04-19 #i27145# Moved function from SwTxtFrm to SwFrm
1229cdf0e10cSrcweir */
InvalidateNextPrtArea()1230cdf0e10cSrcweir void SwFrm::InvalidateNextPrtArea()
1231cdf0e10cSrcweir {
1232cdf0e10cSrcweir // determine next frame
1233cdf0e10cSrcweir SwFrm* pNextFrm = FindNext();
1234cdf0e10cSrcweir // skip empty section frames and hidden text frames
1235cdf0e10cSrcweir {
1236cdf0e10cSrcweir while ( pNextFrm &&
1237cdf0e10cSrcweir ( ( pNextFrm->IsSctFrm() &&
1238cdf0e10cSrcweir !static_cast<SwSectionFrm*>(pNextFrm)->GetSection() ) ||
1239cdf0e10cSrcweir ( pNextFrm->IsTxtFrm() &&
1240cdf0e10cSrcweir static_cast<SwTxtFrm*>(pNextFrm)->IsHiddenNow() ) ) )
1241cdf0e10cSrcweir {
1242cdf0e10cSrcweir pNextFrm = pNextFrm->FindNext();
1243cdf0e10cSrcweir }
1244cdf0e10cSrcweir }
1245cdf0e10cSrcweir
1246cdf0e10cSrcweir // Invalidate printing area of found next frame
1247cdf0e10cSrcweir if ( pNextFrm )
1248cdf0e10cSrcweir {
1249cdf0e10cSrcweir if ( pNextFrm->IsSctFrm() )
1250cdf0e10cSrcweir {
1251cdf0e10cSrcweir // Invalidate printing area of found section frame, if
1252cdf0e10cSrcweir // (1) this text frame isn't in a section OR
1253cdf0e10cSrcweir // (2) found section frame isn't a follow of the section frame this
1254cdf0e10cSrcweir // text frame is in.
1255cdf0e10cSrcweir if ( !IsInSct() || FindSctFrm()->GetFollow() != pNextFrm )
1256cdf0e10cSrcweir {
1257cdf0e10cSrcweir pNextFrm->InvalidatePrt();
1258cdf0e10cSrcweir }
1259cdf0e10cSrcweir
1260cdf0e10cSrcweir // Invalidate printing area of first content in found section.
1261cdf0e10cSrcweir SwFrm* pFstCntntOfSctFrm =
1262cdf0e10cSrcweir static_cast<SwSectionFrm*>(pNextFrm)->ContainsAny();
1263cdf0e10cSrcweir if ( pFstCntntOfSctFrm )
1264cdf0e10cSrcweir {
1265cdf0e10cSrcweir pFstCntntOfSctFrm->InvalidatePrt();
1266cdf0e10cSrcweir }
1267cdf0e10cSrcweir }
1268cdf0e10cSrcweir else
1269cdf0e10cSrcweir {
1270cdf0e10cSrcweir pNextFrm->InvalidatePrt();
1271cdf0e10cSrcweir }
1272cdf0e10cSrcweir }
1273cdf0e10cSrcweir }
1274cdf0e10cSrcweir
1275cdf0e10cSrcweir /*************************************************************************
1276cdf0e10cSrcweir |*
1277cdf0e10cSrcweir |* lcl_IsInColSect()
1278cdf0e10cSrcweir |* liefert nur sal_True, wenn der Frame _direkt_ in einem spaltigen Bereich steht,
1279cdf0e10cSrcweir |* nicht etwa, wenn er in einer Tabelle steht, die in einem spaltigen Bereich ist.
1280cdf0e10cSrcweir |*
1281cdf0e10cSrcweir |*************************************************************************/
1282cdf0e10cSrcweir
lcl_IsInColSct(const SwFrm * pUp)1283cdf0e10cSrcweir sal_Bool lcl_IsInColSct( const SwFrm *pUp )
1284cdf0e10cSrcweir {
1285cdf0e10cSrcweir sal_Bool bRet = sal_False;
1286cdf0e10cSrcweir while( pUp )
1287cdf0e10cSrcweir {
1288cdf0e10cSrcweir if( pUp->IsColumnFrm() )
1289cdf0e10cSrcweir bRet = sal_True;
1290cdf0e10cSrcweir else if( pUp->IsSctFrm() )
1291cdf0e10cSrcweir return bRet;
1292cdf0e10cSrcweir else if( pUp->IsTabFrm() )
1293cdf0e10cSrcweir return sal_False;
1294cdf0e10cSrcweir pUp = pUp->GetUpper();
1295cdf0e10cSrcweir }
1296cdf0e10cSrcweir return sal_False;
1297cdf0e10cSrcweir }
1298cdf0e10cSrcweir
1299cdf0e10cSrcweir /*************************************************************************
1300cdf0e10cSrcweir |*
1301cdf0e10cSrcweir |* SwFrm::IsMoveable();
1302cdf0e10cSrcweir |*
1303cdf0e10cSrcweir |* Ersterstellung MA 09. Mar. 93
1304cdf0e10cSrcweir |* Letzte Aenderung MA 05. May. 95
1305cdf0e10cSrcweir |*
1306cdf0e10cSrcweir |*************************************************************************/
1307cdf0e10cSrcweir /** determine, if frame is moveable in given environment
1308cdf0e10cSrcweir
1309cdf0e10cSrcweir OD 08.08.2003 #110978#
1310cdf0e10cSrcweir method replaced 'old' method <sal_Bool IsMoveable() const>.
1311cdf0e10cSrcweir Determines, if frame is moveable in given environment. if no environment
1312cdf0e10cSrcweir is given (parameter _pLayoutFrm == 0L), the movability in the actual
1313cdf0e10cSrcweir environment (<this->GetUpper()) is checked.
1314cdf0e10cSrcweir
1315cdf0e10cSrcweir @author OD
1316cdf0e10cSrcweir */
1317cdf0e10cSrcweir
IsMoveable(const SwLayoutFrm * _pLayoutFrm) const1318cdf0e10cSrcweir bool SwFrm::IsMoveable( const SwLayoutFrm* _pLayoutFrm ) const
1319cdf0e10cSrcweir {
1320cdf0e10cSrcweir bool bRetVal = false;
1321cdf0e10cSrcweir
1322cdf0e10cSrcweir if ( !_pLayoutFrm )
1323cdf0e10cSrcweir {
1324cdf0e10cSrcweir _pLayoutFrm = GetUpper();
1325cdf0e10cSrcweir }
1326cdf0e10cSrcweir
1327cdf0e10cSrcweir if ( _pLayoutFrm && IsFlowFrm() )
1328cdf0e10cSrcweir {
1329cdf0e10cSrcweir if ( _pLayoutFrm->IsInSct() && lcl_IsInColSct( _pLayoutFrm ) )
1330cdf0e10cSrcweir {
1331cdf0e10cSrcweir bRetVal = true;
1332cdf0e10cSrcweir }
1333cdf0e10cSrcweir else if ( _pLayoutFrm->IsInFly() ||
1334cdf0e10cSrcweir _pLayoutFrm->IsInDocBody() ||
1335cdf0e10cSrcweir _pLayoutFrm->IsInFtn() )
1336cdf0e10cSrcweir {
1337cdf0e10cSrcweir if ( _pLayoutFrm->IsInTab() && !IsTabFrm() &&
1338cdf0e10cSrcweir ( !IsCntntFrm() || !const_cast<SwFrm*>(this)->GetNextCellLeaf( MAKEPAGE_NONE ) ) )
1339cdf0e10cSrcweir {
1340cdf0e10cSrcweir bRetVal = false;
1341cdf0e10cSrcweir }
1342cdf0e10cSrcweir else
1343cdf0e10cSrcweir {
1344cdf0e10cSrcweir if ( _pLayoutFrm->IsInFly() )
1345cdf0e10cSrcweir {
1346cdf0e10cSrcweir // if fly frame has a follow (next linked fly frame),
1347cdf0e10cSrcweir // frame is moveable.
1348cdf0e10cSrcweir if ( const_cast<SwLayoutFrm*>(_pLayoutFrm)->FindFlyFrm()->GetNextLink() )
1349cdf0e10cSrcweir {
1350cdf0e10cSrcweir bRetVal = true;
1351cdf0e10cSrcweir }
1352cdf0e10cSrcweir else
1353cdf0e10cSrcweir {
1354cdf0e10cSrcweir // if environment is columned, frame is moveable, if
1355cdf0e10cSrcweir // it isn't in last column.
1356cdf0e10cSrcweir // search for column frame
1357cdf0e10cSrcweir const SwFrm* pCol = _pLayoutFrm;
1358cdf0e10cSrcweir while ( pCol && !pCol->IsColumnFrm() )
1359cdf0e10cSrcweir {
1360cdf0e10cSrcweir pCol = pCol->GetUpper();
1361cdf0e10cSrcweir }
1362cdf0e10cSrcweir // frame is moveable, if found column frame isn't last one.
1363cdf0e10cSrcweir if ( pCol && pCol->GetNext() )
1364cdf0e10cSrcweir {
1365cdf0e10cSrcweir bRetVal = true;
1366cdf0e10cSrcweir }
1367cdf0e10cSrcweir }
1368cdf0e10cSrcweir }
1369cdf0e10cSrcweir else
1370cdf0e10cSrcweir {
1371cdf0e10cSrcweir bRetVal = true;
1372cdf0e10cSrcweir }
1373cdf0e10cSrcweir }
1374cdf0e10cSrcweir }
1375cdf0e10cSrcweir }
1376cdf0e10cSrcweir
1377cdf0e10cSrcweir return bRetVal;
1378cdf0e10cSrcweir }
1379cdf0e10cSrcweir
1380cdf0e10cSrcweir /*************************************************************************
1381cdf0e10cSrcweir |*
1382cdf0e10cSrcweir |* SwFrm::SetInfFlags();
1383cdf0e10cSrcweir |*
1384cdf0e10cSrcweir |* Ersterstellung MA 05. Apr. 94
1385cdf0e10cSrcweir |* Letzte Aenderung MA 05. Apr. 94
1386cdf0e10cSrcweir |*
1387cdf0e10cSrcweir |*************************************************************************/
SetInfFlags()1388cdf0e10cSrcweir void SwFrm::SetInfFlags()
1389cdf0e10cSrcweir {
1390cdf0e10cSrcweir if ( !IsFlyFrm() && !GetUpper() ) //noch nicht gepastet, keine Informationen
1391cdf0e10cSrcweir return; //lieferbar
1392cdf0e10cSrcweir
1393cdf0e10cSrcweir bInfInvalid = bInfBody = bInfTab = bInfFly = bInfFtn = bInfSct = sal_False;
1394cdf0e10cSrcweir
1395cdf0e10cSrcweir SwFrm *pFrm = this;
1396cdf0e10cSrcweir if( IsFtnContFrm() )
1397cdf0e10cSrcweir bInfFtn = sal_True;
1398cdf0e10cSrcweir do
1399cdf0e10cSrcweir { // bInfBody wird nur am Seitenbody, nicht im ColumnBody gesetzt
1400cdf0e10cSrcweir if ( pFrm->IsBodyFrm() && !bInfFtn && pFrm->GetUpper()
1401cdf0e10cSrcweir && pFrm->GetUpper()->IsPageFrm() )
1402cdf0e10cSrcweir bInfBody = sal_True;
1403cdf0e10cSrcweir else if ( pFrm->IsTabFrm() || pFrm->IsCellFrm() )
1404cdf0e10cSrcweir {
1405cdf0e10cSrcweir bInfTab = sal_True;
1406cdf0e10cSrcweir }
1407cdf0e10cSrcweir else if ( pFrm->IsFlyFrm() )
1408cdf0e10cSrcweir bInfFly = sal_True;
1409cdf0e10cSrcweir else if ( pFrm->IsSctFrm() )
1410cdf0e10cSrcweir bInfSct = sal_True;
1411cdf0e10cSrcweir else if ( pFrm->IsFtnFrm() )
1412cdf0e10cSrcweir bInfFtn = sal_True;
1413cdf0e10cSrcweir
1414cdf0e10cSrcweir pFrm = pFrm->GetUpper();
1415cdf0e10cSrcweir
1416cdf0e10cSrcweir } while ( pFrm && !pFrm->IsPageFrm() ); //Oberhalb der Seite kommt nix
1417cdf0e10cSrcweir }
1418cdf0e10cSrcweir
1419cdf0e10cSrcweir /*-----------------22.8.2001 14:30------------------
1420cdf0e10cSrcweir * SwFrm::SetDirFlags( sal_Bool )
1421cdf0e10cSrcweir * actualizes the vertical or the righttoleft-flags.
1422cdf0e10cSrcweir * If the property is derived, it's from the upper or (for fly frames) from
1423cdf0e10cSrcweir * the anchor. Otherwise we've to call a virtual method to check the property.
1424cdf0e10cSrcweir * --------------------------------------------------*/
1425cdf0e10cSrcweir
SetDirFlags(sal_Bool bVert)1426cdf0e10cSrcweir void SwFrm::SetDirFlags( sal_Bool bVert )
1427cdf0e10cSrcweir {
1428cdf0e10cSrcweir if( bVert )
1429cdf0e10cSrcweir {
1430cdf0e10cSrcweir // OD 2004-01-21 #114969# - if derived, valid vertical flag only if
1431cdf0e10cSrcweir // vertical flag of upper/anchor is valid.
1432cdf0e10cSrcweir if( bDerivedVert )
1433cdf0e10cSrcweir {
1434cdf0e10cSrcweir const SwFrm* pAsk = IsFlyFrm() ?
1435cdf0e10cSrcweir ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1436cdf0e10cSrcweir
1437cdf0e10cSrcweir ASSERT( pAsk != this, "Autsch! Stack overflow is about to happen" )
1438cdf0e10cSrcweir
1439cdf0e10cSrcweir if( pAsk )
1440cdf0e10cSrcweir {
1441cdf0e10cSrcweir bVertical = pAsk->IsVertical() ? 1 : 0;
1442cdf0e10cSrcweir bReverse = pAsk->IsReverse() ? 1 : 0;
1443cdf0e10cSrcweir
1444cdf0e10cSrcweir bVertLR = pAsk->IsVertLR() ? 1 : 0;
1445cdf0e10cSrcweir //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1446cdf0e10cSrcweir if ( !pAsk->bInvalidVert )
1447cdf0e10cSrcweir bInvalidVert = sal_False;
1448cdf0e10cSrcweir }
1449cdf0e10cSrcweir }
1450cdf0e10cSrcweir else
1451cdf0e10cSrcweir CheckDirection( bVert );
1452cdf0e10cSrcweir }
1453cdf0e10cSrcweir else
1454cdf0e10cSrcweir {
1455cdf0e10cSrcweir sal_Bool bInv = 0;
1456cdf0e10cSrcweir if( !bDerivedR2L ) // CheckDirection is able to set bDerivedR2L!
1457cdf0e10cSrcweir CheckDirection( bVert );
1458cdf0e10cSrcweir if( bDerivedR2L )
1459cdf0e10cSrcweir {
1460cdf0e10cSrcweir const SwFrm* pAsk = IsFlyFrm() ?
1461cdf0e10cSrcweir ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1462cdf0e10cSrcweir
1463cdf0e10cSrcweir ASSERT( pAsk != this, "Autsch! Stack overflow is about to happen" )
1464cdf0e10cSrcweir
1465cdf0e10cSrcweir if( pAsk )
1466cdf0e10cSrcweir bRightToLeft = pAsk->IsRightToLeft() ? 1 : 0;
1467cdf0e10cSrcweir if( !pAsk || pAsk->bInvalidR2L )
1468cdf0e10cSrcweir bInv = bInvalidR2L;
1469cdf0e10cSrcweir }
1470cdf0e10cSrcweir bInvalidR2L = bInv;
1471cdf0e10cSrcweir }
1472cdf0e10cSrcweir }
1473cdf0e10cSrcweir
GetNextCellLeaf(MakePageType)1474cdf0e10cSrcweir SwLayoutFrm* SwFrm::GetNextCellLeaf( MakePageType )
1475cdf0e10cSrcweir {
1476cdf0e10cSrcweir SwFrm* pTmpFrm = this;
1477cdf0e10cSrcweir while ( !pTmpFrm->IsCellFrm() )
1478cdf0e10cSrcweir pTmpFrm = pTmpFrm->GetUpper();
1479cdf0e10cSrcweir
1480cdf0e10cSrcweir ASSERT( pTmpFrm, "SwFrm::GetNextCellLeaf() without cell" )
1481cdf0e10cSrcweir return ((SwCellFrm*)pTmpFrm)->GetFollowCell();
1482cdf0e10cSrcweir }
1483cdf0e10cSrcweir
GetPrevCellLeaf(MakePageType)1484cdf0e10cSrcweir SwLayoutFrm* SwFrm::GetPrevCellLeaf( MakePageType )
1485cdf0e10cSrcweir {
1486cdf0e10cSrcweir SwFrm* pTmpFrm = this;
1487cdf0e10cSrcweir while ( !pTmpFrm->IsCellFrm() )
1488cdf0e10cSrcweir pTmpFrm = pTmpFrm->GetUpper();
1489cdf0e10cSrcweir
1490cdf0e10cSrcweir ASSERT( pTmpFrm, "SwFrm::GetNextPreviousLeaf() without cell" )
1491cdf0e10cSrcweir return ((SwCellFrm*)pTmpFrm)->GetPreviousCell();
1492cdf0e10cSrcweir }
1493cdf0e10cSrcweir
lcl_FindCorrespondingCellFrm(const SwRowFrm & rOrigRow,const SwCellFrm & rOrigCell,const SwRowFrm & rCorrRow,bool bInFollow)1494cdf0e10cSrcweir SwCellFrm* lcl_FindCorrespondingCellFrm( const SwRowFrm& rOrigRow,
1495cdf0e10cSrcweir const SwCellFrm& rOrigCell,
1496cdf0e10cSrcweir const SwRowFrm& rCorrRow,
1497cdf0e10cSrcweir bool bInFollow )
1498cdf0e10cSrcweir {
1499cdf0e10cSrcweir SwCellFrm* pRet = NULL;
1500cdf0e10cSrcweir SwCellFrm* pCell = (SwCellFrm*)rOrigRow.Lower();
1501cdf0e10cSrcweir SwCellFrm* pCorrCell = (SwCellFrm*)rCorrRow.Lower();
1502cdf0e10cSrcweir
1503cdf0e10cSrcweir while ( pCell != &rOrigCell && !pCell->IsAnLower( &rOrigCell ) )
1504cdf0e10cSrcweir {
1505cdf0e10cSrcweir pCell = (SwCellFrm*)pCell->GetNext();
1506cdf0e10cSrcweir pCorrCell = (SwCellFrm*)pCorrCell->GetNext();
1507cdf0e10cSrcweir }
1508cdf0e10cSrcweir
1509cdf0e10cSrcweir ASSERT( pCell && pCorrCell, "lcl_FindCorrespondingCellFrm does not work" )
1510cdf0e10cSrcweir
1511cdf0e10cSrcweir if ( pCell != &rOrigCell )
1512cdf0e10cSrcweir {
1513cdf0e10cSrcweir // rOrigCell must be a lower of pCell. We need to recurse into the rows:
1514cdf0e10cSrcweir ASSERT( pCell->Lower() && pCell->Lower()->IsRowFrm(),
1515cdf0e10cSrcweir "lcl_FindCorrespondingCellFrm does not work" )
1516cdf0e10cSrcweir
1517cdf0e10cSrcweir SwRowFrm* pRow = (SwRowFrm*)pCell->Lower();
1518cdf0e10cSrcweir while ( !pRow->IsAnLower( &rOrigCell ) )
1519cdf0e10cSrcweir pRow = (SwRowFrm*)pRow->GetNext();
1520cdf0e10cSrcweir
1521cdf0e10cSrcweir SwRowFrm* pCorrRow = 0;
1522cdf0e10cSrcweir if ( bInFollow )
1523cdf0e10cSrcweir pCorrRow = pRow->GetFollowRow();
1524cdf0e10cSrcweir else
1525cdf0e10cSrcweir {
1526cdf0e10cSrcweir SwRowFrm* pTmpRow = static_cast<SwRowFrm*>(pCorrCell->GetLastLower());
1527cdf0e10cSrcweir
1528cdf0e10cSrcweir if ( pTmpRow && pTmpRow->GetFollowRow() == pRow )
1529cdf0e10cSrcweir pCorrRow = pTmpRow;
1530cdf0e10cSrcweir }
1531cdf0e10cSrcweir
1532cdf0e10cSrcweir if ( pCorrRow )
1533cdf0e10cSrcweir pRet = lcl_FindCorrespondingCellFrm( *pRow, rOrigCell, *pCorrRow, bInFollow );
1534cdf0e10cSrcweir }
1535cdf0e10cSrcweir else
1536cdf0e10cSrcweir pRet = pCorrCell;
1537cdf0e10cSrcweir
1538cdf0e10cSrcweir return pRet;
1539cdf0e10cSrcweir }
1540cdf0e10cSrcweir
1541cdf0e10cSrcweir // VERSION OF GetFollowCell() that assumes that we always have a follow flow line:
GetFollowCell() const1542cdf0e10cSrcweir SwCellFrm* SwCellFrm::GetFollowCell() const
1543cdf0e10cSrcweir {
1544cdf0e10cSrcweir SwCellFrm* pRet = NULL;
1545cdf0e10cSrcweir
1546cdf0e10cSrcweir // NEW TABLES
1547cdf0e10cSrcweir // Covered cells do not have follow cells!
1548cdf0e10cSrcweir const long nRowSpan = GetLayoutRowSpan();
1549cdf0e10cSrcweir if ( nRowSpan < 1 )
1550cdf0e10cSrcweir return NULL;
1551cdf0e10cSrcweir
1552cdf0e10cSrcweir // find most upper row frame
1553cdf0e10cSrcweir const SwFrm* pRow = GetUpper();
1554cdf0e10cSrcweir while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
1555cdf0e10cSrcweir pRow = pRow->GetUpper();
1556cdf0e10cSrcweir
1557cdf0e10cSrcweir if ( !pRow )
1558cdf0e10cSrcweir return NULL;
1559cdf0e10cSrcweir
1560cdf0e10cSrcweir const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( pRow->GetUpper() );
1561cdf0e10cSrcweir if ( !pRow || !pTabFrm->GetFollow() || !pTabFrm->HasFollowFlowLine() )
1562cdf0e10cSrcweir return NULL;
1563cdf0e10cSrcweir
1564cdf0e10cSrcweir const SwCellFrm* pThisCell = this;
1565cdf0e10cSrcweir
1566cdf0e10cSrcweir // Get last cell of the current table frame that belongs to the rowspan:
1567cdf0e10cSrcweir if ( nRowSpan > 1 )
1568cdf0e10cSrcweir {
1569cdf0e10cSrcweir // optimization: Will end of row span be in last row or exceed row?
1570cdf0e10cSrcweir long nMax = 0;
1571cdf0e10cSrcweir while ( pRow->GetNext() && ++nMax < nRowSpan )
1572cdf0e10cSrcweir pRow = pRow->GetNext();
1573cdf0e10cSrcweir
1574cdf0e10cSrcweir if ( !pRow->GetNext() )
1575cdf0e10cSrcweir {
1576cdf0e10cSrcweir pThisCell = &pThisCell->FindStartEndOfRowSpanCell( false, true );
1577cdf0e10cSrcweir pRow = pThisCell->GetUpper();
1578cdf0e10cSrcweir }
1579cdf0e10cSrcweir }
1580cdf0e10cSrcweir
1581cdf0e10cSrcweir const SwRowFrm* pFollowRow = NULL;
1582cdf0e10cSrcweir if ( !pRow->GetNext() &&
1583cdf0e10cSrcweir NULL != ( pFollowRow = pRow->IsInSplitTableRow() ) &&
1584cdf0e10cSrcweir ( !pFollowRow->IsRowSpanLine() || nRowSpan > 1 ) )
1585cdf0e10cSrcweir pRet = lcl_FindCorrespondingCellFrm( *((SwRowFrm*)pRow), *pThisCell, *pFollowRow, true );
1586cdf0e10cSrcweir
1587cdf0e10cSrcweir return pRet;
1588cdf0e10cSrcweir }
1589cdf0e10cSrcweir
1590cdf0e10cSrcweir // VERSION OF GetPreviousCell() THAT ASSUMES THAT WE ALWAYS HAVE A FFL
GetPreviousCell() const1591cdf0e10cSrcweir SwCellFrm* SwCellFrm::GetPreviousCell() const
1592cdf0e10cSrcweir {
1593cdf0e10cSrcweir SwCellFrm* pRet = NULL;
1594cdf0e10cSrcweir
1595cdf0e10cSrcweir // NEW TABLES
1596cdf0e10cSrcweir // Covered cells do not have previous cells!
1597cdf0e10cSrcweir if ( GetLayoutRowSpan() < 1 )
1598cdf0e10cSrcweir return NULL;
1599cdf0e10cSrcweir
1600cdf0e10cSrcweir // find most upper row frame
1601cdf0e10cSrcweir const SwFrm* pRow = GetUpper();
1602cdf0e10cSrcweir while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
1603cdf0e10cSrcweir pRow = pRow->GetUpper();
1604cdf0e10cSrcweir
1605cdf0e10cSrcweir ASSERT( pRow->GetUpper() && pRow->GetUpper()->IsTabFrm(), "GetPreviousCell without Table" );
1606cdf0e10cSrcweir
1607cdf0e10cSrcweir SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1608cdf0e10cSrcweir
1609cdf0e10cSrcweir if ( pTab->IsFollow() )
1610cdf0e10cSrcweir {
1611cdf0e10cSrcweir const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1612cdf0e10cSrcweir const bool bIsInFirstLine = ( pTmp == pRow );
1613cdf0e10cSrcweir
1614cdf0e10cSrcweir if ( bIsInFirstLine )
1615cdf0e10cSrcweir {
1616cdf0e10cSrcweir SwTabFrm *pMaster = (SwTabFrm*)pTab->FindMaster();
1617cdf0e10cSrcweir if ( pMaster && pMaster->HasFollowFlowLine() )
1618cdf0e10cSrcweir {
1619cdf0e10cSrcweir SwRowFrm* pMasterRow = static_cast<SwRowFrm*>(pMaster->GetLastLower());
1620cdf0e10cSrcweir if ( pMasterRow )
1621cdf0e10cSrcweir pRet = lcl_FindCorrespondingCellFrm( *((SwRowFrm*)pRow), *this, *pMasterRow, false );
1622cdf0e10cSrcweir if ( pRet && pRet->GetTabBox()->getRowSpan() < 1 )
1623cdf0e10cSrcweir pRet = &const_cast<SwCellFrm&>(pRet->FindStartEndOfRowSpanCell( true, true ));
1624cdf0e10cSrcweir }
1625cdf0e10cSrcweir }
1626cdf0e10cSrcweir }
1627cdf0e10cSrcweir
1628cdf0e10cSrcweir return pRet;
1629cdf0e10cSrcweir }
1630cdf0e10cSrcweir
1631cdf0e10cSrcweir // --> NEW TABLES
FindStartEndOfRowSpanCell(bool bStart,bool bCurrentTableOnly) const1632cdf0e10cSrcweir const SwCellFrm& SwCellFrm::FindStartEndOfRowSpanCell( bool bStart, bool bCurrentTableOnly ) const
1633cdf0e10cSrcweir {
1634cdf0e10cSrcweir const SwCellFrm* pRet = 0;
1635cdf0e10cSrcweir
1636cdf0e10cSrcweir const SwTabFrm* pTableFrm = dynamic_cast<const SwTabFrm*>(GetUpper()->GetUpper());
1637cdf0e10cSrcweir
1638cdf0e10cSrcweir if ( !bStart && pTableFrm->IsFollow() && pTableFrm->IsInHeadline( *this ) )
1639cdf0e10cSrcweir return *this;
1640cdf0e10cSrcweir
1641cdf0e10cSrcweir ASSERT( pTableFrm &&
1642cdf0e10cSrcweir ( bStart && GetTabBox()->getRowSpan() < 1 ||
1643cdf0e10cSrcweir !bStart && GetLayoutRowSpan() > 1 ),
1644cdf0e10cSrcweir "SwCellFrm::FindStartRowSpanCell: No rowspan, no table, no cookies" )
1645cdf0e10cSrcweir
1646cdf0e10cSrcweir if ( pTableFrm )
1647cdf0e10cSrcweir {
1648cdf0e10cSrcweir const SwTable* pTable = pTableFrm->GetTable();
1649cdf0e10cSrcweir
1650cdf0e10cSrcweir sal_uInt16 nMax = USHRT_MAX;
1651cdf0e10cSrcweir if ( bCurrentTableOnly )
1652cdf0e10cSrcweir {
1653cdf0e10cSrcweir const SwFrm* pCurrentRow = GetUpper();
1654cdf0e10cSrcweir const bool bDoNotEnterHeadline = bStart && pTableFrm->IsFollow() &&
1655cdf0e10cSrcweir !pTableFrm->IsInHeadline( *pCurrentRow );
1656cdf0e10cSrcweir
1657cdf0e10cSrcweir // check how many rows we are allowed to go up or down until we reach the end of
1658cdf0e10cSrcweir // the current table frame:
1659cdf0e10cSrcweir nMax = 0;
1660cdf0e10cSrcweir while ( bStart ? pCurrentRow->GetPrev() : pCurrentRow->GetNext() )
1661cdf0e10cSrcweir {
1662cdf0e10cSrcweir if ( bStart )
1663cdf0e10cSrcweir {
1664cdf0e10cSrcweir // do not enter a repeated headline:
1665cdf0e10cSrcweir if ( bDoNotEnterHeadline && pTableFrm->IsFollow() &&
1666cdf0e10cSrcweir pTableFrm->IsInHeadline( *pCurrentRow->GetPrev() ) )
1667cdf0e10cSrcweir break;
1668cdf0e10cSrcweir
1669cdf0e10cSrcweir pCurrentRow = pCurrentRow->GetPrev();
1670cdf0e10cSrcweir }
1671cdf0e10cSrcweir else
1672cdf0e10cSrcweir pCurrentRow = pCurrentRow->GetNext();
1673cdf0e10cSrcweir
1674cdf0e10cSrcweir ++nMax;
1675cdf0e10cSrcweir }
1676cdf0e10cSrcweir }
1677cdf0e10cSrcweir
1678cdf0e10cSrcweir // By passing the nMax value for Find*OfRowSpan (in case of bCurrentTableOnly
1679cdf0e10cSrcweir // is set) we assure that we find a rMasterBox that has a SwCellFrm in
1680cdf0e10cSrcweir // the current table frame:
1681cdf0e10cSrcweir const SwTableBox& rMasterBox = bStart ?
1682cdf0e10cSrcweir GetTabBox()->FindStartOfRowSpan( *pTable, nMax ) :
1683cdf0e10cSrcweir GetTabBox()->FindEndOfRowSpan( *pTable, nMax );
1684cdf0e10cSrcweir
1685cdf0e10cSrcweir SwIterator<SwCellFrm,SwFmt> aIter( *rMasterBox.GetFrmFmt() );
1686cdf0e10cSrcweir
1687cdf0e10cSrcweir for ( SwCellFrm* pMasterCell = aIter.First(); pMasterCell; pMasterCell = aIter.Next() )
1688cdf0e10cSrcweir {
1689cdf0e10cSrcweir if ( pMasterCell->GetTabBox() == &rMasterBox )
1690cdf0e10cSrcweir {
1691cdf0e10cSrcweir const SwTabFrm* pMasterTable = static_cast<const SwTabFrm*>(pMasterCell->GetUpper()->GetUpper());
1692cdf0e10cSrcweir
1693cdf0e10cSrcweir if ( bCurrentTableOnly )
1694cdf0e10cSrcweir {
1695cdf0e10cSrcweir if ( pMasterTable == pTableFrm )
1696cdf0e10cSrcweir {
1697cdf0e10cSrcweir pRet = pMasterCell;
1698cdf0e10cSrcweir break;
1699cdf0e10cSrcweir }
1700cdf0e10cSrcweir }
1701cdf0e10cSrcweir else
1702cdf0e10cSrcweir {
1703cdf0e10cSrcweir if ( pMasterTable == pTableFrm ||
1704cdf0e10cSrcweir ( (bStart && pMasterTable->IsAnFollow(pTableFrm)) ||
1705cdf0e10cSrcweir (!bStart && pTableFrm->IsAnFollow(pMasterTable)) ) )
1706cdf0e10cSrcweir {
1707cdf0e10cSrcweir pRet = pMasterCell;
1708cdf0e10cSrcweir break;
1709cdf0e10cSrcweir }
1710cdf0e10cSrcweir }
1711cdf0e10cSrcweir }
1712cdf0e10cSrcweir }
1713cdf0e10cSrcweir }
1714cdf0e10cSrcweir
1715cdf0e10cSrcweir ASSERT( pRet, "SwCellFrm::FindStartRowSpanCell: No result" )
1716cdf0e10cSrcweir
1717cdf0e10cSrcweir return *pRet;
1718cdf0e10cSrcweir }
1719cdf0e10cSrcweir // <-- NEW TABLES
1720cdf0e10cSrcweir
IsInSplitTableRow() const1721cdf0e10cSrcweir const SwRowFrm* SwFrm::IsInSplitTableRow() const
1722cdf0e10cSrcweir {
1723cdf0e10cSrcweir ASSERT( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" )
1724cdf0e10cSrcweir
1725cdf0e10cSrcweir const SwFrm* pRow = this;
1726cdf0e10cSrcweir
1727cdf0e10cSrcweir // find most upper row frame
1728cdf0e10cSrcweir while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1729cdf0e10cSrcweir pRow = pRow->GetUpper();
1730cdf0e10cSrcweir
1731cdf0e10cSrcweir if ( !pRow ) return NULL;
1732cdf0e10cSrcweir
1733cdf0e10cSrcweir ASSERT( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" )
1734cdf0e10cSrcweir
1735cdf0e10cSrcweir const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1736cdf0e10cSrcweir // --> OD 2006-06-28 #b6443897#
1737cdf0e10cSrcweir // If most upper row frame is a headline row, the current frame
1738cdf0e10cSrcweir // can't be in a splitted table row. Thus, add corresponding condition.
1739cdf0e10cSrcweir if ( pRow->GetNext() ||
1740cdf0e10cSrcweir pTab->GetTable()->IsHeadline(
1741cdf0e10cSrcweir *(static_cast<const SwRowFrm*>(pRow)->GetTabLine()) ) ||
1742cdf0e10cSrcweir !pTab->HasFollowFlowLine() ||
1743cdf0e10cSrcweir !pTab->GetFollow() )
1744cdf0e10cSrcweir return NULL;
1745cdf0e10cSrcweir // <--
1746cdf0e10cSrcweir
1747cdf0e10cSrcweir // skip headline
1748cdf0e10cSrcweir const SwRowFrm* pFollowRow = pTab->GetFollow()->GetFirstNonHeadlineRow();
1749cdf0e10cSrcweir
1750cdf0e10cSrcweir ASSERT( pFollowRow, "SwFrm::IsInSplitTableRow() does not work" )
1751cdf0e10cSrcweir
1752cdf0e10cSrcweir return pFollowRow;
1753cdf0e10cSrcweir }
1754cdf0e10cSrcweir
IsInFollowFlowRow() const1755cdf0e10cSrcweir const SwRowFrm* SwFrm::IsInFollowFlowRow() const
1756cdf0e10cSrcweir {
1757cdf0e10cSrcweir ASSERT( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" )
1758cdf0e10cSrcweir
1759cdf0e10cSrcweir // find most upper row frame
1760cdf0e10cSrcweir const SwFrm* pRow = this;
1761cdf0e10cSrcweir while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1762cdf0e10cSrcweir pRow = pRow->GetUpper();
1763cdf0e10cSrcweir
1764cdf0e10cSrcweir if ( !pRow ) return NULL;
1765cdf0e10cSrcweir
1766cdf0e10cSrcweir ASSERT( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" )
1767cdf0e10cSrcweir
1768cdf0e10cSrcweir const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1769cdf0e10cSrcweir
1770cdf0e10cSrcweir const SwTabFrm* pMaster = pTab->IsFollow() ? pTab->FindMaster() : 0;
1771cdf0e10cSrcweir
1772cdf0e10cSrcweir if ( !pMaster || !pMaster->HasFollowFlowLine() )
1773cdf0e10cSrcweir return NULL;
1774cdf0e10cSrcweir
1775cdf0e10cSrcweir const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1776cdf0e10cSrcweir const bool bIsInFirstLine = ( pTmp == pRow );
1777cdf0e10cSrcweir
1778cdf0e10cSrcweir if ( !bIsInFirstLine )
1779cdf0e10cSrcweir return NULL;
1780cdf0e10cSrcweir
1781cdf0e10cSrcweir const SwRowFrm* pMasterRow = static_cast<const SwRowFrm*>(pMaster->GetLastLower());
1782cdf0e10cSrcweir return pMasterRow;
1783cdf0e10cSrcweir }
1784cdf0e10cSrcweir
IsInBalancedSection() const1785cdf0e10cSrcweir bool SwFrm::IsInBalancedSection() const
1786cdf0e10cSrcweir {
1787cdf0e10cSrcweir bool bRet = false;
1788cdf0e10cSrcweir
1789cdf0e10cSrcweir if ( IsInSct() )
1790cdf0e10cSrcweir {
1791cdf0e10cSrcweir const SwSectionFrm* pSectionFrm = FindSctFrm();
1792cdf0e10cSrcweir if ( pSectionFrm )
1793cdf0e10cSrcweir bRet = pSectionFrm->IsBalancedSection();
1794cdf0e10cSrcweir }
1795cdf0e10cSrcweir return bRet;
1796cdf0e10cSrcweir }
1797cdf0e10cSrcweir
1798cdf0e10cSrcweir /*
1799cdf0e10cSrcweir * SwLayoutFrm::GetLastLower()
1800cdf0e10cSrcweir */
GetLastLower() const1801cdf0e10cSrcweir const SwFrm* SwLayoutFrm::GetLastLower() const
1802cdf0e10cSrcweir {
1803cdf0e10cSrcweir const SwFrm* pRet = Lower();
1804cdf0e10cSrcweir if ( !pRet )
1805cdf0e10cSrcweir return 0;
1806cdf0e10cSrcweir while ( pRet->GetNext() )
1807cdf0e10cSrcweir pRet = pRet->GetNext();
1808cdf0e10cSrcweir return pRet;
1809cdf0e10cSrcweir }
1810