LCOV - code coverage report
Current view: top level - sw/source/core/docnode - ndcopy.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 414 779 53.1 %
Date: 2012-08-25 Functions: 15 21 71.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 534 1739 30.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <editeng/brkitem.hxx>
      31                 :            : 
      32                 :            : #include <hintids.hxx>
      33                 :            : #include <fmtpdsc.hxx>
      34                 :            : #include <fmtanchr.hxx>
      35                 :            : #include <fmtcntnt.hxx>
      36                 :            : #include <doc.hxx>
      37                 :            : #include <IDocumentUndoRedo.hxx>
      38                 :            : #include <pam.hxx>
      39                 :            : #include <ndtxt.hxx>
      40                 :            : #include <fldbas.hxx>
      41                 :            : #include <swtable.hxx>
      42                 :            : #include <ddefld.hxx>
      43                 :            : #include <undobj.hxx>
      44                 :            : #include <IMark.hxx>
      45                 :            : #include <mvsave.hxx>
      46                 :            : #include <cellatr.hxx>
      47                 :            : #include <swtblfmt.hxx>
      48                 :            : #include <swddetbl.hxx>
      49                 :            : #include <docary.hxx>
      50                 :            : #include <fmtcnct.hxx>
      51                 :            : #include <redline.hxx>
      52                 :            : #include <paratr.hxx>
      53                 :            : #include <pagedesc.hxx>
      54                 :            : #include <poolfmt.hxx>
      55                 :            : #include <SwNodeNum.hxx>
      56                 :            : #include <set>
      57                 :            : #include <vector>
      58                 :            : #include <boost/foreach.hpp>
      59                 :            : 
      60                 :            : #ifdef DBG_UTIL
      61                 :            : #define CHECK_TABLE(t) (t).CheckConsistency();
      62                 :            : #else
      63                 :            : #define CHECK_TABLE(t)
      64                 :            : #endif
      65                 :            : 
      66                 :            : namespace
      67                 :            : {
      68                 :            :     /*
      69                 :            :         The lcl_CopyBookmarks function has to copy bookmarks from the source to the destination nodes
      70                 :            :         array. It is called after a call of the _CopyNodes(..) function. But this function does not copy
      71                 :            :         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.
      72                 :            :         The lcl_NonCopyCount function counts the number of these nodes, given the copied pam and a node
      73                 :            :         index inside the pam.
      74                 :            :         rPam is the original source pam, rLastIdx is the last calculated position, rDelCount the number
      75                 :            :         of "non-copy" nodes between rPam.Start() and rLastIdx.
      76                 :            :         nNewIdx is the new position of interest.
      77                 :            :     */
      78                 :            : 
      79                 :          0 :     static void lcl_NonCopyCount( const SwPaM& rPam, SwNodeIndex& rLastIdx, const sal_uLong nNewIdx, sal_uLong& rDelCount )
      80                 :            :     {
      81                 :          0 :         sal_uLong nStart = rPam.Start()->nNode.GetIndex();
      82                 :          0 :         sal_uLong nEnd = rPam.End()->nNode.GetIndex();
      83         [ #  # ]:          0 :         if( rLastIdx.GetIndex() < nNewIdx ) // Moving forward?
      84                 :            :         {
      85         [ #  # ]:          0 :             do // count "non-copy" nodes
      86                 :            :             {
      87                 :          0 :                 SwNode& rNode = rLastIdx.GetNode();
      88   [ #  #  #  #  :          0 :                 if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
           #  # ][ #  # ]
                 [ #  # ]
      89                 :          0 :                     || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
      90                 :          0 :                     ++rDelCount;
      91                 :          0 :                 rLastIdx++;
      92                 :            :             }
      93                 :          0 :             while( rLastIdx.GetIndex() < nNewIdx );
      94                 :            :         }
      95         [ #  # ]:          0 :         else if( rDelCount ) // optimization: if there are no "non-copy" nodes until now,
      96                 :            :                              // no move backward needed
      97                 :            :         {
      98         [ #  # ]:          0 :             while( rLastIdx.GetIndex() > nNewIdx )
      99                 :            :             {
     100                 :          0 :                 SwNode& rNode = rLastIdx.GetNode();
     101   [ #  #  #  #  :          0 :                 if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
           #  # ][ #  # ]
                 [ #  # ]
     102                 :          0 :                     || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
     103                 :          0 :                     --rDelCount;
     104                 :          0 :                 rLastIdx--;
     105                 :            :             }
     106                 :            :         }
     107                 :          0 :     }
     108                 :            : 
     109                 :          0 :     static void lcl_SetCpyPos( const SwPosition& rOrigPos,
     110                 :            :                         const SwPosition& rOrigStt,
     111                 :            :                         const SwPosition& rCpyStt,
     112                 :            :                         SwPosition& rChgPos,
     113                 :            :                         sal_uLong nDelCount )
     114                 :            :     {
     115                 :          0 :         sal_uLong nNdOff = rOrigPos.nNode.GetIndex();
     116                 :          0 :         nNdOff -= rOrigStt.nNode.GetIndex();
     117                 :          0 :         nNdOff -= nDelCount;
     118                 :          0 :         xub_StrLen nCntntPos = rOrigPos.nContent.GetIndex();
     119                 :            : 
     120                 :            :         // Always adjust <nNode> at to be changed <SwPosition> instance <rChgPos>
     121                 :          0 :         rChgPos.nNode = nNdOff + rCpyStt.nNode.GetIndex();
     122         [ #  # ]:          0 :         if( !nNdOff )
     123                 :            :         {
     124                 :            :             // dann nur den Content anpassen
     125         [ #  # ]:          0 :             if( nCntntPos > rOrigStt.nContent.GetIndex() )
     126                 :          0 :                 nCntntPos = nCntntPos - rOrigStt.nContent.GetIndex();
     127                 :            :             else
     128                 :          0 :                 nCntntPos = 0;
     129                 :          0 :             nCntntPos = nCntntPos + rCpyStt.nContent.GetIndex();
     130                 :            :         }
     131         [ #  # ]:          0 :         rChgPos.nContent.Assign( rChgPos.nNode.GetNode().GetCntntNode(), nCntntPos );
     132                 :          0 :     }
     133                 :            : 
     134                 :            :     // TODO: use SaveBookmark (from _DelBookmarks)
     135                 :         18 :     static void lcl_CopyBookmarks(const SwPaM& rPam, SwPaM& rCpyPam)
     136                 :            :     {
     137                 :         18 :         const SwDoc* pSrcDoc = rPam.GetDoc();
     138                 :         18 :         SwDoc* pDestDoc =  rCpyPam.GetDoc();
     139         [ +  - ]:         18 :         const IDocumentMarkAccess* const pSrcMarkAccess = pSrcDoc->getIDocumentMarkAccess();
     140 [ +  - ][ +  - ]:         18 :         ::sw::UndoGuard const undoGuard(pDestDoc->GetIDocumentUndoRedo());
     141                 :            : 
     142 [ +  - ][ +  - ]:         18 :         const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
     143         [ +  - ]:         18 :         SwPosition* pCpyStt = rCpyPam.Start();
     144                 :            : 
     145                 :            :         typedef ::std::vector< const ::sw::mark::IMark* > mark_vector_t;
     146         [ +  - ]:         18 :         mark_vector_t vMarksToCopy;
     147 [ +  - ][ +  - ]:        120 :         for(IDocumentMarkAccess::const_iterator_t ppMark = pSrcMarkAccess->getMarksBegin();
         [ +  - ][ +  + ]
     148         [ +  - ]:         60 :             ppMark != pSrcMarkAccess->getMarksEnd();
     149                 :            :             ppMark++)
     150                 :            :         {
     151                 :         42 :             const ::sw::mark::IMark* const pMark = ppMark->get();
     152         [ +  - ]:         42 :             const SwPosition& rMarkStart = pMark->GetMarkStart();
     153         [ +  - ]:         42 :             const SwPosition& rMarkEnd = pMark->GetMarkEnd();
     154                 :            :             // only include marks that are in the range and not touching
     155                 :            :             // both start and end
     156         [ +  - ]:         42 :             bool bIsNotOnBoundary = pMark->IsExpanded()
     157 [ +  - ][ +  - ]:         30 :                 ? (rMarkStart != rStt || rMarkEnd != rEnd)  // rMarkStart != rMarkEnd
     158 [ +  + ][ +  - ]:         72 :                 : (rMarkStart != rStt && rMarkEnd != rEnd); // rMarkStart == rMarkEnd
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     159 [ +  - ][ +  - ]:         42 :             if(rMarkStart >= rStt && rMarkEnd <= rEnd && bIsNotOnBoundary)
         [ +  - ][ +  + ]
         [ -  + ][ -  + ]
     160                 :            :             {
     161         [ #  # ]:          0 :                 vMarksToCopy.push_back(pMark);
     162                 :            :             }
     163                 :            :         }
     164                 :            :         // We have to count the "non-copied" nodes..
     165         [ +  - ]:         18 :         SwNodeIndex aCorrIdx(rStt.nNode);
     166                 :         18 :         sal_uLong nDelCount = 0;
     167         [ +  - ]:         36 :         for(mark_vector_t::const_iterator ppMark = vMarksToCopy.begin();
           [ #  #  +  - ]
                 [ -  + ]
     168                 :         18 :             ppMark != vMarksToCopy.end();
     169                 :            :             ++ppMark)
     170                 :            :         {
     171         [ #  # ]:          0 :             const ::sw::mark::IMark* const pMark = *ppMark;
     172         [ #  # ]:          0 :             SwPaM aTmpPam(*pCpyStt);
     173 [ #  # ][ #  # ]:          0 :             lcl_NonCopyCount(rPam, aCorrIdx, pMark->GetMarkPos().nNode.GetIndex(), nDelCount);
     174 [ #  # ][ #  # ]:          0 :             lcl_SetCpyPos( pMark->GetMarkPos(), rStt, *pCpyStt, *aTmpPam.GetPoint(), nDelCount);
     175 [ #  # ][ #  # ]:          0 :             if(pMark->IsExpanded())
     176                 :            :             {
     177         [ #  # ]:          0 :                 aTmpPam.SetMark();
     178 [ #  # ][ #  # ]:          0 :                 lcl_NonCopyCount(rPam, aCorrIdx, pMark->GetOtherMarkPos().nNode.GetIndex(), nDelCount);
     179 [ #  # ][ #  # ]:          0 :                 lcl_SetCpyPos(pMark->GetOtherMarkPos(), rStt, *pCpyStt, *aTmpPam.GetMark(), nDelCount);
     180                 :            :             }
     181                 :            : 
     182         [ #  # ]:          0 :             ::sw::mark::IMark* const pNewMark = pDestDoc->getIDocumentMarkAccess()->makeMark(
     183                 :            :                 aTmpPam,
     184         [ #  # ]:          0 :                 pMark->GetName(),
     185 [ #  # ][ #  # ]:          0 :                 IDocumentMarkAccess::GetType(*pMark));
     186                 :            :             // Explicitly try to get exactly the same name as in the source
     187                 :            :             // because NavigatorReminders, DdeBookmarks etc. ignore the proposed name
     188 [ #  # ][ #  # ]:          0 :             pDestDoc->getIDocumentMarkAccess()->renameMark(pNewMark, pMark->GetName());
                 [ #  # ]
     189                 :            : 
     190                 :            :             // copying additional attributes for bookmarks or fieldmarks
     191                 :            :             ::sw::mark::IBookmark* const pNewBookmark =
     192         [ #  # ]:          0 :                 dynamic_cast< ::sw::mark::IBookmark* const >(pNewMark);
     193         [ #  # ]:          0 :             if(pNewBookmark)
     194                 :            :             {
     195         [ #  # ]:          0 :                 const ::sw::mark::IBookmark* const pOldBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(pMark);
     196 [ #  # ][ #  # ]:          0 :                 pNewBookmark->SetKeyCode(pOldBookmark->GetKeyCode());
     197 [ #  # ][ #  # ]:          0 :                 pNewBookmark->SetShortName(pOldBookmark->GetShortName());
     198                 :            :             }
     199                 :            :             ::sw::mark::IFieldmark* const pNewFieldmark =
     200         [ #  # ]:          0 :                 dynamic_cast< ::sw::mark::IFieldmark* const >(pNewMark);
     201         [ #  # ]:          0 :             if(pNewFieldmark)
     202                 :            :             {
     203         [ #  # ]:          0 :                 const ::sw::mark::IFieldmark* const pOldFieldmark = dynamic_cast< const ::sw::mark::IFieldmark* >(pMark);
     204 [ #  # ][ #  # ]:          0 :                 pNewFieldmark->SetFieldname(pOldFieldmark->GetFieldname());
     205 [ #  # ][ #  # ]:          0 :                 pNewFieldmark->SetFieldHelptext(pOldFieldmark->GetFieldHelptext());
     206         [ #  # ]:          0 :                 ::sw::mark::IFieldmark::parameter_map_t* pNewParams = pNewFieldmark->GetParameters();
     207         [ #  # ]:          0 :                 const ::sw::mark::IFieldmark::parameter_map_t* pOldParams = pOldFieldmark->GetParameters();
     208                 :          0 :                 ::sw::mark::IFieldmark::parameter_map_t::const_iterator pIt = pOldParams->begin();
     209         [ #  # ]:          0 :                 for (; pIt != pOldParams->end(); ++pIt )
     210                 :            :                 {
     211         [ #  # ]:          0 :                     pNewParams->insert( *pIt );
     212                 :            :                 }
     213                 :            :             }
     214                 :            : 
     215                 :            :             ::sfx2::Metadatable const*const pMetadatable(
     216         [ #  # ]:          0 :                     dynamic_cast< ::sfx2::Metadatable const* >(pMark));
     217                 :            :             ::sfx2::Metadatable      *const pNewMetadatable(
     218         [ #  # ]:          0 :                     dynamic_cast< ::sfx2::Metadatable      * >(pNewMark));
     219 [ #  # ][ #  # ]:          0 :             if (pMetadatable && pNewMetadatable)
     220                 :            :             {
     221         [ #  # ]:          0 :                 pNewMetadatable->RegisterAsCopyOf(*pMetadatable);
     222                 :            :             }
     223 [ #  # ][ +  - ]:         18 :         }
                 [ +  - ]
     224                 :         18 :     }
     225                 :            : }
     226                 :            : 
     227                 :            : // Structure for the mapping from old and new frame formats to the
     228                 :            : // boxes and lines of a table
     229                 :            : struct _MapTblFrmFmt
     230                 :            : {
     231                 :            :     const SwFrmFmt *pOld, *pNew;
     232                 :          9 :     _MapTblFrmFmt( const SwFrmFmt *pOldFmt, const SwFrmFmt*pNewFmt )
     233                 :          9 :         : pOld( pOldFmt ), pNew( pNewFmt )
     234                 :          9 :     {}
     235                 :            : };
     236                 :            : 
     237                 :            : typedef std::vector<_MapTblFrmFmt> _MapTblFrmFmts;
     238                 :            : 
     239                 :        149 : SwCntntNode* SwTxtNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
     240                 :            : {
     241                 :            :     // the Copy-Textnode is the Node with the Text, the Copy-Attrnode is the
     242                 :            :     // node with the collection and hard attributes. Normally ist the same
     243                 :            :     // node, but if insert a glossary without formatting, then the Attrnode
     244                 :            :     // is the prev node of the destionation position in dest. document.
     245                 :        149 :     SwTxtNode* pCpyTxtNd = (SwTxtNode*)this;
     246                 :        149 :     SwTxtNode* pCpyAttrNd = pCpyTxtNd;
     247                 :            : 
     248                 :            :     // Copy the formats to the other document
     249                 :        149 :     SwTxtFmtColl* pColl = 0;
     250         [ +  + ]:        149 :     if( pDoc->IsInsOnlyTextGlossary() )
     251                 :            :     {
     252         [ +  - ]:          4 :         SwNodeIndex aIdx( rIdx, -1 );
     253         [ +  - ]:          4 :         if( aIdx.GetNode().IsTxtNode() )
     254                 :            :         {
     255                 :          4 :             pCpyAttrNd = aIdx.GetNode().GetTxtNode();
     256                 :          4 :             pColl = &pCpyAttrNd->GetTxtColl()->GetNextTxtFmtColl();
     257         [ +  - ]:          4 :         }
     258                 :            :     }
     259         [ +  + ]:        149 :     if( !pColl )
     260                 :        145 :         pColl = pDoc->CopyTxtColl( *GetTxtColl() );
     261                 :            : 
     262                 :        149 :     SwTxtNode* pTxtNd = pDoc->GetNodes().MakeTxtNode( rIdx, pColl );
     263                 :            : 
     264                 :            :     // METADATA: register copy
     265                 :        149 :     pTxtNd->RegisterAsCopyOf(*pCpyTxtNd);
     266                 :            : 
     267                 :            :     // Copy Attribute/Text
     268         [ +  + ]:        149 :     if( !pCpyAttrNd->HasSwAttrSet() )
     269                 :            :         // An AttrSet was added for numbering, so delete it
     270                 :        107 :         pTxtNd->ResetAllAttr();
     271                 :            : 
     272                 :            :     // if Copy-Textnode unequal to Copy-Attrnode, then copy first
     273                 :            :     // the attributes into the new Node.
     274         [ +  + ]:        149 :     if( pCpyAttrNd != pCpyTxtNd )
     275                 :            :     {
     276                 :          4 :         pCpyAttrNd->CopyAttr( pTxtNd, 0, 0 );
     277         [ -  + ]:          4 :         if( pCpyAttrNd->HasSwAttrSet() )
     278                 :            :         {
     279 [ #  # ][ #  # ]:          0 :             SwAttrSet aSet( *pCpyAttrNd->GetpSwAttrSet() );
     280         [ #  # ]:          0 :             aSet.ClearItem( RES_PAGEDESC );
     281         [ #  # ]:          0 :             aSet.ClearItem( RES_BREAK );
     282 [ #  # ][ #  # ]:          0 :             aSet.CopyToModify( *pTxtNd );
     283                 :            :         }
     284                 :            :     }
     285                 :            : 
     286                 :            :     // Is that enough? What about PostIts/Fields/FieldTypes?
     287                 :            :     // #i96213# - force copy of all attributes
     288         [ +  - ]:        149 :     pCpyTxtNd->CopyText( pTxtNd, SwIndex( pCpyTxtNd ),
     289         [ +  - ]:        298 :         pCpyTxtNd->GetTxt().Len(), true );
     290                 :            : 
     291         [ -  + ]:        149 :     if( RES_CONDTXTFMTCOLL == pColl->Which() )
     292                 :          0 :         pTxtNd->ChkCondColl();
     293                 :            : 
     294                 :        149 :     return pTxtNd;
     295                 :            : }
     296                 :            : 
     297                 :          9 : static bool lcl_SrchNew( const _MapTblFrmFmt& rMap, const SwFrmFmt** pPara )
     298                 :            : {
     299         [ +  - ]:          9 :     if( rMap.pOld != *pPara )
     300                 :          9 :         return true;
     301                 :          0 :     *pPara = rMap.pNew;
     302                 :          9 :     return false;
     303                 :            : }
     304                 :            : 
     305                 :            : struct _CopyTable
     306                 :            : {
     307                 :            :     SwDoc* pDoc;
     308                 :            :     sal_uLong nOldTblSttIdx;
     309                 :            :     _MapTblFrmFmts& rMapArr;
     310                 :            :     SwTableLine* pInsLine;
     311                 :            :     SwTableBox* pInsBox;
     312                 :            :     SwTableNode *pTblNd;
     313                 :            :     const SwTable *pOldTable;
     314                 :            : 
     315                 :          3 :     _CopyTable( SwDoc* pDc, _MapTblFrmFmts& rArr, sal_uLong nOldStt,
     316                 :            :                 SwTableNode& rTblNd, const SwTable* pOldTbl )
     317                 :            :         : pDoc(pDc), nOldTblSttIdx(nOldStt), rMapArr(rArr),
     318                 :          3 :         pInsLine(0), pInsBox(0), pTblNd(&rTblNd), pOldTable( pOldTbl )
     319                 :          3 :     {}
     320                 :            : };
     321                 :            : 
     322                 :            : static void lcl_CopyTblLine( const SwTableLine* pLine, _CopyTable* pCT );
     323                 :            : 
     324                 :          6 : static void lcl_CopyTblBox( SwTableBox* pBox, _CopyTable* pCT )
     325                 :            : {
     326                 :          6 :     SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
     327 [ +  - ][ +  + ]:         15 :     for( _MapTblFrmFmts::const_iterator it = pCT->rMapArr.begin(); it != pCT->rMapArr.end(); ++it )
                 [ +  - ]
     328         [ -  + ]:          9 :         if ( !lcl_SrchNew( *it, (const SwFrmFmt**)&pBoxFmt ) )
     329                 :          0 :             break;
     330         [ +  - ]:          6 :     if( pBoxFmt == pBox->GetFrmFmt() ) // Create a new one?
     331                 :            :     {
     332                 :            :         const SfxPoolItem* pItem;
     333   [ -  +  #  # ]:          6 :         if( SFX_ITEM_SET == pBoxFmt->GetItemState( RES_BOXATR_FORMULA, sal_False,
                 [ -  + ]
     334         [ +  - ]:          6 :             &pItem ) && ((SwTblBoxFormula*)pItem)->IsIntrnlName() )
     335                 :            :         {
     336         [ #  # ]:          0 :             ((SwTblBoxFormula*)pItem)->PtrToBoxNm( pCT->pOldTable );
     337                 :            :         }
     338                 :            : 
     339         [ +  - ]:          6 :         pBoxFmt = pCT->pDoc->MakeTableBoxFmt();
     340         [ +  - ]:          6 :         pBoxFmt->CopyAttrs( *pBox->GetFrmFmt() );
     341                 :            : 
     342 [ +  - ][ +  - ]:          6 :         if( pBox->GetSttIdx() )
     343                 :            :         {
     344         [ +  - ]:          6 :             SvNumberFormatter* pN = pCT->pDoc->GetNumberFormatter( sal_False );
     345 [ -  + ][ #  # ]:          6 :             if( pN && pN->HasMergeFmtTbl() && SFX_ITEM_SET == pBoxFmt->
         [ #  # ][ -  + ]
     346         [ #  # ]:          0 :                 GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem ) )
     347                 :            :             {
     348                 :          0 :                 sal_uLong nOldIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
     349         [ #  # ]:          0 :                 sal_uLong nNewIdx = pN->GetMergeFmtIndex( nOldIdx );
     350         [ #  # ]:          0 :                 if( nNewIdx != nOldIdx )
     351 [ #  # ][ #  # ]:          0 :                     pBoxFmt->SetFmtAttr( SwTblBoxNumFormat( nNewIdx ));
                 [ #  # ]
     352                 :            : 
     353                 :            :             }
     354                 :            :         }
     355                 :            : 
     356         [ +  - ]:          6 :         pCT->rMapArr.push_back( _MapTblFrmFmt( pBox->GetFrmFmt(), pBoxFmt ) );
     357                 :            :     }
     358                 :            : 
     359                 :          6 :     sal_uInt16 nLines = pBox->GetTabLines().size();
     360                 :            :     SwTableBox* pNewBox;
     361         [ -  + ]:          6 :     if( nLines )
     362 [ #  # ][ #  # ]:          0 :         pNewBox = new SwTableBox( pBoxFmt, nLines, pCT->pInsLine );
     363                 :            :     else
     364                 :            :     {
     365                 :            :         SwNodeIndex aNewIdx( *pCT->pTblNd,
     366 [ +  - ][ +  - ]:          6 :                             pBox->GetSttIdx() - pCT->nOldTblSttIdx );
     367                 :            :         OSL_ENSURE( aNewIdx.GetNode().IsStartNode(), "Index is not on the start node" );
     368 [ +  - ][ +  - ]:          6 :         pNewBox = new SwTableBox( pBoxFmt, aNewIdx, pCT->pInsLine );
     369 [ +  - ][ +  - ]:          6 :         pNewBox->setRowSpan( pBox->getRowSpan() );
                 [ +  - ]
     370                 :            :     }
     371                 :            : 
     372         [ +  - ]:          6 :     pCT->pInsLine->GetTabBoxes().push_back( pNewBox );
     373                 :            : 
     374         [ -  + ]:          6 :     if( nLines )
     375                 :            :     {
     376                 :          0 :         _CopyTable aPara( *pCT );
     377                 :          0 :         aPara.pInsBox = pNewBox;
     378 [ #  # ][ #  # ]:          0 :         BOOST_FOREACH( const SwTableLine* pLine, pBox->GetTabLines() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     379         [ #  # ]:          0 :             lcl_CopyTblLine( pLine, &aPara );
     380                 :            :     }
     381 [ +  - ][ +  - ]:          6 :     else if( pNewBox->IsInHeadline( &pCT->pTblNd->GetTable() ))
     382                 :            :         // In the headline, the paragraphs must match conditional styles
     383         [ +  - ]:          6 :         pNewBox->GetSttNd()->CheckSectionCondColl();
     384                 :          6 : }
     385                 :            : 
     386                 :          3 : static void lcl_CopyTblLine( const SwTableLine* pLine, _CopyTable* pCT )
     387                 :            : {
     388                 :          3 :     SwTableLineFmt* pLineFmt = (SwTableLineFmt*)pLine->GetFrmFmt();
     389 [ +  - ][ -  + ]:          3 :     for( _MapTblFrmFmts::const_iterator it = pCT->rMapArr.begin(); it != pCT->rMapArr.end(); ++it )
                 [ +  - ]
     390         [ #  # ]:          0 :         if ( !lcl_SrchNew( *it, (const SwFrmFmt**)&pLineFmt ) )
     391                 :          0 :             break;
     392         [ +  - ]:          3 :     if( pLineFmt == pLine->GetFrmFmt() ) // Create a new one?
     393                 :            :     {
     394         [ +  - ]:          3 :         pLineFmt = pCT->pDoc->MakeTableLineFmt();
     395         [ +  - ]:          3 :         pLineFmt->CopyAttrs( *pLine->GetFrmFmt() );
     396         [ +  - ]:          3 :         pCT->rMapArr.push_back( _MapTblFrmFmt( pLine->GetFrmFmt(), pLineFmt ) );
     397                 :            :     }
     398                 :            :     SwTableLine* pNewLine = new SwTableLine( pLineFmt,
     399 [ +  - ][ +  - ]:          3 :                             pLine->GetTabBoxes().size(), pCT->pInsBox );
     400                 :            :     // Insert the new row into the table
     401         [ -  + ]:          3 :     if( pCT->pInsBox )
     402                 :            :     {
     403         [ #  # ]:          0 :         pCT->pInsBox->GetTabLines().push_back( pNewLine );
     404                 :            :     }
     405                 :            :     else
     406                 :            :     {
     407         [ +  - ]:          3 :         pCT->pTblNd->GetTable().GetTabLines().push_back( pNewLine );
     408                 :            :     }
     409                 :          3 :     pCT->pInsLine = pNewLine;
     410 [ +  - ][ +  + ]:         18 :     for( SwTableBoxes::iterator it = ((SwTableLine*)pLine)->GetTabBoxes().begin();
     411                 :          9 :              it != ((SwTableLine*)pLine)->GetTabBoxes().end(); ++it)
     412         [ +  - ]:          6 :         lcl_CopyTblBox(*it, pCT );
     413                 :          3 : }
     414                 :            : 
     415                 :          3 : SwTableNode* SwTableNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
     416                 :            : {
     417                 :            :     // In which array are we? Nodes? UndoNodes?
     418                 :          3 :     SwNodes& rNds = (SwNodes&)GetNodes();
     419                 :            : 
     420                 :            :     {
     421   [ -  +  #  # ]:          3 :         if( rIdx < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
         [ -  + ][ +  - ]
     422         [ #  # ]:          0 :             rIdx >= pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() )
     423                 :          0 :             return 0;
     424                 :            :     }
     425                 :            : 
     426                 :            :     // Copy the TableFrmFmt
     427         [ +  - ]:          3 :     String sTblName( GetTable().GetFrmFmt()->GetName() );
     428         [ +  - ]:          3 :     if( !pDoc->IsCopyIsMove() )
     429                 :            :     {
     430                 :          3 :         const SwFrmFmts& rTblFmts = *pDoc->GetTblFrmFmts();
     431         [ +  - ]:          9 :         for( sal_uInt16 n = rTblFmts.size(); n; )
     432 [ +  - ][ +  - ]:          6 :             if( rTblFmts[ --n ]->GetName() == sTblName )
                 [ +  + ]
     433                 :            :             {
     434 [ +  - ][ +  - ]:          3 :                 sTblName = pDoc->GetUniqueTblName();
                 [ +  - ]
     435                 :          3 :                 break;
     436                 :            :             }
     437                 :            :     }
     438                 :            : 
     439         [ +  - ]:          3 :     SwFrmFmt* pTblFmt = pDoc->MakeTblFrmFmt( sTblName, pDoc->GetDfltFrmFmt() );
     440         [ +  - ]:          3 :     pTblFmt->CopyAttrs( *GetTable().GetFrmFmt() );
     441 [ +  - ][ +  - ]:          3 :     SwTableNode* pTblNd = new SwTableNode( rIdx );
     442 [ +  - ][ +  - ]:          3 :     SwEndNode* pEndNd = new SwEndNode( rIdx, *pTblNd );
     443         [ +  - ]:          3 :     SwNodeIndex aInsPos( *pEndNd );
     444                 :            : 
     445                 :          3 :     SwTable& rTbl = (SwTable&)pTblNd->GetTable();
     446         [ +  - ]:          3 :     rTbl.RegisterToFormat( *pTblFmt );
     447                 :            : 
     448         [ +  - ]:          3 :     rTbl.SetRowsToRepeat( GetTable().GetRowsToRepeat() );
     449                 :          3 :     rTbl.SetTblChgMode( GetTable().GetTblChgMode() );
     450                 :          3 :     rTbl.SetTableModel( GetTable().IsNewModel() );
     451                 :            : 
     452                 :          3 :     SwDDEFieldType* pDDEType = 0;
     453 [ +  - ][ +  - ]:          3 :     if( IS_TYPE( SwDDETable, &GetTable() ))
         [ -  + ][ -  + ]
                 [ +  - ]
     454                 :            :     {
     455                 :            :         // We're copying a DDE table
     456                 :            :         // Is the field type available in the new document?
     457         [ #  # ]:          0 :         pDDEType = ((SwDDETable&)GetTable()).GetDDEFldType();
     458         [ #  # ]:          0 :         if( pDDEType->IsDeleted() )
     459         [ #  # ]:          0 :             pDoc->InsDeletedFldType( *pDDEType );
     460                 :            :         else
     461         [ #  # ]:          0 :             pDDEType = (SwDDEFieldType*)pDoc->InsertFldType( *pDDEType );
     462                 :            :         OSL_ENSURE( pDDEType, "unknown FieldType" );
     463                 :            : 
     464                 :            :         // Swap the table pointers in the node
     465 [ #  # ][ #  # ]:          0 :         SwDDETable* pNewTable = new SwDDETable( pTblNd->GetTable(), pDDEType );
     466         [ #  # ]:          0 :         pTblNd->SetNewTable( pNewTable, sal_False );
     467                 :            :     }
     468                 :            :     // First copy the content of the tables, we will later assign the
     469                 :            :     // boxes/lines and create the frames
     470         [ +  - ]:          3 :     SwNodeRange aRg( *this, +1, *EndOfSectionNode() );
     471                 :            : 
     472                 :            :     // If there is a table in this table, the table format for the outer table
     473                 :            :     // does not seem to be used, because the table does not have any contents yet
     474                 :            :     // (see IsUsed). Therefore the inner table gets the same name as the outer table.
     475                 :            :     // We have to make sure that the table node of the SwTable is accessible, even
     476                 :            :     // without any content in aSortCntBoxes. #i26629#
     477                 :          3 :     pTblNd->GetTable().SetTableNode( pTblNd );
     478         [ +  - ]:          3 :     rNds._Copy( aRg, aInsPos, sal_False );
     479                 :          3 :     pTblNd->GetTable().SetTableNode( 0 );
     480                 :            : 
     481                 :            :     // Special case for a single box
     482         [ -  + ]:          3 :     if( 1 == GetTable().GetTabSortBoxes().size() )
     483                 :            :     {
     484         [ #  # ]:          0 :         aRg.aStart.Assign( *pTblNd, 1 );
     485         [ #  # ]:          0 :         aRg.aEnd.Assign( *pTblNd->EndOfSectionNode() );
     486 [ #  # ][ #  # ]:          0 :         pDoc->GetNodes().SectionDown( &aRg, SwTableBoxStartNode );
     487                 :            :     }
     488                 :            : 
     489                 :            :     // Delete all frames from the copied area, they will be created
     490                 :            :     // during the generation of the table frame
     491         [ +  - ]:          3 :     pTblNd->DelFrms();
     492                 :            : 
     493         [ +  - ]:          3 :     _MapTblFrmFmts aMapArr;
     494                 :          3 :     _CopyTable aPara( pDoc, aMapArr, GetIndex(), *pTblNd, &GetTable() );
     495                 :            : 
     496 [ +  - ][ +  - ]:          9 :     BOOST_FOREACH(const SwTableLine* pLine, GetTable().GetTabLines() )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
                 [ +  - ]
     497         [ +  - ]:          3 :         lcl_CopyTblLine( pLine, &aPara );
     498                 :            : 
     499         [ -  + ]:          3 :     if( pDDEType )
     500         [ #  # ]:          0 :         pDDEType->IncRefCnt();
     501                 :            : 
     502                 :            :     CHECK_TABLE( GetTable() );
     503 [ +  - ][ +  - ]:          3 :     return pTblNd;
                 [ +  - ]
     504                 :            : }
     505                 :            : 
     506                 :         20 : void SwTxtNode::CopyCollFmt( SwTxtNode& rDestNd )
     507                 :            : {
     508                 :            :     // Copy the formats into the other document:
     509                 :            :     // Special case for PageBreak/PageDesc/ColBrk
     510                 :         20 :     SwDoc* pDestDoc = rDestNd.GetDoc();
     511         [ +  - ]:         20 :     SwAttrSet aPgBrkSet( pDestDoc->GetAttrPool(), aBreakSetRange );
     512                 :            :     const SwAttrSet* pSet;
     513                 :            : 
     514 [ +  - ][ +  + ]:         20 :     if( 0 != ( pSet = rDestNd.GetpSwAttrSet() ) )
     515                 :            :     {
     516                 :            :         // Special cases for Break-Attributes
     517                 :            :         const SfxPoolItem* pAttr;
     518 [ +  - ][ -  + ]:         17 :         if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False, &pAttr ) )
     519         [ #  # ]:          0 :             aPgBrkSet.Put( *pAttr );
     520                 :            : 
     521 [ +  - ][ -  + ]:         17 :         if( SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, sal_False, &pAttr ) )
     522         [ #  # ]:         17 :             aPgBrkSet.Put( *pAttr );
     523                 :            :     }
     524                 :            : 
     525 [ +  - ][ +  - ]:         20 :     rDestNd.ChgFmtColl( pDestDoc->CopyTxtColl( *GetTxtColl() ));
     526 [ +  - ][ +  + ]:         20 :     if( 0 != ( pSet = GetpSwAttrSet() ) )
     527         [ +  - ]:         17 :         pSet->CopyToModify( rDestNd );
     528                 :            : 
     529         [ -  + ]:         20 :     if( aPgBrkSet.Count() )
     530 [ #  # ][ +  - ]:         20 :         rDestNd.SetAttr( aPgBrkSet );
     531                 :         20 : }
     532                 :            : 
     533                 :            : 
     534                 :            : // Copy method from SwDoc
     535                 :            : // Prevent copying in Flys that are anchored in the area
     536                 :         21 : sal_Bool lcl_ChkFlyFly( SwDoc* pDoc, sal_uLong nSttNd, sal_uLong nEndNd,
     537                 :            :                         sal_uLong nInsNd )
     538                 :            : {
     539                 :         21 :     const SwFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
     540                 :            : 
     541         [ +  + ]:         90 :     for( sal_uInt16 n = 0; n < rFrmFmtTbl.size(); ++n )
     542                 :            :     {
     543                 :         69 :         SwFrmFmt const*const  pFmt = rFrmFmtTbl[n];
     544                 :         69 :         SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
     545                 :         69 :         SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
     546 [ +  + ][ +  +  :        279 :         if (pAPos &&
          +  -  +  +  +  
          -  +  -  +  +  
                   +  + ]
     547                 :         39 :             ((FLY_AS_CHAR == pAnchor->GetAnchorId()) ||
     548                 :         39 :              (FLY_AT_CHAR == pAnchor->GetAnchorId()) ||
     549                 :         30 :              (FLY_AT_FLY  == pAnchor->GetAnchorId()) ||
     550                 :         30 :              (FLY_AT_PARA == pAnchor->GetAnchorId())) &&
     551                 :         39 :             nSttNd <= pAPos->nNode.GetIndex() &&
     552                 :         33 :             pAPos->nNode.GetIndex() < nEndNd )
     553                 :            :         {
     554                 :         18 :             const SwFmtCntnt& rCntnt = pFmt->GetCntnt();
     555                 :            :             SwStartNode* pSNd;
     556         [ +  + ]:         24 :             if( !rCntnt.GetCntntIdx() ||
           [ +  +  -  + ]
     557                 :          6 :                 0 == ( pSNd = rCntnt.GetCntntIdx()->GetNode().GetStartNode() ))
     558                 :         12 :                 continue;
     559                 :            : 
     560   [ +  -  -  + ]:         12 :             if( pSNd->GetIndex() < nInsNd &&
                 [ -  + ]
     561                 :          6 :                 nInsNd < pSNd->EndOfSectionIndex() )
     562                 :            :                 // Do not copy !
     563                 :          0 :                 return sal_True;
     564                 :            : 
     565         [ -  + ]:          6 :             if( lcl_ChkFlyFly( pDoc, pSNd->GetIndex(),
     566                 :          6 :                         pSNd->EndOfSectionIndex(), nInsNd ) )
     567                 :            :                 // Do not copy !
     568                 :          0 :                 return sal_True;
     569                 :            :         }
     570                 :            :     }
     571                 :            : 
     572                 :         21 :     return sal_False;
     573                 :            : }
     574                 :            : 
     575                 :          0 : void lcl_DeleteRedlines( const SwPaM& rPam, SwPaM& rCpyPam )
     576                 :            : {
     577                 :          0 :     const SwDoc* pSrcDoc = rPam.GetDoc();
     578                 :          0 :     const SwRedlineTbl& rTbl = pSrcDoc->GetRedlineTbl();
     579         [ #  # ]:          0 :     if( !rTbl.empty() )
     580                 :            :     {
     581                 :          0 :         SwDoc* pDestDoc = rCpyPam.GetDoc();
     582 [ #  # ][ #  # ]:          0 :         SwPosition* pCpyStt = rCpyPam.Start(), *pCpyEnd = rCpyPam.End();
     583                 :          0 :         SwPaM* pDelPam = 0;
     584 [ #  # ][ #  # ]:          0 :         const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
     585                 :            :         // We have to count the "non-copied" nodes
     586                 :          0 :         sal_uLong nDelCount = 0;
     587         [ #  # ]:          0 :         SwNodeIndex aCorrIdx( pStt->nNode );
     588                 :            : 
     589                 :          0 :         sal_uInt16 n = 0;
     590         [ #  # ]:          0 :         pSrcDoc->GetRedline( *pStt, &n );
     591         [ #  # ]:          0 :         for( ; n < rTbl.size(); ++n )
     592                 :            :         {
     593         [ #  # ]:          0 :             const SwRedline* pRedl = rTbl[ n ];
     594 [ #  # ][ #  # ]:          0 :             if( nsRedlineType_t::REDLINE_DELETE == pRedl->GetType() && pRedl->IsVisible() )
         [ #  # ][ #  # ]
     595                 :            :             {
     596 [ #  # ][ #  # ]:          0 :                 const SwPosition *pRStt = pRedl->Start(), *pREnd = pRedl->End();
     597                 :            : 
     598         [ #  # ]:          0 :                 SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
     599      [ #  #  # ]:          0 :                 switch( eCmpPos )
     600                 :            :                 {
     601                 :            :                 case POS_COLLIDE_END:
     602                 :            :                 case POS_BEFORE:
     603                 :            :                     // Pos1 is before Pos2
     604                 :          0 :                     break;
     605                 :            : 
     606                 :            :                 case POS_COLLIDE_START:
     607                 :            :                 case POS_BEHIND:
     608                 :            :                     // Pos1 is after Pos2
     609                 :          0 :                     n = rTbl.size();
     610                 :          0 :                     break;
     611                 :            : 
     612                 :            :                 default:
     613                 :            :                     {
     614 [ #  # ][ #  # ]:          0 :                         pDelPam = new SwPaM( *pCpyStt, pDelPam );
     615 [ #  # ][ #  # ]:          0 :                         if( *pStt < *pRStt )
     616                 :            :                         {
     617         [ #  # ]:          0 :                             lcl_NonCopyCount( rPam, aCorrIdx, pRStt->nNode.GetIndex(), nDelCount );
     618                 :            :                             lcl_SetCpyPos( *pRStt, *pStt, *pCpyStt,
     619         [ #  # ]:          0 :                                             *pDelPam->GetPoint(), nDelCount );
     620                 :            :                         }
     621         [ #  # ]:          0 :                         pDelPam->SetMark();
     622                 :            : 
     623 [ #  # ][ #  # ]:          0 :                         if( *pEnd < *pREnd )
     624         [ #  # ]:          0 :                             *pDelPam->GetPoint() = *pCpyEnd;
     625                 :            :                         else
     626                 :            :                         {
     627         [ #  # ]:          0 :                             lcl_NonCopyCount( rPam, aCorrIdx, pREnd->nNode.GetIndex(), nDelCount );
     628                 :            :                             lcl_SetCpyPos( *pREnd, *pStt, *pCpyStt,
     629         [ #  # ]:          0 :                                             *pDelPam->GetPoint(), nDelCount );
     630                 :            :                         }
     631                 :            :                     }
     632                 :            :                 }
     633                 :            :             }
     634                 :            :         }
     635                 :            : 
     636         [ #  # ]:          0 :         if( pDelPam )
     637                 :            :         {
     638         [ #  # ]:          0 :             RedlineMode_t eOld = pDestDoc->GetRedlineMode();
     639         [ #  # ]:          0 :             pDestDoc->SetRedlineMode_intern( (RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
     640                 :            : 
     641 [ #  # ][ #  # ]:          0 :             ::sw::UndoGuard const undoGuard(pDestDoc->GetIDocumentUndoRedo());
     642                 :            : 
     643                 :          0 :             do {
     644         [ #  # ]:          0 :                 pDestDoc->DeleteAndJoin( *(SwPaM*)pDelPam->GetNext() );
     645         [ #  # ]:          0 :                 if( pDelPam->GetNext() == pDelPam )
     646                 :          0 :                     break;
     647 [ #  # ][ #  # ]:          0 :                 delete pDelPam->GetNext();
     648                 :            :             } while( sal_True );
     649 [ #  # ][ #  # ]:          0 :             delete pDelPam;
     650                 :            : 
     651 [ #  # ][ #  # ]:          0 :             pDestDoc->SetRedlineMode_intern( eOld );
     652         [ #  # ]:          0 :         }
     653                 :            :     }
     654                 :          0 : }
     655                 :            : 
     656                 :          0 : void lcl_DeleteRedlines( const SwNodeRange& rRg, SwNodeRange& rCpyRg )
     657                 :            : {
     658                 :          0 :     SwDoc* pSrcDoc = rRg.aStart.GetNode().GetDoc();
     659         [ #  # ]:          0 :     if( !pSrcDoc->GetRedlineTbl().empty() )
     660                 :            :     {
     661         [ #  # ]:          0 :         SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
     662         [ #  # ]:          0 :         SwPaM aCpyTmp( rCpyRg.aStart, rCpyRg.aEnd );
     663 [ #  # ][ #  # ]:          0 :         lcl_DeleteRedlines( aRgTmp, aCpyTmp );
                 [ #  # ]
     664                 :            :     }
     665                 :          0 : }
     666                 :            : 
     667                 :            : // Copy an area into this document or into another document
     668                 :            : bool
     669                 :         37 : SwDoc::CopyRange( SwPaM& rPam, SwPosition& rPos, const bool bCopyAll ) const
     670                 :            : {
     671                 :         37 :     const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
     672                 :            : 
     673                 :         37 :     SwDoc* pDoc = rPos.nNode.GetNode().GetDoc();
     674 [ #  # ][ -  + ]:         37 :     bool bColumnSel = pDoc->IsClipBoard() && pDoc->IsColumnSelection();
     675                 :            : 
     676                 :            :     // Catch if there's no copy to do
     677 [ +  - ][ +  + ]:         37 :     if( !rPam.HasMark() || ( *pStt >= *pEnd && !bColumnSel ) )
         [ +  - ][ +  + ]
     678                 :          9 :         return false;
     679                 :            : 
     680                 :            :     // Prevent copying in Flys that are anchored in the area
     681         [ +  + ]:         28 :     if( pDoc == this )
     682                 :            :     {
     683                 :            :         // Correct the Start-/EndNode
     684                 :         18 :         sal_uLong nStt = pStt->nNode.GetIndex(),
     685                 :         18 :                 nEnd = pEnd->nNode.GetIndex(),
     686                 :         18 :                 nDiff = nEnd - nStt +1;
     687                 :         18 :         SwNode* pNd = GetNodes()[ nStt ];
     688 [ +  + ][ +  + ]:         18 :         if( pNd->IsCntntNode() && pStt->nContent.GetIndex() )
                 [ +  - ]
     689                 :          3 :             ++nStt, --nDiff;
     690   [ +  -  -  + ]:         36 :         if( (pNd = GetNodes()[ nEnd ])->IsCntntNode() &&
                 [ -  + ]
     691 [ +  - ][ +  - ]:         18 :             ((SwCntntNode*)pNd)->Len() != pEnd->nContent.GetIndex() )
                 [ +  - ]
     692                 :          0 :             --nEnd, --nDiff;
     693   [ +  +  -  + ]:         33 :         if( nDiff &&
                 [ -  + ]
     694                 :         15 :             lcl_ChkFlyFly( pDoc, nStt, nEnd, rPos.nNode.GetIndex() ) )
     695                 :            :         {
     696                 :          0 :             return false;
     697                 :            :         }
     698                 :            :     }
     699                 :            : 
     700                 :         28 :     SwPaM* pRedlineRange = 0;
     701   [ +  -  +  +  :         81 :     if( pDoc->IsRedlineOn() ||
           -  + ][ -  + ]
     702                 :         53 :         (!pDoc->IsIgnoreRedline() && !pDoc->GetRedlineTbl().empty() ) )
     703         [ #  # ]:          0 :         pRedlineRange = new SwPaM( rPos );
     704                 :            : 
     705                 :         28 :     RedlineMode_t eOld = pDoc->GetRedlineMode();
     706                 :            : 
     707                 :         28 :     bool bRet = false;
     708                 :            : 
     709         [ +  + ]:         28 :     if( pDoc != this )
     710                 :            :     {   // ordinary copy
     711                 :         10 :         bRet = CopyImpl( rPam, rPos, true, bCopyAll, pRedlineRange );
     712                 :            :     }
     713         [ +  - ]:         36 :     else if( ! ( *pStt <= rPos && rPos < *pEnd &&
     714                 :          0 :             ( pStt->nNode != pEnd->nNode ||
     715 [ #  # ][ -  +  :         18 :               !pStt->nNode.GetNode().IsTxtNode() )) )
             #  #  #  # ]
     716                 :            :     {
     717                 :            :         // Copy to a position outside of the area, or copy a single TextNode
     718                 :            :         // Do an ordinary copy
     719                 :         18 :         bRet = CopyImpl( rPam, rPos, true, bCopyAll, pRedlineRange );
     720                 :            :     }
     721                 :            :     else
     722                 :            :     {
     723                 :            :         // Copy the area in itself
     724                 :            :         // Special case for handling an area with several nodes,
     725                 :            :         // or a single node that is not a TextNode
     726                 :            :         OSL_ENSURE( this == pDoc, " invalid copy branch!" );
     727                 :            :         OSL_FAIL("mst: i thought this could be dead code;"
     728                 :            :                 "please tell me what you did to get here!");
     729         [ #  # ]:          0 :         pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
     730                 :            : 
     731                 :            :         // Then copy the area to the underlying document area
     732                 :            :         // (with start/end nodes clamped) and move them to
     733                 :            :         // the desired position.
     734                 :            : 
     735                 :          0 :         SwUndoCpyDoc* pUndo = 0;
     736                 :            :         // Save the Undo area
     737         [ #  # ]:          0 :         SwPaM aPam( rPos );
     738 [ #  # ][ #  # ]:          0 :         if (pDoc->GetIDocumentUndoRedo().DoesUndo())
                 [ #  # ]
     739                 :            :         {
     740 [ #  # ][ #  # ]:          0 :             pDoc->GetIDocumentUndoRedo().ClearRedo();
     741 [ #  # ][ #  # ]:          0 :             pUndo = new SwUndoCpyDoc( aPam );
     742                 :            :         }
     743                 :            : 
     744                 :            :         {
     745 [ #  # ][ #  # ]:          0 :             ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
     746         [ #  # ]:          0 :             SwStartNode* pSttNd = pDoc->GetNodes().MakeEmptySection(
     747 [ #  # ][ #  # ]:          0 :                                 SwNodeIndex( GetNodes().GetEndOfAutotext() ));
         [ #  # ][ #  # ]
     748         [ #  # ]:          0 :             aPam.GetPoint()->nNode = *pSttNd->EndOfSectionNode();
     749                 :            :             // copy without Frames
     750         [ #  # ]:          0 :             pDoc->CopyImpl( rPam, *aPam.GetPoint(), false, bCopyAll, 0 );
     751                 :            : 
     752 [ #  # ][ #  # ]:          0 :             aPam.GetPoint()->nNode = pDoc->GetNodes().GetEndOfAutotext();
     753         [ #  # ]:          0 :             aPam.SetMark();
     754                 :            :             SwCntntNode* pNode =
     755 [ #  # ][ #  # ]:          0 :                 pDoc->GetNodes().GoPrevious( &aPam.GetMark()->nNode );
     756         [ #  # ]:          0 :             pNode->MakeEndIndex( &aPam.GetMark()->nContent );
     757                 :            : 
     758         [ #  # ]:          0 :             aPam.GetPoint()->nNode = *aPam.GetNode()->StartOfSectionNode();
     759 [ #  # ][ #  # ]:          0 :             pNode = pDoc->GetNodes().GoNext( &aPam.GetPoint()->nNode );
     760         [ #  # ]:          0 :             pNode->MakeStartIndex( &aPam.GetPoint()->nContent );
     761                 :            :             // move to desired position
     762         [ #  # ]:          0 :             pDoc->MoveRange( aPam, rPos, DOC_MOVEDEFAULT );
     763                 :            : 
     764                 :          0 :             pNode = aPam.GetCntntNode();
     765         [ #  # ]:          0 :             *aPam.GetPoint() = rPos;      // Move the cursor for Undo
     766         [ #  # ]:          0 :             aPam.SetMark();               // also move the Mark
     767         [ #  # ]:          0 :             aPam.DeleteMark();            // But don't mark any area
     768 [ #  # ][ #  # ]:          0 :             pDoc->DeleteSection( pNode ); // Delete the area again
                 [ #  # ]
     769                 :            :         }
     770                 :            : 
     771                 :            :         // if Undo is enabled, store the insertion range
     772 [ #  # ][ #  # ]:          0 :         if (pDoc->GetIDocumentUndoRedo().DoesUndo())
                 [ #  # ]
     773                 :            :         {
     774         [ #  # ]:          0 :             pUndo->SetInsertRange( aPam );
     775 [ #  # ][ #  # ]:          0 :             pDoc->GetIDocumentUndoRedo().AppendUndo(pUndo);
     776                 :            :         }
     777                 :            : 
     778         [ #  # ]:          0 :         if( pRedlineRange )
     779                 :            :         {
     780         [ #  # ]:          0 :             pRedlineRange->SetMark();
     781         [ #  # ]:          0 :             *pRedlineRange->GetPoint() = *aPam.GetPoint();
     782         [ #  # ]:          0 :             *pRedlineRange->GetMark() = *aPam.GetMark();
     783                 :            :         }
     784                 :            : 
     785         [ #  # ]:          0 :         pDoc->SetModified();
     786         [ #  # ]:          0 :         bRet = true;
     787                 :            :     }
     788                 :            : 
     789                 :         28 :     pDoc->SetRedlineMode_intern( eOld );
     790         [ -  + ]:         28 :     if( pRedlineRange )
     791                 :            :     {
     792         [ #  # ]:          0 :         if( pDoc->IsRedlineOn() )
     793         [ #  # ]:          0 :             pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, *pRedlineRange ), true);
     794                 :            :         else
     795                 :          0 :             pDoc->SplitRedline( *pRedlineRange );
     796         [ #  # ]:          0 :         delete pRedlineRange;
     797                 :            :     }
     798                 :            : 
     799                 :         37 :     return bRet;
     800                 :            : }
     801                 :            : 
     802                 :          5 : bool lcl_MarksWholeNode(const SwPaM & rPam)
     803                 :            : {
     804                 :          5 :     bool bResult = false;
     805                 :          5 :     const SwPosition* pStt = rPam.Start();
     806                 :          5 :     const SwPosition* pEnd = rPam.End();
     807                 :            : 
     808 [ +  - ][ +  - ]:          5 :     if (NULL != pStt && NULL != pEnd)
     809                 :            :     {
     810                 :          5 :         const SwTxtNode* pSttNd = pStt->nNode.GetNode().GetTxtNode();
     811                 :          5 :         const SwTxtNode* pEndNd = pEnd->nNode.GetNode().GetTxtNode();
     812                 :            : 
     813   [ +  -  +  +  :         12 :         if (NULL != pSttNd && NULL != pEndNd &&
           +  - ][ +  + ]
                 [ +  - ]
     814                 :          5 :             pStt->nContent.GetIndex() == 0 &&
     815                 :          2 :             pEnd->nContent.GetIndex() == pEndNd->Len())
     816                 :            :         {
     817                 :          2 :             bResult = true;
     818                 :            :         }
     819                 :            :     }
     820                 :            : 
     821                 :          5 :     return bResult;
     822                 :            : }
     823                 :            : 
     824                 :            : // #i86492#
     825                 :          0 : bool lcl_ContainsOnlyParagraphsInList( const SwPaM& rPam )
     826                 :            : {
     827                 :          0 :     bool bRet = false;
     828                 :            : 
     829                 :          0 :     const SwTxtNode* pTxtNd = rPam.Start()->nNode.GetNode().GetTxtNode();
     830                 :          0 :     const SwTxtNode* pEndTxtNd = rPam.End()->nNode.GetNode().GetTxtNode();
     831         [ #  # ]:          0 :     if ( pTxtNd && pTxtNd->IsInList() &&
           [ #  #  #  # ]
         [ #  # ][ #  # ]
     832                 :          0 :          pEndTxtNd && pEndTxtNd->IsInList() )
     833                 :            :     {
     834                 :          0 :         bRet = true;
     835 [ #  # ][ #  # ]:          0 :         SwNodeIndex aIdx(rPam.Start()->nNode);
     836                 :            : 
     837 [ #  # ][ #  # ]:          0 :         do
                 [ #  # ]
     838                 :            :         {
     839         [ #  # ]:          0 :             aIdx++;
     840                 :          0 :             pTxtNd = aIdx.GetNode().GetTxtNode();
     841                 :            : 
     842 [ #  # ][ #  # ]:          0 :             if ( !pTxtNd || !pTxtNd->IsInList() )
         [ #  # ][ #  # ]
     843                 :            :             {
     844                 :          0 :                 bRet = false;
     845                 :          0 :                 break;
     846                 :            :             }
     847         [ #  # ]:          0 :         } while ( pTxtNd && pTxtNd != pEndTxtNd );
     848                 :            :     }
     849                 :            : 
     850                 :            : 
     851                 :          0 :     return bRet;
     852                 :            : }
     853                 :            : 
     854                 :         28 : bool SwDoc::CopyImpl( SwPaM& rPam, SwPosition& rPos,
     855                 :            :         const bool bMakeNewFrms, const bool bCopyAll,
     856                 :            :         SwPaM *const pCpyRange ) const
     857                 :            : {
     858                 :         28 :     SwDoc* pDoc = rPos.nNode.GetNode().GetDoc();
     859 [ #  # ][ -  + ]:         28 :     const bool bColumnSel = pDoc->IsClipBoard() && pDoc->IsColumnSelection();
     860                 :            : 
     861         [ +  - ]:         28 :     SwPosition* pStt = rPam.Start();
     862         [ +  - ]:         28 :     SwPosition* pEnd = rPam.End();
     863                 :            : 
     864                 :            :     // Catch when there's no copy to do.
     865 [ +  - ][ +  - ]:         46 :     if( !rPam.HasMark() || ( *pStt >= *pEnd && !bColumnSel ) ||
         [ -  + ][ #  # ]
         [ +  + ][ -  + ]
         [ #  # ][ -  + ]
     866                 :            :         //JP 29.6.2001: 88963 - dont copy if inspos is in region of start to end
     867                 :            :         //JP 15.11.2001: don't test inclusive the end, ever exclusive
     868 [ +  - ][ #  # ]:         18 :         ( pDoc == this && *pStt <= rPos && rPos < *pEnd ))
     869                 :            :     {
     870                 :          0 :         return false;
     871                 :            :     }
     872                 :            : 
     873 [ +  + ][ +  - ]:         28 :     const bool bEndEqualIns = pDoc == this && rPos == *pEnd;
                 [ -  + ]
     874                 :            : 
     875                 :            :     // If Undo is enabled, create the UndoCopy object
     876                 :         28 :     SwUndoCpyDoc* pUndo = 0;
     877         [ +  - ]:         28 :     SwPaM aCpyPam( rPos );
     878                 :            : 
     879         [ +  - ]:         28 :     SwTblNumFmtMerge aTNFM( *this, *pDoc );
     880                 :            : 
     881 [ +  - ][ +  - ]:         28 :     if (pDoc->GetIDocumentUndoRedo().DoesUndo())
                 [ +  + ]
     882                 :            :     {
     883 [ +  - ][ +  - ]:          6 :         pUndo = new SwUndoCpyDoc( aCpyPam );
     884 [ +  - ][ +  - ]:          6 :         pDoc->GetIDocumentUndoRedo().AppendUndo( pUndo );
     885                 :            :     }
     886                 :            : 
     887         [ +  - ]:         28 :     RedlineMode_t eOld = pDoc->GetRedlineMode();
     888         [ +  - ]:         28 :     pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
     889                 :            : 
     890                 :            :     // Move the PaM one node back from the insert position, so that
     891                 :            :     // the position doesn't get moved
     892         [ +  - ]:         28 :     aCpyPam.SetMark();
     893         [ +  - ]:         28 :     sal_Bool bCanMoveBack = aCpyPam.Move( fnMoveBackward, fnGoCntnt );
     894                 :            :     // If the position was shifted from more than one node, an end node has been skipped
     895                 :         28 :     bool bAfterTable = false;
     896         [ -  + ]:         28 :     if ( ( rPos.nNode.GetIndex() - aCpyPam.GetPoint()->nNode.GetIndex() ) > 1 )
     897                 :            :     {
     898                 :            :         // First go back to the original place
     899         [ #  # ]:          0 :         aCpyPam.GetPoint()->nNode = rPos.nNode;
     900         [ #  # ]:          0 :         aCpyPam.GetPoint()->nContent = rPos.nContent;
     901                 :            : 
     902                 :          0 :         bCanMoveBack = false;
     903                 :          0 :         bAfterTable = true;
     904                 :            :     }
     905         [ +  - ]:         28 :     if( !bCanMoveBack )
     906         [ +  - ]:         28 :         aCpyPam.GetPoint()->nNode--;
     907                 :            : 
     908         [ +  - ]:         28 :     SwNodeRange aRg( pStt->nNode, pEnd->nNode );
     909         [ +  - ]:         28 :     SwNodeIndex aInsPos( rPos.nNode );
     910                 :         28 :     const bool bOneNode = pStt->nNode == pEnd->nNode;
     911                 :         28 :     SwTxtNode* pSttTxtNd = pStt->nNode.GetNode().GetTxtNode();
     912                 :         28 :     SwTxtNode* pEndTxtNd = pEnd->nNode.GetNode().GetTxtNode();
     913                 :         28 :     SwTxtNode* pDestTxtNd = aInsPos.GetNode().GetTxtNode();
     914                 :         28 :     bool bCopyCollFmt = !pDoc->IsInsOnlyTextGlossary() &&
     915                 :         20 :                         ( ( pDestTxtNd && !pDestTxtNd->GetTxt().Len() ) ||
     916   [ +  -  -  + ]:         48 :                           ( !bOneNode && !rPos.nContent.GetIndex() ) );
         [ #  # ][ #  # ]
                 [ +  + ]
     917                 :         28 :     bool bCopyBookmarks = true;
     918                 :         28 :     sal_Bool bStartIsTxtNode = 0 != pSttTxtNd;
     919                 :            : 
     920                 :            :     // #i104585# copy outline num rule to clipboard (for ASCII filter)
     921 [ -  + ][ #  # ]:         28 :     if (pDoc->IsClipBoard() && GetOutlineNumRule())
                 [ -  + ]
     922                 :            :     {
     923         [ #  # ]:          0 :         pDoc->SetOutlineNumRule(*GetOutlineNumRule());
     924                 :            :     }
     925                 :            : 
     926                 :            :     // #i86492#
     927                 :            :     // Correct the search for a previous list:
     928                 :            :     // First search for non-outline numbering list. Then search for non-outline
     929                 :            :     // bullet list.
     930                 :            :     // Keep also the <ListId> value for possible propagation.
     931         [ +  - ]:         28 :     String aListIdToPropagate;
     932                 :            :     const SwNumRule* pNumRuleToPropagate =
     933         [ +  - ]:         28 :         pDoc->SearchNumRule( rPos, false, true, false, 0, aListIdToPropagate, true );
     934         [ +  - ]:         28 :     if ( !pNumRuleToPropagate )
     935                 :            :     {
     936                 :            :         pNumRuleToPropagate =
     937         [ +  - ]:         28 :             pDoc->SearchNumRule( rPos, false, false, false, 0, aListIdToPropagate, true );
     938                 :            :     }
     939                 :            :     // #i86492#
     940                 :            :     // Do not propagate previous found list, if
     941                 :            :     // - destination is an empty paragraph which is not in a list and
     942                 :            :     // - source contains at least one paragraph which is not in a list
     943         [ -  + ]:         28 :     if ( pNumRuleToPropagate &&
           [ #  #  #  # ]
         [ #  # ][ #  # ]
                 [ -  + ]
     944         [ #  # ]:          0 :          pDestTxtNd && !pDestTxtNd->GetTxt().Len() && !pDestTxtNd->IsInList() &&
     945         [ #  # ]:          0 :          !lcl_ContainsOnlyParagraphsInList( rPam ) )
     946                 :            :     {
     947                 :          0 :         pNumRuleToPropagate = 0;
     948                 :            :     }
     949                 :            : 
     950                 :            :     // This do/while block is only there so that we can break out of it!
     951                 :            :     do {
     952         [ +  - ]:         28 :         if( pSttTxtNd )
     953                 :            :         {
     954                 :            :             // Don't copy the beginning completely?
     955 [ +  + ][ +  - ]:         28 :             if( !bCopyCollFmt || bColumnSel || pStt->nContent.GetIndex() )
         [ +  + ][ +  + ]
     956                 :            :             {
     957         [ +  - ]:         11 :                 SwIndex aDestIdx( rPos.nContent );
     958                 :         11 :                 sal_Bool bCopyOk = sal_False;
     959         [ -  + ]:         11 :                 if( !pDestTxtNd )
     960                 :            :                 {
     961 [ #  # ][ #  # ]:          0 :                     if( pStt->nContent.GetIndex() || bOneNode )
                 [ #  # ]
     962         [ #  # ]:          0 :                         pDestTxtNd = pDoc->GetNodes().MakeTxtNode( aInsPos,
     963 [ #  # ][ #  # ]:          0 :                             pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD));
     964                 :            :                     else
     965                 :            :                     {
     966         [ #  # ]:          0 :                         pDestTxtNd = static_cast<SwTxtNode*>(pSttTxtNd->MakeCopy( pDoc, aInsPos ));
     967                 :          0 :                         bCopyOk = sal_True;
     968                 :            :                     }
     969 [ #  # ][ #  # ]:          0 :                     aDestIdx.Assign( pDestTxtNd, 0 );
     970                 :          0 :                     bCopyCollFmt = true;
     971                 :            :                 }
     972 [ +  + ][ -  + ]:         11 :                 else if( !bOneNode || bColumnSel )
     973                 :            :                 {
     974                 :          8 :                     xub_StrLen nCntntEnd = pEnd->nContent.GetIndex();
     975                 :            :                     {
     976 [ +  - ][ +  - ]:          8 :                         ::sw::UndoGuard const ug(pDoc->GetIDocumentUndoRedo());
     977 [ +  - ][ +  - ]:          8 :                         pDoc->SplitNode( rPos, false );
     978                 :            :                     }
     979                 :            : 
     980 [ -  + ][ #  # ]:          8 :                     if( bCanMoveBack && rPos == *aCpyPam.GetPoint() )
         [ #  # ][ -  + ]
     981                 :            :                     {
     982                 :            :                         // after the SplitNode, span the CpyPam correctly again
     983         [ #  # ]:          0 :                         aCpyPam.Move( fnMoveBackward, fnGoCntnt );
     984         [ #  # ]:          0 :                         aCpyPam.Move( fnMoveBackward, fnGoCntnt );
     985                 :            :                     }
     986                 :            : 
     987 [ +  - ][ +  - ]:          8 :                     pDestTxtNd = pDoc->GetNodes()[ aInsPos.GetIndex()-1 ]->GetTxtNode();
     988 [ +  - ][ +  - ]:          8 :                     aDestIdx.Assign( pDestTxtNd, pDestTxtNd->GetTxt().Len() );
     989                 :            : 
     990                 :            :                     // Correct the area again
     991         [ -  + ]:          8 :                     if( bEndEqualIns )
     992                 :            :                     {
     993                 :          0 :                         sal_Bool bChg = pEnd != rPam.GetPoint();
     994         [ #  # ]:          0 :                         if( bChg )
     995                 :          0 :                             rPam.Exchange();
     996         [ #  # ]:          0 :                         rPam.Move( fnMoveBackward, fnGoCntnt );
     997         [ #  # ]:          0 :                         if( bChg )
     998                 :          0 :                             rPam.Exchange();
     999                 :            : 
    1000         [ #  # ]:          0 :                         aRg.aEnd = pEnd->nNode;
    1001                 :          0 :                         pEndTxtNd = pEnd->nNode.GetNode().GetTxtNode();
    1002                 :            :                     }
    1003 [ +  - ][ -  + ]:          8 :                     else if( rPos == *pEnd )
    1004                 :            :                     {
    1005                 :            :                         // The end was also moved
    1006         [ #  # ]:          0 :                         pEnd->nNode--;
    1007 [ #  # ][ #  # ]:          0 :                         pEnd->nContent.Assign( pDestTxtNd, nCntntEnd );
    1008         [ #  # ]:          0 :                         aRg.aEnd = pEnd->nNode;
    1009                 :          0 :                         pEndTxtNd = pEnd->nNode.GetNode().GetTxtNode();
    1010                 :            :                     }
    1011                 :            :                 }
    1012                 :            : 
    1013                 :            :                 // Safe numrule item at destination.
    1014                 :            :                 // #i86492# - Safe also <ListId> item of destination.
    1015                 :         11 :                 int aNumRuleState = SFX_ITEM_UNKNOWN;
    1016         [ +  - ]:         11 :                 SwNumRuleItem aNumRuleItem;
    1017                 :         11 :                 int aListIdState = SFX_ITEM_UNKNOWN;
    1018 [ +  - ][ +  - ]:         11 :                 SfxStringItem aListIdItem( RES_PARATR_LIST_ID, String() );
                 [ +  - ]
    1019                 :            :                 {
    1020         [ +  - ]:         11 :                     const SfxItemSet * pAttrSet = pDestTxtNd->GetpSwAttrSet();
    1021         [ -  + ]:         11 :                     if (pAttrSet != NULL)
    1022                 :            :                     {
    1023                 :          0 :                         const SfxPoolItem * pItem = NULL;
    1024         [ #  # ]:          0 :                         aNumRuleState = pAttrSet->GetItemState(RES_PARATR_NUMRULE, sal_False, &pItem);
    1025         [ #  # ]:          0 :                         if (SFX_ITEM_SET == aNumRuleState)
    1026         [ #  # ]:          0 :                             aNumRuleItem = *((SwNumRuleItem *) pItem);
    1027                 :            : 
    1028                 :            :                         aListIdState =
    1029         [ #  # ]:          0 :                             pAttrSet->GetItemState(RES_PARATR_LIST_ID, sal_False, &pItem);
    1030         [ #  # ]:          0 :                         if (SFX_ITEM_SET == aListIdState)
    1031                 :            :                         {
    1032         [ #  # ]:          0 :                             aListIdItem.SetValue( static_cast<const SfxStringItem*>(pItem)->GetValue() );
    1033                 :            :                         }
    1034                 :            :                     }
    1035                 :            :                 }
    1036                 :            : 
    1037         [ +  - ]:         11 :                 if( !bCopyOk )
    1038                 :            :                 {
    1039                 :            :                     const xub_StrLen nCpyLen = ( (bOneNode)
    1040                 :          3 :                                            ? pEnd->nContent.GetIndex()
    1041                 :          8 :                                            : pSttTxtNd->GetTxt().Len() )
    1042         [ +  + ]:         19 :                                          - pStt->nContent.GetIndex();
    1043                 :            :                     pSttTxtNd->CopyText( pDestTxtNd, aDestIdx,
    1044         [ +  - ]:         11 :                                             pStt->nContent, nCpyLen );
    1045         [ -  + ]:         11 :                     if( bEndEqualIns )
    1046         [ #  # ]:          0 :                         pEnd->nContent -= nCpyLen;
    1047                 :            :                 }
    1048                 :            : 
    1049         [ +  + ]:         11 :                 if( bOneNode )
    1050                 :            :                 {
    1051         [ +  - ]:          3 :                     if( bCopyCollFmt )
    1052                 :            :                     {
    1053         [ +  - ]:          3 :                         pSttTxtNd->CopyCollFmt( *pDestTxtNd );
    1054                 :            : 
    1055                 :            :                         /* If only a part of one paragraph is copied
    1056                 :            :                            restore the numrule at the destination. */
    1057                 :            :                         // #i86492# - restore also <ListId> item
    1058 [ +  - ][ +  - ]:          3 :                         if ( !lcl_MarksWholeNode(rPam) )
    1059                 :            :                         {
    1060         [ -  + ]:          3 :                             if (SFX_ITEM_SET == aNumRuleState)
    1061                 :            :                             {
    1062         [ #  # ]:          0 :                                 pDestTxtNd->SetAttr(aNumRuleItem);
    1063                 :            :                             }
    1064                 :            :                             else
    1065                 :            :                             {
    1066         [ +  - ]:          3 :                                 pDestTxtNd->ResetAttr(RES_PARATR_NUMRULE);
    1067                 :            :                             }
    1068         [ -  + ]:          3 :                             if (SFX_ITEM_SET == aListIdState)
    1069                 :            :                             {
    1070         [ #  # ]:          0 :                                 pDestTxtNd->SetAttr(aListIdItem);
    1071                 :            :                             }
    1072                 :            :                             else
    1073                 :            :                             {
    1074         [ +  - ]:          3 :                                 pDestTxtNd->ResetAttr(RES_PARATR_LIST_ID);
    1075                 :            :                             }
    1076                 :            :                         }
    1077                 :            :                     }
    1078                 :            : 
    1079                 :            :                     break;
    1080                 :            :                 }
    1081                 :            : 
    1082 [ +  - ][ +  - ]:         11 :                 aRg.aStart++;
         [ +  + ][ +  - ]
         [ +  + ][ +  - ]
                 [ +  + ]
    1083                 :            :             }
    1084                 :            :         }
    1085         [ #  # ]:          0 :         else if( pDestTxtNd )
    1086                 :            :         {
    1087                 :            :             // Problems with insertion of table selections into "normal" text solved.
    1088                 :            :             // We have to set the correct PaM for Undo, if this PaM starts in a textnode,
    1089                 :            :             // the undo operation will try to merge this node after removing the table.
    1090                 :            :             // If we didn't split a textnode, the PaM should start at the inserted table node
    1091 [ #  # ][ #  # ]:          0 :             if( rPos.nContent.GetIndex() == pDestTxtNd->Len() )
    1092                 :            :             {    // Insertion at the last position of a textnode (empty or not)
    1093         [ #  # ]:          0 :                 aInsPos++; // The table will be inserted behind the text node
    1094                 :            :             }
    1095         [ #  # ]:          0 :             else if( rPos.nContent.GetIndex() )
    1096                 :            :             {   // Insertion in the middle of a text node, it has to be split
    1097                 :            :                 // (and joined from undo)
    1098                 :          0 :                 bStartIsTxtNode = sal_True;
    1099                 :            : 
    1100                 :          0 :                 xub_StrLen nCntntEnd = pEnd->nContent.GetIndex();
    1101                 :            :                 {
    1102 [ #  # ][ #  # ]:          0 :                     ::sw::UndoGuard const ug(pDoc->GetIDocumentUndoRedo());
    1103 [ #  # ][ #  # ]:          0 :                     pDoc->SplitNode( rPos, false );
    1104                 :            :                 }
    1105                 :            : 
    1106 [ #  # ][ #  # ]:          0 :                 if( bCanMoveBack && rPos == *aCpyPam.GetPoint() )
         [ #  # ][ #  # ]
    1107                 :            :                 {
    1108                 :            :                     // after the SplitNode, span the CpyPam correctly again
    1109         [ #  # ]:          0 :                     aCpyPam.Move( fnMoveBackward, fnGoCntnt );
    1110         [ #  # ]:          0 :                     aCpyPam.Move( fnMoveBackward, fnGoCntnt );
    1111                 :            :                 }
    1112                 :            : 
    1113                 :            :                 // Correct the area again
    1114         [ #  # ]:          0 :                 if( bEndEqualIns )
    1115         [ #  # ]:          0 :                     aRg.aEnd--;
    1116                 :            :                 // The end would also be moved
    1117 [ #  # ][ #  # ]:          0 :                 else if( rPos == *pEnd )
    1118                 :            :                 {
    1119         [ #  # ]:          0 :                     rPos.nNode-=2;
    1120                 :          0 :                     rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(),
    1121 [ #  # ][ #  # ]:          0 :                                             nCntntEnd );
    1122         [ #  # ]:          0 :                     rPos.nNode++;
    1123         [ #  # ]:          0 :                     aRg.aEnd--;
    1124                 :            :                 }
    1125                 :            :             }
    1126         [ #  # ]:          0 :             else if( bCanMoveBack )
    1127                 :            :             {   //Insertion at the first position of a text node. It will not be splitted, the table
    1128                 :            :                 // will be inserted before the text node.
    1129                 :            :                 // See below, before the SetInsertRange funciton of the undo object will be called,
    1130                 :            :                 // the CpyPam would be moved to the next content position. This has to be avoided
    1131                 :            :                 // We want to be moved to the table node itself thus we have to set bCanMoveBack
    1132                 :            :                 // and to manipulate aCpyPam.
    1133                 :          0 :                 bCanMoveBack = false;
    1134         [ #  # ]:          0 :                 aCpyPam.GetPoint()->nNode--;
    1135                 :            :             }
    1136                 :            :         }
    1137                 :            : 
    1138                 :         25 :         pDestTxtNd = aInsPos.GetNode().GetTxtNode();
    1139         [ +  - ]:         25 :         if( pEndTxtNd )
    1140                 :            :         {
    1141         [ +  - ]:         25 :             SwIndex aDestIdx( rPos.nContent );
    1142         [ -  + ]:         25 :             if( !pDestTxtNd )
    1143                 :            :             {
    1144         [ #  # ]:          0 :                 pDestTxtNd = pDoc->GetNodes().MakeTxtNode( aInsPos,
    1145 [ #  # ][ #  # ]:          0 :                             pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD));
    1146 [ #  # ][ #  # ]:          0 :                 aDestIdx.Assign( pDestTxtNd, 0  );
    1147         [ #  # ]:          0 :                 aInsPos--;
    1148                 :            : 
    1149                 :            :                 // if we have to insert an extra text node
    1150                 :            :                 // at the destination, this node will be our new destination
    1151                 :            :                 // (text) node, and thus we set bStartisTxtNode to true. This
    1152                 :            :                 // will ensure that this node will be deleted during Undo
    1153                 :            :                 // using JoinNext.
    1154                 :            :                 OSL_ENSURE( !bStartIsTxtNode, "Oops, undo may be instable now." );
    1155                 :          0 :                 bStartIsTxtNode = sal_True;
    1156                 :            :             }
    1157                 :            : 
    1158                 :            :             // Save numrule at destination
    1159                 :            :             // #i86492# - Safe also <ListId> item of destination.
    1160                 :         25 :             int aNumRuleState = SFX_ITEM_UNKNOWN;
    1161         [ +  - ]:         25 :             SwNumRuleItem aNumRuleItem;
    1162                 :         25 :             int aListIdState = SFX_ITEM_UNKNOWN;
    1163 [ +  - ][ +  - ]:         25 :             SfxStringItem aListIdItem( RES_PARATR_LIST_ID, String() );
                 [ +  - ]
    1164                 :            :             {
    1165         [ +  - ]:         25 :                 const SfxItemSet* pAttrSet = pDestTxtNd->GetpSwAttrSet();
    1166         [ -  + ]:         25 :                 if (pAttrSet != NULL)
    1167                 :            :                 {
    1168                 :          0 :                     const SfxPoolItem * pItem = NULL;
    1169                 :            : 
    1170                 :            :                     aNumRuleState =
    1171         [ #  # ]:          0 :                         pAttrSet->GetItemState(RES_PARATR_NUMRULE, sal_False, &pItem);
    1172         [ #  # ]:          0 :                     if (SFX_ITEM_SET == aNumRuleState)
    1173         [ #  # ]:          0 :                         aNumRuleItem = *((SwNumRuleItem *) pItem);
    1174                 :            : 
    1175                 :            :                     aListIdState =
    1176         [ #  # ]:          0 :                         pAttrSet->GetItemState(RES_PARATR_LIST_ID, sal_False, &pItem);
    1177         [ #  # ]:          0 :                     if (SFX_ITEM_SET == aListIdState)
    1178         [ #  # ]:          0 :                         aListIdItem.SetValue( static_cast<const SfxStringItem*>(pItem)->GetValue() );
    1179                 :            :                 }
    1180                 :            :             }
    1181                 :            : 
    1182                 :         25 :             const bool bEmptyDestNd = 0 == pDestTxtNd->GetTxt().Len();
    1183         [ +  - ]:         25 :             pEndTxtNd->CopyText( pDestTxtNd, aDestIdx, SwIndex( pEndTxtNd ),
    1184 [ +  - ][ +  - ]:         50 :                             pEnd->nContent.GetIndex() );
                 [ +  - ]
    1185                 :            : 
    1186                 :            :             // Also copy all format templates
    1187 [ +  + ][ +  + ]:         25 :             if( bCopyCollFmt && ( bOneNode || bEmptyDestNd ))
                 [ +  - ]
    1188                 :            :             {
    1189         [ +  - ]:         17 :                 pEndTxtNd->CopyCollFmt( *pDestTxtNd );
    1190                 :            : 
    1191         [ +  + ]:         17 :                 if ( bOneNode )
    1192                 :            :                 {
    1193                 :            :                     /* If only a part of one paragraph is copied
    1194                 :            :                        restore the numrule at the destination. */
    1195                 :            :                     // #i86492# - restore also <ListId> item
    1196 [ +  - ][ -  + ]:          2 :                     if ( !lcl_MarksWholeNode(rPam) )
    1197                 :            :                     {
    1198         [ #  # ]:          0 :                         if (SFX_ITEM_SET == aNumRuleState)
    1199                 :            :                         {
    1200         [ #  # ]:          0 :                             pDestTxtNd->SetAttr(aNumRuleItem);
    1201                 :            :                         }
    1202                 :            :                         else
    1203                 :            :                         {
    1204         [ #  # ]:          0 :                             pDestTxtNd->ResetAttr(RES_PARATR_NUMRULE);
    1205                 :            :                         }
    1206         [ #  # ]:          0 :                         if (SFX_ITEM_SET == aListIdState)
    1207                 :            :                         {
    1208         [ #  # ]:          0 :                             pDestTxtNd->SetAttr(aListIdItem);
    1209                 :            :                         }
    1210                 :            :                         else
    1211                 :            :                         {
    1212         [ #  # ]:          0 :                             pDestTxtNd->ResetAttr(RES_PARATR_LIST_ID);
    1213                 :            :                         }
    1214                 :            :                     }
    1215                 :            :                 }
    1216 [ +  - ][ +  - ]:         25 :             }
                 [ +  - ]
    1217                 :            :         }
    1218                 :            : 
    1219 [ +  - ][ +  + ]:         25 :         if( bCopyAll || aRg.aStart != aRg.aEnd )
                 [ +  + ]
    1220                 :            :         {
    1221         [ +  - ]:         17 :             SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange );
    1222 [ +  - ][ +  + ]:         17 :             if( pSttTxtNd && bCopyCollFmt && pDestTxtNd->HasSwAttrSet() )
         [ +  - ][ +  - ]
                 [ +  + ]
    1223                 :            :             {
    1224 [ +  - ][ +  - ]:         15 :                 aBrkSet.Put( *pDestTxtNd->GetpSwAttrSet() );
    1225 [ +  - ][ -  + ]:         15 :                 if( SFX_ITEM_SET == aBrkSet.GetItemState( RES_BREAK, sal_False ) )
    1226         [ #  # ]:          0 :                     pDestTxtNd->ResetAttr( RES_BREAK );
    1227 [ +  - ][ -  + ]:         15 :                 if( SFX_ITEM_SET == aBrkSet.GetItemState( RES_PAGEDESC, sal_False ) )
    1228         [ #  # ]:          0 :                     pDestTxtNd->ResetAttr( RES_PAGEDESC );
    1229                 :            :             }
    1230                 :            : 
    1231         [ -  + ]:         17 :             if( aInsPos == pEnd->nNode )
    1232                 :            :             {
    1233         [ #  # ]:          0 :                 SwNodeIndex aSaveIdx( aInsPos, -1 );
    1234         [ #  # ]:          0 :                 CopyWithFlyInFly( aRg, 0,aInsPos, bMakeNewFrms, sal_False );
    1235         [ #  # ]:          0 :                 aSaveIdx++;
    1236         [ #  # ]:          0 :                 pEnd->nNode = aSaveIdx;
    1237 [ #  # ][ #  # ]:          0 :                 pEnd->nContent.Assign( aSaveIdx.GetNode().GetTxtNode(), 0 );
                 [ #  # ]
    1238                 :            :             }
    1239                 :            :             else
    1240         [ +  - ]:         17 :                 CopyWithFlyInFly( aRg, pEnd->nContent.GetIndex(), aInsPos, bMakeNewFrms, sal_False );
    1241                 :            : 
    1242                 :         17 :             bCopyBookmarks = false;
    1243                 :            : 
    1244                 :            :             // Put the breaks back into the first node
    1245   [ -  +  #  # ]:         17 :             if( aBrkSet.Count() && 0 != ( pDestTxtNd = pDoc->GetNodes()[
         [ #  # ][ -  + ]
    1246         [ #  # ]:          0 :                     aCpyPam.GetPoint()->nNode.GetIndex()+1 ]->GetTxtNode() ) )
    1247                 :            :             {
    1248         [ #  # ]:          0 :                 pDestTxtNd->SetAttr( aBrkSet );
    1249         [ +  - ]:         17 :             }
    1250                 :            :         }
    1251                 :            :     } while( sal_False );
    1252                 :            : 
    1253                 :            :     // Adjust position (in case it was moved / in another node)
    1254                 :         28 :     rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(),
    1255 [ +  - ][ +  - ]:         56 :                             rPos.nContent.GetIndex() );
    1256                 :            : 
    1257         [ -  + ]:         28 :     if( rPos.nNode != aInsPos )
    1258                 :            :     {
    1259         [ #  # ]:          0 :         aCpyPam.GetMark()->nNode = aInsPos;
    1260 [ #  # ][ #  # ]:          0 :         aCpyPam.GetMark()->nContent.Assign( aCpyPam.GetCntntNode(sal_False), 0 );
    1261         [ #  # ]:          0 :         rPos = *aCpyPam.GetMark();
    1262                 :            :     }
    1263                 :            :     else
    1264         [ +  - ]:         28 :         *aCpyPam.GetMark() = rPos;
    1265                 :            : 
    1266         [ +  - ]:         28 :     if ( !bAfterTable )
    1267 [ -  + ][ +  - ]:         28 :         aCpyPam.Move( fnMoveForward, bCanMoveBack ? fnGoCntnt : fnGoNode );
    1268                 :            :     else
    1269                 :            :     {
    1270                 :            :         // Reset the offset to 0 as it was before the insertion
    1271         [ #  # ]:          0 :         aCpyPam.GetPoint( )->nContent -= aCpyPam.GetPoint( )->nContent;
    1272                 :            : 
    1273         [ #  # ]:          0 :         aCpyPam.GetPoint( )->nNode++;
    1274                 :            :         // If the next node is a start node, then step back: the start node
    1275                 :            :         // has been copied and needs to be in the selection for the undo
    1276         [ #  # ]:          0 :         if ( aCpyPam.GetPoint()->nNode.GetNode().IsStartNode() )
    1277         [ #  # ]:          0 :             aCpyPam.GetPoint( )->nNode--;
    1278                 :            : 
    1279                 :            :     }
    1280                 :         28 :     aCpyPam.Exchange();
    1281                 :            : 
    1282                 :            :     // Also copy all bookmarks
    1283 [ +  - ][ +  - ]:         28 :     if( bCopyBookmarks && getIDocumentMarkAccess()->getMarksCount() )
         [ -  + ][ -  + ]
                 [ +  + ]
    1284         [ #  # ]:          0 :         lcl_CopyBookmarks( rPam, aCpyPam );
    1285                 :            : 
    1286         [ -  + ]:         28 :     if( nsRedlineMode_t::REDLINE_DELETE_REDLINES & eOld )
    1287         [ #  # ]:          0 :         lcl_DeleteRedlines( rPam, aCpyPam );
    1288                 :            : 
    1289                 :            :     // If Undo is enabled, store the inserted area
    1290 [ +  - ][ +  - ]:         28 :     if (pDoc->GetIDocumentUndoRedo().DoesUndo())
                 [ +  + ]
    1291                 :            :     {
    1292         [ +  - ]:          6 :         pUndo->SetInsertRange( aCpyPam, sal_True, bStartIsTxtNode );
    1293                 :            :     }
    1294                 :            : 
    1295         [ -  + ]:         28 :     if( pCpyRange )
    1296                 :            :     {
    1297         [ #  # ]:          0 :         pCpyRange->SetMark();
    1298         [ #  # ]:          0 :         *pCpyRange->GetPoint() = *aCpyPam.GetPoint();
    1299         [ #  # ]:          0 :         *pCpyRange->GetMark() = *aCpyPam.GetMark();
    1300                 :            :     }
    1301                 :            : 
    1302         [ -  + ]:         28 :     if ( pNumRuleToPropagate )
    1303                 :            :     {
    1304                 :            :         // #i86492# - use <SwDoc::SetNumRule(..)>, because it also handles the <ListId>
    1305                 :            :         pDoc->SetNumRule( aCpyPam, *pNumRuleToPropagate, false,
    1306 [ #  # ][ #  # ]:          0 :                           aListIdToPropagate, sal_True, true );
                 [ #  # ]
    1307                 :            :     }
    1308                 :            : 
    1309         [ +  - ]:         28 :     pDoc->SetRedlineMode_intern( eOld );
    1310         [ +  - ]:         28 :     pDoc->SetModified();
    1311                 :            : 
    1312 [ +  - ][ +  - ]:         28 :     return true;
         [ +  - ][ +  - ]
                 [ +  - ]
    1313                 :            : }
    1314                 :            : 
    1315                 :            : // Copy method from SwDoc - "copy Flys in Flys"
    1316                 :         20 : void SwDoc::CopyWithFlyInFly( const SwNodeRange& rRg, const xub_StrLen nEndContentIndex,
    1317                 :            :                             const SwNodeIndex& rInsPos, sal_Bool bMakeNewFrms,
    1318                 :            :                             sal_Bool bDelRedlines, sal_Bool bCopyFlyAtFly ) const
    1319                 :            : {
    1320                 :         20 :     SwDoc* pDest = rInsPos.GetNode().GetDoc();
    1321                 :            : 
    1322         [ +  - ]:         20 :     _SaveRedlEndPosForRestore aRedlRest( rInsPos, 0 );
    1323                 :            : 
    1324         [ +  - ]:         20 :     SwNodeIndex aSavePos( rInsPos, -1 );
    1325                 :         20 :     sal_Bool bEndIsEqualEndPos = rInsPos == rRg.aEnd;
    1326 [ +  - ][ +  - ]:         20 :     GetNodes()._CopyNodes( rRg, rInsPos, bMakeNewFrms, sal_True );
    1327         [ +  - ]:         20 :     aSavePos++;
    1328         [ -  + ]:         20 :     if( bEndIsEqualEndPos )
    1329         [ #  # ]:          0 :         ((SwNodeIndex&)rRg.aEnd) = aSavePos;
    1330                 :            : 
    1331         [ +  - ]:         20 :     aRedlRest.Restore();
    1332                 :            : 
    1333                 :            : #if OSL_DEBUG_LEVEL > 0
    1334                 :            :     {
    1335                 :            :         //JP 17.06.99: Bug 66973 - check count only if the selection is in
    1336                 :            :         // the same section or there's no section, because sections that are
    1337                 :            :         // not fully selected are not copied.
    1338                 :            :         const SwSectionNode* pSSectNd = rRg.aStart.GetNode().FindSectionNode();
    1339                 :            :         SwNodeIndex aTmpI( rRg.aEnd, -1 );
    1340                 :            :         const SwSectionNode* pESectNd = aTmpI.GetNode().FindSectionNode();
    1341                 :            :         if( pSSectNd == pESectNd &&
    1342                 :            :             !rRg.aStart.GetNode().IsSectionNode() &&
    1343                 :            :             !aTmpI.GetNode().IsEndNode() )
    1344                 :            :         {
    1345                 :            :             OSL_ENSURE( rInsPos.GetIndex() - aSavePos.GetIndex() ==
    1346                 :            :                     rRg.aEnd.GetIndex() - rRg.aStart.GetIndex(),
    1347                 :            :                     "An insufficient number of nodes were copied!" );
    1348                 :            :         }
    1349                 :            :     }
    1350                 :            : #endif
    1351                 :            : 
    1352                 :            :     {
    1353 [ +  - ][ +  - ]:         20 :         ::sw::UndoGuard const undoGuard(pDest->GetIDocumentUndoRedo());
    1354 [ +  - ][ +  - ]:         20 :         CopyFlyInFlyImpl( rRg, nEndContentIndex, aSavePos, bCopyFlyAtFly );
    1355                 :            :     }
    1356                 :            : 
    1357         [ +  - ]:         20 :     SwNodeRange aCpyRange( aSavePos, rInsPos );
    1358                 :            : 
    1359                 :            :     // Also copy all bookmarks
    1360 [ +  - ][ +  - ]:         20 :     if( getIDocumentMarkAccess()->getMarksCount() )
                 [ +  + ]
    1361                 :            :     {
    1362         [ +  - ]:         18 :         SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
    1363         [ +  - ]:         18 :         SwPaM aCpyTmp( aCpyRange.aStart, aCpyRange.aEnd );
    1364                 :            : 
    1365 [ +  - ][ +  - ]:         18 :         lcl_CopyBookmarks( aRgTmp, aCpyTmp );
                 [ +  - ]
    1366                 :            :     }
    1367                 :            : 
    1368 [ +  + ][ +  - ]:         20 :     if( bDelRedlines && ( nsRedlineMode_t::REDLINE_DELETE_REDLINES & pDest->GetRedlineMode() ))
         [ -  + ][ -  + ]
    1369         [ #  # ]:          0 :         lcl_DeleteRedlines( rRg, aCpyRange );
    1370                 :            : 
    1371 [ +  - ][ +  - ]:         20 :     pDest->GetNodes()._DelDummyNodes( aCpyRange );
         [ +  - ][ +  - ]
                 [ +  - ]
    1372                 :         20 : }
    1373                 :            : 
    1374                 :          0 : void lcl_ChainFmts( SwFlyFrmFmt *pSrc, SwFlyFrmFmt *pDest )
    1375                 :            : {
    1376 [ #  # ][ #  # ]:          0 :     SwFmtChain aSrc( pSrc->GetChain() );
    1377         [ #  # ]:          0 :     if ( !aSrc.GetNext() )
    1378                 :            :     {
    1379         [ #  # ]:          0 :         aSrc.SetNext( pDest );
    1380         [ #  # ]:          0 :         pSrc->SetFmtAttr( aSrc );
    1381                 :            :     }
    1382 [ #  # ][ #  # ]:          0 :     SwFmtChain aDest( pDest->GetChain() );
    1383         [ #  # ]:          0 :     if ( !aDest.GetPrev() )
    1384                 :            :     {
    1385         [ #  # ]:          0 :         aDest.SetPrev( pSrc );
    1386         [ #  # ]:          0 :         pDest->SetFmtAttr( aDest );
    1387 [ #  # ][ #  # ]:          0 :     }
    1388                 :          0 : }
    1389                 :            : 
    1390                 :        134 : void SwDoc::CopyFlyInFlyImpl( const SwNodeRange& rRg,
    1391                 :            :         const xub_StrLen nEndContentIndex, const SwNodeIndex& rStartIdx,
    1392                 :            :         const bool bCopyFlyAtFly ) const
    1393                 :            : {
    1394                 :            :     // First collect all Flys, sort them according to their ordering number,
    1395                 :            :     // and then only copy them. This maintains the ordering numbers (which are only
    1396                 :            :     // managed in the DrawModel).
    1397                 :        134 :     SwDoc *const pDest = rStartIdx.GetNode().GetDoc();
    1398         [ +  - ]:        134 :     ::std::set< _ZSortFly > aSet;
    1399                 :        134 :     sal_uInt16 nArrLen = GetSpzFrmFmts()->size();
    1400                 :            : 
    1401         [ +  + ]:        203 :     for ( sal_uInt16 n = 0; n < nArrLen; ++n )
    1402                 :            :     {
    1403         [ +  - ]:         69 :         SwFrmFmt const*const pFmt = (*GetSpzFrmFmts())[n];
    1404         [ +  - ]:         69 :         SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
    1405         [ +  - ]:         69 :         SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
    1406                 :         69 :         bool bAtCntnt = (pAnchor->GetAnchorId() == FLY_AT_PARA);
    1407   [ +  +  +  -  :        165 :         if ( pAPos &&
           +  + ][ -  +  
             #  #  #  # ]
           [ +  +  +  + ]
         [ +  + ][ +  + ]
    1408                 :            :              ( bAtCntnt ||
    1409                 :         18 :               (pAnchor->GetAnchorId() == FLY_AT_FLY) ||
    1410                 :         18 :               (pAnchor->GetAnchorId() == FLY_AT_CHAR)) &&
    1411                 :          0 :              (( bCopyFlyAtFly && FLY_AT_FLY == pAnchor->GetAnchorId() )
    1412                 :          0 :                     ? rRg.aStart <= pAPos->nNode.GetIndex() + 1
    1413         [ +  - ]:         30 :                     : ( IsRedlineMove()
    1414                 :         27 :                             ? rRg.aStart < pAPos->nNode
    1415 [ +  - ][ +  + ]:         30 :                             : rRg.aStart <= pAPos->nNode )) &&
    1416                 :          6 :              pAPos->nNode <= rRg.aEnd )
    1417                 :            :         {
    1418                 :            :             //frames at the last source node are not always copied:
    1419                 :            :             //- if the node is empty and is the last node of the document or a table cell
    1420                 :            :             //  or a text frame then tey have to be copied
    1421                 :            :             //- if the content index in this node is > 0 then paragph and frame bound objects are copied
    1422                 :            :             //- to-character bound objects are copied if their index is <= nEndContentIndex
    1423                 :          3 :             bool bAdd = false;
    1424         [ +  - ]:          3 :             if( pAPos->nNode < rRg.aEnd )
    1425                 :          3 :                 bAdd = true;
    1426 [ -  + ][ #  # ]:          3 :             if (!bAdd && !IsRedlineMove()) // fdo#40599: not for redline move
         [ #  # ][ -  + ]
    1427                 :            :             {
    1428                 :          0 :                 bool bEmptyNode = false;
    1429                 :          0 :                 bool bLastNode = false;
    1430                 :            :                 // is the node empty?
    1431                 :          0 :                 const SwNodes& rNodes = pAPos->nNode.GetNodes();
    1432                 :            :                 SwTxtNode* pTxtNode;
    1433         [ #  # ]:          0 :                 if( 0 != ( pTxtNode = pAPos->nNode.GetNode().GetTxtNode() ))
    1434                 :            :                 {
    1435                 :          0 :                     bEmptyNode = !pTxtNode->GetTxt().Len();
    1436         [ #  # ]:          0 :                     if( bEmptyNode )
    1437                 :            :                     {
    1438                 :            :                         //last node information is only necessary to know for the last TextNode
    1439         [ #  # ]:          0 :                         SwNodeIndex aTmp( pAPos->nNode );
    1440         [ #  # ]:          0 :                         ++aTmp;//goto next node
    1441         [ #  # ]:          0 :                         while (aTmp.GetNode().IsEndNode())
    1442                 :            :                         {
    1443         [ #  # ]:          0 :                             if( aTmp == rNodes.GetEndOfContent().GetIndex() )
    1444                 :            :                             {
    1445                 :          0 :                                 bLastNode = true;
    1446                 :          0 :                                 break;
    1447                 :            :                             }
    1448         [ #  # ]:          0 :                             ++aTmp;
    1449         [ #  # ]:          0 :                         }
    1450                 :            :                     }
    1451                 :            :                 }
    1452 [ #  # ][ #  # ]:          0 :                 bAdd = bLastNode && bEmptyNode;
    1453         [ #  # ]:          0 :                 if( !bAdd )
    1454                 :            :                 {
    1455         [ #  # ]:          0 :                     if( bAtCntnt )
    1456                 :          0 :                         bAdd = nEndContentIndex > 0;
    1457                 :            :                     else
    1458                 :          0 :                         bAdd = pAPos->nContent <= nEndContentIndex;
    1459                 :            :                 }
    1460                 :            :             }
    1461         [ +  - ]:          3 :             if( bAdd )
    1462 [ +  - ][ +  - ]:          3 :                 aSet.insert( _ZSortFly( pFmt, pAnchor, nArrLen + aSet.size() ));
    1463                 :            :         }
    1464                 :            :     }
    1465                 :            : 
    1466                 :            :     // Store all copied (and also the newly created) frames in another array.
    1467                 :            :     // They are stored as matching the originals, so that we will be later
    1468                 :            :     // able to build the chains accordingly.
    1469         [ +  - ]:        134 :     ::std::vector< SwFrmFmt* > aVecSwFrmFmt;
    1470                 :            : 
    1471         [ +  + ]:        137 :     for (::std::set< _ZSortFly >::const_iterator it=aSet.begin() ; it != aSet.end(); ++it )
    1472                 :            :     {
    1473                 :            :         // #i59964#
    1474                 :            :         // correct determination of new anchor position
    1475         [ +  - ]:          3 :         SwFmtAnchor aAnchor( *(*it).GetAnchor() );
    1476         [ +  - ]:          3 :         SwPosition* pNewPos = (SwPosition*)aAnchor.GetCntntAnchor();
    1477                 :            :         // for at-paragraph and at-character anchored objects the new anchor
    1478                 :            :         // position can *not* be determined by the difference of the current
    1479                 :            :         // anchor position to the start of the copied range, because not
    1480                 :            :         // complete selected sections in the copied range aren't copied - see
    1481                 :            :         // method <SwNodes::_CopyNodes(..)>.
    1482                 :            :         // Thus, the new anchor position in the destination document is found
    1483                 :            :         // by counting the text nodes.
    1484   [ -  +  #  # ]:          3 :         if ((aAnchor.GetAnchorId() == FLY_AT_PARA) ||
                 [ +  - ]
    1485                 :          0 :             (aAnchor.GetAnchorId() == FLY_AT_CHAR) )
    1486                 :            :         {
    1487                 :            :             // First, determine number of anchor text node in the copied range.
    1488                 :            :             // Note: The anchor text node *have* to be inside the copied range.
    1489                 :          3 :             sal_uLong nAnchorTxtNdNumInRange( 0L );
    1490                 :          3 :             bool bAnchorTxtNdFound( false );
    1491         [ +  - ]:          3 :             SwNodeIndex aIdx( rRg.aStart );
    1492 [ +  + ][ +  - ]:          9 :             while ( !bAnchorTxtNdFound && aIdx <= rRg.aEnd )
                 [ +  + ]
    1493                 :            :             {
    1494         [ +  + ]:          6 :                 if ( aIdx.GetNode().IsTxtNode() )
    1495                 :            :                 {
    1496                 :          3 :                     ++nAnchorTxtNdNumInRange;
    1497         [ +  - ]:          3 :                     bAnchorTxtNdFound = aAnchor.GetCntntAnchor()->nNode == aIdx;
    1498                 :            :                 }
    1499                 :            : 
    1500         [ +  - ]:          6 :                 ++aIdx;
    1501                 :            :             }
    1502         [ -  + ]:          3 :             if ( !bAnchorTxtNdFound )
    1503                 :            :             {
    1504                 :            :                 // This case can *not* happen, but to be robust take the first
    1505                 :            :                 // text node in the destination document.
    1506                 :            :                 OSL_FAIL( "<SwDoc::_CopyFlyInFly(..)> - anchor text node in copied range not found" );
    1507                 :          0 :                 nAnchorTxtNdNumInRange = 1;
    1508                 :            :             }
    1509                 :            :             // Second, search corresponding text node in destination document
    1510                 :            :             // by counting forward from start insert position <rStartIdx> the
    1511                 :            :             // determined number of text nodes.
    1512         [ +  - ]:          3 :             aIdx = rStartIdx;
    1513         [ +  - ]:          3 :             SwNodeIndex aAnchorNdIdx( rStartIdx );
    1514                 :            :             const SwNode& aEndOfContentNd =
    1515                 :          3 :                                     aIdx.GetNode().GetNodes().GetEndOfContent();
    1516   [ +  +  +  - ]:         15 :             while ( nAnchorTxtNdNumInRange > 0 &&
                 [ +  + ]
    1517                 :          6 :                     &(aIdx.GetNode()) != &aEndOfContentNd )
    1518                 :            :             {
    1519         [ +  + ]:          6 :                 if ( aIdx.GetNode().IsTxtNode() )
    1520                 :            :                 {
    1521                 :          3 :                     --nAnchorTxtNdNumInRange;
    1522         [ +  - ]:          3 :                     aAnchorNdIdx = aIdx;
    1523                 :            :                 }
    1524                 :            : 
    1525         [ +  - ]:          6 :                 ++aIdx;
    1526                 :            :             }
    1527         [ -  + ]:          3 :             if ( !aAnchorNdIdx.GetNode().IsTxtNode() )
    1528                 :            :             {
    1529                 :            :                 // This case can *not* happen, but to be robust take the first
    1530                 :            :                 // text node in the destination document.
    1531                 :            :                 OSL_FAIL( "<SwDoc::_CopyFlyInFly(..)> - found anchor node index isn't a text node" );
    1532         [ #  # ]:          0 :                 aAnchorNdIdx = rStartIdx;
    1533         [ #  # ]:          0 :                 while ( !aAnchorNdIdx.GetNode().IsTxtNode() )
    1534                 :            :                 {
    1535         [ #  # ]:          0 :                     ++aAnchorNdIdx;
    1536                 :            :                 }
    1537                 :            :             }
    1538                 :            :             // apply found anchor text node as new anchor position
    1539 [ +  - ][ +  - ]:          3 :             pNewPos->nNode = aAnchorNdIdx;
                 [ +  - ]
    1540                 :            :         }
    1541                 :            :         else
    1542                 :            :         {
    1543                 :          0 :             long nOffset = pNewPos->nNode.GetIndex() - rRg.aStart.GetIndex();
    1544         [ #  # ]:          0 :             SwNodeIndex aIdx( rStartIdx, nOffset );
    1545 [ #  # ][ #  # ]:          0 :             pNewPos->nNode = aIdx;
    1546                 :            :         }
    1547                 :            :         // Set the character bound Flys back at the original character
    1548   [ -  +  #  # ]:          3 :         if ((FLY_AT_CHAR == aAnchor.GetAnchorId()) &&
                 [ -  + ]
    1549                 :          0 :              pNewPos->nNode.GetNode().IsTxtNode() )
    1550                 :            :         {
    1551         [ #  # ]:          0 :             pNewPos->nContent.Assign( (SwTxtNode*)&pNewPos->nNode.GetNode(),
    1552 [ #  # ][ #  # ]:          0 :                                         pNewPos->nContent.GetIndex() );
    1553                 :            :         }
    1554                 :            :         else
    1555                 :            :         {
    1556         [ +  - ]:          3 :             pNewPos->nContent.Assign( 0, 0 );
    1557                 :            :         }
    1558                 :            : 
    1559                 :            :         // Check recursion: copy content in its own frame, then don't copy it.
    1560                 :          3 :         sal_Bool bMakeCpy = sal_True;
    1561         [ +  - ]:          3 :         if( pDest == this )
    1562                 :            :         {
    1563         [ +  - ]:          3 :             const SwFmtCntnt& rCntnt = (*it).GetFmt()->GetCntnt();
    1564                 :            :             const SwStartNode* pSNd;
    1565   [ -  +  #  #  :          3 :             if( rCntnt.GetCntntIdx() &&
             #  #  #  # ]
                 [ -  + ]
    1566                 :          0 :                 0 != ( pSNd = rCntnt.GetCntntIdx()->GetNode().GetStartNode() ) &&
    1567                 :          0 :                 pSNd->GetIndex() < rStartIdx.GetIndex() &&
    1568                 :          0 :                 rStartIdx.GetIndex() < pSNd->EndOfSectionIndex() )
    1569                 :            :             {
    1570                 :          0 :                 bMakeCpy = sal_False;
    1571         [ #  # ]:          0 :                 aSet.erase ( it );
    1572                 :            :             }
    1573                 :            :         }
    1574                 :            : 
    1575                 :            :         // Copy the format and set the new anchor
    1576         [ +  - ]:          3 :         if( bMakeCpy )
    1577                 :          3 :             aVecSwFrmFmt.push_back( pDest->CopyLayoutFmt( *(*it).GetFmt(),
    1578 [ +  - ][ +  - ]:          3 :                         aAnchor, false, true ) );
    1579         [ +  - ]:          3 :     }
    1580                 :            : 
    1581                 :            :     // Rebuild as much as possible of all chains that are available in the original,
    1582                 :            :     OSL_ENSURE( aSet.size() == aVecSwFrmFmt.size(), "Missing new Flys" );
    1583         [ +  - ]:        134 :     if ( aSet.size() == aVecSwFrmFmt.size() )
    1584                 :            :     {
    1585                 :        134 :         size_t n = 0;
    1586         [ +  + ]:        137 :         for (::std::set< _ZSortFly >::const_iterator nIt=aSet.begin() ; nIt != aSet.end(); ++nIt, ++n )
    1587                 :            :         {
    1588                 :          3 :             const SwFrmFmt *pFmtN = (*nIt).GetFmt();
    1589         [ +  - ]:          3 :             const SwFmtChain &rChain = pFmtN->GetChain();
    1590                 :          3 :             int nCnt = 0 != rChain.GetPrev();
    1591         [ -  + ]:          3 :             nCnt += rChain.GetNext() ? 1: 0;
    1592                 :          3 :             size_t k = 0;
    1593         [ +  + ]:          6 :             for (::std::set< _ZSortFly >::const_iterator kIt=aSet.begin() ; kIt != aSet.end(); ++kIt, ++k )
    1594                 :            :             {
    1595                 :          3 :                 const SwFrmFmt *pFmtK = (*kIt).GetFmt();
    1596         [ -  + ]:          3 :                 if ( rChain.GetPrev() == pFmtK )
    1597                 :            :                 {
    1598         [ #  # ]:          0 :                     ::lcl_ChainFmts( dynamic_cast< SwFlyFrmFmt* >(aVecSwFrmFmt[k]),
    1599 [ #  # ][ #  # ]:          0 :                                      dynamic_cast< SwFlyFrmFmt* >(aVecSwFrmFmt[n]) );
         [ #  # ][ #  # ]
    1600                 :          0 :                     --nCnt;
    1601                 :            :                 }
    1602         [ -  + ]:          3 :                 else if ( rChain.GetNext() == pFmtK )
    1603                 :            :                 {
    1604         [ #  # ]:          0 :                     ::lcl_ChainFmts( dynamic_cast< SwFlyFrmFmt* >(aVecSwFrmFmt[n]),
    1605 [ #  # ][ #  # ]:          0 :                                      dynamic_cast< SwFlyFrmFmt* >(aVecSwFrmFmt[k]) );
         [ #  # ][ #  # ]
    1606                 :          0 :                     --nCnt;
    1607                 :            :                 }
    1608                 :            :             }
    1609                 :            :         }
    1610                 :        134 :     }
    1611                 :        134 : }
    1612                 :            : 
    1613                 :            : 
    1614                 :            : 
    1615                 :            : 
    1616                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10