LCOV - code coverage report
Current view: top level - sw/source/core/docnode - nodes.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1119 0.0 %
Date: 2014-04-14 Functions: 0 40 0.0 %
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             : #include <stdlib.h>
      21             : 
      22             : #include <node.hxx>
      23             : #include <doc.hxx>
      24             : #include <IDocumentUndoRedo.hxx>
      25             : #include <pam.hxx>
      26             : #include <txtfld.hxx>
      27             : #include <fmtfld.hxx>
      28             : #include <hints.hxx>
      29             : #include <numrule.hxx>
      30             : #include <ndtxt.hxx>
      31             : #include <ndnotxt.hxx>
      32             : #include <swtable.hxx>
      33             : #include <tblsel.hxx>
      34             : #include <section.hxx>
      35             : #include <ddefld.hxx>
      36             : #include <swddetbl.hxx>
      37             : #include <frame.hxx>
      38             : #include <txtatr.hxx>
      39             : #include <tox.hxx>
      40             : 
      41             : #include <docsh.hxx>
      42             : #include <svl/smplhint.hxx>
      43             : 
      44             : typedef std::vector<SwStartNode*> SwSttNdPtrs;
      45             : 
      46             : // function to determine the highest level in the given range
      47             : sal_uInt16 HighestLevel( SwNodes & rNodes, const SwNodeRange & rRange );
      48             : 
      49             : /** Constructor
      50             :  *
      51             :  * creates the base sections (PostIts, Inserts, AutoText, RedLines, Content)
      52             :  *
      53             :  * @param pDocument TODO: provide documentation
      54             :  */
      55           0 : SwNodes::SwNodes( SwDoc* pDocument )
      56           0 :     : pRoot( 0 ), pMyDoc( pDocument )
      57             : {
      58           0 :     bInNodesDel = bInDelUpdOutl = bInDelUpdNum = sal_False;
      59             : 
      60             :     OSL_ENSURE( pMyDoc, "in which Doc am I?" );
      61             : 
      62           0 :     sal_uLong nPos = 0;
      63           0 :     SwStartNode* pSttNd = new SwStartNode( *this, nPos++ );
      64           0 :     pEndOfPostIts = new SwEndNode( *this, nPos++, *pSttNd );
      65             : 
      66           0 :     SwStartNode* pTmp = new SwStartNode( *this, nPos++ );
      67           0 :     pEndOfInserts = new SwEndNode( *this, nPos++, *pTmp );
      68             : 
      69           0 :     pTmp = new SwStartNode( *this, nPos++ );
      70           0 :     pTmp->pStartOfSection = pSttNd;
      71           0 :     pEndOfAutotext = new SwEndNode( *this, nPos++, *pTmp );
      72             : 
      73           0 :     pTmp = new SwStartNode( *this, nPos++ );
      74           0 :     pTmp->pStartOfSection = pSttNd;
      75           0 :     pEndOfRedlines = new SwEndNode( *this, nPos++, *pTmp );
      76             : 
      77           0 :     pTmp = new SwStartNode( *this, nPos++ );
      78           0 :     pTmp->pStartOfSection = pSttNd;
      79           0 :     pEndOfContent = new SwEndNode( *this, nPos++, *pTmp );
      80             : 
      81           0 :     pOutlineNds = new SwOutlineNodes;
      82           0 : }
      83             : 
      84             : /** Destructor
      85             :  *
      86             :  * Deletes all nodes whose pointer are in a dynamic array. This should be no
      87             :  * problem as nodes cannot be created outside this array and, thus, cannot be
      88             :  * part of multiple arrays.
      89             :  */
      90           0 : SwNodes::~SwNodes()
      91             : {
      92           0 :     delete pOutlineNds;
      93             : 
      94             :     {
      95             :         SwNode *pNode;
      96           0 :         SwNodeIndex aNdIdx( *this );
      97             :         while( true )
      98             :         {
      99           0 :             pNode = &aNdIdx.GetNode();
     100           0 :             if( pNode == pEndOfContent )
     101           0 :                 break;
     102             : 
     103           0 :             ++aNdIdx;
     104           0 :             delete pNode;
     105           0 :         }
     106             :     }
     107             : 
     108             :     // here, all SwNodeIndices must be unregistered
     109           0 :     delete pEndOfContent;
     110           0 : }
     111             : 
     112           0 : void SwNodes::ChgNode( SwNodeIndex& rDelPos, sal_uLong nSz,
     113             :                         SwNodeIndex& rInsPos, sal_Bool bNewFrms )
     114             : {
     115             :     // no need for frames in the UndoArea
     116           0 :     SwNodes& rNds = rInsPos.GetNodes();
     117           0 :     const SwNode* pPrevInsNd = rNds[ rInsPos.GetIndex() -1 ];
     118             : 
     119             :     // declare all fields as invalid, updating will happen
     120             :     // in the idle-handler of the doc
     121           0 :     if( GetDoc()->SetFieldsDirty( true, &rDelPos.GetNode(), nSz ) &&
     122           0 :         rNds.GetDoc() != GetDoc() )
     123           0 :         rNds.GetDoc()->SetFieldsDirty( true, NULL, 0 );
     124             : 
     125             :     // NEVER include nodes from the RedLineArea
     126           0 :     sal_uLong nNd = rInsPos.GetIndex();
     127             :     bool bInsOutlineIdx = !(
     128           0 :             rNds.GetEndOfRedlines().StartOfSectionNode()->GetIndex() < nNd &&
     129           0 :             nNd < rNds.GetEndOfRedlines().GetIndex() );
     130             : 
     131           0 :     if( &rNds == this ) // if in the same node array -> move
     132             :     {
     133             :         // Move order: from front to back, so that new entries are added at
     134             :         // first position, thus, deletion position stays the same
     135           0 :         sal_uInt16 nDiff = rDelPos.GetIndex() < rInsPos.GetIndex() ? 0 : 1;
     136             : 
     137           0 :         for( sal_uLong n = rDelPos.GetIndex(); nSz; n += nDiff, --nSz )
     138             :         {
     139           0 :             SwNodeIndex aDelIdx( *this, n );
     140           0 :             SwNode& rNd = aDelIdx.GetNode();
     141             : 
     142             :             // #i57920# - correction of refactoring done by cws swnumtree:
     143             :             // - <SwTxtNode::SetLevel( NO_NUMBERING ) is deprecated and
     144             :             //   set <IsCounted> state of the text node to <false>, which
     145             :             //   isn't correct here.
     146           0 :             if ( rNd.IsTxtNode() )
     147             :             {
     148           0 :                 SwTxtNode* pTxtNode = rNd.GetTxtNode();
     149             : 
     150           0 :                 pTxtNode->RemoveFromList();
     151             : 
     152           0 :                 if (pTxtNode->IsOutline())
     153             :                 {
     154           0 :                     const SwNodePtr pSrch = (SwNodePtr)&rNd;
     155           0 :                     pOutlineNds->erase( pSrch );
     156             :                 }
     157             :             }
     158             : 
     159           0 :             BigPtrArray::Move( aDelIdx.GetIndex(), rInsPos.GetIndex() );
     160             : 
     161           0 :             if( rNd.IsTxtNode() )
     162             :             {
     163           0 :                 SwTxtNode& rTxtNd = (SwTxtNode&)rNd;
     164             : 
     165           0 :                 rTxtNd.AddToList();
     166             : 
     167           0 :                 if (bInsOutlineIdx && rTxtNd.IsOutline())
     168             :                 {
     169           0 :                     const SwNodePtr pSrch = (SwNodePtr)&rNd;
     170           0 :                     pOutlineNds->insert( pSrch );
     171             :                 }
     172           0 :                 rTxtNd.InvalidateNumRule();
     173             : 
     174             : //FEATURE::CONDCOLL
     175           0 :                 if( RES_CONDTXTFMTCOLL == rTxtNd.GetTxtColl()->Which() )
     176           0 :                     rTxtNd.ChkCondColl();
     177             : //FEATURE::CONDCOLL
     178             :             }
     179           0 :             else if( rNd.IsCntntNode() )
     180           0 :                 ((SwCntntNode&)rNd).InvalidateNumRule();
     181           0 :         }
     182             :     }
     183             :     else
     184             :     {
     185           0 :         bool bSavePersData(GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(rNds));
     186           0 :         bool bRestPersData(GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(*this));
     187           0 :         SwDoc* pDestDoc = rNds.GetDoc() != GetDoc() ? rNds.GetDoc() : 0;
     188             :         OSL_ENSURE(!pDestDoc, "SwNodes::ChgNode(): "
     189             :             "the code to handle text fields here looks broken\n"
     190             :             "if the target is in a different document.");
     191           0 :         if( !bRestPersData && !bSavePersData && pDestDoc )
     192           0 :             bSavePersData = bRestPersData = true;
     193             : 
     194           0 :         OUString sNumRule;
     195           0 :         SwNodeIndex aInsPos( rInsPos );
     196           0 :         for( sal_uLong n = 0; n < nSz; n++ )
     197             :         {
     198           0 :             SwNode* pNd = &rDelPos.GetNode();
     199             : 
     200             :             // NoTextNode keep their persistent data
     201           0 :             if( pNd->IsNoTxtNode() )
     202             :             {
     203           0 :                 if( bSavePersData )
     204           0 :                     ((SwNoTxtNode*)pNd)->SavePersistentData();
     205             :             }
     206           0 :             else if( pNd->IsTxtNode() )
     207             :             {
     208           0 :                 SwTxtNode* pTxtNd = (SwTxtNode*)pNd;
     209             : 
     210             :                 // remove outline index from old nodes array
     211           0 :                 if (pTxtNd->IsOutline())
     212             :                 {
     213           0 :                     pOutlineNds->erase( pNd );
     214             :                 }
     215             : 
     216             :                 // copy rules if needed
     217           0 :                 if( pDestDoc )
     218             :                 {
     219           0 :                     const SwNumRule* pNumRule = pTxtNd->GetNumRule();
     220           0 :                     if( pNumRule && sNumRule != pNumRule->GetName() )
     221             :                     {
     222           0 :                         sNumRule = pNumRule->GetName();
     223           0 :                         SwNumRule* pDestRule = pDestDoc->FindNumRulePtr( sNumRule );
     224           0 :                         if( pDestRule )
     225           0 :                             pDestRule->SetInvalidRule( sal_True );
     226             :                         else
     227           0 :                             pDestDoc->MakeNumRule( sNumRule, pNumRule );
     228             :                     }
     229             :                 }
     230             :                 else
     231             :                     // if movement into the UndoNodes-array, update numbering
     232           0 :                     pTxtNd->InvalidateNumRule();
     233             : 
     234           0 :                 pTxtNd->RemoveFromList();
     235             :             }
     236             : 
     237           0 :             RemoveNode( rDelPos.GetIndex(), 1, sal_False ); // move indices
     238           0 :             SwCntntNode * pCNd = pNd->GetCntntNode();
     239           0 :             rNds.InsertNode( pNd, aInsPos );
     240             : 
     241           0 :             if( pCNd )
     242             :             {
     243           0 :                 SwTxtNode* pTxtNd = pCNd->GetTxtNode();
     244           0 :                 if( pTxtNd )
     245             :                 {
     246           0 :                     SwpHints * const pHts = pTxtNd->GetpSwpHints();
     247             :                     // OultineNodes set the new nodes in the array
     248           0 :                     if (bInsOutlineIdx && pTxtNd->IsOutline())
     249             :                     {
     250           0 :                         rNds.pOutlineNds->insert( pTxtNd );
     251             :                     }
     252             : 
     253           0 :                     pTxtNd->AddToList();
     254             : 
     255             :                     // special treatment for fields
     256           0 :                     if( pHts && pHts->Count() )
     257             :                     {
     258           0 :                         bool const bToUndo = !pDestDoc &&
     259           0 :                             GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(rNds);
     260           0 :                         for( sal_uInt16 i = pHts->Count(); i; )
     261             :                         {
     262           0 :                             sal_uInt16 nDelMsg = 0;
     263           0 :                             SwTxtAttr * const pAttr = pHts->GetTextHint( --i );
     264           0 :                             switch ( pAttr->Which() )
     265             :                             {
     266             :                             case RES_TXTATR_FIELD:
     267             :                             case RES_TXTATR_ANNOTATION:
     268             :                             case RES_TXTATR_INPUTFIELD:
     269             :                                 {
     270           0 :                                     SwTxtFld* pTxtFld = static_cast<SwTxtFld*>(pAttr);
     271           0 :                                     rNds.GetDoc()->InsDelFldInFldLst( !bToUndo, *pTxtFld );
     272             : 
     273           0 :                                     const SwFieldType* pTyp = pTxtFld->GetFmtFld().GetField()->GetTyp();
     274           0 :                                     if ( RES_POSTITFLD == pTyp->Which() )
     275             :                                     {
     276           0 :                                         rNds.GetDoc()->GetDocShell()->Broadcast(
     277             :                                             SwFmtFldHint(
     278           0 :                                                 &pTxtFld->GetFmtFld(),
     279           0 :                                                 ( pTxtFld->GetFmtFld().IsFldInDoc()
     280             :                                                   ? SWFMTFLD_INSERTED
     281           0 :                                                   : SWFMTFLD_REMOVED ) ) );
     282             :                                     }
     283           0 :                                     else if( RES_DDEFLD == pTyp->Which() )
     284             :                                     {
     285           0 :                                         if( bToUndo )
     286           0 :                                             ((SwDDEFieldType*)pTyp)->DecRefCnt();
     287             :                                         else
     288           0 :                                             ((SwDDEFieldType*)pTyp)->IncRefCnt();
     289             :                                     }
     290           0 :                                     nDelMsg = RES_FIELD_DELETED;
     291             :                                 }
     292           0 :                                 break;
     293             : 
     294             :                             case RES_TXTATR_FTN:
     295           0 :                                 nDelMsg = RES_FOOTNOTE_DELETED;
     296           0 :                                 break;
     297             : 
     298             :                             case RES_TXTATR_TOXMARK:
     299           0 :                                 static_cast<SwTOXMark&>(pAttr->GetAttr())
     300           0 :                                     .InvalidateTOXMark();
     301           0 :                                 break;
     302             : 
     303             :                             case RES_TXTATR_REFMARK:
     304           0 :                                 nDelMsg = RES_REFMARK_DELETED;
     305           0 :                                 break;
     306             : 
     307             :                             case RES_TXTATR_META:
     308             :                             case RES_TXTATR_METAFIELD:
     309             :                                 {
     310             :                                     SwTxtMeta *const pTxtMeta(
     311           0 :                                         static_cast<SwTxtMeta*>(pAttr));
     312             :                                     // force removal of UNO object
     313           0 :                                     pTxtMeta->ChgTxtNode(0);
     314           0 :                                     pTxtMeta->ChgTxtNode(pTxtNd);
     315             :                                 }
     316           0 :                                 break;
     317             : 
     318             :                             default:
     319           0 :                                 break;
     320             :                             }
     321             : 
     322           0 :                             if( nDelMsg && bToUndo )
     323             :                             {
     324             :                                 SwPtrMsgPoolItem aMsgHint( nDelMsg,
     325           0 :                                     (void*)&pAttr->GetAttr() );
     326           0 :                                 rNds.GetDoc()->GetUnoCallBack()->
     327           0 :                                     ModifyNotification( &aMsgHint, &aMsgHint );
     328             :                             }
     329             :                         }
     330             :                     }
     331             :                     //FEATURE::CONDCOLL
     332           0 :                     if( RES_CONDTXTFMTCOLL == pTxtNd->GetTxtColl()->Which() )
     333           0 :                         pTxtNd->ChkCondColl();
     334             :                     //FEATURE::CONDCOLL
     335             :                 }
     336             :                 else
     337             :                 {
     338             :                     // Moved into different Docs? Persist data again!
     339           0 :                     if( pCNd->IsNoTxtNode() && bRestPersData )
     340           0 :                         ((SwNoTxtNode*)pCNd)->RestorePersistentData();
     341             :                 }
     342             :             }
     343           0 :         }
     344             :     }
     345             : 
     346             :     // declare all fields as invalid, updating will happen
     347             :     // in the idle-handler of the doc
     348           0 :     GetDoc()->SetFieldsDirty( true, NULL, 0 );
     349           0 :     if( rNds.GetDoc() != GetDoc() )
     350           0 :         rNds.GetDoc()->SetFieldsDirty( true, NULL, 0 );
     351             : 
     352           0 :     if( bNewFrms )
     353           0 :         bNewFrms = &GetDoc()->GetNodes() == (const SwNodes*)&rNds &&
     354           0 :                     GetDoc()->GetCurrentViewShell();
     355             : 
     356           0 :     if( bNewFrms )
     357             :     {
     358             :         // get the frames:
     359           0 :         SwNodeIndex aIdx( *pPrevInsNd, 1 );
     360           0 :         SwNodeIndex aFrmNdIdx( aIdx );
     361             :         SwNode* pFrmNd = rNds.FindPrvNxtFrmNode( aFrmNdIdx,
     362           0 :                                         rNds[ rInsPos.GetIndex() - 1 ] );
     363             : 
     364           0 :         if( !pFrmNd && aFrmNdIdx > rNds.GetEndOfExtras().GetIndex() )
     365             :         {
     366             :             OSL_ENSURE( !this, "here, something wrong happened" );
     367           0 :             aFrmNdIdx = rNds.GetEndOfContent();
     368           0 :             pFrmNd = rNds.GoPrevSection( &aFrmNdIdx, true, false );
     369           0 :             if( pFrmNd && !((SwCntntNode*)pFrmNd)->GetDepends() )
     370           0 :                 pFrmNd = 0;
     371             :             OSL_ENSURE( pFrmNd, "ChgNode() - no FrameNode found" );
     372             :         }
     373           0 :         if( pFrmNd )
     374           0 :             while( aIdx != rInsPos )
     375             :             {
     376           0 :                 SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
     377           0 :                 if( pCNd )
     378             :                 {
     379           0 :                     if( pFrmNd->IsTableNode() )
     380           0 :                         ((SwTableNode*)pFrmNd)->MakeFrms( aIdx );
     381           0 :                     else if( pFrmNd->IsSectionNode() )
     382           0 :                         ((SwSectionNode*)pFrmNd)->MakeFrms( aIdx );
     383             :                     else
     384           0 :                         ((SwCntntNode*)pFrmNd)->MakeFrms( *pCNd );
     385           0 :                     pFrmNd = pCNd;
     386             :                 }
     387           0 :                 ++aIdx;
     388           0 :             }
     389             :     }
     390           0 : }
     391             : 
     392             : // TODO: provide documentation
     393             : /** move the node pointer
     394             :  *
     395             :  * Move the node pointer from "(inclusive) start position to (exclusive) end
     396             :  * position" to target position.
     397             :  * If the target is in front of the first or in the area between first and
     398             :  * last element to move, nothing happens.
     399             :  * If the area to move is empty or the end position is before the start
     400             :  * position, nothing happens.
     401             :  *
     402             :  * @param aRange range to move (excluding end node)
     403             :  * @param rNodes
     404             :  * @param aIndex
     405             :  * @param bNewFrms
     406             :  * @return
     407             :  */
     408           0 : sal_Bool SwNodes::_MoveNodes( const SwNodeRange& aRange, SwNodes & rNodes,
     409             :                     const SwNodeIndex& aIndex, sal_Bool bNewFrms )
     410             : {
     411             :     SwNode * pAktNode;
     412           0 :     if( aIndex == 0 ||
     413           0 :         ( (pAktNode = &aIndex.GetNode())->GetStartNode() &&
     414           0 :           !pAktNode->StartOfSectionIndex() ))
     415           0 :         return sal_False;
     416             : 
     417           0 :     SwNodeRange aRg( aRange );
     418             : 
     419             :     // skip "simple" start or end nodes
     420           0 :     while( ND_STARTNODE == (pAktNode = &aRg.aStart.GetNode())->GetNodeType()
     421           0 :             || ( pAktNode->IsEndNode() &&
     422           0 :                 !pAktNode->pStartOfSection->IsSectionNode() ) )
     423           0 :         aRg.aStart++;
     424           0 :     aRg.aStart--;
     425             : 
     426             :     // if aEnd-1 points to no ContentNode, search previous one
     427           0 :     aRg.aEnd--;
     428           0 :     while( ( (( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() &&
     429           0 :             !pAktNode->IsSectionNode() ) ||
     430           0 :             ( pAktNode->IsEndNode() &&
     431           0 :             ND_STARTNODE == pAktNode->pStartOfSection->GetNodeType()) ) &&
     432           0 :             aRg.aEnd > aRg.aStart )
     433           0 :         aRg.aEnd--;
     434             : 
     435             :     // if in same array, check insertion position
     436           0 :     if( aRg.aStart >= aRg.aEnd )
     437           0 :         return sal_False;
     438             : 
     439           0 :     if( this == &rNodes )
     440             :     {
     441           0 :         if( ( aIndex.GetIndex()-1 >= aRg.aStart.GetIndex() &&
     442           0 :               aIndex.GetIndex()-1 < aRg.aEnd.GetIndex()) ||
     443           0 :             ( aIndex.GetIndex()-1 == aRg.aEnd.GetIndex() ) )
     444           0 :             return sal_False;
     445             :     }
     446             : 
     447           0 :     sal_uInt16 nLevel = 0; // level counter
     448           0 :     sal_uLong nInsPos = 0; // counter for tmp array
     449             : 
     450             :     // array as a stack, storing all StartOfSelections
     451           0 :     SwSttNdPtrs aSttNdStack;
     452             : 
     453             :     // set start index
     454           0 :     SwNodeIndex  aIdx( aIndex );
     455             : 
     456           0 :     SwStartNode* pStartNode = aIdx.GetNode().pStartOfSection;
     457           0 :     aSttNdStack.insert( aSttNdStack.begin(), pStartNode );
     458             : 
     459           0 :     SwNodeRange aOrigInsPos( aIdx, -1, aIdx ); // original insertion position
     460             : 
     461             :     // call DelFrms/MakeFrms for the upmost SectionNode
     462           0 :     sal_uInt16 nSectNdCnt = 0;
     463           0 :     sal_Bool bSaveNewFrms = bNewFrms;
     464             : 
     465             :     // continue until everything has been moved
     466           0 :     while( aRg.aStart < aRg.aEnd )
     467           0 :         switch( (pAktNode = &aRg.aEnd.GetNode())->GetNodeType() )
     468             :         {
     469             :         case ND_ENDNODE:
     470             :             {
     471           0 :                 if( nInsPos ) // move everything until here
     472             :                 {
     473             :                     // delete and copy. CAUTION: all indices after
     474             :                     // "aRg.aEnd+1" will be moved as well!
     475           0 :                     SwNodeIndex aSwIndex( aRg.aEnd, 1 );
     476           0 :                     ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
     477           0 :                     aIdx -= nInsPos;
     478           0 :                     nInsPos = 0;
     479             :                 }
     480             : 
     481           0 :                 SwStartNode* pSttNd = pAktNode->pStartOfSection;
     482           0 :                 if( pSttNd->IsTableNode() )
     483             :                 {
     484           0 :                     SwTableNode* pTblNd = (SwTableNode*)pSttNd;
     485             : 
     486             :                     // move the whole table/range
     487           0 :                     nInsPos = (aRg.aEnd.GetIndex() -
     488           0 :                                     pSttNd->GetIndex() )+1;
     489           0 :                     aRg.aEnd -= nInsPos;
     490             : 
     491             :                     // NEVER include nodes from the RedLineArea
     492           0 :                     sal_uLong nNd = aIdx.GetIndex();
     493           0 :                     bool bInsOutlineIdx = !( rNodes.GetEndOfRedlines().
     494           0 :                             StartOfSectionNode()->GetIndex() < nNd &&
     495           0 :                             nNd < rNodes.GetEndOfRedlines().GetIndex() );
     496             : 
     497           0 :                     if( bNewFrms )
     498             :                         // delete all frames
     499           0 :                         pTblNd->DelFrms();
     500           0 :                     if( &rNodes == this ) // move into self?
     501             :                     {
     502             :                         // move all Start/End/ContentNodes
     503             :                         // ContentNodes: delete also the frames!
     504           0 :                         pTblNd->pStartOfSection = aIdx.GetNode().pStartOfSection;
     505           0 :                         for( sal_uLong n = 0; n < nInsPos; ++n )
     506             :                         {
     507           0 :                             SwNodeIndex aMvIdx( aRg.aEnd, 1 );
     508           0 :                             SwCntntNode* pCNd = 0;
     509           0 :                             SwNode* pTmpNd = &aMvIdx.GetNode();
     510           0 :                             if( pTmpNd->IsCntntNode() )
     511             :                             {
     512           0 :                                 pCNd = (SwCntntNode*)pTmpNd;
     513           0 :                                 if( pTmpNd->IsTxtNode() )
     514           0 :                                     ((SwTxtNode*)pTmpNd)->RemoveFromList();
     515             : 
     516             :                                 // remove outline index from old nodes array
     517           0 :                                 if (pCNd->IsTxtNode() &&
     518           0 :                                     static_cast<SwTxtNode*>(pCNd)->IsOutline())
     519             :                                 {
     520           0 :                                     pOutlineNds->erase( pCNd );
     521             :                                 }
     522             :                                 else
     523           0 :                                     pCNd = 0;
     524             :                             }
     525             : 
     526           0 :                             BigPtrArray::Move( aMvIdx.GetIndex(), aIdx.GetIndex() );
     527             : 
     528           0 :                             if( bInsOutlineIdx && pCNd )
     529           0 :                                 pOutlineNds->insert( pCNd );
     530           0 :                             if( pTmpNd->IsTxtNode() )
     531           0 :                                 ((SwTxtNode*)pTmpNd)->AddToList();
     532           0 :                         }
     533             :                     }
     534             :                     else
     535             :                     {
     536             :                         // get StartNode
     537             :                         // Even aIdx points to a startnode, we need the startnode
     538             :                         // of the environment of aIdx (#i80941)
     539           0 :                         SwStartNode* pSttNode = aIdx.GetNode().pStartOfSection;
     540             : 
     541             :                         // get all boxes with content because their indices
     542             :                         // pointing to the StartNodes need to be reset
     543             :                         // (copying the array and deleting all found ones eases
     544             :                         // searching)
     545           0 :                         SwNodeIndex aMvIdx( aRg.aEnd, 1 );
     546           0 :                         for( sal_uLong n = 0; n < nInsPos; ++n )
     547             :                         {
     548           0 :                             SwNode* pNd = &aMvIdx.GetNode();
     549             : 
     550           0 :                             const bool bOutlNd = pNd->IsTxtNode() &&
     551           0 :                                 static_cast<SwTxtNode*>(pNd)->IsOutline();
     552             :                             // delete outline indices from old node array
     553           0 :                             if( bOutlNd )
     554           0 :                                 pOutlineNds->erase( pNd );
     555             : 
     556           0 :                             RemoveNode( aMvIdx.GetIndex(), 1, sal_False );
     557           0 :                             pNd->pStartOfSection = pSttNode;
     558           0 :                             rNodes.InsertNode( pNd, aIdx );
     559             : 
     560             :                             // set correct indices in Start/EndNodes
     561           0 :                             if( bInsOutlineIdx && bOutlNd )
     562             :                                 // and put them into the new node array
     563           0 :                                 rNodes.pOutlineNds->insert( pNd );
     564           0 :                             else if( pNd->IsStartNode() )
     565           0 :                                 pSttNode = (SwStartNode*)pNd;
     566           0 :                             else if( pNd->IsEndNode() )
     567             :                             {
     568           0 :                                 pSttNode->pEndOfSection = (SwEndNode*)pNd;
     569           0 :                                 if( pSttNode->IsSectionNode() )
     570           0 :                                     ((SwSectionNode*)pSttNode)->NodesArrChgd();
     571           0 :                                 pSttNode = pSttNode->pStartOfSection;
     572             :                             }
     573             :                         }
     574             : 
     575           0 :                         if( pTblNd->GetTable().IsA( TYPE( SwDDETable ) ))
     576             :                         {
     577             :                             SwDDEFieldType* pTyp = ((SwDDETable&)pTblNd->
     578           0 :                                                 GetTable()).GetDDEFldType();
     579           0 :                             if( pTyp )
     580             :                             {
     581           0 :                                 if( rNodes.IsDocNodes() )
     582           0 :                                     pTyp->IncRefCnt();
     583             :                                 else
     584           0 :                                     pTyp->DecRefCnt();
     585             :                             }
     586             :                         }
     587             : 
     588           0 :                         if (GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(
     589           0 :                                     rNodes))
     590             :                         {
     591           0 :                             SwFrmFmt* pTblFmt = pTblNd->GetTable().GetFrmFmt();
     592             :                             SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT,
     593           0 :                                                         pTblFmt );
     594           0 :                             pTblFmt->ModifyNotification( &aMsgHint, &aMsgHint );
     595           0 :                         }
     596             :                     }
     597           0 :                     if( bNewFrms )
     598             :                     {
     599           0 :                         SwNodeIndex aTmp( aIdx );
     600           0 :                         pTblNd->MakeFrms( &aTmp );
     601             :                     }
     602           0 :                     aIdx -= nInsPos;
     603           0 :                     nInsPos = 0;
     604             :                 }
     605           0 :                 else if( pSttNd->GetIndex() < aRg.aStart.GetIndex() )
     606             :                 {
     607             :                     // SectionNode: not the whole section will be moved, thus,
     608             :                     //              move only the ContentNodes
     609             :                     // StartNode:   create a new section at the given position
     610             :                     do {        // middle check loop
     611           0 :                         if( !pSttNd->IsSectionNode() )
     612             :                         {
     613             :                             // create StartNode and EndNode at InsertPos
     614             :                             SwStartNode* pTmp = new SwStartNode( aIdx,
     615             :                                                     ND_STARTNODE,
     616           0 : /*?? NodeType ??*/                                  SwNormalStartNode );
     617             : 
     618           0 :                             nLevel++; // put the index to StartNode on the stack
     619           0 :                             aSttNdStack.insert( aSttNdStack.begin() + nLevel, pTmp );
     620             : 
     621             :                             // create EndNode
     622           0 :                             new SwEndNode( aIdx, *pTmp );
     623             :                         }
     624           0 :                         else if (GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(
     625           0 :                                     rNodes))
     626             :                         {
     627             :                             // use placeholder in UndoNodes array
     628           0 :                             new SwDummySectionNode( aIdx );
     629             :                         }
     630             :                         else
     631             :                         {
     632             :                             // JP 18.5.2001 (Bug 70454) creating new section?
     633           0 :                             aRg.aEnd--;
     634           0 :                             break;
     635             : 
     636             :                         }
     637             : 
     638           0 :                         aRg.aEnd--;
     639           0 :                         aIdx--;
     640             :                     } while( false );
     641             :                 }
     642             :                 else
     643             :                 {
     644             :                     // move StartNode and EndNode in total
     645             : 
     646             :                     // if Start is exactly the Start of the area,
     647             :                     // then the Node needs to be re-visited
     648           0 :                     if( &aRg.aStart.GetNode() == pSttNd )
     649           0 :                         --aRg.aStart;
     650             : 
     651           0 :                     SwSectionNode* pSctNd = pSttNd->GetSectionNode();
     652           0 :                     if( bNewFrms && pSctNd )
     653           0 :                         pSctNd->DelFrms();
     654             : 
     655           0 :                     RemoveNode( aRg.aEnd.GetIndex(), 1, sal_False ); // EndNode loeschen
     656           0 :                     sal_uLong nSttPos = pSttNd->GetIndex();
     657             : 
     658             :                     // this StartNode will be removed later
     659           0 :                     SwStartNode* pTmpSttNd = new SwStartNode( *this, nSttPos+1 );
     660           0 :                     pTmpSttNd->pStartOfSection = pSttNd->pStartOfSection;
     661             : 
     662           0 :                     RemoveNode( nSttPos, 1, sal_False ); // SttNode loeschen
     663             : 
     664           0 :                     pSttNd->pStartOfSection = aIdx.GetNode().pStartOfSection;
     665           0 :                     rNodes.InsertNode( pSttNd, aIdx  );
     666           0 :                     rNodes.InsertNode( pAktNode, aIdx );
     667           0 :                     aIdx--;
     668           0 :                     pSttNd->pEndOfSection = (SwEndNode*)pAktNode;
     669             : 
     670           0 :                     aRg.aEnd--;
     671             : 
     672           0 :                     nLevel++; // put the index pointing to the StartNode onto the stack
     673           0 :                     aSttNdStack.insert( aSttNdStack.begin() + nLevel, pSttNd );
     674             : 
     675             :                     // reset remaining indices if SectionNode
     676           0 :                     if( pSctNd )
     677             :                     {
     678           0 :                         pSctNd->NodesArrChgd();
     679           0 :                         ++nSectNdCnt;
     680           0 :                         bNewFrms = sal_False;
     681             :                     }
     682             :                 }
     683             :             }
     684           0 :             break;
     685             : 
     686             :         case ND_SECTIONNODE:
     687           0 :             if( !nLevel &&
     688           0 :                 GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(rNodes))
     689             :             {
     690             :                 // here, a SectionDummyNode needs to be inserted at the current position
     691           0 :                 if( nInsPos ) // move everything until here
     692             :                 {
     693             :                     // delete and copy. CAUTION: all indices after
     694             :                     // "aRg.aEnd+1" will be moved as well!
     695           0 :                     SwNodeIndex aSwIndex( aRg.aEnd, 1 );
     696           0 :                     ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
     697           0 :                     aIdx -= nInsPos;
     698           0 :                     nInsPos = 0;
     699             :                 }
     700           0 :                 new SwDummySectionNode( aIdx );
     701           0 :                 aRg.aEnd--;
     702           0 :                 aIdx--;
     703           0 :                 break;
     704             :             }
     705             :             // no break !!
     706             :         case ND_TABLENODE:
     707             :         case ND_STARTNODE:
     708             :             {
     709             :                 // empty section -> nothing to do
     710             :                 //  and only if it's a top level section
     711           0 :                 if( !nInsPos && !nLevel )
     712             :                 {
     713           0 :                     aRg.aEnd--;
     714           0 :                     break;
     715             :                 }
     716             : 
     717           0 :                 if( !nLevel ) // level is decreasing
     718             :                 {
     719             :                     // create decrease
     720           0 :                     SwNodeIndex aTmpSIdx( aOrigInsPos.aStart, 1 );
     721             :                     SwStartNode* pTmpStt = new SwStartNode( aTmpSIdx,
     722             :                                 ND_STARTNODE,
     723           0 :                                 ((SwStartNode*)pAktNode)->GetStartNodeType() );
     724             : 
     725           0 :                     aTmpSIdx--;
     726             : 
     727           0 :                     SwNodeIndex aTmpEIdx( aOrigInsPos.aEnd );
     728           0 :                     new SwEndNode( aTmpEIdx, *pTmpStt );
     729           0 :                     aTmpEIdx--;
     730           0 :                     ++aTmpSIdx;
     731             : 
     732             :                     // set correct StartOfSection
     733           0 :                     aRg.aEnd++;
     734             :                     {
     735           0 :                         SwNodeIndex aCntIdx( aRg.aEnd );
     736           0 :                         for( sal_uLong n = 0; n < nInsPos; n++, aCntIdx++)
     737           0 :                             aCntIdx.GetNode().pStartOfSection = pTmpStt;
     738             :                     }
     739             : 
     740             :                     // also set correct StartNode for all decreased nodes
     741           0 :                     while( aTmpSIdx < aTmpEIdx )
     742           0 :                         if( 0 != (( pAktNode = &aTmpEIdx.GetNode())->GetEndNode()) )
     743           0 :                             aTmpEIdx = pAktNode->StartOfSectionIndex();
     744             :                         else
     745             :                         {
     746           0 :                             pAktNode->pStartOfSection = pTmpStt;
     747           0 :                             aTmpEIdx--;
     748             :                         }
     749             : 
     750           0 :                     aIdx--;     // after the inserted StartNode
     751           0 :                     aRg.aEnd--; // before StartNode
     752             :                     // copy array. CAUTION: all indices after
     753             :                     // "aRg.aEnd+1" will be moved as well!
     754           0 :                     SwNodeIndex aSwIndex( aRg.aEnd, 1 );
     755           0 :                     ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
     756           0 :                     aIdx -= nInsPos+1;
     757           0 :                     nInsPos = 0;
     758             :                 }
     759             :                 else // all nodes between StartNode and EndNode were moved
     760             :                 {
     761             :                     OSL_ENSURE( pAktNode == aSttNdStack[nLevel] ||
     762             :                             ( pAktNode->IsStartNode() &&
     763             :                                 aSttNdStack[nLevel]->IsSectionNode()),
     764             :                              "wrong StartNode" );
     765             : 
     766           0 :                     SwNodeIndex aSwIndex( aRg.aEnd, 1 );
     767           0 :                     ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
     768           0 :                     aIdx -= nInsPos+1; // before inserted StartNode
     769           0 :                     nInsPos = 0;
     770             : 
     771             :                     // remove pointer from node array
     772           0 :                     RemoveNode( aRg.aEnd.GetIndex(), 1, sal_True );
     773           0 :                     aRg.aEnd--;
     774             : 
     775           0 :                     SwSectionNode* pSectNd = aSttNdStack[ nLevel ]->GetSectionNode();
     776           0 :                     if( pSectNd && !--nSectNdCnt )
     777             :                     {
     778           0 :                         SwNodeIndex aTmp( *pSectNd );
     779           0 :                         pSectNd->MakeFrms( &aTmp );
     780           0 :                         bNewFrms = bSaveNewFrms;
     781             :                     }
     782           0 :                     aSttNdStack.erase( aSttNdStack.begin() + nLevel ); // remove from stack
     783           0 :                     nLevel--;
     784             :                 }
     785             : 
     786             :                 // delete all resulting empty start/end node pairs
     787           0 :                 SwNode* pTmpNode = (*this)[ aRg.aEnd.GetIndex()+1 ]->GetEndNode();
     788           0 :                 if( pTmpNode && ND_STARTNODE == (pAktNode = &aRg.aEnd.GetNode())
     789           0 :                     ->GetNodeType() && pAktNode->StartOfSectionIndex() &&
     790           0 :                     pTmpNode->StartOfSectionNode() == pAktNode )
     791             :                 {
     792           0 :                     DelNodes( aRg.aEnd, 2 );
     793           0 :                     aRg.aEnd--;
     794             :                 }
     795             :             }
     796           0 :             break;
     797             : 
     798             :         case ND_TEXTNODE:
     799             :             //Add special function to text node.
     800             :             {
     801           0 :                 if( bNewFrms && pAktNode->GetCntntNode() )
     802           0 :                     ((SwCntntNode*)pAktNode)->DelFrms( sal_False );
     803           0 :                 pAktNode->pStartOfSection = aSttNdStack[ nLevel ];
     804           0 :                 nInsPos++;
     805           0 :                 aRg.aEnd--;
     806             :             }
     807           0 :             break;
     808             :         case ND_GRFNODE:
     809             :         case ND_OLENODE:
     810             :             {
     811           0 :                 if( bNewFrms && pAktNode->GetCntntNode() )
     812           0 :                     ((SwCntntNode*)pAktNode)->DelFrms();
     813             : 
     814           0 :                 pAktNode->pStartOfSection = aSttNdStack[ nLevel ];
     815           0 :                 nInsPos++;
     816           0 :                 aRg.aEnd--;
     817             :             }
     818           0 :             break;
     819             : 
     820             :         case ND_SECTIONDUMMY:
     821           0 :             if (GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(*this))
     822             :             {
     823           0 :                 if( &rNodes == this ) // inside UndoNodesArray
     824             :                 {
     825             :                     // move everything
     826           0 :                     pAktNode->pStartOfSection = aSttNdStack[ nLevel ];
     827           0 :                     nInsPos++;
     828             :                 }
     829             :                 else // move into "normal" node array
     830             :                 {
     831             :                     // than a SectionNode (start/end) is needed at the current
     832             :                     // InsPos; if so skip it, otherwise ignore current node
     833           0 :                     if( nInsPos ) // move everything until here
     834             :                     {
     835             :                         // delete and copy. CAUTION: all indices after
     836             :                         // "aRg.aEnd+1" will be moved as well!
     837           0 :                         SwNodeIndex aSwIndex( aRg.aEnd, 1 );
     838           0 :                         ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
     839           0 :                         aIdx -= nInsPos;
     840           0 :                         nInsPos = 0;
     841             :                     }
     842           0 :                     SwNode* pTmpNd = &aIdx.GetNode();
     843           0 :                     if( pTmpNd->IsSectionNode() ||
     844           0 :                         pTmpNd->StartOfSectionNode()->IsSectionNode() )
     845           0 :                         aIdx--; // skip
     846             :                 }
     847             :             }
     848             :             else {
     849             :                 OSL_FAIL( "How can this node be in the node array?" );
     850             :             }
     851           0 :             aRg.aEnd--;
     852           0 :             break;
     853             : 
     854             :         default:
     855             :             OSL_FAIL( "Unknown node type" );
     856           0 :             break;
     857             :         }
     858             : 
     859           0 :     if( nInsPos ) // copy remaining rest
     860             :     {
     861             :         // rest should be ok
     862           0 :         SwNodeIndex aSwIndex( aRg.aEnd, 1 );
     863           0 :         ChgNode( aSwIndex, nInsPos, aIdx, bNewFrms );
     864             :     }
     865           0 :     aRg.aEnd++; // again, exclusive end
     866             : 
     867             :     // delete all resulting empty start/end node pairs
     868           0 :     if( ( pAktNode = &aRg.aStart.GetNode())->GetStartNode() &&
     869           0 :         pAktNode->StartOfSectionIndex() &&
     870           0 :         aRg.aEnd.GetNode().GetEndNode() )
     871           0 :             DelNodes( aRg.aStart, 2 );
     872             : 
     873             :     // initialize numbering update
     874           0 :     aOrigInsPos.aStart++;
     875             :     // Moved in same node array? Then call update top down!
     876           0 :     if( this == &rNodes &&
     877           0 :         aRg.aEnd.GetIndex() >= aOrigInsPos.aStart.GetIndex() )
     878             :     {
     879           0 :         UpdtOutlineIdx( aOrigInsPos.aStart.GetNode() );
     880           0 :         UpdtOutlineIdx( aRg.aEnd.GetNode() );
     881             :     }
     882             :     else
     883             :     {
     884           0 :         UpdtOutlineIdx( aRg.aEnd.GetNode() );
     885           0 :         rNodes.UpdtOutlineIdx( aOrigInsPos.aStart.GetNode() );
     886             :     }
     887             : 
     888           0 :     return sal_True;
     889             : }
     890             : 
     891             : /** create a start/end section pair
     892             :  *
     893             :  * Other nodes might be in between.
     894             :  *
     895             :  * After this method call, the start node of pRange will be pointing to the
     896             :  * first node after the start section node and the end node will be the index
     897             :  * of the end section node. If this method is called multiple times with the
     898             :  * same input, multiple sections containing the previous ones will be created
     899             :  * (no content nodes between start or end node).
     900             :  *
     901             :  * @note Start and end node of the range must be on the same level but MUST
     902             :  *       NOT be on the top level.
     903             :  *
     904             :  * @param [IN,OUT] pRange the range (excl. end)
     905             :  * @param eSttNdTyp type of the start node
     906             :  */
     907           0 : void SwNodes::SectionDown(SwNodeRange *pRange, SwStartNodeType eSttNdTyp )
     908             : {
     909           0 :     if( pRange->aStart >= pRange->aEnd ||
     910           0 :         pRange->aEnd >= Count() ||
     911           0 :         !CheckNodesRange( pRange->aStart, pRange->aEnd ))
     912           0 :         return;
     913             : 
     914             :     // If the beginning of a range is before or at a start node position, so
     915             :     // delete it, otherwise empty S/E or E/S nodes would be created.
     916             :     // For other nodes, create a new start node.
     917           0 :     SwNode * pAktNode = &pRange->aStart.GetNode();
     918           0 :     SwNodeIndex aTmpIdx( *pAktNode->StartOfSectionNode() );
     919             : 
     920           0 :     if( pAktNode->GetEndNode() )
     921           0 :         DelNodes( pRange->aStart, 1 ); // prevent empty section
     922             :     else
     923             :     {
     924             :         // insert a new StartNode
     925           0 :         SwNode* pSttNd = new SwStartNode( pRange->aStart, ND_STARTNODE, eSttNdTyp );
     926           0 :         pRange->aStart = *pSttNd;
     927           0 :         aTmpIdx = pRange->aStart;
     928             :     }
     929             : 
     930             :     // If the end of a range is before or at a StartNode, so delete it,
     931             :     // otherwise empty S/E or E/S nodes would be created.
     932             :     // For other nodes, insert a new end node.
     933           0 :     pRange->aEnd--;
     934           0 :     if( pRange->aEnd.GetNode().GetStartNode() )
     935           0 :         DelNodes( pRange->aEnd, 1 );
     936             :     else
     937             :     {
     938           0 :         pRange->aEnd++;
     939             :         // insert a new EndNode
     940           0 :         new SwEndNode( pRange->aEnd, *pRange->aStart.GetNode().GetStartNode() );
     941             :     }
     942           0 :     pRange->aEnd--;
     943             : 
     944           0 :     SectionUpDown( aTmpIdx, pRange->aEnd );
     945             : }
     946             : 
     947             : /** increase level of the given range
     948             :  *
     949             :  * The range contained in pRange will be lifted to the next higher level.
     950             :  * This is done by adding a end node at pRange.start and a start node at
     951             :  * pRange.end. Furthermore all indices for this range will be updated.
     952             :  *
     953             :  * After this method call, the start node of pRange will be pointing to the
     954             :  * first node inside the lifted range and the end node will be pointing to the
     955             :  * last position inside the lifted range.
     956             :  *
     957             :  * @param [IN,OUT] pRange the range of nodes where the level should be increased
     958             :  */
     959           0 : void SwNodes::SectionUp(SwNodeRange *pRange)
     960             : {
     961           0 :     if( pRange->aStart >= pRange->aEnd ||
     962           0 :         pRange->aEnd >= Count() ||
     963           0 :         !CheckNodesRange( pRange->aStart, pRange->aEnd ) ||
     964           0 :         !( HighestLevel( *this, *pRange ) > 1 ))
     965           0 :         return;
     966             : 
     967             :     // If the beginning of a range is before or at a start node position, so
     968             :     // delete it, otherwise empty S/E or E/S nodes would be created.
     969             :     // For other nodes, create a new start node.
     970           0 :     SwNode * pAktNode = &pRange->aStart.GetNode();
     971           0 :     SwNodeIndex aIdx( *pAktNode->StartOfSectionNode() );
     972           0 :     if( pAktNode->IsStartNode() )       // selbst StartNode
     973             :     {
     974           0 :         SwEndNode* pEndNd = pRange->aEnd.GetNode().GetEndNode();
     975           0 :         if( pAktNode == pEndNd->pStartOfSection )
     976             :         {
     977             :             // there was a pairwise reset, adjust only those in the range
     978           0 :             SwStartNode* pTmpSttNd = pAktNode->pStartOfSection;
     979           0 :             RemoveNode( pRange->aStart.GetIndex(), 1, sal_True );
     980           0 :             RemoveNode( pRange->aEnd.GetIndex(), 1, sal_True );
     981             : 
     982           0 :             SwNodeIndex aTmpIdx( pRange->aStart );
     983           0 :             while( aTmpIdx < pRange->aEnd )
     984             :             {
     985           0 :                 pAktNode = &aTmpIdx.GetNode();
     986           0 :                 pAktNode->pStartOfSection = pTmpSttNd;
     987           0 :                 if( pAktNode->IsStartNode() )
     988           0 :                     aTmpIdx = pAktNode->EndOfSectionIndex() + 1;
     989             :                 else
     990           0 :                     ++aTmpIdx;
     991             :             }
     992           0 :             return ;
     993             :         }
     994           0 :         DelNodes( pRange->aStart, 1 );
     995             :     }
     996           0 :     else if( aIdx == pRange->aStart.GetIndex()-1 ) // before StartNode
     997           0 :         DelNodes( aIdx, 1 );
     998             :     else
     999           0 :         new SwEndNode( pRange->aStart, *aIdx.GetNode().GetStartNode() );
    1000             : 
    1001             :     // If the end of a range is before or at a StartNode, so delete it,
    1002             :     // otherwise empty S/E or E/S nodes would be created.
    1003             :     // For other nodes, insert a new end node.
    1004           0 :     SwNodeIndex aTmpIdx( pRange->aEnd );
    1005           0 :     if( pRange->aEnd.GetNode().IsEndNode() )
    1006           0 :         DelNodes( pRange->aEnd, 1 );
    1007             :     else
    1008             :     {
    1009           0 :         pAktNode = new SwStartNode( pRange->aEnd );
    1010             : /*?? which NodeType ??*/
    1011           0 :         aTmpIdx = *pRange->aEnd.GetNode().EndOfSectionNode();
    1012           0 :         pRange->aEnd--;
    1013             :     }
    1014             : 
    1015           0 :     SectionUpDown( aIdx, aTmpIdx );
    1016             : }
    1017             : 
    1018             : /** correct indices after movement
    1019             :  *
    1020             :  * Update all indices after movement so that the levels are consistent again.
    1021             :  *
    1022             :  * @param aStart index of the start node
    1023             :  * @param aEnd index of the end point
    1024             :  *
    1025             :  * @see SwNodes::SectionUp
    1026             :  * @see SwNodes::SectionDown
    1027             :  */
    1028           0 : void SwNodes::SectionUpDown( const SwNodeIndex & aStart, const SwNodeIndex & aEnd )
    1029             : {
    1030             :     SwNode * pAktNode;
    1031           0 :     SwNodeIndex aTmpIdx( aStart, +1 );
    1032             :     // array forms a stack, holding all StartOfSelections
    1033           0 :     SwSttNdPtrs aSttNdStack;
    1034           0 :     SwStartNode* pTmp = aStart.GetNode().GetStartNode();
    1035           0 :     aSttNdStack.push_back( pTmp );
    1036             : 
    1037             :     // loop until the first start node that needs to be change was found
    1038             :     // (the indices are updated from the end node backwards to the start)
    1039           0 :     for( ;; ++aTmpIdx )
    1040             :     {
    1041           0 :         pAktNode = &aTmpIdx.GetNode();
    1042           0 :         pAktNode->pStartOfSection = aSttNdStack[ aSttNdStack.size()-1 ];
    1043             : 
    1044           0 :         if( pAktNode->GetStartNode() )
    1045             :         {
    1046           0 :             pTmp = (SwStartNode*)pAktNode;
    1047           0 :             aSttNdStack.push_back( pTmp );
    1048             :         }
    1049           0 :         else if( pAktNode->GetEndNode() )
    1050             :         {
    1051           0 :             SwStartNode* pSttNd = aSttNdStack[ aSttNdStack.size() - 1 ];
    1052           0 :             pSttNd->pEndOfSection = (SwEndNode*)pAktNode;
    1053           0 :             aSttNdStack.pop_back();
    1054           0 :             if( !aSttNdStack.empty() )
    1055           0 :                 continue; // still enough EndNodes on the stack
    1056             : 
    1057           0 :             else if( aTmpIdx < aEnd ) // too many StartNodes
    1058             :                 // if the end is not reached, yet, get the start of the section above
    1059             :             {
    1060           0 :                 aSttNdStack.insert( aSttNdStack.begin(), pSttNd->pStartOfSection );
    1061             :             }
    1062             :             else // finished, as soon as out of the range
    1063           0 :                 break;
    1064             :         }
    1065           0 :     }
    1066           0 : }
    1067             : 
    1068             : /** delete nodes
    1069             :  *
    1070             :  * This is a specific implementation of a delete function for a variable array.
    1071             :  * It is necessary as there might be inconsistencies after deleting start or
    1072             :  * end nodes. This method can clean those up.
    1073             :  *
    1074             :  * @param rIndex position to delete at (unchanged afterwards)
    1075             :  * @param nNodes number of nodes to delete (default: 1)
    1076             :  */
    1077           0 : void SwNodes::Delete(const SwNodeIndex &rIndex, sal_uLong nNodes)
    1078             : {
    1079           0 :     sal_uInt16 nLevel = 0; // level counter
    1080             :     SwNode * pAktNode;
    1081             : 
    1082           0 :     sal_uLong nCnt = Count() - rIndex.GetIndex() - 1;
    1083           0 :     if( nCnt > nNodes ) nCnt = nNodes;
    1084             : 
    1085           0 :     if( nCnt == 0 ) // no count -> return
    1086           0 :         return;
    1087             : 
    1088           0 :     SwNodeRange aRg( rIndex, 0, rIndex, nCnt-1 );
    1089             :     // check if [rIndex..rIndex + nCnt] is larger than the range
    1090           0 :     if( ( !aRg.aStart.GetNode().StartOfSectionIndex() &&
    1091           0 :             !aRg.aStart.GetIndex() ) ||
    1092           0 :             ! CheckNodesRange( aRg.aStart, aRg.aEnd ) )
    1093           0 :         return;
    1094             : 
    1095             :     // if aEnd is not on a ContentNode, search the previous one
    1096           0 :     while( ( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() ||
    1097           0 :              ( pAktNode->GetEndNode() &&
    1098           0 :                 !pAktNode->pStartOfSection->IsTableNode() ))
    1099           0 :         aRg.aEnd--;
    1100             : 
    1101           0 :     nCnt = 0;
    1102             : //TODO: check/improve comment
    1103             :     // increase start so that we are able to use "<" (using "<=" might cause
    1104             :     // problems if aEnd == aStart and aEnd is deleted, so aEnd <= aStart)
    1105           0 :     aRg.aStart--;
    1106             : 
    1107           0 :     sal_Bool bSaveInNodesDel = bInNodesDel;
    1108           0 :     bInNodesDel = sal_True;
    1109           0 :     bool bUpdateOutline = false;
    1110             : 
    1111             :     // loop until everything is deleted
    1112           0 :     while( aRg.aStart < aRg.aEnd )
    1113             :     {
    1114           0 :         pAktNode = &aRg.aEnd.GetNode();
    1115             : 
    1116           0 :         if( pAktNode->GetEndNode() )
    1117             :         {
    1118             :             // delete the whole section?
    1119           0 :             if( pAktNode->StartOfSectionIndex() > aRg.aStart.GetIndex() )
    1120             :             {
    1121           0 :                 SwTableNode* pTblNd = pAktNode->pStartOfSection->GetTableNode();
    1122           0 :                 if( pTblNd )
    1123           0 :                     pTblNd->DelFrms();
    1124             : 
    1125           0 :                 SwNode *pNd, *pChkNd = pAktNode->pStartOfSection;
    1126             :                 sal_uInt16 nIdxPos;
    1127           0 :                 do {
    1128           0 :                     pNd = &aRg.aEnd.GetNode();
    1129             : 
    1130           0 :                     if( pNd->IsTxtNode() )
    1131             :                     {
    1132           0 :                         SwTxtNode *const pTxtNode(static_cast<SwTxtNode*>(pNd));
    1133           0 :                         if (pTxtNode->IsOutline() &&
    1134           0 :                                 pOutlineNds->Seek_Entry( pNd, &nIdxPos ))
    1135             :                         {
    1136             :                             // remove outline indices
    1137           0 :                             pOutlineNds->erase(nIdxPos);
    1138           0 :                             bUpdateOutline = true;
    1139             :                         }
    1140           0 :                         pTxtNode->InvalidateNumRule();
    1141             :                     }
    1142           0 :                     else if( pNd->IsEndNode() &&
    1143           0 :                             pNd->pStartOfSection->IsTableNode() )
    1144           0 :                         ((SwTableNode*)pNd->pStartOfSection)->DelFrms();
    1145             : 
    1146           0 :                     aRg.aEnd--;
    1147           0 :                     nCnt++;
    1148             : 
    1149           0 :                 } while( pNd != pChkNd );
    1150             :             }
    1151             :             else
    1152             :             {
    1153           0 :                 RemoveNode( aRg.aEnd.GetIndex()+1, nCnt, sal_True ); // delete
    1154           0 :                 nCnt = 0;
    1155           0 :                 aRg.aEnd--; // before the EndNode
    1156           0 :                 nLevel++;
    1157             :             }
    1158             :         }
    1159           0 :         else if( pAktNode->GetStartNode() ) // found StartNode
    1160             :         {
    1161           0 :             if( nLevel == 0 ) // decrease one level
    1162             :             {
    1163           0 :                 if( nCnt )
    1164             :                 {
    1165             :                     // now delete array
    1166           0 :                     aRg.aEnd++;
    1167           0 :                     RemoveNode( aRg.aEnd.GetIndex(), nCnt, sal_True );
    1168           0 :                     nCnt = 0;
    1169             :                 }
    1170             :             }
    1171             :             else // remove all nodes between start and end node (incl. both)
    1172             :             {
    1173           0 :                 RemoveNode( aRg.aEnd.GetIndex(), nCnt + 2, sal_True ); // delete array
    1174           0 :                 nCnt = 0;
    1175           0 :                 nLevel--;
    1176             :             }
    1177             : 
    1178             :             // after deletion, aEnd might point to a EndNode...
    1179             :             // delete all empty start/end node pairs
    1180           0 :             SwNode* pTmpNode = aRg.aEnd.GetNode().GetEndNode();
    1181           0 :             aRg.aEnd--;
    1182           0 :             while(  pTmpNode &&
    1183           0 :                     ( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() &&
    1184           0 :                     pAktNode->StartOfSectionIndex() )
    1185             :             {
    1186             :                 // remove end and start node
    1187           0 :                 DelNodes( aRg.aEnd, 2 );
    1188           0 :                 pTmpNode = aRg.aEnd.GetNode().GetEndNode();
    1189           0 :                 aRg.aEnd--;
    1190             :             }
    1191             :         }
    1192             :         else // "normal" node, so insert into TmpArray
    1193             :         {
    1194           0 :             SwTxtNode* pTxtNd = pAktNode->GetTxtNode();
    1195           0 :             if( pTxtNd )
    1196             :             {
    1197           0 :                 if( pTxtNd->IsOutline())
    1198             :                 {
    1199             :                     // delete outline indices
    1200           0 :                     pOutlineNds->erase( pTxtNd );
    1201           0 :                     bUpdateOutline = true;
    1202             :                 }
    1203           0 :                 pTxtNd->InvalidateNumRule();
    1204             :             }
    1205           0 :             else if( pAktNode->IsCntntNode() )
    1206           0 :                 ((SwCntntNode*)pAktNode)->InvalidateNumRule();
    1207             : 
    1208           0 :             aRg.aEnd--;
    1209           0 :             nCnt++;
    1210             :         }
    1211             :     }
    1212             : 
    1213           0 :     aRg.aEnd++;
    1214           0 :     if( nCnt != 0 )
    1215           0 :         RemoveNode( aRg.aEnd.GetIndex(), nCnt, sal_True ); // delete the rest
    1216             : 
    1217             :     // delete all empty start/end node pairs
    1218           0 :     while( aRg.aEnd.GetNode().GetEndNode() &&
    1219           0 :             ( pAktNode = &aRg.aStart.GetNode())->GetStartNode() &&
    1220           0 :             pAktNode->StartOfSectionIndex() )
    1221             :     // but none of the holy 5. (???)
    1222             :     {
    1223           0 :         DelNodes( aRg.aStart, 2 );  // delete start and end node
    1224           0 :         aRg.aStart--;
    1225             :     }
    1226             : 
    1227           0 :     bInNodesDel = bSaveInNodesDel;
    1228             : 
    1229           0 :     if( !bInNodesDel )
    1230             :     {
    1231             :         // update numbering
    1232           0 :         if( bUpdateOutline || bInDelUpdOutl )
    1233             :         {
    1234           0 :             UpdtOutlineIdx( aRg.aEnd.GetNode() );
    1235           0 :             bInDelUpdOutl = sal_False;
    1236             :         }
    1237             : 
    1238             :     }
    1239             :     else
    1240             :     {
    1241           0 :         if( bUpdateOutline )
    1242           0 :             bInDelUpdOutl = sal_True;
    1243           0 :     }
    1244             : }
    1245             : 
    1246             : /** get section level at the given position
    1247             :  *
    1248             :  * @note The first node in an array should always be a start node.
    1249             :  *       Because of this, there is a special treatment here based on the
    1250             :  *       assumption that this is true in this context as well.
    1251             :  *
    1252             :  * @param rIdx position of the node
    1253             :  * @return section level at the given position
    1254             :  */
    1255           0 : sal_uInt16 SwNodes::GetSectionLevel(const SwNodeIndex &rIdx) const {
    1256             :     // special treatment for 1st Node
    1257           0 :     if(rIdx == 0) return 1;
    1258             :     // no recursion! This calles a SwNode::GetSectionLevel (missing "s")
    1259           0 :     return rIdx.GetNode().GetSectionLevel();
    1260             : }
    1261             : 
    1262           0 : void SwNodes::GoStartOfSection(SwNodeIndex *pIdx) const
    1263             : {
    1264             :     // after the next start node
    1265           0 :     SwNodeIndex aTmp( *pIdx->GetNode().StartOfSectionNode(), +1 );
    1266             : 
    1267             :     // If index points to no ContentNode, than go to one.
    1268             :     // If there is no further available, do not change the index' position!
    1269           0 :     while( !aTmp.GetNode().IsCntntNode() )
    1270             :     {   // go from this StartNode (can only be one) to its end
    1271           0 :         if( *pIdx <= aTmp )
    1272           0 :             return;     // ERROR: already after the section
    1273           0 :         aTmp = aTmp.GetNode().EndOfSectionIndex()+1;
    1274           0 :         if( *pIdx <= aTmp )
    1275           0 :             return;     // ERROR: already after the section
    1276             :     }
    1277           0 :     (*pIdx) = aTmp;     // is on a ContentNode
    1278             : }
    1279             : 
    1280           0 : void SwNodes::GoEndOfSection(SwNodeIndex *pIdx) const
    1281             : {
    1282           0 :     if( !pIdx->GetNode().IsEndNode() )
    1283           0 :         (*pIdx) = *pIdx->GetNode().EndOfSectionNode();
    1284           0 : }
    1285             : 
    1286           0 : SwCntntNode* SwNodes::GoNext(SwNodeIndex *pIdx) const
    1287             : {
    1288           0 :     if( pIdx->GetIndex() >= Count() - 1 )
    1289           0 :         return 0;
    1290             : 
    1291           0 :     SwNodeIndex aTmp(*pIdx, +1);
    1292           0 :     SwNode* pNd = 0;
    1293           0 :     while( aTmp < Count()-1 && 0 == ( pNd = &aTmp.GetNode())->IsCntntNode() )
    1294           0 :         ++aTmp;
    1295             : 
    1296           0 :     if( aTmp == Count()-1 )
    1297           0 :         pNd = 0;
    1298             :     else
    1299           0 :         (*pIdx) = aTmp;
    1300           0 :     return (SwCntntNode*)pNd;
    1301             : }
    1302             : 
    1303           0 : SwCntntNode* SwNodes::GoPrevious(SwNodeIndex *pIdx) const
    1304             : {
    1305           0 :     if( !pIdx->GetIndex() )
    1306           0 :         return 0;
    1307             : 
    1308           0 :     SwNodeIndex aTmp( *pIdx, -1 );
    1309           0 :     SwNode* pNd = 0;
    1310           0 :     while( aTmp.GetIndex() && 0 == ( pNd = &aTmp.GetNode())->IsCntntNode() )
    1311           0 :         aTmp--;
    1312             : 
    1313           0 :     if( !aTmp.GetIndex() )
    1314           0 :         pNd = 0;
    1315             :     else
    1316           0 :         (*pIdx) = aTmp;
    1317           0 :     return (SwCntntNode*)pNd;
    1318             : }
    1319             : 
    1320           0 : inline bool TstIdx( sal_uLong nSttIdx, sal_uLong nEndIdx, sal_uLong nStt, sal_uLong nEnd )
    1321             : {
    1322           0 :     return nStt < nSttIdx && nEnd >= nSttIdx &&
    1323           0 :             nStt < nEndIdx && nEnd >= nEndIdx;
    1324             : }
    1325             : 
    1326             : /** Check if the given range is inside the defined ranges
    1327             :  *
    1328             :  * The defined ranges are Content, AutoText, PostIts, Inserts, and Redlines.
    1329             :  *
    1330             :  * @param rStt start index of the range
    1331             :  * @param rEnd end index of the range
    1332             :  * @return <true> if valid range
    1333             :  */
    1334           0 : sal_Bool SwNodes::CheckNodesRange( const SwNodeIndex& rStt, const SwNodeIndex& rEnd ) const
    1335             : {
    1336           0 :     sal_uLong nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
    1337           0 :     if( TstIdx( nStt, nEnd, pEndOfContent->StartOfSectionIndex(),
    1338           0 :                 pEndOfContent->GetIndex() )) return sal_True;
    1339           0 :     if( TstIdx( nStt, nEnd, pEndOfAutotext->StartOfSectionIndex(),
    1340           0 :                 pEndOfAutotext->GetIndex() )) return sal_True;
    1341           0 :     if( TstIdx( nStt, nEnd, pEndOfPostIts->StartOfSectionIndex(),
    1342           0 :                 pEndOfPostIts->GetIndex() )) return sal_True;
    1343           0 :     if( TstIdx( nStt, nEnd, pEndOfInserts->StartOfSectionIndex(),
    1344           0 :                 pEndOfInserts->GetIndex() )) return sal_True;
    1345           0 :     if( TstIdx( nStt, nEnd, pEndOfRedlines->StartOfSectionIndex(),
    1346           0 :                 pEndOfRedlines->GetIndex() )) return sal_True;
    1347             : 
    1348           0 :     return sal_False;       // is somewhere in the middle, ERROR
    1349             : }
    1350             : 
    1351             : /** Delete a number of nodes
    1352             :  *
    1353             :  * @param rStart starting position in this nodes array
    1354             :  * @param nCnt number of nodes to delete
    1355             :  */
    1356           0 : void SwNodes::DelNodes( const SwNodeIndex & rStart, sal_uLong nCnt )
    1357             : {
    1358           0 :     sal_uLong nSttIdx = rStart.GetIndex();
    1359             : 
    1360           0 :     if( !nSttIdx && nCnt == GetEndOfContent().GetIndex()+1 )
    1361             :     {
    1362             :         // The whole nodes array will be destroyed, you're in the Doc's DTOR!
    1363             :         // The initial start/end nodes should be only destroyed in the SwNodes' DTOR!
    1364             :         SwNode* aEndNdArr[] = { pEndOfContent,
    1365             :                                 pEndOfPostIts, pEndOfInserts,
    1366             :                                 pEndOfAutotext, pEndOfRedlines,
    1367             :                                 0
    1368           0 :                               };
    1369             : 
    1370           0 :         SwNode** ppEndNdArr = aEndNdArr;
    1371           0 :         while( *ppEndNdArr )
    1372             :         {
    1373           0 :             nSttIdx = (*ppEndNdArr)->StartOfSectionIndex() + 1;
    1374           0 :             sal_uLong nEndIdx = (*ppEndNdArr)->GetIndex();
    1375             : 
    1376           0 :             if( nSttIdx != nEndIdx )
    1377           0 :                 RemoveNode( nSttIdx, nEndIdx - nSttIdx, sal_True );
    1378             : 
    1379           0 :             ++ppEndNdArr;
    1380             :         }
    1381             :     }
    1382             :     else
    1383             :     {
    1384           0 :         int bUpdateNum = 0;
    1385           0 :         for( sal_uLong n = nSttIdx, nEnd = nSttIdx + nCnt; n < nEnd; ++n )
    1386             :         {
    1387           0 :             SwNode* pNd = (*this)[ n ];
    1388             : 
    1389           0 :             if (pNd->IsTxtNode() && static_cast<SwTxtNode*>(pNd)->IsOutline())
    1390             :             {
    1391             :                 // remove the outline indices
    1392             :                 sal_uInt16 nIdxPos;
    1393           0 :                 if( pOutlineNds->Seek_Entry( pNd, &nIdxPos ))
    1394             :                 {
    1395           0 :                     pOutlineNds->erase(nIdxPos);
    1396           0 :                     bUpdateNum = 1;
    1397             :                 }
    1398             :             }
    1399           0 :             if( pNd->IsCntntNode() )
    1400             :             {
    1401           0 :                 ((SwCntntNode*)pNd)->InvalidateNumRule();
    1402           0 :                 ((SwCntntNode*)pNd)->DelFrms();
    1403             :             }
    1404             :         }
    1405           0 :         RemoveNode( nSttIdx, nCnt, sal_True );
    1406             : 
    1407             :         // update numbering
    1408           0 :         if( bUpdateNum )
    1409           0 :             UpdtOutlineIdx( rStart.GetNode() );
    1410             :     }
    1411           0 : }
    1412             : 
    1413             : struct HighLevel
    1414             : {
    1415             :     sal_uInt16 nLevel, nTop;
    1416           0 :     HighLevel( sal_uInt16 nLv ) : nLevel( nLv ), nTop( nLv ) {}
    1417             : 
    1418             : };
    1419             : 
    1420           0 : static bool lcl_HighestLevel( const SwNodePtr& rpNode, void * pPara )
    1421             : {
    1422           0 :     HighLevel * pHL = (HighLevel*)pPara;
    1423           0 :     if( rpNode->GetStartNode() )
    1424           0 :         pHL->nLevel++;
    1425           0 :     else if( rpNode->GetEndNode() )
    1426           0 :         pHL->nLevel--;
    1427           0 :     if( pHL->nTop > pHL->nLevel )
    1428           0 :         pHL->nTop = pHL->nLevel;
    1429           0 :     return true;
    1430             : 
    1431             : }
    1432             : 
    1433             : /** Calculate the highest level in a range
    1434             :  *
    1435             :  * @param rNodes the nodes array
    1436             :  * @param rRange the range to inspect
    1437             :  * @return the highest level
    1438             :  */
    1439           0 : sal_uInt16 HighestLevel( SwNodes & rNodes, const SwNodeRange & rRange )
    1440             : {
    1441           0 :     HighLevel aPara( rNodes.GetSectionLevel( rRange.aStart ));
    1442           0 :     rNodes.ForEach( rRange.aStart, rRange.aEnd, lcl_HighestLevel, &aPara );
    1443           0 :     return aPara.nTop;
    1444             : 
    1445             : }
    1446             : 
    1447             : /** move a range
    1448             :  *
    1449             :  * @param rPam the range to move
    1450             :  * @param rPos to destination position in the given nodes array
    1451             :  * @param rNodes the node array to move the range into
    1452             :  */
    1453           0 : void SwNodes::MoveRange( SwPaM & rPam, SwPosition & rPos, SwNodes& rNodes )
    1454             : {
    1455           0 :     SwPosition * const pStt = rPam.Start();
    1456           0 :     SwPosition * const pEnd = rPam.End();
    1457             : 
    1458           0 :     if( !rPam.HasMark() || *pStt >= *pEnd )
    1459           0 :         return;
    1460             : 
    1461           0 :     if( this == &rNodes && *pStt <= rPos && rPos < *pEnd )
    1462           0 :         return;
    1463             : 
    1464           0 :     SwNodeIndex aEndIdx( pEnd->nNode );
    1465           0 :     SwNodeIndex aSttIdx( pStt->nNode );
    1466           0 :     SwTxtNode *const pSrcNd = aSttIdx.GetNode().GetTxtNode();
    1467           0 :     SwTxtNode * pDestNd = rPos.nNode.GetNode().GetTxtNode();
    1468           0 :     bool bSplitDestNd = true;
    1469           0 :     bool bCopyCollFmt = pDestNd && pDestNd->GetTxt().isEmpty();
    1470             : 
    1471           0 :     if( pSrcNd )
    1472             :     {
    1473             :         // if the first node is a TextNode, than there must
    1474             :         // be also a TextNode in the NodesArray to store the content
    1475           0 :         if( !pDestNd )
    1476             :         {
    1477           0 :             pDestNd = rNodes.MakeTxtNode( rPos.nNode, pSrcNd->GetTxtColl() );
    1478           0 :             rPos.nNode--;
    1479           0 :             rPos.nContent.Assign( pDestNd, 0 );
    1480           0 :             bCopyCollFmt = true;
    1481             :         }
    1482           0 :         bSplitDestNd = pDestNd->Len() > rPos.nContent.GetIndex() ||
    1483           0 :                         pEnd->nNode.GetNode().IsTxtNode();
    1484             : 
    1485             :         // move the content into the new node
    1486           0 :         bool bOneNd = pStt->nNode == pEnd->nNode;
    1487             :         const sal_Int32 nLen =
    1488           0 :                 ( (bOneNd) ? pEnd->nContent.GetIndex() : pSrcNd->Len() )
    1489           0 :                 - pStt->nContent.GetIndex();
    1490             : 
    1491           0 :         if( !pEnd->nNode.GetNode().IsCntntNode() )
    1492             :         {
    1493           0 :             bOneNd = true;
    1494           0 :             sal_uLong nSttNdIdx = pStt->nNode.GetIndex() + 1;
    1495           0 :             const sal_uLong nEndNdIdx = pEnd->nNode.GetIndex();
    1496           0 :             for( ; nSttNdIdx < nEndNdIdx; ++nSttNdIdx )
    1497             :             {
    1498           0 :                 if( (*this)[ nSttNdIdx ]->IsCntntNode() )
    1499             :                 {
    1500           0 :                     bOneNd = false;
    1501           0 :                     break;
    1502             :                 }
    1503             :             }
    1504             :         }
    1505             : 
    1506             :         // templates must be copied/set after a split
    1507           0 :         if( !bOneNd && bSplitDestNd )
    1508             :         {
    1509           0 :             if( !rPos.nContent.GetIndex() )
    1510             :             {
    1511           0 :                 bCopyCollFmt = true;
    1512             :             }
    1513           0 :             if( rNodes.IsDocNodes() )
    1514             :             {
    1515           0 :                 SwDoc* const pInsDoc = pDestNd->GetDoc();
    1516           0 :                 ::sw::UndoGuard const ug(pInsDoc->GetIDocumentUndoRedo());
    1517           0 :                 pInsDoc->SplitNode( rPos, false );
    1518             :             }
    1519             :             else
    1520             :             {
    1521           0 :                 pDestNd->SplitCntntNode( rPos );
    1522             :             }
    1523             : 
    1524           0 :             if( rPos.nNode == aEndIdx )
    1525             :             {
    1526           0 :                 aEndIdx--;
    1527             :             }
    1528           0 :             bSplitDestNd = true;
    1529             : 
    1530           0 :             pDestNd = rNodes[ rPos.nNode.GetIndex() - 1 ]->GetTxtNode();
    1531           0 :             if( nLen )
    1532             :             {
    1533           0 :                 pSrcNd->CutText( pDestNd, SwIndex( pDestNd, pDestNd->Len()),
    1534           0 :                             pStt->nContent, nLen );
    1535           0 :             }
    1536             :         }
    1537           0 :         else if ( nLen )
    1538             :         {
    1539           0 :             pSrcNd->CutText( pDestNd, rPos.nContent, pStt->nContent, nLen );
    1540             :         }
    1541             : 
    1542           0 :         if( bCopyCollFmt )
    1543             :         {
    1544           0 :             SwDoc* const pInsDoc = pDestNd->GetDoc();
    1545           0 :             ::sw::UndoGuard const undoGuard(pInsDoc->GetIDocumentUndoRedo());
    1546           0 :             pSrcNd->CopyCollFmt( *pDestNd );
    1547           0 :             bCopyCollFmt = false;
    1548             :         }
    1549             : 
    1550           0 :         if( bOneNd )
    1551             :         {
    1552             :             // Correct the PaM, because it might have happened that the move
    1553             :             // went over the node borders (so the data might be in different nodes).
    1554             :             // Also, a selection is invalidated.
    1555           0 :             pEnd->nContent = pStt->nContent;
    1556           0 :             rPam.DeleteMark();
    1557           0 :             GetDoc()->GetDocShell()->Broadcast( SwFmtFldHint( 0,
    1558           0 :                 rNodes.IsDocNodes() ? SWFMTFLD_INSERTED : SWFMTFLD_REMOVED ) );
    1559           0 :             return;
    1560             :         }
    1561             : 
    1562           0 :         ++aSttIdx;
    1563             :     }
    1564           0 :     else if( pDestNd )
    1565             :     {
    1566           0 :         if( rPos.nContent.GetIndex() )
    1567             :         {
    1568           0 :             if( rPos.nContent.GetIndex() == pDestNd->Len() )
    1569             :             {
    1570           0 :                 rPos.nNode++;
    1571             :             }
    1572           0 :             else if( rPos.nContent.GetIndex() )
    1573             :             {
    1574             :                 // if the EndNode is split than correct the EndIdx
    1575           0 :                 const bool bCorrEnd = aEndIdx == rPos.nNode;
    1576             : 
    1577             :                 // if no text is attached to the TextNode, split it
    1578           0 :                 if( rNodes.IsDocNodes() )
    1579             :                 {
    1580           0 :                     SwDoc* const pInsDoc = pDestNd->GetDoc();
    1581           0 :                     ::sw::UndoGuard const ug(pInsDoc->GetIDocumentUndoRedo());
    1582           0 :                     pInsDoc->SplitNode( rPos, false );
    1583             :                 }
    1584             :                 else
    1585             :                 {
    1586           0 :                     pDestNd->SplitCntntNode( rPos );
    1587             :                 }
    1588             : 
    1589           0 :                 pDestNd = rPos.nNode.GetNode().GetTxtNode();
    1590             : 
    1591           0 :                 if ( bCorrEnd )
    1592             :                 {
    1593           0 :                     aEndIdx--;
    1594             :                 }
    1595             :             }
    1596             :         }
    1597             :         // at the end only an empty TextNode is left over
    1598           0 :         bSplitDestNd = true;
    1599             :     }
    1600             : 
    1601           0 :     SwTxtNode* const pEndSrcNd = aEndIdx.GetNode().GetTxtNode();
    1602           0 :     if ( pEndSrcNd )
    1603             :     {
    1604             :         {
    1605             :             // at the end of this range a new TextNode will be created
    1606           0 :             if( !bSplitDestNd )
    1607             :             {
    1608           0 :                 if( rPos.nNode < rNodes.GetEndOfContent().GetIndex() )
    1609             :                 {
    1610           0 :                     rPos.nNode++;
    1611             :                 }
    1612             : 
    1613             :                 pDestNd =
    1614           0 :                     rNodes.MakeTxtNode( rPos.nNode, pEndSrcNd->GetTxtColl() );
    1615           0 :                 rPos.nNode--;
    1616           0 :                 rPos.nContent.Assign( pDestNd, 0 );
    1617             :             }
    1618             :             else
    1619             :             {
    1620           0 :                 pDestNd = rPos.nNode.GetNode().GetTxtNode();
    1621             :             }
    1622             : 
    1623           0 :             if( pDestNd && pEnd->nContent.GetIndex() )
    1624             :             {
    1625             :                 // move the content into the new node
    1626           0 :                 SwIndex aIdx( pEndSrcNd, 0 );
    1627             :                 pEndSrcNd->CutText( pDestNd, rPos.nContent, aIdx,
    1628           0 :                                 pEnd->nContent.GetIndex());
    1629             :             }
    1630             : 
    1631           0 :             if( bCopyCollFmt )
    1632             :             {
    1633           0 :                 SwDoc* const pInsDoc = pDestNd->GetDoc();
    1634           0 :                 ::sw::UndoGuard const ug(pInsDoc->GetIDocumentUndoRedo());
    1635           0 :                 pEndSrcNd->CopyCollFmt( *pDestNd );
    1636             :             }
    1637             :         }
    1638             :     }
    1639             :     else
    1640             :     {
    1641           0 :         if ( pSrcNd && aEndIdx.GetNode().IsCntntNode() )
    1642             :         {
    1643           0 :             ++aEndIdx;
    1644             :         }
    1645           0 :         if( !bSplitDestNd )
    1646             :         {
    1647           0 :             rPos.nNode++;
    1648           0 :             rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), 0 );
    1649             :         }
    1650             :     }
    1651             : 
    1652           0 :     if( aEndIdx != aSttIdx )
    1653             :     {
    1654             :         // move the nodes into the NodesArary
    1655           0 :         const sal_uLong nSttDiff = aSttIdx.GetIndex() - pStt->nNode.GetIndex();
    1656           0 :         SwNodeRange aRg( aSttIdx, aEndIdx );
    1657           0 :         _MoveNodes( aRg, rNodes, rPos.nNode );
    1658             : 
    1659             :         // if in the same node array, all indices are now at new positions (so correct them)
    1660           0 :         if( &rNodes == this )
    1661             :         {
    1662           0 :             pStt->nNode = aRg.aEnd.GetIndex() - nSttDiff;
    1663           0 :         }
    1664             :     }
    1665             : 
    1666             :     // if the StartNode was moved to whom the the cursor pointed, so
    1667             :     // the content must be registered in the current content!
    1668           0 :     if ( &pStt->nNode.GetNode() == &GetEndOfContent() )
    1669             :     {
    1670           0 :         const bool bSuccess = GoPrevious( &pStt->nNode );
    1671             :         OSL_ENSURE( bSuccess, "Move() - no ContentNode here" );
    1672             :         (void) bSuccess;
    1673             :     }
    1674           0 :     pStt->nContent.Assign( pStt->nNode.GetNode().GetCntntNode(),
    1675           0 :                             pStt->nContent.GetIndex() );
    1676             :     // Correct the PaM, because it might have happened that the move
    1677             :     // went over the node borders (so the data might be in different nodes).
    1678             :     // Also, a selection is invalidated.
    1679           0 :     *pEnd = *pStt;
    1680           0 :     rPam.DeleteMark();
    1681           0 :     GetDoc()->GetDocShell()->Broadcast( SwFmtFldHint( 0,
    1682           0 :                 rNodes.IsDocNodes() ? SWFMTFLD_INSERTED : SWFMTFLD_REMOVED ) );
    1683             : }
    1684             : 
    1685             : ///@see SwNodes::_MoveNodes (TODO: seems to be C&P programming here)
    1686           0 : void SwNodes::_CopyNodes( const SwNodeRange& rRange,
    1687             :             const SwNodeIndex& rIndex, sal_Bool bNewFrms, sal_Bool bTblInsDummyNode ) const
    1688             : {
    1689           0 :     SwDoc* pDoc = rIndex.GetNode().GetDoc();
    1690             : 
    1691             :     SwNode * pAktNode;
    1692           0 :     if( rIndex == 0 ||
    1693           0 :         ( (pAktNode = &rIndex.GetNode())->GetStartNode() &&
    1694           0 :           !pAktNode->StartOfSectionIndex() ))
    1695           0 :         return;
    1696             : 
    1697           0 :     SwNodeRange aRg( rRange );
    1698             : 
    1699             :     // skip "simple" StartNodes or EndNodes
    1700           0 :     while( ND_STARTNODE == (pAktNode = & aRg.aStart.GetNode())->GetNodeType()
    1701           0 :             || ( pAktNode->IsEndNode() &&
    1702           0 :                 !pAktNode->pStartOfSection->IsSectionNode() ) )
    1703           0 :         aRg.aStart++;
    1704             : 
    1705             :     // if aEnd-1 points to no ContentNode, search previous one
    1706           0 :     aRg.aEnd--;
    1707             :     // #i107142#: if aEnd is start node of a special section, do nothing.
    1708             :     // Otherwise this could lead to crash: going through all previous
    1709             :     // special section nodes and then one before the first.
    1710           0 :     if (aRg.aEnd.GetNode().StartOfSectionIndex() != 0)
    1711             :     {
    1712           0 :         while( ((pAktNode = & aRg.aEnd.GetNode())->GetStartNode() &&
    1713           0 :                 !pAktNode->IsSectionNode() ) ||
    1714           0 :                 ( pAktNode->IsEndNode() &&
    1715           0 :                 ND_STARTNODE == pAktNode->pStartOfSection->GetNodeType()) )
    1716             :         {
    1717           0 :             aRg.aEnd--;
    1718             :         }
    1719             :     }
    1720           0 :     aRg.aEnd++;
    1721             : 
    1722             :     // if in same array, check insertion position
    1723           0 :     if( aRg.aStart >= aRg.aEnd )
    1724           0 :         return;
    1725             : 
    1726             :     // when inserting into the source range, nothing need to be done
    1727             :     OSL_ENSURE( &aRg.aStart.GetNodes() == this,
    1728             :                 "aRg should use thisnodes array" );
    1729             :     OSL_ENSURE( &aRg.aStart.GetNodes() == &aRg.aEnd.GetNodes(),
    1730             :                "Range across different nodes arrays? You deserve punishment!");
    1731           0 :     if( &rIndex.GetNodes() == &aRg.aStart.GetNodes() &&
    1732           0 :         rIndex.GetIndex() >= aRg.aStart.GetIndex() &&
    1733           0 :         rIndex.GetIndex() < aRg.aEnd.GetIndex() )
    1734           0 :             return;
    1735             : 
    1736           0 :     SwNodeIndex aInsPos( rIndex );
    1737           0 :     SwNodeIndex aOrigInsPos( rIndex, -1 ); // original insertion position
    1738           0 :     sal_uInt16 nLevel = 0;                 // level counter
    1739             : 
    1740           0 :     for( sal_uLong nNodeCnt = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex();
    1741             :             nNodeCnt > 0; --nNodeCnt )
    1742             :     {
    1743           0 :         pAktNode = &aRg.aStart.GetNode();
    1744           0 :         switch( pAktNode->GetNodeType() )
    1745             :         {
    1746             :         case ND_TABLENODE:
    1747             :             // Does it copy a table in(to) a footnote?
    1748           0 :             if( aInsPos < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
    1749           0 :                     pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex()
    1750           0 :                     < aInsPos.GetIndex() )
    1751             :             {
    1752             :                 sal_uLong nDistance =
    1753           0 :                     ( pAktNode->EndOfSectionIndex() -
    1754           0 :                         aRg.aStart.GetIndex() );
    1755           0 :                 if (nDistance < nNodeCnt)
    1756           0 :                     nNodeCnt -= nDistance;
    1757             :                 else
    1758           0 :                     nNodeCnt = 1;
    1759             : 
    1760             :                 // insert a DummyNode for a TableNode
    1761           0 :                 if( bTblInsDummyNode )
    1762           0 :                     new SwDummySectionNode( aInsPos );
    1763             : 
    1764             :                 // copy all of the table's nodes into the current cell
    1765           0 :                 for( aRg.aStart++; aRg.aStart.GetIndex() <
    1766           0 :                     pAktNode->EndOfSectionIndex();
    1767             :                     aRg.aStart++ )
    1768             :                 {
    1769             :                     // insert a DummyNode for the box-StartNode?
    1770           0 :                     if( bTblInsDummyNode )
    1771           0 :                         new SwDummySectionNode( aInsPos );
    1772             : 
    1773           0 :                     SwStartNode* pSttNd = aRg.aStart.GetNode().GetStartNode();
    1774             :                     _CopyNodes( SwNodeRange( *pSttNd, + 1,
    1775           0 :                                             *pSttNd->EndOfSectionNode() ),
    1776           0 :                                 aInsPos, bNewFrms, sal_False );
    1777             : 
    1778             :                     // insert a DummyNode for the box-EndNode?
    1779           0 :                     if( bTblInsDummyNode )
    1780           0 :                         new SwDummySectionNode( aInsPos );
    1781           0 :                     aRg.aStart = *pSttNd->EndOfSectionNode();
    1782             :                 }
    1783             :                 // insert a DummyNode for the table-EndNode
    1784           0 :                 if( bTblInsDummyNode )
    1785           0 :                     new SwDummySectionNode( aInsPos );
    1786           0 :                 aRg.aStart = *pAktNode->EndOfSectionNode();
    1787             :             }
    1788             :             else
    1789             :             {
    1790           0 :                 SwNodeIndex nStt( aInsPos, -1 );
    1791             :                 SwTableNode* pTblNd = ((SwTableNode*)pAktNode)->
    1792           0 :                                         MakeCopy( pDoc, aInsPos );
    1793           0 :                 sal_uLong nDistance = aInsPos.GetIndex() - nStt.GetIndex() - 2;
    1794           0 :                 if (nDistance < nNodeCnt)
    1795           0 :                     nNodeCnt -= nDistance;
    1796             :                 else
    1797           0 :                     nNodeCnt = 1;
    1798             : 
    1799           0 :                 aRg.aStart = pAktNode->EndOfSectionIndex();
    1800             : 
    1801           0 :                 if( bNewFrms && pTblNd )
    1802             :                 {
    1803           0 :                     nStt = aInsPos;
    1804           0 :                     pTblNd->MakeFrms( &nStt );
    1805           0 :                 }
    1806             :             }
    1807           0 :             break;
    1808             : 
    1809             :         case ND_SECTIONNODE:
    1810             :             // If the end of the section is outside the copy range,
    1811             :             // the section node will skipped, not copied!
    1812             :             // If someone want to change this behaviour, he has to adjust the function
    1813             :             // lcl_NonCopyCount(..) in ndcopy.cxx which relies on it.
    1814           0 :             if( pAktNode->EndOfSectionIndex() < aRg.aEnd.GetIndex() )
    1815             :             {
    1816             :                 // copy of the whole section, so create a new SectionNode
    1817           0 :                 SwNodeIndex nStt( aInsPos, -1 );
    1818             :                 SwSectionNode* pSectNd = ((SwSectionNode*)pAktNode)->
    1819           0 :                                     MakeCopy( pDoc, aInsPos );
    1820             : 
    1821           0 :                 sal_uLong nDistance = aInsPos.GetIndex() - nStt.GetIndex() - 2;
    1822           0 :                 if (nDistance < nNodeCnt)
    1823           0 :                     nNodeCnt -= nDistance;
    1824             :                 else
    1825           0 :                     nNodeCnt = 1;
    1826           0 :                 aRg.aStart = pAktNode->EndOfSectionIndex();
    1827             : 
    1828           0 :                 if( bNewFrms && pSectNd &&
    1829           0 :                     !pSectNd->GetSection().IsHidden() )
    1830           0 :                     pSectNd->MakeFrms( &nStt );
    1831             :             }
    1832           0 :             break;
    1833             : 
    1834             :         case ND_STARTNODE:
    1835             :             {
    1836             :                 SwStartNode* pTmp = new SwStartNode( aInsPos, ND_STARTNODE,
    1837           0 :                             ((SwStartNode*)pAktNode)->GetStartNodeType() );
    1838           0 :                 new SwEndNode( aInsPos, *pTmp );
    1839           0 :                 aInsPos--;
    1840           0 :                 nLevel++;
    1841             :             }
    1842           0 :             break;
    1843             : 
    1844             :         case ND_ENDNODE:
    1845           0 :             if( nLevel ) // complete section
    1846             :             {
    1847           0 :                 --nLevel;
    1848           0 :                 ++aInsPos; // EndNode already exists
    1849             :             }
    1850           0 :             else if( !pAktNode->pStartOfSection->IsSectionNode() )
    1851             :             {
    1852             :                 // create a section at the original InsertPosition
    1853           0 :                 SwNodeRange aTmpRg( aOrigInsPos, 1, aInsPos );
    1854           0 :                 pDoc->GetNodes().SectionDown( &aTmpRg,
    1855           0 :                         pAktNode->pStartOfSection->GetStartNodeType() );
    1856             :             }
    1857           0 :             break;
    1858             : 
    1859             :         case ND_TEXTNODE:
    1860             :         case ND_GRFNODE:
    1861             :         case ND_OLENODE:
    1862             :             {
    1863           0 :                 SwCntntNode* pNew = ((SwCntntNode*)pAktNode)->MakeCopy(
    1864           0 :                                             pDoc, aInsPos );
    1865             :                 // frames are always created as default, so delete if needed
    1866           0 :                 if( !bNewFrms )
    1867           0 :                     pNew->DelFrms();
    1868             :             }
    1869           0 :             break;
    1870             : 
    1871             :         case ND_SECTIONDUMMY:
    1872           0 :             if (GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(*this))
    1873             :             {
    1874             :                 // than a SectionNode (start/end) is needed at the current
    1875             :                 // InsPos; if so skip it, otherwise ignore current node
    1876           0 :                 SwNode *const pTmpNd = & aInsPos.GetNode();
    1877           0 :                 if( pTmpNd->IsSectionNode() ||
    1878           0 :                     pTmpNd->StartOfSectionNode()->IsSectionNode() )
    1879           0 :                     ++aInsPos;  // skip
    1880             :             }
    1881             :             else {
    1882             :                 OSL_FAIL( "How can this node be in the node array?" );
    1883             :             }
    1884           0 :             break;
    1885             : 
    1886             :         default:
    1887             :             OSL_FAIL( "Unknown node type" );
    1888             :         }
    1889           0 :         aRg.aStart++;
    1890           0 :     }
    1891             : }
    1892             : 
    1893           0 : void SwNodes::_DelDummyNodes( const SwNodeRange& rRg )
    1894             : {
    1895           0 :     SwNodeIndex aIdx( rRg.aStart );
    1896           0 :     while( aIdx.GetIndex() < rRg.aEnd.GetIndex() )
    1897             :     {
    1898           0 :         if( ND_SECTIONDUMMY == aIdx.GetNode().GetNodeType() )
    1899           0 :             RemoveNode( aIdx.GetIndex(), 1, sal_True );
    1900             :         else
    1901           0 :             ++aIdx;
    1902           0 :     }
    1903           0 : }
    1904             : 
    1905           0 : SwStartNode* SwNodes::MakeEmptySection( const SwNodeIndex& rIdx,
    1906             :                                         SwStartNodeType eSttNdTyp )
    1907             : {
    1908           0 :     SwStartNode* pSttNd = new SwStartNode( rIdx, ND_STARTNODE, eSttNdTyp );
    1909           0 :     new SwEndNode( rIdx, *pSttNd );
    1910           0 :     return pSttNd;
    1911             : }
    1912             : 
    1913           0 : SwStartNode* SwNodes::MakeTextSection( const SwNodeIndex & rWhere,
    1914             :                                         SwStartNodeType eSttNdTyp,
    1915             :                                         SwTxtFmtColl *pColl,
    1916             :                                         SwAttrSet* pAutoAttr )
    1917             : {
    1918           0 :     SwStartNode* pSttNd = new SwStartNode( rWhere, ND_STARTNODE, eSttNdTyp );
    1919           0 :     new SwEndNode( rWhere, *pSttNd );
    1920           0 :     MakeTxtNode( SwNodeIndex( rWhere, - 1 ), pColl, pAutoAttr );
    1921           0 :     return pSttNd;
    1922             : }
    1923             : 
    1924             : //TODO: provide better documentation
    1925             : /** go to next section that is not protected nor hidden
    1926             :  *
    1927             :  * @note if !bSkipHidden and !bSkipProtect, use GoNext/GoPrevious
    1928             :  *
    1929             :  * @param pIdx
    1930             :  * @param bSkipHidden
    1931             :  * @param bSkipProtect
    1932             :  * @return
    1933             :  * @see SwNodes::GoNext
    1934             :  * @see SwNodes::GoPrevious
    1935             :  * @see SwNodes::GoNextSection (TODO: seems to be C&P programming here)
    1936             : */
    1937           0 : SwCntntNode* SwNodes::GoNextSection( SwNodeIndex * pIdx,
    1938             :                             bool bSkipHidden, bool bSkipProtect ) const
    1939             : {
    1940           0 :     bool bFirst = true;
    1941           0 :     SwNodeIndex aTmp( *pIdx );
    1942             :     const SwNode* pNd;
    1943           0 :     while( aTmp < Count() - 1 )
    1944             :     {
    1945           0 :         pNd = & aTmp.GetNode();
    1946           0 :         if (ND_SECTIONNODE == pNd->GetNodeType())
    1947             :         {
    1948           0 :             const SwSection& rSect = ((SwSectionNode*)pNd)->GetSection();
    1949           0 :             if( (bSkipHidden && rSect.IsHiddenFlag()) ||
    1950           0 :                 (bSkipProtect && rSect.IsProtectFlag()) )
    1951             :                 // than skip the section
    1952           0 :                 aTmp = *pNd->EndOfSectionNode();
    1953           0 :             bFirst = false;
    1954             :         }
    1955           0 :         else if( bFirst )
    1956             :         {
    1957           0 :             bFirst = false;
    1958           0 :             if( pNd->pStartOfSection->IsSectionNode() )
    1959             :             {
    1960             :                 const SwSection& rSect = ((SwSectionNode*)pNd->
    1961           0 :                                 pStartOfSection)->GetSection();
    1962           0 :                 if( (bSkipHidden && rSect.IsHiddenFlag()) ||
    1963           0 :                     (bSkipProtect && rSect.IsProtectFlag()) )
    1964             :                     // than skip the section
    1965           0 :                     aTmp = *pNd->EndOfSectionNode();
    1966             :             }
    1967             :         }
    1968           0 :         else if( ND_CONTENTNODE & pNd->GetNodeType() )
    1969             :         {
    1970             :             const SwSectionNode* pSectNd;
    1971           0 :             if( ( bSkipHidden || bSkipProtect ) &&
    1972           0 :                 0 != (pSectNd = pNd->FindSectionNode() ) &&
    1973           0 :                 ( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) ||
    1974           0 :                   ( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) )
    1975             :             {
    1976           0 :                 aTmp = *pSectNd->EndOfSectionNode();
    1977             :             }
    1978             :             else
    1979             :             {
    1980           0 :                 (*pIdx) = aTmp;
    1981           0 :                 return (SwCntntNode*)pNd;
    1982             :             }
    1983             :         }
    1984           0 :         ++aTmp;
    1985           0 :         bFirst = false;
    1986             :     }
    1987           0 :     return 0;
    1988             : }
    1989             : 
    1990             : ///@see SwNodes::GoNextSection (TODO: seems to be C&P programming here)
    1991           0 : SwCntntNode* SwNodes::GoPrevSection( SwNodeIndex * pIdx,
    1992             :                             bool bSkipHidden, bool bSkipProtect ) const
    1993             : {
    1994           0 :     bool bFirst = true;
    1995           0 :     SwNodeIndex aTmp( *pIdx );
    1996             :     const SwNode* pNd;
    1997           0 :     while( aTmp > 0 )
    1998             :     {
    1999           0 :         pNd = & aTmp.GetNode();
    2000           0 :         if (ND_ENDNODE == pNd->GetNodeType())
    2001             :         {
    2002           0 :             if( pNd->pStartOfSection->IsSectionNode() )
    2003             :             {
    2004             :                 const SwSection& rSect = ((SwSectionNode*)pNd->
    2005           0 :                                             pStartOfSection)->GetSection();
    2006           0 :                 if( (bSkipHidden && rSect.IsHiddenFlag()) ||
    2007           0 :                     (bSkipProtect && rSect.IsProtectFlag()) )
    2008             :                     // than skip section
    2009           0 :                     aTmp = *pNd->StartOfSectionNode();
    2010             :             }
    2011           0 :             bFirst = false;
    2012             :         }
    2013           0 :         else if( bFirst )
    2014             :         {
    2015           0 :             bFirst = false;
    2016           0 :             if( pNd->pStartOfSection->IsSectionNode() )
    2017             :             {
    2018             :                 const SwSection& rSect = ((SwSectionNode*)pNd->
    2019           0 :                                 pStartOfSection)->GetSection();
    2020           0 :                 if( (bSkipHidden && rSect.IsHiddenFlag()) ||
    2021           0 :                     (bSkipProtect && rSect.IsProtectFlag()) )
    2022             :                     // than skip section
    2023           0 :                     aTmp = *pNd->StartOfSectionNode();
    2024             :             }
    2025             :         }
    2026           0 :         else if( ND_CONTENTNODE & pNd->GetNodeType() )
    2027             :         {
    2028             :             const SwSectionNode* pSectNd;
    2029           0 :             if( ( bSkipHidden || bSkipProtect ) &&
    2030           0 :                 0 != (pSectNd = pNd->FindSectionNode() ) &&
    2031           0 :                 ( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) ||
    2032           0 :                   ( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) )
    2033             :             {
    2034           0 :                 aTmp = *pSectNd;
    2035             :             }
    2036             :             else
    2037             :             {
    2038           0 :                 (*pIdx) = aTmp;
    2039           0 :                 return (SwCntntNode*)pNd;
    2040             :             }
    2041             :         }
    2042           0 :         aTmp--;
    2043             :     }
    2044           0 :     return 0;
    2045             : }
    2046             : 
    2047             : //TODO: improve documentation
    2048             : //TODO: The inventor of the "single responsibility principle" will be crying if you ever show this code to him!
    2049             : /** find the next/previous ContentNode or a table node with frames
    2050             :  *
    2051             :  * If no pEnd is given, search is started with FrameIndex; otherwise
    2052             :  * search is started with the one before rFrmIdx and after pEnd.
    2053             :  *
    2054             :  * @param rFrmIdx node with frames to search in
    2055             :  * @param pEnd ???
    2056             :  * @return result node; 0 (!!!) if not found
    2057             :  */
    2058           0 : SwNode* SwNodes::FindPrvNxtFrmNode( SwNodeIndex& rFrmIdx,
    2059             :                                     const SwNode* pEnd ) const
    2060             : {
    2061           0 :     SwNode* pFrmNd = 0;
    2062             : 
    2063             :     // no layout -> skip
    2064           0 :     if( GetDoc()->GetCurrentViewShell() )
    2065             :     {
    2066           0 :         SwNode* pSttNd = &rFrmIdx.GetNode();
    2067             : 
    2068             :         // move of a hidden section?
    2069           0 :         SwSectionNode* pSectNd = pSttNd->IsSectionNode()
    2070           0 :                     ? pSttNd->StartOfSectionNode()->FindSectionNode()
    2071           0 :                     : pSttNd->FindSectionNode();
    2072           0 :         if( !( pSectNd && pSectNd->GetSection().CalcHiddenFlag() ) )
    2073             :         {
    2074             :             // in a table in table situation we have to assure that we don't leave the
    2075             :             // outer table cell when the inner table is looking for a PrvNxt...
    2076           0 :             SwTableNode* pTableNd = pSttNd->IsTableNode()
    2077           0 :                     ? pSttNd->StartOfSectionNode()->FindTableNode()
    2078           0 :                     : pSttNd->FindTableNode();
    2079           0 :             SwNodeIndex aIdx( rFrmIdx );
    2080             :             SwNode* pNd;
    2081           0 :             if( pEnd )
    2082             :             {
    2083           0 :                 aIdx--;
    2084           0 :                 pNd = &aIdx.GetNode();
    2085             :             }
    2086             :             else
    2087           0 :                 pNd = pSttNd;
    2088             : 
    2089           0 :             if( ( pFrmNd = pNd )->IsCntntNode() )
    2090           0 :                 rFrmIdx = aIdx;
    2091             : 
    2092             :             // search forward or backward for a content node
    2093           0 :             else if( 0 != ( pFrmNd = GoPrevSection( &aIdx, true, false )) &&
    2094           0 :                     ::CheckNodesRange( aIdx, rFrmIdx, true ) &&
    2095             :                     // Never out of the table at the start
    2096           0 :                     pFrmNd->FindTableNode() == pTableNd &&
    2097             :                     // Bug 37652: Never out of the table at the end
    2098           0 :                     (!pFrmNd->FindTableNode() || pFrmNd->FindTableBoxStartNode()
    2099           0 :                         == pSttNd->FindTableBoxStartNode() ) &&
    2100           0 :                      (!pSectNd || pSttNd->IsSectionNode() ||
    2101           0 :                       pSectNd->GetIndex() < pFrmNd->GetIndex())
    2102             :                     )
    2103             :             {
    2104           0 :                 rFrmIdx = aIdx;
    2105             :             }
    2106             :             else
    2107             :             {
    2108           0 :                 if( pEnd )
    2109           0 :                     aIdx = pEnd->GetIndex() + 1;
    2110             :                 else
    2111           0 :                     aIdx = rFrmIdx;
    2112             : 
    2113             :                 // NEVER leave the section when doing this!
    2114           0 :                 if( ( pEnd && ( pFrmNd = &aIdx.GetNode())->IsCntntNode() ) ||
    2115           0 :                     ( 0 != ( pFrmNd = GoNextSection( &aIdx, true, false )) &&
    2116           0 :                     ::CheckNodesRange( aIdx, rFrmIdx, true ) &&
    2117           0 :                     ( pFrmNd->FindTableNode() == pTableNd &&
    2118             :                         // NEVER go out of the table cell at the end
    2119           0 :                         (!pFrmNd->FindTableNode() || pFrmNd->FindTableBoxStartNode()
    2120           0 :                         == pSttNd->FindTableBoxStartNode() ) ) &&
    2121           0 :                      (!pSectNd || pSttNd->IsSectionNode() ||
    2122           0 :                       pSectNd->EndOfSectionIndex() > pFrmNd->GetIndex())
    2123             :                     ))
    2124             :                 {
    2125             :                     // Undo when merging a table with one before, if there is also one after it.
    2126             :                     // However, if the node is in a table, it needs to be returned if the
    2127             :                     // SttNode is a section or a table!
    2128             :                     SwTableNode* pTblNd;
    2129           0 :                     if( pSttNd->IsTableNode() &&
    2130           0 :                         0 != ( pTblNd = pFrmNd->FindTableNode() ) &&
    2131             :                         // TABLE IN TABLE:
    2132           0 :                         pTblNd != pSttNd->StartOfSectionNode()->FindTableNode() )
    2133             :                     {
    2134           0 :                         pFrmNd = pTblNd;
    2135           0 :                         rFrmIdx = *pFrmNd;
    2136             :                     }
    2137             :                     else
    2138           0 :                         rFrmIdx = aIdx;
    2139             :                 }
    2140           0 :                 else if( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsTableNode() )
    2141             :                 {
    2142           0 :                     pFrmNd = pNd->StartOfSectionNode();
    2143           0 :                     rFrmIdx = *pFrmNd;
    2144             :                 }
    2145             :                 else
    2146             :                 {
    2147           0 :                     if( pEnd )
    2148           0 :                         aIdx = pEnd->GetIndex() + 1;
    2149             :                     else
    2150           0 :                         aIdx = rFrmIdx.GetIndex() + 1;
    2151             : 
    2152           0 :                     if( (pFrmNd = &aIdx.GetNode())->IsTableNode() )
    2153           0 :                         rFrmIdx = aIdx;
    2154             :                     else
    2155             :                     {
    2156           0 :                         pFrmNd = 0;
    2157             : 
    2158             :                         // is there some sectionnodes before a tablenode?
    2159           0 :                         while( aIdx.GetNode().IsSectionNode() )
    2160             :                         {
    2161           0 :                             const SwSection& rSect = aIdx.GetNode().
    2162           0 :                                 GetSectionNode()->GetSection();
    2163           0 :                             if( rSect.IsHiddenFlag() )
    2164           0 :                                 aIdx = aIdx.GetNode().EndOfSectionIndex()+1;
    2165             :                             else
    2166           0 :                                 ++aIdx;
    2167             :                         }
    2168           0 :                         if( aIdx.GetNode().IsTableNode() )
    2169             :                         {
    2170           0 :                             rFrmIdx = aIdx;
    2171           0 :                             pFrmNd = &aIdx.GetNode();
    2172             :                         }
    2173             :                     }
    2174             :                 }
    2175           0 :             }
    2176             :         }
    2177             :     }
    2178           0 :     return pFrmNd;
    2179             : }
    2180             : 
    2181           0 : void SwNodes::ForEach( const SwNodeIndex& rStart, const SwNodeIndex& rEnd,
    2182             :                     FnForEach_SwNodes fnForEach, void* pArgs )
    2183             : {
    2184             :     BigPtrArray::ForEach( rStart.GetIndex(), rEnd.GetIndex(),
    2185           0 :                             (FnForEach) fnForEach, pArgs );
    2186           0 : }
    2187             : 
    2188             : namespace {
    2189             : 
    2190             : //TODO: seems to be not/wrongly used
    2191           0 : struct TempBigPtrEntry : public BigPtrEntry
    2192             : {
    2193           0 :     TempBigPtrEntry() {}
    2194             : };
    2195             : 
    2196             : }
    2197             : 
    2198           0 : void SwNodes::RemoveNode( sal_uLong nDelPos, sal_uLong nSz, sal_Bool bDel )
    2199             : {
    2200           0 :     sal_uLong nEnd = nDelPos + nSz;
    2201           0 :     SwNode* pNew = (*this)[ nEnd ];
    2202             : 
    2203           0 :     if( pRoot )
    2204             :     {
    2205           0 :         SwNodeIndex *p = pRoot;
    2206           0 :         while( p )
    2207             :         {
    2208           0 :             sal_uLong nIdx = p->GetIndex();
    2209           0 :             SwNodeIndex* pNext = p->pNext;
    2210           0 :             if( nDelPos <= nIdx && nIdx < nEnd )
    2211           0 :                 (*p) = *pNew;
    2212             : 
    2213           0 :             p = pNext;
    2214             :         }
    2215             : 
    2216           0 :         p = pRoot->pPrev;
    2217           0 :         while( p )
    2218             :         {
    2219           0 :             sal_uLong nIdx = p->GetIndex();
    2220           0 :             SwNodeIndex* pPrev = p->pPrev;
    2221           0 :             if( nDelPos <= nIdx && nIdx < nEnd )
    2222           0 :                 (*p) = *pNew;
    2223             : 
    2224           0 :             p = pPrev;
    2225             :         }
    2226             :     }
    2227             : 
    2228             :     {
    2229           0 :         for (sal_uLong nCnt = 0; nCnt < nSz; nCnt++)
    2230             :         {
    2231           0 :             SwNode* pNode = ((*this)[ nDelPos + nCnt ]);
    2232           0 :             SwTxtNode * pTxtNd = pNode->GetTxtNode();
    2233             : 
    2234           0 :             if (pTxtNd)
    2235             :             {
    2236           0 :                 pTxtNd->RemoveFromList();
    2237             :             }
    2238           0 :             SwTableNode* pTableNode = pNode->GetTableNode();
    2239           0 :             if (pTableNode)
    2240             :             {
    2241             :                 // The node that is deleted is a table node.
    2242             :                 // Need to make sure that all the redlines that are
    2243             :                 // related to this table are removed from the
    2244             :                 // 'Extra Redlines' array
    2245           0 :                 pTableNode->RemoveRedlines();
    2246             :             }
    2247             :         }
    2248             :     }
    2249             : 
    2250           0 :     std::vector<TempBigPtrEntry> aTempEntries;
    2251           0 :     if( bDel )
    2252             :     {
    2253           0 :         sal_uLong nCnt = nSz;
    2254           0 :         SwNode *pDel = (*this)[ nDelPos+nCnt-1 ], *pPrev = (*this)[ nDelPos+nCnt-2 ];
    2255             : 
    2256             :         // set temporary object
    2257             :         // JP 24.08.98: this should actually be removed because one could
    2258             :         // call Remove recursively, e.g. for character bound frames. However,
    2259             :         // since there happens way too much here, this temporary object was
    2260             :         // inserted that will be deleted in Remove again (see Bug 55406)
    2261           0 :         aTempEntries.resize(nCnt);
    2262             : 
    2263           0 :         while( nCnt-- )
    2264             :         {
    2265           0 :             delete pDel;
    2266           0 :             pDel = pPrev;
    2267           0 :             sal_uLong nPrevNdIdx = pPrev->GetIndex();
    2268           0 :             BigPtrEntry* pTempEntry = &aTempEntries[nCnt];
    2269           0 :             BigPtrArray::Replace( nPrevNdIdx+1, pTempEntry );
    2270           0 :             if( nCnt )
    2271           0 :                 pPrev = (*this)[ nPrevNdIdx  - 1 ];
    2272             :         }
    2273           0 :         nDelPos = pDel->GetIndex() + 1;
    2274             :     }
    2275             : 
    2276           0 :     BigPtrArray::Remove( nDelPos, nSz );
    2277           0 : }
    2278             : 
    2279           0 : void SwNodes::RegisterIndex( SwNodeIndex& rIdx )
    2280             : {
    2281           0 :     if( !pRoot ) // no root set, yet?
    2282             :     {
    2283           0 :         pRoot = &rIdx;
    2284           0 :         pRoot->pPrev = 0;
    2285           0 :         pRoot->pNext = 0;
    2286             :     }
    2287             :     else
    2288             :     {
    2289             :         // add always after root
    2290           0 :         rIdx.pNext = pRoot->pNext;
    2291           0 :         pRoot->pNext = &rIdx;
    2292           0 :         rIdx.pPrev = pRoot;
    2293           0 :         if( rIdx.pNext )
    2294           0 :             rIdx.pNext->pPrev = &rIdx;
    2295             :     }
    2296           0 : }
    2297             : 
    2298           0 : void SwNodes::DeRegisterIndex( SwNodeIndex& rIdx )
    2299             : {
    2300           0 :     SwNodeIndex* pN = rIdx.pNext;
    2301           0 :     SwNodeIndex* pP = rIdx.pPrev;
    2302             : 
    2303           0 :     if( pRoot == &rIdx )
    2304           0 :         pRoot = pP ? pP : pN;
    2305             : 
    2306           0 :     if( pP )
    2307           0 :         pP->pNext = pN;
    2308           0 :     if( pN )
    2309           0 :         pN->pPrev = pP;
    2310             : 
    2311           0 :     rIdx.pNext = 0;
    2312           0 :     rIdx.pPrev = 0;
    2313           0 : }
    2314             : 
    2315           0 : void SwNodes::InsertNode( const SwNodePtr pNode,
    2316             :                           const SwNodeIndex& rPos )
    2317             : {
    2318           0 :     const ElementPtr pIns = pNode;
    2319           0 :     BigPtrArray::Insert( pIns, rPos.GetIndex() );
    2320           0 : }
    2321             : 
    2322           0 : void SwNodes::InsertNode( const SwNodePtr pNode,
    2323             :                           sal_uLong nPos )
    2324             : {
    2325           0 :     const ElementPtr pIns = pNode;
    2326           0 :     BigPtrArray::Insert( pIns, nPos );
    2327           0 : }
    2328             : 
    2329             : // ->#112139#
    2330           0 : SwNode * SwNodes::DocumentSectionStartNode(SwNode * pNode) const
    2331             : {
    2332           0 :     if (NULL != pNode)
    2333             :     {
    2334           0 :         SwNodeIndex aIdx(*pNode);
    2335             : 
    2336           0 :         if (aIdx <= (*this)[0]->EndOfSectionIndex())
    2337           0 :             pNode = (*this)[0];
    2338             :         else
    2339             :         {
    2340           0 :             while ((*this)[0] != pNode->StartOfSectionNode())
    2341           0 :                 pNode = pNode->StartOfSectionNode();
    2342           0 :         }
    2343             :     }
    2344             : 
    2345           0 :     return pNode;
    2346             : }
    2347             : 
    2348           0 : SwNode * SwNodes::DocumentSectionEndNode(SwNode * pNode) const
    2349             : {
    2350           0 :     return DocumentSectionStartNode(pNode)->EndOfSectionNode();
    2351             : }
    2352             : 
    2353           0 : sal_Bool SwNodes::IsDocNodes() const
    2354             : {
    2355           0 :     return this == &pMyDoc->GetNodes();
    2356             : }
    2357             : 
    2358             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10