xref: /trunk/main/sw/source/core/docnode/node2lay.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 #include <switerator.hxx>
28cdf0e10cSrcweir #include <calbck.hxx>
29cdf0e10cSrcweir #include <node.hxx>
30cdf0e10cSrcweir #include <ndindex.hxx>
31cdf0e10cSrcweir #include <swtable.hxx>
32cdf0e10cSrcweir #include <ftnfrm.hxx>
33cdf0e10cSrcweir #include <sectfrm.hxx>
34cdf0e10cSrcweir #include "frmfmt.hxx"
35cdf0e10cSrcweir #include "cntfrm.hxx"
36cdf0e10cSrcweir #include "tabfrm.hxx"
37cdf0e10cSrcweir #include "frmtool.hxx"
38cdf0e10cSrcweir #include "section.hxx"
39cdf0e10cSrcweir #include "node2lay.hxx"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir /* -----------------25.02.99 10:31-------------------
42cdf0e10cSrcweir  * Die SwNode2LayImpl-Klasse erledigt die eigentliche Arbeit,
43cdf0e10cSrcweir  * die SwNode2Layout-Klasse ist nur die der Oefffentlichkeit bekannte Schnittstelle
44cdf0e10cSrcweir  * --------------------------------------------------*/
45cdf0e10cSrcweir class SwNode2LayImpl
46cdf0e10cSrcweir {
47cdf0e10cSrcweir     SwIterator<SwFrm,SwModify>* pIter;
48cdf0e10cSrcweir     SwModify* pMod;
49cdf0e10cSrcweir     SvPtrarr *pUpperFrms;// Zum Einsammeln der Upper
50cdf0e10cSrcweir     sal_uLong nIndex;        // Der Index des einzufuegenden Nodes
51cdf0e10cSrcweir     sal_Bool bMaster    : 1; // sal_True => nur Master , sal_False => nur Frames ohne Follow
52cdf0e10cSrcweir     sal_Bool bInit      : 1; // Ist am SwClient bereits ein First()-Aufruf erfolgt?
53cdf0e10cSrcweir public:
54cdf0e10cSrcweir     SwNode2LayImpl( const SwNode& rNode, sal_uLong nIdx, sal_Bool bSearch );
~SwNode2LayImpl()55cdf0e10cSrcweir     ~SwNode2LayImpl() { delete pIter; delete pUpperFrms; }
56cdf0e10cSrcweir     SwFrm* NextFrm(); // liefert den naechsten "sinnvollen" Frame
57cdf0e10cSrcweir     SwLayoutFrm* UpperFrm( SwFrm* &rpFrm, const SwNode &rNode );
58cdf0e10cSrcweir     void SaveUpperFrms(); // Speichert (und lockt ggf.) die pUpper
59cdf0e10cSrcweir     // Fuegt unter jeden pUpper des Arrays einen Frame ein.
60cdf0e10cSrcweir     void RestoreUpperFrms( SwNodes& rNds, sal_uLong nStt, sal_uLong nEnd );
61cdf0e10cSrcweir 
62cdf0e10cSrcweir     SwFrm* GetFrm( const Point* pDocPos = 0,
63cdf0e10cSrcweir                     const SwPosition *pPos = 0,
64cdf0e10cSrcweir                     const sal_Bool bCalcFrm = sal_True ) const;
65cdf0e10cSrcweir };
66cdf0e10cSrcweir 
67cdf0e10cSrcweir /* -----------------25.02.99 10:38-------------------
68cdf0e10cSrcweir  * Hauptaufgabe des Ctor: Das richtige SwModify zu ermitteln,
69cdf0e10cSrcweir  * ueber das iteriert wird.
70cdf0e10cSrcweir  * Uebergibt man bSearch == sal_True, so wird der naechste Cntnt- oder TableNode
71cdf0e10cSrcweir  * gesucht, der Frames besitzt ( zum Einsammeln der pUpper ), ansonsten wird
72cdf0e10cSrcweir  * erwartet, das rNode bereits auf einem solchen Cntnt- oder TableNode sitzt,
73cdf0e10cSrcweir  * vor oder hinter den eingefuegt werden soll.
74cdf0e10cSrcweir  * --------------------------------------------------*/
75cdf0e10cSrcweir 
GoNextWithFrm(const SwNodes & rNodes,SwNodeIndex * pIdx)76cdf0e10cSrcweir SwNode* GoNextWithFrm(const SwNodes& rNodes, SwNodeIndex *pIdx)
77cdf0e10cSrcweir {
78cdf0e10cSrcweir     if( pIdx->GetIndex() >= rNodes.Count() - 1 )
79cdf0e10cSrcweir         return 0;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir     SwNodeIndex aTmp(*pIdx, +1);
82cdf0e10cSrcweir     SwNode* pNd = 0;
83cdf0e10cSrcweir     while( aTmp < rNodes.Count()-1 )
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir         pNd = &aTmp.GetNode();
86cdf0e10cSrcweir         bool bFound = false;
87cdf0e10cSrcweir         if ( pNd->IsCntntNode() )
88cdf0e10cSrcweir             bFound = ( SwIterator<SwFrm,SwCntntNode>::FirstElement(*(SwCntntNode*)pNd) != 0);
89cdf0e10cSrcweir         else if ( pNd->IsTableNode() )
90cdf0e10cSrcweir             bFound = ( SwIterator<SwFrm,SwFmt>::FirstElement(*((SwTableNode*)pNd)->GetTable().GetFrmFmt()) != 0 );
91cdf0e10cSrcweir         else if( pNd->IsEndNode() && !pNd->StartOfSectionNode()->IsSectionNode() )
92cdf0e10cSrcweir         {
93cdf0e10cSrcweir             pNd = 0;
94cdf0e10cSrcweir             break;
95cdf0e10cSrcweir         }
96cdf0e10cSrcweir         if ( bFound )
97cdf0e10cSrcweir                 break;
98cdf0e10cSrcweir         aTmp++;
99cdf0e10cSrcweir     }
100cdf0e10cSrcweir 
101cdf0e10cSrcweir     if( aTmp == rNodes.Count()-1 )
102cdf0e10cSrcweir         pNd = 0;
103cdf0e10cSrcweir     else if( pNd )
104cdf0e10cSrcweir         (*pIdx) = aTmp;
105cdf0e10cSrcweir     return pNd;
106cdf0e10cSrcweir }
107cdf0e10cSrcweir 
GoPreviousWithFrm(SwNodeIndex * pIdx)108cdf0e10cSrcweir SwNode* GoPreviousWithFrm(SwNodeIndex *pIdx)
109cdf0e10cSrcweir {
110cdf0e10cSrcweir     if( !pIdx->GetIndex() )
111cdf0e10cSrcweir         return 0;
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     SwNodeIndex aTmp( *pIdx, -1 );
114cdf0e10cSrcweir     SwNode* pNd(0);
115cdf0e10cSrcweir     while( aTmp.GetIndex() )
116cdf0e10cSrcweir     {
117cdf0e10cSrcweir         pNd = &aTmp.GetNode();
118cdf0e10cSrcweir         bool bFound = false;
119cdf0e10cSrcweir         if ( pNd->IsCntntNode() )
120cdf0e10cSrcweir             bFound = ( SwIterator<SwFrm,SwCntntNode>::FirstElement(*(SwCntntNode*)pNd) != 0);
121cdf0e10cSrcweir         else if ( pNd->IsTableNode() )
122cdf0e10cSrcweir             bFound = ( SwIterator<SwFrm,SwFmt>::FirstElement(*((SwTableNode*)pNd)->GetTable().GetFrmFmt()) != 0 );
123cdf0e10cSrcweir         else if( pNd->IsStartNode() && !pNd->IsSectionNode() )
124cdf0e10cSrcweir         {
125cdf0e10cSrcweir             pNd = 0;
126cdf0e10cSrcweir             break;
127cdf0e10cSrcweir         }
128cdf0e10cSrcweir         if ( bFound )
129cdf0e10cSrcweir                 break;
130cdf0e10cSrcweir         aTmp--;
131cdf0e10cSrcweir     }
132cdf0e10cSrcweir 
133cdf0e10cSrcweir     if( !aTmp.GetIndex() )
134cdf0e10cSrcweir         pNd = 0;
135cdf0e10cSrcweir     else if( pNd )
136cdf0e10cSrcweir         (*pIdx) = aTmp;
137cdf0e10cSrcweir     return pNd;
138cdf0e10cSrcweir }
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 
SwNode2LayImpl(const SwNode & rNode,sal_uLong nIdx,sal_Bool bSearch)141cdf0e10cSrcweir SwNode2LayImpl::SwNode2LayImpl( const SwNode& rNode, sal_uLong nIdx, sal_Bool bSearch )
142cdf0e10cSrcweir     : pUpperFrms( NULL ), nIndex( nIdx ), bInit( sal_False )
143cdf0e10cSrcweir {
144cdf0e10cSrcweir     const SwNode* pNd;
145cdf0e10cSrcweir     if( bSearch || rNode.IsSectionNode() )
146cdf0e10cSrcweir     {
147cdf0e10cSrcweir         // Suche den naechsten Cntnt/TblNode, der einen Frame besitzt,
148cdf0e10cSrcweir         // damit wir uns vor/hinter ihn haengen koennen
149cdf0e10cSrcweir         if( !bSearch && rNode.GetIndex() < nIndex )
150cdf0e10cSrcweir         {
151cdf0e10cSrcweir             SwNodeIndex aTmp( *rNode.EndOfSectionNode(), +1 );
152cdf0e10cSrcweir             pNd = GoPreviousWithFrm( &aTmp );
153cdf0e10cSrcweir             if( !bSearch && pNd && rNode.GetIndex() > pNd->GetIndex() )
154cdf0e10cSrcweir                 pNd = NULL; // Nicht ueber den Bereich hinausschiessen
155cdf0e10cSrcweir             bMaster = sal_False;
156cdf0e10cSrcweir         }
157cdf0e10cSrcweir         else
158cdf0e10cSrcweir         {
159cdf0e10cSrcweir             SwNodeIndex aTmp( rNode, -1 );
160cdf0e10cSrcweir             pNd = GoNextWithFrm( rNode.GetNodes(), &aTmp );
161cdf0e10cSrcweir             bMaster = sal_True;
162cdf0e10cSrcweir             if( !bSearch && pNd && rNode.EndOfSectionIndex() < pNd->GetIndex() )
163cdf0e10cSrcweir                 pNd = NULL; // Nicht ueber den Bereich hinausschiessen
164cdf0e10cSrcweir         }
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir     else
167cdf0e10cSrcweir     {
168cdf0e10cSrcweir         pNd = &rNode;
169cdf0e10cSrcweir         bMaster = nIndex < rNode.GetIndex();
170cdf0e10cSrcweir     }
171cdf0e10cSrcweir     if( pNd )
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir         if( pNd->IsCntntNode() )
174cdf0e10cSrcweir             pMod = (SwModify*)pNd->GetCntntNode();
175cdf0e10cSrcweir         else
176cdf0e10cSrcweir         {
177cdf0e10cSrcweir             ASSERT( pNd->IsTableNode(), "For Tablenodes only" );
178cdf0e10cSrcweir             pMod = pNd->GetTableNode()->GetTable().GetFrmFmt();
179cdf0e10cSrcweir         }
180cdf0e10cSrcweir         pIter = new SwIterator<SwFrm,SwModify>( *pMod );
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir     else
183cdf0e10cSrcweir     {
184cdf0e10cSrcweir         pIter = NULL;
185cdf0e10cSrcweir         pMod = 0;
186cdf0e10cSrcweir     }
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir /* -----------------25.02.99 10:41-------------------
190cdf0e10cSrcweir  * SwNode2LayImpl::NextFrm() liefert den naechsten "sinnvollen" Frame,
191cdf0e10cSrcweir  * beim ersten Aufruf wird am eigentlichen Iterator ein First gerufen,
192cdf0e10cSrcweir  * danach die Next-Methode. Das Ergebnis wird auf Brauchbarkeit untersucht,
193cdf0e10cSrcweir  * so werden keine Follows akzeptiert, ein Master wird beim Einsammeln der
194cdf0e10cSrcweir  * pUpper und beim Einfuegen vor ihm akzeptiert. Beim Einfuegen dahinter
195cdf0e10cSrcweir  * wird vom Master ausgehend der letzte Follow gesucht und zurueckgegeben.
196cdf0e10cSrcweir  * Wenn der Frame innerhalb eines SectionFrms liegt, wird noch festgestellt,
197cdf0e10cSrcweir  * ob statt des Frames der SectionFrm der geeignete Rueckgabewert ist, dies
198cdf0e10cSrcweir  * ist der Fall, wenn der neu einzufuegende Node ausserhalb des Bereichs liegt.
199cdf0e10cSrcweir  * --------------------------------------------------*/
NextFrm()200cdf0e10cSrcweir SwFrm* SwNode2LayImpl::NextFrm()
201cdf0e10cSrcweir {
202cdf0e10cSrcweir     SwFrm* pRet;
203cdf0e10cSrcweir     if( !pIter )
20446d2a04eSHerbert Dürr         return NULL;
205cdf0e10cSrcweir     if( !bInit )
206cdf0e10cSrcweir     {
207cdf0e10cSrcweir          pRet = pIter->First();
208cdf0e10cSrcweir          bInit = sal_True;
209cdf0e10cSrcweir     }
210cdf0e10cSrcweir     else
211cdf0e10cSrcweir         pRet = pIter->Next();
212cdf0e10cSrcweir     while( pRet )
213cdf0e10cSrcweir     {
214cdf0e10cSrcweir         SwFlowFrm* pFlow = SwFlowFrm::CastFlowFrm( pRet );
215cdf0e10cSrcweir         ASSERT( pFlow, "Cntnt or Table expected?!" );
216cdf0e10cSrcweir         // Follows sind fluechtige Gestalten, deshalb werden sie ignoriert.
217cdf0e10cSrcweir         // Auch wenn wir hinter dem Frame eingefuegt werden sollen, nehmen wir
218cdf0e10cSrcweir         // zunaechst den Master, hangeln uns dann aber zum letzten Follow durch.
219cdf0e10cSrcweir         if( !pFlow->IsFollow() )
220cdf0e10cSrcweir         {
221cdf0e10cSrcweir             if( !bMaster )
222cdf0e10cSrcweir             {
223cdf0e10cSrcweir                 while( pFlow->HasFollow() )
224cdf0e10cSrcweir                     pFlow = pFlow->GetFollow();
225cdf0e10cSrcweir                 pRet = pFlow->GetFrm();
226cdf0e10cSrcweir             }
227cdf0e10cSrcweir             if( pRet->IsInSct() )
228cdf0e10cSrcweir             {
229cdf0e10cSrcweir                 SwSectionFrm* pSct = pRet->FindSctFrm();
230cdf0e10cSrcweir                 // Vorsicht: Wenn wir in einer Fussnote sind, so kann diese
231cdf0e10cSrcweir                 // Layoutmaessig in einem spaltigen Bereich liegen, obwohl
232cdf0e10cSrcweir                 // sie nodemaessig ausserhalb liegt. Deshalb muss bei Fussnoten
233cdf0e10cSrcweir                 // ueberprueft werden, ob auch der SectionFrm in der Fussnote
234cdf0e10cSrcweir                 // und nicht ausserhalb liegt.
235cdf0e10cSrcweir                 if( !pRet->IsInFtn() || pSct->IsInFtn() )
236cdf0e10cSrcweir                 {
237cdf0e10cSrcweir                     ASSERT( pSct && pSct->GetSection(), "Where's my section?" );
238cdf0e10cSrcweir                     SwSectionNode* pNd = pSct->GetSection()->GetFmt()->GetSectionNode();
239cdf0e10cSrcweir                     ASSERT( pNd, "Lost SectionNode" );
240cdf0e10cSrcweir                     // Wenn der erhaltene Frame in einem Bereichsframe steht,
241cdf0e10cSrcweir                     // dessen Bereich den Ausgangsnode nicht umfasst, so kehren
242cdf0e10cSrcweir                     // wir mit dem SectionFrm zurueck, sonst mit dem Cntnt/TabFrm
243cdf0e10cSrcweir                     if( bMaster )
244cdf0e10cSrcweir                     {
245cdf0e10cSrcweir                         if( pNd->GetIndex() >= nIndex )
246cdf0e10cSrcweir                             pRet = pSct;
247cdf0e10cSrcweir                     }
248cdf0e10cSrcweir                     else if( pNd->EndOfSectionIndex() < nIndex )
249cdf0e10cSrcweir                         pRet = pSct;
250cdf0e10cSrcweir                 }
251cdf0e10cSrcweir             }
252cdf0e10cSrcweir             return pRet;
253cdf0e10cSrcweir         }
254cdf0e10cSrcweir         pRet = pIter->Next();
255cdf0e10cSrcweir     }
256cdf0e10cSrcweir     return NULL;
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
SaveUpperFrms()259cdf0e10cSrcweir void SwNode2LayImpl::SaveUpperFrms()
260cdf0e10cSrcweir {
261cdf0e10cSrcweir     pUpperFrms = new SvPtrarr( 0, 20 );
262cdf0e10cSrcweir     SwFrm* pFrm;
263cdf0e10cSrcweir     while( 0 != (pFrm = NextFrm()) )
264cdf0e10cSrcweir     {
265cdf0e10cSrcweir         SwFrm* pPrv = pFrm->GetPrev();
266cdf0e10cSrcweir         pFrm = pFrm->GetUpper();
267cdf0e10cSrcweir         if( pFrm )
268cdf0e10cSrcweir         {
269cdf0e10cSrcweir             if( pFrm->IsFtnFrm() )
270cdf0e10cSrcweir                 ((SwFtnFrm*)pFrm)->ColLock();
271cdf0e10cSrcweir             else if( pFrm->IsInSct() )
272cdf0e10cSrcweir                 pFrm->FindSctFrm()->ColLock();
273cdf0e10cSrcweir             if( pPrv && pPrv->IsSctFrm() )
274cdf0e10cSrcweir                 ((SwSectionFrm*)pPrv)->LockJoin();
275cdf0e10cSrcweir             pUpperFrms->Insert( (void*)pPrv, pUpperFrms->Count() );
276cdf0e10cSrcweir             pUpperFrms->Insert( (void*)pFrm, pUpperFrms->Count() );
277cdf0e10cSrcweir         }
278cdf0e10cSrcweir     }
279cdf0e10cSrcweir     delete pIter;
280cdf0e10cSrcweir     pIter = NULL;
281cdf0e10cSrcweir     pMod = 0;
282cdf0e10cSrcweir }
283cdf0e10cSrcweir 
UpperFrm(SwFrm * & rpFrm,const SwNode & rNode)284cdf0e10cSrcweir SwLayoutFrm* SwNode2LayImpl::UpperFrm( SwFrm* &rpFrm, const SwNode &rNode )
285cdf0e10cSrcweir {
286cdf0e10cSrcweir     rpFrm = NextFrm();
287cdf0e10cSrcweir     if( !rpFrm )
288cdf0e10cSrcweir         return NULL;
289cdf0e10cSrcweir     SwLayoutFrm* pUpper = rpFrm->GetUpper();
290cdf0e10cSrcweir     if( rpFrm->IsSctFrm() )
291cdf0e10cSrcweir     {
292cdf0e10cSrcweir         const SwNode* pNode = rNode.StartOfSectionNode();
293cdf0e10cSrcweir         if( pNode->IsSectionNode() )
294cdf0e10cSrcweir         {
295cdf0e10cSrcweir             SwFrm* pFrm = bMaster ? rpFrm->FindPrev() : rpFrm->FindNext();
296cdf0e10cSrcweir             if( pFrm && pFrm->IsSctFrm() )
297cdf0e10cSrcweir             {
298cdf0e10cSrcweir                 // #137684#: pFrm could be a "dummy"-section
299cdf0e10cSrcweir                 if( ((SwSectionFrm*)pFrm)->GetSection() &&
300cdf0e10cSrcweir                     (&((SwSectionNode*)pNode)->GetSection() ==
301cdf0e10cSrcweir                      ((SwSectionFrm*)pFrm)->GetSection()) )
302cdf0e10cSrcweir                 {
303cdf0e10cSrcweir                     // OD 2004-06-02 #i22922# - consider columned sections
304cdf0e10cSrcweir                     // 'Go down' the section frame as long as the layout frame
305cdf0e10cSrcweir                     // is found, which would contain content.
306cdf0e10cSrcweir                     while ( pFrm->IsLayoutFrm() &&
307cdf0e10cSrcweir                             static_cast<SwLayoutFrm*>(pFrm)->Lower() &&
308cdf0e10cSrcweir                             !static_cast<SwLayoutFrm*>(pFrm)->Lower()->IsFlowFrm() &&
309cdf0e10cSrcweir                             static_cast<SwLayoutFrm*>(pFrm)->Lower()->IsLayoutFrm() )
310cdf0e10cSrcweir                     {
311cdf0e10cSrcweir                         pFrm = static_cast<SwLayoutFrm*>(pFrm)->Lower();
312cdf0e10cSrcweir                     }
313cdf0e10cSrcweir                     ASSERT( pFrm->IsLayoutFrm(),
314cdf0e10cSrcweir                             "<SwNode2LayImpl::UpperFrm(..)> - expected upper frame isn't a layout frame." );
315cdf0e10cSrcweir                     rpFrm = bMaster ? NULL
316cdf0e10cSrcweir                                     : static_cast<SwLayoutFrm*>(pFrm)->Lower();
317cdf0e10cSrcweir                     ASSERT( !rpFrm || rpFrm->IsFlowFrm(),
318cdf0e10cSrcweir                             "<SwNode2LayImpl::UpperFrm(..)> - expected sibling isn't a flow frame." );
319cdf0e10cSrcweir                     return static_cast<SwLayoutFrm*>(pFrm);
320cdf0e10cSrcweir                 }
321cdf0e10cSrcweir 
322cdf0e10cSrcweir                 pUpper = new SwSectionFrm(((SwSectionNode*)pNode)->GetSection(), rpFrm);
323cdf0e10cSrcweir                 pUpper->Paste( rpFrm->GetUpper(),
324cdf0e10cSrcweir                                bMaster ? rpFrm : rpFrm->GetNext() );
325cdf0e10cSrcweir                 static_cast<SwSectionFrm*>(pUpper)->Init();
326cdf0e10cSrcweir                 rpFrm = NULL;
327cdf0e10cSrcweir                 // 'Go down' the section frame as long as the layout frame
328cdf0e10cSrcweir                 // is found, which would contain content.
329cdf0e10cSrcweir                 while ( pUpper->Lower() &&
330cdf0e10cSrcweir                         !pUpper->Lower()->IsFlowFrm() &&
331cdf0e10cSrcweir                         pUpper->Lower()->IsLayoutFrm() )
332cdf0e10cSrcweir                 {
333cdf0e10cSrcweir                     pUpper = static_cast<SwLayoutFrm*>(pUpper->Lower());
334cdf0e10cSrcweir                 }
335cdf0e10cSrcweir                 return pUpper;
336cdf0e10cSrcweir             }
337cdf0e10cSrcweir         }
338cdf0e10cSrcweir     };
339cdf0e10cSrcweir     if( !bMaster )
340cdf0e10cSrcweir         rpFrm = rpFrm->GetNext();
341cdf0e10cSrcweir     return pUpper;
342cdf0e10cSrcweir }
343cdf0e10cSrcweir 
RestoreUpperFrms(SwNodes & rNds,sal_uLong nStt,sal_uLong nEnd)344cdf0e10cSrcweir void SwNode2LayImpl::RestoreUpperFrms( SwNodes& rNds, sal_uLong nStt, sal_uLong nEnd )
345cdf0e10cSrcweir {
346cdf0e10cSrcweir     ASSERT( pUpperFrms, "RestoreUpper without SaveUpper?" )
347cdf0e10cSrcweir     SwNode* pNd;
348cdf0e10cSrcweir     SwDoc *pDoc = rNds.GetDoc();
349cdf0e10cSrcweir     sal_Bool bFirst = sal_True;
350cdf0e10cSrcweir     for( ; nStt < nEnd; ++nStt )
351cdf0e10cSrcweir     {
352cdf0e10cSrcweir         SwFrm* pNew = 0;
353cdf0e10cSrcweir         SwFrm* pNxt;
354cdf0e10cSrcweir         SwLayoutFrm* pUp;
355cdf0e10cSrcweir         if( (pNd = rNds[nStt])->IsCntntNode() )
356cdf0e10cSrcweir             for( sal_uInt16 n = 0; n < pUpperFrms->Count(); )
357cdf0e10cSrcweir             {
358cdf0e10cSrcweir                 pNxt = (SwFrm*)(*pUpperFrms)[n++];
359cdf0e10cSrcweir                 if( bFirst && pNxt && pNxt->IsSctFrm() )
360cdf0e10cSrcweir                     ((SwSectionFrm*)pNxt)->UnlockJoin();
361cdf0e10cSrcweir                 pUp = (SwLayoutFrm*)(*pUpperFrms)[n++];
362cdf0e10cSrcweir                 if( pNxt )
363cdf0e10cSrcweir                     pNxt = pNxt->GetNext();
364cdf0e10cSrcweir                 else
365cdf0e10cSrcweir                     pNxt = pUp->Lower();
366cdf0e10cSrcweir                 pNew = ((SwCntntNode*)pNd)->MakeFrm( pUp );
367cdf0e10cSrcweir                 pNew->Paste( pUp, pNxt );
368cdf0e10cSrcweir                 (*pUpperFrms)[n-2] = pNew;
369cdf0e10cSrcweir             }
370cdf0e10cSrcweir         else if( pNd->IsTableNode() )
371cdf0e10cSrcweir             for( sal_uInt16 x = 0; x < pUpperFrms->Count(); )
372cdf0e10cSrcweir             {
373cdf0e10cSrcweir                 pNxt = (SwFrm*)(*pUpperFrms)[x++];
374cdf0e10cSrcweir                 if( bFirst && pNxt && pNxt->IsSctFrm() )
375cdf0e10cSrcweir                     ((SwSectionFrm*)pNxt)->UnlockJoin();
376cdf0e10cSrcweir                 pUp = (SwLayoutFrm*)(*pUpperFrms)[x++];
377cdf0e10cSrcweir                 if( pNxt )
378cdf0e10cSrcweir                     pNxt = pNxt->GetNext();
379cdf0e10cSrcweir                 else
380cdf0e10cSrcweir                     pNxt = pUp->Lower();
381cdf0e10cSrcweir                 pNew = ((SwTableNode*)pNd)->MakeFrm( pUp );
382*7de601c3SJohn Bampton                 ASSERT( pNew->IsTabFrm(), "Table expected" );
383cdf0e10cSrcweir                 pNew->Paste( pUp, pNxt );
384cdf0e10cSrcweir                 ((SwTabFrm*)pNew)->RegistFlys();
385cdf0e10cSrcweir                 (*pUpperFrms)[x-2] = pNew;
386cdf0e10cSrcweir             }
387cdf0e10cSrcweir         else if( pNd->IsSectionNode() )
388cdf0e10cSrcweir         {
389cdf0e10cSrcweir             nStt = pNd->EndOfSectionIndex();
390cdf0e10cSrcweir             for( sal_uInt16 x = 0; x < pUpperFrms->Count(); )
391cdf0e10cSrcweir             {
392cdf0e10cSrcweir                 pNxt = (SwFrm*)(*pUpperFrms)[x++];
393cdf0e10cSrcweir                 if( bFirst && pNxt && pNxt->IsSctFrm() )
394cdf0e10cSrcweir                     ((SwSectionFrm*)pNxt)->UnlockJoin();
395cdf0e10cSrcweir                 pUp = (SwLayoutFrm*)(*pUpperFrms)[x++];
396cdf0e10cSrcweir                 ASSERT( pUp->GetUpper() || pUp->IsFlyFrm(), "Lost Upper" );
397cdf0e10cSrcweir                 ::_InsertCnt( pUp, pDoc, pNd->GetIndex(), sal_False, nStt+1, pNxt );
398cdf0e10cSrcweir                 pNxt = pUp->GetLastLower();
399cdf0e10cSrcweir                 (*pUpperFrms)[x-2] = pNxt;
400cdf0e10cSrcweir             }
401cdf0e10cSrcweir         }
402cdf0e10cSrcweir         bFirst = sal_False;
403cdf0e10cSrcweir     }
404cdf0e10cSrcweir     for( sal_uInt16 x = 0; x < pUpperFrms->Count(); ++x )
405cdf0e10cSrcweir     {
406cdf0e10cSrcweir         SwFrm* pTmp = (SwFrm*)(*pUpperFrms)[++x];
407cdf0e10cSrcweir         if( pTmp->IsFtnFrm() )
408cdf0e10cSrcweir             ((SwFtnFrm*)pTmp)->ColUnlock();
409cdf0e10cSrcweir         else if ( pTmp->IsInSct() )
410cdf0e10cSrcweir         {
411cdf0e10cSrcweir             SwSectionFrm* pSctFrm = pTmp->FindSctFrm();
412cdf0e10cSrcweir             pSctFrm->ColUnlock();
413cdf0e10cSrcweir             // OD 26.08.2003 #i18103# - invalidate size of section in order to
414cdf0e10cSrcweir             // assure, that the section is formatted, unless it was 'Collocked'
415cdf0e10cSrcweir             // from its 'collection' until its 'restoration'.
416cdf0e10cSrcweir             pSctFrm->_InvalidateSize();
417cdf0e10cSrcweir         }
418cdf0e10cSrcweir     }
419cdf0e10cSrcweir }
420cdf0e10cSrcweir 
GetFrm(const Point * pDocPos,const SwPosition * pPos,const sal_Bool bCalcFrm) const421cdf0e10cSrcweir SwFrm* SwNode2LayImpl::GetFrm( const Point* pDocPos,
422cdf0e10cSrcweir                                 const SwPosition *pPos,
423cdf0e10cSrcweir                                 const sal_Bool bCalcFrm ) const
424cdf0e10cSrcweir {
425cdf0e10cSrcweir     // mba: test if change of member pIter -> pMod broke anything
426cdf0e10cSrcweir     return pMod ? ::GetFrmOfModify( 0, *pMod, USHRT_MAX, pDocPos, pPos, bCalcFrm ) : 0;
427cdf0e10cSrcweir }
428cdf0e10cSrcweir 
SwNode2Layout(const SwNode & rNd,sal_uLong nIdx)429cdf0e10cSrcweir SwNode2Layout::SwNode2Layout( const SwNode& rNd, sal_uLong nIdx )
430cdf0e10cSrcweir {
431cdf0e10cSrcweir     pImpl = new SwNode2LayImpl( rNd, nIdx, sal_False );
432cdf0e10cSrcweir }
433cdf0e10cSrcweir 
SwNode2Layout(const SwNode & rNd)434cdf0e10cSrcweir SwNode2Layout::SwNode2Layout( const SwNode& rNd )
435cdf0e10cSrcweir {
436cdf0e10cSrcweir     pImpl = new SwNode2LayImpl( rNd, rNd.GetIndex(), sal_True );
437cdf0e10cSrcweir     pImpl->SaveUpperFrms();
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
RestoreUpperFrms(SwNodes & rNds,sal_uLong nStt,sal_uLong nEnd)440cdf0e10cSrcweir void SwNode2Layout::RestoreUpperFrms( SwNodes& rNds, sal_uLong nStt, sal_uLong nEnd )
441cdf0e10cSrcweir {
442cdf0e10cSrcweir     ASSERT( pImpl, "RestoreUpperFrms without SaveUpperFrms" );
443cdf0e10cSrcweir     pImpl->RestoreUpperFrms( rNds, nStt, nEnd );
444cdf0e10cSrcweir }
445cdf0e10cSrcweir 
NextFrm()446cdf0e10cSrcweir SwFrm* SwNode2Layout::NextFrm()
447cdf0e10cSrcweir {
448cdf0e10cSrcweir     return pImpl->NextFrm();
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
UpperFrm(SwFrm * & rpFrm,const SwNode & rNode)451cdf0e10cSrcweir SwLayoutFrm* SwNode2Layout::UpperFrm( SwFrm* &rpFrm, const SwNode &rNode )
452cdf0e10cSrcweir {
453cdf0e10cSrcweir     return pImpl->UpperFrm( rpFrm, rNode );
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
~SwNode2Layout()456cdf0e10cSrcweir SwNode2Layout::~SwNode2Layout()
457cdf0e10cSrcweir {
458cdf0e10cSrcweir     delete pImpl;
459cdf0e10cSrcweir }
460cdf0e10cSrcweir 
GetFrm(const Point * pDocPos,const SwPosition * pPos,const sal_Bool bCalcFrm) const461cdf0e10cSrcweir SwFrm* SwNode2Layout::GetFrm( const Point* pDocPos,
462cdf0e10cSrcweir                                 const SwPosition *pPos,
463cdf0e10cSrcweir                                 const sal_Bool bCalcFrm ) const
464cdf0e10cSrcweir {
465cdf0e10cSrcweir     return pImpl->GetFrm( pDocPos, pPos, bCalcFrm );
466cdf0e10cSrcweir }
467