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

Generated by: LCOV version 1.11