LCOV - code coverage report
Current view: top level - sw/source/core/undo - undobj.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 275 586 46.9 %
Date: 2012-08-25 Functions: 27 49 55.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 337 1165 28.9 %

           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                 :            : #include <IShellCursorSupplier.hxx>
      30                 :            : #include <txtftn.hxx>
      31                 :            : #include <fmtanchr.hxx>
      32                 :            : #include <ftnidx.hxx>
      33                 :            : #include <frmfmt.hxx>
      34                 :            : #include <doc.hxx>
      35                 :            : #include <UndoManager.hxx>
      36                 :            : #include <docary.hxx>
      37                 :            : #include <swundo.hxx>
      38                 :            : #include <pam.hxx>
      39                 :            : #include <ndtxt.hxx>
      40                 :            : #include <UndoCore.hxx>
      41                 :            : #include <rolbck.hxx>
      42                 :            : #include <ndnotxt.hxx>
      43                 :            : #include <IMark.hxx>
      44                 :            : #include <mvsave.hxx>
      45                 :            : #include <redline.hxx>
      46                 :            : #include <crossrefbookmark.hxx>
      47                 :            : #include <undo.hrc>
      48                 :            : #include <comcore.hrc>
      49                 :            : #include <docsh.hxx>
      50                 :            : 
      51                 :            : class SwRedlineSaveData : public SwUndRng, public SwRedlineData,
      52                 :            :                           private SwUndoSaveSection
      53                 :            : {
      54                 :            : public:
      55                 :            :     SwRedlineSaveData( SwComparePosition eCmpPos,
      56                 :            :                         const SwPosition& rSttPos, const SwPosition& rEndPos,
      57                 :            :                         SwRedline& rRedl, sal_Bool bCopyNext );
      58                 :            :     ~SwRedlineSaveData();
      59                 :            :     void RedlineToDoc( SwPaM& rPam );
      60                 :          0 :     SwNodeIndex* GetMvSttIdx() const
      61                 :          0 :         { return SwUndoSaveSection::GetMvSttIdx(); }
      62                 :            : 
      63                 :            : #if OSL_DEBUG_LEVEL > 0
      64                 :            :     sal_uInt16 nRedlineCount;
      65                 :            : #endif
      66                 :            : };
      67                 :            : 
      68                 :            : // This class saves the Pam as sal_uInt16s and can recompose those into a PaM
      69                 :         18 : SwUndRng::SwUndRng()
      70                 :         18 :     : nSttNode( 0 ), nEndNode( 0 ), nSttCntnt( 0 ), nEndCntnt( 0 )
      71                 :            : {
      72                 :         18 : }
      73                 :            : 
      74                 :       4592 : SwUndRng::SwUndRng( const SwPaM& rPam )
      75                 :            : {
      76                 :       4592 :     SetValues( rPam );
      77                 :       4592 : }
      78                 :            : 
      79                 :       4592 : void SwUndRng::SetValues( const SwPaM& rPam )
      80                 :            : {
      81                 :       4592 :     const SwPosition *pStt = rPam.Start();
      82         [ +  + ]:       4592 :     if( rPam.HasMark() )
      83                 :            :     {
      84                 :       4146 :         const SwPosition *pEnd = rPam.GetPoint() == pStt
      85                 :            :                         ? rPam.GetMark()
      86         [ +  + ]:       4146 :                         : rPam.GetPoint();
      87                 :       4146 :         nEndNode = pEnd->nNode.GetIndex();
      88                 :       4146 :         nEndCntnt = pEnd->nContent.GetIndex();
      89                 :            :     }
      90                 :            :     else
      91                 :            :         // no selection !!
      92                 :        446 :         nEndNode = 0, nEndCntnt = STRING_MAXLEN;
      93                 :            : 
      94                 :       4592 :     nSttNode = pStt->nNode.GetIndex();
      95                 :       4592 :     nSttCntnt = pStt->nContent.GetIndex();
      96                 :       4592 : }
      97                 :            : 
      98                 :          0 : void SwUndRng::SetPaM( SwPaM & rPam, sal_Bool bCorrToCntnt ) const
      99                 :            : {
     100                 :          0 :     rPam.DeleteMark();
     101                 :          0 :     rPam.GetPoint()->nNode = nSttNode;
     102                 :          0 :     SwNode* pNd = rPam.GetNode();
     103         [ #  # ]:          0 :     if( pNd->IsCntntNode() )
     104         [ #  # ]:          0 :         rPam.GetPoint()->nContent.Assign( pNd->GetCntntNode(), nSttCntnt );
     105         [ #  # ]:          0 :     else if( bCorrToCntnt )
     106                 :          0 :         rPam.Move( fnMoveForward, fnGoCntnt );
     107                 :            :     else
     108                 :          0 :         rPam.GetPoint()->nContent.Assign( 0, 0 );
     109                 :            : 
     110 [ #  # ][ #  # ]:          0 :     if( !nEndNode && STRING_MAXLEN == nEndCntnt )       // no selection
     111                 :          0 :         return ;
     112                 :            : 
     113                 :          0 :     rPam.SetMark();
     114 [ #  # ][ #  # ]:          0 :     if( nSttNode == nEndNode && nSttCntnt == nEndCntnt )
     115                 :          0 :         return;                             // nothing left to do
     116                 :            : 
     117                 :          0 :     rPam.GetPoint()->nNode = nEndNode;
     118         [ #  # ]:          0 :     if( (pNd = rPam.GetNode())->IsCntntNode() )
     119         [ #  # ]:          0 :         rPam.GetPoint()->nContent.Assign( pNd->GetCntntNode(), nEndCntnt );
     120         [ #  # ]:          0 :     else if( bCorrToCntnt )
     121                 :          0 :         rPam.Move( fnMoveBackward, fnGoCntnt );
     122                 :            :     else
     123                 :          0 :         rPam.GetPoint()->nContent.Assign( 0, 0 );
     124                 :            : }
     125                 :            : 
     126                 :          0 : SwPaM & SwUndRng::AddUndoRedoPaM(
     127                 :            :         ::sw::UndoRedoContext & rContext, bool const bCorrToCntnt) const
     128                 :            : {
     129                 :          0 :     SwPaM & rPaM( rContext.GetCursorSupplier().CreateNewShellCursor() );
     130                 :          0 :     SetPaM( rPaM, bCorrToCntnt );
     131                 :          0 :     return rPaM;
     132                 :            : }
     133                 :            : 
     134                 :          2 : void SwUndo::RemoveIdxFromSection( SwDoc& rDoc, sal_uLong nSttIdx,
     135                 :            :                                     sal_uLong* pEndIdx )
     136                 :            : {
     137 [ +  - ][ +  - ]:          2 :     SwNodeIndex aIdx( rDoc.GetNodes(), nSttIdx );
     138         [ +  - ]:          2 :     SwNodeIndex aEndIdx( rDoc.GetNodes(), pEndIdx ? *pEndIdx
     139 [ -  + ][ +  - ]:          4 :                                     : aIdx.GetNode().EndOfSectionIndex() );
     140 [ +  - ][ +  - ]:          2 :     SwPosition aPos( rDoc.GetNodes().GetEndOfPostIts() );
     141 [ +  - ][ +  - ]:          2 :     rDoc.CorrAbs( aIdx, aEndIdx, aPos, sal_True );
         [ +  - ][ +  - ]
     142                 :          2 : }
     143                 :            : 
     144                 :          6 : void SwUndo::RemoveIdxFromRange( SwPaM& rPam, sal_Bool bMoveNext )
     145                 :            : {
     146                 :          6 :     const SwPosition* pEnd = rPam.End();
     147         [ -  + ]:          6 :     if( bMoveNext )
     148                 :            :     {
     149         [ #  # ]:          0 :         if( pEnd != rPam.GetPoint() )
     150                 :          0 :             rPam.Exchange();
     151                 :            : 
     152         [ #  # ]:          0 :         SwNodeIndex aStt( rPam.GetMark()->nNode );
     153         [ #  # ]:          0 :         SwNodeIndex aEnd( rPam.GetPoint()->nNode );
     154                 :            : 
     155 [ #  # ][ #  # ]:          0 :         if( !rPam.Move( fnMoveForward ) )
     156                 :            :         {
     157                 :          0 :             rPam.Exchange();
     158 [ #  # ][ #  # ]:          0 :             if( !rPam.Move( fnMoveBackward ) )
     159                 :            :             {
     160 [ #  # ][ #  # ]:          0 :                 rPam.GetPoint()->nNode = rPam.GetDoc()->GetNodes().GetEndOfPostIts();
     161         [ #  # ]:          0 :                 rPam.GetPoint()->nContent.Assign( 0, 0 );
     162                 :            :             }
     163                 :            :         }
     164                 :            : 
     165 [ #  # ][ #  # ]:          0 :         rPam.GetDoc()->CorrAbs( aStt, aEnd, *rPam.GetPoint(), sal_True );
                 [ #  # ]
     166                 :            :     }
     167                 :            :     else
     168                 :          6 :         rPam.GetDoc()->CorrAbs( rPam, *pEnd, sal_True );
     169                 :          6 : }
     170                 :            : 
     171                 :          0 : void SwUndo::RemoveIdxRel( sal_uLong nIdx, const SwPosition& rPos )
     172                 :            : {
     173                 :            :     // Move only the Crsr. Bookmarks/TOXMarks/etc. are done by the corresponding
     174                 :            :     // JoinNext/JoinPrev
     175         [ #  # ]:          0 :     SwNodeIndex aIdx( rPos.nNode.GetNode().GetNodes(), nIdx );
     176 [ #  # ][ #  # ]:          0 :     ::PaMCorrRel( aIdx, rPos );
     177                 :          0 : }
     178                 :            : 
     179                 :      28429 : SwUndo::SwUndo(SwUndoId const nId)
     180                 :            :     : m_nId(nId), nOrigRedlineMode(nsRedlineMode_t::REDLINE_NONE),
     181                 :      28429 :       bCacheComment(true), pComment(NULL)
     182                 :            : {
     183                 :      28429 : }
     184                 :            : 
     185                 :          4 : bool SwUndo::IsDelBox() const
     186                 :            : {
     187                 :          8 :     return GetId() == UNDO_COL_DELETE || GetId() == UNDO_ROW_DELETE ||
     188         [ +  - ]:          8 :         GetId() == UNDO_TABLE_DELBOX;
           [ +  -  +  - ]
     189                 :            : }
     190                 :            : 
     191                 :      28391 : SwUndo::~SwUndo()
     192                 :            : {
     193 [ +  + ][ +  - ]:      28391 :     delete pComment;
     194         [ -  + ]:      28391 : }
     195                 :            : 
     196                 :            : class UndoRedoRedlineGuard
     197                 :            : {
     198                 :            : public:
     199                 :         14 :     UndoRedoRedlineGuard(::sw::UndoRedoContext & rContext, SwUndo & rUndo)
     200                 :         14 :         : m_rRedlineAccess(rContext.GetDoc())
     201                 :         14 :         , m_eMode(m_rRedlineAccess.GetRedlineMode())
     202                 :            :     {
     203                 :            :         RedlineMode_t const eTmpMode =
     204                 :         14 :             static_cast<RedlineMode_t>(rUndo.GetRedlineMode());
     205         [ -  + ]:         14 :         if ((nsRedlineMode_t::REDLINE_SHOW_MASK & eTmpMode) !=
     206                 :            :             (nsRedlineMode_t::REDLINE_SHOW_MASK & m_eMode))
     207                 :            :         {
     208                 :          0 :             m_rRedlineAccess.SetRedlineMode( eTmpMode );
     209                 :            :         }
     210                 :            :         m_rRedlineAccess.SetRedlineMode_intern( static_cast<RedlineMode_t>(
     211                 :         14 :                 eTmpMode | nsRedlineMode_t::REDLINE_IGNORE) );
     212                 :         14 :     }
     213                 :         14 :     ~UndoRedoRedlineGuard()
     214                 :            :     {
     215                 :         14 :         m_rRedlineAccess.SetRedlineMode(m_eMode);
     216                 :         14 :     }
     217                 :            : private:
     218                 :            :     IDocumentRedlineAccess & m_rRedlineAccess;
     219                 :            :     RedlineMode_t const m_eMode;
     220                 :            : };
     221                 :            : 
     222                 :          0 : void SwUndo::Undo()
     223                 :            : {
     224                 :            :     assert(false); // SwUndo::Undo(): ERROR: must call UndoWithContext instead
     225                 :          0 : }
     226                 :            : 
     227                 :          0 : void SwUndo::Redo()
     228                 :            : {
     229                 :            :     assert(false); // SwUndo::Redo(): ERROR: must call RedoWithContext instead
     230                 :          0 : }
     231                 :            : 
     232                 :         12 : void SwUndo::UndoWithContext(SfxUndoContext & rContext)
     233                 :            : {
     234                 :            :     ::sw::UndoRedoContext *const pContext(
     235         [ -  + ]:         12 :             dynamic_cast< ::sw::UndoRedoContext * >(& rContext));
     236                 :            :     assert(pContext);
     237         [ +  - ]:         24 :     if (!pContext) { return; }
     238         [ +  - ]:         12 :     UndoRedoRedlineGuard const g(*pContext, *this);
     239 [ +  - ][ +  - ]:         12 :     UndoImpl(*pContext);
     240                 :            : }
     241                 :            : 
     242                 :          2 : void SwUndo::RedoWithContext(SfxUndoContext & rContext)
     243                 :            : {
     244                 :            :     ::sw::UndoRedoContext *const pContext(
     245         [ -  + ]:          2 :             dynamic_cast< ::sw::UndoRedoContext * >(& rContext));
     246                 :            :     assert(pContext);
     247         [ +  - ]:          4 :     if (!pContext) { return; }
     248         [ +  - ]:          2 :     UndoRedoRedlineGuard const g(*pContext, *this);
     249 [ +  - ][ +  - ]:          2 :     RedoImpl(*pContext);
     250                 :            : }
     251                 :            : 
     252                 :          0 : void SwUndo::Repeat(SfxRepeatTarget & rContext)
     253                 :            : {
     254                 :            :     ::sw::RepeatContext *const pRepeatContext(
     255         [ #  # ]:          0 :             dynamic_cast< ::sw::RepeatContext * >(& rContext));
     256                 :            :     assert(pRepeatContext);
     257         [ #  # ]:          0 :     if (!pRepeatContext) { return; }
     258                 :          0 :     RepeatImpl(*pRepeatContext);
     259                 :            : }
     260                 :            : 
     261                 :          0 : sal_Bool SwUndo::CanRepeat(SfxRepeatTarget & rContext) const
     262                 :            : {
     263                 :            :     ::sw::RepeatContext *const pRepeatContext(
     264         [ #  # ]:          0 :             dynamic_cast< ::sw::RepeatContext * >(& rContext));
     265                 :            :     assert(pRepeatContext);
     266         [ #  # ]:          0 :     if (!pRepeatContext) { return false; }
     267                 :          0 :     return CanRepeatImpl(*pRepeatContext);
     268                 :            : }
     269                 :            : 
     270                 :          0 : void SwUndo::RepeatImpl( ::sw::RepeatContext & )
     271                 :            : {
     272                 :          0 : }
     273                 :            : 
     274                 :          0 : bool SwUndo::CanRepeatImpl( ::sw::RepeatContext & ) const
     275                 :            : {
     276 [ #  # ][ #  # ]:          0 :     return ((REPEAT_START <= GetId()) && (GetId() < REPEAT_END));
     277                 :            : }
     278                 :            : 
     279                 :      16980 : rtl::OUString SwUndo::GetComment() const
     280                 :            : {
     281         [ +  - ]:      16980 :     String aResult;
     282                 :            : 
     283         [ +  + ]:      16980 :     if (bCacheComment)
     284                 :            :     {
     285         [ +  + ]:       8769 :         if (! pComment)
     286                 :            :         {
     287 [ +  - ][ +  - ]:       8431 :             pComment = new String(SW_RES(UNDO_BASE + GetId()));
                 [ +  - ]
     288                 :            : 
     289         [ +  - ]:       8431 :             SwRewriter aRewriter = GetRewriter();
     290                 :            : 
     291 [ +  - ][ +  - ]:       8431 :             *pComment = aRewriter.Apply(*pComment);
         [ +  - ][ +  - ]
     292                 :            :         }
     293                 :            : 
     294         [ +  - ]:       8769 :         aResult = *pComment;
     295                 :            :     }
     296                 :            :     else
     297                 :            :     {
     298 [ +  - ][ +  - ]:       8211 :         aResult = String(SW_RES(UNDO_BASE + GetId()));
         [ +  - ][ +  - ]
     299                 :            : 
     300         [ +  - ]:       8211 :         SwRewriter aRewriter = GetRewriter();
     301                 :            : 
     302 [ +  - ][ +  - ]:       8211 :         aResult = aRewriter.Apply(aResult);
         [ +  - ][ +  - ]
     303                 :            :     }
     304                 :            : 
     305 [ +  - ][ +  - ]:      16980 :     return aResult;
     306                 :            : }
     307                 :            : 
     308                 :       4486 : SwRewriter SwUndo::GetRewriter() const
     309                 :            : {
     310                 :       4486 :     SwRewriter aResult;
     311                 :            : 
     312                 :       4486 :     return aResult;
     313                 :            : }
     314                 :            : 
     315                 :       8878 : SwUndoSaveCntnt::SwUndoSaveCntnt()
     316                 :       8878 :     : pHistory( 0 )
     317                 :       8878 : {}
     318                 :            : 
     319                 :       8846 : SwUndoSaveCntnt::~SwUndoSaveCntnt()
     320                 :            : {
     321         [ +  + ]:       8846 :     delete pHistory;
     322                 :       8846 : }
     323                 :            : 
     324                 :            : // This is needed when deleting content. For REDO all contents will be moved
     325                 :            : // into the UndoNodesArray. These methods add a seperator for the attributes to
     326                 :            : // the end of TextNodes. As a result, the attributes will not be expanded.
     327                 :            : // - MoveTo   moves from NodesArray into UndoNodesArray
     328                 :            : // - MoveFrom moves from UndoNodesArray into NodesArray
     329                 :            : //
     330                 :            : // If pEndNdIdx is given, Undo/Redo calls -Ins/DelFly. In that case the whole
     331                 :            : // section should be moved.
     332                 :         38 : void SwUndoSaveCntnt::MoveToUndoNds( SwPaM& rPaM, SwNodeIndex* pNodeIdx,
     333                 :            :                     SwIndex* pCntIdx, sal_uLong* pEndNdIdx, xub_StrLen* pEndCntIdx )
     334                 :            : {
     335                 :         38 :     SwDoc& rDoc = *rPaM.GetDoc();
     336 [ +  - ][ +  - ]:         38 :     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
     337                 :            : 
     338                 :         38 :     SwNoTxtNode* pCpyNd = rPaM.GetNode()->GetNoTxtNode();
     339                 :            : 
     340                 :            :     // here comes the actual delete (move)
     341 [ +  - ][ +  - ]:         38 :     SwNodes & rNds = rDoc.GetUndoManager().GetUndoNodes();
     342                 :            :     SwPosition aPos( pEndNdIdx ? rNds.GetEndOfPostIts()
     343 [ +  - ][ +  - ]:         38 :                                : rNds.GetEndOfExtras() );
     344         [ +  - ]:         38 :     aPos.nNode--;
     345                 :            : 
     346 [ +  - ][ +  - ]:         38 :     const SwPosition* pStt = rPaM.Start(), *pEnd = rPaM.End();
     347                 :            : 
     348 [ +  + ][ -  + ]:         38 :     if( pCpyNd || pEndNdIdx || !aPos.nNode.GetNode().GetCntntNode() ||
           [ #  #  #  #  
          #  #  #  #  #  
              # ][ +  - ]
     349                 :          0 :         (!pStt->nContent.GetIndex() && (pStt->nNode != pEnd->nNode ||
     350                 :          0 :                 (!pStt->nNode.GetNode().GetCntntNode() ||
     351         [ #  # ]:          0 :                     pStt->nNode.GetNode().GetCntntNode()->Len() ==
     352                 :          0 :                         pEnd->nContent.GetIndex() ) ) ) )
     353                 :            :     {
     354         [ +  - ]:         38 :         aPos.nNode++;
     355         [ +  - ]:         38 :         aPos.nContent = 0;
     356                 :            :     }
     357                 :            :     else
     358         [ #  # ]:          0 :         aPos.nNode.GetNode().GetCntntNode()->MakeEndIndex( &aPos.nContent );
     359                 :            : 
     360                 :            :     // keep as sal_uInt16; the indices shift!
     361                 :         38 :     sal_uLong nTmpMvNode = aPos.nNode.GetIndex();
     362                 :         38 :     xub_StrLen nTmpMvCntnt = aPos.nContent.GetIndex();
     363                 :            : 
     364 [ +  - ][ +  + ]:         38 :     if( pCpyNd || pEndNdIdx )
     365                 :            :     {
     366         [ +  - ]:         38 :         SwNodeRange aRg( pStt->nNode, 0, pEnd->nNode, 1 );
     367 [ +  - ][ +  - ]:         38 :         rDoc.GetNodes()._MoveNodes( aRg, rNds, aPos.nNode, sal_False );
     368         [ +  - ]:         38 :         aPos.nContent = 0;
     369 [ +  - ][ +  - ]:         38 :         aPos.nNode--;
     370                 :            :     }
     371                 :            :     else
     372                 :            :     {
     373 [ #  # ][ #  # ]:          0 :         rDoc.GetNodes().MoveRange( rPaM, aPos, rNds );
     374                 :            : 
     375                 :          0 :         SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode();
     376         [ #  # ]:          0 :         if( pTxtNd )        // add a seperator for the attributes
     377                 :            :         {
     378                 :            :             // But since all attributes will be touched at an insert (meaning
     379                 :            :             // deleted from the array and re-added again), attributes might
     380                 :            :             // disappear (e.g. "no bold" for 10-20,  "bold" for 12-15 -> when
     381                 :            :             // inserting/deleting, the "bold" will be deleted, which is not
     382                 :            :             // wanted here!)! Thus do not touch the hints but manipulate the
     383                 :            :             // string directly.
     384                 :          0 :             String& rStr = (String&)pTxtNd->GetTxt();
     385                 :            :             // For safety reasons better only if positioned at the end
     386         [ #  # ]:          0 :             if( rStr.Len() == aPos.nContent.GetIndex() )
     387                 :            :             {
     388         [ #  # ]:          0 :                 rStr.Insert( ' ' );
     389         [ #  # ]:          0 :                 ++aPos.nContent;
     390                 :            :             }
     391                 :            :             else
     392                 :            :             {
     393                 :            :                 pTxtNd->InsertText( rtl::OUString(' '), aPos.nContent,
     394 [ #  # ][ #  # ]:          0 :                         IDocumentContentOperations::INS_NOHINTEXPAND );
                 [ #  # ]
     395                 :            :             }
     396                 :            :         }
     397                 :            :     }
     398         [ +  - ]:         38 :     if( pEndNdIdx )
     399                 :         38 :         *pEndNdIdx = aPos.nNode.GetIndex();
     400         [ -  + ]:         38 :     if( pEndCntIdx )
     401                 :          0 :         *pEndCntIdx = aPos.nContent.GetIndex();
     402                 :            : 
     403                 :            :     // old position
     404         [ +  - ]:         38 :     aPos.nNode = nTmpMvNode;
     405         [ +  - ]:         38 :     if( pNodeIdx )
     406         [ +  - ]:         38 :         *pNodeIdx = aPos.nNode;
     407                 :            : 
     408         [ -  + ]:         38 :     if( pCntIdx )
     409                 :            :     {
     410                 :          0 :         SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
     411         [ #  # ]:          0 :         if( pCNd )
     412 [ #  # ][ #  # ]:          0 :             pCntIdx->Assign( pCNd, nTmpMvCntnt );
     413                 :            :         else
     414         [ #  # ]:          0 :             pCntIdx->Assign( 0, 0 );
     415 [ +  - ][ +  - ]:         38 :     }
     416                 :         38 : }
     417                 :            : 
     418                 :          0 : void SwUndoSaveCntnt::MoveFromUndoNds( SwDoc& rDoc, sal_uLong nNodeIdx,
     419                 :            :                             xub_StrLen nCntIdx, SwPosition& rInsPos,
     420                 :            :                             sal_uLong* pEndNdIdx, xub_StrLen* pEndCntIdx )
     421                 :            : {
     422                 :            :     // here comes the recovery
     423 [ #  # ][ #  # ]:          0 :     SwNodes & rNds = rDoc.GetUndoManager().GetUndoNodes();
     424         [ #  # ]:          0 :     if( nNodeIdx == rNds.GetEndOfPostIts().GetIndex() )
     425                 :          0 :         return;     // nothing saved
     426                 :            : 
     427 [ #  # ][ #  # ]:          0 :     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
     428                 :            : 
     429         [ #  # ]:          0 :     SwPaM aPaM( rInsPos );
     430         [ #  # ]:          0 :     if( pEndNdIdx )         // than get the section from it
     431         [ #  # ]:          0 :         aPaM.GetPoint()->nNode.Assign( rNds, *pEndNdIdx );
     432                 :            :     else
     433                 :            :     {
     434         [ #  # ]:          0 :         aPaM.GetPoint()->nNode = rNds.GetEndOfExtras();
     435         [ #  # ]:          0 :         GoInCntnt( aPaM, fnMoveBackward );
     436                 :            :     }
     437                 :            : 
     438                 :          0 :     SwTxtNode* pTxtNd = aPaM.GetNode()->GetTxtNode();
     439 [ #  # ][ #  # ]:          0 :     if( !pEndNdIdx && pTxtNd )  // delete the seperator again
     440                 :            :     {
     441         [ #  # ]:          0 :         if( pEndCntIdx )
     442 [ #  # ][ #  # ]:          0 :             aPaM.GetPoint()->nContent.Assign( pTxtNd, *pEndCntIdx );
     443         [ #  # ]:          0 :         if( pTxtNd->GetTxt().Len() )
     444                 :            :         {
     445         [ #  # ]:          0 :             GoInCntnt( aPaM, fnMoveBackward );
     446         [ #  # ]:          0 :             pTxtNd->EraseText( aPaM.GetPoint()->nContent, 1 );
     447                 :            :         }
     448                 :            : 
     449         [ #  # ]:          0 :         aPaM.SetMark();
     450         [ #  # ]:          0 :         aPaM.GetPoint()->nNode = nNodeIdx;
     451 [ #  # ][ #  # ]:          0 :         aPaM.GetPoint()->nContent.Assign( aPaM.GetCntntNode(), nCntIdx );
     452                 :            : 
     453         [ #  # ]:          0 :         _SaveRedlEndPosForRestore aRedlRest( rInsPos.nNode, rInsPos.nContent.GetIndex() );
     454                 :            : 
     455 [ #  # ][ #  # ]:          0 :         rNds.MoveRange( aPaM, rInsPos, rDoc.GetNodes() );
     456                 :            : 
     457                 :            :         // delete the last Node as well
     458         [ #  # ]:          0 :         if( !aPaM.GetPoint()->nContent.GetIndex() ||
           [ #  #  #  # ]
                 [ #  # ]
     459         [ #  # ]:          0 :             ( aPaM.GetPoint()->nNode++ &&       // still empty Nodes at the end?
     460                 :          0 :             &rNds.GetEndOfExtras() != &aPaM.GetPoint()->nNode.GetNode() ))
     461                 :            :         {
     462         [ #  # ]:          0 :             aPaM.GetPoint()->nContent.Assign( 0, 0 );
     463         [ #  # ]:          0 :             aPaM.SetMark();
     464                 :          0 :             rNds.Delete( aPaM.GetPoint()->nNode,
     465                 :          0 :                         rNds.GetEndOfExtras().GetIndex() -
     466         [ #  # ]:          0 :                         aPaM.GetPoint()->nNode.GetIndex() );
     467                 :            :         }
     468                 :            : 
     469 [ #  # ][ #  # ]:          0 :         aRedlRest.Restore();
     470                 :            :     }
     471 [ #  # ][ #  # ]:          0 :     else if( pEndNdIdx || !pTxtNd )
     472                 :            :     {
     473                 :            :         SwNodeRange aRg( rNds, nNodeIdx, rNds, (pEndNdIdx
     474                 :            :                         ? ((*pEndNdIdx) + 1)
     475 [ #  # ][ #  # ]:          0 :                         : rNds.GetEndOfExtras().GetIndex() ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     476 [ #  # ][ #  # ]:          0 :         rNds._MoveNodes( aRg, rDoc.GetNodes(), rInsPos.nNode, 0 == pEndNdIdx );
                 [ #  # ]
     477                 :            : 
     478                 :            :     }
     479                 :            :     else {
     480                 :            :         OSL_FAIL( "What happened now?" );
     481 [ #  # ][ #  # ]:          0 :     }
     482                 :            : }
     483                 :            : 
     484                 :            : // These two methods move the Point of Pam backwards/forwards. With that, one
     485                 :            : // can span an area for a Undo/Redo. (The Point is then positioned in front of
     486                 :            : // the area to manipulate!)
     487                 :            : // The flag indicates if there is still content in front of Point.
     488                 :          2 : sal_Bool SwUndoSaveCntnt::MovePtBackward( SwPaM& rPam )
     489                 :            : {
     490                 :          2 :     rPam.SetMark();
     491         [ -  + ]:          2 :     if( rPam.Move( fnMoveBackward ))
     492                 :          0 :         return sal_True;
     493                 :            : 
     494                 :            :     // If there is no content onwards, set Point simply to the previous position
     495                 :            :     // (Node and Content, so that Content will be detached!)
     496                 :          2 :     rPam.GetPoint()->nNode--;
     497                 :          2 :     rPam.GetPoint()->nContent.Assign( 0, 0 );
     498                 :          2 :     return sal_False;
     499                 :            : }
     500                 :            : 
     501                 :          2 : void SwUndoSaveCntnt::MovePtForward( SwPaM& rPam, sal_Bool bMvBkwrd )
     502                 :            : {
     503                 :            :     // Was there content before this position?
     504         [ -  + ]:          2 :     if( bMvBkwrd )
     505                 :          0 :         rPam.Move( fnMoveForward );
     506                 :            :     else
     507                 :            :     {
     508                 :          2 :         rPam.GetPoint()->nNode++;
     509                 :          2 :         SwCntntNode* pCNd = rPam.GetCntntNode();
     510         [ +  - ]:          2 :         if( pCNd )
     511                 :          2 :             pCNd->MakeStartIndex( &rPam.GetPoint()->nContent );
     512                 :            :         else
     513                 :          0 :             rPam.Move( fnMoveForward );
     514                 :            :     }
     515                 :          2 : }
     516                 :            : 
     517                 :            : 
     518                 :            : // Delete all objects that have ContentIndices to the given area.
     519                 :            : // Currently (1994) these exist:
     520                 :            : //                  - Footnotes
     521                 :            : //                  - Flys
     522                 :            : //                  - Bookmarks
     523                 :            : //                  - Directories
     524                 :            : //
     525                 :            : // #i81002# - extending method
     526                 :            : // delete certain (not all) cross-reference bookmarks at text node of <rMark>
     527                 :            : // and at text node of <rPoint>, if these text nodes aren't the same.
     528                 :       1092 : void SwUndoSaveCntnt::DelCntntIndex( const SwPosition& rMark,
     529                 :            :                                      const SwPosition& rPoint,
     530                 :            :                                      DelCntntType nDelCntntType )
     531                 :            : {
     532 [ +  - ][ +  + ]:       1092 :     const SwPosition *pStt = rMark < rPoint ? &rMark : &rPoint,
     533         [ +  + ]:       1092 :                     *pEnd = &rMark == pStt ? &rPoint : &rMark;
     534                 :            : 
     535                 :       1092 :     SwDoc* pDoc = rMark.nNode.GetNode().GetDoc();
     536                 :            : 
     537 [ +  - ][ +  - ]:       1092 :     ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
     538                 :            : 
     539                 :            :     // 1. Footnotes
     540         [ +  - ]:       1092 :     if( nsDelCntntType::DELCNT_FTN & nDelCntntType )
     541                 :            :     {
     542                 :       1092 :         SwFtnIdxs& rFtnArr = pDoc->GetFtnIdxs();
     543         [ +  + ]:       1092 :         if( !rFtnArr.empty() )
     544                 :            :         {
     545                 :            :             const SwNode* pFtnNd;
     546                 :            :             sal_uInt16 nPos;
     547         [ +  - ]:        150 :             rFtnArr.SeekEntry( pStt->nNode, &nPos );
     548                 :            :             SwTxtFtn* pSrch;
     549                 :            : 
     550                 :            :             // for now delete all that come afterwards
     551   [ +  +  +  + ]:        310 :             while( nPos < rFtnArr.size() && ( pFtnNd =
                 [ +  + ]
     552 [ +  - ][ +  - ]:        124 :                 &( pSrch = rFtnArr[ nPos ] )->GetTxtNode())->GetIndex()
     553                 :        124 :                         <= pEnd->nNode.GetIndex() )
     554                 :            :             {
     555                 :         36 :                 xub_StrLen nFtnSttIdx = *pSrch->GetStart();
     556 [ +  + ][ -  +  :        168 :                 if( (nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
          +  -  +  +  +  
                -  +  + ]
     557                 :          0 :                     ? (&pEnd->nNode.GetNode() == pFtnNd )
     558                 :         36 :                     : (( &pStt->nNode.GetNode() == pFtnNd &&
     559                 :         36 :                     pStt->nContent.GetIndex() > nFtnSttIdx) ||
     560                 :         30 :                     ( &pEnd->nNode.GetNode() == pFtnNd &&
     561                 :         30 :                     nFtnSttIdx >= pEnd->nContent.GetIndex() )) )
     562                 :            :                 {
     563                 :         10 :                     ++nPos;     // continue searching
     564                 :         10 :                     continue;
     565                 :            :                 }
     566                 :            : 
     567                 :            : // FIXME: duplicated code here and below -> refactor?
     568                 :            :                 // Unfortunately an index needs to be created. Otherwise there
     569                 :            :                 // will be problems with TextNode because the index will be
     570                 :            :                 // deleted in the DTOR of SwFtn!
     571         [ +  - ]:         26 :                 SwTxtNode* pTxtNd = (SwTxtNode*)pFtnNd;
     572         [ -  + ]:         26 :                 if( !pHistory )
     573 [ #  # ][ #  # ]:          0 :                     pHistory = new SwHistory;
     574                 :            :                 SwTxtAttr* const pFtnHnt =
     575         [ +  - ]:         26 :                     pTxtNd->GetTxtAttrForCharAt( nFtnSttIdx );
     576                 :            :                 assert(pFtnHnt);
     577 [ +  - ][ +  - ]:         26 :                 SwIndex aIdx( pTxtNd, nFtnSttIdx );
     578         [ +  - ]:         26 :                 pHistory->Add( pFtnHnt, pTxtNd->GetIndex(), false );
     579         [ +  - ]:         26 :                 pTxtNd->EraseText( aIdx, 1 );
     580         [ +  - ]:         26 :             }
     581                 :            : 
     582         [ +  + ]:        214 :             while( nPos-- && ( pFtnNd = &( pSrch = rFtnArr[ nPos ] )->
           [ +  -  +  + ]
                 [ +  + ]
     583         [ +  - ]:         54 :                     GetTxtNode())->GetIndex() >= pStt->nNode.GetIndex() )
     584                 :            :             {
     585                 :         10 :                 xub_StrLen nFtnSttIdx = *pSrch->GetStart();
     586 [ +  - ][ +  -  :         38 :                 if( !(nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType) && (
          +  -  +  +  +  
                -  +  - ]
     587                 :         10 :                     ( &pStt->nNode.GetNode() == pFtnNd &&
     588                 :         10 :                     pStt->nContent.GetIndex() > nFtnSttIdx ) ||
     589                 :          4 :                     ( &pEnd->nNode.GetNode() == pFtnNd &&
     590                 :          4 :                     nFtnSttIdx >= pEnd->nContent.GetIndex() )))
     591                 :         10 :                     continue;               // continue searching
     592                 :            : 
     593                 :            :                 // Unfortunately an index needs to be created. Otherwise there
     594                 :            :                 // will be problems with TextNode because the index will be
     595                 :            :                 // deleted in the DTOR of SwFtn!
     596         [ #  # ]:          0 :                 SwTxtNode* pTxtNd = (SwTxtNode*)pFtnNd;
     597         [ #  # ]:          0 :                 if( !pHistory )
     598 [ #  # ][ #  # ]:          0 :                     pHistory = new SwHistory;
     599                 :            :                 SwTxtAttr* const pFtnHnt =
     600         [ #  # ]:          0 :                     pTxtNd->GetTxtAttrForCharAt( nFtnSttIdx );
     601                 :            :                 assert(pFtnHnt);
     602 [ #  # ][ #  # ]:          0 :                 SwIndex aIdx( pTxtNd, nFtnSttIdx );
     603         [ #  # ]:          0 :                 pHistory->Add( pFtnHnt, pTxtNd->GetIndex(), false );
     604         [ #  # ]:          0 :                 pTxtNd->EraseText( aIdx, 1 );
     605         [ #  # ]:          0 :             }
     606                 :            :         }
     607                 :            :     }
     608                 :            : 
     609                 :            :     // 2. Flys
     610         [ +  - ]:       1092 :     if( nsDelCntntType::DELCNT_FLY & nDelCntntType )
     611                 :            :     {
     612         [ +  + ]:       1092 :         sal_uInt16 nChainInsPos = pHistory ? pHistory->Count() : 0;
     613                 :       1092 :         const SwFrmFmts& rSpzArr = *pDoc->GetSpzFrmFmts();
     614         [ +  + ]:       1092 :         if( !rSpzArr.empty() )
     615                 :            :         {
     616                 :        110 :             const sal_Bool bDelFwrd = rMark.nNode.GetIndex() <= rPoint.nNode.GetIndex();
     617                 :            :             SwFlyFrmFmt* pFmt;
     618                 :            :             const SwFmtAnchor* pAnchor;
     619                 :        110 :             sal_uInt16 n = rSpzArr.size();
     620                 :            :             const SwPosition* pAPos;
     621                 :            : 
     622 [ +  + ][ +  - ]:       1300 :             while( n && !rSpzArr.empty() )
                 [ +  + ]
     623                 :            :             {
     624         [ +  - ]:        208 :                 pFmt = (SwFlyFrmFmt*)rSpzArr[--n];
     625         [ +  - ]:        208 :                 pAnchor = &pFmt->GetAnchor();
     626   [ +  +  -  -  :        208 :                 switch( pAnchor->GetAnchorId() )
                      + ]
     627                 :            :                 {
     628                 :            :                 case FLY_AS_CHAR:
     629 [ +  - ][ +  - ]:         12 :                     if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
           [ -  +  #  #  
           #  # ][ +  - ]
         [ -  + ][ -  + ]
     630                 :            :                         (( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
     631                 :          0 :                         ? ( pStt->nNode <= pAPos->nNode &&
     632                 :          0 :                             pAPos->nNode < pEnd->nNode )
     633 [ +  - ][ +  - ]:          8 :                         : ( *pStt <= *pAPos && *pAPos < *pEnd )) )
     634                 :            :                     {
     635         [ #  # ]:          0 :                         if( !pHistory )
     636 [ #  # ][ #  # ]:          0 :                             pHistory = new SwHistory;
     637                 :            :                         SwTxtNode *const pTxtNd =
     638                 :          0 :                             pAPos->nNode.GetNode().GetTxtNode();
     639                 :            :                         SwTxtAttr* const pFlyHnt = pTxtNd->GetTxtAttrForCharAt(
     640         [ #  # ]:          0 :                             pAPos->nContent.GetIndex());
     641                 :            :                         assert(pFlyHnt);
     642         [ #  # ]:          0 :                         pHistory->Add( pFlyHnt, 0, false );
     643                 :            :                         // reset n so that no Format is skipped
     644         [ #  # ]:          0 :                         n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
     645                 :            :                     }
     646                 :          4 :                     break;
     647                 :            :                 case FLY_AT_PARA:
     648                 :            :                     {
     649         [ +  - ]:         94 :                         pAPos =  pAnchor->GetCntntAnchor();
     650         [ +  - ]:         94 :                         if( pAPos )
     651                 :            :                         {
     652                 :            :                             bool bTmp;
     653         [ -  + ]:         94 :                             if( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
     654 [ #  # ][ #  # ]:          0 :                                 bTmp = pStt->nNode <= pAPos->nNode && pAPos->nNode < pEnd->nNode;
     655                 :            :                             else
     656                 :            :                             {
     657         [ +  - ]:         94 :                                 if (bDelFwrd)
     658                 :         94 :                                     bTmp = rMark.nNode < pAPos->nNode &&
     659 [ -  + ][ +  + ]:         94 :                                         pAPos->nNode <= rPoint.nNode;
     660                 :            :                                 else
     661                 :          0 :                                     bTmp = rPoint.nNode <= pAPos->nNode &&
     662 [ #  # ][ #  # ]:          0 :                                         pAPos->nNode < rMark.nNode;
     663                 :            :                             }
     664                 :            : 
     665         [ -  + ]:         94 :                             if (bTmp)
     666                 :            :                             {
     667         [ #  # ]:          0 :                                 if( !pHistory )
     668 [ #  # ][ #  # ]:          0 :                                     pHistory = new SwHistory;
     669                 :            : 
     670                 :            :                                 // Moving the anchor?
     671   [ #  #  #  # ]:          0 :                                 if( !( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType ) &&
                 [ #  # ]
     672                 :          0 :                                     ( rPoint.nNode.GetIndex() == pAPos->nNode.GetIndex() ) )
     673                 :            :                                 {
     674                 :            :                                     // Do not try to move the anchor to a table!
     675         [ #  # ]:          0 :                                     if( rMark.nNode.GetNode().GetTxtNode() )
     676                 :            :                                     {
     677         [ #  # ]:          0 :                                         pHistory->Add( *pFmt );
     678         [ #  # ]:          0 :                                         SwFmtAnchor aAnch( *pAnchor );
     679         [ #  # ]:          0 :                                         SwPosition aPos( rMark.nNode );
     680         [ #  # ]:          0 :                                         aAnch.SetAnchor( &aPos );
     681 [ #  # ][ #  # ]:          0 :                                         pFmt->SetFmtAttr( aAnch );
                 [ #  # ]
     682                 :            :                                     }
     683                 :            :                                 }
     684                 :            :                                 else
     685                 :            :                                 {
     686         [ #  # ]:          0 :                                     pHistory->Add( *pFmt, nChainInsPos );
     687                 :            :                                     // reset n so that no Format is skipped
     688                 :          0 :                                     n = n >= rSpzArr.size() ?
     689         [ #  # ]:          0 :                                         rSpzArr.size() : n+1;
     690                 :            :                                 }
     691                 :            :                             }
     692                 :            :                         }
     693                 :            :                     }
     694                 :         94 :                     break;
     695                 :            :                 case FLY_AT_CHAR:
     696 [ #  # ][ #  #  :          0 :                     if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
             #  #  #  # ]
                 [ #  # ]
     697                 :          0 :                         ( pStt->nNode <= pAPos->nNode && pAPos->nNode <= pEnd->nNode ) )
     698                 :            :                     {
     699         [ #  # ]:          0 :                         if( !pHistory )
     700 [ #  # ][ #  # ]:          0 :                             pHistory = new SwHistory;
     701         [ #  # ]:          0 :                         if (IsDestroyFrameAnchoredAtChar(
     702                 :          0 :                                 *pAPos, *pStt, *pEnd, nDelCntntType))
     703                 :            :                         {
     704         [ #  # ]:          0 :                             pHistory->Add( *pFmt, nChainInsPos );
     705         [ #  # ]:          0 :                             n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
     706                 :            :                         }
     707         [ #  # ]:          0 :                         else if( !( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType ) )
     708                 :            :                         {
     709 [ #  # ][ #  # ]:          0 :                             if( *pStt <= *pAPos && *pAPos < *pEnd )
         [ #  # ][ #  # ]
                 [ #  # ]
     710                 :            :                             {
     711                 :            :                                 // These are the objects anchored
     712                 :            :                                 // between section start and end position
     713                 :            :                                 // Do not try to move the anchor to a table!
     714         [ #  # ]:          0 :                                 if( rMark.nNode.GetNode().GetTxtNode() )
     715                 :            :                                 {
     716         [ #  # ]:          0 :                                     pHistory->Add( *pFmt );
     717         [ #  # ]:          0 :                                     SwFmtAnchor aAnch( *pAnchor );
     718         [ #  # ]:          0 :                                     aAnch.SetAnchor( &rMark );
     719 [ #  # ][ #  # ]:          0 :                                     pFmt->SetFmtAttr( aAnch );
     720                 :            :                                 }
     721                 :            :                             }
     722                 :            :                         }
     723                 :            :                     }
     724                 :          0 :                     break;
     725                 :            :                 case FLY_AT_FLY:
     726                 :            : 
     727         [ #  # ]:          0 :                     if( 0 != (pAPos = pAnchor->GetCntntAnchor() ) &&
           [ #  #  #  # ]
                 [ #  # ]
     728                 :          0 :                         pStt->nNode == pAPos->nNode )
     729                 :            :                     {
     730         [ #  # ]:          0 :                         if( !pHistory )
     731 [ #  # ][ #  # ]:          0 :                             pHistory = new SwHistory;
     732                 :            : 
     733         [ #  # ]:          0 :                         pHistory->Add( *pFmt, nChainInsPos );
     734                 :            : 
     735                 :            :                         // reset n so that no Format is skipped
     736         [ #  # ]:          0 :                         n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
     737                 :            :                     }
     738                 :          0 :                     break;
     739                 :        110 :                 default: break;
     740                 :            :                 }
     741                 :            :             }
     742                 :            :         }
     743                 :            :     }
     744                 :            : 
     745                 :            :     // 3. Bookmarks
     746         [ +  - ]:       1092 :     if( nsDelCntntType::DELCNT_BKM & nDelCntntType )
     747                 :            :     {
     748         [ +  - ]:       1092 :         IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
     749 [ +  - ][ +  + ]:       1092 :         if( pMarkAccess->getMarksCount() )
     750                 :            :         {
     751                 :            : 
     752 [ +  - ][ +  + ]:     726416 :             for( sal_uInt16 n = 0; n < pMarkAccess->getMarksCount(); ++n )
     753                 :            :             {
     754                 :            :                 // #i81002#
     755                 :     725610 :                 bool bSavePos = false;
     756                 :     725610 :                 bool bSaveOtherPos = false;
     757 [ +  - ][ +  - ]:     725610 :                 const ::sw::mark::IMark* pBkmk = (pMarkAccess->getMarksBegin() + n)->get();
     758         [ -  + ]:     725610 :                 if( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
     759                 :            :                 {
     760         [ #  # ]:          0 :                     if( pStt->nNode <= pBkmk->GetMarkPos().nNode &&
           [ #  #  #  # ]
                 [ #  # ]
     761         [ #  # ]:          0 :                         pBkmk->GetMarkPos().nNode < pEnd->nNode )
     762                 :          0 :                         bSavePos = true;
     763 [ #  # ][ #  #  :          0 :                     if( pBkmk->IsExpanded() &&
             #  #  #  # ]
                 [ #  # ]
     764         [ #  # ]:          0 :                         pStt->nNode <= pBkmk->GetOtherMarkPos().nNode &&
     765         [ #  # ]:          0 :                         pBkmk->GetOtherMarkPos().nNode < pEnd->nNode )
     766                 :          0 :                         bSaveOtherPos = true;
     767                 :            :                 }
     768                 :            :                 else
     769                 :            :                 {
     770                 :            :                     // #i92125#
     771                 :     725610 :                     bool bKeepCrossRefBkmk( false );
     772                 :            :                     {
     773 [ +  + ][ +  - ]:    2159408 :                         if ( rMark.nNode == rPoint.nNode &&
         [ -  + ][ -  + ]
     774         [ +  - ]:     716899 :                              ( IDocumentMarkAccess::GetType(*pBkmk) ==
     775                 :            :                                 IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK ||
     776         [ +  - ]:     716899 :                                IDocumentMarkAccess::GetType(*pBkmk) ==
     777                 :            :                                 IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK ) )
     778                 :            :                         {
     779                 :          0 :                             bKeepCrossRefBkmk = true;
     780                 :            :                         }
     781                 :            :                     }
     782         [ +  - ]:     725610 :                     if ( !bKeepCrossRefBkmk )
     783                 :            :                     {
     784                 :     725610 :                         bool bMaybe = false;
     785 [ +  - ][ +  - ]:     725610 :                         if ( *pStt <= pBkmk->GetMarkPos() && pBkmk->GetMarkPos() <= *pEnd )
         [ +  + ][ +  - ]
         [ +  - ][ +  + ]
                 [ +  + ]
     786                 :            :                         {
     787 [ +  - ][ +  - ]:       1172 :                             if( pBkmk->GetMarkPos() == *pEnd ||
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     788 [ +  - ][ +  - ]:        651 :                                 ( *pStt == pBkmk->GetMarkPos() && pBkmk->IsExpanded() ) )
                 [ +  - ]
     789                 :        196 :                                 bMaybe = true;
     790                 :            :                             else
     791                 :        325 :                                 bSavePos = true;
     792                 :            :                         }
     793 [ +  - ][ +  + ]:    1728125 :                         if( pBkmk->IsExpanded() &&
         [ +  + ][ +  + ]
                 [ +  + ]
     794 [ +  - ][ +  - ]:    1002515 :                             *pStt <= pBkmk->GetOtherMarkPos() && pBkmk->GetOtherMarkPos() <= *pEnd )
         [ +  - ][ +  - ]
     795                 :            :                         {
     796 [ +  + ][ +  - ]:       1171 :                             if( bSavePos || bSaveOtherPos ||
         [ +  + ][ +  + ]
                 [ +  + ]
     797 [ +  - ][ +  - ]:        679 :                                 ( pBkmk->GetOtherMarkPos() < *pEnd && pBkmk->GetOtherMarkPos() > *pStt ) )
         [ +  - ][ +  - ]
     798                 :            :                             {
     799         [ +  + ]:        364 :                                 if( bMaybe )
     800                 :         64 :                                     bSavePos = true;
     801                 :        364 :                                 bSaveOtherPos = true;
     802                 :            :                             }
     803                 :            :                         }
     804                 :            :                     }
     805                 :            : 
     806                 :            :                     // #i81002#
     807                 :            :                     const bool bDifferentTxtNodesAtMarkAndPoint(
     808                 :     725610 :                                         rMark.nNode != rPoint.nNode &&
     809                 :       8711 :                                         rMark.nNode.GetNode().GetTxtNode() &&
     810         [ +  - ]:     734321 :                                         rPoint.nNode.GetNode().GetTxtNode() );
           [ +  +  +  + ]
     811 [ +  + ][ +  + ]:     734297 :                     if( !bSavePos && !bSaveOtherPos && bDifferentTxtNodesAtMarkAndPoint &&
         [ +  + ][ +  - ]
                 [ -  + ]
     812         [ -  + ]:       8687 :                         dynamic_cast< const ::sw::mark::CrossRefBookmark* >(pBkmk))
     813                 :            :                     {
     814                 :            :                         // delete cross-reference bookmark at <pStt>, if only
     815                 :            :                         // part of <pEnd> text node content is deleted.
     816 [ #  # ][ #  # ]:          0 :                         if( pStt->nNode == pBkmk->GetMarkPos().nNode &&
         [ #  # ][ #  # ]
     817                 :          0 :                             pEnd->nContent.GetIndex() !=
     818         [ #  # ]:          0 :                                 pEnd->nNode.GetNode().GetTxtNode()->Len() )
     819                 :            :                         {
     820                 :          0 :                             bSavePos = true;
     821                 :          0 :                             bSaveOtherPos = false;
     822                 :            :                         }
     823                 :            :                         // delete cross-reference bookmark at <pEnd>, if only
     824                 :            :                         // part of <pStt> text node content is deleted.
     825         [ #  # ]:          0 :                         else if( pEnd->nNode == pBkmk->GetMarkPos().nNode &&
           [ #  #  #  # ]
                 [ #  # ]
     826                 :          0 :                             pStt->nContent.GetIndex() != 0 )
     827                 :            :                         {
     828                 :          0 :                             bSavePos = true;
     829                 :          0 :                             bSaveOtherPos = false;
     830                 :            :                         }
     831                 :            :                     }
     832                 :            :                 }
     833 [ +  + ][ +  + ]:     725610 :                 if( bSavePos || bSaveOtherPos )
     834                 :            :                 {
     835         [ -  + ]:        578 :                     if( !pHistory )
     836 [ #  # ][ #  # ]:          0 :                         pHistory = new SwHistory;
     837                 :            : 
     838         [ +  - ]:        578 :                     pHistory->Add( *pBkmk, bSavePos, bSaveOtherPos );
     839 [ +  + ][ +  + ]:        792 :                     if(bSavePos &&
         [ +  + ][ +  + ]
     840         [ +  - ]:        214 :                         (bSaveOtherPos || !pBkmk->IsExpanded()))
     841                 :            :                     {
     842 [ +  - ][ +  - ]:        187 :                         pMarkAccess->deleteMark(pMarkAccess->getMarksBegin()+n);
                 [ +  - ]
     843                 :        187 :                         n--;
     844                 :            :                     }
     845                 :            :                 }
     846                 :            :             }
     847                 :            :         }
     848         [ +  - ]:       1092 :     }
     849                 :       1092 : }
     850                 :            : 
     851                 :            : // save a complete section into UndoNodes array
     852                 :        602 : SwUndoSaveSection::SwUndoSaveSection()
     853                 :        602 :     : pMvStt( 0 ), pRedlSaveData( 0 ), nMvLen( 0 ), nStartPos( ULONG_MAX )
     854                 :            : {
     855                 :        602 : }
     856                 :            : 
     857                 :        602 : SwUndoSaveSection::~SwUndoSaveSection()
     858                 :            : {
     859         [ +  + ]:        602 :     if( pMvStt )        // delete also the section from UndoNodes array
     860                 :            :     {
     861                 :            :         // SaveSection saves the content in the PostIt section.
     862                 :         38 :         SwNodes& rUNds = pMvStt->GetNode().GetNodes();
     863         [ +  - ]:         38 :         rUNds.Delete( *pMvStt, nMvLen );
     864                 :            : 
     865 [ +  - ][ +  - ]:         38 :         delete pMvStt;
     866                 :            :     }
     867 [ -  + ][ #  # ]:        602 :     delete pRedlSaveData;
     868                 :        602 : }
     869                 :            : 
     870                 :         38 : void SwUndoSaveSection::SaveSection( SwDoc* pDoc, const SwNodeIndex& rSttIdx )
     871                 :            : {
     872 [ +  - ][ +  - ]:         38 :     SwNodeRange aRg( rSttIdx.GetNode(), *rSttIdx.GetNode().EndOfSectionNode() );
         [ +  - ][ +  - ]
                 [ +  - ]
     873 [ +  - ][ +  - ]:         38 :     SaveSection( pDoc, aRg );
     874                 :         38 : }
     875                 :            : 
     876                 :         38 : void SwUndoSaveSection::SaveSection( SwDoc* , const SwNodeRange& rRange )
     877                 :            : {
     878         [ +  - ]:         38 :     SwPaM aPam( rRange.aStart, rRange.aEnd );
     879                 :            : 
     880                 :            :     // delete all Footnotes / FlyFrames / Bookmarks / Directories
     881         [ +  - ]:         38 :     DelCntntIndex( *aPam.GetMark(), *aPam.GetPoint() );
     882                 :            : 
     883 [ +  - ][ +  - ]:         38 :     pRedlSaveData = new SwRedlineSaveDatas;
     884 [ +  - ][ +  - ]:         38 :     if( !SwUndo::FillSaveData( aPam, *pRedlSaveData, sal_True, sal_True ))
     885 [ +  - ][ +  - ]:         38 :         delete pRedlSaveData, pRedlSaveData = 0;
     886                 :            : 
     887                 :         38 :     nStartPos = rRange.aStart.GetIndex();
     888                 :            : 
     889         [ +  - ]:         38 :     aPam.GetPoint()->nNode--;
     890         [ +  - ]:         38 :     aPam.GetMark()->nNode++;
     891                 :            : 
     892                 :         38 :     SwCntntNode* pCNd = aPam.GetCntntNode( sal_False );
     893         [ +  - ]:         38 :     if( pCNd )
     894 [ +  - ][ +  - ]:         38 :         aPam.GetMark()->nContent.Assign( pCNd, 0 );
     895         [ +  - ]:         38 :     if( 0 != ( pCNd = aPam.GetCntntNode( sal_True )) )
     896 [ +  - ][ +  - ]:         38 :         aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
                 [ +  - ]
     897                 :            : 
     898                 :            :     // Keep positions as SwIndex so that this section can be deleted in DTOR
     899                 :            :     sal_uLong nEnd;
     900 [ +  - ][ +  - ]:         38 :     pMvStt = new SwNodeIndex( rRange.aStart );
     901         [ +  - ]:         38 :     MoveToUndoNds( aPam, pMvStt, 0, &nEnd, 0 );
     902         [ +  - ]:         38 :     nMvLen = nEnd - pMvStt->GetIndex() + 1;
     903                 :         38 : }
     904                 :            : 
     905                 :          0 : void SwUndoSaveSection::RestoreSection( SwDoc* pDoc, SwNodeIndex* pIdx,
     906                 :            :                                         sal_uInt16 nSectType )
     907                 :            : {
     908         [ #  # ]:          0 :     if( ULONG_MAX != nStartPos )        // was there any content?
     909                 :            :     {
     910                 :            :         // check if the content is at the old position
     911 [ #  # ][ #  # ]:          0 :         SwNodeIndex aSttIdx( pDoc->GetNodes(), nStartPos );
     912                 :            : 
     913                 :            :         // move the content from UndoNodes array into Fly
     914         [ #  # ]:          0 :         SwStartNode* pSttNd = pDoc->GetNodes().MakeEmptySection( aSttIdx,
     915         [ #  # ]:          0 :                                                 (SwStartNodeType)nSectType );
     916                 :            : 
     917 [ #  # ][ #  # ]:          0 :         RestoreSection( pDoc, SwNodeIndex( *pSttNd->EndOfSectionNode() ));
                 [ #  # ]
     918                 :            : 
     919         [ #  # ]:          0 :         if( pIdx )
     920 [ #  # ][ #  # ]:          0 :             *pIdx = *pSttNd;
     921                 :            :     }
     922                 :          0 : }
     923                 :            : 
     924                 :          0 : void SwUndoSaveSection::RestoreSection( SwDoc* pDoc, const SwNodeIndex& rInsPos )
     925                 :            : {
     926         [ #  # ]:          0 :     if( ULONG_MAX != nStartPos )        // was there any content?
     927                 :            :     {
     928         [ #  # ]:          0 :         SwPosition aInsPos( rInsPos );
     929                 :          0 :         sal_uLong nEnd = pMvStt->GetIndex() + nMvLen - 1;
     930         [ #  # ]:          0 :         MoveFromUndoNds( *pDoc, pMvStt->GetIndex(), 0, aInsPos, &nEnd, 0 );
     931                 :            : 
     932                 :            :         // destroy indices again, content was deleted from UndoNodes array
     933 [ #  # ][ #  # ]:          0 :         DELETEZ( pMvStt );
     934                 :          0 :         nMvLen = 0;
     935                 :            : 
     936         [ #  # ]:          0 :         if( pRedlSaveData )
     937                 :            :         {
     938         [ #  # ]:          0 :             SwUndo::SetSaveData( *pDoc, *pRedlSaveData );
     939 [ #  # ][ #  # ]:          0 :             delete pRedlSaveData, pRedlSaveData = 0;
     940         [ #  # ]:          0 :         }
     941                 :            :     }
     942                 :          0 : }
     943                 :            : 
     944                 :            : // save and set the RedlineData
     945                 :          0 : SwRedlineSaveData::SwRedlineSaveData( SwComparePosition eCmpPos,
     946                 :            :                                         const SwPosition& rSttPos,
     947                 :            :                                         const SwPosition& rEndPos,
     948                 :            :                                         SwRedline& rRedl,
     949                 :            :                                         sal_Bool bCopyNext )
     950                 :            :     : SwUndRng( rRedl ),
     951         [ #  # ]:          0 :     SwRedlineData( rRedl.GetRedlineData(), bCopyNext )
     952                 :            : {
     953                 :            :     assert( POS_OUTSIDE == eCmpPos ||
     954                 :            :             !rRedl.GetContentIdx() ); // "Redline with Content"
     955                 :            : 
     956   [ #  #  #  #  :          0 :     switch( eCmpPos )
                   #  # ]
     957                 :            :     {
     958                 :            :     case POS_OVERLAP_BEFORE:        // Pos1 overlaps Pos2 at the beginning
     959                 :          0 :         nEndNode = rEndPos.nNode.GetIndex();
     960                 :          0 :         nEndCntnt = rEndPos.nContent.GetIndex();
     961                 :          0 :         break;
     962                 :            :     case POS_OVERLAP_BEHIND:        // Pos1 overlaps Pos2 at the end
     963                 :          0 :         nSttNode = rSttPos.nNode.GetIndex();
     964                 :          0 :         nSttCntnt = rSttPos.nContent.GetIndex();
     965                 :          0 :         break;
     966                 :            : 
     967                 :            :     case POS_INSIDE:                // Pos1 lays completely in Pos2
     968                 :          0 :         nSttNode = rSttPos.nNode.GetIndex();
     969                 :          0 :         nSttCntnt = rSttPos.nContent.GetIndex();
     970                 :          0 :         nEndNode = rEndPos.nNode.GetIndex();
     971                 :          0 :         nEndCntnt = rEndPos.nContent.GetIndex();
     972                 :          0 :         break;
     973                 :            : 
     974                 :            :     case POS_OUTSIDE:               // Pos2 lays completely in Pos1
     975         [ #  # ]:          0 :         if( rRedl.GetContentIdx() )
     976                 :            :         {
     977                 :            :             // than move section into UndoArray and memorize it
     978         [ #  # ]:          0 :             SaveSection( rRedl.GetDoc(), *rRedl.GetContentIdx() );
     979         [ #  # ]:          0 :             rRedl.SetContentIdx( 0 );
     980                 :            :         }
     981                 :          0 :         break;
     982                 :            : 
     983                 :            :     case POS_EQUAL:                 // Pos1 ist exactly as big as Pos2
     984                 :          0 :         break;
     985                 :            : 
     986                 :            :     default:
     987                 :            :         assert(false);
     988                 :            :     }
     989                 :            : 
     990                 :            : #if OSL_DEBUG_LEVEL > 0
     991                 :            :     nRedlineCount = rSttPos.nNode.GetNode().GetDoc()->GetRedlineTbl().size();
     992                 :            : #endif
     993                 :          0 : }
     994                 :            : 
     995         [ #  # ]:          0 : SwRedlineSaveData::~SwRedlineSaveData()
     996                 :            : {
     997                 :          0 : }
     998                 :            : 
     999                 :          0 : void SwRedlineSaveData::RedlineToDoc( SwPaM& rPam )
    1000                 :            : {
    1001                 :          0 :     SwDoc& rDoc = *rPam.GetDoc();
    1002         [ #  # ]:          0 :     SwRedline* pRedl = new SwRedline( *this, rPam );
    1003                 :            : 
    1004         [ #  # ]:          0 :     if( GetMvSttIdx() )
    1005                 :            :     {
    1006 [ #  # ][ #  # ]:          0 :         SwNodeIndex aIdx( rDoc.GetNodes() );
    1007         [ #  # ]:          0 :         RestoreSection( &rDoc, &aIdx, SwNormalStartNode );
    1008         [ #  # ]:          0 :         if( GetHistory() )
    1009         [ #  # ]:          0 :             GetHistory()->Rollback( &rDoc );
    1010 [ #  # ][ #  # ]:          0 :         pRedl->SetContentIdx( &aIdx );
    1011                 :            :     }
    1012                 :          0 :     SetPaM( *pRedl );
    1013                 :            :     // First, delete the "old" so that in an Append no unexpected things will
    1014                 :            :     // happen, e.g. a delete in an insert. In the latter case the just restored
    1015                 :            :     // content will be deleted and not the one you originally wanted.
    1016                 :          0 :     rDoc.DeleteRedline( *pRedl, false, USHRT_MAX );
    1017                 :            : 
    1018                 :          0 :     RedlineMode_t eOld = rDoc.GetRedlineMode();
    1019                 :          0 :     rDoc.SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_DONTCOMBINE_REDLINES));
    1020                 :            :     //#i92154# let UI know about a new redline with comment
    1021 [ #  # ][ #  # ]:          0 :     if (rDoc.GetDocShell() && (pRedl->GetComment() != String()) )
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
    1022         [ #  # ]:          0 :         rDoc.GetDocShell()->Broadcast(SwRedlineHint(pRedl,SWREDLINE_INSERTED));
    1023                 :            : 
    1024                 :          0 :     bool const bSuccess = rDoc.AppendRedline( pRedl, true );
    1025                 :            :     assert(bSuccess); // SwRedlineSaveData::RedlineToDoc: insert redline failed
    1026                 :            :     (void) bSuccess; // unused in non-debug
    1027                 :          0 :     rDoc.SetRedlineMode_intern( eOld );
    1028                 :          0 : }
    1029                 :            : 
    1030                 :         46 : sal_Bool SwUndo::FillSaveData( const SwPaM& rRange, SwRedlineSaveDatas& rSData,
    1031                 :            :                             sal_Bool bDelRange, sal_Bool bCopyNext )
    1032                 :            : {
    1033         [ +  - ]:         46 :     rSData.DeleteAndDestroyAll();
    1034                 :            : 
    1035                 :            :     SwRedlineSaveData* pNewData;
    1036 [ +  - ][ +  - ]:         46 :     const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
    1037         [ +  - ]:         46 :     const SwRedlineTbl& rTbl = rRange.GetDoc()->GetRedlineTbl();
    1038                 :         46 :     sal_uInt16 n = 0;
    1039         [ +  - ]:         46 :     rRange.GetDoc()->GetRedline( *pStt, &n );
    1040         [ -  + ]:         46 :     for( ; n < rTbl.size(); ++n )
    1041                 :            :     {
    1042         [ #  # ]:          0 :         SwRedline* pRedl = rTbl[ n ];
    1043 [ #  # ][ #  # ]:          0 :         const SwPosition *pRStt = pRedl->Start(), *pREnd = pRedl->End();
    1044                 :            : 
    1045         [ #  # ]:          0 :         SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
    1046 [ #  # ][ #  # ]:          0 :         if( POS_BEFORE != eCmpPos && POS_BEHIND != eCmpPos &&
         [ #  # ][ #  # ]
    1047                 :            :             POS_COLLIDE_END != eCmpPos && POS_COLLIDE_START != eCmpPos )
    1048                 :            :         {
    1049                 :            :             pNewData = new SwRedlineSaveData( eCmpPos, *pStt, *pEnd,
    1050 [ #  # ][ #  # ]:          0 :                                                 *pRedl, bCopyNext );
    1051         [ #  # ]:          0 :             rSData.push_back( pNewData );
    1052                 :            :         }
    1053                 :            :     }
    1054 [ -  + ][ #  # ]:         46 :     if( !rSData.empty() && bDelRange )
                 [ -  + ]
    1055         [ #  # ]:          0 :         rRange.GetDoc()->DeleteRedline( rRange, false, USHRT_MAX );
    1056                 :         46 :     return !rSData.empty();
    1057                 :            : }
    1058                 :            : 
    1059                 :          0 : sal_Bool SwUndo::FillSaveDataForFmt( const SwPaM& rRange, SwRedlineSaveDatas& rSData )
    1060                 :            : {
    1061         [ #  # ]:          0 :     rSData.DeleteAndDestroyAll();
    1062                 :            : 
    1063                 :            :     SwRedlineSaveData* pNewData;
    1064 [ #  # ][ #  # ]:          0 :     const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End();
    1065         [ #  # ]:          0 :     const SwRedlineTbl& rTbl = rRange.GetDoc()->GetRedlineTbl();
    1066                 :          0 :     sal_uInt16 n = 0;
    1067         [ #  # ]:          0 :     rRange.GetDoc()->GetRedline( *pStt, &n );
    1068         [ #  # ]:          0 :     for( ; n < rTbl.size(); ++n )
    1069                 :            :     {
    1070         [ #  # ]:          0 :         SwRedline* pRedl = rTbl[ n ];
    1071 [ #  # ][ #  # ]:          0 :         if( nsRedlineType_t::REDLINE_FORMAT == pRedl->GetType() )
    1072                 :            :         {
    1073 [ #  # ][ #  # ]:          0 :             const SwPosition *pRStt = pRedl->Start(), *pREnd = pRedl->End();
    1074                 :            : 
    1075         [ #  # ]:          0 :             SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
    1076 [ #  # ][ #  # ]:          0 :             if( POS_BEFORE != eCmpPos && POS_BEHIND != eCmpPos &&
         [ #  # ][ #  # ]
    1077                 :            :                 POS_COLLIDE_END != eCmpPos && POS_COLLIDE_START != eCmpPos )
    1078                 :            :             {
    1079                 :            :                 pNewData = new SwRedlineSaveData( eCmpPos, *pStt, *pEnd,
    1080 [ #  # ][ #  # ]:          0 :                                                     *pRedl, sal_True );
    1081         [ #  # ]:          0 :                 rSData.push_back( pNewData );
    1082                 :            :             }
    1083                 :            : 
    1084                 :            : 
    1085                 :            :         }
    1086                 :            :     }
    1087                 :          0 :     return !rSData.empty();
    1088                 :            : }
    1089                 :            : 
    1090                 :          0 : void SwUndo::SetSaveData( SwDoc& rDoc, const SwRedlineSaveDatas& rSData )
    1091                 :            : {
    1092         [ #  # ]:          0 :     RedlineMode_t eOld = rDoc.GetRedlineMode();
    1093         [ #  # ]:          0 :     rDoc.SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
    1094 [ #  # ][ #  # ]:          0 :     SwPaM aPam( rDoc.GetNodes().GetEndOfContent() );
    1095                 :            : 
    1096         [ #  # ]:          0 :     for( sal_uInt16 n = rSData.size(); n; )
    1097         [ #  # ]:          0 :         rSData[ --n ]->RedlineToDoc( aPam );
    1098                 :            : 
    1099                 :            : #if OSL_DEBUG_LEVEL > 0
    1100                 :            :     // check redline count against count saved in RedlineSaveData object
    1101                 :            :     assert(rSData.empty() ||
    1102                 :            :            (rSData[0]->nRedlineCount == rDoc.GetRedlineTbl().size()));
    1103                 :            :             // "redline count not restored properly"
    1104                 :            : #endif
    1105                 :            : 
    1106 [ #  # ][ #  # ]:          0 :     rDoc.SetRedlineMode_intern( eOld );
    1107                 :          0 : }
    1108                 :            : 
    1109                 :          0 : sal_Bool SwUndo::HasHiddenRedlines( const SwRedlineSaveDatas& rSData )
    1110                 :            : {
    1111         [ #  # ]:          0 :     for( sal_uInt16 n = rSData.size(); n; )
    1112         [ #  # ]:          0 :         if( rSData[ --n ]->GetMvSttIdx() )
    1113                 :          0 :             return sal_True;
    1114                 :          0 :     return sal_False;
    1115                 :            : }
    1116                 :            : 
    1117                 :          0 : sal_Bool SwUndo::CanRedlineGroup( SwRedlineSaveDatas& rCurr,
    1118                 :            :                         const SwRedlineSaveDatas& rCheck, sal_Bool bCurrIsEnd )
    1119                 :            : {
    1120                 :          0 :     sal_Bool bRet = sal_False;
    1121                 :            :     sal_uInt16 n;
    1122                 :            : 
    1123         [ #  # ]:          0 :     if( rCurr.size() == rCheck.size() )
    1124                 :            :     {
    1125                 :          0 :         bRet = sal_True;
    1126         [ #  # ]:          0 :         for( n = 0; n < rCurr.size(); ++n )
    1127                 :            :         {
    1128                 :          0 :             const SwRedlineSaveData& rSet = *rCurr[ n ];
    1129                 :          0 :             const SwRedlineSaveData& rGet = *rCheck[ n ];
    1130 [ #  # ][ #  # ]:          0 :             if( rSet.nSttNode != rGet.nSttNode ||
           [ #  #  #  # ]
         [ #  # ][ #  #  
             #  #  #  # ]
    1131                 :          0 :                 rSet.GetMvSttIdx() || rGet.GetMvSttIdx() ||
    1132                 :            :                 ( bCurrIsEnd ? rSet.nSttCntnt != rGet.nEndCntnt
    1133                 :            :                              : rSet.nEndCntnt != rGet.nSttCntnt ) ||
    1134                 :          0 :                 !rGet.CanCombine( rSet ) )
    1135                 :            :             {
    1136                 :          0 :                 bRet = sal_False;
    1137                 :          0 :                 break;
    1138                 :            :             }
    1139                 :            :         }
    1140                 :            : 
    1141         [ #  # ]:          0 :         if( bRet )
    1142         [ #  # ]:          0 :             for( n = 0; n < rCurr.size(); ++n )
    1143                 :            :             {
    1144                 :          0 :                 SwRedlineSaveData& rSet = *rCurr[ n ];
    1145                 :          0 :                 const SwRedlineSaveData& rGet = *rCheck[ n ];
    1146         [ #  # ]:          0 :                 if( bCurrIsEnd )
    1147                 :          0 :                     rSet.nSttCntnt = rGet.nSttCntnt;
    1148                 :            :                 else
    1149                 :          0 :                     rSet.nEndCntnt = rGet.nEndCntnt;
    1150                 :            :             }
    1151                 :            :     }
    1152                 :          0 :     return bRet;
    1153                 :            : }
    1154                 :            : 
    1155                 :            : // #111827#
    1156                 :       8371 : String ShortenString(const String & rStr, xub_StrLen nLength, const String & rFillStr)
    1157                 :            : {
    1158                 :            :     assert(nLength - rFillStr.Len() >= 2);
    1159                 :            : 
    1160                 :       8371 :     String aResult;
    1161                 :            : 
    1162         [ +  + ]:       8371 :     if (rStr.Len() <= nLength)
    1163         [ +  - ]:       5777 :         aResult = rStr;
    1164                 :            :     else
    1165                 :            :     {
    1166                 :       2594 :         long nTmpLength = nLength - rFillStr.Len();
    1167         [ -  + ]:       2594 :         if ( nTmpLength < 2 )
    1168                 :          0 :             nTmpLength = 2;
    1169                 :            : 
    1170                 :       2594 :         nLength = static_cast<xub_StrLen>(nTmpLength);
    1171                 :            : 
    1172                 :       2594 :         const xub_StrLen nFrontLen = nLength - nLength / 2;
    1173                 :       2594 :         const xub_StrLen nBackLen = nLength - nFrontLen;
    1174                 :            : 
    1175 [ +  - ][ +  - ]:       2594 :         aResult += rStr.Copy(0, nFrontLen);
                 [ +  - ]
    1176         [ +  - ]:       2594 :         aResult += rFillStr;
    1177 [ +  - ][ +  - ]:       2594 :         aResult += rStr.Copy(rStr.Len() - nBackLen, nBackLen);
                 [ +  - ]
    1178                 :            :     }
    1179                 :            : 
    1180                 :       8371 :     return aResult;
    1181                 :            : }
    1182                 :            : 
    1183                 :          0 : bool IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos,
    1184                 :            :         SwPosition const & rStart, SwPosition const & rEnd,
    1185                 :            :         DelCntntType const nDelCntntType)
    1186                 :            : {
    1187                 :            : 
    1188                 :            :     // Here we identified the objects to destroy:
    1189                 :            :     // - anchored between start and end of the selection
    1190                 :            :     // - anchored in start of the selection with "CheckNoContent"
    1191                 :            :     // - anchored in start of sel. and the selection start at pos 0
    1192                 :          0 :     return  (rAnchorPos.nNode < rEnd.nNode)
    1193                 :            :          && (   (nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType)
    1194                 :          0 :             ||  (rStart.nNode < rAnchorPos.nNode)
    1195                 :          0 :             ||  !rStart.nContent.GetIndex()
    1196   [ #  #  #  #  :          0 :             );
           #  # ][ #  # ]
    1197                 :            : }
    1198                 :            : 
    1199                 :         92 : void SwRedlineSaveDatas::DeleteAndDestroyAll()
    1200                 :            : {
    1201 [ +  - ][ +  - ]:         92 :     for( const_iterator it = begin(); it != end(); ++it )
                 [ -  + ]
    1202 [ #  # ][ #  # ]:          0 :         delete *it;
    1203                 :         92 :     clear();
    1204                 :         92 : }
    1205                 :            : 
    1206                 :            : 
    1207                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10