xref: /trunk/main/sw/source/core/layout/findfrm.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew 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 
66156b35d86SArmin Le Grand //UUUU
getSdrAllFillAttributesHelper() const66256b35d86SArmin Le Grand drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFrm::getSdrAllFillAttributesHelper() const
66356b35d86SArmin Le Grand {
66456b35d86SArmin Le Grand     if(IsCntntFrm())
66556b35d86SArmin Le Grand     {
66656b35d86SArmin Le Grand         return static_cast< const SwCntntFrm* >(this)->GetNode()->getSdrAllFillAttributesHelper();
66756b35d86SArmin Le Grand     }
66856b35d86SArmin Le Grand     else
66956b35d86SArmin Le Grand     {
67056b35d86SArmin Le Grand         return static_cast< const SwLayoutFrm* >(this)->GetFmt()->getSdrAllFillAttributesHelper();
67156b35d86SArmin Le Grand     }
67256b35d86SArmin Le Grand }
67356b35d86SArmin Le Grand 
674cdf0e10cSrcweir /*************************************************************************
675cdf0e10cSrcweir |*
676cdf0e10cSrcweir |*  SwFrm::_FindNext(), _FindPrev(), InvalidateNextPos()
677cdf0e10cSrcweir |*         _FindNextCnt() geht in Tabellen und Bereiche hineinund liefert
678cdf0e10cSrcweir |*         nur SwCntntFrms.
679cdf0e10cSrcweir |*
680cdf0e10cSrcweir |*  Beschreibung        Invalidiert die Position des Naechsten Frames.
681cdf0e10cSrcweir |*      Dies ist der direkte Nachfolger, oder bei CntntFrm's der naechste
682cdf0e10cSrcweir |*      CntntFrm der im gleichen Fluss liegt wie ich:
683cdf0e10cSrcweir |*      - Body,
684cdf0e10cSrcweir |*      - Fussnoten,
685cdf0e10cSrcweir |*      - Bei Kopf-/Fussbereichen ist die Benachrichtigung nur innerhalb des
686cdf0e10cSrcweir |*        Bereiches weiterzuleiten.
687cdf0e10cSrcweir |*      - dito fuer Flys.
688cdf0e10cSrcweir |*      - Cntnts in Tabs halten sich ausschliesslich innerhalb ihrer Zelle
689cdf0e10cSrcweir |*        auf.
690cdf0e10cSrcweir |*      - Tabellen verhalten sich prinzipiell analog zu den Cntnts
691cdf0e10cSrcweir |*      - Bereiche ebenfalls
692cdf0e10cSrcweir |*  Ersterstellung      AK 14-Feb-1991
693cdf0e10cSrcweir |*  Letzte Aenderung    AMA 10. Mar. 99
694cdf0e10cSrcweir |*
695cdf0e10cSrcweir |*************************************************************************/
696cdf0e10cSrcweir 
697cdf0e10cSrcweir // Diese Hilfsfunktion ist ein Aequivalent zur ImplGetNextCntntFrm()-Methode,
698cdf0e10cSrcweir // sie liefert allerdings neben ContentFrames auch TabFrms und SectionFrms.
lcl_NextFrm(SwFrm * pFrm)699cdf0e10cSrcweir SwFrm* lcl_NextFrm( SwFrm* pFrm )
700cdf0e10cSrcweir {
701cdf0e10cSrcweir     SwFrm *pRet = 0;
702cdf0e10cSrcweir     sal_Bool bGoingUp = sal_False;
703cdf0e10cSrcweir     do {
704cdf0e10cSrcweir         SwFrm *p = 0;
705cdf0e10cSrcweir 
706cdf0e10cSrcweir         sal_Bool bGoingFwd = sal_False;
707cdf0e10cSrcweir         sal_Bool bGoingDown = (!bGoingUp && ( 0 != (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)));
708cdf0e10cSrcweir 
709cdf0e10cSrcweir         if( !bGoingDown )
710cdf0e10cSrcweir         {
711cdf0e10cSrcweir             bGoingFwd = (0 != (p = ( pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink() : pFrm->GetNext())));
712cdf0e10cSrcweir             if ( !bGoingFwd )
713cdf0e10cSrcweir             {
714cdf0e10cSrcweir                 bGoingUp = (0 != (p = pFrm->GetUpper()));
715cdf0e10cSrcweir                 if ( !bGoingUp )
716cdf0e10cSrcweir                 {
717cdf0e10cSrcweir                     return 0;
718cdf0e10cSrcweir                 }
719cdf0e10cSrcweir             }
720cdf0e10cSrcweir         }
721cdf0e10cSrcweir         bGoingUp = !(bGoingFwd || bGoingDown);
722cdf0e10cSrcweir         pFrm = p;
723cdf0e10cSrcweir     } while ( 0 == (pRet = ( ( pFrm->IsCntntFrm() || ( !bGoingUp &&
724cdf0e10cSrcweir             ( pFrm->IsTabFrm() || pFrm->IsSctFrm() ) ) )? pFrm : 0 ) ) );
725cdf0e10cSrcweir     return pRet;
726cdf0e10cSrcweir }
727cdf0e10cSrcweir 
_FindNext()728cdf0e10cSrcweir SwFrm *SwFrm::_FindNext()
729cdf0e10cSrcweir {
730cdf0e10cSrcweir     sal_Bool bIgnoreTab = sal_False;
731cdf0e10cSrcweir     SwFrm *pThis = this;
732cdf0e10cSrcweir 
733cdf0e10cSrcweir     if ( IsTabFrm() )
734cdf0e10cSrcweir     {
735cdf0e10cSrcweir         //Der letzte Cntnt der Tabelle wird
736cdf0e10cSrcweir         //gegriffen und dessen Nachfolger geliefert. Um die Spezialbeh.
737cdf0e10cSrcweir         //Fuer Tabellen (s.u.) auszuschalten wird bIgnoreTab gesetzt.
738cdf0e10cSrcweir         if ( ((SwTabFrm*)this)->GetFollow() )
739cdf0e10cSrcweir             return ((SwTabFrm*)this)->GetFollow();
740cdf0e10cSrcweir 
741cdf0e10cSrcweir         pThis = ((SwTabFrm*)this)->FindLastCntnt();
742cdf0e10cSrcweir         if ( !pThis )
743cdf0e10cSrcweir             pThis = this;
744cdf0e10cSrcweir         bIgnoreTab = sal_True;
745cdf0e10cSrcweir     }
746cdf0e10cSrcweir     else if ( IsSctFrm() )
747cdf0e10cSrcweir     {
748cdf0e10cSrcweir         //Der letzte Cntnt des Bereichs wird gegriffen und dessen Nachfolger
749cdf0e10cSrcweir         // geliefert.
750cdf0e10cSrcweir         if ( ((SwSectionFrm*)this)->GetFollow() )
751cdf0e10cSrcweir             return ((SwSectionFrm*)this)->GetFollow();
752cdf0e10cSrcweir 
753cdf0e10cSrcweir         pThis = ((SwSectionFrm*)this)->FindLastCntnt();
754cdf0e10cSrcweir         if ( !pThis )
755cdf0e10cSrcweir             pThis = this;
756cdf0e10cSrcweir     }
757cdf0e10cSrcweir     else if ( IsCntntFrm() )
758cdf0e10cSrcweir     {
759cdf0e10cSrcweir         if( ((SwCntntFrm*)this)->GetFollow() )
760cdf0e10cSrcweir             return ((SwCntntFrm*)this)->GetFollow();
761cdf0e10cSrcweir     }
762cdf0e10cSrcweir     else if ( IsRowFrm() )
763cdf0e10cSrcweir     {
764cdf0e10cSrcweir         SwFrm* pMyUpper = GetUpper();
765cdf0e10cSrcweir         if ( pMyUpper->IsTabFrm() && ((SwTabFrm*)pMyUpper)->GetFollow() )
766cdf0e10cSrcweir             return ((SwTabFrm*)pMyUpper)->GetFollow()->GetLower();
767cdf0e10cSrcweir         else return NULL;
768cdf0e10cSrcweir     }
769cdf0e10cSrcweir     else
770cdf0e10cSrcweir         return NULL;
771cdf0e10cSrcweir 
772cdf0e10cSrcweir     SwFrm* pRet = NULL;
773cdf0e10cSrcweir     const sal_Bool bFtn  = pThis->IsInFtn();
774cdf0e10cSrcweir     if ( !bIgnoreTab && pThis->IsInTab() )
775cdf0e10cSrcweir     {
776cdf0e10cSrcweir         SwLayoutFrm *pUp = pThis->GetUpper();
777cdf0e10cSrcweir         while ( !pUp->IsCellFrm() )
778cdf0e10cSrcweir             pUp = pUp->GetUpper();
779cdf0e10cSrcweir         ASSERT( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
780cdf0e10cSrcweir         SwFrm* pNxt = ((SwCellFrm*)pUp)->GetFollowCell();
781cdf0e10cSrcweir         if ( pNxt )
782cdf0e10cSrcweir             pNxt = ((SwCellFrm*)pNxt)->ContainsCntnt();
783cdf0e10cSrcweir         if ( !pNxt )
784cdf0e10cSrcweir         {
785cdf0e10cSrcweir             pNxt = lcl_NextFrm( pThis );
786cdf0e10cSrcweir             if ( pUp->IsAnLower( pNxt ) )
787cdf0e10cSrcweir                 pRet = pNxt;
788cdf0e10cSrcweir         }
789cdf0e10cSrcweir         else
790cdf0e10cSrcweir             pRet = pNxt;
791cdf0e10cSrcweir     }
792cdf0e10cSrcweir     else
793cdf0e10cSrcweir     {
794cdf0e10cSrcweir         const sal_Bool bBody = pThis->IsInDocBody();
795cdf0e10cSrcweir         SwFrm *pNxtCnt = lcl_NextFrm( pThis );
796cdf0e10cSrcweir         if ( pNxtCnt )
797cdf0e10cSrcweir         {
798cdf0e10cSrcweir             if ( bBody || bFtn )
799cdf0e10cSrcweir             {
800cdf0e10cSrcweir                 while ( pNxtCnt )
801cdf0e10cSrcweir                 {
802cdf0e10cSrcweir                     // OD 02.04.2003 #108446# - check for endnote, only if found
803cdf0e10cSrcweir                     // next content isn't contained in a section, that collect its
804cdf0e10cSrcweir                     // endnotes at its end.
805cdf0e10cSrcweir                     bool bEndn = IsInSct() && !IsSctFrm() &&
806cdf0e10cSrcweir                                  ( !pNxtCnt->IsInSct() ||
807cdf0e10cSrcweir                                    !pNxtCnt->FindSctFrm()->IsEndnAtEnd()
808cdf0e10cSrcweir                                  );
809cdf0e10cSrcweir                     if ( ( bBody && pNxtCnt->IsInDocBody() ) ||
810cdf0e10cSrcweir                          ( pNxtCnt->IsInFtn() &&
811cdf0e10cSrcweir                            ( bFtn ||
812cdf0e10cSrcweir                              ( bEndn && pNxtCnt->FindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
813cdf0e10cSrcweir                            )
814cdf0e10cSrcweir                          )
815cdf0e10cSrcweir                        )
816cdf0e10cSrcweir                     {
817cdf0e10cSrcweir                         pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
818cdf0e10cSrcweir                                                     : (SwFrm*)pNxtCnt;
819cdf0e10cSrcweir                         break;
820cdf0e10cSrcweir                     }
821cdf0e10cSrcweir                     pNxtCnt = lcl_NextFrm( pNxtCnt );
822cdf0e10cSrcweir                 }
823cdf0e10cSrcweir             }
824cdf0e10cSrcweir             else if ( pThis->IsInFly() )
825cdf0e10cSrcweir             {
826cdf0e10cSrcweir                 pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
827cdf0e10cSrcweir                                             : (SwFrm*)pNxtCnt;
828cdf0e10cSrcweir             }
829cdf0e10cSrcweir             else    //Fuss-/oder Kopfbereich
830cdf0e10cSrcweir             {
831cdf0e10cSrcweir                 const SwFrm *pUp = pThis->GetUpper();
832cdf0e10cSrcweir                 const SwFrm *pCntUp = pNxtCnt->GetUpper();
833cdf0e10cSrcweir                 while ( pUp && pUp->GetUpper() &&
834cdf0e10cSrcweir                         !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
835cdf0e10cSrcweir                     pUp = pUp->GetUpper();
836cdf0e10cSrcweir                 while ( pCntUp && pCntUp->GetUpper() &&
837cdf0e10cSrcweir                         !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
838cdf0e10cSrcweir                     pCntUp = pCntUp->GetUpper();
839cdf0e10cSrcweir                 if ( pCntUp == pUp )
840cdf0e10cSrcweir                 {
841cdf0e10cSrcweir                     pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
842cdf0e10cSrcweir                                                 : (SwFrm*)pNxtCnt;
843cdf0e10cSrcweir                 }
844cdf0e10cSrcweir             }
845cdf0e10cSrcweir         }
846cdf0e10cSrcweir     }
847cdf0e10cSrcweir     if( pRet && pRet->IsInSct() )
848cdf0e10cSrcweir     {
849cdf0e10cSrcweir         SwSectionFrm* pSct = pRet->FindSctFrm();
850cdf0e10cSrcweir         //Fussnoten in spaltigen Rahmen duerfen nicht den Bereich
851cdf0e10cSrcweir         //liefern, der die Fussnoten umfasst
852cdf0e10cSrcweir         if( !pSct->IsAnLower( this ) &&
853cdf0e10cSrcweir             (!bFtn || pSct->IsInFtn() ) )
854cdf0e10cSrcweir             return pSct;
855cdf0e10cSrcweir     }
856cdf0e10cSrcweir     return pRet;
857cdf0e10cSrcweir }
858cdf0e10cSrcweir 
859cdf0e10cSrcweir // --> OD 2005-12-01 #i27138# - add parameter <_bInSameFtn>
_FindNextCnt(const bool _bInSameFtn)860cdf0e10cSrcweir SwCntntFrm *SwFrm::_FindNextCnt( const bool _bInSameFtn )
861cdf0e10cSrcweir {
862cdf0e10cSrcweir     SwFrm *pThis = this;
863cdf0e10cSrcweir 
864cdf0e10cSrcweir     if ( IsTabFrm() )
865cdf0e10cSrcweir     {
866cdf0e10cSrcweir         if ( ((SwTabFrm*)this)->GetFollow() )
867cdf0e10cSrcweir         {
868cdf0e10cSrcweir             pThis = ((SwTabFrm*)this)->GetFollow()->ContainsCntnt();
869cdf0e10cSrcweir             if( pThis )
870cdf0e10cSrcweir                 return (SwCntntFrm*)pThis;
871cdf0e10cSrcweir         }
872cdf0e10cSrcweir         pThis = ((SwTabFrm*)this)->FindLastCntnt();
873cdf0e10cSrcweir         if ( !pThis )
874cdf0e10cSrcweir             return 0;
875cdf0e10cSrcweir     }
876cdf0e10cSrcweir     else if ( IsSctFrm() )
877cdf0e10cSrcweir     {
878cdf0e10cSrcweir         if ( ((SwSectionFrm*)this)->GetFollow() )
879cdf0e10cSrcweir         {
880cdf0e10cSrcweir             pThis = ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
881cdf0e10cSrcweir             if( pThis )
882cdf0e10cSrcweir                 return (SwCntntFrm*)pThis;
883cdf0e10cSrcweir         }
884cdf0e10cSrcweir         pThis = ((SwSectionFrm*)this)->FindLastCntnt();
885cdf0e10cSrcweir         if ( !pThis )
886cdf0e10cSrcweir             return 0;
887cdf0e10cSrcweir     }
888cdf0e10cSrcweir     else if ( IsCntntFrm() && ((SwCntntFrm*)this)->GetFollow() )
889cdf0e10cSrcweir         return ((SwCntntFrm*)this)->GetFollow();
890cdf0e10cSrcweir 
891cdf0e10cSrcweir     if ( pThis->IsCntntFrm() )
892cdf0e10cSrcweir     {
893cdf0e10cSrcweir         const sal_Bool bBody = pThis->IsInDocBody();
894cdf0e10cSrcweir         const sal_Bool bFtn  = pThis->IsInFtn();
895cdf0e10cSrcweir         SwCntntFrm *pNxtCnt = ((SwCntntFrm*)pThis)->GetNextCntntFrm();
896cdf0e10cSrcweir         if ( pNxtCnt )
897cdf0e10cSrcweir         {
898cdf0e10cSrcweir             // --> OD 2005-12-01 #i27138#
899cdf0e10cSrcweir             if ( bBody || ( bFtn && !_bInSameFtn ) )
900cdf0e10cSrcweir             // <--
901cdf0e10cSrcweir             {
902cdf0e10cSrcweir                 // handling for environments 'footnotes' and 'document body frames':
903cdf0e10cSrcweir                 while ( pNxtCnt )
904cdf0e10cSrcweir                 {
905cdf0e10cSrcweir                     if ( (bBody && pNxtCnt->IsInDocBody()) ||
906cdf0e10cSrcweir                          (bFtn  && pNxtCnt->IsInFtn()) )
907cdf0e10cSrcweir                         return pNxtCnt;
908cdf0e10cSrcweir                     pNxtCnt = pNxtCnt->GetNextCntntFrm();
909cdf0e10cSrcweir                 }
910cdf0e10cSrcweir             }
911cdf0e10cSrcweir             // --> OD 2005-12-01 #i27138#
912cdf0e10cSrcweir             else if ( bFtn && _bInSameFtn )
913cdf0e10cSrcweir             {
914cdf0e10cSrcweir                 // handling for environments 'each footnote':
915cdf0e10cSrcweir                 // Assure that found next content frame belongs to the same footnotes
916cdf0e10cSrcweir                 const SwFtnFrm* pFtnFrmOfNext( pNxtCnt->FindFtnFrm() );
917cdf0e10cSrcweir                 const SwFtnFrm* pFtnFrmOfCurr( pThis->FindFtnFrm() );
918cdf0e10cSrcweir                 ASSERT( pFtnFrmOfCurr,
919cdf0e10cSrcweir                         "<SwFrm::_FindNextCnt() - unknown layout situation: current frame has to have an upper footnote frame." );
920cdf0e10cSrcweir                 if ( pFtnFrmOfNext == pFtnFrmOfCurr )
921cdf0e10cSrcweir                 {
922cdf0e10cSrcweir                     return pNxtCnt;
923cdf0e10cSrcweir                 }
924cdf0e10cSrcweir                 else if ( pFtnFrmOfCurr->GetFollow() )
925cdf0e10cSrcweir                 {
926cdf0e10cSrcweir                     // next content frame has to be the first content frame
927cdf0e10cSrcweir                     // in the follow footnote, which contains a content frame.
928cdf0e10cSrcweir                     SwFtnFrm* pFollowFtnFrmOfCurr(
929cdf0e10cSrcweir                                         const_cast<SwFtnFrm*>(pFtnFrmOfCurr) );
930cdf0e10cSrcweir                     pNxtCnt = 0L;
931cdf0e10cSrcweir                     do {
932cdf0e10cSrcweir                         pFollowFtnFrmOfCurr = pFollowFtnFrmOfCurr->GetFollow();
933cdf0e10cSrcweir                         pNxtCnt = pFollowFtnFrmOfCurr->ContainsCntnt();
934cdf0e10cSrcweir                     } while ( !pNxtCnt && pFollowFtnFrmOfCurr->GetFollow() );
935cdf0e10cSrcweir                     return pNxtCnt;
936cdf0e10cSrcweir                 }
937cdf0e10cSrcweir                 else
938cdf0e10cSrcweir                 {
939cdf0e10cSrcweir                     // current content frame is the last content frame in the
940cdf0e10cSrcweir                     // footnote - no next content frame exists.
941cdf0e10cSrcweir                     return 0L;
942cdf0e10cSrcweir                 }
943cdf0e10cSrcweir             }
944cdf0e10cSrcweir             // <--
945cdf0e10cSrcweir             else if ( pThis->IsInFly() )
946cdf0e10cSrcweir                 // handling for environments 'unlinked fly frame' and
947cdf0e10cSrcweir                 // 'group of linked fly frames':
948cdf0e10cSrcweir                 return pNxtCnt;
949cdf0e10cSrcweir             else
950cdf0e10cSrcweir             {
951cdf0e10cSrcweir                 // handling for environments 'page header' and 'page footer':
952cdf0e10cSrcweir                 const SwFrm *pUp = pThis->GetUpper();
953cdf0e10cSrcweir                 const SwFrm *pCntUp = pNxtCnt->GetUpper();
954cdf0e10cSrcweir                 while ( pUp && pUp->GetUpper() &&
955cdf0e10cSrcweir                         !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
956cdf0e10cSrcweir                     pUp = pUp->GetUpper();
957cdf0e10cSrcweir                 while ( pCntUp && pCntUp->GetUpper() &&
958cdf0e10cSrcweir                         !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
959cdf0e10cSrcweir                     pCntUp = pCntUp->GetUpper();
960cdf0e10cSrcweir                 if ( pCntUp == pUp )
961cdf0e10cSrcweir                     return pNxtCnt;
962cdf0e10cSrcweir             }
963cdf0e10cSrcweir         }
964cdf0e10cSrcweir     }
965cdf0e10cSrcweir     return 0;
966cdf0e10cSrcweir }
967cdf0e10cSrcweir 
968cdf0e10cSrcweir /** method to determine previous content frame in the same environment
969cdf0e10cSrcweir     for a flow frame (content frame, table frame, section frame)
970cdf0e10cSrcweir 
971cdf0e10cSrcweir     OD 2005-11-30 #i27138#
972cdf0e10cSrcweir 
973cdf0e10cSrcweir     @author OD
974cdf0e10cSrcweir */
_FindPrevCnt(const bool _bInSameFtn)975cdf0e10cSrcweir SwCntntFrm* SwFrm::_FindPrevCnt( const bool _bInSameFtn )
976cdf0e10cSrcweir {
977cdf0e10cSrcweir     if ( !IsFlowFrm() )
978cdf0e10cSrcweir     {
979cdf0e10cSrcweir         // nothing to do, if current frame isn't a flow frame.
980cdf0e10cSrcweir         return 0L;
981cdf0e10cSrcweir     }
982cdf0e10cSrcweir 
983cdf0e10cSrcweir     SwCntntFrm* pPrevCntntFrm( 0L );
984cdf0e10cSrcweir 
985cdf0e10cSrcweir     // Because method <SwCntntFrm::GetPrevCntntFrm()> is used to travel
986cdf0e10cSrcweir     // through the layout, a content frame, at which the travel starts, is needed.
987cdf0e10cSrcweir     SwCntntFrm* pCurrCntntFrm = dynamic_cast<SwCntntFrm*>(this);
988cdf0e10cSrcweir 
989cdf0e10cSrcweir     // perform shortcut, if current frame is a follow, and
990cdf0e10cSrcweir     // determine <pCurrCntntFrm>, if current frame is a table or section frame
991cdf0e10cSrcweir     if ( pCurrCntntFrm && pCurrCntntFrm->IsFollow() )
992cdf0e10cSrcweir     {
993cdf0e10cSrcweir         // previous content frame is its master content frame
994cdf0e10cSrcweir         pPrevCntntFrm = pCurrCntntFrm->FindMaster();
995cdf0e10cSrcweir     }
996cdf0e10cSrcweir     else if ( IsTabFrm() )
997cdf0e10cSrcweir     {
998cdf0e10cSrcweir         SwTabFrm* pTabFrm( static_cast<SwTabFrm*>(this) );
999cdf0e10cSrcweir         if ( pTabFrm->IsFollow() )
1000cdf0e10cSrcweir         {
1001cdf0e10cSrcweir             // previous content frame is the last content of its master table frame
1002cdf0e10cSrcweir             pPrevCntntFrm = pTabFrm->FindMaster()->FindLastCntnt();
1003cdf0e10cSrcweir         }
1004cdf0e10cSrcweir         else
1005cdf0e10cSrcweir         {
1006cdf0e10cSrcweir             // start content frame for the search is the first content frame of
1007cdf0e10cSrcweir             // the table frame.
1008cdf0e10cSrcweir             pCurrCntntFrm = pTabFrm->ContainsCntnt();
1009cdf0e10cSrcweir         }
1010cdf0e10cSrcweir     }
1011cdf0e10cSrcweir     else if ( IsSctFrm() )
1012cdf0e10cSrcweir     {
1013cdf0e10cSrcweir         SwSectionFrm* pSectFrm( static_cast<SwSectionFrm*>(this) );
1014cdf0e10cSrcweir         if ( pSectFrm->IsFollow() )
1015cdf0e10cSrcweir         {
1016cdf0e10cSrcweir             // previous content frame is the last content of its master section frame
1017cdf0e10cSrcweir             pPrevCntntFrm = pSectFrm->FindMaster()->FindLastCntnt();
1018cdf0e10cSrcweir         }
1019cdf0e10cSrcweir         else
1020cdf0e10cSrcweir         {
1021cdf0e10cSrcweir             // start content frame for the search is the first content frame of
1022cdf0e10cSrcweir             // the section frame.
1023cdf0e10cSrcweir             pCurrCntntFrm = pSectFrm->ContainsCntnt();
1024cdf0e10cSrcweir         }
1025cdf0e10cSrcweir     }
1026cdf0e10cSrcweir 
1027cdf0e10cSrcweir     // search for next content frame, depending on the environment, in which
1028cdf0e10cSrcweir     // the current frame is in.
1029cdf0e10cSrcweir     if ( !pPrevCntntFrm && pCurrCntntFrm )
1030cdf0e10cSrcweir     {
1031cdf0e10cSrcweir         pPrevCntntFrm = pCurrCntntFrm->GetPrevCntntFrm();
1032cdf0e10cSrcweir         if ( pPrevCntntFrm )
1033cdf0e10cSrcweir         {
1034cdf0e10cSrcweir             if ( pCurrCntntFrm->IsInFly() )
1035cdf0e10cSrcweir             {
1036cdf0e10cSrcweir                 // handling for environments 'unlinked fly frame' and
1037cdf0e10cSrcweir                 // 'group of linked fly frames':
1038cdf0e10cSrcweir                 // Nothing to do, <pPrevCntntFrm> is the one
1039cdf0e10cSrcweir             }
1040cdf0e10cSrcweir             else
1041cdf0e10cSrcweir             {
1042cdf0e10cSrcweir                 const bool bInDocBody = pCurrCntntFrm->IsInDocBody();
1043cdf0e10cSrcweir                 const bool bInFtn  = pCurrCntntFrm->IsInFtn();
1044cdf0e10cSrcweir                 if ( bInDocBody || ( bInFtn && !_bInSameFtn ) )
1045cdf0e10cSrcweir                 {
1046cdf0e10cSrcweir                     // handling for environments 'footnotes' and 'document body frames':
1047cdf0e10cSrcweir                     // Assure that found previous frame is also in one of these
1048cdf0e10cSrcweir                     // environments. Otherwise, travel further
1049cdf0e10cSrcweir                     while ( pPrevCntntFrm )
1050cdf0e10cSrcweir                     {
1051cdf0e10cSrcweir                         if ( ( bInDocBody && pPrevCntntFrm->IsInDocBody() ) ||
1052cdf0e10cSrcweir                              ( bInFtn && pPrevCntntFrm->IsInFtn() ) )
1053cdf0e10cSrcweir                         {
1054cdf0e10cSrcweir                             break;
1055cdf0e10cSrcweir                         }
1056cdf0e10cSrcweir                         pPrevCntntFrm = pPrevCntntFrm->GetPrevCntntFrm();
1057cdf0e10cSrcweir                     }
1058cdf0e10cSrcweir                 }
1059cdf0e10cSrcweir                 else if ( bInFtn && _bInSameFtn )
1060cdf0e10cSrcweir                 {
1061cdf0e10cSrcweir                     // handling for environments 'each footnote':
1062cdf0e10cSrcweir                     // Assure that found next content frame belongs to the same footnotes
1063cdf0e10cSrcweir                     const SwFtnFrm* pFtnFrmOfPrev( pPrevCntntFrm->FindFtnFrm() );
1064cdf0e10cSrcweir                     const SwFtnFrm* pFtnFrmOfCurr( pCurrCntntFrm->FindFtnFrm() );
1065cdf0e10cSrcweir                     if ( pFtnFrmOfPrev != pFtnFrmOfCurr )
1066cdf0e10cSrcweir                     {
1067cdf0e10cSrcweir                         if ( pFtnFrmOfCurr->GetMaster() )
1068cdf0e10cSrcweir                         {
1069cdf0e10cSrcweir                             SwFtnFrm* pMasterFtnFrmOfCurr(
1070cdf0e10cSrcweir                                         const_cast<SwFtnFrm*>(pFtnFrmOfCurr) );
1071cdf0e10cSrcweir                             pPrevCntntFrm = 0L;
1072cdf0e10cSrcweir                             // --> OD 2007-07-05 #146872#
1073cdf0e10cSrcweir                             // correct wrong loop-condition
1074cdf0e10cSrcweir                             do {
1075cdf0e10cSrcweir                                 pMasterFtnFrmOfCurr = pMasterFtnFrmOfCurr->GetMaster();
1076cdf0e10cSrcweir                                 pPrevCntntFrm = pMasterFtnFrmOfCurr->FindLastCntnt();
1077cdf0e10cSrcweir                             } while ( !pPrevCntntFrm &&
1078cdf0e10cSrcweir                                       pMasterFtnFrmOfCurr->GetMaster() );
1079cdf0e10cSrcweir                             // <--
1080cdf0e10cSrcweir                         }
1081cdf0e10cSrcweir                         else
1082cdf0e10cSrcweir                         {
1083cdf0e10cSrcweir                             // current content frame is the first content in the
1084cdf0e10cSrcweir                             // footnote - no previous content exists.
1085*6bcc9fe0Smseidel                             pPrevCntntFrm = 0L;
1086cdf0e10cSrcweir                         }
1087cdf0e10cSrcweir                     }
1088cdf0e10cSrcweir                 }
1089cdf0e10cSrcweir                 else
1090cdf0e10cSrcweir                 {
1091cdf0e10cSrcweir                     // handling for environments 'page header' and 'page footer':
1092cdf0e10cSrcweir                     // Assure that found previous frame is also in the same
1093cdf0e10cSrcweir                     // page header respectively page footer as <pCurrCntntFrm>
1094cdf0e10cSrcweir                     // Note: At this point its clear, that <pCurrCntntFrm> has
1095cdf0e10cSrcweir                     //       to be inside a page header or page footer and that
1096cdf0e10cSrcweir                     //       neither <pCurrCntntFrm> nor <pPrevCntntFrm> are
1097cdf0e10cSrcweir                     //       inside a fly frame.
1098cdf0e10cSrcweir                     //       Thus, method <FindFooterOrHeader()> can be used.
1099cdf0e10cSrcweir                     ASSERT( pCurrCntntFrm->FindFooterOrHeader(),
1100cdf0e10cSrcweir                             "<SwFrm::_FindPrevCnt()> - unknown layout situation: current frame should be in page header or page footer" );
1101cdf0e10cSrcweir                     ASSERT( !pPrevCntntFrm->IsInFly(),
1102cdf0e10cSrcweir                             "<SwFrm::_FindPrevCnt()> - unknown layout situation: found previous frame should *not* be inside a fly frame." );
1103cdf0e10cSrcweir                     if ( pPrevCntntFrm->FindFooterOrHeader() !=
1104cdf0e10cSrcweir                                             pCurrCntntFrm->FindFooterOrHeader() )
1105cdf0e10cSrcweir                     {
1106cdf0e10cSrcweir                         pPrevCntntFrm = 0L;
1107cdf0e10cSrcweir                     }
1108cdf0e10cSrcweir                 }
1109cdf0e10cSrcweir             }
1110cdf0e10cSrcweir         }
1111cdf0e10cSrcweir     }
1112cdf0e10cSrcweir 
1113cdf0e10cSrcweir     return pPrevCntntFrm;
1114cdf0e10cSrcweir }
1115cdf0e10cSrcweir 
_FindPrev()1116cdf0e10cSrcweir SwFrm *SwFrm::_FindPrev()
1117cdf0e10cSrcweir {
1118cdf0e10cSrcweir     sal_Bool bIgnoreTab = sal_False;
1119cdf0e10cSrcweir     SwFrm *pThis = this;
1120cdf0e10cSrcweir 
1121cdf0e10cSrcweir     if ( IsTabFrm() )
1122cdf0e10cSrcweir     {
1123cdf0e10cSrcweir         //Der erste Cntnt der Tabelle wird
1124cdf0e10cSrcweir         //gegriffen und dessen Vorgaenger geliefert. Um die Spezialbeh.
1125cdf0e10cSrcweir         //Fuer Tabellen (s.u.) auszuschalten wird bIgnoreTab gesetzt.
1126cdf0e10cSrcweir         if ( ((SwTabFrm*)this)->IsFollow() )
1127cdf0e10cSrcweir             return ((SwTabFrm*)this)->FindMaster();
1128cdf0e10cSrcweir         else
1129cdf0e10cSrcweir             pThis = ((SwTabFrm*)this)->ContainsCntnt();
1130cdf0e10cSrcweir         bIgnoreTab = sal_True;
1131cdf0e10cSrcweir     }
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir     if ( pThis && pThis->IsCntntFrm() )
1134cdf0e10cSrcweir     {
1135cdf0e10cSrcweir         SwCntntFrm *pPrvCnt = ((SwCntntFrm*)pThis)->GetPrevCntntFrm();
1136cdf0e10cSrcweir         if( !pPrvCnt )
1137cdf0e10cSrcweir             return 0;
1138cdf0e10cSrcweir         if ( !bIgnoreTab && pThis->IsInTab() )
1139cdf0e10cSrcweir         {
1140cdf0e10cSrcweir             SwLayoutFrm *pUp = pThis->GetUpper();
1141cdf0e10cSrcweir             while ( !pUp->IsCellFrm() )
1142cdf0e10cSrcweir                 pUp = pUp->GetUpper();
1143cdf0e10cSrcweir             ASSERT( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
1144cdf0e10cSrcweir             if ( pUp->IsAnLower( pPrvCnt ) )
1145cdf0e10cSrcweir                 return pPrvCnt;
1146cdf0e10cSrcweir         }
1147cdf0e10cSrcweir         else
1148cdf0e10cSrcweir         {
1149cdf0e10cSrcweir             SwFrm* pRet;
1150cdf0e10cSrcweir             const sal_Bool bBody = pThis->IsInDocBody();
1151cdf0e10cSrcweir             const sal_Bool bFtn  = bBody ? sal_False : pThis->IsInFtn();
1152cdf0e10cSrcweir             if ( bBody || bFtn )
1153cdf0e10cSrcweir             {
1154cdf0e10cSrcweir                 while ( pPrvCnt )
1155cdf0e10cSrcweir                 {
1156cdf0e10cSrcweir                     if ( (bBody && pPrvCnt->IsInDocBody()) ||
1157cdf0e10cSrcweir                             (bFtn   && pPrvCnt->IsInFtn()) )
1158cdf0e10cSrcweir                     {
1159cdf0e10cSrcweir                         pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1160cdf0e10cSrcweir                                                   : (SwFrm*)pPrvCnt;
1161cdf0e10cSrcweir                         return pRet;
1162cdf0e10cSrcweir                     }
1163cdf0e10cSrcweir                     pPrvCnt = pPrvCnt->GetPrevCntntFrm();
1164cdf0e10cSrcweir                 }
1165cdf0e10cSrcweir             }
1166cdf0e10cSrcweir             else if ( pThis->IsInFly() )
1167cdf0e10cSrcweir             {
1168cdf0e10cSrcweir                 pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1169cdf0e10cSrcweir                                             : (SwFrm*)pPrvCnt;
1170cdf0e10cSrcweir                 return pRet;
1171cdf0e10cSrcweir             }
1172cdf0e10cSrcweir             else    //Fuss-/oder Kopfbereich oder Fly
1173cdf0e10cSrcweir             {
1174cdf0e10cSrcweir                 const SwFrm *pUp = pThis->GetUpper();
1175cdf0e10cSrcweir                 const SwFrm *pCntUp = pPrvCnt->GetUpper();
1176cdf0e10cSrcweir                 while ( pUp && pUp->GetUpper() &&
1177cdf0e10cSrcweir                         !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
1178cdf0e10cSrcweir                     pUp = pUp->GetUpper();
1179cdf0e10cSrcweir                 while ( pCntUp && pCntUp->GetUpper() )
1180cdf0e10cSrcweir                     pCntUp = pCntUp->GetUpper();
1181cdf0e10cSrcweir                 if ( pCntUp == pUp )
1182cdf0e10cSrcweir                 {
1183cdf0e10cSrcweir                     pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1184cdf0e10cSrcweir                                                 : (SwFrm*)pPrvCnt;
1185cdf0e10cSrcweir                     return pRet;
1186cdf0e10cSrcweir                 }
1187cdf0e10cSrcweir             }
1188cdf0e10cSrcweir         }
1189cdf0e10cSrcweir     }
1190cdf0e10cSrcweir     return 0;
1191cdf0e10cSrcweir }
1192cdf0e10cSrcweir 
ImplInvalidateNextPos(sal_Bool bNoFtn)1193cdf0e10cSrcweir void SwFrm::ImplInvalidateNextPos( sal_Bool bNoFtn )
1194cdf0e10cSrcweir {
1195cdf0e10cSrcweir     SwFrm *pFrm;
1196cdf0e10cSrcweir     if ( 0 != (pFrm = _FindNext()) )
1197cdf0e10cSrcweir     {
1198cdf0e10cSrcweir         if( pFrm->IsSctFrm() )
1199cdf0e10cSrcweir         {
1200cdf0e10cSrcweir             while( pFrm && pFrm->IsSctFrm() )
1201cdf0e10cSrcweir             {
1202cdf0e10cSrcweir                 if( ((SwSectionFrm*)pFrm)->GetSection() )
1203cdf0e10cSrcweir                 {
1204cdf0e10cSrcweir                     SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
1205cdf0e10cSrcweir                     if( pTmp )
1206cdf0e10cSrcweir                         pTmp->InvalidatePos();
1207cdf0e10cSrcweir                     else if( !bNoFtn )
1208cdf0e10cSrcweir                         ((SwSectionFrm*)pFrm)->InvalidateFtnPos();
1209cdf0e10cSrcweir                     if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
1210cdf0e10cSrcweir                         pFrm->InvalidatePos();
1211cdf0e10cSrcweir                     return;
1212cdf0e10cSrcweir                 }
1213cdf0e10cSrcweir                 pFrm = pFrm->FindNext();
1214cdf0e10cSrcweir             }
1215cdf0e10cSrcweir             if( pFrm )
1216cdf0e10cSrcweir             {
1217cdf0e10cSrcweir                 if ( pFrm->IsSctFrm())
1218cdf0e10cSrcweir                 { // Damit der Inhalt eines Bereichs die Chance erhaelt,
1219cdf0e10cSrcweir                   // die Seite zu wechseln, muss er ebenfalls invalidiert werden.
1220cdf0e10cSrcweir                     SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
1221cdf0e10cSrcweir                     if( pTmp )
1222cdf0e10cSrcweir                         pTmp->InvalidatePos();
1223cdf0e10cSrcweir                     if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
1224cdf0e10cSrcweir                         pFrm->InvalidatePos();
1225cdf0e10cSrcweir                 }
1226cdf0e10cSrcweir                 else
1227cdf0e10cSrcweir                     pFrm->InvalidatePos();
1228cdf0e10cSrcweir             }
1229cdf0e10cSrcweir         }
1230cdf0e10cSrcweir         else
1231cdf0e10cSrcweir             pFrm->InvalidatePos();
1232cdf0e10cSrcweir     }
1233cdf0e10cSrcweir }
1234cdf0e10cSrcweir 
1235cdf0e10cSrcweir /** method to invalidate printing area of next frame
1236cdf0e10cSrcweir 
1237cdf0e10cSrcweir     OD 09.01.2004 #i11859#
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir     @author OD
1240cdf0e10cSrcweir 
1241cdf0e10cSrcweir     FME 2004-04-19 #i27145# Moved function from SwTxtFrm to SwFrm
1242cdf0e10cSrcweir */
InvalidateNextPrtArea()1243cdf0e10cSrcweir void SwFrm::InvalidateNextPrtArea()
1244cdf0e10cSrcweir {
1245cdf0e10cSrcweir     // determine next frame
1246cdf0e10cSrcweir     SwFrm* pNextFrm = FindNext();
1247cdf0e10cSrcweir     // skip empty section frames and hidden text frames
1248cdf0e10cSrcweir     {
1249cdf0e10cSrcweir         while ( pNextFrm &&
1250cdf0e10cSrcweir                 ( ( pNextFrm->IsSctFrm() &&
1251cdf0e10cSrcweir                     !static_cast<SwSectionFrm*>(pNextFrm)->GetSection() ) ||
1252cdf0e10cSrcweir                   ( pNextFrm->IsTxtFrm() &&
1253cdf0e10cSrcweir                     static_cast<SwTxtFrm*>(pNextFrm)->IsHiddenNow() ) ) )
1254cdf0e10cSrcweir         {
1255cdf0e10cSrcweir             pNextFrm = pNextFrm->FindNext();
1256cdf0e10cSrcweir         }
1257cdf0e10cSrcweir     }
1258cdf0e10cSrcweir 
1259cdf0e10cSrcweir     // Invalidate printing area of found next frame
1260cdf0e10cSrcweir     if ( pNextFrm )
1261cdf0e10cSrcweir     {
1262cdf0e10cSrcweir         if ( pNextFrm->IsSctFrm() )
1263cdf0e10cSrcweir         {
1264cdf0e10cSrcweir             // Invalidate printing area of found section frame, if
1265cdf0e10cSrcweir             // (1) this text frame isn't in a section OR
1266cdf0e10cSrcweir             // (2) found section frame isn't a follow of the section frame this
1267cdf0e10cSrcweir             //     text frame is in.
1268cdf0e10cSrcweir             if ( !IsInSct() || FindSctFrm()->GetFollow() != pNextFrm )
1269cdf0e10cSrcweir             {
1270cdf0e10cSrcweir                 pNextFrm->InvalidatePrt();
1271cdf0e10cSrcweir             }
1272cdf0e10cSrcweir 
1273cdf0e10cSrcweir             // Invalidate printing area of first content in found section.
1274cdf0e10cSrcweir             SwFrm* pFstCntntOfSctFrm =
1275cdf0e10cSrcweir                     static_cast<SwSectionFrm*>(pNextFrm)->ContainsAny();
1276cdf0e10cSrcweir             if ( pFstCntntOfSctFrm )
1277cdf0e10cSrcweir             {
1278cdf0e10cSrcweir                 pFstCntntOfSctFrm->InvalidatePrt();
1279cdf0e10cSrcweir             }
1280cdf0e10cSrcweir         }
1281cdf0e10cSrcweir         else
1282cdf0e10cSrcweir         {
1283cdf0e10cSrcweir             pNextFrm->InvalidatePrt();
1284cdf0e10cSrcweir         }
1285cdf0e10cSrcweir     }
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir 
1288cdf0e10cSrcweir /*************************************************************************
1289cdf0e10cSrcweir |*
1290cdf0e10cSrcweir |*    lcl_IsInColSect()
1291cdf0e10cSrcweir |*      liefert nur sal_True, wenn der Frame _direkt_ in einem spaltigen Bereich steht,
1292cdf0e10cSrcweir |*      nicht etwa, wenn er in einer Tabelle steht, die in einem spaltigen Bereich ist.
1293cdf0e10cSrcweir |*
1294cdf0e10cSrcweir |*************************************************************************/
1295cdf0e10cSrcweir 
lcl_IsInColSct(const SwFrm * pUp)1296cdf0e10cSrcweir sal_Bool lcl_IsInColSct( const SwFrm *pUp )
1297cdf0e10cSrcweir {
1298cdf0e10cSrcweir     sal_Bool bRet = sal_False;
1299cdf0e10cSrcweir     while( pUp )
1300cdf0e10cSrcweir     {
1301cdf0e10cSrcweir         if( pUp->IsColumnFrm() )
1302cdf0e10cSrcweir             bRet = sal_True;
1303cdf0e10cSrcweir         else if( pUp->IsSctFrm() )
1304cdf0e10cSrcweir             return bRet;
1305cdf0e10cSrcweir         else if( pUp->IsTabFrm() )
1306cdf0e10cSrcweir             return sal_False;
1307cdf0e10cSrcweir         pUp = pUp->GetUpper();
1308cdf0e10cSrcweir     }
1309cdf0e10cSrcweir     return sal_False;
1310cdf0e10cSrcweir }
1311cdf0e10cSrcweir 
1312cdf0e10cSrcweir /*************************************************************************
1313cdf0e10cSrcweir |*
1314cdf0e10cSrcweir |*    SwFrm::IsMoveable();
1315cdf0e10cSrcweir |*
1316cdf0e10cSrcweir |*    Ersterstellung    MA 09. Mar. 93
1317cdf0e10cSrcweir |*    Letzte Aenderung  MA 05. May. 95
1318cdf0e10cSrcweir |*
1319cdf0e10cSrcweir |*************************************************************************/
1320cdf0e10cSrcweir /** determine, if frame is moveable in given environment
1321cdf0e10cSrcweir 
1322cdf0e10cSrcweir     OD 08.08.2003 #110978#
1323cdf0e10cSrcweir     method replaced 'old' method <sal_Bool IsMoveable() const>.
1324cdf0e10cSrcweir     Determines, if frame is moveable in given environment. if no environment
1325cdf0e10cSrcweir     is given (parameter _pLayoutFrm == 0L), the movability in the actual
1326cdf0e10cSrcweir     environment (<this->GetUpper()) is checked.
1327cdf0e10cSrcweir 
1328cdf0e10cSrcweir     @author OD
1329cdf0e10cSrcweir */
1330cdf0e10cSrcweir 
IsMoveable(const SwLayoutFrm * _pLayoutFrm) const1331cdf0e10cSrcweir bool SwFrm::IsMoveable( const SwLayoutFrm* _pLayoutFrm ) const
1332cdf0e10cSrcweir {
1333cdf0e10cSrcweir     bool bRetVal = false;
1334cdf0e10cSrcweir 
1335cdf0e10cSrcweir     if ( !_pLayoutFrm )
1336cdf0e10cSrcweir     {
1337cdf0e10cSrcweir         _pLayoutFrm = GetUpper();
1338cdf0e10cSrcweir     }
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir     if ( _pLayoutFrm && IsFlowFrm() )
1341cdf0e10cSrcweir     {
1342cdf0e10cSrcweir         if ( _pLayoutFrm->IsInSct() && lcl_IsInColSct( _pLayoutFrm ) )
1343cdf0e10cSrcweir         {
1344cdf0e10cSrcweir             bRetVal = true;
1345cdf0e10cSrcweir         }
1346cdf0e10cSrcweir         else if ( _pLayoutFrm->IsInFly() ||
1347cdf0e10cSrcweir                   _pLayoutFrm->IsInDocBody() ||
1348cdf0e10cSrcweir                   _pLayoutFrm->IsInFtn() )
1349cdf0e10cSrcweir         {
1350cdf0e10cSrcweir             if ( _pLayoutFrm->IsInTab() && !IsTabFrm() &&
1351cdf0e10cSrcweir                  ( !IsCntntFrm() || !const_cast<SwFrm*>(this)->GetNextCellLeaf( MAKEPAGE_NONE ) ) )
1352cdf0e10cSrcweir             {
1353cdf0e10cSrcweir                 bRetVal = false;
1354cdf0e10cSrcweir             }
1355cdf0e10cSrcweir             else
1356cdf0e10cSrcweir             {
1357cdf0e10cSrcweir                 if ( _pLayoutFrm->IsInFly() )
1358cdf0e10cSrcweir                 {
1359cdf0e10cSrcweir                     // if fly frame has a follow (next linked fly frame),
1360cdf0e10cSrcweir                     // frame is moveable.
1361cdf0e10cSrcweir                     if ( const_cast<SwLayoutFrm*>(_pLayoutFrm)->FindFlyFrm()->GetNextLink() )
1362cdf0e10cSrcweir                     {
1363cdf0e10cSrcweir                         bRetVal = true;
1364cdf0e10cSrcweir                     }
1365cdf0e10cSrcweir                     else
1366cdf0e10cSrcweir                     {
1367cdf0e10cSrcweir                         // if environment is columned, frame is moveable, if
1368cdf0e10cSrcweir                         // it isn't in last column.
1369cdf0e10cSrcweir                         // search for column frame
1370cdf0e10cSrcweir                         const SwFrm* pCol = _pLayoutFrm;
1371cdf0e10cSrcweir                         while ( pCol && !pCol->IsColumnFrm() )
1372cdf0e10cSrcweir                         {
1373cdf0e10cSrcweir                             pCol = pCol->GetUpper();
1374cdf0e10cSrcweir                         }
1375cdf0e10cSrcweir                         // frame is moveable, if found column frame isn't last one.
1376cdf0e10cSrcweir                         if ( pCol && pCol->GetNext() )
1377cdf0e10cSrcweir                         {
1378cdf0e10cSrcweir                             bRetVal = true;
1379cdf0e10cSrcweir                         }
1380cdf0e10cSrcweir                     }
1381cdf0e10cSrcweir                 }
1382cdf0e10cSrcweir                 else
1383cdf0e10cSrcweir                 {
1384cdf0e10cSrcweir                     bRetVal = true;
1385cdf0e10cSrcweir                 }
1386cdf0e10cSrcweir             }
1387cdf0e10cSrcweir         }
1388cdf0e10cSrcweir     }
1389cdf0e10cSrcweir 
1390cdf0e10cSrcweir     return bRetVal;
1391cdf0e10cSrcweir }
1392cdf0e10cSrcweir 
1393cdf0e10cSrcweir /*************************************************************************
1394cdf0e10cSrcweir |*
1395cdf0e10cSrcweir |*    SwFrm::SetInfFlags();
1396cdf0e10cSrcweir |*
1397cdf0e10cSrcweir |*    Ersterstellung    MA 05. Apr. 94
1398cdf0e10cSrcweir |*    Letzte Aenderung  MA 05. Apr. 94
1399cdf0e10cSrcweir |*
1400cdf0e10cSrcweir |*************************************************************************/
SetInfFlags()1401cdf0e10cSrcweir void SwFrm::SetInfFlags()
1402cdf0e10cSrcweir {
1403cdf0e10cSrcweir     if ( !IsFlyFrm() && !GetUpper() ) //noch nicht gepastet, keine Informationen
1404cdf0e10cSrcweir         return;                       //lieferbar
1405cdf0e10cSrcweir 
1406cdf0e10cSrcweir     bInfInvalid = bInfBody = bInfTab = bInfFly = bInfFtn = bInfSct = sal_False;
1407cdf0e10cSrcweir 
1408cdf0e10cSrcweir     SwFrm *pFrm = this;
1409cdf0e10cSrcweir     if( IsFtnContFrm() )
1410cdf0e10cSrcweir         bInfFtn = sal_True;
1411cdf0e10cSrcweir     do
1412cdf0e10cSrcweir     {   // bInfBody wird nur am Seitenbody, nicht im ColumnBody gesetzt
1413cdf0e10cSrcweir         if ( pFrm->IsBodyFrm() && !bInfFtn && pFrm->GetUpper()
1414cdf0e10cSrcweir              && pFrm->GetUpper()->IsPageFrm() )
1415cdf0e10cSrcweir             bInfBody = sal_True;
1416cdf0e10cSrcweir         else if ( pFrm->IsTabFrm() || pFrm->IsCellFrm() )
1417cdf0e10cSrcweir         {
1418cdf0e10cSrcweir             bInfTab = sal_True;
1419cdf0e10cSrcweir         }
1420cdf0e10cSrcweir         else if ( pFrm->IsFlyFrm() )
1421cdf0e10cSrcweir             bInfFly = sal_True;
1422cdf0e10cSrcweir         else if ( pFrm->IsSctFrm() )
1423cdf0e10cSrcweir             bInfSct = sal_True;
1424cdf0e10cSrcweir         else if ( pFrm->IsFtnFrm() )
1425cdf0e10cSrcweir             bInfFtn = sal_True;
1426cdf0e10cSrcweir 
1427cdf0e10cSrcweir         pFrm = pFrm->GetUpper();
1428cdf0e10cSrcweir 
1429cdf0e10cSrcweir     } while ( pFrm && !pFrm->IsPageFrm() ); //Oberhalb der Seite kommt nix
1430cdf0e10cSrcweir }
1431cdf0e10cSrcweir 
1432cdf0e10cSrcweir /*-----------------22.8.2001 14:30------------------
1433cdf0e10cSrcweir  * SwFrm::SetDirFlags( sal_Bool )
1434cdf0e10cSrcweir  * actualizes the vertical or the righttoleft-flags.
1435cdf0e10cSrcweir  * If the property is derived, it's from the upper or (for fly frames) from
1436cdf0e10cSrcweir  * the anchor. Otherwise we've to call a virtual method to check the property.
1437cdf0e10cSrcweir  * --------------------------------------------------*/
1438cdf0e10cSrcweir 
SetDirFlags(sal_Bool bVert)1439cdf0e10cSrcweir void SwFrm::SetDirFlags( sal_Bool bVert )
1440cdf0e10cSrcweir {
1441cdf0e10cSrcweir     if( bVert )
1442cdf0e10cSrcweir     {
1443cdf0e10cSrcweir         // OD 2004-01-21 #114969# - if derived, valid vertical flag only if
1444cdf0e10cSrcweir         // vertical flag of upper/anchor is valid.
1445cdf0e10cSrcweir         if( bDerivedVert )
1446cdf0e10cSrcweir         {
1447cdf0e10cSrcweir             const SwFrm* pAsk = IsFlyFrm() ?
1448cdf0e10cSrcweir                           ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1449cdf0e10cSrcweir 
1450cdf0e10cSrcweir             ASSERT( pAsk != this, "Autsch! Stack overflow is about to happen" )
1451cdf0e10cSrcweir 
1452cdf0e10cSrcweir             if( pAsk )
1453cdf0e10cSrcweir             {
1454cdf0e10cSrcweir                 bVertical = pAsk->IsVertical() ? 1 : 0;
1455cdf0e10cSrcweir                 bReverse  = pAsk->IsReverse()  ? 1 : 0;
1456cdf0e10cSrcweir 
1457cdf0e10cSrcweir                 bVertLR  = pAsk->IsVertLR() ? 1 : 0;
1458cdf0e10cSrcweir                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1459cdf0e10cSrcweir                 if ( !pAsk->bInvalidVert )
1460cdf0e10cSrcweir                     bInvalidVert = sal_False;
1461cdf0e10cSrcweir             }
1462cdf0e10cSrcweir         }
1463cdf0e10cSrcweir         else
1464cdf0e10cSrcweir             CheckDirection( bVert );
1465cdf0e10cSrcweir     }
1466cdf0e10cSrcweir     else
1467cdf0e10cSrcweir     {
1468cdf0e10cSrcweir         sal_Bool bInv = 0;
1469cdf0e10cSrcweir         if( !bDerivedR2L ) // CheckDirection is able to set bDerivedR2L!
1470cdf0e10cSrcweir             CheckDirection( bVert );
1471cdf0e10cSrcweir         if( bDerivedR2L )
1472cdf0e10cSrcweir         {
1473cdf0e10cSrcweir             const SwFrm* pAsk = IsFlyFrm() ?
1474cdf0e10cSrcweir                           ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1475cdf0e10cSrcweir 
1476cdf0e10cSrcweir             ASSERT( pAsk != this, "Autsch! Stack overflow is about to happen" )
1477cdf0e10cSrcweir 
1478cdf0e10cSrcweir             if( pAsk )
1479cdf0e10cSrcweir                 bRightToLeft = pAsk->IsRightToLeft() ? 1 : 0;
1480cdf0e10cSrcweir             if( !pAsk || pAsk->bInvalidR2L )
1481cdf0e10cSrcweir                 bInv = bInvalidR2L;
1482cdf0e10cSrcweir         }
1483cdf0e10cSrcweir         bInvalidR2L = bInv;
1484cdf0e10cSrcweir     }
1485cdf0e10cSrcweir }
1486cdf0e10cSrcweir 
GetNextCellLeaf(MakePageType)1487cdf0e10cSrcweir SwLayoutFrm* SwFrm::GetNextCellLeaf( MakePageType )
1488cdf0e10cSrcweir {
1489cdf0e10cSrcweir     SwFrm* pTmpFrm = this;
1490cdf0e10cSrcweir     while ( !pTmpFrm->IsCellFrm() )
1491cdf0e10cSrcweir         pTmpFrm = pTmpFrm->GetUpper();
1492cdf0e10cSrcweir 
1493cdf0e10cSrcweir     ASSERT( pTmpFrm, "SwFrm::GetNextCellLeaf() without cell" )
1494cdf0e10cSrcweir     return ((SwCellFrm*)pTmpFrm)->GetFollowCell();
1495cdf0e10cSrcweir }
1496cdf0e10cSrcweir 
GetPrevCellLeaf(MakePageType)1497cdf0e10cSrcweir SwLayoutFrm* SwFrm::GetPrevCellLeaf( MakePageType )
1498cdf0e10cSrcweir {
1499cdf0e10cSrcweir     SwFrm* pTmpFrm = this;
1500cdf0e10cSrcweir     while ( !pTmpFrm->IsCellFrm() )
1501cdf0e10cSrcweir         pTmpFrm = pTmpFrm->GetUpper();
1502cdf0e10cSrcweir 
1503cdf0e10cSrcweir     ASSERT( pTmpFrm, "SwFrm::GetNextPreviousLeaf() without cell" )
1504cdf0e10cSrcweir     return ((SwCellFrm*)pTmpFrm)->GetPreviousCell();
1505cdf0e10cSrcweir }
1506cdf0e10cSrcweir 
lcl_FindCorrespondingCellFrm(const SwRowFrm & rOrigRow,const SwCellFrm & rOrigCell,const SwRowFrm & rCorrRow,bool bInFollow)1507cdf0e10cSrcweir SwCellFrm* lcl_FindCorrespondingCellFrm( const SwRowFrm& rOrigRow,
1508cdf0e10cSrcweir                                          const SwCellFrm& rOrigCell,
1509cdf0e10cSrcweir                                          const SwRowFrm& rCorrRow,
1510cdf0e10cSrcweir                                          bool bInFollow )
1511cdf0e10cSrcweir {
1512cdf0e10cSrcweir     SwCellFrm* pRet = NULL;
1513cdf0e10cSrcweir     SwCellFrm* pCell = (SwCellFrm*)rOrigRow.Lower();
1514cdf0e10cSrcweir     SwCellFrm* pCorrCell = (SwCellFrm*)rCorrRow.Lower();
1515cdf0e10cSrcweir 
1516cdf0e10cSrcweir     while ( pCell != &rOrigCell && !pCell->IsAnLower( &rOrigCell ) )
1517cdf0e10cSrcweir     {
1518cdf0e10cSrcweir         pCell = (SwCellFrm*)pCell->GetNext();
1519cdf0e10cSrcweir         pCorrCell = (SwCellFrm*)pCorrCell->GetNext();
1520cdf0e10cSrcweir     }
1521cdf0e10cSrcweir 
1522cdf0e10cSrcweir     ASSERT( pCell && pCorrCell, "lcl_FindCorrespondingCellFrm does not work" )
1523cdf0e10cSrcweir 
1524cdf0e10cSrcweir     if ( pCell != &rOrigCell )
1525cdf0e10cSrcweir     {
1526cdf0e10cSrcweir         // rOrigCell must be a lower of pCell. We need to recurse into the rows:
1527cdf0e10cSrcweir         ASSERT( pCell->Lower() && pCell->Lower()->IsRowFrm(),
1528cdf0e10cSrcweir                 "lcl_FindCorrespondingCellFrm does not work" )
1529cdf0e10cSrcweir 
1530cdf0e10cSrcweir         SwRowFrm* pRow = (SwRowFrm*)pCell->Lower();
1531cdf0e10cSrcweir         while ( !pRow->IsAnLower( &rOrigCell ) )
1532cdf0e10cSrcweir             pRow = (SwRowFrm*)pRow->GetNext();
1533cdf0e10cSrcweir 
1534cdf0e10cSrcweir         SwRowFrm* pCorrRow = 0;
1535cdf0e10cSrcweir         if ( bInFollow )
1536cdf0e10cSrcweir             pCorrRow = pRow->GetFollowRow();
1537cdf0e10cSrcweir         else
1538cdf0e10cSrcweir         {
1539cdf0e10cSrcweir             SwRowFrm* pTmpRow = static_cast<SwRowFrm*>(pCorrCell->GetLastLower());
1540cdf0e10cSrcweir 
1541cdf0e10cSrcweir             if ( pTmpRow && pTmpRow->GetFollowRow() == pRow )
1542cdf0e10cSrcweir                 pCorrRow = pTmpRow;
1543cdf0e10cSrcweir         }
1544cdf0e10cSrcweir 
1545cdf0e10cSrcweir         if ( pCorrRow )
1546cdf0e10cSrcweir             pRet = lcl_FindCorrespondingCellFrm( *pRow, rOrigCell, *pCorrRow, bInFollow );
1547cdf0e10cSrcweir     }
1548cdf0e10cSrcweir     else
1549cdf0e10cSrcweir         pRet = pCorrCell;
1550cdf0e10cSrcweir 
1551cdf0e10cSrcweir     return pRet;
1552cdf0e10cSrcweir }
1553cdf0e10cSrcweir 
1554cdf0e10cSrcweir // VERSION OF GetFollowCell() that assumes that we always have a follow flow line:
GetFollowCell() const1555cdf0e10cSrcweir SwCellFrm* SwCellFrm::GetFollowCell() const
1556cdf0e10cSrcweir {
1557cdf0e10cSrcweir     SwCellFrm* pRet = NULL;
1558cdf0e10cSrcweir 
1559cdf0e10cSrcweir     // NEW TABLES
1560cdf0e10cSrcweir     // Covered cells do not have follow cells!
1561cdf0e10cSrcweir     const long nRowSpan = GetLayoutRowSpan();
1562cdf0e10cSrcweir     if ( nRowSpan < 1 )
1563cdf0e10cSrcweir         return NULL;
1564cdf0e10cSrcweir 
1565cdf0e10cSrcweir     // find most upper row frame
1566cdf0e10cSrcweir     const SwFrm* pRow = GetUpper();
1567cdf0e10cSrcweir     while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
1568cdf0e10cSrcweir         pRow = pRow->GetUpper();
1569cdf0e10cSrcweir 
1570cdf0e10cSrcweir     if ( !pRow )
1571cdf0e10cSrcweir         return NULL;
1572cdf0e10cSrcweir 
1573cdf0e10cSrcweir     const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( pRow->GetUpper() );
1574cdf0e10cSrcweir     if ( !pRow || !pTabFrm->GetFollow() || !pTabFrm->HasFollowFlowLine() )
1575cdf0e10cSrcweir         return NULL;
1576cdf0e10cSrcweir 
1577cdf0e10cSrcweir     const SwCellFrm* pThisCell = this;
1578cdf0e10cSrcweir 
1579cdf0e10cSrcweir     // Get last cell of the current table frame that belongs to the rowspan:
1580cdf0e10cSrcweir     if ( nRowSpan > 1 )
1581cdf0e10cSrcweir     {
1582cdf0e10cSrcweir         // optimization: Will end of row span be in last row or exceed row?
1583cdf0e10cSrcweir         long nMax = 0;
1584cdf0e10cSrcweir         while ( pRow->GetNext() && ++nMax < nRowSpan )
1585cdf0e10cSrcweir             pRow = pRow->GetNext();
1586cdf0e10cSrcweir 
1587cdf0e10cSrcweir         if ( !pRow->GetNext() )
1588cdf0e10cSrcweir         {
1589cdf0e10cSrcweir             pThisCell = &pThisCell->FindStartEndOfRowSpanCell( false, true );
1590cdf0e10cSrcweir             pRow = pThisCell->GetUpper();
1591cdf0e10cSrcweir         }
1592cdf0e10cSrcweir     }
1593cdf0e10cSrcweir 
1594cdf0e10cSrcweir     const SwRowFrm* pFollowRow = NULL;
1595cdf0e10cSrcweir     if ( !pRow->GetNext() &&
1596cdf0e10cSrcweir          NULL != ( pFollowRow = pRow->IsInSplitTableRow() ) &&
1597cdf0e10cSrcweir          ( !pFollowRow->IsRowSpanLine() || nRowSpan > 1 ) )
1598cdf0e10cSrcweir          pRet = lcl_FindCorrespondingCellFrm( *((SwRowFrm*)pRow), *pThisCell, *pFollowRow, true );
1599cdf0e10cSrcweir 
1600cdf0e10cSrcweir     return pRet;
1601cdf0e10cSrcweir }
1602cdf0e10cSrcweir 
1603cdf0e10cSrcweir // VERSION OF GetPreviousCell() THAT ASSUMES THAT WE ALWAYS HAVE A FFL
GetPreviousCell() const1604cdf0e10cSrcweir SwCellFrm* SwCellFrm::GetPreviousCell() const
1605cdf0e10cSrcweir {
1606cdf0e10cSrcweir     SwCellFrm* pRet = NULL;
1607cdf0e10cSrcweir 
1608cdf0e10cSrcweir     // NEW TABLES
1609cdf0e10cSrcweir     // Covered cells do not have previous cells!
1610cdf0e10cSrcweir     if ( GetLayoutRowSpan() < 1 )
1611cdf0e10cSrcweir         return NULL;
1612cdf0e10cSrcweir 
1613cdf0e10cSrcweir     // find most upper row frame
1614cdf0e10cSrcweir     const SwFrm* pRow = GetUpper();
1615cdf0e10cSrcweir     while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
1616cdf0e10cSrcweir         pRow = pRow->GetUpper();
1617cdf0e10cSrcweir 
1618cdf0e10cSrcweir     ASSERT( pRow->GetUpper() && pRow->GetUpper()->IsTabFrm(), "GetPreviousCell without Table" );
1619cdf0e10cSrcweir 
1620cdf0e10cSrcweir     SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1621cdf0e10cSrcweir 
1622cdf0e10cSrcweir     if ( pTab->IsFollow() )
1623cdf0e10cSrcweir     {
1624cdf0e10cSrcweir         const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1625cdf0e10cSrcweir         const bool bIsInFirstLine = ( pTmp == pRow );
1626cdf0e10cSrcweir 
1627cdf0e10cSrcweir         if ( bIsInFirstLine )
1628cdf0e10cSrcweir         {
1629cdf0e10cSrcweir             SwTabFrm *pMaster = (SwTabFrm*)pTab->FindMaster();
1630cdf0e10cSrcweir             if ( pMaster && pMaster->HasFollowFlowLine() )
1631cdf0e10cSrcweir             {
1632cdf0e10cSrcweir                 SwRowFrm* pMasterRow = static_cast<SwRowFrm*>(pMaster->GetLastLower());
1633cdf0e10cSrcweir                 if ( pMasterRow )
1634cdf0e10cSrcweir                     pRet = lcl_FindCorrespondingCellFrm( *((SwRowFrm*)pRow), *this, *pMasterRow, false );
1635cdf0e10cSrcweir                 if ( pRet && pRet->GetTabBox()->getRowSpan() < 1 )
1636cdf0e10cSrcweir                     pRet = &const_cast<SwCellFrm&>(pRet->FindStartEndOfRowSpanCell( true, true ));
1637cdf0e10cSrcweir             }
1638cdf0e10cSrcweir         }
1639cdf0e10cSrcweir     }
1640cdf0e10cSrcweir 
1641cdf0e10cSrcweir     return pRet;
1642cdf0e10cSrcweir }
1643cdf0e10cSrcweir 
1644cdf0e10cSrcweir // --> NEW TABLES
FindStartEndOfRowSpanCell(bool bStart,bool bCurrentTableOnly) const1645cdf0e10cSrcweir const SwCellFrm& SwCellFrm::FindStartEndOfRowSpanCell( bool bStart, bool bCurrentTableOnly ) const
1646cdf0e10cSrcweir {
1647cdf0e10cSrcweir     const SwCellFrm* pRet = 0;
1648cdf0e10cSrcweir 
1649cdf0e10cSrcweir     const SwTabFrm* pTableFrm = dynamic_cast<const SwTabFrm*>(GetUpper()->GetUpper());
1650cdf0e10cSrcweir 
1651cdf0e10cSrcweir     if ( !bStart && pTableFrm->IsFollow() && pTableFrm->IsInHeadline( *this ) )
1652cdf0e10cSrcweir         return *this;
1653cdf0e10cSrcweir 
1654cdf0e10cSrcweir     ASSERT( pTableFrm &&
1655cdf0e10cSrcweir             (  bStart && GetTabBox()->getRowSpan() < 1 ||
1656cdf0e10cSrcweir               !bStart && GetLayoutRowSpan() > 1 ),
1657cdf0e10cSrcweir             "SwCellFrm::FindStartRowSpanCell: No rowspan, no table, no cookies" )
1658cdf0e10cSrcweir 
1659cdf0e10cSrcweir     if ( pTableFrm )
1660cdf0e10cSrcweir     {
1661cdf0e10cSrcweir         const SwTable* pTable = pTableFrm->GetTable();
1662cdf0e10cSrcweir 
1663cdf0e10cSrcweir         sal_uInt16 nMax = USHRT_MAX;
1664cdf0e10cSrcweir         if ( bCurrentTableOnly )
1665cdf0e10cSrcweir         {
1666cdf0e10cSrcweir             const SwFrm* pCurrentRow = GetUpper();
1667cdf0e10cSrcweir             const bool bDoNotEnterHeadline = bStart && pTableFrm->IsFollow() &&
1668cdf0e10cSrcweir                                         !pTableFrm->IsInHeadline( *pCurrentRow );
1669cdf0e10cSrcweir 
1670cdf0e10cSrcweir             // check how many rows we are allowed to go up or down until we reach the end of
1671cdf0e10cSrcweir             // the current table frame:
1672cdf0e10cSrcweir             nMax = 0;
1673cdf0e10cSrcweir             while ( bStart ? pCurrentRow->GetPrev() : pCurrentRow->GetNext() )
1674cdf0e10cSrcweir             {
1675cdf0e10cSrcweir                 if ( bStart )
1676cdf0e10cSrcweir                 {
1677cdf0e10cSrcweir                     // do not enter a repeated headline:
1678cdf0e10cSrcweir                     if ( bDoNotEnterHeadline && pTableFrm->IsFollow() &&
1679cdf0e10cSrcweir                          pTableFrm->IsInHeadline( *pCurrentRow->GetPrev() ) )
1680cdf0e10cSrcweir                         break;
1681cdf0e10cSrcweir 
1682cdf0e10cSrcweir                     pCurrentRow = pCurrentRow->GetPrev();
1683cdf0e10cSrcweir                 }
1684cdf0e10cSrcweir                 else
1685cdf0e10cSrcweir                     pCurrentRow = pCurrentRow->GetNext();
1686cdf0e10cSrcweir 
1687cdf0e10cSrcweir                 ++nMax;
1688cdf0e10cSrcweir             }
1689cdf0e10cSrcweir         }
1690cdf0e10cSrcweir 
1691cdf0e10cSrcweir         // By passing the nMax value for Find*OfRowSpan (in case of bCurrentTableOnly
1692cdf0e10cSrcweir         // is set) we assure that we find a rMasterBox that has a SwCellFrm in
1693cdf0e10cSrcweir         // the current table frame:
1694cdf0e10cSrcweir         const SwTableBox& rMasterBox = bStart ?
1695cdf0e10cSrcweir                                        GetTabBox()->FindStartOfRowSpan( *pTable, nMax ) :
1696cdf0e10cSrcweir                                        GetTabBox()->FindEndOfRowSpan( *pTable, nMax );
1697cdf0e10cSrcweir 
1698cdf0e10cSrcweir         SwIterator<SwCellFrm,SwFmt> aIter( *rMasterBox.GetFrmFmt() );
1699cdf0e10cSrcweir 
1700cdf0e10cSrcweir         for ( SwCellFrm* pMasterCell = aIter.First(); pMasterCell; pMasterCell = aIter.Next() )
1701cdf0e10cSrcweir         {
1702cdf0e10cSrcweir             if ( pMasterCell->GetTabBox() == &rMasterBox )
1703cdf0e10cSrcweir             {
1704cdf0e10cSrcweir                 const SwTabFrm* pMasterTable = static_cast<const SwTabFrm*>(pMasterCell->GetUpper()->GetUpper());
1705cdf0e10cSrcweir 
1706cdf0e10cSrcweir                 if ( bCurrentTableOnly )
1707cdf0e10cSrcweir                 {
1708cdf0e10cSrcweir                     if ( pMasterTable == pTableFrm )
1709cdf0e10cSrcweir                     {
1710cdf0e10cSrcweir                         pRet = pMasterCell;
1711cdf0e10cSrcweir                         break;
1712cdf0e10cSrcweir                     }
1713cdf0e10cSrcweir                 }
1714cdf0e10cSrcweir                 else
1715cdf0e10cSrcweir                 {
1716cdf0e10cSrcweir                     if ( pMasterTable == pTableFrm ||
1717cdf0e10cSrcweir                          (  (bStart && pMasterTable->IsAnFollow(pTableFrm)) ||
1718cdf0e10cSrcweir                            (!bStart && pTableFrm->IsAnFollow(pMasterTable)) ) )
1719cdf0e10cSrcweir                     {
1720cdf0e10cSrcweir                         pRet = pMasterCell;
1721cdf0e10cSrcweir                         break;
1722cdf0e10cSrcweir                     }
1723cdf0e10cSrcweir                 }
1724cdf0e10cSrcweir             }
1725cdf0e10cSrcweir         }
1726cdf0e10cSrcweir     }
1727cdf0e10cSrcweir 
1728cdf0e10cSrcweir     ASSERT( pRet, "SwCellFrm::FindStartRowSpanCell: No result" )
1729cdf0e10cSrcweir 
1730cdf0e10cSrcweir     return *pRet;
1731cdf0e10cSrcweir }
1732cdf0e10cSrcweir // <-- NEW TABLES
1733cdf0e10cSrcweir 
IsInSplitTableRow() const1734cdf0e10cSrcweir const SwRowFrm* SwFrm::IsInSplitTableRow() const
1735cdf0e10cSrcweir {
1736cdf0e10cSrcweir     ASSERT( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" )
1737cdf0e10cSrcweir 
1738cdf0e10cSrcweir     const SwFrm* pRow = this;
1739cdf0e10cSrcweir 
1740cdf0e10cSrcweir     // find most upper row frame
1741cdf0e10cSrcweir     while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1742cdf0e10cSrcweir         pRow = pRow->GetUpper();
1743cdf0e10cSrcweir 
1744cdf0e10cSrcweir     if ( !pRow ) return NULL;
1745cdf0e10cSrcweir 
1746cdf0e10cSrcweir     ASSERT( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" )
1747cdf0e10cSrcweir 
1748cdf0e10cSrcweir     const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1749cdf0e10cSrcweir     // --> OD 2006-06-28 #b6443897#
1750cdf0e10cSrcweir     // If most upper row frame is a headline row, the current frame
1751cdf0e10cSrcweir     // can't be in a splitted table row. Thus, add corresponding condition.
1752cdf0e10cSrcweir     if ( pRow->GetNext() ||
1753cdf0e10cSrcweir          pTab->GetTable()->IsHeadline(
1754cdf0e10cSrcweir                     *(static_cast<const SwRowFrm*>(pRow)->GetTabLine()) ) ||
1755cdf0e10cSrcweir          !pTab->HasFollowFlowLine() ||
1756cdf0e10cSrcweir          !pTab->GetFollow() )
1757cdf0e10cSrcweir         return NULL;
1758cdf0e10cSrcweir     // <--
1759cdf0e10cSrcweir 
1760cdf0e10cSrcweir     // skip headline
1761cdf0e10cSrcweir     const SwRowFrm* pFollowRow = pTab->GetFollow()->GetFirstNonHeadlineRow();
1762cdf0e10cSrcweir 
1763cdf0e10cSrcweir     ASSERT( pFollowRow, "SwFrm::IsInSplitTableRow() does not work" )
1764cdf0e10cSrcweir 
1765cdf0e10cSrcweir     return pFollowRow;
1766cdf0e10cSrcweir }
1767cdf0e10cSrcweir 
IsInFollowFlowRow() const1768cdf0e10cSrcweir const SwRowFrm* SwFrm::IsInFollowFlowRow() const
1769cdf0e10cSrcweir {
1770cdf0e10cSrcweir     ASSERT( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" )
1771cdf0e10cSrcweir 
1772cdf0e10cSrcweir     // find most upper row frame
1773cdf0e10cSrcweir     const SwFrm* pRow = this;
1774cdf0e10cSrcweir     while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1775cdf0e10cSrcweir         pRow = pRow->GetUpper();
1776cdf0e10cSrcweir 
1777cdf0e10cSrcweir     if ( !pRow ) return NULL;
1778cdf0e10cSrcweir 
1779cdf0e10cSrcweir     ASSERT( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" )
1780cdf0e10cSrcweir 
1781cdf0e10cSrcweir     const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1782cdf0e10cSrcweir 
1783cdf0e10cSrcweir     const SwTabFrm* pMaster = pTab->IsFollow() ? pTab->FindMaster() : 0;
1784cdf0e10cSrcweir 
1785cdf0e10cSrcweir     if ( !pMaster || !pMaster->HasFollowFlowLine() )
1786cdf0e10cSrcweir         return NULL;
1787cdf0e10cSrcweir 
1788cdf0e10cSrcweir     const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1789cdf0e10cSrcweir     const bool bIsInFirstLine = ( pTmp == pRow );
1790cdf0e10cSrcweir 
1791cdf0e10cSrcweir     if ( !bIsInFirstLine )
1792cdf0e10cSrcweir         return NULL;
1793cdf0e10cSrcweir 
1794cdf0e10cSrcweir     const SwRowFrm* pMasterRow = static_cast<const SwRowFrm*>(pMaster->GetLastLower());
1795cdf0e10cSrcweir     return pMasterRow;
1796cdf0e10cSrcweir }
1797cdf0e10cSrcweir 
IsInBalancedSection() const1798cdf0e10cSrcweir bool SwFrm::IsInBalancedSection() const
1799cdf0e10cSrcweir {
1800cdf0e10cSrcweir     bool bRet = false;
1801cdf0e10cSrcweir 
1802cdf0e10cSrcweir     if ( IsInSct() )
1803cdf0e10cSrcweir     {
1804cdf0e10cSrcweir         const SwSectionFrm* pSectionFrm = FindSctFrm();
1805cdf0e10cSrcweir         if ( pSectionFrm )
1806cdf0e10cSrcweir             bRet = pSectionFrm->IsBalancedSection();
1807cdf0e10cSrcweir     }
1808cdf0e10cSrcweir     return bRet;
1809cdf0e10cSrcweir }
1810cdf0e10cSrcweir 
1811cdf0e10cSrcweir /*
1812cdf0e10cSrcweir  * SwLayoutFrm::GetLastLower()
1813cdf0e10cSrcweir  */
GetLastLower() const1814cdf0e10cSrcweir const SwFrm* SwLayoutFrm::GetLastLower() const
1815cdf0e10cSrcweir {
1816cdf0e10cSrcweir     const SwFrm* pRet = Lower();
1817cdf0e10cSrcweir     if ( !pRet )
1818cdf0e10cSrcweir         return 0;
1819cdf0e10cSrcweir     while ( pRet->GetNext() )
1820cdf0e10cSrcweir         pRet = pRet->GetNext();
1821cdf0e10cSrcweir     return pRet;
1822cdf0e10cSrcweir }
1823