LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/docnode - nodes.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 372 1089 34.2 %
Date: 2012-12-17 Functions: 30 39 76.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10