xref: /aoo41x/main/sw/source/core/layout/findfrm.cxx (revision efeef26f)
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