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