xref: /aoo41x/main/sw/source/core/docnode/nodes.cxx (revision dec99bbd)
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 <stdlib.h>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <node.hxx>
30cdf0e10cSrcweir #include <doc.hxx>
31cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
32cdf0e10cSrcweir #include <pam.hxx>
33cdf0e10cSrcweir #include <txtfld.hxx>
34cdf0e10cSrcweir #include <fmtfld.hxx>
35cdf0e10cSrcweir #include <hints.hxx>
36cdf0e10cSrcweir #include <numrule.hxx>
37cdf0e10cSrcweir #include <ndtxt.hxx>
38cdf0e10cSrcweir #include <ndnotxt.hxx>
39cdf0e10cSrcweir #include <swtable.hxx>      // fuer erzuegen / loeschen der Table-Frames
40cdf0e10cSrcweir #include <tblsel.hxx>
41cdf0e10cSrcweir #include <section.hxx>
42cdf0e10cSrcweir #include <ddefld.hxx>
43cdf0e10cSrcweir #include <swddetbl.hxx>
44cdf0e10cSrcweir #include <frame.hxx>
45cdf0e10cSrcweir #include <txtatr.hxx>
46cdf0e10cSrcweir #include <tox.hxx> // InvalidateTOXMark
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include <docsh.hxx>
49cdf0e10cSrcweir #include <svl/smplhint.hxx>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir extern sal_Bool CheckNodesRange( const SwNodeIndex& rStt,
52cdf0e10cSrcweir 							const SwNodeIndex& rEnd, sal_Bool bChkSection );
53cdf0e10cSrcweir 
54cdf0e10cSrcweir SV_DECL_PTRARR(SwSttNdPtrs,SwStartNode*,2,2)
55cdf0e10cSrcweir 
56cdf0e10cSrcweir 
57cdf0e10cSrcweir //#define JP_DEBUG
58cdf0e10cSrcweir #ifdef JP_DEBUG
59cdf0e10cSrcweir #include "shellio.hxx"
60cdf0e10cSrcweir #endif
61cdf0e10cSrcweir 
62cdf0e10cSrcweir 
63cdf0e10cSrcweir // Funktion zum bestimmen des hoechsten Levels innerhalb des Bereiches
64cdf0e10cSrcweir 
65cdf0e10cSrcweir sal_uInt16 HighestLevel( SwNodes & rNodes, const SwNodeRange & rRange );
66cdf0e10cSrcweir 
67cdf0e10cSrcweir //-----------------------------------------------------------------------
68cdf0e10cSrcweir 
69cdf0e10cSrcweir /*******************************************************************
70cdf0e10cSrcweir |*	SwNodes::SwNodes
71cdf0e10cSrcweir |*
72cdf0e10cSrcweir |*	Beschreibung
73cdf0e10cSrcweir |*		Konstruktor; legt die vier Grundsektions (PostIts,
74cdf0e10cSrcweir |*		Inserts, Icons, Inhalt) an
75cdf0e10cSrcweir *******************************************************************/
SwNodes(SwDoc * pDocument)76cdf0e10cSrcweir SwNodes::SwNodes( SwDoc* pDocument )
77cdf0e10cSrcweir 	: pRoot( 0 ), pMyDoc( pDocument )
78cdf0e10cSrcweir {
79cdf0e10cSrcweir 	bInNodesDel = bInDelUpdOutl = bInDelUpdNum = sal_False;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 	ASSERT( pMyDoc, "in welchem Doc stehe ich denn?" );
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 	sal_uLong nPos = 0;
84cdf0e10cSrcweir 	SwStartNode* pSttNd = new SwStartNode( *this, nPos++ );
85cdf0e10cSrcweir 	pEndOfPostIts = new SwEndNode( *this, nPos++, *pSttNd );
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 	SwStartNode* pTmp = new SwStartNode( *this, nPos++ );
88cdf0e10cSrcweir 	pEndOfInserts = new SwEndNode( *this, nPos++, *pTmp );
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 	pTmp = new SwStartNode( *this, nPos++ );
91cdf0e10cSrcweir 	pTmp->pStartOfSection = pSttNd;
92cdf0e10cSrcweir 	pEndOfAutotext = new SwEndNode( *this, nPos++, *pTmp );
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 	pTmp = new SwStartNode( *this, nPos++ );
95cdf0e10cSrcweir 	pTmp->pStartOfSection = pSttNd;
96cdf0e10cSrcweir 	pEndOfRedlines = new SwEndNode( *this, nPos++, *pTmp );
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 	pTmp = new SwStartNode( *this, nPos++ );
99cdf0e10cSrcweir 	pTmp->pStartOfSection = pSttNd;
100cdf0e10cSrcweir 	pEndOfContent = new SwEndNode( *this, nPos++, *pTmp );
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	pOutlineNds = new SwOutlineNodes;
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir /*******************************************************************
106cdf0e10cSrcweir |*
107cdf0e10cSrcweir |*	SwNodes::~SwNodes
108cdf0e10cSrcweir |*
109cdf0e10cSrcweir |*	Beschreibung
110cdf0e10cSrcweir |*		dtor, loescht alle Nodes, deren Pointer in diesem dynamischen
111cdf0e10cSrcweir |*		Array sind. Ist kein Problem, da Nodes ausserhalb dieses
112cdf0e10cSrcweir |*		Arrays nicht erzeugt werden koennen und somit auch nicht
113cdf0e10cSrcweir |*		in mehreren drin sein koennen
114cdf0e10cSrcweir |*
115cdf0e10cSrcweir |*	Ersterstellung
116cdf0e10cSrcweir |*		VER0100 vb 901214
117cdf0e10cSrcweir |*
118cdf0e10cSrcweir |*	Stand
119cdf0e10cSrcweir |*		VER0100 vb 901214
120cdf0e10cSrcweir |*
121cdf0e10cSrcweir *******************************************************************/
122cdf0e10cSrcweir 
~SwNodes()123cdf0e10cSrcweir SwNodes::~SwNodes()
124cdf0e10cSrcweir {
125cdf0e10cSrcweir 	delete pOutlineNds;
126cdf0e10cSrcweir 
127cdf0e10cSrcweir 	{
128cdf0e10cSrcweir 		SwNode *pNode;
129cdf0e10cSrcweir 		SwNodeIndex aNdIdx( *this );
130cdf0e10cSrcweir 		while( sal_True )
131cdf0e10cSrcweir 		{
132cdf0e10cSrcweir 			pNode = &aNdIdx.GetNode();
133cdf0e10cSrcweir 			if( pNode == pEndOfContent )
134cdf0e10cSrcweir 				break;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 			aNdIdx++;
137cdf0e10cSrcweir 			delete pNode;
138cdf0e10cSrcweir 		}
139cdf0e10cSrcweir 	}
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 	// jetzt muessen alle SwNodeIndizies abgemeldet sein!!!
142cdf0e10cSrcweir 	delete pEndOfContent;
143cdf0e10cSrcweir }
144cdf0e10cSrcweir 
ChgNode(SwNodeIndex & rDelPos,sal_uLong nSz,SwNodeIndex & rInsPos,sal_Bool bNewFrms)145cdf0e10cSrcweir void SwNodes::ChgNode( SwNodeIndex& rDelPos, sal_uLong nSz,
146cdf0e10cSrcweir 						SwNodeIndex& rInsPos, sal_Bool bNewFrms )
147cdf0e10cSrcweir {
148cdf0e10cSrcweir 	// im UndoBereich brauchen wir keine Frames
149cdf0e10cSrcweir 	SwNodes& rNds = rInsPos.GetNodes();
150cdf0e10cSrcweir 	const SwNode* pPrevInsNd = rNds[ rInsPos.GetIndex() -1 ];
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 	//JP 03.02.99: alle Felder als invalide erklaeren, aktu. erfolgt im
153cdf0e10cSrcweir 	//				Idle-Handler des Docs
154cdf0e10cSrcweir 	if( GetDoc()->SetFieldsDirty( sal_True, &rDelPos.GetNode(), nSz ) &&
155cdf0e10cSrcweir 		rNds.GetDoc() != GetDoc() )
156cdf0e10cSrcweir 		rNds.GetDoc()->SetFieldsDirty( true, NULL, 0 );
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 	//JP 12.03.99: 63293 - Nodes vom RedlineBereich NIE aufnehmen
159cdf0e10cSrcweir 	sal_uLong nNd = rInsPos.GetIndex();
160cdf0e10cSrcweir 	sal_Bool bInsOutlineIdx = !(
161cdf0e10cSrcweir             rNds.GetEndOfRedlines().StartOfSectionNode()->GetIndex() < nNd &&
162cdf0e10cSrcweir 			nNd < rNds.GetEndOfRedlines().GetIndex() );
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 	if( &rNds == this ) 		// im gleichen Nodes-Array -> moven !!
165cdf0e10cSrcweir 	{
166cdf0e10cSrcweir 		// wird von vorne nach hinten gemovt, so wird nach vorne immer
167cdf0e10cSrcweir 		// nachgeschoben, d.H. die Loeschposition ist immer gleich
168cdf0e10cSrcweir 		sal_uInt16 nDiff = rDelPos.GetIndex() < rInsPos.GetIndex() ? 0 : 1;
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 		for( sal_uLong n = rDelPos.GetIndex(); nSz; n += nDiff, --nSz )
171cdf0e10cSrcweir 		{
172cdf0e10cSrcweir 			SwNodeIndex aDelIdx( *this, n );
173cdf0e10cSrcweir 			SwNode& rNd = aDelIdx.GetNode();
174cdf0e10cSrcweir 
175cdf0e10cSrcweir             // --> OD 2005-11-16 #i57920#
176cdf0e10cSrcweir             // correction of refactoring done by cws swnumtree:
177cdf0e10cSrcweir             // - <SwTxtNode::SetLevel( NO_NUMBERING ) is deprecated and
178cdf0e10cSrcweir             //   set <IsCounted> state of the text node to <false>, which
179cdf0e10cSrcweir             //   isn't correct here.
180cdf0e10cSrcweir             if ( rNd.IsTxtNode() )
181cdf0e10cSrcweir             {
182cdf0e10cSrcweir                 SwTxtNode* pTxtNode = rNd.GetTxtNode();
183cdf0e10cSrcweir                 pTxtNode->RemoveFromList();
184cdf0e10cSrcweir 
18569a74367SOliver-Rainer Wittmann                 //if ( pTxtNode->GetTxtColl()->GetOutlineLevel() != NO_NUMBERING )//#outline level,zhaojianwei
186cdf0e10cSrcweir                 if ( pTxtNode->GetAttrOutlineLevel() != 0 )//<-end,zhaojianwei
187cdf0e10cSrcweir                 {
188cdf0e10cSrcweir                     const SwNodePtr pSrch = (SwNodePtr)&rNd;
189cdf0e10cSrcweir                     pOutlineNds->Remove( pSrch );
190cdf0e10cSrcweir                 }
191cdf0e10cSrcweir             }
192cdf0e10cSrcweir             // <--
193cdf0e10cSrcweir 
19469a74367SOliver-Rainer Wittmann             BigPtrArray::Move( aDelIdx.GetIndex(), rInsPos.GetIndex() );
195cdf0e10cSrcweir 
19669a74367SOliver-Rainer Wittmann             if( rNd.IsTxtNode() )
19769a74367SOliver-Rainer Wittmann             {
19869a74367SOliver-Rainer Wittmann                 SwTxtNode& rTxtNd = (SwTxtNode&)rNd;
199cdf0e10cSrcweir                 rTxtNd.AddToList();
200cdf0e10cSrcweir 
201cdf0e10cSrcweir                 if( bInsOutlineIdx &&
20269a74367SOliver-Rainer Wittmann                     //NO_NUMBERING != rTxtNd.GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
203cdf0e10cSrcweir                     0 != rTxtNd.GetAttrOutlineLevel() )//<-end,zhaojianwei
20469a74367SOliver-Rainer Wittmann                 {
20569a74367SOliver-Rainer Wittmann                     const SwNodePtr pSrch = (SwNodePtr)&rNd;
20669a74367SOliver-Rainer Wittmann                     pOutlineNds->Insert( pSrch );
20769a74367SOliver-Rainer Wittmann                 }
20869a74367SOliver-Rainer Wittmann                 rTxtNd.InvalidateNumRule();
209cdf0e10cSrcweir 
210cdf0e10cSrcweir //FEATURE::CONDCOLL
211cdf0e10cSrcweir 				if( RES_CONDTXTFMTCOLL == rTxtNd.GetTxtColl()->Which() )
212cdf0e10cSrcweir 					rTxtNd.ChkCondColl();
213cdf0e10cSrcweir //FEATURE::CONDCOLL
214cdf0e10cSrcweir 			}
215cdf0e10cSrcweir 			else if( rNd.IsCntntNode() )
216cdf0e10cSrcweir 				((SwCntntNode&)rNd).InvalidateNumRule();
217cdf0e10cSrcweir 		}
218cdf0e10cSrcweir 	}
219cdf0e10cSrcweir 	else
220cdf0e10cSrcweir 	{
221cdf0e10cSrcweir         bool bSavePersData(GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(rNds));
222cdf0e10cSrcweir         bool bRestPersData(GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(*this));
223cdf0e10cSrcweir 		SwDoc* pDestDoc = rNds.GetDoc() != GetDoc() ? rNds.GetDoc() : 0;
224cdf0e10cSrcweir         OSL_ENSURE(!pDestDoc, "SwNodes::ChgNode(): "
225cdf0e10cSrcweir             "the code to handle text fields here looks broken\n"
226cdf0e10cSrcweir             "if the target is in a different document.");
227cdf0e10cSrcweir 		if( !bRestPersData && !bSavePersData && pDestDoc )
228cdf0e10cSrcweir 			bSavePersData = bRestPersData = sal_True;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 		String sNumRule;
231cdf0e10cSrcweir 		SwNodeIndex aInsPos( rInsPos );
232cdf0e10cSrcweir 		for( sal_uLong n = 0; n < nSz; n++ )
233cdf0e10cSrcweir 		{
234cdf0e10cSrcweir 			SwNode* pNd = &rDelPos.GetNode();
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 			// NoTextNode muessen ihre Persitenten Daten mitnehmen
237cdf0e10cSrcweir 			if( pNd->IsNoTxtNode() )
238cdf0e10cSrcweir 			{
239cdf0e10cSrcweir 				if( bSavePersData )
240cdf0e10cSrcweir 					((SwNoTxtNode*)pNd)->SavePersistentData();
241cdf0e10cSrcweir 			}
242cdf0e10cSrcweir 			else if( pNd->IsTxtNode() )
243cdf0e10cSrcweir 			{
244cdf0e10cSrcweir 				SwTxtNode* pTxtNd = (SwTxtNode*)pNd;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 				// loesche die Gliederungs-Indizies aus dem alten Nodes-Array
247cdf0e10cSrcweir 				//if( NO_NUMBERING != pTxtNd->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
248cdf0e10cSrcweir 				if( 0 != pTxtNd->GetAttrOutlineLevel() )//<-end,zhaojianwei
249cdf0e10cSrcweir 					pOutlineNds->Remove( pNd );
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 				// muss die Rule kopiere werden?
252cdf0e10cSrcweir 				if( pDestDoc )
253cdf0e10cSrcweir 				{
254cdf0e10cSrcweir 					const SwNumRule* pNumRule = pTxtNd->GetNumRule();
255cdf0e10cSrcweir 					if( pNumRule && sNumRule != pNumRule->GetName() )
256cdf0e10cSrcweir 					{
257cdf0e10cSrcweir 						sNumRule = pNumRule->GetName();
258cdf0e10cSrcweir 						SwNumRule* pDestRule = pDestDoc->FindNumRulePtr( sNumRule );
259cdf0e10cSrcweir 						if( pDestRule )
260cdf0e10cSrcweir 							pDestRule->SetInvalidRule( sal_True );
261cdf0e10cSrcweir 						else
262cdf0e10cSrcweir 							pDestDoc->MakeNumRule( sNumRule, pNumRule );
263cdf0e10cSrcweir 					}
264cdf0e10cSrcweir 				}
265cdf0e10cSrcweir 				else
266cdf0e10cSrcweir 					// wenns ins UndoNodes-Array gemoved wird, sollten die
267cdf0e10cSrcweir 					// Numerierungen auch aktualisiert werden.
268cdf0e10cSrcweir 					pTxtNd->InvalidateNumRule();
269cdf0e10cSrcweir 
270cdf0e10cSrcweir                 pTxtNd->RemoveFromList();
27169a74367SOliver-Rainer Wittmann             }
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 			RemoveNode( rDelPos.GetIndex(), 1, sal_False );		// Indizies verschieben !!
274cdf0e10cSrcweir 			SwCntntNode * pCNd = pNd->GetCntntNode();
275cdf0e10cSrcweir             rNds.InsertNode( pNd, aInsPos );
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 			if( pCNd )
278cdf0e10cSrcweir 			{
279cdf0e10cSrcweir 				SwTxtNode* pTxtNd = pCNd->GetTxtNode();
280cdf0e10cSrcweir 				if( pTxtNd )
281cdf0e10cSrcweir                 {
282cdf0e10cSrcweir                     SwpHints * const pHts = pTxtNd->GetpSwpHints();
283cdf0e10cSrcweir 					// setze die OultineNodes im neuen Nodes-Array
284cdf0e10cSrcweir 					//if( bInsOutlineIdx && NO_NUMBERING !=	//#outline level,removed by zhaojianwei
285cdf0e10cSrcweir 					//	pTxtNd->GetTxtColl()->GetOutlineLevel() )
286cdf0e10cSrcweir                     if( bInsOutlineIdx &&
287cdf0e10cSrcweir                         0 != pTxtNd->GetAttrOutlineLevel() ) //#outline level,added by zhaojianwei
288cdf0e10cSrcweir                     {
289cdf0e10cSrcweir 						rNds.pOutlineNds->Insert( pTxtNd );
290cdf0e10cSrcweir                     }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir                     pTxtNd->AddToList();
293cdf0e10cSrcweir 
294*dec99bbdSOliver-Rainer Wittmann                     // Sonderbehandlung fuer die Felder!
295*dec99bbdSOliver-Rainer Wittmann                     if( pHts && pHts->Count() )
296cdf0e10cSrcweir                     {
297cdf0e10cSrcweir                         // this looks fishy if pDestDoc != 0
298cdf0e10cSrcweir                         bool const bToUndo = !pDestDoc &&
299cdf0e10cSrcweir                             GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(rNds);
300*dec99bbdSOliver-Rainer Wittmann                         for( sal_uInt16 i = pHts->Count(); i; )
301*dec99bbdSOliver-Rainer Wittmann                         {
302*dec99bbdSOliver-Rainer Wittmann                             sal_uInt16 nDelMsg = 0;
303cdf0e10cSrcweir                             SwTxtAttr * const pAttr = pHts->GetTextHint( --i );
304cdf0e10cSrcweir                             switch ( pAttr->Which() )
305cdf0e10cSrcweir                             {
306cdf0e10cSrcweir                             case RES_TXTATR_FIELD:
307*dec99bbdSOliver-Rainer Wittmann                             case RES_TXTATR_ANNOTATION:
30869a74367SOliver-Rainer Wittmann                             case RES_TXTATR_INPUTFIELD:
309cdf0e10cSrcweir                                 {
31069a74367SOliver-Rainer Wittmann                                     SwTxtFld* pTxtFld = static_cast<SwTxtFld*>(pAttr);
311c0286415SOliver-Rainer Wittmann                                     rNds.GetDoc()->InsDelFldInFldLst( !bToUndo, *pTxtFld );
312c0286415SOliver-Rainer Wittmann 
313c0286415SOliver-Rainer Wittmann                                     const SwFieldType* pTyp = pTxtFld->GetFmtFld().GetField()->GetTyp();
314c0286415SOliver-Rainer Wittmann                                     if ( RES_POSTITFLD == pTyp->Which() )
315c0286415SOliver-Rainer Wittmann                                     {
316c0286415SOliver-Rainer Wittmann                                         rNds.GetDoc()->GetDocShell()->Broadcast(
317c0286415SOliver-Rainer Wittmann                                             SwFmtFldHint(
318c0286415SOliver-Rainer Wittmann                                                 &pTxtFld->GetFmtFld(),
319c0286415SOliver-Rainer Wittmann                                                 ( pTxtFld->GetFmtFld().IsFldInDoc()
320c0286415SOliver-Rainer Wittmann                                                   ? SWFMTFLD_INSERTED
321c0286415SOliver-Rainer Wittmann                                                   : SWFMTFLD_REMOVED ) ) );
322*dec99bbdSOliver-Rainer Wittmann                                     }
323*dec99bbdSOliver-Rainer Wittmann                                     else
324*dec99bbdSOliver-Rainer Wittmann                                         if( RES_DDEFLD == pTyp->Which() )
325*dec99bbdSOliver-Rainer Wittmann                                         {
326*dec99bbdSOliver-Rainer Wittmann                                             if( bToUndo )
327*dec99bbdSOliver-Rainer Wittmann                                                 ((SwDDEFieldType*)pTyp)->DecRefCnt();
328*dec99bbdSOliver-Rainer Wittmann                                             else
329*dec99bbdSOliver-Rainer Wittmann                                                 ((SwDDEFieldType*)pTyp)->IncRefCnt();
330*dec99bbdSOliver-Rainer Wittmann                                         }
331*dec99bbdSOliver-Rainer Wittmann                                         nDelMsg = RES_FIELD_DELETED;
332*dec99bbdSOliver-Rainer Wittmann                                 }
333*dec99bbdSOliver-Rainer Wittmann                                 break;
334*dec99bbdSOliver-Rainer Wittmann 
335*dec99bbdSOliver-Rainer Wittmann                             case RES_TXTATR_FTN:
336*dec99bbdSOliver-Rainer Wittmann                                 nDelMsg = RES_FOOTNOTE_DELETED;
337*dec99bbdSOliver-Rainer Wittmann                                 break;
338*dec99bbdSOliver-Rainer Wittmann 
339*dec99bbdSOliver-Rainer Wittmann                             case RES_TXTATR_TOXMARK:
340cdf0e10cSrcweir                                 static_cast<SwTOXMark&>(pAttr->GetAttr())
341cdf0e10cSrcweir                                     .InvalidateTOXMark();
342*dec99bbdSOliver-Rainer Wittmann                                 break;
343cdf0e10cSrcweir 
344*dec99bbdSOliver-Rainer Wittmann                             case RES_TXTATR_REFMARK:
345*dec99bbdSOliver-Rainer Wittmann                                 nDelMsg = RES_REFMARK_DELETED;
346*dec99bbdSOliver-Rainer Wittmann                                 break;
347cdf0e10cSrcweir 
348cdf0e10cSrcweir                             case RES_TXTATR_META:
349cdf0e10cSrcweir                             case RES_TXTATR_METAFIELD:
350cdf0e10cSrcweir                                 {
351cdf0e10cSrcweir                                     SwTxtMeta *const pTxtMeta(
352cdf0e10cSrcweir                                         static_cast<SwTxtMeta*>(pAttr));
353cdf0e10cSrcweir                                     // force removal of UNO object
354cdf0e10cSrcweir                                     pTxtMeta->ChgTxtNode(0);
355cdf0e10cSrcweir                                     pTxtMeta->ChgTxtNode(pTxtNd);
356cdf0e10cSrcweir                                 }
357cdf0e10cSrcweir                                 break;
358cdf0e10cSrcweir 
359cdf0e10cSrcweir                             default:
360cdf0e10cSrcweir                                 break;
361*dec99bbdSOliver-Rainer Wittmann                             }
362cdf0e10cSrcweir 
363*dec99bbdSOliver-Rainer Wittmann                             if( nDelMsg && bToUndo )
364*dec99bbdSOliver-Rainer Wittmann                             {
365*dec99bbdSOliver-Rainer Wittmann                                 SwPtrMsgPoolItem aMsgHint( nDelMsg,
366*dec99bbdSOliver-Rainer Wittmann                                     (void*)&pAttr->GetAttr() );
367*dec99bbdSOliver-Rainer Wittmann                                 rNds.GetDoc()->GetUnoCallBack()->
368*dec99bbdSOliver-Rainer Wittmann                                     ModifyNotification( &aMsgHint, &aMsgHint );
369*dec99bbdSOliver-Rainer Wittmann                             }
370*dec99bbdSOliver-Rainer Wittmann                         }
371*dec99bbdSOliver-Rainer Wittmann                     }
372*dec99bbdSOliver-Rainer Wittmann                     //FEATURE::CONDCOLL
373*dec99bbdSOliver-Rainer Wittmann                     if( RES_CONDTXTFMTCOLL == pTxtNd->GetTxtColl()->Which() )
374*dec99bbdSOliver-Rainer Wittmann                         pTxtNd->ChkCondColl();
375*dec99bbdSOliver-Rainer Wittmann                     //FEATURE::CONDCOLL
376*dec99bbdSOliver-Rainer Wittmann                 }
377*dec99bbdSOliver-Rainer Wittmann                 else
378*dec99bbdSOliver-Rainer Wittmann                 {
379*dec99bbdSOliver-Rainer Wittmann                     // in unterschiedliche Docs gemoved ?
380*dec99bbdSOliver-Rainer Wittmann                     // dann die Daten wieder persistent machen
381*dec99bbdSOliver-Rainer Wittmann                     if( pCNd->IsNoTxtNode() && bRestPersData )
382*dec99bbdSOliver-Rainer Wittmann                         ((SwNoTxtNode*)pCNd)->RestorePersistentData();
383*dec99bbdSOliver-Rainer Wittmann                 }
384*dec99bbdSOliver-Rainer Wittmann             }
385*dec99bbdSOliver-Rainer Wittmann         }
386*dec99bbdSOliver-Rainer Wittmann     }
387*dec99bbdSOliver-Rainer Wittmann 
388*dec99bbdSOliver-Rainer Wittmann     //JP 03.02.99: alle Felder als invalide erklaeren, aktu. erfolgt im
389*dec99bbdSOliver-Rainer Wittmann     //				Idle-Handler des Docs
390*dec99bbdSOliver-Rainer Wittmann     GetDoc()->SetFieldsDirty( true, NULL, 0 );
391*dec99bbdSOliver-Rainer Wittmann     if( rNds.GetDoc() != GetDoc() )
392*dec99bbdSOliver-Rainer Wittmann         rNds.GetDoc()->SetFieldsDirty( true, NULL, 0 );
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 	if( bNewFrms )
396cdf0e10cSrcweir 		bNewFrms = &GetDoc()->GetNodes() == (const SwNodes*)&rNds &&
397cdf0e10cSrcweir 					GetDoc()->GetCurrentViewShell();	//swmod 071108//swmod 071225
398cdf0e10cSrcweir 	if( bNewFrms )
399cdf0e10cSrcweir 	{
400cdf0e10cSrcweir 		// Frames besorgen:
401cdf0e10cSrcweir 		SwNodeIndex aIdx( *pPrevInsNd, 1 );
402cdf0e10cSrcweir 		SwNodeIndex aFrmNdIdx( aIdx );
403cdf0e10cSrcweir 		SwNode* pFrmNd = rNds.FindPrvNxtFrmNode( aFrmNdIdx,
404cdf0e10cSrcweir 										rNds[ rInsPos.GetIndex() - 1 ] );
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 		if( !pFrmNd && aFrmNdIdx > rNds.GetEndOfExtras().GetIndex() )
407cdf0e10cSrcweir 		{
408cdf0e10cSrcweir 			ASSERT( !this, "ob das so richtig ist ??" );
409cdf0e10cSrcweir 			aFrmNdIdx = rNds.GetEndOfContent();
410cdf0e10cSrcweir 			pFrmNd = rNds.GoPrevSection( &aFrmNdIdx, sal_True, sal_False );
411cdf0e10cSrcweir 			if( pFrmNd && !((SwCntntNode*)pFrmNd)->GetDepends() )
412cdf0e10cSrcweir 				pFrmNd = 0;
413cdf0e10cSrcweir 
414cdf0e10cSrcweir #ifdef DBG_UTIL
415cdf0e10cSrcweir 			if( !pFrmNd )
416cdf0e10cSrcweir 				ASSERT( !this, "ChgNode() - kein FrameNode gefunden" );
417cdf0e10cSrcweir #endif
418cdf0e10cSrcweir 		}
419cdf0e10cSrcweir 		if( pFrmNd )
420cdf0e10cSrcweir 			while( aIdx != rInsPos )
421cdf0e10cSrcweir 			{
422cdf0e10cSrcweir 				SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
423cdf0e10cSrcweir 				if( pCNd )
424cdf0e10cSrcweir 				{
425cdf0e10cSrcweir 					if( pFrmNd->IsTableNode() )
426cdf0e10cSrcweir 						((SwTableNode*)pFrmNd)->MakeFrms( aIdx );
427cdf0e10cSrcweir 					else if( pFrmNd->IsSectionNode() )
428cdf0e10cSrcweir 						((SwSectionNode*)pFrmNd)->MakeFrms( aIdx );
429cdf0e10cSrcweir 					else
430cdf0e10cSrcweir 						((SwCntntNode*)pFrmNd)->MakeFrms( *pCNd );
431cdf0e10cSrcweir 					pFrmNd = pCNd;
432cdf0e10cSrcweir 				}
433cdf0e10cSrcweir 				aIdx++;
434cdf0e10cSrcweir 			}
435cdf0e10cSrcweir 	}
436cdf0e10cSrcweir }
437cdf0e10cSrcweir 
438cdf0e10cSrcweir 
439cdf0e10cSrcweir /***********************************************************************
440cdf0e10cSrcweir |*
441cdf0e10cSrcweir |*	SwNodes::Move
442cdf0e10cSrcweir |*
443cdf0e10cSrcweir |*	Beschreibung
444cdf0e10cSrcweir |*	Move loescht die Node-Pointer ab und einschliesslich der Startposition
445cdf0e10cSrcweir |*	bis zu und ausschliesslich der Endposition und fuegt sie an
446cdf0e10cSrcweir |*	der vor der Zielposition ein.
447cdf0e10cSrcweir |*	Wenn das Ziel vor dem ersten oder dem letzten zu bewegenden Element oder
448cdf0e10cSrcweir |*	dazwischen liegt, geschieht nichts.
449cdf0e10cSrcweir |*	Wenn der zu bewegende Bereich leer ist oder das Ende vor
450cdf0e10cSrcweir |*	dem Anfang liegt, geschieht nichts.
451cdf0e10cSrcweir |*
452cdf0e10cSrcweir |*	Allg.: aRange beschreibt den Bereich  -exklusive- aEnd !!
453cdf0e10cSrcweir |*				( 1.Node: aStart, letzer Node: aEnd-1 !! )
454cdf0e10cSrcweir |*
455cdf0e10cSrcweir |*
456cdf0e10cSrcweir |*
457cdf0e10cSrcweir ***********************************************************************/
458cdf0e10cSrcweir 
_MoveNodes(const SwNodeRange & aRange,SwNodes & rNodes,const SwNodeIndex & aIndex,sal_Bool bNewFrms)459cdf0e10cSrcweir sal_Bool SwNodes::_MoveNodes( const SwNodeRange& aRange, SwNodes & rNodes,
460cdf0e10cSrcweir 					const SwNodeIndex& aIndex, sal_Bool bNewFrms )
461cdf0e10cSrcweir {
462cdf0e10cSrcweir 	SwNode * pAktNode;
463cdf0e10cSrcweir 	if( aIndex == 0 ||
464cdf0e10cSrcweir 		( (pAktNode = &aIndex.GetNode())->GetStartNode() &&
465cdf0e10cSrcweir 		  !pAktNode->StartOfSectionIndex() ))
466cdf0e10cSrcweir         return sal_False;
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 	SwNodeRange aRg( aRange );
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 	// "einfache" StartNodes oder EndNodes ueberspringen
471cdf0e10cSrcweir 	while( ND_STARTNODE == (pAktNode = &aRg.aStart.GetNode())->GetNodeType()
472cdf0e10cSrcweir 			|| ( pAktNode->IsEndNode() &&
473cdf0e10cSrcweir 				!pAktNode->pStartOfSection->IsSectionNode() ) )
474cdf0e10cSrcweir 		aRg.aStart++;
475cdf0e10cSrcweir 	aRg.aStart--;
476cdf0e10cSrcweir 
477cdf0e10cSrcweir 	// falls aEnd-1 auf keinem ContentNode steht, dann suche den vorherigen
478cdf0e10cSrcweir 	aRg.aEnd--;
479cdf0e10cSrcweir 	while( ( (( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() &&
480cdf0e10cSrcweir 			!pAktNode->IsSectionNode() ) ||
481cdf0e10cSrcweir 			( pAktNode->IsEndNode() &&
482cdf0e10cSrcweir 			ND_STARTNODE == pAktNode->pStartOfSection->GetNodeType()) ) &&
483cdf0e10cSrcweir             aRg.aEnd > aRg.aStart )
484cdf0e10cSrcweir 		aRg.aEnd--;
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 
487cdf0e10cSrcweir 	// wird im selben Array's verschoben, dann ueberpruefe die Einfuegepos.
488cdf0e10cSrcweir 	if( aRg.aStart >= aRg.aEnd )
489cdf0e10cSrcweir 		return sal_False;
490cdf0e10cSrcweir 
491cdf0e10cSrcweir 	if( this == &rNodes )
492cdf0e10cSrcweir 	{
493cdf0e10cSrcweir 		if( ( aIndex.GetIndex()-1 >= aRg.aStart.GetIndex() &&
494cdf0e10cSrcweir 			  aIndex.GetIndex()-1 < aRg.aEnd.GetIndex()) ||
495cdf0e10cSrcweir 			( aIndex.GetIndex()-1 == aRg.aEnd.GetIndex() ) )
496cdf0e10cSrcweir 			return sal_False;
497cdf0e10cSrcweir 	}
498cdf0e10cSrcweir 
499cdf0e10cSrcweir 	sal_uInt16 nLevel = 0;					// Level-Counter
500cdf0e10cSrcweir 	sal_uLong nInsPos = 0; 					// Cnt fuer das TmpArray
501cdf0e10cSrcweir 
502cdf0e10cSrcweir 	// das Array bildet einen Stack, es werden alle StartOfSelction's gesichert
503cdf0e10cSrcweir 	SwSttNdPtrs aSttNdStack( 1, 5 );
504cdf0e10cSrcweir 
505cdf0e10cSrcweir 	// setze den Start-Index
506cdf0e10cSrcweir 	SwNodeIndex  aIdx( aIndex );
507cdf0e10cSrcweir /*
508cdf0e10cSrcweir 	--- JP 17.11.94: sollte ueberholt sein, wird im ChgNode schon erledigt!
509cdf0e10cSrcweir 	sal_Bool bCorrNum = pSect && pSect->aStart.GetIndex() == aIdx.GetIndex();
510cdf0e10cSrcweir */
511cdf0e10cSrcweir 
512cdf0e10cSrcweir 	SwStartNode* pStartNode = aIdx.GetNode().pStartOfSection;
513cdf0e10cSrcweir 	aSttNdStack.C40_INSERT( SwStartNode, pStartNode, 0 );
514cdf0e10cSrcweir //	aSttNdStack.Insert( rNodes[ aIdx ]->pStartOfSection, 0 );
515cdf0e10cSrcweir 	SwNodeRange aOrigInsPos( aIdx, -1, aIdx );		// Originale Insert Pos
516cdf0e10cSrcweir 
517cdf0e10cSrcweir 	//JP 16.01.98: SectionNodes: DelFrms/MakeFrms beim obersten SectionNode!
518cdf0e10cSrcweir 	sal_uInt16 nSectNdCnt = 0;
519cdf0e10cSrcweir 	sal_Bool bSaveNewFrms = bNewFrms;
520cdf0e10cSrcweir 
521a0a540c1SAndre Fischer     // Check that the range of nodes to move is valid.
522a0a540c1SAndre Fischer     // This is a very specific test that only checks that table nodes
523a0a540c1SAndre Fischer     // are completely covered by the range.  Issue 121479 has a
524a0a540c1SAndre Fischer     // document for which this test fails.
525a0a540c1SAndre Fischer     SwNodeIndex aNodeIndex (aRg.aEnd);
526a0a540c1SAndre Fischer     while (aNodeIndex > aRg.aStart)
527a0a540c1SAndre Fischer     {
528335aba51SAndre Fischer         SwNode& rNode (aNodeIndex.GetNode());
529335aba51SAndre Fischer         if (rNode.GetNodeType() != ND_ENDNODE)
530a0a540c1SAndre Fischer             break;
531335aba51SAndre Fischer         SwStartNode* pStartNode = rNode.pStartOfSection;
532a0a540c1SAndre Fischer         if (pStartNode==NULL)
533a0a540c1SAndre Fischer             break;
534a0a540c1SAndre Fischer         if ( ! pStartNode->IsTableNode())
535a0a540c1SAndre Fischer             break;
536a0a540c1SAndre Fischer         aNodeIndex = *pStartNode;
537a0a540c1SAndre Fischer         if (aNodeIndex < aRg.aStart.GetIndex())
538a0a540c1SAndre Fischer         {
539a0a540c1SAndre Fischer             return sal_False;
540a0a540c1SAndre Fischer         }
541a0a540c1SAndre Fischer         --aNodeIndex;
542a0a540c1SAndre Fischer     }
543a0a540c1SAndre Fischer 
544a0a540c1SAndre Fischer 
545cdf0e10cSrcweir 	// bis alles verschoben ist
546cdf0e10cSrcweir 	while( aRg.aStart < aRg.aEnd )
547cdf0e10cSrcweir 		switch( (pAktNode = &aRg.aEnd.GetNode())->GetNodeType() )
548cdf0e10cSrcweir 		{
549cdf0e10cSrcweir 		case ND_ENDNODE:
550cdf0e10cSrcweir 			{
551cdf0e10cSrcweir 				if( nInsPos )		// verschieb schon mal alle bis hier her
552cdf0e10cSrcweir 				{
553cdf0e10cSrcweir 					// loeschen und kopieren. ACHTUNG: die Indizies ab
554cdf0e10cSrcweir 					// "aRg.aEnd+1" werden mit verschoben !!
555cdf0e10cSrcweir 					SwNodeIndex aSwIndex( aRg.aEnd, 1 );
556cdf0e10cSrcweir 					ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
557cdf0e10cSrcweir 					aIdx -= nInsPos;
558cdf0e10cSrcweir 					nInsPos = 0;
559cdf0e10cSrcweir 				}
560cdf0e10cSrcweir 
561cdf0e10cSrcweir 				SwStartNode* pSttNd = pAktNode->pStartOfSection;
562cdf0e10cSrcweir 				if( pSttNd->IsTableNode() )
563cdf0e10cSrcweir 				{
564cdf0e10cSrcweir 					SwTableNode* pTblNd = (SwTableNode*)pSttNd;
565cdf0e10cSrcweir 
566cdf0e10cSrcweir 					// dann bewege die gesamte Tabelle/den Bereich !!
567cdf0e10cSrcweir 					nInsPos = (aRg.aEnd.GetIndex() -
568cdf0e10cSrcweir 									pSttNd->GetIndex() )+1;
569cdf0e10cSrcweir 					aRg.aEnd -= nInsPos;
570cdf0e10cSrcweir 
571cdf0e10cSrcweir 					//JP 12.03.99: 63293 - Nodes vom RedlineBereich NIE aufnehmen
572cdf0e10cSrcweir 					sal_uLong nNd = aIdx.GetIndex();
573cdf0e10cSrcweir 					sal_Bool bInsOutlineIdx = !( rNodes.GetEndOfRedlines().
574cdf0e10cSrcweir                             StartOfSectionNode()->GetIndex() < nNd &&
575cdf0e10cSrcweir 							nNd < rNodes.GetEndOfRedlines().GetIndex() );
576cdf0e10cSrcweir 
577cdf0e10cSrcweir 					if( bNewFrms )
578cdf0e10cSrcweir 						// loesche erstmal die Frames
579cdf0e10cSrcweir 						pTblNd->DelFrms();
580cdf0e10cSrcweir 					if( &rNodes == this )	// in sich selbst moven ??
581cdf0e10cSrcweir 					{
582cdf0e10cSrcweir 						// dann bewege alle Start/End/ContentNodes. Loesche
583cdf0e10cSrcweir 						// bei den ContentNodes auch die Frames !!
584cdf0e10cSrcweir 						pTblNd->pStartOfSection = aIdx.GetNode().pStartOfSection;
585cdf0e10cSrcweir 						for( sal_uLong n = 0; n < nInsPos; ++n )
586cdf0e10cSrcweir 						{
587cdf0e10cSrcweir 							SwNodeIndex aMvIdx( aRg.aEnd, 1 );
588cdf0e10cSrcweir 							SwCntntNode* pCNd = 0;
589cdf0e10cSrcweir 							SwNode* pTmpNd = &aMvIdx.GetNode();
590cdf0e10cSrcweir 							if( pTmpNd->IsCntntNode() )
591cdf0e10cSrcweir 							{
592cdf0e10cSrcweir 								pCNd = (SwCntntNode*)pTmpNd;
593cdf0e10cSrcweir                                 if( pTmpNd->IsTxtNode() )
594cdf0e10cSrcweir                                     ((SwTxtNode*)pTmpNd)->RemoveFromList();
595cdf0e10cSrcweir 
596cdf0e10cSrcweir //								if( bNewFrms )
597cdf0e10cSrcweir //									pCNd->DelFrms();
598cdf0e10cSrcweir 
599cdf0e10cSrcweir 								// setze bei Start/EndNodes die richtigen Indizies
600cdf0e10cSrcweir 								// loesche die Gliederungs-Indizies aus
601cdf0e10cSrcweir 								// dem alten Nodes-Array
602cdf0e10cSrcweir 								//if( pCNd->IsTxtNode() && NO_NUMBERING !=		//#outline level,zhaojianwei
603cdf0e10cSrcweir 								//	((SwTxtNode*)pCNd)->GetTxtColl()->GetOutlineLevel() )
604cdf0e10cSrcweir 								if( pCNd->IsTxtNode() && 0 !=
605cdf0e10cSrcweir 									((SwTxtNode*)pCNd)->GetAttrOutlineLevel() )//<-end,by zhaojianwei
606cdf0e10cSrcweir 									pOutlineNds->Remove( pCNd );
607cdf0e10cSrcweir 								else
608cdf0e10cSrcweir 									pCNd = 0;
609cdf0e10cSrcweir 							}
610cdf0e10cSrcweir //							else if( bNewFrms && pTmpNd->IsSectionNode() )
611cdf0e10cSrcweir //								((SwSectionNode*)pTmpNd)->DelFrms();
612cdf0e10cSrcweir 							BigPtrArray::Move( aMvIdx.GetIndex(), aIdx.GetIndex() );
613cdf0e10cSrcweir 
614cdf0e10cSrcweir 							if( bInsOutlineIdx && pCNd )
615cdf0e10cSrcweir 								pOutlineNds->Insert( pCNd );
616cdf0e10cSrcweir                             if( pTmpNd->IsTxtNode() )
617cdf0e10cSrcweir                                 ((SwTxtNode*)pTmpNd)->AddToList();
618cdf0e10cSrcweir 						}
619cdf0e10cSrcweir 					}
620cdf0e10cSrcweir 					else
621cdf0e10cSrcweir 					{
622cdf0e10cSrcweir 						// StartNode holen
623cdf0e10cSrcweir 						// Even aIdx points to a startnode, we need the startnode
624cdf0e10cSrcweir 						// of the environment of aIdx (#i80941)
625cdf0e10cSrcweir 						SwStartNode* pSttNode = aIdx.GetNode().pStartOfSection;
626cdf0e10cSrcweir 
627cdf0e10cSrcweir 						// Hole alle Boxen mit Inhalt. Deren Indizies auf die
628cdf0e10cSrcweir 						// StartNodes muessen umgemeldet werden !!
629cdf0e10cSrcweir 						// (Array kopieren und alle gefunden wieder loeschen;
630cdf0e10cSrcweir 						//  erleichtert das suchen!!)
631cdf0e10cSrcweir 						SwNodeIndex aMvIdx( aRg.aEnd, 1 );
632cdf0e10cSrcweir 						for( sal_uLong n = 0; n < nInsPos; ++n )
633cdf0e10cSrcweir 						{
634cdf0e10cSrcweir 							SwNode* pNd = &aMvIdx.GetNode();
635cdf0e10cSrcweir /*							if( bNewFrms )
636cdf0e10cSrcweir 							{
637cdf0e10cSrcweir 								if( pNd->IsCntntNode() )
638cdf0e10cSrcweir 									((SwCntntNode*)pNd)->DelFrms();
639cdf0e10cSrcweir 								else if( pNd->IsSectionNode() )
640cdf0e10cSrcweir 									((SwSectionNode*)pNd)->DelFrms();
641cdf0e10cSrcweir 							}
642cdf0e10cSrcweir */
643cdf0e10cSrcweir 							//sal_Bool bOutlNd = pNd->IsTxtNode() && NO_NUMBERING !=//#outline level,zhaojianwei
644cdf0e10cSrcweir 							//	((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel();
645cdf0e10cSrcweir                             const bool bOutlNd = pNd->IsTxtNode() &&
646cdf0e10cSrcweir                                     0 != ((SwTxtNode*)pNd)->GetAttrOutlineLevel();//<-end,zhaojianwei
647cdf0e10cSrcweir 							// loesche die Gliederungs-Indizies aus
648cdf0e10cSrcweir 							// dem alten Nodes-Array
649cdf0e10cSrcweir 							if( bOutlNd )
650cdf0e10cSrcweir 								pOutlineNds->Remove( pNd );
651cdf0e10cSrcweir 
652cdf0e10cSrcweir 							RemoveNode( aMvIdx.GetIndex(), 1, sal_False );
653cdf0e10cSrcweir 							pNd->pStartOfSection = pSttNode;
654cdf0e10cSrcweir                             rNodes.InsertNode( pNd, aIdx );
655cdf0e10cSrcweir 
656cdf0e10cSrcweir 							// setze bei Start/EndNodes die richtigen Indizies
657cdf0e10cSrcweir 							if( bInsOutlineIdx && bOutlNd )
658cdf0e10cSrcweir 								// und setze sie im neuen Nodes-Array
659cdf0e10cSrcweir 								rNodes.pOutlineNds->Insert( pNd );
660cdf0e10cSrcweir 							else if( pNd->IsStartNode() )
661cdf0e10cSrcweir 								pSttNode = (SwStartNode*)pNd;
662cdf0e10cSrcweir 							else if( pNd->IsEndNode() )
663cdf0e10cSrcweir 							{
664cdf0e10cSrcweir 								pSttNode->pEndOfSection = (SwEndNode*)pNd;
665cdf0e10cSrcweir 								if( pSttNode->IsSectionNode() )
666cdf0e10cSrcweir 									((SwSectionNode*)pSttNode)->NodesArrChgd();
667cdf0e10cSrcweir 								pSttNode = pSttNode->pStartOfSection;
668cdf0e10cSrcweir 							}
669cdf0e10cSrcweir 						}
670cdf0e10cSrcweir 
671cdf0e10cSrcweir 						if( pTblNd->GetTable().IsA( TYPE( SwDDETable ) ))
672cdf0e10cSrcweir 						{
673cdf0e10cSrcweir 							SwDDEFieldType* pTyp = ((SwDDETable&)pTblNd->
674cdf0e10cSrcweir 												GetTable()).GetDDEFldType();
675cdf0e10cSrcweir 							if( pTyp )
676cdf0e10cSrcweir 							{
677cdf0e10cSrcweir 								if( rNodes.IsDocNodes() )
678cdf0e10cSrcweir 									pTyp->IncRefCnt();
679cdf0e10cSrcweir 								else
680cdf0e10cSrcweir 									pTyp->DecRefCnt();
681cdf0e10cSrcweir 							}
682cdf0e10cSrcweir 						}
683cdf0e10cSrcweir 
684cdf0e10cSrcweir                         if (GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(
685cdf0e10cSrcweir                                     rNodes))
686cdf0e10cSrcweir                         {
687cdf0e10cSrcweir 							SwFrmFmt* pTblFmt = pTblNd->GetTable().GetFrmFmt();
688cdf0e10cSrcweir 							SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT,
689cdf0e10cSrcweir 														pTblFmt );
690cdf0e10cSrcweir 							pTblFmt->ModifyNotification( &aMsgHint, &aMsgHint );
691cdf0e10cSrcweir 						}
692cdf0e10cSrcweir 					}
693cdf0e10cSrcweir 					if( bNewFrms )
694cdf0e10cSrcweir 					{
695cdf0e10cSrcweir 						SwNodeIndex aTmp( aIdx );
696cdf0e10cSrcweir 						pTblNd->MakeFrms( &aTmp );
697cdf0e10cSrcweir 					}
698cdf0e10cSrcweir 					aIdx -= nInsPos;
699cdf0e10cSrcweir 					nInsPos = 0;
700cdf0e10cSrcweir 				}
701cdf0e10cSrcweir 				else if( pSttNd->GetIndex() < aRg.aStart.GetIndex() )
702cdf0e10cSrcweir 				{
703cdf0e10cSrcweir 					// SectionNode: es wird nicht die gesamte Section
704cdf0e10cSrcweir 					//				verschoben, also bewege nur die
705cdf0e10cSrcweir 					//				ContentNodes
706cdf0e10cSrcweir 					// StartNode:	erzeuge an der Postion eine neue Section
707cdf0e10cSrcweir 					do {		// middle check loop
708cdf0e10cSrcweir 						if( !pSttNd->IsSectionNode() )
709cdf0e10cSrcweir 						{
710cdf0e10cSrcweir 							// Start und EndNode an der InsertPos erzeugen
711cdf0e10cSrcweir 							SwStartNode* pTmp = new SwStartNode( aIdx,
712cdf0e10cSrcweir 													ND_STARTNODE,
713cdf0e10cSrcweir /*?? welcher NodeTyp ??*/
714cdf0e10cSrcweir 													SwNormalStartNode );
715cdf0e10cSrcweir 
716cdf0e10cSrcweir 							nLevel++;			// den Index auf StartNode auf den Stack
717cdf0e10cSrcweir 							aSttNdStack.C40_INSERT( SwStartNode, pTmp, nLevel );
718cdf0e10cSrcweir 
719cdf0e10cSrcweir 							// noch den EndNode erzeugen
720cdf0e10cSrcweir 							new SwEndNode( aIdx, *pTmp );
721cdf0e10cSrcweir                         }
722cdf0e10cSrcweir                         else if (GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(
723cdf0e10cSrcweir                                     rNodes))
724cdf0e10cSrcweir                         {
725cdf0e10cSrcweir 							// im UndoNodes-Array spendieren wir einen
726cdf0e10cSrcweir 							// Platzhalter
727cdf0e10cSrcweir 							new SwNode( aIdx, ND_SECTIONDUMMY );
728cdf0e10cSrcweir 						}
729cdf0e10cSrcweir 						else
730cdf0e10cSrcweir 						{
731cdf0e10cSrcweir 							// JP 18.5.2001: neue Section anlegen?? Bug 70454
732cdf0e10cSrcweir 							aRg.aEnd--;
733cdf0e10cSrcweir 							break;
734cdf0e10cSrcweir 
735cdf0e10cSrcweir 						}
736cdf0e10cSrcweir 
737cdf0e10cSrcweir 						aRg.aEnd--;
738cdf0e10cSrcweir 						aIdx--;
739cdf0e10cSrcweir 					} while( sal_False );
740cdf0e10cSrcweir 				}
741cdf0e10cSrcweir 				else
742cdf0e10cSrcweir 				{
743cdf0e10cSrcweir 					// Start und EndNode komplett verschieben
744cdf0e10cSrcweir // s. u. SwIndex aOldStt( pSttNd->theIndex );
745cdf0e10cSrcweir //JP 21.05.97: sollte der Start genau der Start des Bereiches sein, so muss
746cdf0e10cSrcweir //				der Node auf jedenfall noch besucht werden!
747cdf0e10cSrcweir 					if( &aRg.aStart.GetNode() == pSttNd )
748cdf0e10cSrcweir 						--aRg.aStart;
749cdf0e10cSrcweir 
750cdf0e10cSrcweir 					SwSectionNode* pSctNd = pSttNd->GetSectionNode();
751cdf0e10cSrcweir 					if( bNewFrms && pSctNd )
752cdf0e10cSrcweir 						pSctNd->DelFrms();
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 					RemoveNode( aRg.aEnd.GetIndex(), 1, sal_False ); // EndNode loeschen
755cdf0e10cSrcweir 					sal_uLong nSttPos = pSttNd->GetIndex();
756cdf0e10cSrcweir 
757cdf0e10cSrcweir 					// dieser StartNode wird spaeter wieder entfernt!
758cdf0e10cSrcweir 					SwStartNode* pTmpSttNd = new SwStartNode( *this, nSttPos+1 );
759cdf0e10cSrcweir 					pTmpSttNd->pStartOfSection = pSttNd->pStartOfSection;
760cdf0e10cSrcweir 
761cdf0e10cSrcweir 					RemoveNode( nSttPos, 1, sal_False ); // SttNode loeschen
762cdf0e10cSrcweir 
763cdf0e10cSrcweir 					pSttNd->pStartOfSection = aIdx.GetNode().pStartOfSection;
764cdf0e10cSrcweir                     rNodes.InsertNode( pSttNd, aIdx  );
765cdf0e10cSrcweir                     rNodes.InsertNode( pAktNode, aIdx );
766cdf0e10cSrcweir 					aIdx--;
767cdf0e10cSrcweir 					pSttNd->pEndOfSection = (SwEndNode*)pAktNode;
768cdf0e10cSrcweir 
769cdf0e10cSrcweir 					aRg.aEnd--;
770cdf0e10cSrcweir 
771cdf0e10cSrcweir 					nLevel++;			// den Index auf StartNode auf den Stack
772cdf0e10cSrcweir 					aSttNdStack.C40_INSERT( SwStartNode, pSttNd, nLevel );
773cdf0e10cSrcweir 
774cdf0e10cSrcweir 					// SectionNode muss noch ein paar Indizies ummelden
775cdf0e10cSrcweir 					if( pSctNd )
776cdf0e10cSrcweir 					{
777cdf0e10cSrcweir 						pSctNd->NodesArrChgd();
778cdf0e10cSrcweir 						++nSectNdCnt;
779cdf0e10cSrcweir 						bNewFrms = sal_False;
780cdf0e10cSrcweir 					}
781cdf0e10cSrcweir 				}
782cdf0e10cSrcweir 			}
783cdf0e10cSrcweir 			break;
784cdf0e10cSrcweir 
785cdf0e10cSrcweir 
786cdf0e10cSrcweir 
787cdf0e10cSrcweir 		case ND_SECTIONNODE:
788cdf0e10cSrcweir 			if( !nLevel &&
789cdf0e10cSrcweir                 GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(rNodes))
790cdf0e10cSrcweir             {
791cdf0e10cSrcweir 				// dann muss an der akt. InsPos ein SectionDummyNode
792cdf0e10cSrcweir 				// eingefuegt werden
793cdf0e10cSrcweir 				if( nInsPos )		// verschieb schon mal alle bis hier her
794cdf0e10cSrcweir 				{
795cdf0e10cSrcweir 					// loeschen und kopieren. ACHTUNG: die Indizies ab
796cdf0e10cSrcweir 					// "aRg.aEnd+1" werden mit verschoben !!
797cdf0e10cSrcweir 					SwNodeIndex aSwIndex( aRg.aEnd, 1 );
798cdf0e10cSrcweir 					ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
799cdf0e10cSrcweir 					aIdx -= nInsPos;
800cdf0e10cSrcweir 					nInsPos = 0;
801cdf0e10cSrcweir 				}
802cdf0e10cSrcweir 				new SwNode( aIdx, ND_SECTIONDUMMY );
803cdf0e10cSrcweir 				aRg.aEnd--;
804cdf0e10cSrcweir 				aIdx--;
805cdf0e10cSrcweir 				break;
806cdf0e10cSrcweir 			}
807cdf0e10cSrcweir 			// kein break !!
808cdf0e10cSrcweir 		case ND_TABLENODE:
809cdf0e10cSrcweir 		case ND_STARTNODE:
810cdf0e10cSrcweir 			{
811cdf0e10cSrcweir 				// Bug #78589# - empty section -> nothing to do
812cdf0e10cSrcweir 				//  and only if it's a top level section
813cdf0e10cSrcweir 				if( !nInsPos && !nLevel )
814cdf0e10cSrcweir 				{
815cdf0e10cSrcweir 					aRg.aEnd--;
816cdf0e10cSrcweir 					break;
817cdf0e10cSrcweir 				}
818cdf0e10cSrcweir 
819cdf0e10cSrcweir 				if( !nLevel )		// es wird eine Stufe runter gestuft
820cdf0e10cSrcweir 				{
821cdf0e10cSrcweir 					// erzeuge die Runterstufung
822cdf0e10cSrcweir 					SwNodeIndex aTmpSIdx( aOrigInsPos.aStart, 1 );
823cdf0e10cSrcweir 					SwStartNode* pTmpStt = new SwStartNode( aTmpSIdx,
824cdf0e10cSrcweir 								ND_STARTNODE,
825cdf0e10cSrcweir 								((SwStartNode*)pAktNode)->GetStartNodeType() );
826cdf0e10cSrcweir 
827cdf0e10cSrcweir 					aTmpSIdx--;
828cdf0e10cSrcweir 
829cdf0e10cSrcweir 					SwNodeIndex aTmpEIdx( aOrigInsPos.aEnd );
830cdf0e10cSrcweir 					new SwEndNode( aTmpEIdx, *pTmpStt );
831cdf0e10cSrcweir 					aTmpEIdx--;
832cdf0e10cSrcweir 					aTmpSIdx++;
833cdf0e10cSrcweir 
834cdf0e10cSrcweir 					// setze die StartOfSection richtig
835cdf0e10cSrcweir 					aRg.aEnd++;
836cdf0e10cSrcweir 					{
837cdf0e10cSrcweir 						SwNodeIndex aCntIdx( aRg.aEnd );
838cdf0e10cSrcweir 						for( sal_uLong n = 0; n < nInsPos; n++, aCntIdx++)
839cdf0e10cSrcweir 							aCntIdx.GetNode().pStartOfSection = pTmpStt;
840cdf0e10cSrcweir 					}
841cdf0e10cSrcweir 
842cdf0e10cSrcweir 					// Setze auch bei allen runtergestuften den richtigen StartNode
843cdf0e10cSrcweir 					while( aTmpSIdx < aTmpEIdx )
844cdf0e10cSrcweir 						if( 0 != (( pAktNode = &aTmpEIdx.GetNode())->GetEndNode()) )
845cdf0e10cSrcweir 							aTmpEIdx = pAktNode->StartOfSectionIndex();
846cdf0e10cSrcweir 						else
847cdf0e10cSrcweir 						{
848cdf0e10cSrcweir 							pAktNode->pStartOfSection = pTmpStt;
849cdf0e10cSrcweir 							aTmpEIdx--;
850cdf0e10cSrcweir 						}
851cdf0e10cSrcweir 
852cdf0e10cSrcweir 					aIdx--; 				// hinter den eingefuegten StartNode
853cdf0e10cSrcweir 					aRg.aEnd--; 			// vor den StartNode
854cdf0e10cSrcweir 					// kopiere jetzt das Array. ACHTUNG: die Indizies ab
855cdf0e10cSrcweir 					// "aRg.aEnd+1" werden mit verschoben !!
856cdf0e10cSrcweir 					SwNodeIndex aSwIndex( aRg.aEnd, 1 );
857cdf0e10cSrcweir 					ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
858cdf0e10cSrcweir 					aIdx -= nInsPos+1;
859cdf0e10cSrcweir 					nInsPos = 0;
860cdf0e10cSrcweir 				}
861cdf0e10cSrcweir 				else 				// es wurden alle Nodes innerhalb eines
862cdf0e10cSrcweir 				{	 				// Start- und End-Nodes verschoben
863cdf0e10cSrcweir 					ASSERT( pAktNode == aSttNdStack[nLevel] ||
864cdf0e10cSrcweir 							( pAktNode->IsStartNode() &&
865cdf0e10cSrcweir 								aSttNdStack[nLevel]->IsSectionNode()),
866cdf0e10cSrcweir 							 "falscher StartNode" );
867cdf0e10cSrcweir 
868cdf0e10cSrcweir 					SwNodeIndex aSwIndex( aRg.aEnd, 1 );
869cdf0e10cSrcweir 					ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
870cdf0e10cSrcweir 					aIdx -= nInsPos+1;		// vor den eingefuegten StartNode
871cdf0e10cSrcweir 					nInsPos = 0;
872cdf0e10cSrcweir 
873cdf0e10cSrcweir 					// loesche nur noch den Pointer aus dem Nodes-Array.
874cdf0e10cSrcweir //					RemoveNode( aRg.aEnd.GetIndex(), 1, sal_False );
875cdf0e10cSrcweir 					RemoveNode( aRg.aEnd.GetIndex(), 1, sal_True );
876cdf0e10cSrcweir 					aRg.aEnd--;
877cdf0e10cSrcweir 
878cdf0e10cSrcweir 					SwSectionNode* pSectNd = aSttNdStack[ nLevel ]->GetSectionNode();
879cdf0e10cSrcweir 					if( pSectNd && !--nSectNdCnt )
880cdf0e10cSrcweir 					{
881cdf0e10cSrcweir 						SwNodeIndex aTmp( *pSectNd );
882cdf0e10cSrcweir 						pSectNd->MakeFrms( &aTmp );
883cdf0e10cSrcweir 						bNewFrms = bSaveNewFrms;
884cdf0e10cSrcweir 					}
885cdf0e10cSrcweir 					aSttNdStack.Remove( nLevel ); 	// vom Stack loeschen
886cdf0e10cSrcweir 					nLevel--;
887cdf0e10cSrcweir 				}
888cdf0e10cSrcweir 
889cdf0e10cSrcweir 				// loesche alle entstehenden leeren Start-/End-Node-Paare
890cdf0e10cSrcweir 				SwNode* pTmpNode = (*this)[ aRg.aEnd.GetIndex()+1 ]->GetEndNode();
891cdf0e10cSrcweir 				if( pTmpNode && ND_STARTNODE == (pAktNode = &aRg.aEnd.GetNode())
892cdf0e10cSrcweir 					->GetNodeType() && pAktNode->StartOfSectionIndex() &&
893cdf0e10cSrcweir                     pTmpNode->StartOfSectionNode() == pAktNode )
894cdf0e10cSrcweir 				{
895cdf0e10cSrcweir 					DelNodes( aRg.aEnd, 2 );
896cdf0e10cSrcweir 					aRg.aEnd--;
897cdf0e10cSrcweir 				}
898cdf0e10cSrcweir //				aRg.aEnd--;
899cdf0e10cSrcweir 			}
900cdf0e10cSrcweir 			break;
901cdf0e10cSrcweir 
902cdf0e10cSrcweir 		case ND_TEXTNODE:
903ca62e2c2SSteve Yin 			//Solution:Add special function to text node.
904ca62e2c2SSteve Yin 			{
905ca62e2c2SSteve Yin 				if( bNewFrms && pAktNode->GetCntntNode() )
906ca62e2c2SSteve Yin 					((SwCntntNode*)pAktNode)->DelFrms( sal_False );
907ca62e2c2SSteve Yin 				pAktNode->pStartOfSection = aSttNdStack[ nLevel ];
908ca62e2c2SSteve Yin 				nInsPos++;
909ca62e2c2SSteve Yin 				aRg.aEnd--;
910ca62e2c2SSteve Yin 			}
911ca62e2c2SSteve Yin 			break;
912cdf0e10cSrcweir 		case ND_GRFNODE:
913cdf0e10cSrcweir 		case ND_OLENODE:
914cdf0e10cSrcweir 			{
915cdf0e10cSrcweir 				if( bNewFrms && pAktNode->GetCntntNode() )
916cdf0e10cSrcweir 					((SwCntntNode*)pAktNode)->DelFrms();
917cdf0e10cSrcweir 
918cdf0e10cSrcweir 				pAktNode->pStartOfSection = aSttNdStack[ nLevel ];
919cdf0e10cSrcweir 				nInsPos++;
920cdf0e10cSrcweir 				aRg.aEnd--;
921cdf0e10cSrcweir 			}
922cdf0e10cSrcweir 			break;
923cdf0e10cSrcweir 
924cdf0e10cSrcweir 		case ND_SECTIONDUMMY:
925cdf0e10cSrcweir             if (GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(*this))
926cdf0e10cSrcweir             {
927cdf0e10cSrcweir 				if( &rNodes == this )		// innerhalb vom UndoNodesArray
928cdf0e10cSrcweir 				{
929cdf0e10cSrcweir 					// mit verschieben
930cdf0e10cSrcweir 					pAktNode->pStartOfSection = aSttNdStack[ nLevel ];
931cdf0e10cSrcweir 					nInsPos++;
932cdf0e10cSrcweir 				}
933cdf0e10cSrcweir 				else	// in ein "normales" Nodes-Array verschieben
934cdf0e10cSrcweir 				{
935cdf0e10cSrcweir 					// dann muss an der akt. InsPos auch ein SectionNode
936cdf0e10cSrcweir 					// (Start/Ende) stehen; dann diesen ueberspringen.
937cdf0e10cSrcweir 					// Andernfalls nicht weiter beachten.
938cdf0e10cSrcweir 					if( nInsPos )		// verschieb schon mal alle bis hier her
939cdf0e10cSrcweir 					{
940cdf0e10cSrcweir 						// loeschen und kopieren. ACHTUNG: die Indizies ab
941cdf0e10cSrcweir 						// "aRg.aEnd+1" werden mit verschoben !!
942cdf0e10cSrcweir 						SwNodeIndex aSwIndex( aRg.aEnd, 1 );
943cdf0e10cSrcweir 						ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
944cdf0e10cSrcweir 						aIdx -= nInsPos;
945cdf0e10cSrcweir 						nInsPos = 0;
946cdf0e10cSrcweir 					}
947cdf0e10cSrcweir 					SwNode* pTmpNd = &aIdx.GetNode();
948cdf0e10cSrcweir 					if( pTmpNd->IsSectionNode() ||
949cdf0e10cSrcweir                         pTmpNd->StartOfSectionNode()->IsSectionNode() )
950cdf0e10cSrcweir 						aIdx--;	// ueberspringen
951cdf0e10cSrcweir 				}
952cdf0e10cSrcweir 			}
953cdf0e10cSrcweir 			else {
954cdf0e10cSrcweir 				ASSERT( sal_False, "wie kommt diser Node ins Nodes-Array??" );
955cdf0e10cSrcweir             }
956cdf0e10cSrcweir 			aRg.aEnd--;
957cdf0e10cSrcweir 			break;
958cdf0e10cSrcweir 
959cdf0e10cSrcweir 		default:
960cdf0e10cSrcweir 			ASSERT( sal_False, "was ist das fuer ein Node??" );
961cdf0e10cSrcweir 			break;
962cdf0e10cSrcweir 		}
963cdf0e10cSrcweir 
964cdf0e10cSrcweir 	if( nInsPos )							// kopiere den Rest
965cdf0e10cSrcweir 	{
966cdf0e10cSrcweir 		// der Rest muesste so stimmen
967cdf0e10cSrcweir 		SwNodeIndex aSwIndex( aRg.aEnd, 1 );
968cdf0e10cSrcweir 		ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
969cdf0e10cSrcweir 	}
970cdf0e10cSrcweir 	aRg.aEnd++;						// wieder exklusive Ende
971cdf0e10cSrcweir 
972cdf0e10cSrcweir 	// loesche alle leeren Start-/End-Node-Paare
973cdf0e10cSrcweir 	if( ( pAktNode = &aRg.aStart.GetNode())->GetStartNode() &&
974cdf0e10cSrcweir 		pAktNode->StartOfSectionIndex() &&
975cdf0e10cSrcweir 		aRg.aEnd.GetNode().GetEndNode() )
976cdf0e10cSrcweir 			DelNodes( aRg.aStart, 2 );
977cdf0e10cSrcweir 
978cdf0e10cSrcweir 	// rufe jetzt noch das Update fuer die Gliederung/Nummerierung auf
979cdf0e10cSrcweir 	aOrigInsPos.aStart++;
980cdf0e10cSrcweir 	// im gleichen Nodes-Array verschoben ??,
981cdf0e10cSrcweir 	// dann von oben nach unten das Update aufrufen !!
982cdf0e10cSrcweir 	if( this == &rNodes &&
983cdf0e10cSrcweir 		aRg.aEnd.GetIndex() >= aOrigInsPos.aStart.GetIndex() )
984cdf0e10cSrcweir 	{
985cdf0e10cSrcweir 		UpdtOutlineIdx( aOrigInsPos.aStart.GetNode() );
986cdf0e10cSrcweir 		UpdtOutlineIdx( aRg.aEnd.GetNode() );
987cdf0e10cSrcweir 	}
988cdf0e10cSrcweir 	else
989cdf0e10cSrcweir 	{
990cdf0e10cSrcweir 		UpdtOutlineIdx( aRg.aEnd.GetNode() );
991cdf0e10cSrcweir 		rNodes.UpdtOutlineIdx( aOrigInsPos.aStart.GetNode() );
992cdf0e10cSrcweir 	}
993cdf0e10cSrcweir 
994cdf0e10cSrcweir #ifdef JP_DEBUG
995cdf0e10cSrcweir 	{
996cdf0e10cSrcweir extern Writer* GetDebugWriter(const String&);
997cdf0e10cSrcweir 
998cdf0e10cSrcweir 		Writer* pWriter = GetDebugWriter(aEmptyStr);
999cdf0e10cSrcweir 		if( pWriter )
1000cdf0e10cSrcweir 		{
1001cdf0e10cSrcweir 			int nError;
1002cdf0e10cSrcweir 			SvFileStream aStrm( "c:\\$$move.db", STREAM_WRITE );
1003cdf0e10cSrcweir 			SwWriter aWriter( aStrm, *pMyDoc );
1004cdf0e10cSrcweir 			aWriter.Write( &nError, pWriter );
1005cdf0e10cSrcweir 		}
1006cdf0e10cSrcweir 	}
1007cdf0e10cSrcweir #endif
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir 	return sal_True;
1010cdf0e10cSrcweir }
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir /*******************************************************************
1014cdf0e10cSrcweir |*
1015cdf0e10cSrcweir |*	SwNodes::SectionDown
1016cdf0e10cSrcweir |*
1017cdf0e10cSrcweir |*	Beschreibung
1018cdf0e10cSrcweir |*	  SectionDown() legt ein Paar von Start- und EndSection-Node
1019cdf0e10cSrcweir |*	  (andere Nodes koennen dazwischen liegen) an.
1020cdf0e10cSrcweir |*
1021cdf0e10cSrcweir |*	  Zustand des SRange beim Verlassen der Funktion: nStart ist der
1022cdf0e10cSrcweir |*	  Index des ersten Node hinter dem Start Section Node, nEnd ist
1023cdf0e10cSrcweir |*	  der Index des End Section Nodes. Beispiel: Wird Insert Section
1024cdf0e10cSrcweir |*	  mehrmals hintereinander aufgerufen, so werden mehrere
1025cdf0e10cSrcweir |*	  unmittelbar geschachtelte Sections (keine Content Nodes
1026cdf0e10cSrcweir |*	  zwischen Start- bzw. End Nodes) angelegt.
1027cdf0e10cSrcweir |*
1028cdf0e10cSrcweir |*	Allg.: aRange beschreibt den Bereich  -exklusive- aEnd !!
1029cdf0e10cSrcweir |*				( 1.Node: aStart, letzer Node: aEnd-1 !! )
1030cdf0e10cSrcweir |*
1031cdf0e10cSrcweir |*	Parameter
1032cdf0e10cSrcweir |*		SwRange &rRange
1033cdf0e10cSrcweir |*			IO:
1034cdf0e10cSrcweir |*			IN
1035cdf0e10cSrcweir |*			rRange.aStart: Einfuegeposition des StartNodes
1036cdf0e10cSrcweir |*			rRange.aEnd: Einfuegeposition des EndNodes
1037cdf0e10cSrcweir |*			OUT
1038cdf0e10cSrcweir |*			rRange.aStart: steht hinter dem eingefuegten Startnode
1039cdf0e10cSrcweir |*			rRange.aEnd: steht auf dem eingefuegen Endnode
1040cdf0e10cSrcweir |*
1041cdf0e10cSrcweir |*	Ausnahmen
1042cdf0e10cSrcweir |*	 1. SRange-Anfang und SRange-Ende muessen auf dem gleichen Level sein
1043cdf0e10cSrcweir |*	 2. duerfen nicht auf dem obersten Level sein
1044cdf0e10cSrcweir |*		Ist dies nicht der Fall, wird die
1045cdf0e10cSrcweir |*		Funktion durch Aufruf von ERR_RAISE verlassen.
1046cdf0e10cSrcweir |*
1047cdf0e10cSrcweir |*	Debug-Funktionen
1048cdf0e10cSrcweir |*		die Debugging Tools geben rRange beim Eintritt und beim
1049cdf0e10cSrcweir |*		Verlassen der Funktion aus
1050cdf0e10cSrcweir |*
1051cdf0e10cSrcweir |*	Ersterstellung
1052cdf0e10cSrcweir |*		VER0100 vb 901214
1053cdf0e10cSrcweir |*
1054cdf0e10cSrcweir |*	Stand
1055cdf0e10cSrcweir |*		VER0100 vb 901214
1056cdf0e10cSrcweir |*
1057cdf0e10cSrcweir *******************************************************************/
SectionDown(SwNodeRange * pRange,SwStartNodeType eSttNdTyp)1058cdf0e10cSrcweir void SwNodes::SectionDown(SwNodeRange *pRange, SwStartNodeType eSttNdTyp )
1059cdf0e10cSrcweir {
1060cdf0e10cSrcweir 	if( pRange->aStart >= pRange->aEnd ||
1061cdf0e10cSrcweir 		pRange->aEnd >= Count() ||
1062cdf0e10cSrcweir 		!CheckNodesRange( pRange->aStart, pRange->aEnd ))
1063cdf0e10cSrcweir 		return;
1064cdf0e10cSrcweir 
1065cdf0e10cSrcweir 	// Ist der Anfang vom Bereich vor oder auf einem EndNode, so loesche
1066cdf0e10cSrcweir 	// diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes enstehen.
1067cdf0e10cSrcweir 	// Bei anderen Nodes wird eine neuer StartNode eingefuegt
1068cdf0e10cSrcweir 	SwNode * pAktNode = &pRange->aStart.GetNode();
1069cdf0e10cSrcweir 	SwNodeIndex aTmpIdx( *pAktNode->StartOfSectionNode() );
1070cdf0e10cSrcweir 
1071cdf0e10cSrcweir 	if( pAktNode->GetEndNode() )
1072cdf0e10cSrcweir 		DelNodes( pRange->aStart, 1 );		// verhinder leere Section
1073cdf0e10cSrcweir 	else
1074cdf0e10cSrcweir 	{
1075cdf0e10cSrcweir 		// fuege einen neuen StartNode ein
1076cdf0e10cSrcweir 		SwNode* pSttNd = new SwStartNode( pRange->aStart, ND_STARTNODE, eSttNdTyp );
1077cdf0e10cSrcweir 		pRange->aStart = *pSttNd;
1078cdf0e10cSrcweir 		aTmpIdx = pRange->aStart;
1079cdf0e10cSrcweir 	}
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir 	// Ist das Ende vom Bereich vor oder auf einem StartNode, so loesche
1082cdf0e10cSrcweir 	// diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes enstehen
1083cdf0e10cSrcweir 	// Bei anderen Nodes wird eine neuer EndNode eingefuegt
1084cdf0e10cSrcweir 	pRange->aEnd--;
1085cdf0e10cSrcweir 	if( pRange->aEnd.GetNode().GetStartNode() )
1086cdf0e10cSrcweir 		DelNodes( pRange->aEnd, 1 );
1087cdf0e10cSrcweir 	else
1088cdf0e10cSrcweir 	{
1089cdf0e10cSrcweir 		pRange->aEnd++;
1090cdf0e10cSrcweir 		// fuege einen neuen EndNode ein
1091cdf0e10cSrcweir 		new SwEndNode( pRange->aEnd, *pRange->aStart.GetNode().GetStartNode() );
1092cdf0e10cSrcweir 	}
1093cdf0e10cSrcweir 	pRange->aEnd--;
1094cdf0e10cSrcweir 
1095cdf0e10cSrcweir 	SectionUpDown( aTmpIdx, pRange->aEnd );
1096cdf0e10cSrcweir }
1097cdf0e10cSrcweir 
1098cdf0e10cSrcweir /*******************************************************************
1099cdf0e10cSrcweir |*
1100cdf0e10cSrcweir |*	SwNodes::SectionUp
1101cdf0e10cSrcweir |*
1102cdf0e10cSrcweir |*	Beschreibung
1103cdf0e10cSrcweir |*		Der von rRange umspannte Bereich wird auf die naechst hoehere
1104cdf0e10cSrcweir |*		Ebene gehoben. Das geschieht dadurch, dass bei
1105cdf0e10cSrcweir |*		rRange.aStart ein Endnode und bei rRange.aEnd ein
1106cdf0e10cSrcweir |*		Startnode eingefuegt wird. Die Indices fuer den Bereich
1107cdf0e10cSrcweir |*		innerhalb von rRange werden geupdated.
1108cdf0e10cSrcweir |*
1109cdf0e10cSrcweir |*	Allg.: aRange beschreibt den Bereich  -exklusive- aEnd !!
1110cdf0e10cSrcweir |*				( 1.Node: aStart, letzer Node: aEnd-1 !! )
1111cdf0e10cSrcweir |*
1112cdf0e10cSrcweir |*	Parameter
1113cdf0e10cSrcweir |*		SwRange &rRange
1114cdf0e10cSrcweir |*			IO:
1115cdf0e10cSrcweir |*			IN
1116cdf0e10cSrcweir |*			rRange.aStart: Anfang des hoeher zubewegenden Bereiches
1117cdf0e10cSrcweir |*			rRange.aEnd:   der 1.Node hinter dem Bereich
1118cdf0e10cSrcweir |*			OUT
1119cdf0e10cSrcweir |*			rRange.aStart:	an der ersten Position innerhalb des
1120cdf0e10cSrcweir |*							hochbewegten Bereiches
1121cdf0e10cSrcweir |*			rRange.aEnd:	an der letzten Position innerhalb des
1122cdf0e10cSrcweir |*							hochbewegten Bereiches
1123cdf0e10cSrcweir |*
1124cdf0e10cSrcweir |*	Debug-Funktionen
1125cdf0e10cSrcweir |*		die Debugging Tools geben rRange beim Eintritt und beim
1126cdf0e10cSrcweir |*		Verlassen der Funktion aus
1127cdf0e10cSrcweir |*
1128cdf0e10cSrcweir |*	Ersterstellung
1129cdf0e10cSrcweir |*		VER0100 vb 901214
1130cdf0e10cSrcweir |*
1131cdf0e10cSrcweir |*	Stand
1132cdf0e10cSrcweir |*		VER0100 vb 901214
1133cdf0e10cSrcweir |*
1134cdf0e10cSrcweir *******************************************************************/
SectionUp(SwNodeRange * pRange)1135cdf0e10cSrcweir void SwNodes::SectionUp(SwNodeRange *pRange)
1136cdf0e10cSrcweir {
1137cdf0e10cSrcweir 	if( pRange->aStart >= pRange->aEnd ||
1138cdf0e10cSrcweir 		pRange->aEnd >= Count() ||
1139cdf0e10cSrcweir 		!CheckNodesRange( pRange->aStart, pRange->aEnd ) ||
1140cdf0e10cSrcweir 		!( HighestLevel( *this, *pRange ) > 1 ))
1141cdf0e10cSrcweir 		return;
1142cdf0e10cSrcweir 
1143cdf0e10cSrcweir 	// Ist der Anfang vom Bereich vor oder auf einem StartNode, so loesche
1144cdf0e10cSrcweir 	// diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes enstehen.
1145cdf0e10cSrcweir 	// Bei anderen Nodes wird eine neuer EndNode eingefuegt
1146cdf0e10cSrcweir 	SwNode * pAktNode = &pRange->aStart.GetNode();
1147cdf0e10cSrcweir 	SwNodeIndex aIdx( *pAktNode->StartOfSectionNode() );
1148cdf0e10cSrcweir 	if( pAktNode->IsStartNode() )		// selbst StartNode
1149cdf0e10cSrcweir 	{
1150cdf0e10cSrcweir 		SwEndNode* pEndNd = pRange->aEnd.GetNode().GetEndNode();
1151cdf0e10cSrcweir 		if( pAktNode == pEndNd->pStartOfSection )
1152cdf0e10cSrcweir 		{
1153cdf0e10cSrcweir 			// dann wurde paarig aufgehoben, also nur die im Berich neu anpassen
1154cdf0e10cSrcweir 			SwStartNode* pTmpSttNd = pAktNode->pStartOfSection;
1155cdf0e10cSrcweir 			RemoveNode( pRange->aStart.GetIndex(), 1, sal_True );
1156cdf0e10cSrcweir 			RemoveNode( pRange->aEnd.GetIndex(), 1, sal_True );
1157cdf0e10cSrcweir 
1158cdf0e10cSrcweir 			SwNodeIndex aTmpIdx( pRange->aStart );
1159cdf0e10cSrcweir 			while( aTmpIdx < pRange->aEnd )
1160cdf0e10cSrcweir 			{
1161cdf0e10cSrcweir 				pAktNode = &aTmpIdx.GetNode();
1162cdf0e10cSrcweir 				pAktNode->pStartOfSection = pTmpSttNd;
1163cdf0e10cSrcweir 				if( pAktNode->IsStartNode() )
1164cdf0e10cSrcweir 					aTmpIdx = pAktNode->EndOfSectionIndex() + 1;
1165cdf0e10cSrcweir 				else
1166cdf0e10cSrcweir 					aTmpIdx++;
1167cdf0e10cSrcweir 			}
1168cdf0e10cSrcweir 			return ;
1169cdf0e10cSrcweir 		}
1170cdf0e10cSrcweir 		DelNodes( pRange->aStart, 1 );
1171cdf0e10cSrcweir 	}
1172cdf0e10cSrcweir 	else if( aIdx == pRange->aStart.GetIndex()-1 )			// vor StartNode
1173cdf0e10cSrcweir 		DelNodes( aIdx, 1 );
1174cdf0e10cSrcweir 	else
1175cdf0e10cSrcweir 		new SwEndNode( pRange->aStart, *aIdx.GetNode().GetStartNode() );
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir 	// Ist das Ende vom Bereich vor oder auf einem StartNode, so loesche
1178cdf0e10cSrcweir 	// diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes entstehen
1179cdf0e10cSrcweir 	// Bei anderen Nodes wird eine neuer EndNode eingefuegt
1180cdf0e10cSrcweir 	SwNodeIndex aTmpIdx( pRange->aEnd );
1181cdf0e10cSrcweir 	if( pRange->aEnd.GetNode().IsEndNode() )
1182cdf0e10cSrcweir 		DelNodes( pRange->aEnd, 1 );
1183cdf0e10cSrcweir 	else
1184cdf0e10cSrcweir 	{
1185cdf0e10cSrcweir 		pAktNode = new SwStartNode( pRange->aEnd );
1186cdf0e10cSrcweir /*?? welcher NodeTyp ??*/
1187cdf0e10cSrcweir 		aTmpIdx = *pRange->aEnd.GetNode().EndOfSectionNode();
1188cdf0e10cSrcweir 		pRange->aEnd--;
1189cdf0e10cSrcweir 	}
1190cdf0e10cSrcweir 
1191cdf0e10cSrcweir 	SectionUpDown( aIdx, aTmpIdx );
1192cdf0e10cSrcweir }
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir 
1195cdf0e10cSrcweir /*************************************************************************
1196cdf0e10cSrcweir |*
1197cdf0e10cSrcweir |*	SwNodes::SectionUpDown()
1198cdf0e10cSrcweir |*
1199cdf0e10cSrcweir |*	Beschreibung
1200cdf0e10cSrcweir |*		Methode setzt die Indizies die bei SectionUp oder SectionDwon
1201cdf0e10cSrcweir |*		veraendert wurden wieder richtig, sodass die Ebenen wieder
1202cdf0e10cSrcweir |*		Konsistent sind.
1203cdf0e10cSrcweir |*
1204cdf0e10cSrcweir |*	  Parameter
1205cdf0e10cSrcweir |*						SwIndex & aStart		StartNode !!!
1206cdf0e10cSrcweir |*						SwIndex & aEnd			EndPunkt
1207cdf0e10cSrcweir |*
1208cdf0e10cSrcweir |*	  Ersterstellung	JP 23.04.91
1209cdf0e10cSrcweir |*	  Letzte Aenderung	JP 23.04.91
1210cdf0e10cSrcweir |*
1211cdf0e10cSrcweir *************************************************************************/
SectionUpDown(const SwNodeIndex & aStart,const SwNodeIndex & aEnd)1212cdf0e10cSrcweir void SwNodes::SectionUpDown( const SwNodeIndex & aStart, const SwNodeIndex & aEnd )
1213cdf0e10cSrcweir {
1214cdf0e10cSrcweir 	SwNode * pAktNode;
1215cdf0e10cSrcweir 	SwNodeIndex aTmpIdx( aStart, +1 );
1216cdf0e10cSrcweir 	// das Array bildet einen Stack, es werden alle StartOfSelction's gesichert
1217cdf0e10cSrcweir 	SwSttNdPtrs aSttNdStack( 1, 5 );
1218cdf0e10cSrcweir 	SwStartNode* pTmp = aStart.GetNode().GetStartNode();
1219cdf0e10cSrcweir 	aSttNdStack.C40_INSERT( SwStartNode, pTmp, 0 );
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir 	// durchlaufe bis der erste zu aendernde Start-Node gefunden wurde
1222cdf0e10cSrcweir 	// ( Es wird vom eingefuegten EndNode bis nach vorne die Indexe gesetzt )
1223cdf0e10cSrcweir 	for( ;; aTmpIdx++ )
1224cdf0e10cSrcweir 	{
1225cdf0e10cSrcweir 		pAktNode = &aTmpIdx.GetNode();
1226cdf0e10cSrcweir 		pAktNode->pStartOfSection = aSttNdStack[ aSttNdStack.Count()-1 ];
1227cdf0e10cSrcweir 
1228cdf0e10cSrcweir 		if( pAktNode->GetStartNode() )
1229cdf0e10cSrcweir 		{
1230cdf0e10cSrcweir 			pTmp = (SwStartNode*)pAktNode;
1231cdf0e10cSrcweir 			aSttNdStack.C40_INSERT( SwStartNode, pTmp, aSttNdStack.Count() );
1232cdf0e10cSrcweir 		}
1233cdf0e10cSrcweir 		else if( pAktNode->GetEndNode() )
1234cdf0e10cSrcweir 		{
1235cdf0e10cSrcweir 			SwStartNode* pSttNd = aSttNdStack[ aSttNdStack.Count() - 1 ];
1236cdf0e10cSrcweir 			pSttNd->pEndOfSection = (SwEndNode*)pAktNode;
1237cdf0e10cSrcweir 			aSttNdStack.Remove( aSttNdStack.Count() - 1 );
1238cdf0e10cSrcweir 			if( aSttNdStack.Count() )
1239cdf0e10cSrcweir 				continue;		// noch genuegend EndNodes auf dem Stack
1240cdf0e10cSrcweir 
1241cdf0e10cSrcweir 			else if( aTmpIdx < aEnd ) 	// Uebergewicht an StartNodes
1242cdf0e10cSrcweir 				// ist das Ende noch nicht erreicht, so hole den Start von
1243cdf0e10cSrcweir 				// der uebergeordneten Section
1244cdf0e10cSrcweir 			{
1245cdf0e10cSrcweir 				aSttNdStack.C40_INSERT( SwStartNode, pSttNd->pStartOfSection, 0 );
1246cdf0e10cSrcweir 			}
1247cdf0e10cSrcweir 			else	// wenn ueber den Bereich hinaus, dann Ende
1248cdf0e10cSrcweir 				break;
1249cdf0e10cSrcweir 		}
1250cdf0e10cSrcweir 	}
1251cdf0e10cSrcweir }
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir 
1254cdf0e10cSrcweir 
1255cdf0e10cSrcweir 
1256cdf0e10cSrcweir /*******************************************************************
1257cdf0e10cSrcweir |*
1258cdf0e10cSrcweir |*	SwNodes::Delete
1259cdf0e10cSrcweir |*
1260cdf0e10cSrcweir |*	Beschreibung
1261cdf0e10cSrcweir |*		Spezielle Implementierung der Delete-Funktion des
1262cdf0e10cSrcweir |*		variablen Array. Diese spezielle Implementierung ist
1263cdf0e10cSrcweir |*		notwendig, da durch das Loeschen von Start- bzw.
1264cdf0e10cSrcweir |*		Endnodes Inkonsistenzen entstehen koennen. Diese werden
1265cdf0e10cSrcweir |*		durch diese Funktion beseitigt.
1266cdf0e10cSrcweir |*
1267cdf0e10cSrcweir |*	Parameter
1268cdf0e10cSrcweir |*		IN
1269cdf0e10cSrcweir |*		SwIndex &rIndex bezeichnet die Position, an der
1270cdf0e10cSrcweir |*		geloescht wird
1271cdf0e10cSrcweir |*		rIndex ist nach Aufruf der Funktion unveraendert (Kopie?!)
1272cdf0e10cSrcweir |*		sal_uInt16 nNodes bezeichnet die Anzahl der zu loeschenden
1273cdf0e10cSrcweir |*		Nodes; ist auf 1 defaulted
1274cdf0e10cSrcweir |*
1275cdf0e10cSrcweir |*	Debug-Funktionen
1276cdf0e10cSrcweir |*		geben beim Eintritt in die Funktion Position und Anzahl
1277cdf0e10cSrcweir |*		der zu loeschenden Nodes aus.
1278cdf0e10cSrcweir |*
1279cdf0e10cSrcweir |*	Ersterstellung
1280cdf0e10cSrcweir |*		VER0100 vb 901214
1281cdf0e10cSrcweir |*
1282cdf0e10cSrcweir |*	Stand
1283cdf0e10cSrcweir |*		VER0100 vb 901214
1284cdf0e10cSrcweir |*
1285cdf0e10cSrcweir *******************************************************************/
Delete(const SwNodeIndex & rIndex,sal_uLong nNodes)1286cdf0e10cSrcweir void SwNodes::Delete(const SwNodeIndex &rIndex, sal_uLong nNodes)
1287cdf0e10cSrcweir {
1288cdf0e10cSrcweir 	sal_uInt16 nLevel = 0;						// Level-Counter
1289cdf0e10cSrcweir 	SwNode * pAktNode;
1290cdf0e10cSrcweir 
1291cdf0e10cSrcweir 	sal_uLong nCnt = Count() - rIndex.GetIndex() - 1;
1292cdf0e10cSrcweir 	if( nCnt > nNodes ) nCnt = nNodes;
1293cdf0e10cSrcweir 
1294cdf0e10cSrcweir 	if( nCnt == 0 ) 		// keine Anzahl -> return
1295cdf0e10cSrcweir 		return;
1296cdf0e10cSrcweir 
1297cdf0e10cSrcweir 	SwNodeRange aRg( rIndex, 0, rIndex, nCnt-1 );
1298cdf0e10cSrcweir 	// ueberprufe ob rIndex..rIndex + nCnt ueber einen Bereich hinausragt !!
1299cdf0e10cSrcweir 	if( ( !aRg.aStart.GetNode().StartOfSectionIndex() &&
1300cdf0e10cSrcweir 			!aRg.aStart.GetIndex() ) ||
1301cdf0e10cSrcweir 			! CheckNodesRange( aRg.aStart, aRg.aEnd ) )
1302cdf0e10cSrcweir 		return;
1303cdf0e10cSrcweir 
1304cdf0e10cSrcweir 
1305cdf0e10cSrcweir 	// falls aEnd auf keinem ContentNode steht, dann suche den vorherigen
1306cdf0e10cSrcweir 	while( ( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() ||
1307cdf0e10cSrcweir 			 ( pAktNode->GetEndNode() &&
1308cdf0e10cSrcweir 				!pAktNode->pStartOfSection->IsTableNode() ))
1309cdf0e10cSrcweir 		aRg.aEnd--;
1310cdf0e10cSrcweir 
1311cdf0e10cSrcweir 	nCnt = 0;
1312cdf0e10cSrcweir 	// Start erhoehen, damit auf < abgefragt wird. ( bei <= kann es zu
1313cdf0e10cSrcweir 	// Problemen fuehren; ist aEnd == aStart und wird aEnd geloscht,
1314cdf0e10cSrcweir 	// so ist aEnd <= aStart
1315cdf0e10cSrcweir 	aRg.aStart--;
1316cdf0e10cSrcweir 
1317cdf0e10cSrcweir 	sal_Bool bSaveInNodesDel = bInNodesDel;
1318cdf0e10cSrcweir 	bInNodesDel = sal_True;
1319cdf0e10cSrcweir 	sal_Bool bUpdateOutline = sal_False;
1320cdf0e10cSrcweir 
1321cdf0e10cSrcweir 	// bis alles geloescht ist
1322cdf0e10cSrcweir 	while( aRg.aStart < aRg.aEnd )
1323cdf0e10cSrcweir 	{
1324cdf0e10cSrcweir 		pAktNode = &aRg.aEnd.GetNode();
1325cdf0e10cSrcweir 
1326cdf0e10cSrcweir 		if( pAktNode->GetEndNode() )
1327cdf0e10cSrcweir 		{
1328cdf0e10cSrcweir 			// die gesamte Section loeschen ?
1329cdf0e10cSrcweir 			if( pAktNode->StartOfSectionIndex() > aRg.aStart.GetIndex() )
1330cdf0e10cSrcweir 			{
1331cdf0e10cSrcweir 				SwTableNode* pTblNd = pAktNode->pStartOfSection->GetTableNode();
1332cdf0e10cSrcweir 				if( pTblNd )
1333cdf0e10cSrcweir 					pTblNd->DelFrms();
1334cdf0e10cSrcweir 
1335cdf0e10cSrcweir 				SwNode *pNd, *pChkNd = pAktNode->pStartOfSection;
1336cdf0e10cSrcweir 				sal_uInt16 nIdxPos;
1337cdf0e10cSrcweir 				do {
1338cdf0e10cSrcweir 					pNd = &aRg.aEnd.GetNode();
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir 					if( pNd->IsTxtNode() )
1341cdf0e10cSrcweir 					{
1342cdf0e10cSrcweir 						//if( NO_NUMBERING !=					//#outline level,zhaojianwei
1343cdf0e10cSrcweir 						//	((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel() &&
1344cdf0e10cSrcweir 						if( 0 != ((SwTxtNode*)pNd)->GetAttrOutlineLevel() &&//<-end,zhaojianwei
1345cdf0e10cSrcweir 								pOutlineNds->Seek_Entry( pNd, &nIdxPos ))
1346cdf0e10cSrcweir 						{
1347cdf0e10cSrcweir 							// loesche die Gliederungs-Indizies.
1348cdf0e10cSrcweir 							pOutlineNds->Remove( nIdxPos );
1349cdf0e10cSrcweir 							bUpdateOutline = sal_True;
1350cdf0e10cSrcweir 						}
1351cdf0e10cSrcweir                         ((SwTxtNode*)pNd)->InvalidateNumRule();
1352cdf0e10cSrcweir 					}
1353cdf0e10cSrcweir 					else if( pNd->IsEndNode() &&
1354cdf0e10cSrcweir 							pNd->pStartOfSection->IsTableNode() )
1355cdf0e10cSrcweir 						((SwTableNode*)pNd->pStartOfSection)->DelFrms();
1356cdf0e10cSrcweir 
1357cdf0e10cSrcweir 					aRg.aEnd--;
1358cdf0e10cSrcweir 					nCnt++;
1359cdf0e10cSrcweir 
1360cdf0e10cSrcweir 				} while( pNd != pChkNd );
1361cdf0e10cSrcweir 			}
1362cdf0e10cSrcweir 			else
1363cdf0e10cSrcweir 			{
1364cdf0e10cSrcweir 				RemoveNode( aRg.aEnd.GetIndex()+1, nCnt, sal_True );	// loesche
1365cdf0e10cSrcweir 				nCnt = 0;
1366cdf0e10cSrcweir 				aRg.aEnd--;				// vor den EndNode
1367cdf0e10cSrcweir 				nLevel++;
1368cdf0e10cSrcweir 			}
1369cdf0e10cSrcweir 		}
1370cdf0e10cSrcweir 		else if( pAktNode->GetStartNode() )	  // StartNode gefunden
1371cdf0e10cSrcweir 		{
1372cdf0e10cSrcweir 			if( nLevel == 0 )		// es wird eine Stufe runter gestuft
1373cdf0e10cSrcweir 			{
1374cdf0e10cSrcweir 				if( nCnt )
1375cdf0e10cSrcweir 				{
1376cdf0e10cSrcweir 					// loesche jetzt das Array
1377cdf0e10cSrcweir 					aRg.aEnd++;
1378cdf0e10cSrcweir 					RemoveNode( aRg.aEnd.GetIndex(), nCnt, sal_True );
1379cdf0e10cSrcweir 					nCnt = 0;
1380cdf0e10cSrcweir 				}
1381cdf0e10cSrcweir 			}
1382cdf0e10cSrcweir 			else	// es werden alle Nodes Innerhalb eines Start- und
1383cdf0e10cSrcweir 			{		// End-Nodes geloescht, loesche mit Start/EndNode
1384cdf0e10cSrcweir 				RemoveNode( aRg.aEnd.GetIndex(), nCnt + 2, sal_True );			// loesche Array
1385cdf0e10cSrcweir 				nCnt = 0;
1386cdf0e10cSrcweir 				nLevel--;
1387cdf0e10cSrcweir 			}
1388cdf0e10cSrcweir 
1389cdf0e10cSrcweir 			// nach dem loeschen kann aEnd auf einem EndNode stehen
1390cdf0e10cSrcweir 			// loesche alle leeren Start-/End-Node-Paare
1391cdf0e10cSrcweir 			SwNode* pTmpNode = aRg.aEnd.GetNode().GetEndNode();
1392cdf0e10cSrcweir 			aRg.aEnd--;
1393cdf0e10cSrcweir 			while(  pTmpNode &&
1394cdf0e10cSrcweir 					( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() &&
1395cdf0e10cSrcweir 					pAktNode->StartOfSectionIndex() )
1396cdf0e10cSrcweir 			{
1397cdf0e10cSrcweir 				// loesche den EndNode und StartNode
1398cdf0e10cSrcweir 				DelNodes( aRg.aEnd, 2 );
1399cdf0e10cSrcweir 				pTmpNode = aRg.aEnd.GetNode().GetEndNode();
1400cdf0e10cSrcweir 				aRg.aEnd--;
1401cdf0e10cSrcweir 			}
1402cdf0e10cSrcweir 		}
1403cdf0e10cSrcweir 		else		// normaler Node, also ins TmpArray einfuegen
1404cdf0e10cSrcweir 		{
1405cdf0e10cSrcweir 			SwTxtNode* pTxtNd = pAktNode->GetTxtNode();
1406cdf0e10cSrcweir 			if( pTxtNd )
1407cdf0e10cSrcweir 			{
1408cdf0e10cSrcweir 				if( pTxtNd->IsOutline())
1409cdf0e10cSrcweir 				{					// loesche die Gliederungs-Indizies.
1410cdf0e10cSrcweir 					pOutlineNds->Remove( pTxtNd );
1411cdf0e10cSrcweir 					bUpdateOutline = sal_True;
1412cdf0e10cSrcweir 				}
1413cdf0e10cSrcweir 				pTxtNd->InvalidateNumRule();
1414cdf0e10cSrcweir 			}
1415cdf0e10cSrcweir 			else if( pAktNode->IsCntntNode() )
1416cdf0e10cSrcweir 				((SwCntntNode*)pAktNode)->InvalidateNumRule();
1417cdf0e10cSrcweir 
1418cdf0e10cSrcweir 			aRg.aEnd--;
1419cdf0e10cSrcweir 			nCnt++;
1420cdf0e10cSrcweir 		}
1421cdf0e10cSrcweir 	}
1422cdf0e10cSrcweir 
1423cdf0e10cSrcweir 	aRg.aEnd++;
1424cdf0e10cSrcweir 	if( nCnt != 0 )
1425cdf0e10cSrcweir 		RemoveNode( aRg.aEnd.GetIndex(), nCnt, sal_True );				// loesche den Rest
1426cdf0e10cSrcweir 
1427cdf0e10cSrcweir 	// loesche alle leeren Start-/End-Node-Paare
1428cdf0e10cSrcweir 	while( aRg.aEnd.GetNode().GetEndNode() &&
1429cdf0e10cSrcweir 			( pAktNode = &aRg.aStart.GetNode())->GetStartNode() &&
1430cdf0e10cSrcweir 			pAktNode->StartOfSectionIndex() )
1431cdf0e10cSrcweir 	// aber ja keinen der heiligen 5.
1432cdf0e10cSrcweir 	{
1433cdf0e10cSrcweir 		DelNodes( aRg.aStart, 2 );	// loesche den Start- und EndNode
1434cdf0e10cSrcweir 		aRg.aStart--;
1435cdf0e10cSrcweir 	}
1436cdf0e10cSrcweir 
1437cdf0e10cSrcweir 	bInNodesDel = bSaveInNodesDel;
1438cdf0e10cSrcweir 
1439cdf0e10cSrcweir 	if( !bInNodesDel )
1440cdf0e10cSrcweir 	{
1441cdf0e10cSrcweir 		// rufe jetzt noch das Update fuer die Gliederung/Nummerierung auf
1442cdf0e10cSrcweir 		if( bUpdateOutline || bInDelUpdOutl )
1443cdf0e10cSrcweir 		{
1444cdf0e10cSrcweir 			UpdtOutlineIdx( aRg.aEnd.GetNode() );
1445cdf0e10cSrcweir 			bInDelUpdOutl = sal_False;
1446cdf0e10cSrcweir 		}
1447cdf0e10cSrcweir 
1448cdf0e10cSrcweir 	}
1449cdf0e10cSrcweir 	else
1450cdf0e10cSrcweir 	{
1451cdf0e10cSrcweir 		if( bUpdateOutline )
1452cdf0e10cSrcweir 			bInDelUpdOutl = sal_True;
1453cdf0e10cSrcweir 	}
1454cdf0e10cSrcweir }
1455cdf0e10cSrcweir 
1456cdf0e10cSrcweir /*******************************************************************
1457cdf0e10cSrcweir |*
1458cdf0e10cSrcweir |*	SwNodes::GetSectionLevel
1459cdf0e10cSrcweir |*
1460cdf0e10cSrcweir |*	Beschreibung
1461cdf0e10cSrcweir |*		Die Funktion liefert den Sectionlevel an der durch
1462cdf0e10cSrcweir |*		aIndex bezeichneten Position. Die Funktion ruft die
1463cdf0e10cSrcweir |*		GetSectionlevel-Funktion des durch aIndex bezeichneten
1464cdf0e10cSrcweir |*		Nodes. Diese ist eine virtuelle Funktion, die fuer
1465cdf0e10cSrcweir |*		Endnodes speziell implementiert werden musste.
1466cdf0e10cSrcweir |*		Die Sectionlevels werden ermittelt, indem rekursiv durch
1467cdf0e10cSrcweir |*		die Nodesstruktur (jeweils zum naechsten theEndOfSection)
1468cdf0e10cSrcweir |*		gegangen wird, bis die oberste Ebene erreicht ist
1469cdf0e10cSrcweir |*		(theEndOfSection == 0)
1470cdf0e10cSrcweir |*
1471cdf0e10cSrcweir |*	Parameter
1472cdf0e10cSrcweir |*		aIndex bezeichnet die Position des Nodes, dessen
1473cdf0e10cSrcweir |*		Sectionlevel ermittelt werden soll. Hier wird eine Kopie
1474cdf0e10cSrcweir |*		uebergeben, da eine Veraenderung der Variablen in der
1475cdf0e10cSrcweir |*		rufenden Funktion nicht wuenschenswert ist.
1476cdf0e10cSrcweir |*
1477cdf0e10cSrcweir |*	Ausnahmen
1478cdf0e10cSrcweir |*		Der erste Node im Array  sollte immer ein Startnode sein.
1479cdf0e10cSrcweir |*		Dieser erfaehrt in der Funktion SwNodes::GetSectionLevel()
1480cdf0e10cSrcweir |*      eine Sonderbehandlung; es wird davon ausgegangen, dass der
1481cdf0e10cSrcweir |*		erste Node auch ein Startnode ist.
1482cdf0e10cSrcweir |*
1483cdf0e10cSrcweir |*	Ersterstellung
1484cdf0e10cSrcweir |*		VER0100 vb 901214
1485cdf0e10cSrcweir |*
1486cdf0e10cSrcweir |*	Stand
1487cdf0e10cSrcweir |*		VER0100 vb 901214
1488cdf0e10cSrcweir |*
1489cdf0e10cSrcweir *******************************************************************/
GetSectionLevel(const SwNodeIndex & rIdx) const1490cdf0e10cSrcweir sal_uInt16 SwNodes::GetSectionLevel(const SwNodeIndex &rIdx) const {
1491cdf0e10cSrcweir 	// Sonderbehandlung 1. Node
1492cdf0e10cSrcweir 	if(rIdx == 0) return 1;
1493cdf0e10cSrcweir 	/*
1494cdf0e10cSrcweir 	 * Keine Rekursion! - hier wird das SwNode::GetSectionLevel
1495cdf0e10cSrcweir 	 * aufgerufen
1496cdf0e10cSrcweir 	 */
1497cdf0e10cSrcweir     return rIdx.GetNode().GetSectionLevel();
1498cdf0e10cSrcweir }
1499cdf0e10cSrcweir 
GoStartOfSection(SwNodeIndex * pIdx) const1500cdf0e10cSrcweir void SwNodes::GoStartOfSection(SwNodeIndex *pIdx) const
1501cdf0e10cSrcweir {
1502cdf0e10cSrcweir 	// hinter den naechsten Startnode
1503cdf0e10cSrcweir 	SwNodeIndex aTmp( *pIdx->GetNode().StartOfSectionNode(), +1 );
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir 	// steht der Index auf keinem ContentNode, dann gehe dahin. Ist aber
1506cdf0e10cSrcweir 	// kein weiterer vorhanden, dann lasse den Index an alter Pos stehen !!!
1507cdf0e10cSrcweir 	while( !aTmp.GetNode().IsCntntNode() )
1508cdf0e10cSrcweir 	{	// gehe vom StartNode ( es kann nur ein StartNode sein ! ) an sein
1509cdf0e10cSrcweir 		// Ende
1510cdf0e10cSrcweir 		if( *pIdx <= aTmp )
1511cdf0e10cSrcweir 			return; 	// FEHLER: Steht schon hinter der Sektion
1512cdf0e10cSrcweir 		aTmp = aTmp.GetNode().EndOfSectionIndex()+1;
1513cdf0e10cSrcweir 		if( *pIdx <= aTmp )
1514cdf0e10cSrcweir 			return; 	// FEHLER: Steht schon hinter der Sektion
1515cdf0e10cSrcweir 	}
1516cdf0e10cSrcweir 	(*pIdx) = aTmp; 	// steht auf einem ContentNode
1517cdf0e10cSrcweir }
1518cdf0e10cSrcweir 
GoEndOfSection(SwNodeIndex * pIdx) const1519cdf0e10cSrcweir void SwNodes::GoEndOfSection(SwNodeIndex *pIdx) const
1520cdf0e10cSrcweir {
1521cdf0e10cSrcweir 	// falls er vor einem Endnode steht --> nichts tun
1522cdf0e10cSrcweir 	if( !pIdx->GetNode().IsEndNode() )
1523cdf0e10cSrcweir 		(*pIdx) = *pIdx->GetNode().EndOfSectionNode();
1524cdf0e10cSrcweir }
1525cdf0e10cSrcweir 
GoNext(SwNodeIndex * pIdx) const1526cdf0e10cSrcweir SwCntntNode* SwNodes::GoNext(SwNodeIndex *pIdx) const
1527cdf0e10cSrcweir {
1528cdf0e10cSrcweir 	if( pIdx->GetIndex() >= Count() - 1 )
1529cdf0e10cSrcweir 		return 0;
1530cdf0e10cSrcweir 
1531cdf0e10cSrcweir 	SwNodeIndex aTmp(*pIdx, +1);
1532cdf0e10cSrcweir     SwNode* pNd = 0;
1533cdf0e10cSrcweir 	while( aTmp < Count()-1 && 0 == ( pNd = &aTmp.GetNode())->IsCntntNode() )
1534cdf0e10cSrcweir 		aTmp++;
1535cdf0e10cSrcweir 
1536cdf0e10cSrcweir 	if( aTmp == Count()-1 )
1537cdf0e10cSrcweir 		pNd = 0;
1538cdf0e10cSrcweir 	else
1539cdf0e10cSrcweir 		(*pIdx) = aTmp;
1540cdf0e10cSrcweir 	return (SwCntntNode*)pNd;
1541cdf0e10cSrcweir }
1542cdf0e10cSrcweir 
GoPrevious(SwNodeIndex * pIdx) const1543cdf0e10cSrcweir SwCntntNode* SwNodes::GoPrevious(SwNodeIndex *pIdx) const
1544cdf0e10cSrcweir {
1545cdf0e10cSrcweir 	if( !pIdx->GetIndex() )
1546cdf0e10cSrcweir 		return 0;
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir 	SwNodeIndex aTmp( *pIdx, -1 );
1549cdf0e10cSrcweir 	SwNode* pNd = 0;
1550cdf0e10cSrcweir 	while( aTmp.GetIndex() && 0 == ( pNd = &aTmp.GetNode())->IsCntntNode() )
1551cdf0e10cSrcweir 		aTmp--;
1552cdf0e10cSrcweir 
1553cdf0e10cSrcweir 	if( !aTmp.GetIndex() )
1554cdf0e10cSrcweir 		pNd = 0;
1555cdf0e10cSrcweir 	else
1556cdf0e10cSrcweir 		(*pIdx) = aTmp;
1557cdf0e10cSrcweir 	return (SwCntntNode*)pNd;
1558cdf0e10cSrcweir }
1559cdf0e10cSrcweir 
1560cdf0e10cSrcweir /*************************************************************************
1561cdf0e10cSrcweir |*
1562cdf0e10cSrcweir |*	  sal_Bool SwNodes::CheckNodesRange()
1563cdf0e10cSrcweir |*
1564cdf0e10cSrcweir |*	  Beschreibung
1565cdf0e10cSrcweir |*		Teste ob der uebergene SRange nicht ueber die Grenzen der
1566cdf0e10cSrcweir |*		einzelnen Bereiche (PosIts, Autotext, Content, Icons und Inserts )
1567cdf0e10cSrcweir |*		hinaus reicht.
1568cdf0e10cSrcweir |*		Nach Wahrscheinlichkeit des Ranges sortiert.
1569cdf0e10cSrcweir |*
1570cdf0e10cSrcweir |*	Alg.: Da festgelegt ist, das aRange.aEnd den 1.Node hinter dem Bereich
1571cdf0e10cSrcweir |*		  bezeichnet, wird hier auf aEnd <= End.. getestet !!
1572cdf0e10cSrcweir |*
1573cdf0e10cSrcweir |*	  Parameter 		SwIndex &	Start-Index vom Bereich
1574cdf0e10cSrcweir |*						SwIndex &	End-Index vom Bereich
1575cdf0e10cSrcweir |*                      sal_Bool		sal_True: 	Start+End in gleicher Section!
1576cdf0e10cSrcweir |*									sal_False:	Start+End in verschiedenen Sect.
1577cdf0e10cSrcweir |*	  Return-Wert		sal_Bool		sal_True:	gueltiger SRange
1578cdf0e10cSrcweir |*									sal_False:	ungueltiger SRange
1579cdf0e10cSrcweir |*
1580cdf0e10cSrcweir |*	  Ersterstellung	JP 23.04.91
1581cdf0e10cSrcweir |*	  Letzte Aenderung	JP 18.06.92
1582cdf0e10cSrcweir |*
1583cdf0e10cSrcweir *************************************************************************/
1584cdf0e10cSrcweir 
TstIdx(sal_uLong nSttIdx,sal_uLong nEndIdx,sal_uLong nStt,sal_uLong nEnd)1585cdf0e10cSrcweir inline int TstIdx( sal_uLong nSttIdx, sal_uLong nEndIdx, sal_uLong nStt, sal_uLong nEnd )
1586cdf0e10cSrcweir {
1587cdf0e10cSrcweir 	return nStt < nSttIdx && nEnd >= nSttIdx &&
1588cdf0e10cSrcweir 			nStt < nEndIdx && nEnd >= nEndIdx;
1589cdf0e10cSrcweir }
1590cdf0e10cSrcweir 
CheckNodesRange(const SwNodeIndex & rStt,const SwNodeIndex & rEnd) const1591cdf0e10cSrcweir sal_Bool SwNodes::CheckNodesRange( const SwNodeIndex& rStt, const SwNodeIndex& rEnd ) const
1592cdf0e10cSrcweir {
1593cdf0e10cSrcweir 	sal_uLong nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
1594cdf0e10cSrcweir 	if( TstIdx( nStt, nEnd, pEndOfContent->StartOfSectionIndex(),
1595cdf0e10cSrcweir 				pEndOfContent->GetIndex() )) return sal_True;
1596cdf0e10cSrcweir 	if( TstIdx( nStt, nEnd, pEndOfAutotext->StartOfSectionIndex(),
1597cdf0e10cSrcweir 				pEndOfAutotext->GetIndex() )) return sal_True;
1598cdf0e10cSrcweir 	if( TstIdx( nStt, nEnd, pEndOfPostIts->StartOfSectionIndex(),
1599cdf0e10cSrcweir 				pEndOfPostIts->GetIndex() )) return sal_True;
1600cdf0e10cSrcweir 	if( TstIdx( nStt, nEnd, pEndOfInserts->StartOfSectionIndex(),
1601cdf0e10cSrcweir 				pEndOfInserts->GetIndex() )) return sal_True;
1602cdf0e10cSrcweir 	if( TstIdx( nStt, nEnd, pEndOfRedlines->StartOfSectionIndex(),
1603cdf0e10cSrcweir 				pEndOfRedlines->GetIndex() )) return sal_True;
1604cdf0e10cSrcweir 
1605cdf0e10cSrcweir 	return sal_False;		// liegt irgendwo dazwischen, FEHLER
1606cdf0e10cSrcweir }
1607cdf0e10cSrcweir 
1608cdf0e10cSrcweir 
1609cdf0e10cSrcweir /*************************************************************************
1610cdf0e10cSrcweir |*
1611cdf0e10cSrcweir |*	  void SwNodes::DelNodes()
1612cdf0e10cSrcweir |*
1613cdf0e10cSrcweir |*	  Beschreibung
1614cdf0e10cSrcweir |*		Loesche aus den NodesArray ab einer Position entsprechend Node's.
1615cdf0e10cSrcweir |*
1616cdf0e10cSrcweir |*	  Parameter 		SwIndex &	Der Startpunkt im Nodes-Array
1617cdf0e10cSrcweir |*						sal_uInt16		die Anzahl
1618cdf0e10cSrcweir |*
1619cdf0e10cSrcweir |*	  Ersterstellung	JP 23.04.91
1620cdf0e10cSrcweir |*	  Letzte Aenderung	JP 23.04.91
1621cdf0e10cSrcweir |*
1622cdf0e10cSrcweir *************************************************************************/
DelNodes(const SwNodeIndex & rStart,sal_uLong nCnt)1623cdf0e10cSrcweir void SwNodes::DelNodes( const SwNodeIndex & rStart, sal_uLong nCnt )
1624cdf0e10cSrcweir {
1625cdf0e10cSrcweir 	int bUpdateNum = 0;
1626cdf0e10cSrcweir 	sal_uLong nSttIdx = rStart.GetIndex();
1627cdf0e10cSrcweir 
1628cdf0e10cSrcweir 	if( !nSttIdx && nCnt == GetEndOfContent().GetIndex()+1 )
1629cdf0e10cSrcweir 	{
1630cdf0e10cSrcweir 		// es wird das gesamte Nodes-Array zerstoert, man ist im Doc DTOR!
1631cdf0e10cSrcweir 		// Die initialen Start-/End-Nodes duerfen nur im SwNodes-DTOR
1632cdf0e10cSrcweir 		// zerstoert werden!
1633cdf0e10cSrcweir 		SwNode* aEndNdArr[] = { pEndOfContent,
1634cdf0e10cSrcweir 								pEndOfPostIts, pEndOfInserts,
1635cdf0e10cSrcweir 								pEndOfAutotext, pEndOfRedlines,
1636cdf0e10cSrcweir 								0
1637cdf0e10cSrcweir 							  };
1638cdf0e10cSrcweir 
1639cdf0e10cSrcweir 		SwNode** ppEndNdArr = aEndNdArr;
1640cdf0e10cSrcweir 		while( *ppEndNdArr )
1641cdf0e10cSrcweir 		{
1642cdf0e10cSrcweir 			nSttIdx = (*ppEndNdArr)->StartOfSectionIndex() + 1;
1643cdf0e10cSrcweir 			sal_uLong nEndIdx = (*ppEndNdArr)->GetIndex();
1644cdf0e10cSrcweir 
1645cdf0e10cSrcweir 			if( nSttIdx != nEndIdx )
1646cdf0e10cSrcweir 				RemoveNode( nSttIdx, nEndIdx - nSttIdx, sal_True );
1647cdf0e10cSrcweir 
1648cdf0e10cSrcweir 			++ppEndNdArr;
1649cdf0e10cSrcweir 		}
1650cdf0e10cSrcweir 	}
1651cdf0e10cSrcweir 	else
1652cdf0e10cSrcweir 	{
1653cdf0e10cSrcweir 		for( sal_uLong n = nSttIdx, nEnd = nSttIdx + nCnt; n < nEnd; ++n )
1654cdf0e10cSrcweir 		{
1655cdf0e10cSrcweir 			SwNode* pNd = (*this)[ n ];
1656cdf0e10cSrcweir 
1657cdf0e10cSrcweir 			if( pNd->IsTxtNode() &&
1658cdf0e10cSrcweir 				//NO_NUMBERING != ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
1659cdf0e10cSrcweir 				0 != ((SwTxtNode*)pNd)->GetAttrOutlineLevel() )	//<-end,zhaojianwei
1660cdf0e10cSrcweir 			{                   // loesche die Gliederungs-Indizies.
1661cdf0e10cSrcweir 				sal_uInt16 nIdxPos;
1662cdf0e10cSrcweir 				if( pOutlineNds->Seek_Entry( pNd, &nIdxPos ))
1663cdf0e10cSrcweir 				{
1664cdf0e10cSrcweir 					pOutlineNds->Remove( nIdxPos );
1665cdf0e10cSrcweir 					bUpdateNum = 1;
1666cdf0e10cSrcweir 				}
1667cdf0e10cSrcweir 			}
1668cdf0e10cSrcweir 			if( pNd->IsCntntNode() )
1669cdf0e10cSrcweir             {
1670cdf0e10cSrcweir 				((SwCntntNode*)pNd)->InvalidateNumRule();
1671cdf0e10cSrcweir                 ((SwCntntNode*)pNd)->DelFrms();
1672cdf0e10cSrcweir             }
1673cdf0e10cSrcweir 		}
1674cdf0e10cSrcweir 		RemoveNode( nSttIdx, nCnt, sal_True );
1675cdf0e10cSrcweir 
1676cdf0e10cSrcweir 		// rufe noch das Update fuer die Gliederungsnumerierung auf
1677cdf0e10cSrcweir 		if( bUpdateNum )
1678cdf0e10cSrcweir 			UpdtOutlineIdx( rStart.GetNode() );
1679cdf0e10cSrcweir 	}
1680cdf0e10cSrcweir }
1681cdf0e10cSrcweir 
1682cdf0e10cSrcweir 
1683cdf0e10cSrcweir /*************************************************************************
1684cdf0e10cSrcweir |*
1685cdf0e10cSrcweir |*	  sal_uInt16 HighestLevel( SwNodes & rNodes, const SwNodeRange & rRange )
1686cdf0e10cSrcweir |*
1687cdf0e10cSrcweir |*	  Beschreibung
1688cdf0e10cSrcweir |*		Berechne den hoehsten Level innerhalb des Bereiches
1689cdf0e10cSrcweir |*
1690cdf0e10cSrcweir |*	  Parameter 		SwNodes &	das Node-Array
1691cdf0e10cSrcweir |*						SwNodeRange &	der zu ueberpruefende Bereich
1692cdf0e10cSrcweir |*	  Return			sal_uInt16		der hoechste Level
1693cdf0e10cSrcweir |*
1694cdf0e10cSrcweir |*	  Ersterstellung	JP 24.04.91
1695cdf0e10cSrcweir |*	  Letzte Aenderung	JP 24.04.91
1696cdf0e10cSrcweir |*
1697cdf0e10cSrcweir *************************************************************************/
1698cdf0e10cSrcweir 
1699cdf0e10cSrcweir struct HighLevel
1700cdf0e10cSrcweir {
1701cdf0e10cSrcweir 	sal_uInt16 nLevel, nTop;
HighLevelHighLevel1702cdf0e10cSrcweir 	HighLevel( sal_uInt16 nLv ) : nLevel( nLv ), nTop( nLv ) {}
1703cdf0e10cSrcweir 
1704cdf0e10cSrcweir };
1705cdf0e10cSrcweir 
_HighestLevel(const SwNodePtr & rpNode,void * pPara)1706cdf0e10cSrcweir sal_Bool _HighestLevel( const SwNodePtr& rpNode, void * pPara )
1707cdf0e10cSrcweir {
1708cdf0e10cSrcweir 	HighLevel * pHL = (HighLevel*)pPara;
1709cdf0e10cSrcweir 	if( rpNode->GetStartNode() )
1710cdf0e10cSrcweir 		pHL->nLevel++;
1711cdf0e10cSrcweir 	else if( rpNode->GetEndNode() )
1712cdf0e10cSrcweir 		pHL->nLevel--;
1713cdf0e10cSrcweir 	if( pHL->nTop > pHL->nLevel )
1714cdf0e10cSrcweir 		pHL->nTop = pHL->nLevel;
1715cdf0e10cSrcweir 	return sal_True;
1716cdf0e10cSrcweir 
1717cdf0e10cSrcweir }
1718cdf0e10cSrcweir 
HighestLevel(SwNodes & rNodes,const SwNodeRange & rRange)1719cdf0e10cSrcweir sal_uInt16 HighestLevel( SwNodes & rNodes, const SwNodeRange & rRange )
1720cdf0e10cSrcweir {
1721cdf0e10cSrcweir 	HighLevel aPara( rNodes.GetSectionLevel( rRange.aStart ));
1722cdf0e10cSrcweir 	rNodes.ForEach( rRange.aStart, rRange.aEnd, _HighestLevel, &aPara );
1723cdf0e10cSrcweir 	return aPara.nTop;
1724cdf0e10cSrcweir 
1725cdf0e10cSrcweir }
1726cdf0e10cSrcweir 
1727cdf0e10cSrcweir /*************************************************************************
1728cdf0e10cSrcweir |*
1729cdf0e10cSrcweir |*    SwNodes::Move()
1730cdf0e10cSrcweir |*
1731cdf0e10cSrcweir |*    Beschreibung
1732cdf0e10cSrcweir |*    Parameter         SwPaM&		zu kopierender Bereich
1733cdf0e10cSrcweir |*                      SwNodes&	in dieses Nodes-Array
1734cdf0e10cSrcweir |*                      SwPosition&	auf diese Position im Nodes-Array
1735cdf0e10cSrcweir |*    Ersterstellung    JP 09.07.92
1736cdf0e10cSrcweir |*    Letzte Aenderung  JP 09.07.92
1737cdf0e10cSrcweir |*
1738cdf0e10cSrcweir *************************************************************************/
MoveRange(SwPaM & rPam,SwPosition & rPos,SwNodes & rNodes)1739cdf0e10cSrcweir void SwNodes::MoveRange( SwPaM & rPam, SwPosition & rPos, SwNodes& rNodes )
1740cdf0e10cSrcweir {
1741cdf0e10cSrcweir     SwPosition * const pStt = rPam.Start();
1742cdf0e10cSrcweir     SwPosition * const pEnd = rPam.End();
1743cdf0e10cSrcweir 
1744cdf0e10cSrcweir 	if( !rPam.HasMark() || *pStt >= *pEnd )
1745cdf0e10cSrcweir 		return;
1746cdf0e10cSrcweir 
1747cdf0e10cSrcweir 	if( this == &rNodes && *pStt <= rPos && rPos < *pEnd )
1748cdf0e10cSrcweir 		return;
1749cdf0e10cSrcweir 
1750cdf0e10cSrcweir 	SwNodeIndex aEndIdx( pEnd->nNode );
1751cdf0e10cSrcweir 	SwNodeIndex aSttIdx( pStt->nNode );
1752cdf0e10cSrcweir     SwTxtNode *const pSrcNd = aSttIdx.GetNode().GetTxtNode();
1753cdf0e10cSrcweir     SwTxtNode * pDestNd = rPos.nNode.GetNode().GetTxtNode();
1754cdf0e10cSrcweir 	sal_Bool bSplitDestNd = sal_True;
1755cdf0e10cSrcweir 	sal_Bool bCopyCollFmt = pDestNd && !pDestNd->GetTxt().Len();
1756cdf0e10cSrcweir 
1757cdf0e10cSrcweir 	if( pSrcNd )
1758cdf0e10cSrcweir 	{
1759cdf0e10cSrcweir 		// ist der 1.Node ein TextNode, dann muss im NodesArray auch
1760cdf0e10cSrcweir 		// ein TextNode vorhanden sein, in den der Inhalt geschoben wird
1761cdf0e10cSrcweir 		if( !pDestNd )
1762cdf0e10cSrcweir 		{
1763cdf0e10cSrcweir 			pDestNd = rNodes.MakeTxtNode( rPos.nNode, pSrcNd->GetTxtColl() );
1764cdf0e10cSrcweir 			rPos.nNode--;
1765cdf0e10cSrcweir 			rPos.nContent.Assign( pDestNd, 0 );
1766cdf0e10cSrcweir 			bCopyCollFmt = sal_True;
1767cdf0e10cSrcweir 		}
1768cdf0e10cSrcweir 		bSplitDestNd = pDestNd->Len() > rPos.nContent.GetIndex() ||
1769cdf0e10cSrcweir 						pEnd->nNode.GetNode().IsTxtNode();
1770cdf0e10cSrcweir 
1771cdf0e10cSrcweir 		// verschiebe jetzt noch den Inhalt in den neuen Node
1772cdf0e10cSrcweir 		sal_Bool bOneNd = pStt->nNode == pEnd->nNode;
1773cdf0e10cSrcweir         const xub_StrLen nLen =
1774cdf0e10cSrcweir                 ( (bOneNd) ? pEnd->nContent.GetIndex() : pSrcNd->Len() )
1775cdf0e10cSrcweir                 - pStt->nContent.GetIndex();
1776cdf0e10cSrcweir 
1777cdf0e10cSrcweir 		if( !pEnd->nNode.GetNode().IsCntntNode() )
1778cdf0e10cSrcweir 		{
1779cdf0e10cSrcweir 			bOneNd = sal_True;
1780cdf0e10cSrcweir             sal_uLong nSttNdIdx = pStt->nNode.GetIndex() + 1;
1781cdf0e10cSrcweir             const sal_uLong nEndNdIdx = pEnd->nNode.GetIndex();
1782cdf0e10cSrcweir 			for( ; nSttNdIdx < nEndNdIdx; ++nSttNdIdx )
1783cdf0e10cSrcweir             {
1784cdf0e10cSrcweir 				if( (*this)[ nSttNdIdx ]->IsCntntNode() )
1785cdf0e10cSrcweir 				{
1786cdf0e10cSrcweir 					bOneNd = sal_False;
1787cdf0e10cSrcweir 					break;
1788cdf0e10cSrcweir 				}
1789cdf0e10cSrcweir             }
1790cdf0e10cSrcweir 		}
1791cdf0e10cSrcweir 
1792cdf0e10cSrcweir 		// das kopieren / setzen der Vorlagen darf erst nach
1793cdf0e10cSrcweir 		// dem Splitten erfolgen
1794cdf0e10cSrcweir 		if( !bOneNd && bSplitDestNd )
1795cdf0e10cSrcweir 		{
1796cdf0e10cSrcweir             if( !rPos.nContent.GetIndex() )
1797cdf0e10cSrcweir             {
1798cdf0e10cSrcweir                 bCopyCollFmt = sal_True;
1799cdf0e10cSrcweir             }
1800cdf0e10cSrcweir 			if( rNodes.IsDocNodes() )
1801cdf0e10cSrcweir 			{
1802cdf0e10cSrcweir                 SwDoc* const pInsDoc = pDestNd->GetDoc();
1803cdf0e10cSrcweir                 ::sw::UndoGuard const ug(pInsDoc->GetIDocumentUndoRedo());
1804cdf0e10cSrcweir 				pInsDoc->SplitNode( rPos, false );
1805cdf0e10cSrcweir             }
1806cdf0e10cSrcweir             else
1807cdf0e10cSrcweir             {
1808cdf0e10cSrcweir                 pDestNd->SplitCntntNode( rPos );
1809cdf0e10cSrcweir             }
1810cdf0e10cSrcweir 
1811cdf0e10cSrcweir 			if( rPos.nNode == aEndIdx )
1812cdf0e10cSrcweir             {
1813cdf0e10cSrcweir 				aEndIdx--;
1814cdf0e10cSrcweir             }
1815cdf0e10cSrcweir 			bSplitDestNd = sal_True;
1816cdf0e10cSrcweir 
1817cdf0e10cSrcweir 			pDestNd = rNodes[ rPos.nNode.GetIndex() - 1 ]->GetTxtNode();
1818cdf0e10cSrcweir 			if( nLen )
1819cdf0e10cSrcweir             {
1820cdf0e10cSrcweir                 pSrcNd->CutText( pDestNd, SwIndex( pDestNd, pDestNd->Len()),
1821cdf0e10cSrcweir                             pStt->nContent, nLen );
1822cdf0e10cSrcweir             }
1823cdf0e10cSrcweir         }
1824cdf0e10cSrcweir         else if ( nLen )
1825cdf0e10cSrcweir         {
1826cdf0e10cSrcweir             pSrcNd->CutText( pDestNd, rPos.nContent, pStt->nContent, nLen );
1827cdf0e10cSrcweir         }
1828cdf0e10cSrcweir 
1829cdf0e10cSrcweir 		if( bCopyCollFmt )
1830cdf0e10cSrcweir 		{
1831cdf0e10cSrcweir             SwDoc* const pInsDoc = pDestNd->GetDoc();
1832cdf0e10cSrcweir             ::sw::UndoGuard const undoGuard(pInsDoc->GetIDocumentUndoRedo());
1833cdf0e10cSrcweir 			pSrcNd->CopyCollFmt( *pDestNd );
1834cdf0e10cSrcweir             bCopyCollFmt = sal_False;
1835cdf0e10cSrcweir 		}
1836cdf0e10cSrcweir 
1837cdf0e10cSrcweir 		if( bOneNd )		// das wars schon
1838cdf0e10cSrcweir 		{
1839cdf0e10cSrcweir 			// der PaM wird korrigiert, denn falls ueber Nodegrenzen verschoben
1840cdf0e10cSrcweir 			// wurde, so stehen sie in unterschieden Nodes. Auch die Selektion
1841cdf0e10cSrcweir 			// wird aufgehoben !
1842cdf0e10cSrcweir 			pEnd->nContent = pStt->nContent;
1843cdf0e10cSrcweir 			rPam.DeleteMark();
1844cdf0e10cSrcweir             GetDoc()->GetDocShell()->Broadcast( SwFmtFldHint( 0,
1845cdf0e10cSrcweir                 rNodes.IsDocNodes() ? SWFMTFLD_INSERTED : SWFMTFLD_REMOVED ) );
1846cdf0e10cSrcweir 			return;
1847cdf0e10cSrcweir 		}
1848cdf0e10cSrcweir 
1849cdf0e10cSrcweir 		aSttIdx++;
1850cdf0e10cSrcweir 	}
1851cdf0e10cSrcweir 	else if( pDestNd )
1852cdf0e10cSrcweir 	{
1853cdf0e10cSrcweir 		if( rPos.nContent.GetIndex() )
1854cdf0e10cSrcweir 		{
1855cdf0e10cSrcweir 			if( rPos.nContent.GetIndex() == pDestNd->Len() )
1856cdf0e10cSrcweir             {
1857cdf0e10cSrcweir 				rPos.nNode++;
1858cdf0e10cSrcweir             }
1859cdf0e10cSrcweir 			else if( rPos.nContent.GetIndex() )
1860cdf0e10cSrcweir 			{
1861cdf0e10cSrcweir 				// falls im EndNode gesplittet wird, dann muss der EndIdx
1862cdf0e10cSrcweir 				// korrigiert werden !!
1863cdf0e10cSrcweir                 const bool bCorrEnd = aEndIdx == rPos.nNode;
1864cdf0e10cSrcweir 				// es wird kein Text an den TextNode angehaengt, also splitte ihn
1865cdf0e10cSrcweir 
1866cdf0e10cSrcweir 				if( rNodes.IsDocNodes() )
1867cdf0e10cSrcweir 				{
1868cdf0e10cSrcweir                     SwDoc* const pInsDoc = pDestNd->GetDoc();
1869cdf0e10cSrcweir                     ::sw::UndoGuard const ug(pInsDoc->GetIDocumentUndoRedo());
1870cdf0e10cSrcweir 					pInsDoc->SplitNode( rPos, false );
1871cdf0e10cSrcweir                 }
1872cdf0e10cSrcweir                 else
1873cdf0e10cSrcweir                 {
1874cdf0e10cSrcweir                     pDestNd->SplitCntntNode( rPos );
1875cdf0e10cSrcweir                 }
1876cdf0e10cSrcweir 
1877cdf0e10cSrcweir 				pDestNd = rPos.nNode.GetNode().GetTxtNode();
1878cdf0e10cSrcweir 
1879cdf0e10cSrcweir                 if ( bCorrEnd )
1880cdf0e10cSrcweir                 {
1881cdf0e10cSrcweir 					aEndIdx--;
1882cdf0e10cSrcweir                 }
1883cdf0e10cSrcweir 			}
1884cdf0e10cSrcweir 		}
1885cdf0e10cSrcweir 		// am Ende steht noch ein leerer Text Node herum.
1886cdf0e10cSrcweir 		bSplitDestNd = sal_True;
1887cdf0e10cSrcweir 	}
1888cdf0e10cSrcweir 
1889cdf0e10cSrcweir     SwTxtNode* const pEndSrcNd = aEndIdx.GetNode().GetTxtNode();
1890cdf0e10cSrcweir     if ( pEndSrcNd )
1891cdf0e10cSrcweir 	{
1892cdf0e10cSrcweir 		{
1893cdf0e10cSrcweir 			// am Bereichsende entsteht ein neuer TextNode
1894cdf0e10cSrcweir 			if( !bSplitDestNd )
1895cdf0e10cSrcweir 			{
1896cdf0e10cSrcweir 				if( rPos.nNode < rNodes.GetEndOfContent().GetIndex() )
1897cdf0e10cSrcweir                 {
1898cdf0e10cSrcweir 					rPos.nNode++;
1899cdf0e10cSrcweir                 }
1900cdf0e10cSrcweir 
1901cdf0e10cSrcweir                 pDestNd =
1902cdf0e10cSrcweir                     rNodes.MakeTxtNode( rPos.nNode, pEndSrcNd->GetTxtColl() );
1903cdf0e10cSrcweir 				rPos.nNode--;
1904cdf0e10cSrcweir 				rPos.nContent.Assign( pDestNd, 0 );
1905cdf0e10cSrcweir 			}
1906cdf0e10cSrcweir 			else
1907cdf0e10cSrcweir             {
1908cdf0e10cSrcweir                 pDestNd = rPos.nNode.GetNode().GetTxtNode();
1909cdf0e10cSrcweir             }
1910cdf0e10cSrcweir 
1911cdf0e10cSrcweir 			if( pDestNd && pEnd->nContent.GetIndex() )
1912cdf0e10cSrcweir 			{
1913cdf0e10cSrcweir 				// verschiebe jetzt noch den Inhalt in den neuen Node
1914cdf0e10cSrcweir                 SwIndex aIdx( pEndSrcNd, 0 );
1915cdf0e10cSrcweir                 pEndSrcNd->CutText( pDestNd, rPos.nContent, aIdx,
1916cdf0e10cSrcweir 								pEnd->nContent.GetIndex());
1917cdf0e10cSrcweir 			}
1918cdf0e10cSrcweir 
1919cdf0e10cSrcweir 			if( bCopyCollFmt )
1920cdf0e10cSrcweir 			{
1921cdf0e10cSrcweir                 SwDoc* const pInsDoc = pDestNd->GetDoc();
1922cdf0e10cSrcweir                 ::sw::UndoGuard const ug(pInsDoc->GetIDocumentUndoRedo());
1923cdf0e10cSrcweir                 pEndSrcNd->CopyCollFmt( *pDestNd );
1924cdf0e10cSrcweir             }
1925cdf0e10cSrcweir         }
1926cdf0e10cSrcweir     }
1927cdf0e10cSrcweir     else
1928cdf0e10cSrcweir     {
1929cdf0e10cSrcweir         if ( pSrcNd && aEndIdx.GetNode().IsCntntNode() )
1930cdf0e10cSrcweir         {
1931cdf0e10cSrcweir 			aEndIdx++;
1932cdf0e10cSrcweir         }
1933cdf0e10cSrcweir 		if( !bSplitDestNd )
1934cdf0e10cSrcweir 		{
1935cdf0e10cSrcweir 			rPos.nNode++;
1936cdf0e10cSrcweir 			rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), 0 );
1937cdf0e10cSrcweir 		}
1938cdf0e10cSrcweir 	}
1939cdf0e10cSrcweir 
1940cdf0e10cSrcweir 	if( aEndIdx != aSttIdx )
1941cdf0e10cSrcweir 	{
1942cdf0e10cSrcweir 		// verschiebe jetzt die Nodes in das NodesArary
1943cdf0e10cSrcweir         const sal_uLong nSttDiff = aSttIdx.GetIndex() - pStt->nNode.GetIndex();
1944cdf0e10cSrcweir 		SwNodeRange aRg( aSttIdx, aEndIdx );
1945cdf0e10cSrcweir 		_MoveNodes( aRg, rNodes, rPos.nNode );
1946cdf0e10cSrcweir 		// falls ins gleiche Nodes-Array verschoben wurde, stehen die
1947cdf0e10cSrcweir 		// Indizies jetzt auch an der neuen Position !!!!
1948cdf0e10cSrcweir 		// (also alles wieder umsetzen)
1949cdf0e10cSrcweir 		if( &rNodes == this )
1950cdf0e10cSrcweir         {
1951cdf0e10cSrcweir 			pStt->nNode = aRg.aEnd.GetIndex() - nSttDiff;
1952cdf0e10cSrcweir         }
1953cdf0e10cSrcweir 	}
1954cdf0e10cSrcweir 
1955cdf0e10cSrcweir 	// falls der Start-Node verschoben wurde, in dem der Cursor stand, so
1956cdf0e10cSrcweir 	// muss der Content im akt. Content angemeldet werden !!!
1957cdf0e10cSrcweir     if ( &pStt->nNode.GetNode() == &GetEndOfContent() )
1958cdf0e10cSrcweir     {
1959cdf0e10cSrcweir         const bool bSuccess = GoPrevious( &pStt->nNode );
1960cdf0e10cSrcweir         ASSERT( bSuccess, "Move() - no ContentNode here" );
1961cdf0e10cSrcweir         (void) bSuccess;
1962cdf0e10cSrcweir 	}
1963cdf0e10cSrcweir     pStt->nContent.Assign( pStt->nNode.GetNode().GetCntntNode(),
1964cdf0e10cSrcweir 							pStt->nContent.GetIndex() );
1965cdf0e10cSrcweir 	// der PaM wird korrigiert, denn falls ueber Nodegrenzen verschoben
1966cdf0e10cSrcweir 	// wurde, so stehen sie in unterschielichen Nodes. Auch die Selektion
1967cdf0e10cSrcweir 	// wird aufgehoben !
1968cdf0e10cSrcweir 	*pEnd = *pStt;
1969cdf0e10cSrcweir 	rPam.DeleteMark();
1970cdf0e10cSrcweir     GetDoc()->GetDocShell()->Broadcast( SwFmtFldHint( 0,
1971cdf0e10cSrcweir                 rNodes.IsDocNodes() ? SWFMTFLD_INSERTED : SWFMTFLD_REMOVED ) );
1972cdf0e10cSrcweir }
1973cdf0e10cSrcweir 
1974cdf0e10cSrcweir 
1975cdf0e10cSrcweir 
1976cdf0e10cSrcweir /*************************************************************************
1977cdf0e10cSrcweir |*
1978cdf0e10cSrcweir |*    SwNodes::_Copy()
1979cdf0e10cSrcweir |*
1980cdf0e10cSrcweir |*    Beschreibung
1981cdf0e10cSrcweir |*    Parameter         SwNodeRange&	zu kopierender Bereich
1982cdf0e10cSrcweir |*                      SwDoc&		in dieses Dokument
1983cdf0e10cSrcweir |*                      SwIndex&	auf diese Position im Nodes-Array
1984cdf0e10cSrcweir |*    Ersterstellung    JP 11.11.92
1985cdf0e10cSrcweir |*    Letzte Aenderung  JP 11.11.92
1986cdf0e10cSrcweir |*
1987cdf0e10cSrcweir *************************************************************************/
1988cdf0e10cSrcweir 
MaxLvl(sal_uInt8 nMin,sal_uInt8 nMax,short nNew)1989cdf0e10cSrcweir inline sal_uInt8 MaxLvl( sal_uInt8 nMin, sal_uInt8 nMax, short nNew )
1990cdf0e10cSrcweir {
1991cdf0e10cSrcweir 	return (sal_uInt8)(nNew < nMin ? nMin : nNew > nMax ? nMax : nNew);
1992cdf0e10cSrcweir }
1993cdf0e10cSrcweir 
_CopyNodes(const SwNodeRange & rRange,const SwNodeIndex & rIndex,sal_Bool bNewFrms,sal_Bool bTblInsDummyNode) const1994cdf0e10cSrcweir void SwNodes::_CopyNodes( const SwNodeRange& rRange,
1995cdf0e10cSrcweir 			const SwNodeIndex& rIndex, sal_Bool bNewFrms, sal_Bool bTblInsDummyNode ) const
1996cdf0e10cSrcweir {
1997cdf0e10cSrcweir 	SwDoc* pDoc = rIndex.GetNode().GetDoc();
1998cdf0e10cSrcweir 
1999cdf0e10cSrcweir 	SwNode * pAktNode;
2000cdf0e10cSrcweir 	if( rIndex == 0 ||
2001cdf0e10cSrcweir 		( (pAktNode = &rIndex.GetNode())->GetStartNode() &&
2002cdf0e10cSrcweir 		  !pAktNode->StartOfSectionIndex() ))
2003cdf0e10cSrcweir 		return;
2004cdf0e10cSrcweir 
2005cdf0e10cSrcweir 	SwNodeRange aRg( rRange );
2006cdf0e10cSrcweir 
2007cdf0e10cSrcweir 	// "einfache" StartNodes oder EndNodes ueberspringen
2008cdf0e10cSrcweir     while( ND_STARTNODE == (pAktNode = & aRg.aStart.GetNode())->GetNodeType()
2009cdf0e10cSrcweir 			|| ( pAktNode->IsEndNode() &&
2010cdf0e10cSrcweir 				!pAktNode->pStartOfSection->IsSectionNode() ) )
2011cdf0e10cSrcweir 		aRg.aStart++;
2012cdf0e10cSrcweir 
2013cdf0e10cSrcweir 	// falls aEnd-1 auf keinem ContentNode steht, dann suche den vorherigen
2014cdf0e10cSrcweir 	aRg.aEnd--;
2015cdf0e10cSrcweir     // #i107142#: if aEnd is start node of a special section, do nothing.
2016cdf0e10cSrcweir     // Otherwise this could lead to crash: going through all previous
2017cdf0e10cSrcweir     // special section nodes and then one before the first.
2018cdf0e10cSrcweir     if (aRg.aEnd.GetNode().StartOfSectionIndex() != 0)
2019cdf0e10cSrcweir     {
2020cdf0e10cSrcweir         while( ((pAktNode = & aRg.aEnd.GetNode())->GetStartNode() &&
2021cdf0e10cSrcweir                 !pAktNode->IsSectionNode() ) ||
2022cdf0e10cSrcweir                 ( pAktNode->IsEndNode() &&
2023cdf0e10cSrcweir                 ND_STARTNODE == pAktNode->pStartOfSection->GetNodeType()) )
2024cdf0e10cSrcweir         {
2025cdf0e10cSrcweir             aRg.aEnd--;
2026cdf0e10cSrcweir         }
2027cdf0e10cSrcweir     }
2028cdf0e10cSrcweir 	aRg.aEnd++;
2029cdf0e10cSrcweir 
2030cdf0e10cSrcweir 	// wird im selben Array's verschoben, dann ueberpruefe die Einfuegepos.
2031cdf0e10cSrcweir 	if( aRg.aStart >= aRg.aEnd )
2032cdf0e10cSrcweir 		return;
2033cdf0e10cSrcweir 
2034cdf0e10cSrcweir     // when inserting into the source range, nothing need to be done
2035cdf0e10cSrcweir     DBG_ASSERT( &aRg.aStart.GetNodes() == this,
2036cdf0e10cSrcweir                 "aRg should use thisnodes array" );
2037cdf0e10cSrcweir     DBG_ASSERT( &aRg.aStart.GetNodes() == &aRg.aEnd.GetNodes(),
2038cdf0e10cSrcweir                "Range across different nodes arrays? You deserve punishment!");
2039cdf0e10cSrcweir     if( &rIndex.GetNodes() == &aRg.aStart.GetNodes() &&
2040cdf0e10cSrcweir 		rIndex.GetIndex() >= aRg.aStart.GetIndex() &&
2041cdf0e10cSrcweir 		rIndex.GetIndex() < aRg.aEnd.GetIndex() )
2042cdf0e10cSrcweir 			return;
2043cdf0e10cSrcweir 
2044cdf0e10cSrcweir 	SwNodeIndex aInsPos( rIndex );
2045cdf0e10cSrcweir 	SwNodeIndex aOrigInsPos( rIndex, -1 );			// Originale Insert Pos
2046cdf0e10cSrcweir 	sal_uInt16 nLevel = 0;							// Level-Counter
2047cdf0e10cSrcweir 
2048cdf0e10cSrcweir 	for( sal_uLong nNodeCnt = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex();
2049cdf0e10cSrcweir 			nNodeCnt > 0; --nNodeCnt )
2050cdf0e10cSrcweir 	{
2051cdf0e10cSrcweir 		pAktNode = &aRg.aStart.GetNode();
2052cdf0e10cSrcweir 		switch( pAktNode->GetNodeType() )
2053cdf0e10cSrcweir 		{
2054cdf0e10cSrcweir 		case ND_TABLENODE:
2055cdf0e10cSrcweir 			// dann kopiere mal den TableNode
2056cdf0e10cSrcweir 			// Tabell in Fussnote kopieren ?
2057cdf0e10cSrcweir 			if( aInsPos < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
2058cdf0e10cSrcweir 					pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex()
2059cdf0e10cSrcweir 					< aInsPos.GetIndex() )
2060cdf0e10cSrcweir 			{
2061cdf0e10cSrcweir 				nNodeCnt -=
2062cdf0e10cSrcweir 					( pAktNode->EndOfSectionIndex() -
2063cdf0e10cSrcweir 						aRg.aStart.GetIndex() );
2064cdf0e10cSrcweir 
2065cdf0e10cSrcweir 				// dann alle Nodes der Tabelle in die akt. Zelle kopieren
2066cdf0e10cSrcweir 				// fuer den TabellenNode einen DummyNode einfuegen?
2067cdf0e10cSrcweir 				if( bTblInsDummyNode )
2068cdf0e10cSrcweir 					new SwNode( aInsPos, ND_SECTIONDUMMY );
2069cdf0e10cSrcweir 
2070cdf0e10cSrcweir 				for( aRg.aStart++; aRg.aStart.GetIndex() <
2071cdf0e10cSrcweir 					pAktNode->EndOfSectionIndex();
2072cdf0e10cSrcweir 					aRg.aStart++ )
2073cdf0e10cSrcweir 				{
2074cdf0e10cSrcweir 					// fuer den Box-StartNode einen DummyNode einfuegen?
2075cdf0e10cSrcweir 					if( bTblInsDummyNode )
2076cdf0e10cSrcweir 						new SwNode( aInsPos, ND_SECTIONDUMMY );
2077cdf0e10cSrcweir 
2078cdf0e10cSrcweir 					SwStartNode* pSttNd = aRg.aStart.GetNode().GetStartNode();
2079cdf0e10cSrcweir 					_CopyNodes( SwNodeRange( *pSttNd, + 1,
2080cdf0e10cSrcweir 											*pSttNd->EndOfSectionNode() ),
2081cdf0e10cSrcweir 								aInsPos, bNewFrms, sal_False );
2082cdf0e10cSrcweir 
2083cdf0e10cSrcweir 					// fuer den Box-EndNode einen DummyNode einfuegen?
2084cdf0e10cSrcweir 					if( bTblInsDummyNode )
2085cdf0e10cSrcweir 						new SwNode( aInsPos, ND_SECTIONDUMMY );
2086cdf0e10cSrcweir 					aRg.aStart = *pSttNd->EndOfSectionNode();
2087cdf0e10cSrcweir 				}
2088cdf0e10cSrcweir 				// fuer den TabellenEndNode einen DummyNode einfuegen?
2089cdf0e10cSrcweir 				if( bTblInsDummyNode )
2090cdf0e10cSrcweir 					new SwNode( aInsPos, ND_SECTIONDUMMY );
2091cdf0e10cSrcweir 				aRg.aStart = *pAktNode->EndOfSectionNode();
2092cdf0e10cSrcweir 			}
2093cdf0e10cSrcweir 			else
2094cdf0e10cSrcweir 			{
2095cdf0e10cSrcweir 				SwNodeIndex nStt( aInsPos, -1 );
2096cdf0e10cSrcweir 				SwTableNode* pTblNd = ((SwTableNode*)pAktNode)->
2097cdf0e10cSrcweir 										MakeCopy( pDoc, aInsPos );
2098cdf0e10cSrcweir 				nNodeCnt -= aInsPos.GetIndex() - nStt.GetIndex() -2;
2099cdf0e10cSrcweir 
2100cdf0e10cSrcweir 				aRg.aStart = pAktNode->EndOfSectionIndex();
2101cdf0e10cSrcweir 
2102cdf0e10cSrcweir 				if( bNewFrms && pTblNd )
2103cdf0e10cSrcweir 				{
2104cdf0e10cSrcweir 					nStt = aInsPos;
2105cdf0e10cSrcweir 					pTblNd->MakeFrms( &nStt );
2106cdf0e10cSrcweir 				}
2107cdf0e10cSrcweir 			}
2108cdf0e10cSrcweir 			break;
2109cdf0e10cSrcweir 
2110cdf0e10cSrcweir 		case ND_SECTIONNODE:			// SectionNode
2111cdf0e10cSrcweir             // If the end of the section is outside the copy range,
2112cdf0e10cSrcweir             // the section node will skipped, not copied!
2113cdf0e10cSrcweir             // If someone want to change this behaviour, he has to adjust the function
2114cdf0e10cSrcweir             // lcl_NonCopyCount(..) in ndcopy.cxx which relies on it.
2115cdf0e10cSrcweir             if( pAktNode->EndOfSectionIndex() < aRg.aEnd.GetIndex() )
2116cdf0e10cSrcweir 			{
2117cdf0e10cSrcweir 				// also der gesamte, lege einen neuen SectionNode an
2118cdf0e10cSrcweir 				SwNodeIndex nStt( aInsPos, -1 );
2119cdf0e10cSrcweir 				SwSectionNode* pSectNd = ((SwSectionNode*)pAktNode)->
2120cdf0e10cSrcweir 									MakeCopy( pDoc, aInsPos );
2121cdf0e10cSrcweir 
2122cdf0e10cSrcweir 				nNodeCnt -= aInsPos.GetIndex() - nStt.GetIndex() -2;
2123cdf0e10cSrcweir 				aRg.aStart = pAktNode->EndOfSectionIndex();
2124cdf0e10cSrcweir 
2125cdf0e10cSrcweir 				if( bNewFrms && pSectNd &&
2126cdf0e10cSrcweir 					!pSectNd->GetSection().IsHidden() )
2127cdf0e10cSrcweir 					pSectNd->MakeFrms( &nStt );
2128cdf0e10cSrcweir 			}
2129cdf0e10cSrcweir 			break;
2130cdf0e10cSrcweir 
2131cdf0e10cSrcweir 		case ND_STARTNODE:				// StartNode gefunden
2132cdf0e10cSrcweir 			{
2133cdf0e10cSrcweir 				SwStartNode* pTmp = new SwStartNode( aInsPos, ND_STARTNODE,
2134cdf0e10cSrcweir 							((SwStartNode*)pAktNode)->GetStartNodeType() );
2135cdf0e10cSrcweir 				new SwEndNode( aInsPos, *pTmp );
2136cdf0e10cSrcweir 				aInsPos--;
2137cdf0e10cSrcweir 				nLevel++;
2138cdf0e10cSrcweir 			}
2139cdf0e10cSrcweir 			break;
2140cdf0e10cSrcweir 
2141cdf0e10cSrcweir 		case ND_ENDNODE:
2142cdf0e10cSrcweir 			if( nLevel )						// vollstaendige Section
2143cdf0e10cSrcweir 			{
2144cdf0e10cSrcweir 				--nLevel;
2145cdf0e10cSrcweir 				aInsPos++;						// EndNode schon vorhanden
2146cdf0e10cSrcweir 			}
2147cdf0e10cSrcweir 			else if( !pAktNode->pStartOfSection->IsSectionNode() )
2148cdf0e10cSrcweir 			{
2149cdf0e10cSrcweir 				// erzeuge eine Section an der originalen InsertPosition
2150cdf0e10cSrcweir 				SwNodeRange aTmpRg( aOrigInsPos, 1, aInsPos );
2151cdf0e10cSrcweir 				pDoc->GetNodes().SectionDown( &aTmpRg,
2152cdf0e10cSrcweir 						pAktNode->pStartOfSection->GetStartNodeType() );
2153cdf0e10cSrcweir 			}
2154cdf0e10cSrcweir 			break;
2155cdf0e10cSrcweir 
2156cdf0e10cSrcweir 		case ND_TEXTNODE:
2157cdf0e10cSrcweir 		case ND_GRFNODE:
2158cdf0e10cSrcweir 		case ND_OLENODE:
2159cdf0e10cSrcweir 			{
2160cdf0e10cSrcweir 				SwCntntNode* pNew = ((SwCntntNode*)pAktNode)->MakeCopy(
2161cdf0e10cSrcweir 											pDoc, aInsPos );
2162cdf0e10cSrcweir 				if( !bNewFrms )	    	// dflt. werden die Frames immer angelegt
2163cdf0e10cSrcweir 					pNew->DelFrms();
2164cdf0e10cSrcweir 			}
2165cdf0e10cSrcweir 			break;
2166cdf0e10cSrcweir 
2167cdf0e10cSrcweir 		case ND_SECTIONDUMMY:
2168cdf0e10cSrcweir             if (GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(*this))
2169cdf0e10cSrcweir             {
2170cdf0e10cSrcweir 				// dann muss an der akt. InsPos auch ein SectionNode
2171cdf0e10cSrcweir 				// (Start/Ende) stehen; dann diesen ueberspringen.
2172cdf0e10cSrcweir 				// Andernfalls nicht weiter beachten.
2173cdf0e10cSrcweir                 SwNode *const pTmpNd = & aInsPos.GetNode();
2174cdf0e10cSrcweir 				if( pTmpNd->IsSectionNode() ||
2175cdf0e10cSrcweir                     pTmpNd->StartOfSectionNode()->IsSectionNode() )
2176cdf0e10cSrcweir 					aInsPos++;	// ueberspringen
2177cdf0e10cSrcweir 			}
2178cdf0e10cSrcweir 			else {
2179cdf0e10cSrcweir 				ASSERT( sal_False, "wie kommt diser Node ins Nodes-Array??" );
2180cdf0e10cSrcweir             }
2181cdf0e10cSrcweir 			break;
2182cdf0e10cSrcweir 
2183cdf0e10cSrcweir 		default:
2184cdf0e10cSrcweir 			ASSERT( sal_False, "weder Start-/End-/Content-Node, unbekannter Typ" );
2185cdf0e10cSrcweir 		}
2186cdf0e10cSrcweir 		aRg.aStart++;
2187cdf0e10cSrcweir 	}
2188cdf0e10cSrcweir 
2189cdf0e10cSrcweir 
2190cdf0e10cSrcweir #ifdef JP_DEBUG
2191cdf0e10cSrcweir 	{
2192cdf0e10cSrcweir extern Writer* GetDebugWriter(const String&);
2193cdf0e10cSrcweir 
2194cdf0e10cSrcweir 		Writer* pWriter = GetDebugWriter(aEmptyStr);
2195cdf0e10cSrcweir 		if( pWriter )
2196cdf0e10cSrcweir 		{
2197cdf0e10cSrcweir 			int nError;
2198cdf0e10cSrcweir 			SvFileStream aStrm( "c:\\$$copy.db", STREAM_WRITE );
2199cdf0e10cSrcweir 			SwWriter aWriter( aStrm, *pMyDoc );
2200cdf0e10cSrcweir 			aWriter.Write( &nError, pWriter );
2201cdf0e10cSrcweir 		}
2202cdf0e10cSrcweir 	}
2203cdf0e10cSrcweir #endif
2204cdf0e10cSrcweir }
2205cdf0e10cSrcweir 
_DelDummyNodes(const SwNodeRange & rRg)2206cdf0e10cSrcweir void SwNodes::_DelDummyNodes( const SwNodeRange& rRg )
2207cdf0e10cSrcweir {
2208cdf0e10cSrcweir 	SwNodeIndex aIdx( rRg.aStart );
2209cdf0e10cSrcweir 	while( aIdx.GetIndex() < rRg.aEnd.GetIndex() )
2210cdf0e10cSrcweir 	{
2211cdf0e10cSrcweir 		if( ND_SECTIONDUMMY == aIdx.GetNode().GetNodeType() )
2212cdf0e10cSrcweir 			RemoveNode( aIdx.GetIndex(), 1, sal_True );
2213cdf0e10cSrcweir 		else
2214cdf0e10cSrcweir 			aIdx++;
2215cdf0e10cSrcweir 	}
2216cdf0e10cSrcweir }
2217cdf0e10cSrcweir 
MakeEmptySection(const SwNodeIndex & rIdx,SwStartNodeType eSttNdTyp)2218cdf0e10cSrcweir SwStartNode* SwNodes::MakeEmptySection( const SwNodeIndex& rIdx,
2219cdf0e10cSrcweir 										SwStartNodeType eSttNdTyp )
2220cdf0e10cSrcweir {
2221cdf0e10cSrcweir 	SwStartNode* pSttNd = new SwStartNode( rIdx, ND_STARTNODE, eSttNdTyp );
2222cdf0e10cSrcweir 	new SwEndNode( rIdx, *pSttNd );
2223cdf0e10cSrcweir 	return pSttNd;
2224cdf0e10cSrcweir }
2225cdf0e10cSrcweir 
2226cdf0e10cSrcweir 
MakeTextSection(const SwNodeIndex & rWhere,SwStartNodeType eSttNdTyp,SwTxtFmtColl * pColl,SwAttrSet * pAutoAttr)2227cdf0e10cSrcweir SwStartNode* SwNodes::MakeTextSection( const SwNodeIndex & rWhere,
2228cdf0e10cSrcweir 										SwStartNodeType eSttNdTyp,
2229cdf0e10cSrcweir 										SwTxtFmtColl *pColl,
2230cdf0e10cSrcweir 										SwAttrSet* pAutoAttr )
2231cdf0e10cSrcweir {
2232cdf0e10cSrcweir 	SwStartNode* pSttNd = new SwStartNode( rWhere, ND_STARTNODE, eSttNdTyp );
2233cdf0e10cSrcweir 	new SwEndNode( rWhere, *pSttNd );
2234cdf0e10cSrcweir 	MakeTxtNode( SwNodeIndex( rWhere, - 1 ), pColl, pAutoAttr );
2235cdf0e10cSrcweir 	return pSttNd;
2236cdf0e10cSrcweir }
2237cdf0e10cSrcweir 
2238cdf0e10cSrcweir 	// zum naechsten Content-Node, der nicht geschuetzt oder versteckt ist
2239cdf0e10cSrcweir 	// (beides auf sal_False ==> GoNext/GoPrevious!!!)
GoNextSection(SwNodeIndex * pIdx,int bSkipHidden,int bSkipProtect) const2240cdf0e10cSrcweir SwCntntNode* SwNodes::GoNextSection( SwNodeIndex * pIdx,
2241cdf0e10cSrcweir 							int bSkipHidden, int bSkipProtect ) const
2242cdf0e10cSrcweir {
2243cdf0e10cSrcweir 	int bFirst = sal_True;
2244cdf0e10cSrcweir 	SwNodeIndex aTmp( *pIdx );
2245cdf0e10cSrcweir 	const SwNode* pNd;
2246cdf0e10cSrcweir 	while( aTmp < Count() - 1 )
2247cdf0e10cSrcweir 	{
2248cdf0e10cSrcweir         pNd = & aTmp.GetNode();
2249cdf0e10cSrcweir         if (ND_SECTIONNODE == pNd->GetNodeType())
2250cdf0e10cSrcweir 		{
2251cdf0e10cSrcweir 			const SwSection& rSect = ((SwSectionNode*)pNd)->GetSection();
2252cdf0e10cSrcweir 			if( (bSkipHidden && rSect.IsHiddenFlag()) ||
2253cdf0e10cSrcweir 				(bSkipProtect && rSect.IsProtectFlag()) )
2254cdf0e10cSrcweir 				// dann diese Section ueberspringen
2255cdf0e10cSrcweir 				aTmp = *pNd->EndOfSectionNode();
2256cdf0e10cSrcweir 			bFirst = sal_False;
2257cdf0e10cSrcweir 		}
2258cdf0e10cSrcweir 		else if( bFirst )
2259cdf0e10cSrcweir 		{
2260cdf0e10cSrcweir 			bFirst = sal_False;
2261cdf0e10cSrcweir 			if( pNd->pStartOfSection->IsSectionNode() )
2262cdf0e10cSrcweir 			{
2263cdf0e10cSrcweir 				const SwSection& rSect = ((SwSectionNode*)pNd->
2264cdf0e10cSrcweir 								pStartOfSection)->GetSection();
2265cdf0e10cSrcweir 				if( (bSkipHidden && rSect.IsHiddenFlag()) ||
2266cdf0e10cSrcweir 					(bSkipProtect && rSect.IsProtectFlag()) )
2267cdf0e10cSrcweir 					// dann diese Section ueberspringen
2268cdf0e10cSrcweir 					aTmp = *pNd->EndOfSectionNode();
2269cdf0e10cSrcweir 			}
2270cdf0e10cSrcweir 		}
2271cdf0e10cSrcweir 		else if( ND_CONTENTNODE & pNd->GetNodeType() )
2272cdf0e10cSrcweir 		{
2273cdf0e10cSrcweir 			const SwSectionNode* pSectNd;
2274cdf0e10cSrcweir 			if( ( bSkipHidden || bSkipProtect ) &&
2275cdf0e10cSrcweir 				0 != (pSectNd = pNd->FindSectionNode() ) &&
2276cdf0e10cSrcweir 				( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) ||
2277cdf0e10cSrcweir 				  ( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) )
2278cdf0e10cSrcweir 			{
2279cdf0e10cSrcweir 				aTmp = *pSectNd->EndOfSectionNode();
2280cdf0e10cSrcweir 			}
2281cdf0e10cSrcweir 			else
2282cdf0e10cSrcweir 			{
2283cdf0e10cSrcweir 				(*pIdx) = aTmp;
2284cdf0e10cSrcweir 				return (SwCntntNode*)pNd;
2285cdf0e10cSrcweir 			}
2286cdf0e10cSrcweir 		}
2287cdf0e10cSrcweir 		aTmp++;
2288cdf0e10cSrcweir 		bFirst = sal_False;
2289cdf0e10cSrcweir 	}
2290cdf0e10cSrcweir 	return 0;
2291cdf0e10cSrcweir }
2292cdf0e10cSrcweir 
GoPrevSection(SwNodeIndex * pIdx,int bSkipHidden,int bSkipProtect) const2293cdf0e10cSrcweir SwCntntNode* SwNodes::GoPrevSection( SwNodeIndex * pIdx,
2294cdf0e10cSrcweir 							int bSkipHidden, int bSkipProtect ) const
2295cdf0e10cSrcweir {
2296cdf0e10cSrcweir 	int bFirst = sal_True;
2297cdf0e10cSrcweir 	SwNodeIndex aTmp( *pIdx );
2298cdf0e10cSrcweir 	const SwNode* pNd;
2299cdf0e10cSrcweir 	while( aTmp > 0 )
2300cdf0e10cSrcweir 	{
2301cdf0e10cSrcweir         pNd = & aTmp.GetNode();
2302cdf0e10cSrcweir         if (ND_ENDNODE == pNd->GetNodeType())
2303cdf0e10cSrcweir 		{
2304cdf0e10cSrcweir 			if( pNd->pStartOfSection->IsSectionNode() )
2305cdf0e10cSrcweir 			{
2306cdf0e10cSrcweir 				const SwSection& rSect = ((SwSectionNode*)pNd->
2307cdf0e10cSrcweir 											pStartOfSection)->GetSection();
2308cdf0e10cSrcweir 				if( (bSkipHidden && rSect.IsHiddenFlag()) ||
2309cdf0e10cSrcweir 					(bSkipProtect && rSect.IsProtectFlag()) )
2310cdf0e10cSrcweir 					// dann diese Section ueberspringen
2311cdf0e10cSrcweir 					aTmp = *pNd->StartOfSectionNode();
2312cdf0e10cSrcweir 			}
2313cdf0e10cSrcweir 			bFirst = sal_False;
2314cdf0e10cSrcweir 		}
2315cdf0e10cSrcweir 		else if( bFirst )
2316cdf0e10cSrcweir 		{
2317cdf0e10cSrcweir 			bFirst = sal_False;
2318cdf0e10cSrcweir 			if( pNd->pStartOfSection->IsSectionNode() )
2319cdf0e10cSrcweir 			{
2320cdf0e10cSrcweir 				const SwSection& rSect = ((SwSectionNode*)pNd->
2321cdf0e10cSrcweir 								pStartOfSection)->GetSection();
2322cdf0e10cSrcweir 				if( (bSkipHidden && rSect.IsHiddenFlag()) ||
2323cdf0e10cSrcweir 					(bSkipProtect && rSect.IsProtectFlag()) )
2324cdf0e10cSrcweir 					// dann diese Section ueberspringen
2325cdf0e10cSrcweir 					aTmp = *pNd->StartOfSectionNode();
2326cdf0e10cSrcweir 			}
2327cdf0e10cSrcweir 		}
2328cdf0e10cSrcweir 		else if( ND_CONTENTNODE & pNd->GetNodeType() )
2329cdf0e10cSrcweir 		{
2330cdf0e10cSrcweir 			const SwSectionNode* pSectNd;
2331cdf0e10cSrcweir 			if( ( bSkipHidden || bSkipProtect ) &&
2332cdf0e10cSrcweir 				0 != (pSectNd = pNd->FindSectionNode() ) &&
2333cdf0e10cSrcweir 				( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) ||
2334cdf0e10cSrcweir 				  ( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) )
2335cdf0e10cSrcweir 			{
2336cdf0e10cSrcweir 				aTmp = *pSectNd;
2337cdf0e10cSrcweir 			}
2338cdf0e10cSrcweir 			else
2339cdf0e10cSrcweir 			{
2340cdf0e10cSrcweir 				(*pIdx) = aTmp;
2341cdf0e10cSrcweir 				return (SwCntntNode*)pNd;
2342cdf0e10cSrcweir 			}
2343cdf0e10cSrcweir 		}
2344cdf0e10cSrcweir 		aTmp--;
2345cdf0e10cSrcweir 	}
2346cdf0e10cSrcweir 	return 0;
2347cdf0e10cSrcweir }
2348cdf0e10cSrcweir 
2349cdf0e10cSrcweir 
2350cdf0e10cSrcweir 	// suche den vorhergehenden [/nachfolgenden ] ContentNode oder
2351cdf0e10cSrcweir 	// TabellenNode mit Frames. Wird kein Ende angeben, dann wird mit
2352cdf0e10cSrcweir 	// dem FrameIndex begonnen; ansonsten, wird mit dem vor rFrmIdx und
2353cdf0e10cSrcweir 	// dem hintern pEnd die Suche gestartet. Sollte kein gueltiger Node
2354cdf0e10cSrcweir 	// gefunden werden, wird 0 returnt. rFrmIdx zeigt auf dem Node mit
2355cdf0e10cSrcweir 	// Frames
FindPrvNxtFrmNode(SwNodeIndex & rFrmIdx,const SwNode * pEnd) const2356cdf0e10cSrcweir SwNode* SwNodes::FindPrvNxtFrmNode( SwNodeIndex& rFrmIdx,
2357cdf0e10cSrcweir 									const SwNode* pEnd ) const
2358cdf0e10cSrcweir {
2359cdf0e10cSrcweir 	SwNode* pFrmNd = 0;
2360cdf0e10cSrcweir 
2361cdf0e10cSrcweir 	// habe wir gar kein Layout, vergiss es
2362cdf0e10cSrcweir 	if( GetDoc()->GetCurrentViewShell() )	//swmod 071108//swmod 071225
2363cdf0e10cSrcweir 	{
2364cdf0e10cSrcweir 		SwNode* pSttNd = &rFrmIdx.GetNode();
2365cdf0e10cSrcweir 
2366cdf0e10cSrcweir 		// wird in eine versteckte Section verschoben ??
2367cdf0e10cSrcweir 		SwSectionNode* pSectNd = pSttNd->IsSectionNode()
2368cdf0e10cSrcweir                     ? pSttNd->StartOfSectionNode()->FindSectionNode()
2369cdf0e10cSrcweir 					: pSttNd->FindSectionNode();
2370cdf0e10cSrcweir 		if( !( pSectNd && pSectNd->GetSection().CalcHiddenFlag()/*IsHiddenFlag()*/ ) )
2371cdf0e10cSrcweir 		{
2372cdf0e10cSrcweir             // #130650# in a table in table situation we have to assure that we don't leave the
2373cdf0e10cSrcweir             // outer table cell when the inner table is looking for a PrvNxt...
2374cdf0e10cSrcweir             SwTableNode* pTableNd = pSttNd->IsTableNode()
2375cdf0e10cSrcweir 					? pSttNd->StartOfSectionNode()->FindTableNode()
2376cdf0e10cSrcweir 					: pSttNd->FindTableNode();
2377cdf0e10cSrcweir 			SwNodeIndex aIdx( rFrmIdx );
2378cdf0e10cSrcweir 			SwNode* pNd;
2379cdf0e10cSrcweir 			if( pEnd )
2380cdf0e10cSrcweir 			{
2381cdf0e10cSrcweir 				aIdx--;
2382cdf0e10cSrcweir 				pNd = &aIdx.GetNode();
2383cdf0e10cSrcweir 			}
2384cdf0e10cSrcweir 			else
2385cdf0e10cSrcweir 				pNd = pSttNd;
2386cdf0e10cSrcweir 
2387cdf0e10cSrcweir 			if( ( pFrmNd = pNd )->IsCntntNode() )
2388cdf0e10cSrcweir 				rFrmIdx = aIdx;
2389cdf0e10cSrcweir 
2390cdf0e10cSrcweir 				// suche nach vorne/hinten nach einem Content Node
2391cdf0e10cSrcweir 			else if( 0 != ( pFrmNd = GoPrevSection( &aIdx, sal_True, sal_False )) &&
2392cdf0e10cSrcweir 					::CheckNodesRange( aIdx, rFrmIdx, sal_True ) &&
2393cdf0e10cSrcweir 					// nach vorne nie aus der Tabelle hinaus!
2394cdf0e10cSrcweir 					pFrmNd->FindTableNode() == pTableNd &&
2395cdf0e10cSrcweir 					// Bug 37652: nach hinten nie aus der Tabellenzelle hinaus!
2396cdf0e10cSrcweir 					(!pFrmNd->FindTableNode() || pFrmNd->FindTableBoxStartNode()
2397cdf0e10cSrcweir 						== pSttNd->FindTableBoxStartNode() ) &&
2398cdf0e10cSrcweir 					 (!pSectNd || pSttNd->IsSectionNode() ||
2399cdf0e10cSrcweir 					  pSectNd->GetIndex() < pFrmNd->GetIndex())
2400cdf0e10cSrcweir 					)
2401cdf0e10cSrcweir 			{
2402cdf0e10cSrcweir 				rFrmIdx = aIdx;
2403cdf0e10cSrcweir 			}
2404cdf0e10cSrcweir 			else
2405cdf0e10cSrcweir 			{
2406cdf0e10cSrcweir 				if( pEnd )
2407cdf0e10cSrcweir 					aIdx = pEnd->GetIndex() + 1;
2408cdf0e10cSrcweir 				else
2409cdf0e10cSrcweir 					aIdx = rFrmIdx;
2410cdf0e10cSrcweir 
2411cdf0e10cSrcweir 				// JP 19.09.93: aber nie die Section dafuer verlassen !!
2412cdf0e10cSrcweir 				if( ( pEnd && ( pFrmNd = &aIdx.GetNode())->IsCntntNode() ) ||
2413cdf0e10cSrcweir 					( 0 != ( pFrmNd = GoNextSection( &aIdx, sal_True, sal_False )) &&
2414cdf0e10cSrcweir 					::CheckNodesRange( aIdx, rFrmIdx, sal_True ) &&
2415cdf0e10cSrcweir 					( pFrmNd->FindTableNode() == pTableNd &&
2416cdf0e10cSrcweir 						// Bug 37652: nach hinten nie aus der Tabellenzelle hinaus!
2417cdf0e10cSrcweir 						(!pFrmNd->FindTableNode() || pFrmNd->FindTableBoxStartNode()
2418cdf0e10cSrcweir 						== pSttNd->FindTableBoxStartNode() ) ) &&
2419cdf0e10cSrcweir 					 (!pSectNd || pSttNd->IsSectionNode() ||
2420cdf0e10cSrcweir 					  pSectNd->EndOfSectionIndex() > pFrmNd->GetIndex())
2421cdf0e10cSrcweir 					))
2422cdf0e10cSrcweir 				{
2423cdf0e10cSrcweir 					//JP 18.02.99: Undo von Merge einer Tabelle mit der
2424cdf0e10cSrcweir 					// der vorherigen, wenn dahinter auch noch eine steht
2425cdf0e10cSrcweir 					// falls aber der Node in einer Tabelle steht, muss
2426cdf0e10cSrcweir 					// natuerlich dieser returnt werden, wenn der SttNode eine
2427cdf0e10cSrcweir 					// Section oder Tabelle ist!
2428cdf0e10cSrcweir 					SwTableNode* pTblNd;
2429cdf0e10cSrcweir 					if( pSttNd->IsTableNode() &&
2430cdf0e10cSrcweir 						0 != ( pTblNd = pFrmNd->FindTableNode() ) &&
2431cdf0e10cSrcweir                         // TABLE IN TABLE:
2432cdf0e10cSrcweir                         pTblNd != pSttNd->StartOfSectionNode()->FindTableNode() )
2433cdf0e10cSrcweir 					{
2434cdf0e10cSrcweir 						pFrmNd = pTblNd;
2435cdf0e10cSrcweir 						rFrmIdx = *pFrmNd;
2436cdf0e10cSrcweir 					}
2437cdf0e10cSrcweir 					else
2438cdf0e10cSrcweir 						rFrmIdx = aIdx;
2439cdf0e10cSrcweir 				}
2440cdf0e10cSrcweir                 else if( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsTableNode() )
2441cdf0e10cSrcweir 				{
2442cdf0e10cSrcweir                     pFrmNd = pNd->StartOfSectionNode();
2443cdf0e10cSrcweir 					rFrmIdx = *pFrmNd;
2444cdf0e10cSrcweir 				}
2445cdf0e10cSrcweir 				else
2446cdf0e10cSrcweir 				{
2447cdf0e10cSrcweir 					if( pEnd )
2448cdf0e10cSrcweir 						aIdx = pEnd->GetIndex() + 1;
2449cdf0e10cSrcweir 					else
2450cdf0e10cSrcweir 						aIdx = rFrmIdx.GetIndex() + 1;
2451cdf0e10cSrcweir 
2452cdf0e10cSrcweir 					if( (pFrmNd = &aIdx.GetNode())->IsTableNode() )
2453cdf0e10cSrcweir 						rFrmIdx = aIdx;
2454cdf0e10cSrcweir 					else
2455cdf0e10cSrcweir 					{
2456cdf0e10cSrcweir 						pFrmNd = 0;
2457cdf0e10cSrcweir 
2458cdf0e10cSrcweir 						// is there some sectionnodes before a tablenode?
2459cdf0e10cSrcweir 						while( aIdx.GetNode().IsSectionNode() )
2460cdf0e10cSrcweir 						{
2461cdf0e10cSrcweir 							const SwSection& rSect = aIdx.GetNode().
2462cdf0e10cSrcweir 								GetSectionNode()->GetSection();
2463cdf0e10cSrcweir 							if( rSect.IsHiddenFlag() )
2464cdf0e10cSrcweir 								aIdx = aIdx.GetNode().EndOfSectionIndex()+1;
2465cdf0e10cSrcweir 							else
2466cdf0e10cSrcweir 								aIdx++;
2467cdf0e10cSrcweir 						}
2468cdf0e10cSrcweir 						if( aIdx.GetNode().IsTableNode() )
2469cdf0e10cSrcweir 						{
2470cdf0e10cSrcweir 							rFrmIdx = aIdx;
2471cdf0e10cSrcweir 							pFrmNd = &aIdx.GetNode();
2472cdf0e10cSrcweir 						}
2473cdf0e10cSrcweir 					}
2474cdf0e10cSrcweir 				}
2475cdf0e10cSrcweir 			}
2476cdf0e10cSrcweir 		}
2477cdf0e10cSrcweir 	}
2478cdf0e10cSrcweir 	return pFrmNd;
2479cdf0e10cSrcweir }
2480cdf0e10cSrcweir 
ForEach(const SwNodeIndex & rStart,const SwNodeIndex & rEnd,FnForEach_SwNodes fnForEach,void * pArgs)2481cdf0e10cSrcweir void SwNodes::ForEach( const SwNodeIndex& rStart, const SwNodeIndex& rEnd,
2482cdf0e10cSrcweir 					FnForEach_SwNodes fnForEach, void* pArgs )
2483cdf0e10cSrcweir {
2484cdf0e10cSrcweir 	BigPtrArray::ForEach( rStart.GetIndex(), rEnd.GetIndex(),
2485cdf0e10cSrcweir 							(FnForEach) fnForEach, pArgs );
2486cdf0e10cSrcweir }
2487cdf0e10cSrcweir 
2488cdf0e10cSrcweir struct _TempBigPtrEntry : public BigPtrEntry
2489cdf0e10cSrcweir {
_TempBigPtrEntry_TempBigPtrEntry2490cdf0e10cSrcweir 	_TempBigPtrEntry() {}
2491cdf0e10cSrcweir };
2492cdf0e10cSrcweir 
2493cdf0e10cSrcweir 
RemoveNode(sal_uLong nDelPos,sal_uLong nSz,sal_Bool bDel)2494cdf0e10cSrcweir void SwNodes::RemoveNode( sal_uLong nDelPos, sal_uLong nSz, sal_Bool bDel )
2495cdf0e10cSrcweir {
2496cdf0e10cSrcweir 	sal_uLong nEnd = nDelPos + nSz;
2497cdf0e10cSrcweir 	SwNode* pNew = (*this)[ nEnd ];
2498cdf0e10cSrcweir 
2499cdf0e10cSrcweir 	if( pRoot )
2500cdf0e10cSrcweir 	{
2501cdf0e10cSrcweir 		SwNodeIndex *p = pRoot;
2502cdf0e10cSrcweir 		while( p )
2503cdf0e10cSrcweir 		{
2504cdf0e10cSrcweir 			sal_uLong nIdx = p->GetIndex();
2505cdf0e10cSrcweir 			SwNodeIndex* pNext = p->pNext;
2506cdf0e10cSrcweir 			if( nDelPos <= nIdx && nIdx < nEnd )
2507cdf0e10cSrcweir 				(*p) = *pNew;
2508cdf0e10cSrcweir 
2509cdf0e10cSrcweir 			p = pNext;
2510cdf0e10cSrcweir 		}
2511cdf0e10cSrcweir 
2512cdf0e10cSrcweir 		p = pRoot->pPrev;
2513cdf0e10cSrcweir 		while( p )
2514cdf0e10cSrcweir 		{
2515cdf0e10cSrcweir 			sal_uLong nIdx = p->GetIndex();
2516cdf0e10cSrcweir 			SwNodeIndex* pPrev = p->pPrev;
2517cdf0e10cSrcweir 			if( nDelPos <= nIdx && nIdx < nEnd )
2518cdf0e10cSrcweir 				(*p) = *pNew;
2519cdf0e10cSrcweir 
2520cdf0e10cSrcweir 			p = pPrev;
2521cdf0e10cSrcweir 		}
2522cdf0e10cSrcweir 	}
2523cdf0e10cSrcweir 
2524cdf0e10cSrcweir     {
2525cdf0e10cSrcweir         for (sal_uLong nCnt = 0; nCnt < nSz; nCnt++)
2526cdf0e10cSrcweir         {
2527cdf0e10cSrcweir             SwTxtNode * pTxtNd = ((*this)[ nDelPos + nCnt ])->GetTxtNode();
2528cdf0e10cSrcweir 
2529cdf0e10cSrcweir             if (pTxtNd)
2530cdf0e10cSrcweir             {
2531cdf0e10cSrcweir                 // --> OD 2008-03-13 #refactorlists#
2532cdf0e10cSrcweir //                pTxtNd->UnregisterNumber();
2533cdf0e10cSrcweir                 pTxtNd->RemoveFromList();
2534cdf0e10cSrcweir                 // <--
2535cdf0e10cSrcweir             }
2536cdf0e10cSrcweir         }
2537cdf0e10cSrcweir     }
2538cdf0e10cSrcweir 
2539cdf0e10cSrcweir 	if( bDel )
2540cdf0e10cSrcweir 	{
2541cdf0e10cSrcweir 		sal_uLong nCnt = nSz;
2542cdf0e10cSrcweir 		SwNode *pDel = (*this)[ nDelPos+nCnt-1 ], *pPrev = (*this)[ nDelPos+nCnt-2 ];
2543cdf0e10cSrcweir 
2544cdf0e10cSrcweir // temp. Object setzen
2545cdf0e10cSrcweir 		//JP 24.08.98: muessten eigentlich einzeln removed werden, weil
2546cdf0e10cSrcweir 		//		das Remove auch rekursiv gerufen werden kann, z.B. bei
2547cdf0e10cSrcweir 		//		zeichengebundenen Rahmen. Da aber dabei viel zu viel
2548cdf0e10cSrcweir 		//		ablaueft, wird hier ein temp. Objekt eingefuegt, das
2549cdf0e10cSrcweir 		//		dann mit dem Remove wieder entfernt wird.
2550cdf0e10cSrcweir 		// siehe Bug 55406
2551cdf0e10cSrcweir 		_TempBigPtrEntry aTempEntry;
2552cdf0e10cSrcweir 		BigPtrEntry* pTempEntry = &aTempEntry;
2553cdf0e10cSrcweir 
2554cdf0e10cSrcweir 		while( nCnt-- )
2555cdf0e10cSrcweir 		{
2556cdf0e10cSrcweir 			delete pDel;
2557cdf0e10cSrcweir 			pDel = pPrev;
2558cdf0e10cSrcweir 			sal_uLong nPrevNdIdx = pPrev->GetIndex();
2559cdf0e10cSrcweir 			BigPtrArray::Replace( nPrevNdIdx+1, pTempEntry );
2560cdf0e10cSrcweir 			if( nCnt )
2561cdf0e10cSrcweir 				pPrev = (*this)[ nPrevNdIdx  - 1 ];
2562cdf0e10cSrcweir 		}
2563cdf0e10cSrcweir 		nDelPos = pDel->GetIndex() + 1;
2564cdf0e10cSrcweir 	}
2565cdf0e10cSrcweir 
2566cdf0e10cSrcweir 	BigPtrArray::Remove( nDelPos, nSz );
2567cdf0e10cSrcweir }
2568cdf0e10cSrcweir 
RegisterIndex(SwNodeIndex & rIdx)2569cdf0e10cSrcweir void SwNodes::RegisterIndex( SwNodeIndex& rIdx )
2570cdf0e10cSrcweir {
2571cdf0e10cSrcweir 	if( !pRoot )		// noch keine Root gesetzt?
2572cdf0e10cSrcweir 	{
2573cdf0e10cSrcweir 		pRoot = &rIdx;
2574cdf0e10cSrcweir 		pRoot->pPrev = 0;
2575cdf0e10cSrcweir 		pRoot->pNext = 0;
2576cdf0e10cSrcweir 	}
2577cdf0e10cSrcweir 	else
2578cdf0e10cSrcweir 	{
2579cdf0e10cSrcweir 		// immer hinter die Root haengen
2580cdf0e10cSrcweir 		rIdx.pNext = pRoot->pNext;
2581cdf0e10cSrcweir 		pRoot->pNext = &rIdx;
2582cdf0e10cSrcweir 		rIdx.pPrev = pRoot;
2583cdf0e10cSrcweir 		if( rIdx.pNext )
2584cdf0e10cSrcweir 			rIdx.pNext->pPrev = &rIdx;
2585cdf0e10cSrcweir 	}
2586cdf0e10cSrcweir }
2587cdf0e10cSrcweir 
DeRegisterIndex(SwNodeIndex & rIdx)2588cdf0e10cSrcweir void SwNodes::DeRegisterIndex( SwNodeIndex& rIdx )
2589cdf0e10cSrcweir {
2590cdf0e10cSrcweir 	SwNodeIndex* pN = rIdx.pNext;
2591cdf0e10cSrcweir 	SwNodeIndex* pP = rIdx.pPrev;
2592cdf0e10cSrcweir 
2593cdf0e10cSrcweir 	if( pRoot == &rIdx )
2594cdf0e10cSrcweir 		pRoot = pP ? pP : pN;
2595cdf0e10cSrcweir 
2596cdf0e10cSrcweir 	if( pP )
2597cdf0e10cSrcweir 		pP->pNext = pN;
2598cdf0e10cSrcweir 	if( pN )
2599cdf0e10cSrcweir 		pN->pPrev = pP;
2600cdf0e10cSrcweir 
2601cdf0e10cSrcweir 	rIdx.pNext = 0;
2602cdf0e10cSrcweir 	rIdx.pPrev = 0;
2603cdf0e10cSrcweir }
2604cdf0e10cSrcweir 
InsertNode(const SwNodePtr pNode,const SwNodeIndex & rPos)2605cdf0e10cSrcweir void SwNodes::InsertNode( const SwNodePtr pNode,
2606cdf0e10cSrcweir                           const SwNodeIndex& rPos )
2607cdf0e10cSrcweir {
2608cdf0e10cSrcweir 	const ElementPtr pIns = pNode;
2609cdf0e10cSrcweir     BigPtrArray::Insert( pIns, rPos.GetIndex() );
2610cdf0e10cSrcweir }
2611cdf0e10cSrcweir 
InsertNode(const SwNodePtr pNode,sal_uLong nPos)2612cdf0e10cSrcweir void SwNodes::InsertNode( const SwNodePtr pNode,
2613cdf0e10cSrcweir                           sal_uLong nPos )
2614cdf0e10cSrcweir {
2615cdf0e10cSrcweir 	const ElementPtr pIns = pNode;
2616cdf0e10cSrcweir     BigPtrArray::Insert( pIns, nPos );
2617cdf0e10cSrcweir }
2618cdf0e10cSrcweir 
2619cdf0e10cSrcweir // ->#112139#
DocumentSectionStartNode(SwNode * pNode) const2620cdf0e10cSrcweir SwNode * SwNodes::DocumentSectionStartNode(SwNode * pNode) const
2621cdf0e10cSrcweir {
2622cdf0e10cSrcweir     if (NULL != pNode)
2623cdf0e10cSrcweir     {
2624cdf0e10cSrcweir         SwNodeIndex aIdx(*pNode);
2625cdf0e10cSrcweir 
2626cdf0e10cSrcweir         if (aIdx <= (*this)[0]->EndOfSectionIndex())
2627cdf0e10cSrcweir             pNode = (*this)[0];
2628cdf0e10cSrcweir         else
2629cdf0e10cSrcweir         {
2630cdf0e10cSrcweir             while ((*this)[0] != pNode->StartOfSectionNode())
2631cdf0e10cSrcweir                 pNode = pNode->StartOfSectionNode();
2632cdf0e10cSrcweir         }
2633cdf0e10cSrcweir     }
2634cdf0e10cSrcweir 
2635cdf0e10cSrcweir     return pNode;
2636cdf0e10cSrcweir }
2637cdf0e10cSrcweir 
DocumentSectionEndNode(SwNode * pNode) const2638cdf0e10cSrcweir SwNode * SwNodes::DocumentSectionEndNode(SwNode * pNode) const
2639cdf0e10cSrcweir {
2640cdf0e10cSrcweir     return DocumentSectionStartNode(pNode)->EndOfSectionNode();
2641cdf0e10cSrcweir }
2642cdf0e10cSrcweir 
2643cdf0e10cSrcweir //SwNode * SwNodes::operator[](int n) const
2644cdf0e10cSrcweir //{
2645cdf0e10cSrcweir //    return operator[]((sal_uLong) n);
2646cdf0e10cSrcweir //}
2647cdf0e10cSrcweir // <-#112139#
2648cdf0e10cSrcweir 
IsDocNodes() const2649cdf0e10cSrcweir sal_Bool SwNodes::IsDocNodes() const
2650cdf0e10cSrcweir {
2651cdf0e10cSrcweir     return this == &pMyDoc->GetNodes();
2652cdf0e10cSrcweir }
2653