LCOV - code coverage report
Current view: top level - sw/source/core/doc - DocumentContentOperationsManager.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1340 2181 61.4 %
Date: 2014-11-03 Functions: 52 65 80.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             : #include <DocumentContentOperationsManager.hxx>
      20             : #include <doc.hxx>
      21             : #include <IDocumentUndoRedo.hxx>
      22             : #include <IDocumentMarkAccess.hxx>
      23             : #include <DocumentRedlineManager.hxx>
      24             : #include <IDocumentState.hxx>
      25             : #include <IDocumentLayoutAccess.hxx>
      26             : #include <IDocumentStylePoolAccess.hxx>
      27             : #include <UndoManager.hxx>
      28             : #include <docary.hxx>
      29             : #include <textboxhelper.hxx>
      30             : #include <dcontact.hxx>
      31             : #include <grfatr.hxx>
      32             : #include <numrule.hxx>
      33             : #include <charfmt.hxx>
      34             : #include <ndgrf.hxx>
      35             : #include <ndnotxt.hxx>
      36             : #include <ndole.hxx>
      37             : #include <fmtcol.hxx>
      38             : #include <breakit.hxx>
      39             : #include <frmfmt.hxx>
      40             : #include <fmtanchr.hxx>
      41             : #include <fmtcntnt.hxx>
      42             : #include <fmtinfmt.hxx>
      43             : #include <fmtpdsc.hxx>
      44             : #include <fmtcnct.hxx>
      45             : #include <SwStyleNameMapper.hxx>
      46             : #include <redline.hxx>
      47             : #include <unocrsr.hxx>
      48             : #include <mvsave.hxx>
      49             : #include <ndtxt.hxx>
      50             : #include <poolfmt.hxx>
      51             : #include <paratr.hxx>
      52             : #include <txatbase.hxx>
      53             : #include <UndoRedline.hxx>
      54             : #include <undobj.hxx>
      55             : #include <UndoDelete.hxx>
      56             : #include <UndoSplitMove.hxx>
      57             : #include <UndoOverwrite.hxx>
      58             : #include <UndoInsert.hxx>
      59             : #include <UndoAttribute.hxx>
      60             : #include <rolbck.hxx>
      61             : #include <acorrect.hxx>
      62             : #include <ftnidx.hxx>
      63             : #include <txtftn.hxx>
      64             : #include <hints.hxx>
      65             : #include <crsrsh.hxx>
      66             : #include <fmtflcnt.hxx>
      67             : #include <docedt.hxx>
      68             : #include <unotools/charclass.hxx>
      69             : #include <sfx2/Metadatable.hxx>
      70             : #include <svl/stritem.hxx>
      71             : #include <svl/itemiter.hxx>
      72             : #include <svx/svdobj.hxx>
      73             : #include <svx/svdouno.hxx>
      74             : #include <editeng/formatbreakitem.hxx>
      75             : #include <com/sun/star/i18n/Boundary.hpp>
      76             : 
      77             : using namespace ::com::sun::star::i18n;
      78             : 
      79             : namespace
      80             : {
      81             :     // Copy method from SwDoc
      82             :     // Prevent copying in Flys that are anchored in the area
      83         432 :     static bool lcl_ChkFlyFly( SwDoc* pDoc, sal_uLong nSttNd, sal_uLong nEndNd,
      84             :                         sal_uLong nInsNd )
      85             :     {
      86         432 :         const SwFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
      87             : 
      88        5186 :         for( size_t n = 0; n < rFrmFmtTbl.size(); ++n )
      89             :         {
      90        4754 :             SwFrmFmt const*const  pFmt = rFrmFmtTbl[n];
      91        4754 :             SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
      92        4754 :             SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
      93        9246 :             if (pAPos &&
      94        7150 :                 ((FLY_AS_CHAR == pAnchor->GetAnchorId()) ||
      95        5146 :                  (FLY_AT_CHAR == pAnchor->GetAnchorId()) ||
      96        4976 :                  (FLY_AT_FLY  == pAnchor->GetAnchorId()) ||
      97        6980 :                  (FLY_AT_PARA == pAnchor->GetAnchorId())) &&
      98       12404 :                 nSttNd <= pAPos->nNode.GetIndex() &&
      99        3158 :                 pAPos->nNode.GetIndex() < nEndNd )
     100             :             {
     101          90 :                 const SwFmtCntnt& rCntnt = pFmt->GetCntnt();
     102             :                 SwStartNode* pSNd;
     103         154 :                 if( !rCntnt.GetCntntIdx() ||
     104          64 :                     0 == ( pSNd = rCntnt.GetCntntIdx()->GetNode().GetStartNode() ))
     105          26 :                     continue;
     106             : 
     107         128 :                 if( pSNd->GetIndex() < nInsNd &&
     108          64 :                     nInsNd < pSNd->EndOfSectionIndex() )
     109             :                     // Do not copy !
     110           0 :                     return true;
     111             : 
     112          64 :                 if( lcl_ChkFlyFly( pDoc, pSNd->GetIndex(),
     113          64 :                             pSNd->EndOfSectionIndex(), nInsNd ) )
     114             :                     // Do not copy !
     115           0 :                     return true;
     116             :             }
     117             :         }
     118             : 
     119         432 :         return false;
     120             :     }
     121             : 
     122             :     /*
     123             :         The lcl_CopyBookmarks function has to copy bookmarks from the source to the destination nodes
     124             :         array. It is called after a call of the _CopyNodes(..) function. But this function does not copy
     125             :         every node (at least at the moment: 2/08/2006 ), section start and end nodes will not be copied if the corresponding end/start node is outside the copied pam.
     126             :         The lcl_NonCopyCount function counts the number of these nodes, given the copied pam and a node
     127             :         index inside the pam.
     128             :         rPam is the original source pam, rLastIdx is the last calculated position, rDelCount the number
     129             :         of "non-copy" nodes between rPam.Start() and rLastIdx.
     130             :         nNewIdx is the new position of interest.
     131             :     */
     132             : 
     133         798 :     static void lcl_NonCopyCount( const SwPaM& rPam, SwNodeIndex& rLastIdx, const sal_uLong nNewIdx, sal_uLong& rDelCount )
     134             :     {
     135         798 :         sal_uLong nStart = rPam.Start()->nNode.GetIndex();
     136         798 :         sal_uLong nEnd = rPam.End()->nNode.GetIndex();
     137         798 :         if( rLastIdx.GetIndex() < nNewIdx ) // Moving forward?
     138             :         {
     139        1572 :             do // count "non-copy" nodes
     140             :             {
     141        1572 :                 SwNode& rNode = rLastIdx.GetNode();
     142        3168 :                 if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
     143        3144 :                     || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
     144           0 :                     ++rDelCount;
     145        1572 :                 ++rLastIdx;
     146             :             }
     147        1572 :             while( rLastIdx.GetIndex() < nNewIdx );
     148             :         }
     149         318 :         else if( rDelCount ) // optimization: if there are no "non-copy" nodes until now,
     150             :                              // no move backward needed
     151             :         {
     152           0 :             while( rLastIdx.GetIndex() > nNewIdx )
     153             :             {
     154           0 :                 SwNode& rNode = rLastIdx.GetNode();
     155           0 :                 if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
     156           0 :                     || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
     157           0 :                     --rDelCount;
     158           0 :                 rLastIdx--;
     159             :             }
     160             :         }
     161         798 :     }
     162             : 
     163         798 :     static void lcl_SetCpyPos( const SwPosition& rOrigPos,
     164             :                         const SwPosition& rOrigStt,
     165             :                         const SwPosition& rCpyStt,
     166             :                         SwPosition& rChgPos,
     167             :                         sal_uLong nDelCount )
     168             :     {
     169         798 :         sal_uLong nNdOff = rOrigPos.nNode.GetIndex();
     170         798 :         nNdOff -= rOrigStt.nNode.GetIndex();
     171         798 :         nNdOff -= nDelCount;
     172         798 :         sal_Int32 nCntntPos = rOrigPos.nContent.GetIndex();
     173             : 
     174             :         // Always adjust <nNode> at to be changed <SwPosition> instance <rChgPos>
     175         798 :         rChgPos.nNode = nNdOff + rCpyStt.nNode.GetIndex();
     176         798 :         if( !nNdOff )
     177             :         {
     178             :             // dann nur den Content anpassen
     179          40 :             if( nCntntPos > rOrigStt.nContent.GetIndex() )
     180          20 :                 nCntntPos -= rOrigStt.nContent.GetIndex();
     181             :             else
     182          20 :                 nCntntPos = 0;
     183          40 :             nCntntPos += rCpyStt.nContent.GetIndex();
     184             :         }
     185         798 :         rChgPos.nContent.Assign( rChgPos.nNode.GetNode().GetCntntNode(), nCntntPos );
     186         798 :     }
     187             : 
     188             :     // TODO: use SaveBookmark (from _DelBookmarks)
     189         872 :     static void lcl_CopyBookmarks(
     190             :         const SwPaM& rPam,
     191             :         SwPaM& rCpyPam )
     192             :     {
     193         872 :         const SwDoc* pSrcDoc = rPam.GetDoc();
     194         872 :         SwDoc* pDestDoc =  rCpyPam.GetDoc();
     195         872 :         const IDocumentMarkAccess* const pSrcMarkAccess = pSrcDoc->getIDocumentMarkAccess();
     196         872 :         ::sw::UndoGuard const undoGuard(pDestDoc->GetIDocumentUndoRedo());
     197             : 
     198         872 :         const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
     199         872 :         SwPosition* pCpyStt = rCpyPam.Start();
     200             : 
     201             :         typedef ::std::vector< const ::sw::mark::IMark* > mark_vector_t;
     202        1744 :         mark_vector_t vMarksToCopy;
     203       56268 :         for ( IDocumentMarkAccess::const_iterator_t ppMark = pSrcMarkAccess->getAllMarksBegin();
     204       37512 :               ppMark != pSrcMarkAccess->getAllMarksEnd();
     205             :               ++ppMark )
     206             :         {
     207       17884 :             const ::sw::mark::IMark* const pMark = ppMark->get();
     208             : 
     209       17884 :             const SwPosition& rMarkStart = pMark->GetMarkStart();
     210       17884 :             const SwPosition& rMarkEnd = pMark->GetMarkEnd();
     211             :             // only include marks that are in the range and not touching both start and end
     212             :             // - not for annotation marks.
     213             :             const bool bIsNotOnBoundary =
     214       17884 :                 pMark->IsExpanded()
     215        6998 :                 ? (rMarkStart != rStt || rMarkEnd != rEnd)  // rMarkStart != rMarkEnd
     216       24882 :                 : (rMarkStart != rStt && rMarkEnd != rEnd); // rMarkStart == rMarkEnd
     217       52182 :             if ( rMarkStart >= rStt && rMarkEnd <= rEnd
     218       19606 :                  && ( bIsNotOnBoundary
     219         206 :                       || IDocumentMarkAccess::GetType( *pMark ) == IDocumentMarkAccess::ANNOTATIONMARK ) )
     220             :             {
     221         758 :                 vMarksToCopy.push_back(pMark);
     222             :             }
     223             :         }
     224             :         // We have to count the "non-copied" nodes..
     225        1744 :         SwNodeIndex aCorrIdx(rStt.nNode);
     226         872 :         sal_uLong nDelCount = 0;
     227        4890 :         for(mark_vector_t::const_iterator ppMark = vMarksToCopy.begin();
     228        3260 :             ppMark != vMarksToCopy.end();
     229             :             ++ppMark)
     230             :         {
     231         758 :             const ::sw::mark::IMark* const pMark = *ppMark;
     232         758 :             SwPaM aTmpPam(*pCpyStt);
     233         758 :             lcl_NonCopyCount(rPam, aCorrIdx, pMark->GetMarkPos().nNode.GetIndex(), nDelCount);
     234         758 :             lcl_SetCpyPos( pMark->GetMarkPos(), rStt, *pCpyStt, *aTmpPam.GetPoint(), nDelCount);
     235         758 :             if(pMark->IsExpanded())
     236             :             {
     237          40 :                 aTmpPam.SetMark();
     238          40 :                 lcl_NonCopyCount(rPam, aCorrIdx, pMark->GetOtherMarkPos().nNode.GetIndex(), nDelCount);
     239          40 :                 lcl_SetCpyPos(pMark->GetOtherMarkPos(), rStt, *pCpyStt, *aTmpPam.GetMark(), nDelCount);
     240             :             }
     241             : 
     242         758 :             ::sw::mark::IMark* const pNewMark = pDestDoc->getIDocumentMarkAccess()->makeMark(
     243             :                 aTmpPam,
     244         758 :                 pMark->GetName(),
     245        1516 :                 IDocumentMarkAccess::GetType(*pMark));
     246             :             // Explicitly try to get exactly the same name as in the source
     247             :             // because NavigatorReminders, DdeBookmarks etc. ignore the proposed name
     248         758 :             pDestDoc->getIDocumentMarkAccess()->renameMark(pNewMark, pMark->GetName());
     249             : 
     250             :             // copying additional attributes for bookmarks or fieldmarks
     251             :             ::sw::mark::IBookmark* const pNewBookmark =
     252         758 :                 dynamic_cast< ::sw::mark::IBookmark* const >(pNewMark);
     253             :             const ::sw::mark::IBookmark* const pOldBookmark =
     254         758 :                 dynamic_cast< const ::sw::mark::IBookmark* >(pMark);
     255         758 :             if (pNewBookmark && pOldBookmark)
     256             :             {
     257          58 :                 pNewBookmark->SetKeyCode(pOldBookmark->GetKeyCode());
     258          58 :                 pNewBookmark->SetShortName(pOldBookmark->GetShortName());
     259             :             }
     260             :             ::sw::mark::IFieldmark* const pNewFieldmark =
     261         758 :                 dynamic_cast< ::sw::mark::IFieldmark* const >(pNewMark);
     262             :             const ::sw::mark::IFieldmark* const pOldFieldmark =
     263         758 :                 dynamic_cast< const ::sw::mark::IFieldmark* >(pMark);
     264         758 :             if (pNewFieldmark && pOldFieldmark)
     265             :             {
     266           4 :                 pNewFieldmark->SetFieldname(pOldFieldmark->GetFieldname());
     267           4 :                 pNewFieldmark->SetFieldHelptext(pOldFieldmark->GetFieldHelptext());
     268           4 :                 ::sw::mark::IFieldmark::parameter_map_t* pNewParams = pNewFieldmark->GetParameters();
     269           4 :                 const ::sw::mark::IFieldmark::parameter_map_t* pOldParams = pOldFieldmark->GetParameters();
     270           4 :                 ::sw::mark::IFieldmark::parameter_map_t::const_iterator pIt = pOldParams->begin();
     271           4 :                 for (; pIt != pOldParams->end(); ++pIt )
     272             :                 {
     273           0 :                     pNewParams->insert( *pIt );
     274             :                 }
     275             :             }
     276             : 
     277             :             ::sfx2::Metadatable const*const pMetadatable(
     278         758 :                     dynamic_cast< ::sfx2::Metadatable const* >(pMark));
     279             :             ::sfx2::Metadatable      *const pNewMetadatable(
     280         758 :                     dynamic_cast< ::sfx2::Metadatable      * >(pNewMark));
     281         758 :             if (pMetadatable && pNewMetadatable)
     282             :             {
     283          58 :                 pNewMetadatable->RegisterAsCopyOf(*pMetadatable);
     284             :             }
     285        1630 :         }
     286         872 :     }
     287             : 
     288           4 :     static void lcl_DeleteRedlines( const SwPaM& rPam, SwPaM& rCpyPam )
     289             :     {
     290           4 :         const SwDoc* pSrcDoc = rPam.GetDoc();
     291           4 :         const SwRedlineTbl& rTbl = pSrcDoc->getIDocumentRedlineAccess().GetRedlineTbl();
     292           4 :         if( !rTbl.empty() )
     293             :         {
     294           0 :             SwDoc* pDestDoc = rCpyPam.GetDoc();
     295           0 :             SwPosition* pCpyStt = rCpyPam.Start(), *pCpyEnd = rCpyPam.End();
     296           0 :             SwPaM* pDelPam = 0;
     297           0 :             const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
     298             :             // We have to count the "non-copied" nodes
     299           0 :             sal_uLong nDelCount = 0;
     300           0 :             SwNodeIndex aCorrIdx( pStt->nNode );
     301             : 
     302           0 :             sal_uInt16 n = 0;
     303           0 :             pSrcDoc->getIDocumentRedlineAccess().GetRedline( *pStt, &n );
     304           0 :             for( ; n < rTbl.size(); ++n )
     305             :             {
     306           0 :                 const SwRangeRedline* pRedl = rTbl[ n ];
     307           0 :                 if( nsRedlineType_t::REDLINE_DELETE == pRedl->GetType() && pRedl->IsVisible() )
     308             :                 {
     309           0 :                     const SwPosition *pRStt = pRedl->Start(), *pREnd = pRedl->End();
     310             : 
     311           0 :                     SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
     312           0 :                     switch( eCmpPos )
     313             :                     {
     314             :                     case POS_COLLIDE_END:
     315             :                     case POS_BEFORE:
     316             :                         // Pos1 is before Pos2
     317           0 :                         break;
     318             : 
     319             :                     case POS_COLLIDE_START:
     320             :                     case POS_BEHIND:
     321             :                         // Pos1 is after Pos2
     322           0 :                         n = rTbl.size();
     323           0 :                         break;
     324             : 
     325             :                     default:
     326             :                         {
     327           0 :                             pDelPam = new SwPaM( *pCpyStt, pDelPam );
     328           0 :                             if( *pStt < *pRStt )
     329             :                             {
     330           0 :                                 lcl_NonCopyCount( rPam, aCorrIdx, pRStt->nNode.GetIndex(), nDelCount );
     331             :                                 lcl_SetCpyPos( *pRStt, *pStt, *pCpyStt,
     332           0 :                                                 *pDelPam->GetPoint(), nDelCount );
     333             :                             }
     334           0 :                             pDelPam->SetMark();
     335             : 
     336           0 :                             if( *pEnd < *pREnd )
     337           0 :                                 *pDelPam->GetPoint() = *pCpyEnd;
     338             :                             else
     339             :                             {
     340           0 :                                 lcl_NonCopyCount( rPam, aCorrIdx, pREnd->nNode.GetIndex(), nDelCount );
     341             :                                 lcl_SetCpyPos( *pREnd, *pStt, *pCpyStt,
     342           0 :                                                 *pDelPam->GetPoint(), nDelCount );
     343             :                             }
     344             :                         }
     345             :                     }
     346             :                 }
     347             :             }
     348             : 
     349           0 :             if( pDelPam )
     350             :             {
     351           0 :                 RedlineMode_t eOld = pDestDoc->getIDocumentRedlineAccess().GetRedlineMode();
     352           0 :                 pDestDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
     353             : 
     354           0 :                 ::sw::UndoGuard const undoGuard(pDestDoc->GetIDocumentUndoRedo());
     355             : 
     356             :                 do {
     357           0 :                     pDestDoc->getIDocumentContentOperations().DeleteAndJoin( *(SwPaM*)pDelPam->GetNext() );
     358           0 :                     if( pDelPam->GetNext() == pDelPam )
     359           0 :                         break;
     360           0 :                     delete pDelPam->GetNext();
     361             :                 } while( true );
     362           0 :                 delete pDelPam;
     363             : 
     364           0 :                 pDestDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
     365           0 :             }
     366             :         }
     367           4 :     }
     368             : 
     369           2 :     static void lcl_DeleteRedlines( const SwNodeRange& rRg, SwNodeRange& rCpyRg )
     370             :     {
     371           2 :         SwDoc* pSrcDoc = rRg.aStart.GetNode().GetDoc();
     372           2 :         if( !pSrcDoc->getIDocumentRedlineAccess().GetRedlineTbl().empty() )
     373             :         {
     374           0 :             SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
     375           0 :             SwPaM aCpyTmp( rCpyRg.aStart, rCpyRg.aEnd );
     376           0 :             lcl_DeleteRedlines( aRgTmp, aCpyTmp );
     377             :         }
     378           2 :     }
     379             : 
     380           0 :     static void lcl_ChainFmts( SwFlyFrmFmt *pSrc, SwFlyFrmFmt *pDest )
     381             :     {
     382           0 :         SwFmtChain aSrc( pSrc->GetChain() );
     383           0 :         if ( !aSrc.GetNext() )
     384             :         {
     385           0 :             aSrc.SetNext( pDest );
     386           0 :             pSrc->SetFmtAttr( aSrc );
     387             :         }
     388           0 :         SwFmtChain aDest( pDest->GetChain() );
     389           0 :         if ( !aDest.GetPrev() )
     390             :         {
     391           0 :             aDest.SetPrev( pSrc );
     392           0 :             pDest->SetFmtAttr( aDest );
     393           0 :         }
     394           0 :     }
     395             : 
     396             :     // #i86492#
     397           4 :     static bool lcl_ContainsOnlyParagraphsInList( const SwPaM& rPam )
     398             :     {
     399           4 :         bool bRet = false;
     400             : 
     401           4 :         const SwTxtNode* pTxtNd = rPam.Start()->nNode.GetNode().GetTxtNode();
     402           4 :         const SwTxtNode* pEndTxtNd = rPam.End()->nNode.GetNode().GetTxtNode();
     403           8 :         if ( pTxtNd && pTxtNd->IsInList() &&
     404           6 :              pEndTxtNd && pEndTxtNd->IsInList() )
     405             :         {
     406           2 :             bRet = true;
     407           2 :             SwNodeIndex aIdx(rPam.Start()->nNode);
     408             : 
     409           0 :             do
     410             :             {
     411           2 :                 ++aIdx;
     412           2 :                 pTxtNd = aIdx.GetNode().GetTxtNode();
     413             : 
     414           2 :                 if ( !pTxtNd || !pTxtNd->IsInList() )
     415             :                 {
     416           2 :                     bRet = false;
     417           2 :                     break;
     418             :                 }
     419           0 :             } while ( pTxtNd && pTxtNd != pEndTxtNd );
     420             :         }
     421             : 
     422           4 :         return bRet;
     423             :     }
     424             : 
     425         158 :     static bool lcl_MarksWholeNode(const SwPaM & rPam)
     426             :     {
     427         158 :         bool bResult = false;
     428         158 :         const SwPosition* pStt = rPam.Start();
     429         158 :         const SwPosition* pEnd = rPam.End();
     430             : 
     431         158 :         if (NULL != pStt && NULL != pEnd)
     432             :         {
     433         158 :             const SwTxtNode* pSttNd = pStt->nNode.GetNode().GetTxtNode();
     434         158 :             const SwTxtNode* pEndNd = pEnd->nNode.GetNode().GetTxtNode();
     435             : 
     436         474 :             if (NULL != pSttNd && NULL != pEndNd &&
     437         470 :                 pStt->nContent.GetIndex() == 0 &&
     438         154 :                 pEnd->nContent.GetIndex() == pEndNd->Len())
     439             :             {
     440         154 :                 bResult = true;
     441             :             }
     442             :         }
     443             : 
     444         158 :         return bResult;
     445             :     }
     446             : }
     447             : 
     448             : //local functions originally from sw/source/core/doc/docedt.cxx
     449             : namespace
     450             : {
     451             :     static void
     452       10591 :     lcl_CalcBreaks( ::std::vector<sal_Int32> & rBreaks, SwPaM const & rPam )
     453             :     {
     454             :         SwTxtNode const * const pTxtNode(
     455       10591 :                 rPam.End()->nNode.GetNode().GetTxtNode() );
     456       10591 :         if (!pTxtNode)
     457         558 :             return; // left-overlap only possible at end of selection...
     458             : 
     459       10033 :         const sal_Int32 nStart(rPam.Start()->nContent.GetIndex());
     460       10033 :         const sal_Int32 nEnd  (rPam.End  ()->nContent.GetIndex());
     461       10033 :         if (nEnd == pTxtNode->Len())
     462        8873 :             return; // paragraph selected until the end
     463             : 
     464        9308 :         for (sal_Int32 i = nStart; i < nEnd; ++i)
     465             :         {
     466        8148 :             const sal_Unicode c(pTxtNode->GetTxt()[i]);
     467        8148 :             if ((CH_TXTATR_INWORD == c) || (CH_TXTATR_BREAKWORD == c))
     468             :             {
     469         152 :                 SwTxtAttr const * const pAttr( pTxtNode->GetTxtAttrForCharAt(i) );
     470         152 :                 if (pAttr && pAttr->End() && (*pAttr->End() > nEnd))
     471             :                 {
     472             :                     OSL_ENSURE(pAttr->HasDummyChar(), "GetTxtAttrForCharAt broken?");
     473           0 :                     rBreaks.push_back(i);
     474             :                 }
     475             :             }
     476             :         }
     477             :     }
     478             : 
     479       10499 :     static bool lcl_DoWithBreaks(::sw::DocumentContentOperationsManager & rDocumentContentOperations, SwPaM & rPam,
     480             :             bool (::sw::DocumentContentOperationsManager::*pFunc)(SwPaM&, bool), const bool bForceJoinNext = false)
     481             :     {
     482       10499 :         ::std::vector<sal_Int32> Breaks;
     483             : 
     484       10499 :         lcl_CalcBreaks(Breaks, rPam);
     485             : 
     486       10499 :         if (!Breaks.size())
     487             :         {
     488       10499 :             return (rDocumentContentOperations.*pFunc)(rPam, bForceJoinNext);
     489             :         }
     490             : 
     491             :         // Deletion must be split into several parts if the text node
     492             :         // contains a text attribute with end and with dummy character
     493             :         // and the selection does not contain the text attribute completely,
     494             :         // but overlaps its start (left), where the dummy character is.
     495             : 
     496           0 :         SwPosition const & rSelectionEnd( *rPam.End() );
     497             : 
     498           0 :         bool bRet( true );
     499             :         // iterate from end to start, to avoid invalidating the offsets!
     500           0 :         ::std::vector<sal_Int32>::reverse_iterator iter( Breaks.rbegin() );
     501           0 :         SwPaM aPam( rSelectionEnd, rSelectionEnd ); // end node!
     502           0 :         SwPosition & rEnd( *aPam.End() );
     503           0 :         SwPosition & rStart( *aPam.Start() );
     504             : 
     505           0 :         while (iter != Breaks.rend())
     506             :         {
     507           0 :             rStart.nContent = *iter + 1;
     508           0 :             if (rEnd.nContent > rStart.nContent) // check if part is empty
     509             :             {
     510           0 :                 bRet &= (rDocumentContentOperations.*pFunc)(aPam, bForceJoinNext);
     511             :             }
     512           0 :             rEnd.nContent = *iter;
     513           0 :             ++iter;
     514             :         }
     515             : 
     516           0 :         rStart = *rPam.Start(); // set to original start
     517           0 :         if (rEnd.nContent > rStart.nContent) // check if part is empty
     518             :         {
     519           0 :             bRet &= (rDocumentContentOperations.*pFunc)(aPam, bForceJoinNext);
     520             :         }
     521             : 
     522       10499 :         return bRet;
     523             :     }
     524             : 
     525        9629 :     static bool lcl_StrLenOverflow( const SwPaM& rPam )
     526             :     {
     527             :         // If we try to merge two paragraphs we have to test if afterwards
     528             :         // the string doesn't exceed the allowed string length
     529        9629 :         if( rPam.GetPoint()->nNode != rPam.GetMark()->nNode )
     530             :         {
     531        5022 :             const SwPosition* pStt = rPam.Start(), *pEnd = rPam.End();
     532        5022 :             const SwTxtNode* pEndNd = pEnd->nNode.GetNode().GetTxtNode();
     533        5022 :             if( (0 != pEndNd) && pStt->nNode.GetNode().IsTxtNode() )
     534             :             {
     535       10036 :                 const sal_uInt64 nSum = pStt->nContent.GetIndex() +
     536       10036 :                     pEndNd->GetTxt().getLength() - pEnd->nContent.GetIndex();
     537        5018 :                 return nSum > static_cast<sal_uInt64>(SAL_MAX_INT32);
     538             :             }
     539             :         }
     540        4611 :         return false;
     541             :     }
     542             : 
     543             :     struct _SaveRedline
     544             :     {
     545             :         SwRangeRedline* pRedl;
     546             :         sal_uInt32 nStt, nEnd;
     547             :         sal_Int32 nSttCnt;
     548             :         sal_Int32 nEndCnt;
     549             : 
     550           0 :         _SaveRedline( SwRangeRedline* pR, const SwNodeIndex& rSttIdx )
     551             :             : pRedl(pR)
     552             :             , nEnd(0)
     553           0 :             , nEndCnt(0)
     554             :         {
     555           0 :             const SwPosition* pStt = pR->Start(),
     556           0 :                 * pEnd = pR->GetMark() == pStt ? pR->GetPoint() : pR->GetMark();
     557           0 :             sal_uInt32 nSttIdx = rSttIdx.GetIndex();
     558           0 :             nStt = pStt->nNode.GetIndex() - nSttIdx;
     559           0 :             nSttCnt = pStt->nContent.GetIndex();
     560           0 :             if( pR->HasMark() )
     561             :             {
     562           0 :                 nEnd = pEnd->nNode.GetIndex() - nSttIdx;
     563           0 :                 nEndCnt = pEnd->nContent.GetIndex();
     564             :             }
     565             : 
     566           0 :             pRedl->GetPoint()->nNode = 0;
     567           0 :             pRedl->GetPoint()->nContent.Assign( 0, 0 );
     568           0 :             pRedl->GetMark()->nNode = 0;
     569           0 :             pRedl->GetMark()->nContent.Assign( 0, 0 );
     570           0 :         }
     571             : 
     572           0 :         _SaveRedline( SwRangeRedline* pR, const SwPosition& rPos )
     573             :             : pRedl(pR)
     574             :             , nEnd(0)
     575           0 :             , nEndCnt(0)
     576             :         {
     577           0 :             const SwPosition* pStt = pR->Start(),
     578           0 :                 * pEnd = pR->GetMark() == pStt ? pR->GetPoint() : pR->GetMark();
     579           0 :             sal_uInt32 nSttIdx = rPos.nNode.GetIndex();
     580           0 :             nStt = pStt->nNode.GetIndex() - nSttIdx;
     581           0 :             nSttCnt = pStt->nContent.GetIndex();
     582           0 :             if( nStt == 0 )
     583           0 :                 nSttCnt = nSttCnt - rPos.nContent.GetIndex();
     584           0 :             if( pR->HasMark() )
     585             :             {
     586           0 :                 nEnd = pEnd->nNode.GetIndex() - nSttIdx;
     587           0 :                 nEndCnt = pEnd->nContent.GetIndex();
     588           0 :                 if( nEnd == 0 )
     589           0 :                     nEndCnt = nEndCnt - rPos.nContent.GetIndex();
     590             :             }
     591             : 
     592           0 :             pRedl->GetPoint()->nNode = 0;
     593           0 :             pRedl->GetPoint()->nContent.Assign( 0, 0 );
     594           0 :             pRedl->GetMark()->nNode = 0;
     595           0 :             pRedl->GetMark()->nContent.Assign( 0, 0 );
     596           0 :         }
     597             : 
     598           0 :         void SetPos( sal_uInt32 nInsPos )
     599             :         {
     600           0 :             pRedl->GetPoint()->nNode = nInsPos + nStt;
     601           0 :             pRedl->GetPoint()->nContent.Assign( pRedl->GetCntntNode(), nSttCnt );
     602           0 :             if( pRedl->HasMark() )
     603             :             {
     604           0 :                 pRedl->GetMark()->nNode = nInsPos + nEnd;
     605           0 :                 pRedl->GetMark()->nContent.Assign( pRedl->GetCntntNode(false), nEndCnt );
     606             :             }
     607           0 :         }
     608             : 
     609           0 :         void SetPos( const SwPosition& aPos )
     610             :         {
     611           0 :             pRedl->GetPoint()->nNode = aPos.nNode.GetIndex() + nStt;
     612           0 :             pRedl->GetPoint()->nContent.Assign( pRedl->GetCntntNode(), nSttCnt + ( nStt == 0 ? aPos.nContent.GetIndex() : 0 ) );
     613           0 :             if( pRedl->HasMark() )
     614             :             {
     615           0 :                 pRedl->GetMark()->nNode = aPos.nNode.GetIndex() + nEnd;
     616           0 :                 pRedl->GetMark()->nContent.Assign( pRedl->GetCntntNode(false), nEndCnt  + ( nEnd == 0 ? aPos.nContent.GetIndex() : 0 ) );
     617             :             }
     618           0 :         }
     619             :     };
     620             : 
     621             :     typedef boost::ptr_vector< _SaveRedline > _SaveRedlines;
     622             : 
     623           0 :     static void lcl_SaveRedlines( const SwPaM& aPam, _SaveRedlines& rArr )
     624             :     {
     625           0 :         SwDoc* pDoc = aPam.GetNode().GetDoc();
     626             : 
     627           0 :         const SwPosition* pStart = aPam.Start();
     628           0 :         const SwPosition* pEnd = aPam.End();
     629             : 
     630             :         // get first relevant redline
     631             :         sal_uInt16 nCurrentRedline;
     632           0 :         pDoc->getIDocumentRedlineAccess().GetRedline( *pStart, &nCurrentRedline );
     633           0 :         if( nCurrentRedline > 0)
     634           0 :             nCurrentRedline--;
     635             : 
     636             :         // redline mode REDLINE_IGNORE|REDLINE_ON; save old mode
     637           0 :         RedlineMode_t eOld = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
     638           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
     639             : 
     640             :         // iterate over relevant redlines and decide for each whether it should
     641             :         // be saved, or split + saved
     642           0 :         SwRedlineTbl& rRedlineTable = const_cast<SwRedlineTbl&>( pDoc->getIDocumentRedlineAccess().GetRedlineTbl() );
     643           0 :         for( ; nCurrentRedline < rRedlineTable.size(); nCurrentRedline++ )
     644             :         {
     645           0 :             SwRangeRedline* pCurrent = rRedlineTable[ nCurrentRedline ];
     646             :             SwComparePosition eCompare =
     647           0 :                 ComparePosition( *pCurrent->Start(), *pCurrent->End(),
     648           0 :                                  *pStart, *pEnd);
     649             : 
     650             :             // we must save this redline if it overlaps aPam
     651             :             // (we may have to split it, too)
     652           0 :             if( eCompare == POS_OVERLAP_BEHIND  ||
     653           0 :                 eCompare == POS_OVERLAP_BEFORE  ||
     654           0 :                 eCompare == POS_OUTSIDE ||
     655           0 :                 eCompare == POS_INSIDE ||
     656             :                 eCompare == POS_EQUAL )
     657             :             {
     658           0 :                 rRedlineTable.Remove( nCurrentRedline-- );
     659             : 
     660             :                 // split beginning, if necessary
     661           0 :                 if( eCompare == POS_OVERLAP_BEFORE  ||
     662             :                     eCompare == POS_OUTSIDE )
     663             :                 {
     664           0 :                     SwRangeRedline* pNewRedline = new SwRangeRedline( *pCurrent );
     665           0 :                     *pNewRedline->End() = *pStart;
     666           0 :                     *pCurrent->Start() = *pStart;
     667           0 :                     pDoc->getIDocumentRedlineAccess().AppendRedline( pNewRedline, true );
     668             :                 }
     669             : 
     670             :                 // split end, if necessary
     671           0 :                 if( eCompare == POS_OVERLAP_BEHIND  ||
     672             :                     eCompare == POS_OUTSIDE )
     673             :                 {
     674           0 :                     SwRangeRedline* pNewRedline = new SwRangeRedline( *pCurrent );
     675           0 :                     *pNewRedline->Start() = *pEnd;
     676           0 :                     *pCurrent->End() = *pEnd;
     677           0 :                     pDoc->getIDocumentRedlineAccess().AppendRedline( pNewRedline, true );
     678             :                 }
     679             : 
     680             :                 // save the current redline
     681           0 :                 _SaveRedline* pSave = new _SaveRedline( pCurrent, *pStart );
     682           0 :                 rArr.push_back( pSave );
     683             :             }
     684             :         }
     685             : 
     686             :         // restore old redline mode
     687           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
     688           0 :     }
     689             : 
     690           0 :     static void lcl_RestoreRedlines( SwDoc* pDoc, const SwPosition& rPos, _SaveRedlines& rArr )
     691             :     {
     692           0 :         RedlineMode_t eOld = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
     693           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
     694             : 
     695           0 :         for( size_t n = 0; n < rArr.size(); ++n )
     696             :         {
     697           0 :             rArr[ n ].SetPos( rPos );
     698           0 :             pDoc->getIDocumentRedlineAccess().AppendRedline( rArr[ n ].pRedl, true );
     699             :         }
     700             : 
     701           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
     702           0 :     }
     703             : 
     704           0 :     static void lcl_SaveRedlines( const SwNodeRange& rRg, _SaveRedlines& rArr )
     705             :     {
     706           0 :         SwDoc* pDoc = rRg.aStart.GetNode().GetDoc();
     707             :         sal_uInt16 nRedlPos;
     708           0 :         SwPosition aSrchPos( rRg.aStart ); aSrchPos.nNode--;
     709           0 :         aSrchPos.nContent.Assign( aSrchPos.nNode.GetNode().GetCntntNode(), 0 );
     710           0 :         if( pDoc->getIDocumentRedlineAccess().GetRedline( aSrchPos, &nRedlPos ) && nRedlPos )
     711           0 :             --nRedlPos;
     712           0 :         else if( nRedlPos >= pDoc->getIDocumentRedlineAccess().GetRedlineTbl().size() )
     713           0 :             return ;
     714             : 
     715           0 :         RedlineMode_t eOld = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
     716           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
     717           0 :         SwRedlineTbl& rRedlTbl = (SwRedlineTbl&)pDoc->getIDocumentRedlineAccess().GetRedlineTbl();
     718             : 
     719           0 :         do {
     720           0 :             SwRangeRedline* pTmp = rRedlTbl[ nRedlPos ];
     721             : 
     722           0 :             const SwPosition* pRStt = pTmp->Start(),
     723           0 :                             * pREnd = pTmp->GetMark() == pRStt
     724           0 :                                 ? pTmp->GetPoint() : pTmp->GetMark();
     725             : 
     726           0 :             if( pRStt->nNode < rRg.aStart )
     727             :             {
     728           0 :                 if( pREnd->nNode > rRg.aStart && pREnd->nNode < rRg.aEnd )
     729             :                 {
     730             :                     // Create a copy and set the end of the original to the end of the MoveArea.
     731             :                     // The copy is moved too.
     732           0 :                     SwRangeRedline* pNewRedl = new SwRangeRedline( *pTmp );
     733           0 :                     SwPosition* pTmpPos = pNewRedl->Start();
     734           0 :                     pTmpPos->nNode = rRg.aStart;
     735             :                     pTmpPos->nContent.Assign(
     736           0 :                                 pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
     737             : 
     738           0 :                     _SaveRedline* pSave = new _SaveRedline( pNewRedl, rRg.aStart );
     739           0 :                     rArr.push_back( pSave );
     740             : 
     741           0 :                     pTmpPos = pTmp->End();
     742           0 :                     pTmpPos->nNode = rRg.aEnd;
     743             :                     pTmpPos->nContent.Assign(
     744           0 :                                 pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
     745             :                 }
     746           0 :                 else if( pREnd->nNode == rRg.aStart )
     747             :                 {
     748           0 :                     SwPosition* pTmpPos = pTmp->End();
     749           0 :                     pTmpPos->nNode = rRg.aEnd;
     750             :                     pTmpPos->nContent.Assign(
     751           0 :                                 pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
     752             :                 }
     753             :             }
     754           0 :             else if( pRStt->nNode < rRg.aEnd )
     755             :             {
     756           0 :                 rRedlTbl.Remove( nRedlPos-- );
     757           0 :                 if( pREnd->nNode < rRg.aEnd ||
     758           0 :                     ( pREnd->nNode == rRg.aEnd && !pREnd->nContent.GetIndex()) )
     759             :                 {
     760             :                     // move everything
     761           0 :                     _SaveRedline* pSave = new _SaveRedline( pTmp, rRg.aStart );
     762           0 :                     rArr.push_back( pSave );
     763             :                 }
     764             :                 else
     765             :                 {
     766             :                     // split
     767           0 :                     SwRangeRedline* pNewRedl = new SwRangeRedline( *pTmp );
     768           0 :                     SwPosition* pTmpPos = pNewRedl->End();
     769           0 :                     pTmpPos->nNode = rRg.aEnd;
     770             :                     pTmpPos->nContent.Assign(
     771           0 :                                 pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
     772             : 
     773           0 :                     _SaveRedline* pSave = new _SaveRedline( pNewRedl, rRg.aStart );
     774           0 :                     rArr.push_back( pSave );
     775             : 
     776           0 :                     pTmpPos = pTmp->Start();
     777           0 :                     pTmpPos->nNode = rRg.aEnd;
     778             :                     pTmpPos->nContent.Assign(
     779           0 :                                 pTmpPos->nNode.GetNode().GetCntntNode(), 0 );
     780           0 :                     pDoc->getIDocumentRedlineAccess().AppendRedline( pTmp, true );
     781             :                 }
     782             :             }
     783             :             else
     784           0 :                 break;
     785             : 
     786           0 :         } while( ++nRedlPos < pDoc->getIDocumentRedlineAccess().GetRedlineTbl().size() );
     787           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
     788             :     }
     789             : 
     790           0 :     static void lcl_RestoreRedlines( SwDoc* pDoc, sal_uInt32 nInsPos, _SaveRedlines& rArr )
     791             :     {
     792           0 :         RedlineMode_t eOld = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
     793           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
     794             : 
     795           0 :         for( size_t n = 0; n < rArr.size(); ++n )
     796             :         {
     797           0 :             rArr[ n ].SetPos( nInsPos );
     798           0 :             pDoc->getIDocumentRedlineAccess().AppendRedline( rArr[ n ].pRedl, true );
     799             :         }
     800             : 
     801           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
     802           0 :     }
     803             : 
     804         144 :     static bool lcl_SaveFtn( const SwNodeIndex& rSttNd, const SwNodeIndex& rEndNd,
     805             :                      const SwNodeIndex& rInsPos,
     806             :                      SwFtnIdxs& rFtnArr, SwFtnIdxs& rSaveArr,
     807             :                      const SwIndex* pSttCnt = 0, const SwIndex* pEndCnt = 0 )
     808             :     {
     809         144 :         bool bUpdateFtn = false;
     810         144 :         const SwNodes& rNds = rInsPos.GetNodes();
     811         144 :         const bool bDelFtn = rInsPos.GetIndex() < rNds.GetEndOfAutotext().GetIndex() &&
     812         144 :                     rSttNd.GetIndex() >= rNds.GetEndOfAutotext().GetIndex();
     813         288 :         const bool bSaveFtn = !bDelFtn &&
     814         288 :                         rInsPos.GetIndex() >= rNds.GetEndOfExtras().GetIndex();
     815         144 :         if( !rFtnArr.empty() )
     816             :         {
     817             : 
     818           0 :             size_t nPos = 0;
     819           0 :             rFtnArr.SeekEntry( rSttNd, &nPos );
     820             :             SwTxtFtn* pSrch;
     821             :             const SwNode* pFtnNd;
     822             : 
     823             :             // Delete/save all that come after it
     824           0 :             while( nPos < rFtnArr.size() && ( pFtnNd =
     825           0 :                 &( pSrch = rFtnArr[ nPos ] )->GetTxtNode())->GetIndex()
     826           0 :                         <= rEndNd.GetIndex() )
     827             :             {
     828           0 :                 const sal_Int32 nFtnSttIdx = pSrch->GetStart();
     829           0 :                 if( ( pEndCnt && pSttCnt )
     830           0 :                     ? (( &rSttNd.GetNode() == pFtnNd &&
     831           0 :                          pSttCnt->GetIndex() > nFtnSttIdx) ||
     832           0 :                        ( &rEndNd.GetNode() == pFtnNd &&
     833           0 :                         nFtnSttIdx >= pEndCnt->GetIndex() ))
     834           0 :                     : ( &rEndNd.GetNode() == pFtnNd ))
     835             :                 {
     836           0 :                     ++nPos;     // continue searching
     837             :                 }
     838             :                 else
     839             :                 {
     840             :                     // delete it
     841           0 :                     if( bDelFtn )
     842             :                     {
     843           0 :                         SwTxtNode& rTxtNd = (SwTxtNode&)pSrch->GetTxtNode();
     844           0 :                         SwIndex aIdx( &rTxtNd, nFtnSttIdx );
     845           0 :                         rTxtNd.EraseText( aIdx, 1 );
     846             :                     }
     847             :                     else
     848             :                     {
     849           0 :                         pSrch->DelFrms(0);
     850           0 :                         rFtnArr.erase( rFtnArr.begin() + nPos );
     851           0 :                         if( bSaveFtn )
     852           0 :                             rSaveArr.insert( pSrch );
     853             :                     }
     854           0 :                     bUpdateFtn = true;
     855             :                 }
     856             :             }
     857             : 
     858           0 :             while( nPos-- && ( pFtnNd = &( pSrch = rFtnArr[ nPos ] )->
     859           0 :                     GetTxtNode())->GetIndex() >= rSttNd.GetIndex() )
     860             :             {
     861           0 :                 const sal_Int32 nFtnSttIdx = pSrch->GetStart();
     862           0 :                 if( !pEndCnt || !pSttCnt ||
     863           0 :                     !( (( &rSttNd.GetNode() == pFtnNd &&
     864           0 :                         pSttCnt->GetIndex() > nFtnSttIdx ) ||
     865           0 :                        ( &rEndNd.GetNode() == pFtnNd &&
     866           0 :                         nFtnSttIdx >= pEndCnt->GetIndex() )) ))
     867             :                 {
     868           0 :                     if( bDelFtn )
     869             :                     {
     870             :                         // delete it
     871           0 :                         SwTxtNode& rTxtNd = (SwTxtNode&)pSrch->GetTxtNode();
     872           0 :                         SwIndex aIdx( &rTxtNd, nFtnSttIdx );
     873           0 :                         rTxtNd.EraseText( aIdx, 1 );
     874             :                     }
     875             :                     else
     876             :                     {
     877           0 :                         pSrch->DelFrms(0);
     878           0 :                         rFtnArr.erase( rFtnArr.begin() + nPos );
     879           0 :                         if( bSaveFtn )
     880           0 :                             rSaveArr.insert( pSrch );
     881             :                     }
     882           0 :                     bUpdateFtn = true;
     883             :                 }
     884             :             }
     885             :         }
     886             :         // When moving from redline section into document content section, e.g.
     887             :         // after loading a document with (delete-)redlines, the footnote array
     888             :         // has to be adjusted... (#i70572)
     889         144 :         if( bSaveFtn )
     890             :         {
     891         144 :             SwNodeIndex aIdx( rSttNd );
     892         426 :             while( aIdx < rEndNd ) // Check the moved section
     893             :             {
     894         138 :                 SwNode* pNode = &aIdx.GetNode();
     895         138 :                 if( pNode->IsTxtNode() ) // Looking for text nodes...
     896             :                 {
     897             :                     SwpHints *pHints =
     898         138 :                         static_cast<SwTxtNode*>(pNode)->GetpSwpHints();
     899         138 :                     if( pHints && pHints->HasFtn() ) //...with footnotes
     900             :                     {
     901           0 :                         bUpdateFtn = true; // Heureka
     902           0 :                         const size_t nCount = pHints->Count();
     903           0 :                         for( size_t i = 0; i < nCount; ++i )
     904             :                         {
     905           0 :                             SwTxtAttr *pAttr = pHints->GetTextHint( i );
     906           0 :                             if ( pAttr->Which() == RES_TXTATR_FTN )
     907             :                             {
     908           0 :                                 rSaveArr.insert( static_cast<SwTxtFtn*>(pAttr) );
     909             :                             }
     910             :                         }
     911             :                     }
     912             :                 }
     913         138 :                 ++aIdx;
     914         144 :             }
     915             :         }
     916         144 :         return bUpdateFtn;
     917             :     }
     918             : 
     919           0 :     static bool lcl_MayOverwrite( const SwTxtNode *pNode, const sal_Int32 nPos )
     920             :     {
     921           0 :         sal_Unicode const cChr = pNode->GetTxt()[nPos];
     922           0 :         switch (cChr)
     923             :         {
     924             :             case CH_TXTATR_BREAKWORD:
     925             :             case CH_TXTATR_INWORD:
     926           0 :                 return !pNode->GetTxtAttrForCharAt(nPos);// how could there be none?
     927             :             case CH_TXT_ATR_FIELDSTART:
     928             :             case CH_TXT_ATR_FIELDEND:
     929             :             case CH_TXT_ATR_FORMELEMENT:
     930           0 :                 return false;
     931             :             default:
     932           0 :                 return true;
     933             :         }
     934             :     }
     935             : 
     936           0 :     static void lcl_SkipAttr( const SwTxtNode *pNode, SwIndex &rIdx, sal_Int32 &rStart )
     937             :     {
     938           0 :         if( !lcl_MayOverwrite( pNode, rStart ) )
     939             :         {
     940             :             // skip all special attributes
     941           0 :             do {
     942           0 :                 ++rIdx;
     943           0 :                 rStart = rIdx.GetIndex();
     944           0 :             } while (rStart < pNode->GetTxt().getLength()
     945           0 :                    && !lcl_MayOverwrite(pNode, rStart) );
     946             :         }
     947           0 :     }
     948             : 
     949          92 :     static bool lcl_GetTokenToParaBreak( OUString& rStr, OUString& rRet, bool bRegExpRplc )
     950             :     {
     951          92 :         if( bRegExpRplc )
     952             :         {
     953           0 :             sal_Int32 nPos = 0;
     954           0 :             const OUString sPara("\\n");
     955             :             for (;;)
     956             :             {
     957           0 :                 nPos = rStr.indexOf( sPara, nPos );
     958           0 :                 if (nPos<0)
     959             :                 {
     960           0 :                     break;
     961             :                 }
     962             :                 // Has this been escaped?
     963           0 :                 if( nPos && '\\' == rStr[nPos-1])
     964             :                 {
     965           0 :                     ++nPos;
     966           0 :                     if( nPos >= rStr.getLength() )
     967             :                     {
     968           0 :                         break;
     969             :                     }
     970             :                 }
     971             :                 else
     972             :                 {
     973           0 :                     rRet = rStr.copy( 0, nPos );
     974           0 :                     rStr = rStr.copy( nPos + sPara.getLength() );
     975           0 :                     return true;
     976             :                 }
     977           0 :             }
     978             :         }
     979          92 :         rRet = rStr;
     980          92 :         rStr = OUString();
     981          92 :         return false;
     982             :     }
     983             : }
     984             : 
     985             : namespace //local functions originally from docfmt.cxx
     986             : {
     987             :     #define DELETECHARSETS if ( bDelete ) { delete pCharSet; delete pOtherSet; }
     988             : 
     989             :     /// Insert Hints according to content types;
     990             :     // Is used in SwDoc::Insert(..., SwFmtHint &rHt)
     991             : 
     992      244696 :     static bool lcl_InsAttr(
     993             :         SwDoc *const pDoc,
     994             :         const SwPaM &rRg,
     995             :         const SfxItemSet& rChgSet,
     996             :         const SetAttrMode nFlags,
     997             :         SwUndoAttr *const pUndo,
     998             :         const bool bExpandCharToPara=false)
     999             :     {
    1000             :         // Divide the Sets (for selections in Nodes)
    1001      244696 :         const SfxItemSet* pCharSet = 0;
    1002      244696 :         const SfxItemSet* pOtherSet = 0;
    1003      244696 :         bool bDelete = false;
    1004      244696 :         bool bCharAttr = false;
    1005      244696 :         bool bOtherAttr = false;
    1006             : 
    1007             :         // Check, if we can work with rChgSet or if we have to create additional SfxItemSets
    1008      244696 :         if ( 1 == rChgSet.Count() )
    1009             :         {
    1010      117922 :             SfxItemIter aIter( rChgSet );
    1011      117922 :             const SfxPoolItem* pItem = aIter.FirstItem();
    1012      117922 :             if (!IsInvalidItem(pItem))
    1013             :             {
    1014      117922 :                 const sal_uInt16 nWhich = pItem->Which();
    1015             : 
    1016      297468 :                 if ( isCHRATR(nWhich) ||
    1017       52622 :                      (RES_TXTATR_CHARFMT == nWhich) ||
    1018       49846 :                      (RES_TXTATR_INETFMT == nWhich) ||
    1019      161084 :                      (RES_TXTATR_AUTOFMT == nWhich) ||
    1020             :                      (RES_TXTATR_UNKNOWN_CONTAINER == nWhich) )
    1021             :                 {
    1022       74806 :                     pCharSet  = &rChgSet;
    1023       74806 :                     bCharAttr = true;
    1024             :                 }
    1025             : 
    1026      235844 :                 if (    isPARATR(nWhich)
    1027       97742 :                      || isPARATR_LIST(nWhich)
    1028       97742 :                      || isFRMATR(nWhich)
    1029       77984 :                      || isGRFATR(nWhich)
    1030       77984 :                      || isUNKNOWNATR(nWhich)
    1031      195906 :                      || isDrawingLayerAttribute(nWhich) ) //UUUU
    1032             :                 {
    1033       39938 :                     pOtherSet = &rChgSet;
    1034       39938 :                     bOtherAttr = true;
    1035             :                 }
    1036      117922 :             }
    1037             :         }
    1038             : 
    1039             :         // Build new itemset if either
    1040             :         // - rChgSet.Count() > 1 or
    1041             :         // - The attribute in rChgSet does not belong to one of the above categories
    1042      244696 :         if ( !bCharAttr && !bOtherAttr )
    1043             :         {
    1044      129952 :             SfxItemSet* pTmpCharItemSet = new SfxItemSet( pDoc->GetAttrPool(),
    1045             :                                        RES_CHRATR_BEGIN, RES_CHRATR_END-1,
    1046             :                                        RES_TXTATR_AUTOFMT, RES_TXTATR_AUTOFMT,
    1047             :                                        RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
    1048             :                                        RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
    1049             :                    RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
    1050      129952 :                                        0 );
    1051             : 
    1052      129952 :             SfxItemSet* pTmpOtherItemSet = new SfxItemSet( pDoc->GetAttrPool(),
    1053             :                                         RES_PARATR_BEGIN, RES_PARATR_END-1,
    1054             :                                         RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
    1055             :                                         RES_FRMATR_BEGIN, RES_FRMATR_END-1,
    1056             :                                         RES_GRFATR_BEGIN, RES_GRFATR_END-1,
    1057             :                                         RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
    1058             : 
    1059             :                                         //UUUU FillAttribute support
    1060             :                                         XATTR_FILL_FIRST, XATTR_FILL_LAST,
    1061             : 
    1062      129952 :                                         0 );
    1063             : 
    1064      129952 :             pTmpCharItemSet->Put( rChgSet );
    1065      129952 :             pTmpOtherItemSet->Put( rChgSet );
    1066             : 
    1067      129952 :             pCharSet = pTmpCharItemSet;
    1068      129952 :             pOtherSet = pTmpOtherItemSet;
    1069             : 
    1070      129952 :             bDelete = true;
    1071             :         }
    1072             : 
    1073      244696 :         SwHistory* pHistory = pUndo ? &pUndo->GetHistory() : 0;
    1074      244696 :         bool bRet = false;
    1075      244696 :         const SwPosition *pStt = rRg.Start(), *pEnd = rRg.End();
    1076      244696 :         SwCntntNode* pNode = pStt->nNode.GetNode().GetCntntNode();
    1077             : 
    1078      244696 :         if( pNode && pNode->IsTxtNode() )
    1079             :         {
    1080             :             // #i27615#
    1081      244696 :             if (rRg.IsInFrontOfLabel())
    1082             :             {
    1083           0 :                 SwTxtNode * pTxtNd = pNode->GetTxtNode();
    1084           0 :                 SwNumRule * pNumRule = pTxtNd->GetNumRule();
    1085             : 
    1086           0 :                 if ( !pNumRule )
    1087             :                 {
    1088             :                     OSL_FAIL( "<InsAttr(..)> - PaM in front of label, but text node has no numbering rule set. This is a serious defect, please inform OD." );
    1089           0 :                     DELETECHARSETS
    1090           0 :                     return false;
    1091             :                 }
    1092             : 
    1093           0 :                 int nLevel = pTxtNd->GetActualListLevel();
    1094             : 
    1095           0 :                 if (nLevel < 0)
    1096           0 :                     nLevel = 0;
    1097             : 
    1098           0 :                 if (nLevel >= MAXLEVEL)
    1099           0 :                     nLevel = MAXLEVEL - 1;
    1100             : 
    1101           0 :                 SwNumFmt aNumFmt = pNumRule->Get(static_cast<sal_uInt16>(nLevel));
    1102             :                 SwCharFmt * pCharFmt =
    1103           0 :                     pDoc->FindCharFmtByName(aNumFmt.GetCharFmtName());
    1104             : 
    1105           0 :                 if (pCharFmt)
    1106             :                 {
    1107           0 :                     if (pHistory)
    1108           0 :                         pHistory->Add(pCharFmt->GetAttrSet(), *pCharFmt);
    1109             : 
    1110           0 :                     if ( pCharSet )
    1111           0 :                         pCharFmt->SetFmtAttr(*pCharSet);
    1112             :                 }
    1113             : 
    1114           0 :                 DELETECHARSETS
    1115           0 :                 return true;
    1116             :             }
    1117             : 
    1118      244696 :             const SwIndex& rSt = pStt->nContent;
    1119             : 
    1120             :             // Attributes without an end do not have a range
    1121      244696 :             if ( !bCharAttr && !bOtherAttr )
    1122             :             {
    1123      129952 :                 SfxItemSet aTxtSet( pDoc->GetAttrPool(),
    1124      129952 :                             RES_TXTATR_NOEND_BEGIN, RES_TXTATR_NOEND_END-1 );
    1125      129952 :                 aTxtSet.Put( rChgSet );
    1126      129952 :                 if( aTxtSet.Count() )
    1127             :                 {
    1128        2238 :                     SwRegHistory history( pNode, *pNode, pHistory );
    1129             :                     bRet = history.InsertItems(
    1130        2238 :                         aTxtSet, rSt.GetIndex(), rSt.GetIndex(), nFlags ) || bRet;
    1131             : 
    1132        2248 :                     if (bRet && (pDoc->getIDocumentRedlineAccess().IsRedlineOn() || (!pDoc->getIDocumentRedlineAccess().IsIgnoreRedline()
    1133        2238 :                                     && !pDoc->getIDocumentRedlineAccess().GetRedlineTbl().empty())))
    1134             :                     {
    1135          10 :                         SwPaM aPam( pStt->nNode, pStt->nContent.GetIndex()-1,
    1136          20 :                                     pStt->nNode, pStt->nContent.GetIndex() );
    1137             : 
    1138          10 :                         if( pUndo )
    1139           0 :                             pUndo->SaveRedlineData( aPam, true );
    1140             : 
    1141          10 :                         if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
    1142           0 :                             pDoc->getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
    1143             :                         else
    1144          10 :                             pDoc->getIDocumentRedlineAccess().SplitRedline( aPam );
    1145        2238 :                     }
    1146      129952 :                 }
    1147             :             }
    1148             : 
    1149             :             // TextAttributes with an end never expand their range
    1150      244696 :             if ( !bCharAttr && !bOtherAttr )
    1151             :             {
    1152             :                 // CharFmt and URL attributes are treated separately!
    1153             :                 // TEST_TEMP ToDo: AutoFmt!
    1154      129952 :                 SfxItemSet aTxtSet( pDoc->GetAttrPool(),
    1155             :                                     RES_TXTATR_REFMARK, RES_TXTATR_TOXMARK,
    1156             :                                     RES_TXTATR_META, RES_TXTATR_METAFIELD,
    1157             :                                     RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY,
    1158             :                                     RES_TXTATR_INPUTFIELD, RES_TXTATR_INPUTFIELD,
    1159      129952 :                                     0 );
    1160             : 
    1161      129952 :                 aTxtSet.Put( rChgSet );
    1162      129952 :                 if( aTxtSet.Count() )
    1163             :                 {
    1164         940 :                     const sal_Int32 nInsCnt = rSt.GetIndex();
    1165         940 :                     const sal_Int32 nEnd = pStt->nNode == pEnd->nNode
    1166         940 :                                     ? pEnd->nContent.GetIndex()
    1167        1880 :                                     : pNode->Len();
    1168         940 :                     SwRegHistory history( pNode, *pNode, pHistory );
    1169         940 :                     bRet = history.InsertItems( aTxtSet, nInsCnt, nEnd, nFlags )
    1170         940 :                            || bRet;
    1171             : 
    1172         940 :                     if (bRet && (pDoc->getIDocumentRedlineAccess().IsRedlineOn() || (!pDoc->getIDocumentRedlineAccess().IsIgnoreRedline()
    1173         936 :                                     && !pDoc->getIDocumentRedlineAccess().GetRedlineTbl().empty())))
    1174             :                     {
    1175             :                         // Was text content inserted? (RefMark/TOXMarks without an end)
    1176           0 :                         bool bTxtIns = nInsCnt != rSt.GetIndex();
    1177             :                         // Was content inserted or set over the selection?
    1178             :                         SwPaM aPam( pStt->nNode, bTxtIns ? nInsCnt + 1 : nEnd,
    1179           0 :                                     pStt->nNode, nInsCnt );
    1180           0 :                         if( pUndo )
    1181           0 :                             pUndo->SaveRedlineData( aPam, bTxtIns );
    1182             : 
    1183           0 :                         if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
    1184           0 :                             pDoc->getIDocumentRedlineAccess().AppendRedline(
    1185             :                                 new SwRangeRedline(
    1186           0 :                                     bTxtIns ? nsRedlineType_t::REDLINE_INSERT : nsRedlineType_t::REDLINE_FORMAT, aPam ),
    1187           0 :                                     true);
    1188           0 :                         else if( bTxtIns )
    1189           0 :                             pDoc->getIDocumentRedlineAccess().SplitRedline( aPam );
    1190         940 :                     }
    1191      129952 :                 }
    1192             :             }
    1193             :         }
    1194             : 
    1195             :         // We always have to set the auto flag for PageDescs that are set at the Node!
    1196      244696 :         if( pOtherSet && pOtherSet->Count() )
    1197             :         {
    1198             :             SwTableNode* pTblNd;
    1199             :             const SwFmtPageDesc* pDesc;
    1200       78546 :             if( SfxItemState::SET == pOtherSet->GetItemState( RES_PAGEDESC,
    1201       78546 :                             false, (const SfxPoolItem**)&pDesc ))
    1202             :             {
    1203        4426 :                 if( pNode )
    1204             :                 {
    1205             :                     // Set auto flag. Only in the template it's without auto!
    1206        4426 :                     SwFmtPageDesc aNew( *pDesc );
    1207             : 
    1208             :                     // Tables now also know line breaks
    1209        4646 :                     if( 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) &&
    1210         220 :                         0 != ( pTblNd = pNode->FindTableNode() ) )
    1211             :                     {
    1212           0 :                         SwTableNode* pCurTblNd = pTblNd;
    1213           0 :                         while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) )
    1214           0 :                             pTblNd = pCurTblNd;
    1215             : 
    1216             :                         // set the table format
    1217           0 :                         SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt();
    1218           0 :                         SwRegHistory aRegH( pFmt, *pTblNd, pHistory );
    1219           0 :                         pFmt->SetFmtAttr( aNew );
    1220           0 :                         bRet = true;
    1221             :                     }
    1222             :                     else
    1223             :                     {
    1224        4426 :                         SwRegHistory aRegH( pNode, *pNode, pHistory );
    1225        4426 :                         bRet = pNode->SetAttr( aNew ) || bRet;
    1226        4426 :                     }
    1227             :                 }
    1228             : 
    1229             :                 // bOtherAttr = true means that pOtherSet == rChgSet. In this case
    1230             :                 // we know, that there is only one attribute in pOtherSet. We cannot
    1231             :                 // perform the following operations, instead we return:
    1232        4426 :                 if ( bOtherAttr )
    1233        8852 :                     return bRet;
    1234             : 
    1235           0 :                 const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_PAGEDESC );
    1236           0 :                 if( !pOtherSet->Count() )
    1237             :                 {
    1238           0 :                     DELETECHARSETS
    1239           0 :                     return bRet;
    1240             :                 }
    1241             :             }
    1242             : 
    1243             :             // Tables now also know line breaks
    1244             :             const SvxFmtBreakItem* pBreak;
    1245      155656 :             if( pNode && 0 == (nFlags & nsSetAttrMode::SETATTR_APICALL) &&
    1246       84894 :                 0 != (pTblNd = pNode->FindTableNode() ) &&
    1247             :                 SfxItemState::SET == pOtherSet->GetItemState( RES_BREAK,
    1248        3358 :                             false, (const SfxPoolItem**)&pBreak ) )
    1249             :             {
    1250           0 :                 SwTableNode* pCurTblNd = pTblNd;
    1251           0 :                 while ( 0 != ( pCurTblNd = pCurTblNd->StartOfSectionNode()->FindTableNode() ) )
    1252           0 :                     pTblNd = pCurTblNd;
    1253             : 
    1254             :                  // set the table format
    1255           0 :                 SwFrmFmt* pFmt = pTblNd->GetTable().GetFrmFmt();
    1256           0 :                 SwRegHistory aRegH( pFmt, *pTblNd, pHistory );
    1257           0 :                 pFmt->SetFmtAttr( *pBreak );
    1258           0 :                 bRet = true;
    1259             : 
    1260             :                 // bOtherAttr = true means that pOtherSet == rChgSet. In this case
    1261             :                 // we know, that there is only one attribute in pOtherSet. We cannot
    1262             :                 // perform the following operations, instead we return:
    1263           0 :                 if ( bOtherAttr )
    1264           0 :                     return bRet;
    1265             : 
    1266           0 :                 const_cast<SfxItemSet*>(pOtherSet)->ClearItem( RES_BREAK );
    1267           0 :                 if( !pOtherSet->Count() )
    1268             :                 {
    1269           0 :                     DELETECHARSETS
    1270           0 :                     return bRet;
    1271           0 :                 }
    1272             :             }
    1273             : 
    1274             :             {
    1275             :                 // If we have a PoolNumRule, create it if needed
    1276             :                 const SwNumRuleItem* pRule;
    1277       74120 :                 sal_uInt16 nPoolId=0;
    1278       74120 :                 if( SfxItemState::SET == pOtherSet->GetItemState( RES_PARATR_NUMRULE,
    1279       77316 :                                     false, (const SfxPoolItem**)&pRule ) &&
    1280       74626 :                     !pDoc->FindNumRulePtr( pRule->GetValue() ) &&
    1281         506 :                     USHRT_MAX != (nPoolId = SwStyleNameMapper::GetPoolIdFromUIName ( pRule->GetValue(),
    1282             :                                     nsSwGetPoolIdFromName::GET_POOLID_NUMRULE )) )
    1283           0 :                     pDoc->getIDocumentStylePoolAccess().GetNumRuleFromPool( nPoolId );
    1284             :             }
    1285             :         }
    1286             : 
    1287      240270 :         if( !rRg.HasMark() )        // no range
    1288             :         {
    1289       86940 :             if( !pNode )
    1290             :             {
    1291           0 :                 DELETECHARSETS
    1292           0 :                 return bRet;
    1293             :             }
    1294             : 
    1295       86940 :             if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
    1296             :             {
    1297       52998 :                 SwTxtNode* pTxtNd = static_cast<SwTxtNode*>(pNode);
    1298       52998 :                 const SwIndex& rSt = pStt->nContent;
    1299       52998 :                 sal_Int32 nMkPos, nPtPos = rSt.GetIndex();
    1300       52998 :                 const OUString& rStr = pTxtNd->GetTxt();
    1301             : 
    1302             :                 // Special case: if the Crsr is located within a URL attribute, we take over it's area
    1303             :                 SwTxtAttr const*const pURLAttr(
    1304       52998 :                     pTxtNd->GetTxtAttrAt(rSt.GetIndex(), RES_TXTATR_INETFMT));
    1305       52998 :                 if (pURLAttr && !pURLAttr->GetINetFmt().GetValue().isEmpty())
    1306             :                 {
    1307          22 :                     nMkPos = pURLAttr->GetStart();
    1308          22 :                     nPtPos = *pURLAttr->End();
    1309             :                 }
    1310             :                 else
    1311             :                 {
    1312       52976 :                     Boundary aBndry;
    1313       52976 :                     if( g_pBreakIt->GetBreakIter().is() )
    1314      105952 :                         aBndry = g_pBreakIt->GetBreakIter()->getWordBoundary(
    1315       52976 :                                     pTxtNd->GetTxt(), nPtPos,
    1316       52976 :                                     g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
    1317             :                                     WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/,
    1318      105952 :                                     sal_True );
    1319             : 
    1320       52976 :                     if( aBndry.startPos < nPtPos && nPtPos < aBndry.endPos )
    1321             :                     {
    1322           0 :                         nMkPos = aBndry.startPos;
    1323           0 :                         nPtPos = aBndry.endPos;
    1324             :                     }
    1325             :                     else
    1326       52976 :                         nPtPos = nMkPos = rSt.GetIndex();
    1327             :                 }
    1328             : 
    1329             :                 // Remove the overriding attributes from the SwpHintsArray,
    1330             :                 // if the selection spans across the whole paragraph.
    1331             :                 // These attributes are inserted as FormatAttributes and
    1332             :                 // never override the TextAttributes!
    1333      158994 :                 if( !(nFlags & nsSetAttrMode::SETATTR_DONTREPLACE ) &&
    1334       91110 :                     pTxtNd->HasHints() && !nMkPos && nPtPos == rStr.getLength())
    1335             :                 {
    1336          22 :                     SwIndex aSt( pTxtNd );
    1337          22 :                     if( pHistory )
    1338             :                     {
    1339             :                         // Save all attributes for the Undo.
    1340          22 :                         SwRegHistory aRHst( *pTxtNd, pHistory );
    1341          22 :                         pTxtNd->GetpSwpHints()->Register( &aRHst );
    1342          22 :                         pTxtNd->RstTxtAttr( aSt, nPtPos, 0, pCharSet );
    1343          22 :                         if( pTxtNd->GetpSwpHints() )
    1344          22 :                             pTxtNd->GetpSwpHints()->DeRegister();
    1345             :                     }
    1346             :                     else
    1347           0 :                         pTxtNd->RstTxtAttr( aSt, nPtPos, 0, pCharSet );
    1348             :                 }
    1349             : 
    1350             :                 // the SwRegHistory inserts the attribute into the TxtNode!
    1351       52998 :                 SwRegHistory history( pNode, *pNode, pHistory );
    1352       52998 :                 bRet = history.InsertItems( *pCharSet, nMkPos, nPtPos, nFlags )
    1353       52998 :                     || bRet;
    1354             : 
    1355       52998 :                 if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
    1356             :                 {
    1357           0 :                     SwPaM aPam( *pNode, nMkPos, *pNode, nPtPos );
    1358             : 
    1359           0 :                     if( pUndo )
    1360           0 :                         pUndo->SaveRedlineData( aPam, false );
    1361           0 :                     pDoc->getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_FORMAT, aPam ), true);
    1362       52998 :                 }
    1363             :             }
    1364       86940 :             if( pOtherSet && pOtherSet->Count() )
    1365             :             {
    1366       44998 :                 SwRegHistory aRegH( pNode, *pNode, pHistory );
    1367             : 
    1368             :                 //UUUU Need to check for unique item for DrawingLayer items of type NameOrIndex
    1369             :                 // and evtl. correct that item to ensure unique names for that type. This call may
    1370             :                 // modify/correct entries inside of the given SfxItemSet
    1371       89996 :                 SfxItemSet aTempLocalCopy(*pOtherSet);
    1372             : 
    1373       44998 :                 pDoc->CheckForUniqueItemForLineFillNameOrIndex(aTempLocalCopy);
    1374       89996 :                 bRet = pNode->SetAttr(aTempLocalCopy) || bRet;
    1375             :             }
    1376             : 
    1377       86940 :             DELETECHARSETS
    1378       86940 :             return bRet;
    1379             :         }
    1380             : 
    1381      153330 :         if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() && pCharSet && pCharSet->Count() )
    1382             :         {
    1383           0 :             if( pUndo )
    1384           0 :                 pUndo->SaveRedlineData( rRg, false );
    1385           0 :             pDoc->getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_FORMAT, rRg ), true);
    1386             :         }
    1387             : 
    1388             :         /* now if range */
    1389      153330 :         sal_uLong nNodes = 0;
    1390             : 
    1391      153330 :         SwNodeIndex aSt( pDoc->GetNodes() );
    1392      306660 :         SwNodeIndex aEnd( pDoc->GetNodes() );
    1393      306660 :         SwIndex aCntEnd( pEnd->nContent );
    1394             : 
    1395      153330 :         if( pNode )
    1396             :         {
    1397      153330 :             const sal_Int32 nLen = pNode->Len();
    1398      153330 :             if( pStt->nNode != pEnd->nNode )
    1399       12060 :                 aCntEnd.Assign( pNode, nLen );
    1400             : 
    1401      153330 :             if( pStt->nContent.GetIndex() != 0 || aCntEnd.GetIndex() != nLen )
    1402             :             {
    1403             :                 // the SwRegHistory inserts the attribute into the TxtNode!
    1404       71860 :                 if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
    1405             :                 {
    1406       70794 :                     SwRegHistory history( pNode, *pNode, pHistory );
    1407             :                     bRet = history.InsertItems(*pCharSet,
    1408       70794 :                             pStt->nContent.GetIndex(), aCntEnd.GetIndex(), nFlags)
    1409       70794 :                         || bRet;
    1410             :                 }
    1411             : 
    1412       71860 :                 if( pOtherSet && pOtherSet->Count() )
    1413             :                 {
    1414        1490 :                     SwRegHistory aRegH( pNode, *pNode, pHistory );
    1415        1490 :                     bRet = pNode->SetAttr( *pOtherSet ) || bRet;
    1416             :                 }
    1417             : 
    1418             :                 // Only selection in a Node.
    1419       71860 :                 if( pStt->nNode == pEnd->nNode )
    1420             :                 {
    1421             :                 //The data parameter flag: bExpandCharToPara, comes from the data member of SwDoc,
    1422             :                 //Which is set in SW MS word Binary filter WW8ImplRreader. With this flag on, means that
    1423             :                 //current setting attribute set is a character range properties set and comes from a MS word
    1424             :                 //binary file, And the setting range include a paragraph end position (0X0D);
    1425             :                 //More specifications, as such property inside the character range properties set recorded in
    1426             :                 //MS word binary file are dealed and inserted into data model (SwDoc) one by one, so we
    1427             :                 //only dealing the scenario that the char properties set with 1 item inside;
    1428             : 
    1429       65942 :                     if (bExpandCharToPara && pCharSet && pCharSet->Count() ==1 )
    1430             :                     {
    1431         966 :                         SwTxtNode* pCurrentNd = pStt->nNode.GetNode().GetTxtNode();
    1432             : 
    1433         966 :                         if (pCurrentNd)
    1434             :                         {
    1435         966 :                              pCurrentNd->TryCharSetExpandToNum(*pCharSet);
    1436             : 
    1437             :                         }
    1438             :                     }
    1439       65942 :                     DELETECHARSETS
    1440       65942 :                     return bRet;
    1441             :                 }
    1442        5918 :                 ++nNodes;
    1443        5918 :                 aSt.Assign( pStt->nNode.GetNode(), +1 );
    1444             :             }
    1445             :             else
    1446       81470 :                 aSt = pStt->nNode;
    1447       87388 :             aCntEnd = pEnd->nContent; // aEnd was changed!
    1448             :         }
    1449             :         else
    1450           0 :             aSt.Assign( pStt->nNode.GetNode(), +1 );
    1451             : 
    1452             :         // aSt points to the first full Node now
    1453             : 
    1454             :         /*
    1455             :          * The selection spans more than one Node.
    1456             :          */
    1457       87388 :         if( pStt->nNode < pEnd->nNode )
    1458             :         {
    1459       12060 :             pNode = pEnd->nNode.GetNode().GetCntntNode();
    1460       12060 :             if(pNode)
    1461             :             {
    1462       12060 :                 if( aCntEnd.GetIndex() != pNode->Len() )
    1463             :                 {
    1464             :                     // the SwRegHistory inserts the attribute into the TxtNode!
    1465        6120 :                     if( pNode->IsTxtNode() && pCharSet && pCharSet->Count() )
    1466             :                     {
    1467        6074 :                         SwRegHistory history( pNode, *pNode, pHistory );
    1468             :                         (void)history.InsertItems(*pCharSet,
    1469        6074 :                                 0, aCntEnd.GetIndex(), nFlags);
    1470             :                     }
    1471             : 
    1472        6120 :                     if( pOtherSet && pOtherSet->Count() )
    1473             :                     {
    1474          46 :                         SwRegHistory aRegH( pNode, *pNode, pHistory );
    1475          46 :                         pNode->SetAttr( *pOtherSet );
    1476             :                     }
    1477             : 
    1478        6120 :                     ++nNodes;
    1479        6120 :                     aEnd = pEnd->nNode;
    1480             :                 }
    1481             :                 else
    1482        5940 :                     aEnd.Assign( pEnd->nNode.GetNode(), +1 );
    1483             :             }
    1484             :             else
    1485           0 :                 aEnd = pEnd->nNode;
    1486             :         }
    1487             :         else
    1488       75328 :             aEnd.Assign( pEnd->nNode.GetNode(), +1 );
    1489             : 
    1490             :         // aEnd points BEHIND the last full node now
    1491             : 
    1492             :         /* Edit the fully selected Nodes. */
    1493             :         // Reset all attributes from the set!
    1494       87388 :         if( pCharSet && pCharSet->Count() && !( nsSetAttrMode::SETATTR_DONTREPLACE & nFlags ) )
    1495             :         {
    1496       52788 :             ::sw::DocumentContentOperationsManager::ParaRstFmt aPara( pStt, pEnd, pHistory, 0, pCharSet );
    1497       52788 :             pDoc->GetNodes().ForEach( aSt, aEnd, ::sw::DocumentContentOperationsManager::lcl_RstTxtAttr, &aPara );
    1498             :         }
    1499             : 
    1500      151360 :         bool bCreateSwpHints = pCharSet && (
    1501      118012 :             SfxItemState::SET == pCharSet->GetItemState( RES_TXTATR_CHARFMT, false ) ||
    1502      145420 :             SfxItemState::SET == pCharSet->GetItemState( RES_TXTATR_INETFMT, false ) );
    1503             : 
    1504      193764 :         for(; aSt < aEnd; ++aSt )
    1505             :         {
    1506      106376 :             pNode = aSt.GetNode().GetCntntNode();
    1507      106376 :             if( !pNode )
    1508       12872 :                 continue;
    1509             : 
    1510       93504 :             SwTxtNode* pTNd = pNode->GetTxtNode();
    1511       93504 :             if( pHistory )
    1512             :             {
    1513       14114 :                 SwRegHistory aRegH( pNode, *pNode, pHistory );
    1514             :                 SwpHints *pSwpHints;
    1515             : 
    1516       14114 :                 if( pTNd && pCharSet && pCharSet->Count() )
    1517             :                 {
    1518             :                     pSwpHints = bCreateSwpHints ? &pTNd->GetOrCreateSwpHints()
    1519        5740 :                                                 : pTNd->GetpSwpHints();
    1520        5740 :                     if( pSwpHints )
    1521         986 :                         pSwpHints->Register( &aRegH );
    1522             : 
    1523        5740 :                     pTNd->SetAttr(*pCharSet, 0, pTNd->GetTxt().getLength(), nFlags);
    1524        5740 :                     if( pSwpHints )
    1525         986 :                         pSwpHints->DeRegister();
    1526             :                 }
    1527       14114 :                 if( pOtherSet && pOtherSet->Count() )
    1528        4118 :                     pNode->SetAttr( *pOtherSet );
    1529             :             }
    1530             :             else
    1531             :             {
    1532       79390 :                 if( pTNd && pCharSet && pCharSet->Count() )
    1533       52134 :                     pTNd->SetAttr(*pCharSet, 0, pTNd->GetTxt().getLength(), nFlags);
    1534       79390 :                 if( pOtherSet && pOtherSet->Count() )
    1535       24600 :                     pNode->SetAttr( *pOtherSet );
    1536             :             }
    1537       93504 :             ++nNodes;
    1538             :         }
    1539             : 
    1540             :         //The data parameter flag: bExpandCharToPara, comes from the data member of SwDoc,
    1541             :         //Which is set in SW MS word Binary filter WW8ImplRreader. With this flag on, means that
    1542             :         //current setting attribute set is a character range properties set and comes from a MS word
    1543             :         //binary file, And the setting range include a paragraph end position (0X0D);
    1544             :         //More specifications, as such property inside the character range properties set recorded in
    1545             :         //MS word binary file are dealed and inserted into data model (SwDoc) one by one, so we
    1546             :         //only dealing the scenario that the char properties set with 1 item inside;
    1547       87388 :         if (bExpandCharToPara && pCharSet && pCharSet->Count() ==1)
    1548             :         {
    1549        3990 :             SwPosition aStartPos (*rRg.Start());
    1550        7980 :             SwPosition aEndPos (*rRg.End());
    1551             : 
    1552        3990 :             if (aEndPos.nNode.GetNode().GetTxtNode() && aEndPos.nContent != aEndPos.nNode.GetNode().GetTxtNode()->Len())
    1553        1228 :                 aEndPos.nNode--;
    1554             : 
    1555        3990 :             sal_uLong nStart = aStartPos.nNode.GetIndex();
    1556        3990 :             sal_uLong nEnd = aEndPos.nNode.GetIndex();
    1557       13894 :             for(; nStart <= nEnd; ++nStart)
    1558             :             {
    1559        9904 :                 SwNode* pNd = pDoc->GetNodes()[ nStart ];
    1560        9904 :                 if (!pNd || !pNd->IsTxtNode())
    1561         340 :                     continue;
    1562        9564 :                 SwTxtNode *pCurrentNd = (SwTxtNode*)pNd;
    1563        9564 :                 pCurrentNd->TryCharSetExpandToNum(*pCharSet);
    1564        3990 :             }
    1565             :         }
    1566             : 
    1567       87388 :         DELETECHARSETS
    1568      240718 :         return (nNodes != 0) || bRet;
    1569             :     }
    1570             : }
    1571             : 
    1572             : namespace sw
    1573             : {
    1574             : 
    1575        5052 : DocumentContentOperationsManager::DocumentContentOperationsManager( SwDoc& i_rSwdoc ) : m_rSwdoc( i_rSwdoc )
    1576             : {
    1577        5052 : }
    1578             : 
    1579             : // Copy an area into this document or into another document
    1580             : bool
    1581         406 : DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, const bool bCopyAll ) const
    1582             : {
    1583         406 :     const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
    1584             : 
    1585         406 :     SwDoc* pDoc = rPos.nNode.GetNode().GetDoc();
    1586         406 :     bool bColumnSel = pDoc->IsClipBoard() && pDoc->IsColumnSelection();
    1587             : 
    1588             :     // Catch if there's no copy to do
    1589         406 :     if( !rPam.HasMark() || ( *pStt > *pEnd && !bColumnSel ) )
    1590           0 :         return false;
    1591             : 
    1592             :     // Prevent copying in Flys that are anchored in the area
    1593         406 :     if( pDoc == &m_rSwdoc )
    1594             :     {
    1595             :         // Correct the Start-/EndNode
    1596         370 :         sal_uLong nStt = pStt->nNode.GetIndex(),
    1597         370 :                 nEnd = pEnd->nNode.GetIndex(),
    1598         370 :                 nDiff = nEnd - nStt +1;
    1599         370 :         SwNode* pNd = m_rSwdoc.GetNodes()[ nStt ];
    1600         370 :         if( pNd->IsCntntNode() && pStt->nContent.GetIndex() )
    1601           2 :             ++nStt, --nDiff;
    1602         740 :         if( (pNd = m_rSwdoc.GetNodes()[ nEnd ])->IsCntntNode() &&
    1603         370 :             ((SwCntntNode*)pNd)->Len() != pEnd->nContent.GetIndex() )
    1604           0 :             --nEnd, --nDiff;
    1605         738 :         if( nDiff &&
    1606         368 :             lcl_ChkFlyFly( pDoc, nStt, nEnd, rPos.nNode.GetIndex() ) )
    1607             :         {
    1608           0 :             return false;
    1609             :         }
    1610             :     }
    1611             : 
    1612         406 :     SwPaM* pRedlineRange = 0;
    1613         822 :     if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() ||
    1614         810 :         (!pDoc->getIDocumentRedlineAccess().IsIgnoreRedline() && !pDoc->getIDocumentRedlineAccess().GetRedlineTbl().empty() ) )
    1615          10 :         pRedlineRange = new SwPaM( rPos );
    1616             : 
    1617         406 :     RedlineMode_t eOld = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
    1618             : 
    1619         406 :     bool bRet = false;
    1620             : 
    1621         406 :     if( pDoc != &m_rSwdoc )
    1622             :     {   // ordinary copy
    1623          36 :         bRet = CopyImpl( rPam, rPos, true, bCopyAll, pRedlineRange );
    1624             :     }
    1625         964 :     else if( ! ( *pStt <= rPos && rPos < *pEnd &&
    1626           0 :             ( pStt->nNode != pEnd->nNode ||
    1627         740 :               !pStt->nNode.GetNode().IsTxtNode() )) )
    1628             :     {
    1629             :         // Copy to a position outside of the area, or copy a single TextNode
    1630             :         // Do an ordinary copy
    1631         370 :         bRet = CopyImpl( rPam, rPos, true, bCopyAll, pRedlineRange );
    1632             :     }
    1633             :     else
    1634             :     {
    1635             :         // Copy the area in itself
    1636             :         // Special case for handling an area with several nodes,
    1637             :         // or a single node that is not a TextNode
    1638             :         OSL_ENSURE( &m_rSwdoc == pDoc, " invalid copy branch!" );
    1639             :         OSL_FAIL("mst: i thought this could be dead code;"
    1640             :                 "please tell me what you did to get here!");
    1641           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
    1642             : 
    1643             :         // Then copy the area to the underlying document area
    1644             :         // (with start/end nodes clamped) and move them to
    1645             :         // the desired position.
    1646             : 
    1647           0 :         SwUndoCpyDoc* pUndo = 0;
    1648             :         // Save the Undo area
    1649           0 :         SwPaM aPam( rPos );
    1650           0 :         if (pDoc->GetIDocumentUndoRedo().DoesUndo())
    1651             :         {
    1652           0 :             pDoc->GetIDocumentUndoRedo().ClearRedo();
    1653           0 :             pUndo = new SwUndoCpyDoc( aPam );
    1654             :         }
    1655             : 
    1656             :         {
    1657           0 :             ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
    1658           0 :             SwStartNode* pSttNd = pDoc->GetNodes().MakeEmptySection(
    1659           0 :                                 SwNodeIndex( m_rSwdoc.GetNodes().GetEndOfAutotext() ));
    1660           0 :             aPam.GetPoint()->nNode = *pSttNd->EndOfSectionNode();
    1661             :             // copy without Frames
    1662           0 :             pDoc->GetDocumentContentOperationsManager().CopyImpl( rPam, *aPam.GetPoint(), false, bCopyAll, 0 );
    1663             : 
    1664           0 :             aPam.GetPoint()->nNode = pDoc->GetNodes().GetEndOfAutotext();
    1665           0 :             aPam.SetMark();
    1666             :             SwCntntNode* pNode =
    1667           0 :                 pDoc->GetNodes().GoPrevious( &aPam.GetMark()->nNode );
    1668           0 :             pNode->MakeEndIndex( &aPam.GetMark()->nContent );
    1669             : 
    1670           0 :             aPam.GetPoint()->nNode = *aPam.GetNode().StartOfSectionNode();
    1671           0 :             pNode = pDoc->GetNodes().GoNext( &aPam.GetPoint()->nNode );
    1672           0 :             pNode->MakeStartIndex( &aPam.GetPoint()->nContent );
    1673             :             // move to desired position
    1674           0 :             pDoc->getIDocumentContentOperations().MoveRange( aPam, rPos, DOC_MOVEDEFAULT );
    1675             : 
    1676           0 :             pNode = aPam.GetCntntNode();
    1677           0 :             *aPam.GetPoint() = rPos;      // Move the cursor for Undo
    1678           0 :             aPam.SetMark();               // also move the Mark
    1679           0 :             aPam.DeleteMark();            // But don't mark any area
    1680           0 :             pDoc->getIDocumentContentOperations().DeleteSection( pNode ); // Delete the area again
    1681             :         }
    1682             : 
    1683             :         // if Undo is enabled, store the insertion range
    1684           0 :         if (pDoc->GetIDocumentUndoRedo().DoesUndo())
    1685             :         {
    1686           0 :             pUndo->SetInsertRange( aPam );
    1687           0 :             pDoc->GetIDocumentUndoRedo().AppendUndo(pUndo);
    1688             :         }
    1689             : 
    1690           0 :         if( pRedlineRange )
    1691             :         {
    1692           0 :             pRedlineRange->SetMark();
    1693           0 :             *pRedlineRange->GetPoint() = *aPam.GetPoint();
    1694           0 :             *pRedlineRange->GetMark() = *aPam.GetMark();
    1695             :         }
    1696             : 
    1697           0 :         pDoc->getIDocumentState().SetModified();
    1698           0 :         bRet = true;
    1699             :     }
    1700             : 
    1701         406 :     pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
    1702         406 :     if( pRedlineRange )
    1703             :     {
    1704          10 :         if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
    1705           0 :             pDoc->getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, *pRedlineRange ), true);
    1706             :         else
    1707          10 :             pDoc->getIDocumentRedlineAccess().SplitRedline( *pRedlineRange );
    1708          10 :         delete pRedlineRange;
    1709             :     }
    1710             : 
    1711         406 :     return bRet;
    1712             : }
    1713             : 
    1714             : /// Delete a full Section of the NodeArray.
    1715             : /// The passed Node is located somewhere in the designated Section.
    1716        6986 : void DocumentContentOperationsManager::DeleteSection( SwNode *pNode )
    1717             : {
    1718             :     assert(pNode && "Didn't pass a Node.");
    1719             : 
    1720        6986 :     SwStartNode* pSttNd = pNode->IsStartNode() ? (SwStartNode*)pNode
    1721        6986 :                                                : pNode->StartOfSectionNode();
    1722       13972 :     SwNodeIndex aSttIdx( *pSttNd ), aEndIdx( *pNode->EndOfSectionNode() );
    1723             : 
    1724             :     // delete all Flys, Bookmarks, ...
    1725        6986 :     DelFlyInRange( aSttIdx, aEndIdx );
    1726        6986 :     m_rSwdoc.getIDocumentRedlineAccess().DeleteRedline( *pSttNd, true, USHRT_MAX );
    1727        6986 :     _DelBookmarks(aSttIdx, aEndIdx);
    1728             : 
    1729             :     {
    1730             :         // move all Crsr/StkCrsr/UnoCrsr out of the to-be-deleted area
    1731        6986 :         SwNodeIndex aMvStt( aSttIdx, 1 );
    1732        6986 :         m_rSwdoc.CorrAbs( aMvStt, aEndIdx, SwPosition( aSttIdx ), true );
    1733             :     }
    1734             : 
    1735       13972 :     m_rSwdoc.GetNodes().DelNodes( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() + 1 );
    1736        6986 : }
    1737             : 
    1738         870 : bool DocumentContentOperationsManager::DeleteRange( SwPaM & rPam )
    1739             : {
    1740         870 :     return lcl_DoWithBreaks( *this, rPam, &DocumentContentOperationsManager::DeleteRangeImpl );
    1741             : }
    1742             : 
    1743        5955 : bool DocumentContentOperationsManager::DelFullPara( SwPaM& rPam )
    1744             : {
    1745        5955 :     const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
    1746        5955 :     const SwNode* pNd = &rStt.nNode.GetNode();
    1747        5955 :     sal_uInt32 nSectDiff = pNd->StartOfSectionNode()->EndOfSectionIndex() -
    1748        5955 :                         pNd->StartOfSectionIndex();
    1749        5955 :     sal_uInt32 nNodeDiff = rEnd.nNode.GetIndex() - rStt.nNode.GetIndex();
    1750             : 
    1751       11019 :     if ( nSectDiff-2 <= nNodeDiff || m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn() ||
    1752             :          /* #i9185# Prevent getting the node after the end node (see below) */
    1753        5064 :         rEnd.nNode.GetIndex() + 1 == m_rSwdoc.GetNodes().Count() )
    1754             :     {
    1755         891 :         return false;
    1756             :     }
    1757             : 
    1758             :     // Move hard page brakes to the following Node.
    1759        5064 :     bool bSavePageBreak = false, bSavePageDesc = false;
    1760             : 
    1761             :     /* #i9185# This whould lead to a segmentation fault if not caught above. */
    1762        5064 :     sal_uLong nNextNd = rEnd.nNode.GetIndex() + 1;
    1763        5064 :     SwTableNode *const pTblNd = m_rSwdoc.GetNodes()[ nNextNd ]->GetTableNode();
    1764             : 
    1765        5064 :     if( pTblNd && pNd->IsCntntNode() )
    1766             :     {
    1767         386 :         SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
    1768             : 
    1769             :         {
    1770             :             const SfxPoolItem *pItem;
    1771         386 :             const SfxItemSet* pSet = ((SwCntntNode*)pNd)->GetpSwAttrSet();
    1772         708 :             if( pSet && SfxItemState::SET == pSet->GetItemState( RES_PAGEDESC,
    1773         322 :                 false, &pItem ) )
    1774             :             {
    1775         304 :                 pTableFmt->SetFmtAttr( *pItem );
    1776         304 :                 bSavePageDesc = true;
    1777             :             }
    1778             : 
    1779         708 :             if( pSet && SfxItemState::SET == pSet->GetItemState( RES_BREAK,
    1780         322 :                 false, &pItem ) )
    1781             :             {
    1782           0 :                 pTableFmt->SetFmtAttr( *pItem );
    1783           0 :                 bSavePageBreak = true;
    1784             :             }
    1785             :         }
    1786             :     }
    1787             : 
    1788        5064 :     bool const bDoesUndo = m_rSwdoc.GetIDocumentUndoRedo().DoesUndo();
    1789        5064 :     if( bDoesUndo )
    1790             :     {
    1791         438 :         if( !rPam.HasMark() )
    1792         438 :             rPam.SetMark();
    1793           0 :         else if( rPam.GetPoint() == &rStt )
    1794           0 :             rPam.Exchange();
    1795         438 :         rPam.GetPoint()->nNode++;
    1796             : 
    1797         438 :         SwCntntNode *pTmpNode = rPam.GetPoint()->nNode.GetNode().GetCntntNode();
    1798         438 :         rPam.GetPoint()->nContent.Assign( pTmpNode, 0 );
    1799         438 :         bool bGoNext = (0 == pTmpNode);
    1800         438 :         pTmpNode = rPam.GetMark()->nNode.GetNode().GetCntntNode();
    1801         438 :         rPam.GetMark()->nContent.Assign( pTmpNode, 0 );
    1802             : 
    1803         438 :         m_rSwdoc.GetIDocumentUndoRedo().ClearRedo();
    1804             : 
    1805         438 :         SwPaM aDelPam( *rPam.GetMark(), *rPam.GetPoint() );
    1806             :         {
    1807         438 :             SwPosition aTmpPos( *aDelPam.GetPoint() );
    1808         438 :             if( bGoNext )
    1809             :             {
    1810         438 :                 pTmpNode = m_rSwdoc.GetNodes().GoNext( &aTmpPos.nNode );
    1811         438 :                 aTmpPos.nContent.Assign( pTmpNode, 0 );
    1812             :             }
    1813         438 :             ::PaMCorrAbs( aDelPam, aTmpPos );
    1814             :         }
    1815             : 
    1816         438 :         SwUndoDelete* pUndo = new SwUndoDelete( aDelPam, true );
    1817             : 
    1818         438 :         *rPam.GetPoint() = *aDelPam.GetPoint();
    1819         438 :         pUndo->SetPgBrkFlags( bSavePageBreak, bSavePageDesc );
    1820         438 :         m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
    1821             :     }
    1822             :     else
    1823             :     {
    1824        4626 :         SwNodeRange aRg( rStt.nNode, rEnd.nNode );
    1825        4626 :         if( rPam.GetPoint() != &rEnd )
    1826           0 :             rPam.Exchange();
    1827             : 
    1828             :         // Try to move past the End
    1829        4626 :         if( !rPam.Move( fnMoveForward, fnGoNode ) )
    1830             :         {
    1831             :             // Fair enough, at the Beginning then
    1832        3278 :             rPam.Exchange();
    1833        3278 :             if( !rPam.Move( fnMoveBackward, fnGoNode ))
    1834             :             {
    1835             :                 OSL_FAIL( "no more Nodes" );
    1836           0 :                 return false;
    1837             :             }
    1838             :         }
    1839             :         // move bookmarks, redlines etc.
    1840        4626 :         if (aRg.aStart == aRg.aEnd) // only first CorrAbs variant handles this
    1841             :         {
    1842        4626 :             m_rSwdoc.CorrAbs( aRg.aStart, *rPam.GetPoint(), 0, true );
    1843             :         }
    1844             :         else
    1845             :         {
    1846           0 :             m_rSwdoc.CorrAbs( aRg.aStart, aRg.aEnd, *rPam.GetPoint(), true );
    1847             :         }
    1848             : 
    1849             :             // What's with Flys?
    1850             :         {
    1851             :             // If there are FlyFrames left, delete these too
    1852       17990 :             for( size_t n = 0; n < m_rSwdoc.GetSpzFrmFmts()->size(); ++n )
    1853             :             {
    1854       13364 :                 SwFrmFmt* pFly = (*m_rSwdoc.GetSpzFrmFmts())[n];
    1855       13364 :                 const SwFmtAnchor* pAnchor = &pFly->GetAnchor();
    1856       13364 :                 SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
    1857       26562 :                 if (pAPos &&
    1858       17080 :                     ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
    1859       14474 :                      (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
    1860       31144 :                     aRg.aStart <= pAPos->nNode && pAPos->nNode <= aRg.aEnd )
    1861             :                 {
    1862          12 :                     m_rSwdoc.getIDocumentLayoutAccess().DelLayoutFmt( pFly );
    1863          12 :                     --n;
    1864             :                 }
    1865             :             }
    1866             :         }
    1867             : 
    1868        4626 :         SwCntntNode *pTmpNode = rPam.GetBound( true ).nNode.GetNode().GetCntntNode();
    1869        4626 :         rPam.GetBound( true ).nContent.Assign( pTmpNode, 0 );
    1870        4626 :         pTmpNode = rPam.GetBound( false ).nNode.GetNode().GetCntntNode();
    1871        4626 :         rPam.GetBound( false ).nContent.Assign( pTmpNode, 0 );
    1872        4626 :         m_rSwdoc.GetNodes().Delete( aRg.aStart, nNodeDiff+1 );
    1873             :     }
    1874        5064 :     rPam.DeleteMark();
    1875        5064 :     m_rSwdoc.getIDocumentState().SetModified();
    1876             : 
    1877        5064 :     return true;
    1878             : }
    1879             : 
    1880             : // #i100466# Add handling of new optional parameter <bForceJoinNext>
    1881        9629 : bool DocumentContentOperationsManager::DeleteAndJoin( SwPaM & rPam,
    1882             :                            const bool bForceJoinNext )
    1883             : {
    1884        9629 :     if ( lcl_StrLenOverflow( rPam ) )
    1885           0 :         return false;
    1886             : 
    1887        9629 :     return lcl_DoWithBreaks( *this, rPam, (m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn())
    1888             :                 ? &DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl
    1889             :                 : &DocumentContentOperationsManager::DeleteAndJoinImpl,
    1890       19258 :                 bForceJoinNext );
    1891             : }
    1892             : 
    1893             : // It seems that this is mostly used by SwDoc internals; the only
    1894             : // way to call this from the outside seems to be the special case in
    1895             : // SwDoc::CopyRange (but I have not managed to actually hit that case).
    1896        5226 : bool DocumentContentOperationsManager::MoveRange( SwPaM& rPaM, SwPosition& rPos, SwMoveFlags eMvFlags )
    1897             : {
    1898             :     // nothing moved: return
    1899        5226 :     const SwPosition *pStt = rPaM.Start(), *pEnd = rPaM.End();
    1900        5226 :     if( !rPaM.HasMark() || *pStt >= *pEnd || (*pStt <= rPos && rPos < *pEnd))
    1901        5214 :         return false;
    1902             : 
    1903             :     // Save the paragraph anchored Flys, so that they can be moved.
    1904          12 :     _SaveFlyArr aSaveFlyArr;
    1905          12 :     _SaveFlyInRange( rPaM, rPos.nNode, aSaveFlyArr, 0 != ( DOC_MOVEALLFLYS & eMvFlags ) );
    1906             : 
    1907             :     // save redlines (if DOC_MOVEREDLINES is used)
    1908          24 :     _SaveRedlines aSaveRedl;
    1909          12 :     if( DOC_MOVEREDLINES & eMvFlags && !m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().empty() )
    1910             :     {
    1911           0 :         lcl_SaveRedlines( rPaM, aSaveRedl );
    1912             : 
    1913             :         // #i17764# unfortunately, code below relies on undos being
    1914             :         //          in a particular order, and presence of bookmarks
    1915             :         //          will change this order. Hence, we delete bookmarks
    1916             :         //          here without undo.
    1917           0 :         ::sw::UndoGuard const undoGuard(m_rSwdoc.GetIDocumentUndoRedo());
    1918             :         _DelBookmarks(
    1919             :             pStt->nNode,
    1920             :             pEnd->nNode,
    1921             :             NULL,
    1922             :             &pStt->nContent,
    1923           0 :             &pEnd->nContent);
    1924             :     }
    1925             : 
    1926          12 :     bool bUpdateFtn = false;
    1927          24 :     SwFtnIdxs aTmpFntIdx;
    1928             : 
    1929          12 :     SwUndoMove * pUndoMove = 0;
    1930          12 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    1931             :     {
    1932           0 :         m_rSwdoc.GetIDocumentUndoRedo().ClearRedo();
    1933           0 :         pUndoMove = new SwUndoMove( rPaM, rPos );
    1934           0 :         pUndoMove->SetMoveRedlines( eMvFlags == DOC_MOVEREDLINES );
    1935             :     }
    1936             :     else
    1937             :     {
    1938             :         bUpdateFtn = lcl_SaveFtn( pStt->nNode, pEnd->nNode, rPos.nNode,
    1939          12 :                                     m_rSwdoc.GetFtnIdxs(), aTmpFntIdx,
    1940          24 :                                     &pStt->nContent, &pEnd->nContent );
    1941             :     }
    1942             : 
    1943          12 :     bool bSplit = false;
    1944          24 :     SwPaM aSavePam( rPos, rPos );
    1945             : 
    1946             :     // Move the SPoint to the beginning of the range
    1947          12 :     if( rPaM.GetPoint() == pEnd )
    1948          12 :         rPaM.Exchange();
    1949             : 
    1950             :     // If there is a TextNode before and after the Move, create a JoinNext in the EditShell.
    1951          12 :     SwTxtNode* pSrcNd = rPaM.GetPoint()->nNode.GetNode().GetTxtNode();
    1952          12 :     bool bCorrSavePam = pSrcNd && pStt->nNode != pEnd->nNode;
    1953             : 
    1954             :     // If one ore more TextNodes are moved, SwNodes::Move will do a SplitNode.
    1955             :     // However, this does not update the cursor. So we create a TextNode to keep
    1956             :     // updating the indices. After the Move the Node is optionally deleted.
    1957          12 :     SwTxtNode * pTNd = rPos.nNode.GetNode().GetTxtNode();
    1958          24 :     if( pTNd && rPaM.GetPoint()->nNode != rPaM.GetMark()->nNode &&
    1959           6 :         ( rPos.nContent.GetIndex() || ( pTNd->Len() && bCorrSavePam  )) )
    1960             :     {
    1961           6 :         bSplit = true;
    1962           6 :         const sal_Int32 nMkCntnt = rPaM.GetMark()->nContent.GetIndex();
    1963             : 
    1964           6 :         const boost::shared_ptr<sw::mark::CntntIdxStore> pCntntStore(sw::mark::CntntIdxStore::Create());
    1965           6 :         pCntntStore->Save( &m_rSwdoc, rPos.nNode.GetIndex(), rPos.nContent.GetIndex(), true );
    1966             : 
    1967           6 :         pTNd = static_cast<SwTxtNode*>(pTNd->SplitCntntNode( rPos ));
    1968             : 
    1969           6 :         if( !pCntntStore->Empty() )
    1970           2 :             pCntntStore->Restore( &m_rSwdoc, rPos.nNode.GetIndex()-1, 0, true );
    1971             : 
    1972             :         // correct the PaM!
    1973           6 :         if( rPos.nNode == rPaM.GetMark()->nNode )
    1974             :         {
    1975           0 :             rPaM.GetMark()->nNode = rPos.nNode.GetIndex()-1;
    1976           0 :             rPaM.GetMark()->nContent.Assign( pTNd, nMkCntnt );
    1977           6 :         }
    1978             :     }
    1979             : 
    1980             :     // Put back the Pam by one "content"; so that it's always outside of
    1981             :     // the manipulated range.
    1982             :     // If there's no content anymore, set it to the StartNode (that's
    1983             :     // always there).
    1984          12 :     const bool bNullCntnt = !aSavePam.Move( fnMoveBackward, fnGoCntnt );
    1985          12 :     if( bNullCntnt )
    1986             :     {
    1987           2 :         aSavePam.GetPoint()->nNode--;
    1988             :     }
    1989             : 
    1990             :     // Copy all Bookmarks that are within the Move range into an array,
    1991             :     // that saves the position as an offset.
    1992          24 :     ::std::vector< ::sw::mark::SaveBookmark> aSaveBkmks;
    1993             :     _DelBookmarks(
    1994             :         pStt->nNode,
    1995             :         pEnd->nNode,
    1996             :         &aSaveBkmks,
    1997             :         &pStt->nContent,
    1998          12 :         &pEnd->nContent);
    1999             : 
    2000             :     // If there is no range anymore due to the above deletions (e.g. the
    2001             :     // footnotes got deleted), it's still a valid Move!
    2002          12 :     if( *rPaM.GetPoint() != *rPaM.GetMark() )
    2003             :     {
    2004             :         // now do the actual move
    2005          12 :         m_rSwdoc.GetNodes().MoveRange( rPaM, rPos, m_rSwdoc.GetNodes() );
    2006             : 
    2007             :         // after a MoveRange() the Mark is deleted
    2008          12 :         if ( rPaM.HasMark() ) // => no Move occurred!
    2009             :         {
    2010           0 :             delete pUndoMove;
    2011           0 :             return false;
    2012             :         }
    2013             :     }
    2014             :     else
    2015           0 :         rPaM.DeleteMark();
    2016             : 
    2017             :     OSL_ENSURE( *aSavePam.GetMark() == rPos ||
    2018             :             ( aSavePam.GetMark()->nNode.GetNode().GetCntntNode() == NULL ),
    2019             :             "PaM was not moved. Aren't there ContentNodes at the beginning/end?" );
    2020          12 :     *aSavePam.GetMark() = rPos;
    2021             : 
    2022          12 :     rPaM.SetMark();         // create a Sel. around the new range
    2023          12 :     pTNd = aSavePam.GetNode().GetTxtNode();
    2024          12 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    2025             :     {
    2026             :         // correct the SavePam's Content first
    2027           0 :         if( bNullCntnt )
    2028             :         {
    2029           0 :             aSavePam.GetPoint()->nContent = 0;
    2030             :         }
    2031             : 
    2032             :         // The method SwEditShell::Move() merges the TextNode after the Move,
    2033             :         // where the rPaM is located.
    2034             :         // If the Content was moved to the back and the SavePam's SPoint is
    2035             :         // in the next Node, we have to deal with this when saving the Undo object!
    2036           0 :         SwTxtNode * pPamTxtNd = 0;
    2037             : 
    2038             :         // Is passed to SwUndoMove, which happens when subsequently calling Undo JoinNext.
    2039             :         // If it's not possible to call Undo JoinNext here.
    2040           0 :         bool bJoin = bSplit && pTNd;
    2041           0 :         bCorrSavePam = bCorrSavePam &&
    2042           0 :                         0 != ( pPamTxtNd = rPaM.GetNode().GetTxtNode() )
    2043           0 :                         && pPamTxtNd->CanJoinNext()
    2044           0 :                         && (*rPaM.GetPoint() <= *aSavePam.GetPoint());
    2045             : 
    2046             :         // Do two Nodes have to be joined at the SavePam?
    2047           0 :         if( bJoin && pTNd->CanJoinNext() )
    2048             :         {
    2049           0 :             pTNd->JoinNext();
    2050             :             // No temporary Index when using &&.
    2051             :             // We probably only want to compare the indices.
    2052           0 :             if( bCorrSavePam && rPaM.GetPoint()->nNode.GetIndex()+1 ==
    2053           0 :                                 aSavePam.GetPoint()->nNode.GetIndex() )
    2054             :             {
    2055           0 :                 aSavePam.GetPoint()->nContent += pPamTxtNd->Len();
    2056             :             }
    2057           0 :             bJoin = false;
    2058             :         }
    2059           0 :         else if ( !aSavePam.Move( fnMoveForward, fnGoCntnt ) )
    2060             :         {
    2061           0 :             aSavePam.GetPoint()->nNode++;
    2062             :         }
    2063             : 
    2064             :         // The newly inserted range is now inbetween SPoint and GetMark.
    2065           0 :         pUndoMove->SetDestRange( aSavePam, *rPaM.GetPoint(),
    2066           0 :                                     bJoin, bCorrSavePam );
    2067           0 :         m_rSwdoc.GetIDocumentUndoRedo().AppendUndo( pUndoMove );
    2068             :     }
    2069             :     else
    2070             :     {
    2071          12 :         bool bRemove = true;
    2072             :         // Do two Nodes have to be joined at the SavePam?
    2073          12 :         if( bSplit && pTNd )
    2074             :         {
    2075           6 :             if( pTNd->CanJoinNext())
    2076             :             {
    2077             :                 // Always join next, because <pTNd> has to stay as it is.
    2078             :                 // A join previous from its next would more or less delete <pTNd>
    2079           6 :                 pTNd->JoinNext();
    2080           6 :                 bRemove = false;
    2081             :             }
    2082             :         }
    2083          12 :         if( bNullCntnt )
    2084             :         {
    2085           2 :             aSavePam.GetPoint()->nNode++;
    2086           2 :             aSavePam.GetPoint()->nContent.Assign( aSavePam.GetCntntNode(), 0 );
    2087             :         }
    2088          10 :         else if( bRemove ) // No move forward after joining with next paragraph
    2089             :         {
    2090           4 :             aSavePam.Move( fnMoveForward, fnGoCntnt );
    2091             :         }
    2092             :     }
    2093             : 
    2094             :     // Insert the Bookmarks back into the Document.
    2095          12 :     *rPaM.GetMark() = *aSavePam.Start();
    2096          36 :     for(
    2097          12 :         ::std::vector< ::sw::mark::SaveBookmark>::iterator pBkmk = aSaveBkmks.begin();
    2098          24 :         pBkmk != aSaveBkmks.end();
    2099             :         ++pBkmk)
    2100             :         pBkmk->SetInDoc(
    2101             :             &m_rSwdoc,
    2102           0 :             rPaM.GetMark()->nNode,
    2103           0 :             &rPaM.GetMark()->nContent);
    2104          12 :     *rPaM.GetPoint() = *aSavePam.End();
    2105             : 
    2106             :     // Move the Flys to the new position.
    2107          12 :     _RestFlyInRange( aSaveFlyArr, rPaM.Start()->nNode, &(rPos.nNode) );
    2108             : 
    2109             :     // restore redlines (if DOC_MOVEREDLINES is used)
    2110          12 :     if( !aSaveRedl.empty() )
    2111             :     {
    2112           0 :         lcl_RestoreRedlines( &m_rSwdoc, *aSavePam.Start(), aSaveRedl );
    2113             :     }
    2114             : 
    2115          12 :     if( bUpdateFtn )
    2116             :     {
    2117           0 :         if( !aTmpFntIdx.empty() )
    2118             :         {
    2119           0 :             m_rSwdoc.GetFtnIdxs().insert( aTmpFntIdx );
    2120           0 :             aTmpFntIdx.clear();
    2121             :         }
    2122             : 
    2123           0 :         m_rSwdoc.GetFtnIdxs().UpdateAllFtn();
    2124             :     }
    2125             : 
    2126          12 :     m_rSwdoc.getIDocumentState().SetModified();
    2127          24 :     return true;
    2128             : }
    2129             : 
    2130         132 : bool DocumentContentOperationsManager::MoveNodeRange( SwNodeRange& rRange, SwNodeIndex& rPos,
    2131             :         SwMoveFlags eMvFlags )
    2132             : {
    2133             :     // Moves all Nodes to the new position.
    2134             :     // Bookmarks are moved too (currently without Undo support).
    2135             : 
    2136             :     // If footnotes are being moved to the special section, remove them now.
    2137             : 
    2138             :     // Or else delete the Frames for all footnotes that are being moved
    2139             :     // and have it rebuild after the Move (footnotes can change pages).
    2140             :     // Additionally we have to correct the FtnIdx array's sorting.
    2141         132 :     bool bUpdateFtn = false;
    2142         132 :     SwFtnIdxs aTmpFntIdx;
    2143             : 
    2144         132 :     SwUndoMove* pUndo = 0;
    2145         132 :     if ((DOC_CREATEUNDOOBJ & eMvFlags ) && m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    2146             :     {
    2147           0 :         pUndo = new SwUndoMove( &m_rSwdoc, rRange, rPos );
    2148             :     }
    2149             :     else
    2150             :     {
    2151             :         bUpdateFtn = lcl_SaveFtn( rRange.aStart, rRange.aEnd, rPos,
    2152         132 :                                     m_rSwdoc.GetFtnIdxs(), aTmpFntIdx );
    2153             :     }
    2154             : 
    2155         264 :     _SaveRedlines aSaveRedl;
    2156         264 :     std::vector<SwRangeRedline*> aSavRedlInsPosArr;
    2157         132 :     if( DOC_MOVEREDLINES & eMvFlags && !m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().empty() )
    2158             :     {
    2159           0 :         lcl_SaveRedlines( rRange, aSaveRedl );
    2160             : 
    2161             :         // Find all RedLines that end at the InsPos.
    2162             :         // These have to be moved back to the "old" position after the Move.
    2163           0 :         sal_uInt16 nRedlPos = m_rSwdoc.getIDocumentRedlineAccess().GetRedlinePos( rPos.GetNode(), USHRT_MAX );
    2164           0 :         if( USHRT_MAX != nRedlPos )
    2165             :         {
    2166             :             const SwPosition *pRStt, *pREnd;
    2167           0 :             do {
    2168           0 :                 SwRangeRedline* pTmp = m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl()[ nRedlPos ];
    2169           0 :                 pRStt = pTmp->Start();
    2170           0 :                 pREnd = pTmp->End();
    2171           0 :                 if( pREnd->nNode == rPos && pRStt->nNode < rPos )
    2172             :                 {
    2173           0 :                     aSavRedlInsPosArr.push_back( pTmp );
    2174             :                 }
    2175           0 :             } while( pRStt->nNode < rPos && ++nRedlPos < m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().size());
    2176             :         }
    2177             :     }
    2178             : 
    2179             :     // Copy all Bookmarks that are within the Move range into an array
    2180             :     // that stores all references to positions as an offset.
    2181             :     // The final mapping happens after the Move.
    2182         264 :     ::std::vector< ::sw::mark::SaveBookmark> aSaveBkmks;
    2183         132 :     _DelBookmarks(rRange.aStart, rRange.aEnd, &aSaveBkmks);
    2184             : 
    2185             :     // Save the paragraph-bound Flys, so that they can be moved.
    2186         264 :     _SaveFlyArr aSaveFlyArr;
    2187         132 :     if( !m_rSwdoc.GetSpzFrmFmts()->empty() )
    2188           0 :         _SaveFlyInRange( rRange, aSaveFlyArr );
    2189             : 
    2190             :     // Set it to before the Position, so that it cannot be moved further.
    2191         264 :     SwNodeIndex aIdx( rPos, -1 );
    2192             : 
    2193         132 :     SwNodeIndex* pSaveInsPos = 0;
    2194         132 :     if( pUndo )
    2195           0 :         pSaveInsPos = new SwNodeIndex( rRange.aStart, -1 );
    2196             : 
    2197             :     // move the Nodes
    2198         132 :     bool bNoDelFrms = 0 != (DOC_NO_DELFRMS & eMvFlags);
    2199         132 :     if( m_rSwdoc.GetNodes()._MoveNodes( rRange, m_rSwdoc.GetNodes(), rPos, !bNoDelFrms ) )
    2200             :     {
    2201         108 :         ++aIdx;     // again back to old position
    2202         108 :         if( pSaveInsPos )
    2203           0 :             ++(*pSaveInsPos);
    2204             :     }
    2205             :     else
    2206             :     {
    2207          24 :         aIdx = rRange.aStart;
    2208          24 :         delete pUndo, pUndo = 0;
    2209             :     }
    2210             : 
    2211             :     // move the Flys to the new position
    2212         132 :     if( !aSaveFlyArr.empty() )
    2213           0 :         _RestFlyInRange( aSaveFlyArr, aIdx, NULL );
    2214             : 
    2215             :     // Add the Bookmarks back to the Document
    2216         396 :     for(
    2217         132 :         ::std::vector< ::sw::mark::SaveBookmark>::iterator pBkmk = aSaveBkmks.begin();
    2218         264 :         pBkmk != aSaveBkmks.end();
    2219             :         ++pBkmk)
    2220           0 :         pBkmk->SetInDoc(&m_rSwdoc, aIdx);
    2221             : 
    2222         132 :     if( !aSavRedlInsPosArr.empty() )
    2223             :     {
    2224           0 :         SwNode* pNewNd = &aIdx.GetNode();
    2225           0 :         for( size_t n = 0; n < aSavRedlInsPosArr.size(); ++n )
    2226             :         {
    2227           0 :             SwRangeRedline* pTmp = aSavRedlInsPosArr[ n ];
    2228           0 :             if( m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().Contains( pTmp ) )
    2229             :             {
    2230           0 :                 SwPosition* pEnd = pTmp->End();
    2231           0 :                 pEnd->nNode = aIdx;
    2232           0 :                 pEnd->nContent.Assign( pNewNd->GetCntntNode(), 0 );
    2233             :             }
    2234             :         }
    2235             :     }
    2236             : 
    2237         132 :     if( !aSaveRedl.empty() )
    2238           0 :         lcl_RestoreRedlines( &m_rSwdoc, aIdx.GetIndex(), aSaveRedl );
    2239             : 
    2240         132 :     if( pUndo )
    2241             :     {
    2242           0 :         pUndo->SetDestRange( aIdx, rPos, *pSaveInsPos );
    2243           0 :         m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
    2244             :     }
    2245             : 
    2246         132 :     delete pSaveInsPos;
    2247             : 
    2248         132 :     if( bUpdateFtn )
    2249             :     {
    2250           0 :         if( !aTmpFntIdx.empty() )
    2251             :         {
    2252           0 :             m_rSwdoc.GetFtnIdxs().insert( aTmpFntIdx );
    2253           0 :             aTmpFntIdx.clear();
    2254             :         }
    2255             : 
    2256           0 :         m_rSwdoc.GetFtnIdxs().UpdateAllFtn();
    2257             :     }
    2258             : 
    2259         132 :     m_rSwdoc.getIDocumentState().SetModified();
    2260         264 :     return true;
    2261             : }
    2262             : 
    2263           0 : bool DocumentContentOperationsManager::MoveAndJoin( SwPaM& rPaM, SwPosition& rPos, SwMoveFlags eMvFlags )
    2264             : {
    2265           0 :     SwNodeIndex aIdx( rPaM.Start()->nNode );
    2266           0 :     bool bJoinTxt = aIdx.GetNode().IsTxtNode();
    2267           0 :     bool bOneNode = rPaM.GetPoint()->nNode == rPaM.GetMark()->nNode;
    2268           0 :     aIdx--;             // in front of the move area!
    2269             : 
    2270           0 :     bool bRet = MoveRange( rPaM, rPos, eMvFlags );
    2271           0 :     if( bRet && !bOneNode )
    2272             :     {
    2273           0 :         if( bJoinTxt )
    2274           0 :             ++aIdx;
    2275           0 :         SwTxtNode * pTxtNd = aIdx.GetNode().GetTxtNode();
    2276           0 :         SwNodeIndex aNxtIdx( aIdx );
    2277           0 :         if( pTxtNd && pTxtNd->CanJoinNext( &aNxtIdx ) )
    2278             :         {
    2279             :             {   // Block so SwIndex into node is deleted before Join
    2280             :                 m_rSwdoc.CorrRel( aNxtIdx, SwPosition( aIdx, SwIndex(pTxtNd,
    2281           0 :                             pTxtNd->GetTxt().getLength()) ), 0, true );
    2282             :             }
    2283           0 :             pTxtNd->JoinNext();
    2284           0 :         }
    2285             :     }
    2286           0 :     return bRet;
    2287             : }
    2288             : 
    2289        2624 : bool DocumentContentOperationsManager::Overwrite( const SwPaM &rRg, const OUString &rStr )
    2290             : {
    2291        2624 :     SwPosition& rPt = *(SwPosition*)rRg.GetPoint();
    2292        2624 :     if( m_rSwdoc.GetAutoCorrExceptWord() )                  // Add to AutoCorrect
    2293             :     {
    2294           0 :         if( 1 == rStr.getLength() )
    2295           0 :             m_rSwdoc.GetAutoCorrExceptWord()->CheckChar( rPt, rStr[ 0 ] );
    2296           0 :         m_rSwdoc.DeleteAutoCorrExceptWord();
    2297             :     }
    2298             : 
    2299        2624 :     SwTxtNode *pNode = rPt.nNode.GetNode().GetTxtNode();
    2300        2624 :     if (!pNode || rStr.getLength() > pNode->GetSpaceLeft()) // worst case: no erase
    2301             :     {
    2302         904 :         return false;
    2303             :     }
    2304             : 
    2305        1720 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    2306             :     {
    2307           0 :         m_rSwdoc.GetIDocumentUndoRedo().ClearRedo(); // AppendUndo not always called
    2308             :     }
    2309             : 
    2310        1720 :     const size_t nOldAttrCnt = pNode->GetpSwpHints()
    2311        1720 :                                 ? pNode->GetpSwpHints()->Count() : 0;
    2312        1720 :     SwDataChanged aTmp( rRg );
    2313        1720 :     SwIndex& rIdx = rPt.nContent;
    2314        1720 :     sal_Int32 nStart = 0;
    2315             : 
    2316        1720 :     bool bOldExpFlg = pNode->IsIgnoreDontExpand();
    2317        1720 :     pNode->SetIgnoreDontExpand( true );
    2318             : 
    2319       10749 :     for( sal_Int32 nCnt = 0; nCnt < rStr.getLength(); ++nCnt )
    2320             :     {
    2321             :         // start behind the characters (to fix the attributes!)
    2322        9029 :         nStart = rIdx.GetIndex();
    2323        9029 :         if  (nStart < pNode->GetTxt().getLength())
    2324             :         {
    2325           0 :             lcl_SkipAttr( pNode, rIdx, nStart );
    2326             :         }
    2327        9029 :         sal_Unicode c = rStr[ nCnt ];
    2328        9029 :         if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    2329             :         {
    2330           0 :             bool bMerged(false);
    2331           0 :             if (m_rSwdoc.GetIDocumentUndoRedo().DoesGroupUndo())
    2332             :             {
    2333           0 :                 SwUndo *const pUndo = m_rSwdoc.GetUndoManager().GetLastUndo();
    2334             :                 SwUndoOverwrite *const pUndoOW(
    2335           0 :                     dynamic_cast<SwUndoOverwrite *>(pUndo) );
    2336           0 :                 if (pUndoOW)
    2337             :                 {
    2338             :                     // if CanGrouping() returns true it's already merged
    2339           0 :                     bMerged = pUndoOW->CanGrouping( &m_rSwdoc, rPt, c );
    2340             :                 }
    2341             :             }
    2342           0 :             if (!bMerged)
    2343             :             {
    2344           0 :                 SwUndo *const pUndoOW( new SwUndoOverwrite(&m_rSwdoc, rPt, c) );
    2345           0 :                 m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndoOW);
    2346             :             }
    2347             :         }
    2348             :         else
    2349             :         {
    2350             :             // start behind the characters (to fix the attributes!)
    2351        9029 :             if (nStart < pNode->GetTxt().getLength())
    2352           0 :                 ++rIdx;
    2353        9029 :             pNode->InsertText( OUString(c), rIdx, INS_EMPTYEXPAND );
    2354        9029 :             if( nStart+1 < rIdx.GetIndex() )
    2355             :             {
    2356           0 :                 rIdx = nStart;
    2357           0 :                 pNode->EraseText( rIdx, 1 );
    2358           0 :                 ++rIdx;
    2359             :             }
    2360             :         }
    2361             :     }
    2362        1720 :     pNode->SetIgnoreDontExpand( bOldExpFlg );
    2363             : 
    2364        1720 :     const size_t nNewAttrCnt = pNode->GetpSwpHints()
    2365        1720 :                                 ? pNode->GetpSwpHints()->Count() : 0;
    2366        1720 :     if( nOldAttrCnt != nNewAttrCnt )
    2367             :     {
    2368             :         SwUpdateAttr aHint(
    2369             :             0,
    2370             :             0,
    2371           0 :             0);
    2372             : 
    2373           0 :         pNode->ModifyBroadcast( 0, &aHint, TYPE( SwCrsrShell ) );
    2374             :     }
    2375             : 
    2376        5160 :     if (!m_rSwdoc.GetIDocumentUndoRedo().DoesUndo() &&
    2377        3010 :         !m_rSwdoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().empty())
    2378             :     {
    2379         600 :         SwPaM aPam( rPt.nNode, nStart, rPt.nNode, rPt.nContent.GetIndex() );
    2380         600 :         m_rSwdoc.getIDocumentRedlineAccess().DeleteRedline( aPam, true, USHRT_MAX );
    2381             :     }
    2382        1120 :     else if( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn() )
    2383             :     {
    2384             :         // FIXME: this redline is WRONG: there is no DELETE, and the skipped
    2385             :         // characters are also included in aPam
    2386         250 :         SwPaM aPam( rPt.nNode, nStart, rPt.nNode, rPt.nContent.GetIndex() );
    2387         250 :         m_rSwdoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
    2388             :     }
    2389             : 
    2390        1720 :     m_rSwdoc.getIDocumentState().SetModified();
    2391        1720 :     return true;
    2392             : }
    2393             : 
    2394      219348 : bool DocumentContentOperationsManager::InsertString( const SwPaM &rRg, const OUString &rStr,
    2395             :         const enum InsertFlags nInsertMode )
    2396             : {
    2397             :     // fetching DoesUndo is surprisingly expensive
    2398      219348 :     bool bDoesUndo = m_rSwdoc.GetIDocumentUndoRedo().DoesUndo();
    2399      219348 :     if (bDoesUndo)
    2400       16506 :         m_rSwdoc.GetIDocumentUndoRedo().ClearRedo(); // AppendUndo not always called!
    2401             : 
    2402      219348 :     const SwPosition& rPos = *rRg.GetPoint();
    2403             : 
    2404      219348 :     if( m_rSwdoc.GetAutoCorrExceptWord() )                  // add to auto correction
    2405             :     {
    2406           0 :         if( 1 == rStr.getLength() && m_rSwdoc.GetAutoCorrExceptWord()->IsDeleted() )
    2407             :         {
    2408           0 :             m_rSwdoc.GetAutoCorrExceptWord()->CheckChar( rPos, rStr[ 0 ] );
    2409             :         }
    2410           0 :         m_rSwdoc.DeleteAutoCorrExceptWord();
    2411             :     }
    2412             : 
    2413      219348 :     SwTxtNode *const pNode = rPos.nNode.GetNode().GetTxtNode();
    2414      219348 :     if(!pNode)
    2415        1846 :         return false;
    2416             : 
    2417      217502 :     SwDataChanged aTmp( rRg );
    2418             : 
    2419      217502 :     if (!bDoesUndo || !m_rSwdoc.GetIDocumentUndoRedo().DoesGroupUndo())
    2420             :     {
    2421      217302 :         OUString const ins(pNode->InsertText(rStr, rPos.nContent, nInsertMode));
    2422      217302 :         if (bDoesUndo)
    2423             :         {
    2424             :             SwUndoInsert * const pUndo( new SwUndoInsert(rPos.nNode,
    2425       16306 :                     rPos.nContent.GetIndex(), ins.getLength(), nInsertMode));
    2426       16306 :             m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
    2427      217302 :         }
    2428             :     }
    2429             :     else
    2430             :     {   // if Undo and grouping is enabled, everything changes!
    2431         200 :         SwUndoInsert * pUndo = NULL;
    2432             : 
    2433             :         // don't group the start if hints at the start should be expanded
    2434         200 :         if (!(nInsertMode & IDocumentContentOperations::INS_FORCEHINTEXPAND))
    2435             :         {
    2436         198 :             SwUndo *const pLastUndo = m_rSwdoc.GetUndoManager().GetLastUndo();
    2437             :             SwUndoInsert *const pUndoInsert(
    2438         198 :                 dynamic_cast<SwUndoInsert *>(pLastUndo) );
    2439         198 :             if (pUndoInsert && pUndoInsert->CanGrouping(rPos))
    2440             :             {
    2441          94 :                 pUndo = pUndoInsert;
    2442             :             }
    2443             :         }
    2444             : 
    2445         200 :         CharClass const& rCC = GetAppCharClass();
    2446         200 :         sal_Int32 nInsPos = rPos.nContent.GetIndex();
    2447             : 
    2448         200 :         if (!pUndo)
    2449             :         {
    2450             :             pUndo = new SwUndoInsert( rPos.nNode, nInsPos, 0, nInsertMode,
    2451         106 :                             !rCC.isLetterNumeric( rStr, 0 ) );
    2452         106 :             m_rSwdoc.GetIDocumentUndoRedo().AppendUndo( pUndo );
    2453             :         }
    2454             : 
    2455         200 :         OUString const ins(pNode->InsertText(rStr, rPos.nContent, nInsertMode));
    2456             : 
    2457         816 :         for (sal_Int32 i = 0; i < ins.getLength(); ++i)
    2458             :         {
    2459         616 :             nInsPos++;
    2460             :             // if CanGrouping() returns true, everything has already been done
    2461         616 :             if (!pUndo->CanGrouping(ins[i]))
    2462             :             {
    2463             :                 pUndo = new SwUndoInsert(rPos.nNode, nInsPos, 1, nInsertMode,
    2464          74 :                             !rCC.isLetterNumeric(ins, i));
    2465          74 :                 m_rSwdoc.GetIDocumentUndoRedo().AppendUndo( pUndo );
    2466             :             }
    2467         200 :         }
    2468             :     }
    2469             : 
    2470             :     // To-Do - add 'SwExtraRedlineTbl' also ?
    2471      217502 :     if( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn() || (!m_rSwdoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().empty() ))
    2472             :     {
    2473             :         SwPaM aPam( rPos.nNode, aTmp.GetCntnt(),
    2474        3476 :                     rPos.nNode, rPos.nContent.GetIndex());
    2475        3476 :         if( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn() )
    2476             :         {
    2477        1854 :             m_rSwdoc.getIDocumentRedlineAccess().AppendRedline(
    2478        1854 :                 new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
    2479             :         }
    2480             :         else
    2481             :         {
    2482        1622 :             m_rSwdoc.getIDocumentRedlineAccess().SplitRedline( aPam );
    2483        3476 :         }
    2484             :     }
    2485             : 
    2486      217502 :     m_rSwdoc.getIDocumentState().SetModified();
    2487      217502 :     return true;
    2488             : }
    2489             : 
    2490          12 : void DocumentContentOperationsManager::TransliterateText(
    2491             :     const SwPaM& rPaM,
    2492             :     utl::TransliterationWrapper& rTrans )
    2493             : {
    2494          12 :     SwUndoTransliterate *const pUndo = (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    2495           0 :         ?   new SwUndoTransliterate( rPaM, rTrans )
    2496          12 :         :   0;
    2497             : 
    2498          12 :     const SwPosition* pStt = rPaM.Start(),
    2499          12 :                        * pEnd = rPaM.End();
    2500          12 :     sal_uLong nSttNd = pStt->nNode.GetIndex(),
    2501          12 :           nEndNd = pEnd->nNode.GetIndex();
    2502          12 :     sal_Int32 nSttCnt = pStt->nContent.GetIndex();
    2503          12 :     sal_Int32 nEndCnt = pEnd->nContent.GetIndex();
    2504             : 
    2505          12 :     SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode();
    2506          12 :     if( pStt == pEnd && pTNd )  // no selection?
    2507             :     {
    2508             :         // set current word as 'area of effect'
    2509             : 
    2510           0 :         Boundary aBndry;
    2511           0 :         if( g_pBreakIt->GetBreakIter().is() )
    2512           0 :             aBndry = g_pBreakIt->GetBreakIter()->getWordBoundary(
    2513           0 :                         pTNd->GetTxt(), nSttCnt,
    2514           0 :                         g_pBreakIt->GetLocale( pTNd->GetLang( nSttCnt ) ),
    2515             :                         WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/,
    2516           0 :                         sal_True );
    2517             : 
    2518           0 :         if( aBndry.startPos < nSttCnt && nSttCnt < aBndry.endPos )
    2519             :         {
    2520           0 :             nSttCnt = aBndry.startPos;
    2521           0 :             nEndCnt = aBndry.endPos;
    2522             :         }
    2523             :     }
    2524             : 
    2525          12 :     if( nSttNd != nEndNd )  // is more than one text node involved?
    2526             :     {
    2527             :         // iterate over all effected text nodes, the first and the last one
    2528             :         // may be incomplete because the selection starts and/or ends there
    2529             : 
    2530           0 :         SwNodeIndex aIdx( pStt->nNode );
    2531           0 :         if( nSttCnt )
    2532             :         {
    2533           0 :             ++aIdx;
    2534           0 :             if( pTNd )
    2535             :                 pTNd->TransliterateText(
    2536           0 :                         rTrans, nSttCnt, pTNd->GetTxt().getLength(), pUndo);
    2537             :         }
    2538             : 
    2539           0 :         for( ; aIdx.GetIndex() < nEndNd; ++aIdx )
    2540             :         {
    2541           0 :             pTNd = aIdx.GetNode().GetTxtNode();
    2542           0 :             if (pTNd)
    2543             :             {
    2544             :                 pTNd->TransliterateText(
    2545           0 :                         rTrans, 0, pTNd->GetTxt().getLength(), pUndo);
    2546             :             }
    2547             :         }
    2548             : 
    2549           0 :         if( nEndCnt && 0 != ( pTNd = pEnd->nNode.GetNode().GetTxtNode() ))
    2550           0 :             pTNd->TransliterateText( rTrans, 0, nEndCnt, pUndo );
    2551             :     }
    2552          12 :     else if( pTNd && nSttCnt < nEndCnt )
    2553          12 :         pTNd->TransliterateText( rTrans, nSttCnt, nEndCnt, pUndo );
    2554             : 
    2555          12 :     if( pUndo )
    2556             :     {
    2557           0 :         if( pUndo->HasData() )
    2558             :         {
    2559           0 :             m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
    2560             :         }
    2561             :         else
    2562           0 :             delete pUndo;
    2563             :     }
    2564          12 :     m_rSwdoc.getIDocumentState().SetModified();
    2565          12 : }
    2566             : 
    2567         506 : SwFlyFrmFmt* DocumentContentOperationsManager::Insert( const SwPaM &rRg,
    2568             :                             const OUString& rGrfName,
    2569             :                             const OUString& rFltName,
    2570             :                             const Graphic* pGraphic,
    2571             :                             const SfxItemSet* pFlyAttrSet,
    2572             :                             const SfxItemSet* pGrfAttrSet,
    2573             :                             SwFrmFmt* pFrmFmt )
    2574             : {
    2575         506 :     if( !pFrmFmt )
    2576         506 :         pFrmFmt = m_rSwdoc.getIDocumentStylePoolAccess().GetFrmFmtFromPool( RES_POOLFRM_GRAPHIC );
    2577         506 :     SwGrfNode* pSwGrfNode = m_rSwdoc.GetNodes().MakeGrfNode(
    2578         506 :                             SwNodeIndex( m_rSwdoc.GetNodes().GetEndOfAutotext() ),
    2579             :                             rGrfName, rFltName, pGraphic,
    2580        1518 :                             m_rSwdoc.GetDfltGrfFmtColl() );
    2581         506 :     SwFlyFrmFmt* pSwFlyFrmFmt = _InsNoTxtNode( *rRg.GetPoint(), pSwGrfNode,
    2582         506 :                             pFlyAttrSet, pGrfAttrSet, pFrmFmt );
    2583         506 :     return pSwFlyFrmFmt;
    2584             : }
    2585             : 
    2586         292 : SwFlyFrmFmt* DocumentContentOperationsManager::Insert( const SwPaM &rRg, const GraphicObject& rGrfObj,
    2587             :                             const SfxItemSet* pFlyAttrSet,
    2588             :                             const SfxItemSet* pGrfAttrSet,
    2589             :                             SwFrmFmt* pFrmFmt )
    2590             : {
    2591         292 :     if( !pFrmFmt )
    2592           0 :         pFrmFmt = m_rSwdoc.getIDocumentStylePoolAccess().GetFrmFmtFromPool( RES_POOLFRM_GRAPHIC );
    2593         292 :     SwGrfNode* pSwGrfNode = m_rSwdoc.GetNodes().MakeGrfNode(
    2594         292 :                             SwNodeIndex( m_rSwdoc.GetNodes().GetEndOfAutotext() ),
    2595         876 :                             rGrfObj, m_rSwdoc.GetDfltGrfFmtColl() );
    2596         292 :     SwFlyFrmFmt* pSwFlyFrmFmt = _InsNoTxtNode( *rRg.GetPoint(), pSwGrfNode,
    2597         292 :                             pFlyAttrSet, pGrfAttrSet, pFrmFmt );
    2598         292 :     return pSwFlyFrmFmt;
    2599             : }
    2600             : 
    2601         730 : SwFlyFrmFmt* DocumentContentOperationsManager::Insert(const SwPaM &rRg, const svt::EmbeddedObjectRef& xObj,
    2602             :                         const SfxItemSet* pFlyAttrSet,
    2603             :                         const SfxItemSet* pGrfAttrSet,
    2604             :                         SwFrmFmt* pFrmFmt )
    2605             : {
    2606         730 :     if( !pFrmFmt )
    2607             :     {
    2608         730 :         sal_uInt16 nId = RES_POOLFRM_OLE;
    2609         730 :         SvGlobalName aClassName( xObj->getClassID() );
    2610         730 :         if (SotExchange::IsMath(aClassName))
    2611         534 :             nId = RES_POOLFRM_FORMEL;
    2612             : 
    2613         730 :         pFrmFmt = m_rSwdoc.getIDocumentStylePoolAccess().GetFrmFmtFromPool( nId );
    2614             :     }
    2615        1460 :     return _InsNoTxtNode( *rRg.GetPoint(), m_rSwdoc.GetNodes().MakeOLENode(
    2616         730 :                             SwNodeIndex( m_rSwdoc.GetNodes().GetEndOfAutotext() ),
    2617             :                             xObj,
    2618        2920 :                             m_rSwdoc.GetDfltGrfFmtColl() ),
    2619             :                             pFlyAttrSet, pGrfAttrSet,
    2620        1460 :                             pFrmFmt );
    2621             : }
    2622             : 
    2623         148 : SwFlyFrmFmt* DocumentContentOperationsManager::InsertOLE(const SwPaM &rRg, const OUString& rObjName,
    2624             :                         sal_Int64 nAspect,
    2625             :                         const SfxItemSet* pFlyAttrSet,
    2626             :                         const SfxItemSet* pGrfAttrSet,
    2627             :                         SwFrmFmt* pFrmFmt )
    2628             : {
    2629         148 :     if( !pFrmFmt )
    2630         148 :         pFrmFmt = m_rSwdoc.getIDocumentStylePoolAccess().GetFrmFmtFromPool( RES_POOLFRM_OLE );
    2631             : 
    2632         148 :     return _InsNoTxtNode( *rRg.GetPoint(),
    2633         148 :                             m_rSwdoc.GetNodes().MakeOLENode(
    2634         148 :                                 SwNodeIndex( m_rSwdoc.GetNodes().GetEndOfAutotext() ),
    2635             :                                 rObjName,
    2636             :                                 nAspect,
    2637             :                                 m_rSwdoc.GetDfltGrfFmtColl(),
    2638         592 :                                 0 ),
    2639             :                             pFlyAttrSet, pGrfAttrSet,
    2640         296 :                             pFrmFmt );
    2641             : }
    2642             : 
    2643          12 : void DocumentContentOperationsManager::ReRead( SwPaM& rPam, const OUString& rGrfName,
    2644             :                     const OUString& rFltName, const Graphic* pGraphic,
    2645             :                     const GraphicObject* pGrafObj )
    2646             : {
    2647             :     SwGrfNode *pGrfNd;
    2648          24 :     if( ( !rPam.HasMark()
    2649           0 :          || rPam.GetPoint()->nNode.GetIndex() == rPam.GetMark()->nNode.GetIndex() )
    2650          24 :          && 0 != ( pGrfNd = rPam.GetPoint()->nNode.GetNode().GetGrfNode() ) )
    2651             :     {
    2652          12 :         if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    2653             :         {
    2654          12 :             m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(new SwUndoReRead(rPam, *pGrfNd));
    2655             :         }
    2656             : 
    2657             :         // Because we don't know if we can mirror the graphic, the mirror attribute is always reset
    2658          24 :         if( RES_MIRROR_GRAPH_DONT != pGrfNd->GetSwAttrSet().
    2659          12 :                                                 GetMirrorGrf().GetValue() )
    2660           2 :             pGrfNd->SetAttr( SwMirrorGrf() );
    2661             : 
    2662          12 :         pGrfNd->ReRead( rGrfName, rFltName, pGraphic, pGrafObj, true );
    2663          12 :         m_rSwdoc.getIDocumentState().SetModified();
    2664             :     }
    2665          12 : }
    2666             : 
    2667             : // Insert drawing object, which has to be already inserted in the DrawModel
    2668        4020 : SwDrawFrmFmt* DocumentContentOperationsManager::InsertDrawObj(
    2669             :     const SwPaM &rRg,
    2670             :     SdrObject& rDrawObj,
    2671             :     const SfxItemSet& rFlyAttrSet )
    2672             : {
    2673        4020 :     SwDrawFrmFmt* pFmt = m_rSwdoc.MakeDrawFrmFmt( OUString(), m_rSwdoc.GetDfltFrmFmt() );
    2674             : 
    2675        4020 :     const SwFmtAnchor* pAnchor = 0;
    2676        4020 :     rFlyAttrSet.GetItemState( RES_ANCHOR, false, (const SfxPoolItem**) &pAnchor );
    2677        4020 :     pFmt->SetFmtAttr( rFlyAttrSet );
    2678             : 
    2679             :     // Didn't set the Anchor yet?
    2680             :     // DrawObjecte must never end up in the Header/Footer!
    2681        4020 :     RndStdIds eAnchorId = pAnchor != NULL ? pAnchor->GetAnchorId() : pFmt->GetAnchor().GetAnchorId();
    2682        4020 :     const bool bIsAtCntnt = (FLY_AT_PAGE != eAnchorId);
    2683             : 
    2684        4020 :     const SwNodeIndex* pChkIdx = 0;
    2685        4020 :     if ( pAnchor == NULL )
    2686             :     {
    2687           0 :         pChkIdx = &rRg.GetPoint()->nNode;
    2688             :     }
    2689        4020 :     else if ( bIsAtCntnt )
    2690             :     {
    2691             :         pChkIdx =
    2692         776 :             pAnchor->GetCntntAnchor() ? &pAnchor->GetCntntAnchor()->nNode : &rRg.GetPoint()->nNode;
    2693             :     }
    2694             : 
    2695             :     // allow drawing objects in header/footer, but control objects aren't allowed in header/footer.
    2696        4020 :     if( pChkIdx != NULL
    2697         776 :         && ::CheckControlLayer( &rDrawObj )
    2698        4550 :         && m_rSwdoc.IsInHeaderFooter( *pChkIdx ) )
    2699             :     {
    2700             :         // apply at-page anchor format
    2701           0 :         eAnchorId = FLY_AT_PAGE;
    2702           0 :         pFmt->SetFmtAttr( SwFmtAnchor( eAnchorId ) );
    2703             :     }
    2704        8040 :     else if( pAnchor == NULL
    2705        4196 :              || ( bIsAtCntnt
    2706         776 :                   && pAnchor->GetCntntAnchor() == NULL ) )
    2707             :     {
    2708             :         // apply anchor format
    2709         176 :         SwFmtAnchor aAnch( pAnchor != NULL ? *pAnchor : pFmt->GetAnchor() );
    2710         176 :         eAnchorId = aAnch.GetAnchorId();
    2711         176 :         if ( eAnchorId == FLY_AT_FLY )
    2712             :         {
    2713          18 :             SwPosition aPos( *rRg.GetNode().FindFlyStartNode() );
    2714          18 :             aAnch.SetAnchor( &aPos );
    2715             :         }
    2716             :         else
    2717             :         {
    2718         158 :             aAnch.SetAnchor( rRg.GetPoint() );
    2719         158 :             if ( eAnchorId == FLY_AT_PAGE )
    2720             :             {
    2721           0 :                 eAnchorId = rDrawObj.ISA( SdrUnoObj ) ? FLY_AS_CHAR : FLY_AT_PARA;
    2722           0 :                 aAnch.SetType( eAnchorId );
    2723             :             }
    2724             :         }
    2725         176 :         pFmt->SetFmtAttr( aAnch );
    2726             :     }
    2727             : 
    2728             :     // insert text attribute for as-character anchored drawing object
    2729        4020 :     if ( eAnchorId == FLY_AS_CHAR )
    2730             :     {
    2731         566 :         bool bAnchorAtPageAsFallback = true;
    2732         566 :         const SwFmtAnchor& rDrawObjAnchorFmt = pFmt->GetAnchor();
    2733         566 :         if ( rDrawObjAnchorFmt.GetCntntAnchor() != NULL )
    2734             :         {
    2735             :             SwTxtNode* pAnchorTxtNode =
    2736         566 :                     rDrawObjAnchorFmt.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
    2737         566 :             if ( pAnchorTxtNode != NULL )
    2738             :             {
    2739         566 :                 const sal_Int32 nStt = rDrawObjAnchorFmt.GetCntntAnchor()->nContent.GetIndex();
    2740         566 :                 SwFmtFlyCnt aFmt( pFmt );
    2741         566 :                 pAnchorTxtNode->InsertItem( aFmt, nStt, nStt );
    2742         566 :                 bAnchorAtPageAsFallback = false;
    2743             :             }
    2744             :         }
    2745             : 
    2746         566 :         if ( bAnchorAtPageAsFallback )
    2747             :         {
    2748             :             OSL_ENSURE( false, "DocumentContentOperationsManager::InsertDrawObj(..) - missing content anchor for as-character anchored drawing object --> anchor at-page" );
    2749           0 :             pFmt->SetFmtAttr( SwFmtAnchor( FLY_AT_PAGE ) );
    2750             :         }
    2751             :     }
    2752             : 
    2753        4020 :     SwDrawContact* pContact = new SwDrawContact( pFmt, &rDrawObj );
    2754             : 
    2755             :     // Create Frames if necessary
    2756        4020 :     if( m_rSwdoc.getIDocumentLayoutAccess().GetCurrentViewShell() )
    2757             :     {
    2758             :         // create layout representation
    2759         502 :         pFmt->MakeFrms();
    2760             :         // #i42319# - follow-up of #i35635#
    2761             :         // move object to visible layer
    2762             :         // #i79391#
    2763         502 :         if ( pContact->GetAnchorFrm() )
    2764             :         {
    2765         502 :             pContact->MoveObjToVisibleLayer( &rDrawObj );
    2766             :         }
    2767             :     }
    2768             : 
    2769        4020 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    2770             :     {
    2771         502 :         m_rSwdoc.GetIDocumentUndoRedo().AppendUndo( new SwUndoInsLayFmt(pFmt, 0, 0) );
    2772             :     }
    2773             : 
    2774        4020 :     m_rSwdoc.getIDocumentState().SetModified();
    2775        4020 :     return pFmt;
    2776             : }
    2777             : 
    2778        1238 : bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool bChkTableStart )
    2779             : {
    2780        1238 :     SwCntntNode *pNode = rPos.nNode.GetNode().GetCntntNode();
    2781        1238 :     if(0 == pNode)
    2782           0 :         return false;
    2783             : 
    2784             :     {
    2785             :         // BUG 26675: Send DataChanged before deleting, so that we notice which objects are in scope.
    2786             :         //            After that they can be before/after the position.
    2787        1238 :         SwDataChanged aTmp( &m_rSwdoc, rPos );
    2788             :     }
    2789             : 
    2790        1238 :     SwUndoSplitNode* pUndo = 0;
    2791        1238 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    2792             :     {
    2793         664 :         m_rSwdoc.GetIDocumentUndoRedo().ClearRedo();
    2794             :         // insert the Undo object (currently only for TextNode)
    2795         664 :         if( pNode->IsTxtNode() )
    2796             :         {
    2797         664 :             pUndo = new SwUndoSplitNode( &m_rSwdoc, rPos, bChkTableStart );
    2798         664 :             m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
    2799             :         }
    2800             :     }
    2801             : 
    2802             :     // Update the rsid of the old and the new node unless
    2803             :     // the old node is split at the beginning or at the end
    2804        1238 :     SwTxtNode *pTxtNode =  rPos.nNode.GetNode().GetTxtNode();
    2805        1238 :     const sal_Int32 nPos = rPos.nContent.GetIndex();
    2806        1238 :     if( pTxtNode && nPos && nPos != pTxtNode->Len() )
    2807             :     {
    2808          84 :         m_rSwdoc.UpdateParRsid( pTxtNode );
    2809             :     }
    2810             : 
    2811             :     //JP 28.01.97: Special case for SplitNode at table start:
    2812             :     //             If it is at the beginning of a Doc/Fly/Footer/... or right at after a table
    2813             :     //             then insert a paragraph before it.
    2814        1238 :     if( bChkTableStart && !rPos.nContent.GetIndex() && pNode->IsTxtNode() )
    2815             :     {
    2816          12 :         sal_uLong nPrevPos = rPos.nNode.GetIndex() - 1;
    2817             :         const SwTableNode* pTblNd;
    2818          12 :         const SwNode* pNd = m_rSwdoc.GetNodes()[ nPrevPos ];
    2819          30 :         if( pNd->IsStartNode() &&
    2820           6 :             SwTableBoxStartNode == ((SwStartNode*)pNd)->GetStartNodeType() &&
    2821          12 :             0 != ( pTblNd = m_rSwdoc.GetNodes()[ --nPrevPos ]->GetTableNode() ) &&
    2822           0 :             ((( pNd = m_rSwdoc.GetNodes()[ --nPrevPos ])->IsStartNode() &&
    2823           0 :                SwTableBoxStartNode != ((SwStartNode*)pNd)->GetStartNodeType() )
    2824           0 :                || ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsTableNode() )
    2825           0 :                || pNd->IsCntntNode() ))
    2826             :         {
    2827           0 :             if( pNd->IsCntntNode() )
    2828             :             {
    2829             :                 //JP 30.04.99 Bug 65660:
    2830             :                 // There are no page breaks outside of the normal body area,
    2831             :                 // so this is not a valid condition to insert a paragraph.
    2832           0 :                 if( nPrevPos < m_rSwdoc.GetNodes().GetEndOfExtras().GetIndex() )
    2833           0 :                     pNd = 0;
    2834             :                 else
    2835             :                 {
    2836             :                     // Only if the table has page breaks!
    2837           0 :                     const SwFrmFmt* pFrmFmt = pTblNd->GetTable().GetFrmFmt();
    2838           0 :                     if( SfxItemState::SET != pFrmFmt->GetItemState(RES_PAGEDESC, false) &&
    2839           0 :                         SfxItemState::SET != pFrmFmt->GetItemState( RES_BREAK, false ) )
    2840           0 :                         pNd = 0;
    2841             :                 }
    2842             :             }
    2843             : 
    2844           0 :             if( pNd )
    2845             :             {
    2846           0 :                 SwTxtNode* pTxtNd = m_rSwdoc.GetNodes().MakeTxtNode(
    2847             :                                         SwNodeIndex( *pTblNd ),
    2848           0 :                                         m_rSwdoc.getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_TEXT ));
    2849           0 :                 if( pTxtNd )
    2850             :                 {
    2851           0 :                     ((SwPosition&)rPos).nNode = pTblNd->GetIndex()-1;
    2852           0 :                     ((SwPosition&)rPos).nContent.Assign( pTxtNd, 0 );
    2853             : 
    2854             :                     // only add page breaks/styles to the body area
    2855           0 :                     if( nPrevPos > m_rSwdoc.GetNodes().GetEndOfExtras().GetIndex() )
    2856             :                     {
    2857           0 :                         SwFrmFmt* pFrmFmt = pTblNd->GetTable().GetFrmFmt();
    2858             :                         const SfxPoolItem *pItem;
    2859           0 :                         if( SfxItemState::SET == pFrmFmt->GetItemState( RES_PAGEDESC,
    2860           0 :                             false, &pItem ) )
    2861             :                         {
    2862           0 :                             pTxtNd->SetAttr( *pItem );
    2863           0 :                             pFrmFmt->ResetFmtAttr( RES_PAGEDESC );
    2864             :                         }
    2865           0 :                         if( SfxItemState::SET == pFrmFmt->GetItemState( RES_BREAK,
    2866           0 :                             false, &pItem ) )
    2867             :                         {
    2868           0 :                             pTxtNd->SetAttr( *pItem );
    2869           0 :                             pFrmFmt->ResetFmtAttr( RES_BREAK );
    2870             :                         }
    2871             :                     }
    2872             : 
    2873           0 :                     if( pUndo )
    2874           0 :                         pUndo->SetTblFlag();
    2875           0 :                     m_rSwdoc.getIDocumentState().SetModified();
    2876           0 :                     return true;
    2877             :                 }
    2878             :             }
    2879             :         }
    2880             :     }
    2881             : 
    2882        1238 :     const boost::shared_ptr<sw::mark::CntntIdxStore> pCntntStore(sw::mark::CntntIdxStore::Create());
    2883        1238 :     pCntntStore->Save( &m_rSwdoc, rPos.nNode.GetIndex(), rPos.nContent.GetIndex(), true );
    2884             :     // FIXME: only SwTxtNode has a valid implementation of SplitCntntNode!
    2885             :     OSL_ENSURE(pNode->IsTxtNode(), "splitting non-text node?");
    2886        1238 :     pNode = pNode->SplitCntntNode( rPos );
    2887        1238 :     if (pNode)
    2888             :     {
    2889             :         // move all bookmarks, TOXMarks, FlyAtCnt
    2890        1238 :         if( !pCntntStore->Empty() )
    2891          66 :             pCntntStore->Restore( &m_rSwdoc, rPos.nNode.GetIndex()-1, 0, true );
    2892             : 
    2893             :         // To-Do - add 'SwExtraRedlineTbl' also ?
    2894        1238 :         if( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn() || (!m_rSwdoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().empty() ))
    2895             :         {
    2896           0 :             SwPaM aPam( rPos );
    2897           0 :             aPam.SetMark();
    2898           0 :             aPam.Move( fnMoveBackward );
    2899           0 :             if( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn() )
    2900           0 :                 m_rSwdoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
    2901             :             else
    2902           0 :                 m_rSwdoc.getIDocumentRedlineAccess().SplitRedline( aPam );
    2903             :         }
    2904             :     }
    2905             : 
    2906        1238 :     m_rSwdoc.getIDocumentState().SetModified();
    2907        1238 :     return true;
    2908             : }
    2909             : 
    2910       61880 : bool DocumentContentOperationsManager::AppendTxtNode( SwPosition& rPos )
    2911             : {
    2912             :     // create new node before EndOfContent
    2913       61880 :     SwTxtNode * pCurNode = rPos.nNode.GetNode().GetTxtNode();
    2914       61880 :     if( !pCurNode )
    2915             :     {
    2916             :         // so then one can be created!
    2917         264 :         SwNodeIndex aIdx( rPos.nNode, 1 );
    2918         264 :         pCurNode = m_rSwdoc.GetNodes().MakeTxtNode( aIdx,
    2919         528 :                         m_rSwdoc.getIDocumentStylePoolAccess().GetTxtCollFromPool( RES_POOLCOLL_STANDARD ));
    2920             :     }
    2921             :     else
    2922       61616 :         pCurNode = (SwTxtNode*)pCurNode->AppendNode( rPos );
    2923             : 
    2924       61880 :     rPos.nNode++;
    2925       61880 :     rPos.nContent.Assign( pCurNode, 0 );
    2926             : 
    2927       61880 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    2928             :     {
    2929        3760 :         m_rSwdoc.GetIDocumentUndoRedo().AppendUndo( new SwUndoInsert( rPos.nNode ) );
    2930             :     }
    2931             : 
    2932             :     // To-Do - add 'SwExtraRedlineTbl' also ?
    2933       61880 :     if( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn() || (!m_rSwdoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().empty() ))
    2934             :     {
    2935         776 :         SwPaM aPam( rPos );
    2936         776 :         aPam.SetMark();
    2937         776 :         aPam.Move( fnMoveBackward );
    2938         776 :         if( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn() )
    2939          26 :             m_rSwdoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
    2940             :         else
    2941         750 :             m_rSwdoc.getIDocumentRedlineAccess().SplitRedline( aPam );
    2942             :     }
    2943             : 
    2944       61880 :     m_rSwdoc.getIDocumentState().SetModified();
    2945       61880 :     return true;
    2946             : }
    2947             : 
    2948          92 : bool DocumentContentOperationsManager::ReplaceRange( SwPaM& rPam, const OUString& rStr,
    2949             :         const bool bRegExReplace )
    2950             : {
    2951             :     // unfortunately replace works slightly differently from delete,
    2952             :     // so we cannot use lcl_DoWithBreaks here...
    2953             : 
    2954          92 :     ::std::vector<sal_Int32> Breaks;
    2955             : 
    2956         184 :     SwPaM aPam( *rPam.GetMark(), *rPam.GetPoint() );
    2957          92 :     aPam.Normalize(false);
    2958          92 :     if (aPam.GetPoint()->nNode != aPam.GetMark()->nNode)
    2959             :     {
    2960           0 :         aPam.Move(fnMoveBackward);
    2961             :     }
    2962             :     OSL_ENSURE((aPam.GetPoint()->nNode == aPam.GetMark()->nNode), "invalid pam?");
    2963             : 
    2964          92 :     lcl_CalcBreaks(Breaks, aPam);
    2965             : 
    2966         460 :     while (!Breaks.empty() // skip over prefix of dummy chars
    2967         276 :             && (aPam.GetMark()->nContent.GetIndex() == *Breaks.begin()) )
    2968             :     {
    2969             :         // skip!
    2970           0 :         ++aPam.GetMark()->nContent; // always in bounds if Breaks valid
    2971           0 :         Breaks.erase(Breaks.begin());
    2972             :     }
    2973          92 :     *rPam.Start() = *aPam.GetMark(); // update start of original pam w/ prefix
    2974             : 
    2975          92 :     if (!Breaks.size())
    2976             :     {
    2977             :         // park aPam somewhere so it does not point to node that is deleted
    2978          92 :         aPam.DeleteMark();
    2979          92 :         *aPam.GetPoint() = SwPosition(m_rSwdoc.GetNodes().GetEndOfContent());
    2980          92 :         return ReplaceRangeImpl(rPam, rStr, bRegExReplace); // original pam!
    2981             :     }
    2982             : 
    2983             :     // Deletion must be split into several parts if the text node
    2984             :     // contains a text attribute with end and with dummy character
    2985             :     // and the selection does not contain the text attribute completely,
    2986             :     // but overlaps its start (left), where the dummy character is.
    2987             : 
    2988           0 :     bool bRet( true );
    2989             :     // iterate from end to start, to avoid invalidating the offsets!
    2990           0 :     ::std::vector<sal_Int32>::reverse_iterator iter( Breaks.rbegin() );
    2991             :     OSL_ENSURE(aPam.GetPoint() == aPam.End(), "wrong!");
    2992           0 :     SwPosition & rEnd( *aPam.End() );
    2993           0 :     SwPosition & rStart( *aPam.Start() );
    2994             : 
    2995             :     // set end of temp pam to original end (undo Move backward above)
    2996           0 :     rEnd = *rPam.End();
    2997             :     // after first deletion, rEnd will point into the original text node again!
    2998             : 
    2999           0 :     while (iter != Breaks.rend())
    3000             :     {
    3001           0 :         rStart.nContent = *iter + 1;
    3002           0 :         if (rEnd.nContent != rStart.nContent) // check if part is empty
    3003             :         {
    3004           0 :             bRet &= (m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn())
    3005             :                 ? DeleteAndJoinWithRedlineImpl(aPam)
    3006           0 :                 : DeleteAndJoinImpl(aPam, false);
    3007             :         }
    3008           0 :         rEnd.nContent = *iter;
    3009           0 :         ++iter;
    3010             :     }
    3011             : 
    3012           0 :     rStart = *rPam.Start(); // set to original start
    3013             :     OSL_ENSURE(rEnd.nContent > rStart.nContent, "replace part empty!");
    3014           0 :     if (rEnd.nContent > rStart.nContent) // check if part is empty
    3015             :     {
    3016           0 :         bRet &= ReplaceRangeImpl(aPam, rStr, bRegExReplace);
    3017             :     }
    3018             : 
    3019           0 :     rPam = aPam; // update original pam (is this required?)
    3020             : 
    3021          92 :     return bRet;
    3022             : }
    3023             : 
    3024             : ///Add a para for the char attribute exp...
    3025       45456 : bool DocumentContentOperationsManager::InsertPoolItem(
    3026             :     const SwPaM &rRg,
    3027             :     const SfxPoolItem &rHt,
    3028             :     const SetAttrMode nFlags,
    3029             :     const bool bExpandCharToPara)
    3030             : {
    3031       45456 :     SwDataChanged aTmp( rRg );
    3032       45456 :     SwUndoAttr* pUndoAttr = 0;
    3033       45456 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    3034             :     {
    3035         582 :         m_rSwdoc.GetIDocumentUndoRedo().ClearRedo();
    3036         582 :         pUndoAttr = new SwUndoAttr( rRg, rHt, nFlags );
    3037             :     }
    3038             : 
    3039       90912 :     SfxItemSet aSet( m_rSwdoc.GetAttrPool(), rHt.Which(), rHt.Which() );
    3040       45456 :     aSet.Put( rHt );
    3041       45456 :     const bool bRet = lcl_InsAttr( &m_rSwdoc, rRg, aSet, nFlags, pUndoAttr, bExpandCharToPara );
    3042             : 
    3043       45456 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    3044             :     {
    3045         582 :         m_rSwdoc.GetIDocumentUndoRedo().AppendUndo( pUndoAttr );
    3046             :     }
    3047             : 
    3048       45456 :     if( bRet )
    3049             :     {
    3050       45412 :         m_rSwdoc.getIDocumentState().SetModified();
    3051             :     }
    3052       90912 :     return bRet;
    3053             : }
    3054             : 
    3055      199240 : bool DocumentContentOperationsManager::InsertItemSet ( const SwPaM &rRg, const SfxItemSet &rSet,
    3056             :                             const SetAttrMode nFlags )
    3057             : {
    3058      199240 :     SwDataChanged aTmp( rRg );
    3059      199240 :     SwUndoAttr* pUndoAttr = 0;
    3060      199240 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    3061             :     {
    3062       17960 :         m_rSwdoc.GetIDocumentUndoRedo().ClearRedo();
    3063       17960 :         pUndoAttr = new SwUndoAttr( rRg, rSet, nFlags );
    3064             :     }
    3065             : 
    3066      199240 :     bool bRet = lcl_InsAttr( &m_rSwdoc, rRg, rSet, nFlags, pUndoAttr );
    3067             : 
    3068      199240 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    3069             :     {
    3070       17960 :         m_rSwdoc.GetIDocumentUndoRedo().AppendUndo( pUndoAttr );
    3071             :     }
    3072             : 
    3073      199240 :     if( bRet )
    3074      178624 :         m_rSwdoc.getIDocumentState().SetModified();
    3075      199240 :     return bRet;
    3076             : }
    3077             : 
    3078           0 : void DocumentContentOperationsManager::RemoveLeadingWhiteSpace(const SwPosition & rPos )
    3079             : {
    3080           0 :     const SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
    3081           0 :     if ( pTNd )
    3082             :     {
    3083           0 :         const OUString& rTxt = pTNd->GetTxt();
    3084           0 :         sal_Int32 nIdx = 0;
    3085           0 :         while (nIdx < rTxt.getLength())
    3086             :         {
    3087           0 :             sal_Unicode const cCh = rTxt[nIdx];
    3088           0 :             if (('\t' != cCh) && (' ' != cCh))
    3089             :             {
    3090           0 :                 break;
    3091             :             }
    3092           0 :             ++nIdx;
    3093             :         }
    3094             : 
    3095           0 :         if ( nIdx > 0 )
    3096             :         {
    3097           0 :             SwPaM aPam(rPos);
    3098           0 :             aPam.GetPoint()->nContent = 0;
    3099           0 :             aPam.SetMark();
    3100           0 :             aPam.GetMark()->nContent = nIdx;
    3101           0 :             DeleteRange( aPam );
    3102             :         }
    3103             :     }
    3104           0 : }
    3105             : 
    3106             : // Copy method from SwDoc - "copy Flys in Flys"
    3107         954 : void DocumentContentOperationsManager::CopyWithFlyInFly(
    3108             :     const SwNodeRange& rRg,
    3109             :     const sal_Int32 nEndContentIndex,
    3110             :     const SwNodeIndex& rInsPos,
    3111             :     const SwPaM* pCopiedPaM,
    3112             :     const bool bMakeNewFrms,
    3113             :     const bool bDelRedlines,
    3114             :     const bool bCopyFlyAtFly,
    3115             :     const bool bMergedFirstNode ) const
    3116             : {
    3117         954 :     SwDoc* pDest = rInsPos.GetNode().GetDoc();
    3118             : 
    3119         954 :     _SaveRedlEndPosForRestore aRedlRest( rInsPos, 0 );
    3120             : 
    3121        1908 :     SwNodeIndex aSavePos( rInsPos, -1 );
    3122         954 :     bool bEndIsEqualEndPos = rInsPos == rRg.aEnd;
    3123        1908 :     SwNodeRange aRg( rRg );
    3124         954 :     if ( bMergedFirstNode )
    3125          10 :         aRg.aStart++;
    3126         954 :     if ( aRg.aStart <= aRg.aEnd )
    3127         954 :         m_rSwdoc.GetNodes()._CopyNodes( aRg, rInsPos, bMakeNewFrms, true );
    3128         954 :     if ( !bMergedFirstNode )
    3129         944 :         ++aSavePos;
    3130         954 :     if ( bEndIsEqualEndPos )
    3131           0 :         ((SwNodeIndex&)rRg.aEnd) = aSavePos;
    3132             : 
    3133         954 :     aRedlRest.Restore();
    3134             : #if OSL_DEBUG_LEVEL > 0
    3135             :     {
    3136             :         //JP 17.06.99: Bug 66973 - check count only if the selection is in
    3137             :         // the same section or there's no section, because sections that are
    3138             :         // not fully selected are not copied.
    3139             :         const SwSectionNode* pSSectNd = rRg.aStart.GetNode().FindSectionNode();
    3140             :         SwNodeIndex aTmpI( rRg.aEnd, -1 );
    3141             :         const SwSectionNode* pESectNd = aTmpI.GetNode().FindSectionNode();
    3142             :         if( pSSectNd == pESectNd &&
    3143             :             !rRg.aStart.GetNode().IsSectionNode() &&
    3144             :             !aTmpI.GetNode().IsEndNode() )
    3145             :         {
    3146             :             // If the range starts with a SwStartNode, it isn't copied
    3147             :             sal_uInt16 offset = (aRg.aStart.GetNode().GetNodeType() != ND_STARTNODE) ? 1 : 0;
    3148             :             OSL_ENSURE( rInsPos.GetIndex() - aSavePos.GetIndex() ==
    3149             :                     aRg.aEnd.GetIndex() - aRg.aStart.GetIndex() - 1 + offset,
    3150             :                     "An insufficient number of nodes were copied!" );
    3151             :         }
    3152             :     }
    3153             : #endif
    3154             : 
    3155             :     {
    3156         954 :         ::sw::UndoGuard const undoGuard(pDest->GetIDocumentUndoRedo());
    3157         954 :         CopyFlyInFlyImpl( rRg, nEndContentIndex, aSavePos, bCopyFlyAtFly, bMergedFirstNode );
    3158             :     }
    3159             : 
    3160        1908 :     SwNodeRange aCpyRange( aSavePos, rInsPos );
    3161             : 
    3162             :     // Also copy all bookmarks
    3163         954 :     if( m_rSwdoc.getIDocumentMarkAccess()->getAllMarksCount() )
    3164             :     {
    3165         736 :         SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
    3166        1472 :         SwPaM aCpyTmp( aCpyRange.aStart, aCpyRange.aEnd );
    3167             : 
    3168             :         lcl_CopyBookmarks(
    3169             :             pCopiedPaM != NULL ? *pCopiedPaM : aRgTmp,
    3170        1472 :             aCpyTmp );
    3171             :     }
    3172             : 
    3173         954 :     if( bDelRedlines && ( nsRedlineMode_t::REDLINE_DELETE_REDLINES & pDest->getIDocumentRedlineAccess().GetRedlineMode() ))
    3174           2 :         lcl_DeleteRedlines( rRg, aCpyRange );
    3175             : 
    3176        1908 :     pDest->GetNodes()._DelDummyNodes( aCpyRange );
    3177         954 : }
    3178             : 
    3179        7368 : void DocumentContentOperationsManager::CopyFlyInFlyImpl(
    3180             :     const SwNodeRange& rRg,
    3181             :     const sal_Int32 nEndContentIndex,
    3182             :     const SwNodeIndex& rStartIdx,
    3183             :     const bool bCopyFlyAtFly,
    3184             :     const bool bMergedFirstNode ) const
    3185             : {
    3186             :     // First collect all Flys, sort them according to their ordering number,
    3187             :     // and then only copy them. This maintains the ordering numbers (which are only
    3188             :     // managed in the DrawModel).
    3189        7368 :     SwDoc *const pDest = rStartIdx.GetNode().GetDoc();
    3190        7368 :     ::std::set< _ZSortFly > aSet;
    3191        7368 :     const size_t nArrLen = m_rSwdoc.GetSpzFrmFmts()->size();
    3192             : 
    3193       14736 :     SwTextBoxHelper::SavedLink aOldTextBoxes;
    3194        7368 :     SwTextBoxHelper::saveLinks(*m_rSwdoc.GetSpzFrmFmts(), aOldTextBoxes);
    3195       14736 :     SwTextBoxHelper::SavedContent aOldContent;
    3196             : 
    3197       31332 :     for ( size_t n = 0; n < nArrLen; ++n )
    3198             :     {
    3199       23964 :         SwFrmFmt* pFmt = (*m_rSwdoc.GetSpzFrmFmts())[n];
    3200       23964 :         SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
    3201       23964 :         SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
    3202       23964 :         bool bAtCntnt = (pAnchor->GetAnchorId() == FLY_AT_PARA);
    3203       47586 :         if ( pAPos &&
    3204        8686 :              ( bAtCntnt ||
    3205       17372 :               (pAnchor->GetAnchorId() == FLY_AT_FLY) ||
    3206       25892 :               (pAnchor->GetAnchorId() == FLY_AT_CHAR)) &&
    3207        5762 :              (( bCopyFlyAtFly && FLY_AT_FLY == pAnchor->GetAnchorId() )
    3208           0 :                     ? rRg.aStart <= pAPos->nNode.GetIndex() + 1
    3209       17206 :                     : ( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineMove()
    3210        1286 :                             ? rRg.aStart < pAPos->nNode
    3211       88364 :                             : rRg.aStart <= pAPos->nNode )) &&
    3212       14068 :              pAPos->nNode <= rRg.aEnd )
    3213             :         {
    3214             :             //frames at the last source node are not always copied:
    3215             :             //- if the node is empty and is the last node of the document or a table cell
    3216             :             //  or a text frame then tey have to be copied
    3217             :             //- if the content index in this node is > 0 then paragph and frame bound objects are copied
    3218             :             //- to-character bound objects are copied if their index is <= nEndContentIndex
    3219         840 :             bool bAdd = false;
    3220         840 :             if( pAPos->nNode < rRg.aEnd )
    3221         840 :                 bAdd = true;
    3222         840 :             if (!bAdd && !m_rSwdoc.getIDocumentRedlineAccess().IsRedlineMove()) // fdo#40599: not for redline move
    3223             :             {
    3224           0 :                 bool bEmptyNode = false;
    3225           0 :                 bool bLastNode = false;
    3226             :                 // is the node empty?
    3227           0 :                 const SwNodes& rNodes = pAPos->nNode.GetNodes();
    3228             :                 SwTxtNode* pTxtNode;
    3229           0 :                 if( 0 != ( pTxtNode = pAPos->nNode.GetNode().GetTxtNode() ))
    3230             :                 {
    3231           0 :                     bEmptyNode = pTxtNode->GetTxt().isEmpty();
    3232           0 :                     if( bEmptyNode )
    3233             :                     {
    3234             :                         //last node information is only necessary to know for the last TextNode
    3235           0 :                         SwNodeIndex aTmp( pAPos->nNode );
    3236           0 :                         ++aTmp;//goto next node
    3237           0 :                         while (aTmp.GetNode().IsEndNode())
    3238             :                         {
    3239           0 :                             if( aTmp == rNodes.GetEndOfContent().GetIndex() )
    3240             :                             {
    3241           0 :                                 bLastNode = true;
    3242           0 :                                 break;
    3243             :                             }
    3244           0 :                             ++aTmp;
    3245           0 :                         }
    3246             :                     }
    3247             :                 }
    3248           0 :                 bAdd = bLastNode && bEmptyNode;
    3249           0 :                 if( !bAdd )
    3250             :                 {
    3251           0 :                     if( bAtCntnt )
    3252           0 :                         bAdd = nEndContentIndex > 0;
    3253             :                     else
    3254           0 :                         bAdd = pAPos->nContent <= nEndContentIndex;
    3255             :                 }
    3256             :             }
    3257         840 :             if( bAdd )
    3258             :             {
    3259             :                 // Make sure draw formats don't refer to content, so that such
    3260             :                 // content can be removed without problems.
    3261         840 :                 SwTextBoxHelper::resetLink(pFmt, aOldContent);
    3262         840 :                 aSet.insert( _ZSortFly( pFmt, pAnchor, nArrLen + aSet.size() ));
    3263             :             }
    3264             :         }
    3265             :     }
    3266             : 
    3267             :     // Store all copied (and also the newly created) frames in another array.
    3268             :     // They are stored as matching the originals, so that we will be later
    3269             :     // able to build the chains accordingly.
    3270       14736 :     ::std::vector< SwFrmFmt* > aVecSwFrmFmt;
    3271        7368 :     ::std::set< _ZSortFly >::const_iterator it=aSet.begin();
    3272             : 
    3273       15576 :     while (it != aSet.end())
    3274             :     {
    3275             :         // #i59964#
    3276             :         // correct determination of new anchor position
    3277         840 :         SwFmtAnchor aAnchor( *(*it).GetAnchor() );
    3278         840 :         SwPosition* pNewPos = (SwPosition*)aAnchor.GetCntntAnchor();
    3279             :         // for at-paragraph and at-character anchored objects the new anchor
    3280             :         // position can *not* be determined by the difference of the current
    3281             :         // anchor position to the start of the copied range, because not
    3282             :         // complete selected sections in the copied range aren't copied - see
    3283             :         // method <SwNodes::_CopyNodes(..)>.
    3284             :         // Thus, the new anchor position in the destination document is found
    3285             :         // by counting the text nodes.
    3286        1110 :         if ((aAnchor.GetAnchorId() == FLY_AT_PARA) ||
    3287         270 :             (aAnchor.GetAnchorId() == FLY_AT_CHAR) )
    3288             :         {
    3289             :             // First, determine number of anchor text node in the copied range.
    3290             :             // Note: The anchor text node *have* to be inside the copied range.
    3291         840 :             sal_uLong nAnchorTxtNdNumInRange( 0L );
    3292         840 :             bool bAnchorTxtNdFound( false );
    3293         840 :             SwNodeIndex aIdx( rRg.aStart );
    3294        4006 :             while ( !bAnchorTxtNdFound && aIdx <= rRg.aEnd )
    3295             :             {
    3296        2326 :                 if ( aIdx.GetNode().IsTxtNode() )
    3297             :                 {
    3298        1078 :                     ++nAnchorTxtNdNumInRange;
    3299        1078 :                     bAnchorTxtNdFound = aAnchor.GetCntntAnchor()->nNode == aIdx;
    3300             :                 }
    3301             : 
    3302        2326 :                 ++aIdx;
    3303             :             }
    3304         840 :             if ( bMergedFirstNode )
    3305           0 :                 nAnchorTxtNdNumInRange--;
    3306             : 
    3307         840 :             if ( !bAnchorTxtNdFound )
    3308             :             {
    3309             :                 // This case can *not* happen, but to be robust take the first
    3310             :                 // text node in the destination document.
    3311             :                 OSL_FAIL( "<SwDoc::_CopyFlyInFly(..)> - anchor text node in copied range not found" );
    3312           0 :                 nAnchorTxtNdNumInRange = 1;
    3313             :             }
    3314             :             // Second, search corresponding text node in destination document
    3315             :             // by counting forward from start insert position <rStartIdx> the
    3316             :             // determined number of text nodes.
    3317         840 :             aIdx = rStartIdx;
    3318        1680 :             SwNodeIndex aAnchorNdIdx( rStartIdx );
    3319             :             const SwNode& aEndOfContentNd =
    3320         840 :                                     aIdx.GetNode().GetNodes().GetEndOfContent();
    3321        6220 :             while ( nAnchorTxtNdNumInRange > 0 &&
    3322        2270 :                     &(aIdx.GetNode()) != &aEndOfContentNd )
    3323             :             {
    3324        2270 :                 if ( aIdx.GetNode().IsTxtNode() )
    3325             :                 {
    3326        1078 :                     --nAnchorTxtNdNumInRange;
    3327        1078 :                     aAnchorNdIdx = aIdx;
    3328             :                 }
    3329             : 
    3330        2270 :                 ++aIdx;
    3331             :             }
    3332         840 :             if ( !aAnchorNdIdx.GetNode().IsTxtNode() )
    3333             :             {
    3334             :                 // This case can *not* happen, but to be robust take the first
    3335             :                 // text node in the destination document.
    3336             :                 OSL_FAIL( "<SwDoc::_CopyFlyInFly(..)> - found anchor node index isn't a text node" );
    3337           0 :                 aAnchorNdIdx = rStartIdx;
    3338           0 :                 while ( !aAnchorNdIdx.GetNode().IsTxtNode() )
    3339             :                 {
    3340           0 :                     ++aAnchorNdIdx;
    3341             :                 }
    3342             :             }
    3343             :             // apply found anchor text node as new anchor position
    3344        1680 :             pNewPos->nNode = aAnchorNdIdx;
    3345             :         }
    3346             :         else
    3347             :         {
    3348           0 :             long nOffset = pNewPos->nNode.GetIndex() - rRg.aStart.GetIndex();
    3349           0 :             SwNodeIndex aIdx( rStartIdx, nOffset );
    3350           0 :             pNewPos->nNode = aIdx;
    3351             :         }
    3352             :         // Set the character bound Flys back at the original character
    3353        1110 :         if ((FLY_AT_CHAR == aAnchor.GetAnchorId()) &&
    3354         270 :              pNewPos->nNode.GetNode().IsTxtNode() )
    3355             :         {
    3356         270 :             pNewPos->nContent.Assign( (SwTxtNode*)&pNewPos->nNode.GetNode(),
    3357         540 :                                         pNewPos->nContent.GetIndex() );
    3358             :         }
    3359             :         else
    3360             :         {
    3361         570 :             pNewPos->nContent.Assign( 0, 0 );
    3362             :         }
    3363             : 
    3364             :         // Check recursion: copy content in its own frame, then don't copy it.
    3365         840 :         bool bMakeCpy = true;
    3366         840 :         if( pDest == &m_rSwdoc )
    3367             :         {
    3368         784 :             const SwFmtCntnt& rCntnt = (*it).GetFmt()->GetCntnt();
    3369             :             const SwStartNode* pSNd;
    3370        1994 :             if( rCntnt.GetCntntIdx() &&
    3371         852 :                 0 != ( pSNd = rCntnt.GetCntntIdx()->GetNode().GetStartNode() ) &&
    3372        1636 :                 pSNd->GetIndex() < rStartIdx.GetIndex() &&
    3373         426 :                 rStartIdx.GetIndex() < pSNd->EndOfSectionIndex() )
    3374             :             {
    3375           0 :                 bMakeCpy = false;
    3376           0 :                 aSet.erase (it++);
    3377           0 :                 continue;
    3378             :             }
    3379             :         }
    3380             : 
    3381             :         // Copy the format and set the new anchor
    3382         840 :         if( bMakeCpy )
    3383        1680 :             aVecSwFrmFmt.push_back( pDest->getIDocumentLayoutAccess().CopyLayoutFmt( *(*it).GetFmt(),
    3384        1680 :                         aAnchor, false, true ) );
    3385         840 :         ++it;
    3386         840 :     }
    3387             : 
    3388             :     // Rebuild as much as possible of all chains that are available in the original,
    3389             :     OSL_ENSURE( aSet.size() == aVecSwFrmFmt.size(), "Missing new Flys" );
    3390        7368 :     if ( aSet.size() == aVecSwFrmFmt.size() )
    3391             :     {
    3392        7368 :         size_t n = 0;
    3393        8208 :         for (::std::set< _ZSortFly >::const_iterator nIt=aSet.begin() ; nIt != aSet.end(); ++nIt, ++n )
    3394             :         {
    3395         840 :             const SwFrmFmt *pFmtN = (*nIt).GetFmt();
    3396         840 :             const SwFmtChain &rChain = pFmtN->GetChain();
    3397         840 :             int nCnt = int(0 != rChain.GetPrev());
    3398         840 :             nCnt += rChain.GetNext() ? 1: 0;
    3399         840 :             size_t k = 0;
    3400        3972 :             for (::std::set< _ZSortFly >::const_iterator kIt=aSet.begin() ; kIt != aSet.end(); ++kIt, ++k )
    3401             :             {
    3402        3132 :                 const SwFrmFmt *pFmtK = (*kIt).GetFmt();
    3403        3132 :                 if ( rChain.GetPrev() == pFmtK )
    3404             :                 {
    3405           0 :                     ::lcl_ChainFmts( static_cast< SwFlyFrmFmt* >(aVecSwFrmFmt[k]),
    3406           0 :                                      static_cast< SwFlyFrmFmt* >(aVecSwFrmFmt[n]) );
    3407           0 :                     --nCnt;
    3408             :                 }
    3409        3132 :                 else if ( rChain.GetNext() == pFmtK )
    3410             :                 {
    3411           0 :                     ::lcl_ChainFmts( static_cast< SwFlyFrmFmt* >(aVecSwFrmFmt[n]),
    3412           0 :                                      static_cast< SwFlyFrmFmt* >(aVecSwFrmFmt[k]) );
    3413           0 :                     --nCnt;
    3414             :                 }
    3415             :             }
    3416             :         }
    3417             : 
    3418             :         // Re-create content property of draw formats, knowing how old shapes
    3419             :         // were paired with old fly formats (aOldTextBoxes) and that aSet is
    3420             :         // parallel with aVecSwFrmFmt.
    3421        7368 :         SwTextBoxHelper::restoreLinks(aSet, aVecSwFrmFmt, aOldTextBoxes, aOldContent);
    3422        7368 :     }
    3423        7368 : }
    3424             : 
    3425             : /*
    3426             :  * Reset the text's hard formatting
    3427             :  */
    3428             : /** @params pArgs contains the document's ChrFmtTable
    3429             :  *                Is need for selections at the beginning/end and with no SSelection.
    3430             :  */
    3431      120280 : bool DocumentContentOperationsManager::lcl_RstTxtAttr( const SwNodePtr& rpNd, void* pArgs )
    3432             : {
    3433      120280 :     ParaRstFmt* pPara = (ParaRstFmt*)pArgs;
    3434      120280 :     SwTxtNode * pTxtNode = (SwTxtNode*)rpNd->GetTxtNode();
    3435      120280 :     if( pTxtNode && pTxtNode->GetpSwpHints() )
    3436             :     {
    3437       12426 :         SwIndex aSt( pTxtNode, 0 );
    3438       12426 :         sal_Int32 nEnd = pTxtNode->Len();
    3439             : 
    3440       24650 :         if( &pPara->pSttNd->nNode.GetNode() == pTxtNode &&
    3441       12224 :             pPara->pSttNd->nContent.GetIndex() )
    3442         988 :             aSt = pPara->pSttNd->nContent.GetIndex();
    3443             : 
    3444       12426 :         if( &pPara->pEndNd->nNode.GetNode() == rpNd )
    3445       10154 :             nEnd = pPara->pEndNd->nContent.GetIndex();
    3446             : 
    3447       12426 :         if( pPara->pHistory )
    3448             :         {
    3449             :             // Save all attributes for the Undo.
    3450         986 :             SwRegHistory aRHst( *pTxtNode, pPara->pHistory );
    3451         986 :             pTxtNode->GetpSwpHints()->Register( &aRHst );
    3452         986 :             pTxtNode->RstTxtAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich,
    3453        1972 :                                   pPara->pDelSet, pPara->bInclRefToxMark );
    3454         986 :             if( pTxtNode->GetpSwpHints() )
    3455         982 :                 pTxtNode->GetpSwpHints()->DeRegister();
    3456             :         }
    3457             :         else
    3458       11440 :             pTxtNode->RstTxtAttr( aSt, nEnd - aSt.GetIndex(), pPara->nWhich,
    3459       22880 :                                   pPara->pDelSet, pPara->bInclRefToxMark );
    3460             :     }
    3461      120280 :     return true;
    3462             : }
    3463             : 
    3464       10090 : DocumentContentOperationsManager::~DocumentContentOperationsManager()
    3465             : {
    3466       10090 : }
    3467             : //Private methods
    3468             : 
    3469         455 : bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPam, const bool )
    3470             : {
    3471             :     OSL_ENSURE( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn(), "DeleteAndJoinWithRedline: redline off" );
    3472             : 
    3473             :     {
    3474         455 :         SwUndoRedlineDelete* pUndo = 0;
    3475         455 :         RedlineMode_t eOld = m_rSwdoc.getIDocumentRedlineAccess().GetRedlineMode();
    3476         455 :         m_rSwdoc.GetDocumentRedlineManager().checkRedlining( eOld );
    3477         455 :         if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    3478             :         {
    3479             : 
    3480             :             /* please don't translate -- for cultural reasons this comment is protected
    3481             :                until the redline implementation is finally fixed some day */
    3482             :             //JP 06.01.98: MUSS noch optimiert werden!!!
    3483           0 :             m_rSwdoc.getIDocumentRedlineAccess().SetRedlineMode(
    3484           0 :                 (RedlineMode_t) ( nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE ) );
    3485             : 
    3486           0 :             m_rSwdoc.GetIDocumentUndoRedo().StartUndo( UNDO_DELETE, NULL );
    3487           0 :             pUndo = new SwUndoRedlineDelete( rPam, UNDO_DELETE );
    3488           0 :             m_rSwdoc.GetIDocumentUndoRedo().AppendUndo( pUndo );
    3489             :         }
    3490             : 
    3491         455 :         if ( *rPam.GetPoint() != *rPam.GetMark() )
    3492          34 :             m_rSwdoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, rPam ), true );
    3493         455 :         m_rSwdoc.getIDocumentState().SetModified();
    3494             : 
    3495         455 :         if ( pUndo )
    3496             :         {
    3497           0 :             m_rSwdoc.GetIDocumentUndoRedo().EndUndo( UNDO_EMPTY, NULL );
    3498             :             // ??? why the hell is the AppendUndo not below the
    3499             :             // CanGrouping, so this hideous cleanup wouldn't be necessary?
    3500             :             // bah, this is redlining, probably changing this would break it...
    3501           0 :             if ( m_rSwdoc.GetIDocumentUndoRedo().DoesGroupUndo() )
    3502             :             {
    3503           0 :                 SwUndo * const pLastUndo( m_rSwdoc.GetUndoManager().GetLastUndo() );
    3504           0 :                 SwUndoRedlineDelete * const pUndoRedlineDel( dynamic_cast< SwUndoRedlineDelete* >( pLastUndo ) );
    3505           0 :                 if ( pUndoRedlineDel )
    3506             :                 {
    3507           0 :                     bool const bMerged = pUndoRedlineDel->CanGrouping( *pUndo );
    3508           0 :                     if ( bMerged )
    3509             :                     {
    3510           0 :                         ::sw::UndoGuard const undoGuard( m_rSwdoc.GetIDocumentUndoRedo() );
    3511           0 :                         SwUndo const* const pDeleted = m_rSwdoc.GetUndoManager().RemoveLastUndo();
    3512             :                         OSL_ENSURE( pDeleted == pUndo, "DeleteAndJoinWithRedlineImpl: "
    3513             :                             "undo removed is not undo inserted?" );
    3514           0 :                         delete pDeleted;
    3515             :                     }
    3516             :                 }
    3517             :             }
    3518             :             //JP 06.01.98: MUSS noch optimiert werden!!!
    3519           0 :             m_rSwdoc.getIDocumentRedlineAccess().SetRedlineMode( eOld );
    3520             :         }
    3521         455 :         return true;
    3522             :     }
    3523             : }
    3524             : 
    3525        9174 : bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam,
    3526             :                                const bool bForceJoinNext )
    3527             : {
    3528             :     bool bJoinTxt, bJoinPrev;
    3529        9174 :     ::sw_GetJoinFlags( rPam, bJoinTxt, bJoinPrev );
    3530             :     // #i100466#
    3531        9174 :     if ( bForceJoinNext )
    3532             :     {
    3533           2 :         bJoinPrev = false;
    3534             :     }
    3535             : 
    3536             :     {
    3537        9174 :         bool const bSuccess( DeleteRangeImpl( rPam ) );
    3538        9174 :         if (!bSuccess)
    3539        1446 :             return false;
    3540             :     }
    3541             : 
    3542        7728 :     if( bJoinTxt )
    3543             :     {
    3544        5018 :         ::sw_JoinText( rPam, bJoinPrev );
    3545             :     }
    3546             : 
    3547        7728 :     return true;
    3548             : }
    3549             : 
    3550       10044 : bool DocumentContentOperationsManager::DeleteRangeImpl(SwPaM & rPam, const bool)
    3551             : {
    3552             :     // Move all cursors out of the deleted range, but first copy the
    3553             :     // passed PaM, because it could be a cursor that would be moved!
    3554       10044 :     SwPaM aDelPam( *rPam.GetMark(), *rPam.GetPoint() );
    3555       10044 :     ::PaMCorrAbs( aDelPam, *aDelPam.GetPoint() );
    3556             : 
    3557       10044 :     bool const bSuccess( DeleteRangeImplImpl( aDelPam ) );
    3558       10044 :     if (bSuccess)
    3559             :     {   // now copy position from temp copy to given PaM
    3560        7736 :         *rPam.GetPoint() = *aDelPam.GetPoint();
    3561             :     }
    3562             : 
    3563       10044 :     return bSuccess;
    3564             : }
    3565             : 
    3566       10044 : bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam)
    3567             : {
    3568       10044 :     SwPosition *pStt = (SwPosition*)rPam.Start(), *pEnd = (SwPosition*)rPam.End();
    3569             : 
    3570       10044 :     if( !rPam.HasMark() || *pStt >= *pEnd )
    3571        2308 :         return false;
    3572             : 
    3573        7736 :     if( m_rSwdoc.GetAutoCorrExceptWord() )
    3574             :     {
    3575             :         // if necessary the saved Word for the exception
    3576           0 :         if( m_rSwdoc.GetAutoCorrExceptWord()->IsDeleted() ||  pStt->nNode != pEnd->nNode ||
    3577           0 :             pStt->nContent.GetIndex() + 1 != pEnd->nContent.GetIndex() ||
    3578           0 :             !m_rSwdoc.GetAutoCorrExceptWord()->CheckDelChar( *pStt ))
    3579           0 :                 { m_rSwdoc.DeleteAutoCorrExceptWord(); }
    3580             :     }
    3581             : 
    3582             :     {
    3583             :         // Delete all empty TextHints at the Mark's position
    3584        7736 :         SwTxtNode* pTxtNd = rPam.GetMark()->nNode.GetNode().GetTxtNode();
    3585             :         SwpHints* pHts;
    3586        7736 :         if( pTxtNd &&  0 != ( pHts = pTxtNd->GetpSwpHints()) && pHts->Count() )
    3587             :         {
    3588             :             const sal_Int32 *pEndIdx;
    3589        3308 :             const sal_Int32 nMkCntPos = rPam.GetMark()->nContent.GetIndex();
    3590        8108 :             for( size_t n = pHts->Count(); n; )
    3591             :             {
    3592        4622 :                 const SwTxtAttr* pAttr = (*pHts)[ --n ];
    3593        4622 :                 if( nMkCntPos > pAttr->GetStart() )
    3594        3130 :                     break;
    3595             : 
    3596        4350 :                 if( nMkCntPos == pAttr->GetStart() &&
    3597        2678 :                     0 != (pEndIdx = pAttr->End()) &&
    3598        1186 :                     *pEndIdx == pAttr->GetStart() )
    3599        1078 :                     pTxtNd->DestroyAttr( pHts->Cut( n ) );
    3600             :             }
    3601             :         }
    3602             :     }
    3603             : 
    3604             :     {
    3605             :         // Send DataChanged before deletion, so that we still know
    3606             :         // which objects are in the range.
    3607             :         // Afterwards they could be before/after the Position.
    3608        7736 :         SwDataChanged aTmp( rPam );
    3609             :     }
    3610             : 
    3611        7736 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    3612             :     {
    3613        1050 :         m_rSwdoc.GetIDocumentUndoRedo().ClearRedo();
    3614        1050 :         bool bMerged(false);
    3615        1050 :         if (m_rSwdoc.GetIDocumentUndoRedo().DoesGroupUndo())
    3616             :         {
    3617        1050 :             SwUndo *const pLastUndo( m_rSwdoc.GetUndoManager().GetLastUndo() );
    3618             :             SwUndoDelete *const pUndoDelete(
    3619        1050 :                     dynamic_cast<SwUndoDelete *>(pLastUndo) );
    3620        1050 :             if (pUndoDelete)
    3621             :             {
    3622          16 :                 bMerged = pUndoDelete->CanGrouping( &m_rSwdoc, rPam );
    3623             :                 // if CanGrouping() returns true it's already merged
    3624             :             }
    3625             :         }
    3626        1050 :         if (!bMerged)
    3627             :         {
    3628        1050 :             m_rSwdoc.GetIDocumentUndoRedo().AppendUndo( new SwUndoDelete( rPam ) );
    3629             :         }
    3630             : 
    3631        1050 :         m_rSwdoc.getIDocumentState().SetModified();
    3632             : 
    3633        1050 :         return true;
    3634             :     }
    3635             : 
    3636        6686 :     if( !m_rSwdoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().empty() )
    3637         120 :         m_rSwdoc.getIDocumentRedlineAccess().DeleteRedline( rPam, true, USHRT_MAX );
    3638             : 
    3639             :     // Delete and move all "Flys at the paragraph", which are within the Selection
    3640        6686 :     DelFlyInRange(rPam.GetMark()->nNode, rPam.GetPoint()->nNode);
    3641             :     _DelBookmarks(
    3642             :         pStt->nNode,
    3643             :         pEnd->nNode,
    3644             :         NULL,
    3645             :         &pStt->nContent,
    3646        6686 :         &pEnd->nContent);
    3647             : 
    3648        6686 :     SwNodeIndex aSttIdx( pStt->nNode );
    3649        6686 :     SwCntntNode * pCNd = aSttIdx.GetNode().GetCntntNode();
    3650             : 
    3651             :     do {        // middle checked loop!
    3652        6686 :         if( pCNd )
    3653             :         {
    3654        6686 :             SwTxtNode * pStartTxtNode( pCNd->GetTxtNode() );
    3655        6686 :             if ( pStartTxtNode )
    3656             :             {
    3657             :                 // now move the Content to the new Node
    3658        6686 :                 bool bOneNd = pStt->nNode == pEnd->nNode;
    3659        1712 :                 const sal_Int32 nLen = ( bOneNd ? pEnd->nContent.GetIndex()
    3660        4974 :                                            : pCNd->Len() )
    3661       13372 :                                         - pStt->nContent.GetIndex();
    3662             : 
    3663             :                 // Don't call again, if already empty
    3664        6686 :                 if( nLen )
    3665             :                 {
    3666        1850 :                     pStartTxtNode->EraseText( pStt->nContent, nLen );
    3667             : 
    3668        1850 :                     if( !pStartTxtNode->Len() )
    3669             :                     {
    3670             :                 // METADATA: remove reference if empty (consider node deleted)
    3671         476 :                         pStartTxtNode->RemoveMetadataReference();
    3672             :                     }
    3673             :                 }
    3674             : 
    3675        6686 :                 if( bOneNd )        // that's it
    3676        1712 :                     break;
    3677             : 
    3678        4974 :                 ++aSttIdx;
    3679             :             }
    3680             :             else
    3681             :             {
    3682             :                 // So that there are no indices left registered when deleted,
    3683             :                 // we remove a SwPaM from the Content here.
    3684           0 :                 pStt->nContent.Assign( 0, 0 );
    3685             :             }
    3686             :         }
    3687             : 
    3688        4974 :         pCNd = pEnd->nNode.GetNode().GetCntntNode();
    3689        4974 :         if( pCNd )
    3690             :         {
    3691        4974 :             SwTxtNode * pEndTxtNode( pCNd->GetTxtNode() );
    3692        4974 :             if( pEndTxtNode )
    3693             :             {
    3694             :                 // if already empty, don't call again
    3695        4974 :                 if( pEnd->nContent.GetIndex() )
    3696             :                 {
    3697          14 :                     SwIndex aIdx( pCNd, 0 );
    3698          14 :                     pEndTxtNode->EraseText( aIdx, pEnd->nContent.GetIndex() );
    3699             : 
    3700          14 :                     if( !pEndTxtNode->Len() )
    3701             :                     {
    3702             :                         // METADATA: remove reference if empty (consider node deleted)
    3703          12 :                         pEndTxtNode->RemoveMetadataReference();
    3704          14 :                     }
    3705             :                 }
    3706             :             }
    3707             :             else
    3708             :             {
    3709             :                 // So that there are no indices left registered when deleted,
    3710             :                 // we remove a SwPaM from the Content here.
    3711           0 :                 pEnd->nContent.Assign( 0, 0 );
    3712             :             }
    3713             :         }
    3714             : 
    3715             :         // if the end is not a content node, delete it as well
    3716        4974 :         sal_uInt32 nEnde = pEnd->nNode.GetIndex();
    3717        4974 :         if( pCNd == NULL )
    3718           0 :             nEnde++;
    3719             : 
    3720        4974 :         if( aSttIdx != nEnde )
    3721             :         {
    3722             :             // delete the Nodes into the NodesArary
    3723         300 :             m_rSwdoc.GetNodes().Delete( aSttIdx, nEnde - aSttIdx.GetIndex() );
    3724             :         }
    3725             : 
    3726             :         // If the Node that contained the Cursor has been deleted,
    3727             :         // the Content has to be assigned to the current Content.
    3728        4974 :         pStt->nContent.Assign( pStt->nNode.GetNode().GetCntntNode(),
    3729        9948 :                                 pStt->nContent.GetIndex() );
    3730             : 
    3731             :         // If we deleted across Node boundaries we have to correct the PaM,
    3732             :         // because they are in different Nodes now.
    3733             :         // Also, the Selection is revoked.
    3734        4974 :         *pEnd = *pStt;
    3735        4974 :         rPam.DeleteMark();
    3736             : 
    3737             :     } while( false );
    3738             : 
    3739        6686 :     if( !m_rSwdoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().empty() )
    3740         120 :         m_rSwdoc.getIDocumentRedlineAccess().CompressRedlines();
    3741        6686 :     m_rSwdoc.getIDocumentState().SetModified();
    3742             : 
    3743        6686 :     return true;
    3744             : }
    3745             : 
    3746             : // It's possible to call Replace with a PaM that spans 2 paragraphs:
    3747             : // search with regex for "$", then replace _all_
    3748          92 : bool DocumentContentOperationsManager::ReplaceRangeImpl( SwPaM& rPam, const OUString& rStr,
    3749             :         const bool bRegExReplace )
    3750             : {
    3751          92 :     if( !rPam.HasMark() || *rPam.GetPoint() == *rPam.GetMark() )
    3752           0 :         return false;
    3753             : 
    3754             :     bool bJoinTxt, bJoinPrev;
    3755          92 :     ::sw_GetJoinFlags( rPam, bJoinTxt, bJoinPrev );
    3756             : 
    3757             :     {
    3758             :         // Create a copy of the Cursor in order to move all Pams from
    3759             :         // the other views out of the deletion range.
    3760             :         // Except for itself!
    3761          92 :         SwPaM aDelPam( *rPam.GetMark(), *rPam.GetPoint() );
    3762          92 :         ::PaMCorrAbs( aDelPam, *aDelPam.GetPoint() );
    3763             : 
    3764          92 :         SwPosition *pStt = (SwPosition*)aDelPam.Start(),
    3765          92 :                    *pEnd = (SwPosition*)aDelPam.End();
    3766             :         OSL_ENSURE( pStt->nNode == pEnd->nNode ||
    3767             :                 ( pStt->nNode.GetIndex() + 1 == pEnd->nNode.GetIndex() &&
    3768             :                     !pEnd->nContent.GetIndex() ),
    3769             :                 "invalid range: Point and Mark on different nodes" );
    3770          92 :         bool bOneNode = pStt->nNode == pEnd->nNode;
    3771             : 
    3772             :         // Own Undo?
    3773         184 :         OUString sRepl( rStr );
    3774          92 :         SwTxtNode* pTxtNd = pStt->nNode.GetNode().GetTxtNode();
    3775          92 :         sal_Int32 nStt = pStt->nContent.GetIndex();
    3776          92 :         sal_Int32 nEnd = bOneNode ? pEnd->nContent.GetIndex()
    3777         184 :                                 : pTxtNd->GetTxt().getLength();
    3778             : 
    3779         184 :         SwDataChanged aTmp( aDelPam );
    3780             : 
    3781          92 :         if( m_rSwdoc.getIDocumentRedlineAccess().IsRedlineOn() )
    3782             :         {
    3783           0 :             RedlineMode_t eOld = m_rSwdoc.getIDocumentRedlineAccess().GetRedlineMode();
    3784           0 :             m_rSwdoc.GetDocumentRedlineManager().checkRedlining(eOld);
    3785           0 :             if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    3786             :             {
    3787           0 :                 m_rSwdoc.GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
    3788             : 
    3789             :                 // If any Redline will change (split!) the node
    3790           0 :                 const ::sw::mark::IMark* pBkmk = m_rSwdoc.getIDocumentMarkAccess()->makeMark( aDelPam, OUString(), IDocumentMarkAccess::UNO_BOOKMARK );
    3791             : 
    3792             :                 //JP 06.01.98: MUSS noch optimiert werden!!!
    3793           0 :                 m_rSwdoc.getIDocumentRedlineAccess().SetRedlineMode(
    3794           0 :                     (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
    3795             : 
    3796           0 :                 *aDelPam.GetPoint() = pBkmk->GetMarkPos();
    3797           0 :                 if(pBkmk->IsExpanded())
    3798           0 :                     *aDelPam.GetMark() = pBkmk->GetOtherMarkPos();
    3799           0 :                 m_rSwdoc.getIDocumentMarkAccess()->deleteMark(pBkmk);
    3800           0 :                 pStt = aDelPam.Start();
    3801           0 :                 pTxtNd = pStt->nNode.GetNode().GetTxtNode();
    3802           0 :                 nStt = pStt->nContent.GetIndex();
    3803             :             }
    3804             : 
    3805           0 :             if( !sRepl.isEmpty() )
    3806             :             {
    3807             :                 // Apply the first character's attributes to the ReplaceText
    3808           0 :                 SfxItemSet aSet( m_rSwdoc.GetAttrPool(),
    3809             :                             RES_CHRATR_BEGIN,     RES_TXTATR_WITHEND_END - 1,
    3810             :                             RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
    3811           0 :                             0 );
    3812           0 :                 pTxtNd->GetAttr( aSet, nStt+1, nStt+1 );
    3813             : 
    3814           0 :                 aSet.ClearItem( RES_TXTATR_REFMARK );
    3815           0 :                 aSet.ClearItem( RES_TXTATR_TOXMARK );
    3816           0 :                 aSet.ClearItem( RES_TXTATR_CJK_RUBY );
    3817           0 :                 aSet.ClearItem( RES_TXTATR_INETFMT );
    3818           0 :                 aSet.ClearItem( RES_TXTATR_META );
    3819           0 :                 aSet.ClearItem( RES_TXTATR_METAFIELD );
    3820             : 
    3821           0 :                 if( aDelPam.GetPoint() != aDelPam.End() )
    3822           0 :                     aDelPam.Exchange();
    3823             : 
    3824             :                 // Remember the End
    3825           0 :                 SwNodeIndex aPtNd( aDelPam.GetPoint()->nNode, -1 );
    3826           0 :                 const sal_Int32 nPtCnt = aDelPam.GetPoint()->nContent.GetIndex();
    3827             : 
    3828           0 :                 bool bFirst = true;
    3829           0 :                 OUString sIns;
    3830           0 :                 while ( lcl_GetTokenToParaBreak( sRepl, sIns, bRegExReplace ) )
    3831             :                 {
    3832           0 :                     InsertString( aDelPam, sIns );
    3833           0 :                     if( bFirst )
    3834             :                     {
    3835           0 :                         SwNodeIndex aMkNd( aDelPam.GetMark()->nNode, -1 );
    3836           0 :                         const sal_Int32 nMkCnt = aDelPam.GetMark()->nContent.GetIndex();
    3837             : 
    3838           0 :                         SplitNode( *aDelPam.GetPoint(), false );
    3839             : 
    3840           0 :                         ++aMkNd;
    3841           0 :                         aDelPam.GetMark()->nNode = aMkNd;
    3842           0 :                         aDelPam.GetMark()->nContent.Assign(
    3843           0 :                                     aMkNd.GetNode().GetCntntNode(), nMkCnt );
    3844           0 :                         bFirst = false;
    3845             :                     }
    3846             :                     else
    3847           0 :                         SplitNode( *aDelPam.GetPoint(), false );
    3848             :                 }
    3849           0 :                 if( !sIns.isEmpty() )
    3850             :                 {
    3851           0 :                     InsertString( aDelPam, sIns );
    3852             :                 }
    3853             : 
    3854           0 :                 SwPaM aTmpRange( *aDelPam.GetPoint() );
    3855           0 :                 aTmpRange.SetMark();
    3856             : 
    3857           0 :                 ++aPtNd;
    3858           0 :                 aDelPam.GetPoint()->nNode = aPtNd;
    3859           0 :                 aDelPam.GetPoint()->nContent.Assign( aPtNd.GetNode().GetCntntNode(),
    3860           0 :                                                     nPtCnt);
    3861           0 :                 *aTmpRange.GetMark() = *aDelPam.GetPoint();
    3862             : 
    3863           0 :                 m_rSwdoc.RstTxtAttrs( aTmpRange );
    3864           0 :                 InsertItemSet( aTmpRange, aSet, 0 );
    3865             :             }
    3866             : 
    3867           0 :             if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    3868             :             {
    3869             :                 SwUndo *const pUndoRD =
    3870           0 :                     new SwUndoRedlineDelete( aDelPam, UNDO_REPLACE );
    3871           0 :                 m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndoRD);
    3872             :             }
    3873           0 :             m_rSwdoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, aDelPam ), true);
    3874             : 
    3875           0 :             *rPam.GetMark() = *aDelPam.GetMark();
    3876           0 :             if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
    3877             :             {
    3878           0 :                 *aDelPam.GetPoint() = *rPam.GetPoint();
    3879           0 :                 m_rSwdoc.GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
    3880             : 
    3881             :                 // If any Redline will change (split!) the node
    3882           0 :                 const ::sw::mark::IMark* pBkmk = m_rSwdoc.getIDocumentMarkAccess()->makeMark( aDelPam, OUString(), IDocumentMarkAccess::UNO_BOOKMARK );
    3883             : 
    3884           0 :                 SwIndex& rIdx = aDelPam.GetPoint()->nContent;
    3885           0 :                 rIdx.Assign( 0, 0 );
    3886           0 :                 aDelPam.GetMark()->nContent = rIdx;
    3887           0 :                 rPam.GetPoint()->nNode = 0;
    3888           0 :                 rPam.GetPoint()->nContent = rIdx;
    3889           0 :                 *rPam.GetMark() = *rPam.GetPoint();
    3890             :                 //JP 06.01.98: MUSS noch optimiert werden!!!
    3891           0 :                 m_rSwdoc.getIDocumentRedlineAccess().SetRedlineMode( eOld );
    3892             : 
    3893           0 :                 *rPam.GetPoint() = pBkmk->GetMarkPos();
    3894           0 :                 if(pBkmk->IsExpanded())
    3895           0 :                     *rPam.GetMark() = pBkmk->GetOtherMarkPos();
    3896           0 :                 m_rSwdoc.getIDocumentMarkAccess()->deleteMark(pBkmk);
    3897             :             }
    3898           0 :             bJoinTxt = false;
    3899             :         }
    3900             :         else
    3901             :         {
    3902          92 :             if( !m_rSwdoc.getIDocumentRedlineAccess().IsIgnoreRedline() && m_rSwdoc.getIDocumentRedlineAccess().GetRedlineTbl().size() )
    3903           0 :                 m_rSwdoc.getIDocumentRedlineAccess().DeleteRedline( aDelPam, true, USHRT_MAX );
    3904             : 
    3905          92 :             SwUndoReplace* pUndoRpl = 0;
    3906          92 :             bool const bDoesUndo = m_rSwdoc.GetIDocumentUndoRedo().DoesUndo();
    3907          92 :             if (bDoesUndo)
    3908             :             {
    3909          92 :                 pUndoRpl = new SwUndoReplace(aDelPam, sRepl, bRegExReplace);
    3910          92 :                 m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndoRpl);
    3911             :             }
    3912          92 :             ::sw::UndoGuard const undoGuard(m_rSwdoc.GetIDocumentUndoRedo());
    3913             : 
    3914          92 :             if( aDelPam.GetPoint() != pStt )
    3915          90 :                 aDelPam.Exchange();
    3916             : 
    3917         184 :             SwNodeIndex aPtNd( pStt->nNode, -1 );
    3918          92 :             const sal_Int32 nPtCnt = pStt->nContent.GetIndex();
    3919             : 
    3920             :             // Set the values again, if Frames or footnotes on the Text have been removed.
    3921          92 :             nStt = nPtCnt;
    3922          92 :             nEnd = bOneNode ? pEnd->nContent.GetIndex()
    3923         184 :                             : pTxtNd->GetTxt().getLength();
    3924             : 
    3925          92 :             bool bFirst = true;
    3926         184 :             OUString sIns;
    3927         184 :             while ( lcl_GetTokenToParaBreak( sRepl, sIns, bRegExReplace ) )
    3928             :             {
    3929           0 :                 if (!bFirst || nStt == pTxtNd->GetTxt().getLength())
    3930             :                 {
    3931           0 :                     InsertString( aDelPam, sIns );
    3932             :                 }
    3933           0 :                 else if( nStt < nEnd || !sIns.isEmpty() )
    3934             :                 {
    3935           0 :                     pTxtNd->ReplaceText( pStt->nContent, nEnd - nStt, sIns );
    3936             :                 }
    3937           0 :                 SplitNode( *pStt, false);
    3938           0 :                 bFirst = false;
    3939             :             }
    3940             : 
    3941          92 :             if( bFirst || !sIns.isEmpty() )
    3942             :             {
    3943          92 :                 if (!bFirst || nStt == pTxtNd->GetTxt().getLength())
    3944             :                 {
    3945           0 :                     InsertString( aDelPam, sIns );
    3946             :                 }
    3947          92 :                 else if( nStt < nEnd || !sIns.isEmpty() )
    3948             :                 {
    3949          92 :                     pTxtNd->ReplaceText( pStt->nContent, nEnd - nStt, sIns );
    3950             :                 }
    3951             :             }
    3952             : 
    3953          92 :             *rPam.GetPoint() = *aDelPam.GetMark();
    3954          92 :             ++aPtNd;
    3955          92 :             rPam.GetMark()->nNode = aPtNd;
    3956         184 :             rPam.GetMark()->nContent.Assign( aPtNd.GetNode().GetCntntNode(),
    3957         184 :                                                 nPtCnt );
    3958             : 
    3959          92 :             if (bJoinTxt)
    3960             :             {
    3961             :                 assert(rPam.GetPoint() == rPam.End());
    3962             :                 // move so that SetEnd remembers position after sw_JoinText
    3963           0 :                 rPam.Move(fnMoveBackward);
    3964             :             }
    3965          92 :             else if (aDelPam.GetPoint() == pStt) // backward selection?
    3966             :             {
    3967             :                 assert(*rPam.GetMark() <= *rPam.GetPoint());
    3968          92 :                 rPam.Exchange(); // swap so that rPam is backwards
    3969             :             }
    3970             : 
    3971          92 :             if( pUndoRpl )
    3972             :             {
    3973          92 :                 pUndoRpl->SetEnd(rPam);
    3974          92 :             }
    3975          92 :         }
    3976             :     }
    3977             : 
    3978          92 :     if( bJoinTxt )
    3979           0 :         ::sw_JoinText( rPam, bJoinPrev );
    3980             : 
    3981          92 :     m_rSwdoc.getIDocumentState().SetModified();
    3982          92 :     return true;
    3983             : }
    3984             : 
    3985        1676 : SwFlyFrmFmt* DocumentContentOperationsManager::_InsNoTxtNode( const SwPosition& rPos, SwNoTxtNode* pNode,
    3986             :                                     const SfxItemSet* pFlyAttrSet,
    3987             :                                     const SfxItemSet* pGrfAttrSet,
    3988             :                                     SwFrmFmt* pFrmFmt)
    3989             : {
    3990        1676 :     SwFlyFrmFmt *pFmt = 0;
    3991        1676 :     if( pNode )
    3992             :     {
    3993             :         pFmt = m_rSwdoc._MakeFlySection( rPos, *pNode, FLY_AT_PARA,
    3994        1676 :                                 pFlyAttrSet, pFrmFmt );
    3995        1676 :         if( pGrfAttrSet )
    3996         818 :             pNode->SetAttr( *pGrfAttrSet );
    3997             :     }
    3998        1676 :     return pFmt;
    3999             : }
    4000             : 
    4001             : #define NUMRULE_STATE \
    4002             :      SfxItemState aNumRuleState = SfxItemState::UNKNOWN; \
    4003             :      SwNumRuleItem aNumRuleItem; \
    4004             :      SfxItemState aListIdState = SfxItemState::UNKNOWN; \
    4005             :      SfxStringItem aListIdItem( RES_PARATR_LIST_ID, OUString() ); \
    4006             : 
    4007             : #define PUSH_NUMRULE_STATE \
    4008             :      lcl_PushNumruleState( aNumRuleState, aNumRuleItem, aListIdState, aListIdItem, pDestTxtNd );
    4009             : 
    4010             : #define POP_NUMRULE_STATE \
    4011             :      lcl_PopNumruleState( aNumRuleState, aNumRuleItem, aListIdState, aListIdItem, pDestTxtNd, rPam );
    4012             : 
    4013         396 : static void lcl_PushNumruleState( SfxItemState &aNumRuleState, SwNumRuleItem &aNumRuleItem,
    4014             :                                   SfxItemState &aListIdState, SfxStringItem &aListIdItem,
    4015             :                                   const SwTxtNode *pDestTxtNd )
    4016             : {
    4017             :     // Safe numrule item at destination.
    4018             :     // #i86492# - Safe also <ListId> item of destination.
    4019         396 :     const SfxItemSet * pAttrSet = pDestTxtNd->GetpSwAttrSet();
    4020         396 :     if (pAttrSet != NULL)
    4021             :     {
    4022           0 :         const SfxPoolItem * pItem = NULL;
    4023           0 :         aNumRuleState = pAttrSet->GetItemState(RES_PARATR_NUMRULE, false, &pItem);
    4024           0 :         if (SfxItemState::SET == aNumRuleState)
    4025           0 :             aNumRuleItem = *((SwNumRuleItem *) pItem);
    4026             : 
    4027             :         aListIdState =
    4028           0 :             pAttrSet->GetItemState(RES_PARATR_LIST_ID, false, &pItem);
    4029           0 :         if (SfxItemState::SET == aListIdState)
    4030             :         {
    4031           0 :             aListIdItem.SetValue( static_cast<const SfxStringItem*>(pItem)->GetValue() );
    4032             :         }
    4033             :     }
    4034         396 : }
    4035             : 
    4036         158 : static void lcl_PopNumruleState( SfxItemState aNumRuleState, const SwNumRuleItem &aNumRuleItem,
    4037             :                                  SfxItemState aListIdState, const SfxStringItem &aListIdItem,
    4038             :                                  SwTxtNode *pDestTxtNd, const SwPaM& rPam )
    4039             : {
    4040             :     /* If only a part of one paragraph is copied
    4041             :        restore the numrule at the destination. */
    4042             :     // #i86492# - restore also <ListId> item
    4043         158 :     if ( !lcl_MarksWholeNode(rPam) )
    4044             :     {
    4045           4 :         if (SfxItemState::SET == aNumRuleState)
    4046             :         {
    4047           0 :             pDestTxtNd->SetAttr(aNumRuleItem);
    4048             :         }
    4049             :         else
    4050             :         {
    4051           4 :             pDestTxtNd->ResetAttr(RES_PARATR_NUMRULE);
    4052             :         }
    4053           4 :         if (SfxItemState::SET == aListIdState)
    4054             :         {
    4055           0 :             pDestTxtNd->SetAttr(aListIdItem);
    4056             :         }
    4057             :         else
    4058             :         {
    4059           4 :             pDestTxtNd->ResetAttr(RES_PARATR_LIST_ID);
    4060             :         }
    4061             :     }
    4062         158 : }
    4063             : 
    4064         406 : bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
    4065             :         const bool bMakeNewFrms, const bool bCopyAll,
    4066             :         SwPaM *const pCpyRange ) const
    4067             : {
    4068         406 :     SwDoc* pDoc = rPos.nNode.GetNode().GetDoc();
    4069         406 :     const bool bColumnSel = pDoc->IsClipBoard() && pDoc->IsColumnSelection();
    4070             : 
    4071         406 :     SwPosition* pStt = rPam.Start();
    4072         406 :     SwPosition* pEnd = rPam.End();
    4073             : 
    4074             :     // Catch when there's no copy to do.
    4075         812 :     if( !rPam.HasMark() || ( *pStt > *pEnd && !bColumnSel ) ||
    4076             :         //JP 29.6.2001: 88963 - dont copy if inspos is in region of start to end
    4077             :         //JP 15.11.2001: don't test inclusive the end, ever exclusive
    4078         776 :         ( pDoc == &m_rSwdoc && *pStt <= rPos && rPos < *pEnd ))
    4079             :     {
    4080           0 :         return false;
    4081             :     }
    4082             : 
    4083         406 :     const bool bEndEqualIns = pDoc == &m_rSwdoc && rPos == *pEnd;
    4084             : 
    4085             :     // If Undo is enabled, create the UndoCopy object
    4086         406 :     SwUndoCpyDoc* pUndo = 0;
    4087             :     // lcl_DeleteRedlines may delete the start or end node of the cursor when
    4088             :     // removing the redlines so use cursor that is corrected by PaMCorrAbs
    4089         406 :     ::boost::scoped_ptr<SwUnoCrsr> const pCopyPam(pDoc->CreateUnoCrsr(rPos));
    4090             : 
    4091         812 :     SwTblNumFmtMerge aTNFM( m_rSwdoc, *pDoc );
    4092             : 
    4093         406 :     if (pDoc->GetIDocumentUndoRedo().DoesUndo())
    4094             :     {
    4095          18 :         pUndo = new SwUndoCpyDoc(*pCopyPam);
    4096          18 :         pDoc->GetIDocumentUndoRedo().AppendUndo( pUndo );
    4097             :     }
    4098             : 
    4099         406 :     RedlineMode_t eOld = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
    4100         406 :     pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
    4101             : 
    4102             :     // Move the PaM one node back from the insert position, so that
    4103             :     // the position doesn't get moved
    4104         406 :     pCopyPam->SetMark();
    4105         406 :     bool bCanMoveBack = pCopyPam->Move(fnMoveBackward, fnGoCntnt);
    4106             :     // If the position was shifted from more than one node, an end node has been skipped
    4107         406 :     bool bAfterTable = false;
    4108         406 :     if ((rPos.nNode.GetIndex() - pCopyPam->GetPoint()->nNode.GetIndex()) > 1)
    4109             :     {
    4110             :         // First go back to the original place
    4111           0 :         pCopyPam->GetPoint()->nNode = rPos.nNode;
    4112           0 :         pCopyPam->GetPoint()->nContent = rPos.nContent;
    4113             : 
    4114           0 :         bCanMoveBack = false;
    4115           0 :         bAfterTable = true;
    4116             :     }
    4117         406 :     if( !bCanMoveBack )
    4118         384 :         pCopyPam->GetPoint()->nNode--;
    4119             : 
    4120         812 :     SwNodeRange aRg( pStt->nNode, pEnd->nNode );
    4121         812 :     SwNodeIndex aInsPos( rPos.nNode );
    4122         406 :     const bool bOneNode = pStt->nNode == pEnd->nNode;
    4123         406 :     SwTxtNode* pSttTxtNd = pStt->nNode.GetNode().GetTxtNode();
    4124         406 :     SwTxtNode* pEndTxtNd = pEnd->nNode.GetNode().GetTxtNode();
    4125         406 :     SwTxtNode* pDestTxtNd = aInsPos.GetNode().GetTxtNode();
    4126         802 :     bool bCopyCollFmt = !pDoc->IsInsOnlyTextGlossary() &&
    4127         400 :                         ( (pDestTxtNd && !pDestTxtNd->GetTxt().getLength()) ||
    4128         450 :                           ( !bOneNode && !rPos.nContent.GetIndex() ) );
    4129         406 :     bool bCopyBookmarks = true;
    4130         406 :     bool bStartIsTxtNode = 0 != pSttTxtNd;
    4131             : 
    4132             :     // #i104585# copy outline num rule to clipboard (for ASCII filter)
    4133         406 :     if (pDoc->IsClipBoard() && m_rSwdoc.GetOutlineNumRule())
    4134             :     {
    4135           4 :         pDoc->SetOutlineNumRule(*m_rSwdoc.GetOutlineNumRule());
    4136             :     }
    4137             : 
    4138             :     // #i86492#
    4139             :     // Correct the search for a previous list:
    4140             :     // First search for non-outline numbering list. Then search for non-outline
    4141             :     // bullet list.
    4142             :     // Keep also the <ListId> value for possible propagation.
    4143         812 :     OUString aListIdToPropagate;
    4144             :     const SwNumRule* pNumRuleToPropagate =
    4145         406 :         pDoc->SearchNumRule( rPos, false, true, false, 0, aListIdToPropagate, true );
    4146         406 :     if ( !pNumRuleToPropagate )
    4147             :     {
    4148             :         pNumRuleToPropagate =
    4149         406 :             pDoc->SearchNumRule( rPos, false, false, false, 0, aListIdToPropagate, true );
    4150             :     }
    4151             :     // #i86492#
    4152             :     // Do not propagate previous found list, if
    4153             :     // - destination is an empty paragraph which is not in a list and
    4154             :     // - source contains at least one paragraph which is not in a list
    4155         410 :     if ( pNumRuleToPropagate &&
    4156           8 :          pDestTxtNd && !pDestTxtNd->GetTxt().getLength() &&
    4157         414 :          !pDestTxtNd->IsInList() &&
    4158           4 :          !lcl_ContainsOnlyParagraphsInList( rPam ) )
    4159             :     {
    4160           4 :         pNumRuleToPropagate = 0;
    4161             :     }
    4162             : 
    4163         406 :     bool bHandledStartNode = false;
    4164             : 
    4165             :     // This do/while block is only there so that we can break out of it!
    4166             :     do {
    4167         406 :         if( pSttTxtNd )
    4168             :         {
    4169             :             // Don't copy the beginning completely?
    4170         384 :             if( !bCopyCollFmt || bColumnSel || pStt->nContent.GetIndex() )
    4171             :             {
    4172          14 :                 bHandledStartNode = true;
    4173             : 
    4174          14 :                 SwIndex aDestIdx( rPos.nContent );
    4175          14 :                 bool bCopyOk = false;
    4176          14 :                 if( !pDestTxtNd )
    4177             :                 {
    4178           0 :                     if( pStt->nContent.GetIndex() || bOneNode )
    4179           0 :                         pDestTxtNd = pDoc->GetNodes().MakeTxtNode( aInsPos,
    4180           0 :                             pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool(RES_POOLCOLL_STANDARD));
    4181             :                     else
    4182             :                     {
    4183           0 :                         pDestTxtNd = static_cast<SwTxtNode*>(pSttTxtNd->MakeCopy( pDoc, aInsPos ));
    4184           0 :                         bCopyOk = true;
    4185             :                     }
    4186           0 :                     aDestIdx.Assign( pDestTxtNd, 0 );
    4187           0 :                     bCopyCollFmt = true;
    4188             :                 }
    4189          14 :                 else if( !bOneNode || bColumnSel )
    4190             :                 {
    4191          10 :                     const sal_Int32 nCntntEnd = pEnd->nContent.GetIndex();
    4192             :                     {
    4193          10 :                         ::sw::UndoGuard const ug(pDoc->GetIDocumentUndoRedo());
    4194          10 :                         pDoc->getIDocumentContentOperations().SplitNode( rPos, false );
    4195             :                     }
    4196             : 
    4197          10 :                     if (bCanMoveBack && rPos == *pCopyPam->GetPoint())
    4198             :                     {
    4199             :                         // after the SplitNode, span the CpyPam correctly again
    4200           2 :                         pCopyPam->Move( fnMoveBackward, fnGoCntnt );
    4201           2 :                         pCopyPam->Move( fnMoveBackward, fnGoCntnt );
    4202             :                     }
    4203             : 
    4204          10 :                     pDestTxtNd = pDoc->GetNodes()[ aInsPos.GetIndex()-1 ]->GetTxtNode();
    4205             :                     aDestIdx.Assign(
    4206          10 :                             pDestTxtNd, pDestTxtNd->GetTxt().getLength());
    4207             : 
    4208             :                     // Correct the area again
    4209          10 :                     if( bEndEqualIns )
    4210             :                     {
    4211           0 :                         bool bChg = pEnd != rPam.GetPoint();
    4212           0 :                         if( bChg )
    4213           0 :                             rPam.Exchange();
    4214           0 :                         rPam.Move( fnMoveBackward, fnGoCntnt );
    4215           0 :                         if( bChg )
    4216           0 :                             rPam.Exchange();
    4217             : 
    4218           0 :                         aRg.aEnd = pEnd->nNode;
    4219           0 :                         pEndTxtNd = pEnd->nNode.GetNode().GetTxtNode();
    4220             :                     }
    4221          10 :                     else if( rPos == *pEnd )
    4222             :                     {
    4223             :                         // The end was also moved
    4224           0 :                         pEnd->nNode--;
    4225           0 :                         pEnd->nContent.Assign( pDestTxtNd, nCntntEnd );
    4226           0 :                         aRg.aEnd = pEnd->nNode;
    4227           0 :                         pEndTxtNd = pEnd->nNode.GetNode().GetTxtNode();
    4228             :                     }
    4229             :                 }
    4230             : 
    4231          28 :                 NUMRULE_STATE
    4232          14 :                 if( bCopyCollFmt && bOneNode )
    4233             :                 {
    4234           4 :                     PUSH_NUMRULE_STATE
    4235             :                 }
    4236             : 
    4237          14 :                 if( !bCopyOk )
    4238             :                 {
    4239             :                     const sal_Int32 nCpyLen = ( (bOneNode)
    4240           4 :                                            ? pEnd->nContent.GetIndex()
    4241          10 :                                            : pSttTxtNd->GetTxt().getLength())
    4242          28 :                                          - pStt->nContent.GetIndex();
    4243             :                     pSttTxtNd->CopyText( pDestTxtNd, aDestIdx,
    4244          14 :                                             pStt->nContent, nCpyLen );
    4245          14 :                     if( bEndEqualIns )
    4246           0 :                         pEnd->nContent -= nCpyLen;
    4247             :                 }
    4248             : 
    4249          14 :                 if( bCopyCollFmt && bOneNode )
    4250             :                 {
    4251           4 :                     pSttTxtNd->CopyCollFmt( *pDestTxtNd );
    4252           4 :                     POP_NUMRULE_STATE
    4253          14 :                 }
    4254             :             }
    4255             :         }
    4256          22 :         else if( pDestTxtNd )
    4257             :         {
    4258             :             // Problems with insertion of table selections into "normal" text solved.
    4259             :             // We have to set the correct PaM for Undo, if this PaM starts in a textnode,
    4260             :             // the undo operation will try to merge this node after removing the table.
    4261             :             // If we didn't split a textnode, the PaM should start at the inserted table node
    4262           2 :             if( rPos.nContent.GetIndex() == pDestTxtNd->Len() )
    4263             :             {    // Insertion at the last position of a textnode (empty or not)
    4264           2 :                 ++aInsPos; // The table will be inserted behind the text node
    4265             :             }
    4266           0 :             else if( rPos.nContent.GetIndex() )
    4267             :             {   // Insertion in the middle of a text node, it has to be split
    4268             :                 // (and joined from undo)
    4269           0 :                 bStartIsTxtNode = true;
    4270             : 
    4271           0 :                 const sal_Int32 nCntntEnd = pEnd->nContent.GetIndex();
    4272             :                 {
    4273           0 :                     ::sw::UndoGuard const ug(pDoc->GetIDocumentUndoRedo());
    4274           0 :                     pDoc->getIDocumentContentOperations().SplitNode( rPos, false );
    4275             :                 }
    4276             : 
    4277           0 :                 if (bCanMoveBack && rPos == *pCopyPam->GetPoint())
    4278             :                 {
    4279             :                     // after the SplitNode, span the CpyPam correctly again
    4280           0 :                     pCopyPam->Move( fnMoveBackward, fnGoCntnt );
    4281           0 :                     pCopyPam->Move( fnMoveBackward, fnGoCntnt );
    4282             :                 }
    4283             : 
    4284             :                 // Correct the area again
    4285           0 :                 if( bEndEqualIns )
    4286           0 :                     aRg.aEnd--;
    4287             :                 // The end would also be moved
    4288           0 :                 else if( rPos == *pEnd )
    4289             :                 {
    4290           0 :                     rPos.nNode-=2;
    4291           0 :                     rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(),
    4292           0 :                                             nCntntEnd );
    4293           0 :                     rPos.nNode++;
    4294           0 :                     aRg.aEnd--;
    4295             :                 }
    4296             :             }
    4297           0 :             else if( bCanMoveBack )
    4298             :             {   //Insertion at the first position of a text node. It will not be splitted, the table
    4299             :                 // will be inserted before the text node.
    4300             :                 // See below, before the SetInsertRange funciton of the undo object will be called,
    4301             :                 // the CpyPam would be moved to the next content position. This has to be avoided
    4302             :                 // We want to be moved to the table node itself thus we have to set bCanMoveBack
    4303             :                 // and to manipulate pCopyPam.
    4304           0 :                 bCanMoveBack = false;
    4305           0 :                 pCopyPam->GetPoint()->nNode--;
    4306             :             }
    4307             :         }
    4308             : 
    4309         406 :         pDestTxtNd = aInsPos.GetNode().GetTxtNode();
    4310         406 :         if( pEndTxtNd && (!bOneNode || !bHandledStartNode) )
    4311             :         {
    4312         402 :             SwIndex aDestIdx( rPos.nContent );
    4313         402 :             if( !pDestTxtNd )
    4314             :             {
    4315          22 :                 pDestTxtNd = pDoc->GetNodes().MakeTxtNode( aInsPos,
    4316          44 :                             pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool(RES_POOLCOLL_STANDARD));
    4317          22 :                 aDestIdx.Assign( pDestTxtNd, 0  );
    4318          22 :                 aInsPos--;
    4319             : 
    4320             :                 // if we have to insert an extra text node
    4321             :                 // at the destination, this node will be our new destination
    4322             :                 // (text) node, and thus we set bStartisTxtNode to true. This
    4323             :                 // will ensure that this node will be deleted during Undo
    4324             :                 // using JoinNext.
    4325             :                 OSL_ENSURE( !bStartIsTxtNode, "Oops, undo may be instable now." );
    4326          22 :                 bStartIsTxtNode = true;
    4327             :             }
    4328             : 
    4329         402 :             const bool bEmptyDestNd = pDestTxtNd->GetTxt().isEmpty();
    4330             : 
    4331         804 :             NUMRULE_STATE
    4332         402 :             if( bCopyCollFmt && ( bOneNode || bEmptyDestNd ))
    4333             :             {
    4334         392 :                 PUSH_NUMRULE_STATE
    4335             :             }
    4336             : 
    4337         402 :             pEndTxtNd->CopyText( pDestTxtNd, aDestIdx, SwIndex( pEndTxtNd ),
    4338         804 :                             pEnd->nContent.GetIndex() );
    4339             : 
    4340             :             // Also copy all format templates
    4341         402 :             if( bCopyCollFmt && ( bOneNode || bEmptyDestNd ))
    4342             :             {
    4343         392 :                 pEndTxtNd->CopyCollFmt( *pDestTxtNd );
    4344         392 :                 if ( bOneNode )
    4345             :                 {
    4346         154 :                     POP_NUMRULE_STATE
    4347             :                 }
    4348         402 :             }
    4349             :         }
    4350             : 
    4351         406 :         if( bCopyAll || aRg.aStart != aRg.aEnd )
    4352             :         {
    4353         248 :             SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange );
    4354         248 :             if( !bOneNode && pSttTxtNd && bCopyCollFmt && pDestTxtNd->HasSwAttrSet() )
    4355             :             {
    4356         150 :                 aBrkSet.Put( *pDestTxtNd->GetpSwAttrSet() );
    4357         150 :                 if( SfxItemState::SET == aBrkSet.GetItemState( RES_BREAK, false ) )
    4358           0 :                     pDestTxtNd->ResetAttr( RES_BREAK );
    4359         150 :                 if( SfxItemState::SET == aBrkSet.GetItemState( RES_PAGEDESC, false ) )
    4360           0 :                     pDestTxtNd->ResetAttr( RES_PAGEDESC );
    4361             :             }
    4362             : 
    4363         248 :             if( aInsPos == pEnd->nNode )
    4364             :             {
    4365           0 :                 SwNodeIndex aSaveIdx( aInsPos, -1 );
    4366             :                 CopyWithFlyInFly( aRg, 0, aInsPos, &rPam, bMakeNewFrms,
    4367           0 :                                   false, false, bHandledStartNode );
    4368           0 :                 ++aSaveIdx;
    4369           0 :                 pEnd->nNode = aSaveIdx;
    4370           0 :                 pEnd->nContent.Assign( aSaveIdx.GetNode().GetTxtNode(), 0 );
    4371             :             }
    4372             :             else
    4373             :                 CopyWithFlyInFly( aRg, pEnd->nContent.GetIndex(), aInsPos, &rPam,
    4374         248 :                                   bMakeNewFrms, false, false, bHandledStartNode );
    4375             : 
    4376         248 :             bCopyBookmarks = false;
    4377             : 
    4378             :             // Put the breaks back into the first node
    4379         248 :             if( aBrkSet.Count() && 0 != ( pDestTxtNd = pDoc->GetNodes()[
    4380           0 :                     pCopyPam->GetPoint()->nNode.GetIndex()+1 ]->GetTxtNode()))
    4381             :             {
    4382           0 :                 pDestTxtNd->SetAttr( aBrkSet );
    4383         248 :             }
    4384             :         }
    4385             :     } while( false );
    4386             : 
    4387             :     // Adjust position (in case it was moved / in another node)
    4388         406 :     rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(),
    4389         812 :                             rPos.nContent.GetIndex() );
    4390             : 
    4391         406 :     if( rPos.nNode != aInsPos )
    4392             :     {
    4393          22 :         pCopyPam->GetMark()->nNode = aInsPos;
    4394          22 :         pCopyPam->GetMark()->nContent.Assign(pCopyPam->GetCntntNode(false), 0);
    4395          22 :         rPos = *pCopyPam->GetMark();
    4396             :     }
    4397             :     else
    4398         384 :         *pCopyPam->GetMark() = rPos;
    4399             : 
    4400         406 :     if ( !bAfterTable )
    4401         406 :         pCopyPam->Move( fnMoveForward, bCanMoveBack ? fnGoCntnt : fnGoNode );
    4402             :     else
    4403             :     {
    4404             :         // Reset the offset to 0 as it was before the insertion
    4405           0 :         pCopyPam->GetPoint()->nContent -= pCopyPam->GetPoint()->nContent;
    4406             : 
    4407           0 :         pCopyPam->GetPoint()->nNode++;
    4408             :         // If the next node is a start node, then step back: the start node
    4409             :         // has been copied and needs to be in the selection for the undo
    4410           0 :         if (pCopyPam->GetPoint()->nNode.GetNode().IsStartNode())
    4411           0 :             pCopyPam->GetPoint()->nNode--;
    4412             : 
    4413             :     }
    4414         406 :     pCopyPam->Exchange();
    4415             : 
    4416             :     // Also copy all bookmarks
    4417         406 :     if( bCopyBookmarks && m_rSwdoc.getIDocumentMarkAccess()->getAllMarksCount() )
    4418         136 :         lcl_CopyBookmarks( rPam, *pCopyPam );
    4419             : 
    4420         406 :     if( nsRedlineMode_t::REDLINE_DELETE_REDLINES & eOld )
    4421             :     {
    4422             :         assert(*pCopyPam->GetPoint() == rPos);
    4423             :         // the Node rPos points to may be deleted so unregister ...
    4424           4 :         rPos.nContent = SwIndex(0);
    4425           4 :         lcl_DeleteRedlines(rPam, *pCopyPam);
    4426           4 :         rPos = *pCopyPam->GetPoint(); // ... and restore.
    4427             :     }
    4428             : 
    4429             :     // If Undo is enabled, store the inserted area
    4430         406 :     if (pDoc->GetIDocumentUndoRedo().DoesUndo())
    4431             :     {
    4432          18 :         pUndo->SetInsertRange( *pCopyPam, true, bStartIsTxtNode );
    4433             :     }
    4434             : 
    4435         406 :     if( pCpyRange )
    4436             :     {
    4437          10 :         pCpyRange->SetMark();
    4438          10 :         *pCpyRange->GetPoint() = *pCopyPam->GetPoint();
    4439          10 :         *pCpyRange->GetMark() = *pCopyPam->GetMark();
    4440             :     }
    4441             : 
    4442         406 :     if ( pNumRuleToPropagate != NULL )
    4443             :     {
    4444             :         // #i86492# - use <SwDoc::SetNumRule(..)>, because it also handles the <ListId>
    4445           0 :         pDoc->SetNumRule( *pCopyPam, *pNumRuleToPropagate, false,
    4446           0 :                           aListIdToPropagate, true, true );
    4447             :     }
    4448             : 
    4449         406 :     pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
    4450         406 :     pDoc->getIDocumentState().SetModified();
    4451             : 
    4452         812 :     return true;
    4453             : }
    4454             : 
    4455             : 
    4456         270 : }
    4457             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10