xref: /aoo41x/main/sw/source/core/docnode/node2lay.cxx (revision 46d2a04e)
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
10efeef26fSAndrew Rist  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12efeef26fSAndrew Rist  *
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.
19efeef26fSAndrew Rist  *
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 )
204*46d2a04eSHerbert 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 );
382cdf0e10cSrcweir 				ASSERT( pNew->IsTabFrm(), "Table exspected" );
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 }
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 
469