LCOV - code coverage report
Current view: top level - sw/source/core/doc - DocumentRedlineManager.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 452 1272 35.5 %
Date: 2015-06-13 12:38:46 Functions: 34 46 73.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       3             : /*
       4             :  * This file is part of the LibreOffice project.
       5             :  *
       6             :  * This Source Code Form is subject to the terms of the Mozilla Public
       7             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       8             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       9             :  *
      10             :  * This file incorporates work covered by the following license notice:
      11             :  *
      12             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      13             :  *   contributor license agreements. See the NOTICE file distributed
      14             :  *   with this work for additional information regarding copyright
      15             :  *   ownership. The ASF licenses this file to you under the Apache
      16             :  *   License, Version 2.0 (the "License"); you may not use this file
      17             :  *   except in compliance with the License. You may obtain a copy of
      18             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      19             : */
      20             : #include <DocumentRedlineManager.hxx>
      21             : #include <atrfrm.hxx>
      22             : #include <doc.hxx>
      23             : #include <IDocumentUndoRedo.hxx>
      24             : #include <IDocumentState.hxx>
      25             : #include <redline.hxx>
      26             : #include <UndoRedline.hxx>
      27             : #include <docary.hxx>
      28             : #include <ndtxt.hxx>
      29             : #include <comcore.hrc>
      30             : #include <swmodule.hxx>
      31             : #include <editsh.hxx>
      32             : #include <vcl/layout.hxx>
      33             : 
      34             : using namespace com::sun::star;
      35             : 
      36             : #ifdef DBG_UTIL
      37             : 
      38             :     #define _ERROR_PREFIX "redline table corrupted: "
      39             : 
      40             :     namespace
      41             :     {
      42             :         // helper function for lcl_CheckRedline
      43             :         // 1. make sure that pPos->nContent points into pPos->nNode
      44             :         // 2. check that position is valid and doesn't point after text
      45             :         static void lcl_CheckPosition( const SwPosition* pPos )
      46             :         {
      47             :             assert(dynamic_cast<SwIndexReg*>(&pPos->nNode.GetNode())
      48             :                     == pPos->nContent.GetIdxReg());
      49             : 
      50             :             SwTextNode* pTextNode = pPos->nNode.GetNode().GetTextNode();
      51             :             if( pTextNode == NULL )
      52             :             {
      53             :                 assert(pPos->nContent == 0);
      54             :             }
      55             :             else
      56             :             {
      57             :                 assert(pPos->nContent >= 0 && pPos->nContent <= pTextNode->Len());
      58             :             }
      59             :         }
      60             : 
      61             :         static void lcl_CheckPam( const SwPaM* pPam )
      62             :         {
      63             :             assert(pPam);
      64             :             lcl_CheckPosition( pPam->GetPoint() );
      65             :             lcl_CheckPosition( pPam->GetMark() );
      66             :         }
      67             : 
      68             :         // check validity of the redline table. Checks redline bounds, and make
      69             :         // sure the redlines are sorted and non-overlapping.
      70             :         static void lcl_CheckRedline( IDocumentRedlineAccess& redlineAccess )
      71             :         {
      72             :             const SwRedlineTable& rTable = redlineAccess.GetRedlineTable();
      73             : 
      74             :             // verify valid redline positions
      75             :             for( size_t i = 0; i < rTable.size(); ++i )
      76             :                 lcl_CheckPam( rTable[ i ] );
      77             : 
      78             :             for( size_t j = 0; j < rTable.size(); ++j )
      79             :             {
      80             :                 // check for empty redlines
      81             :                 OSL_ENSURE( ( *(rTable[j]->GetPoint()) != *(rTable[j]->GetMark()) ) ||
      82             :                             ( rTable[j]->GetContentIdx() != NULL ),
      83             :                             _ERROR_PREFIX "empty redline" );
      84             :              }
      85             : 
      86             :             // verify proper redline sorting
      87             :             for( size_t n = 1; n < rTable.size(); ++n )
      88             :             {
      89             :                 const SwRangeRedline* pPrev = rTable[ n-1 ];
      90             :                 const SwRangeRedline* pCurrent = rTable[ n ];
      91             : 
      92             :                 // check redline sorting
      93             :                 SAL_WARN_IF( *pPrev->Start() > *pCurrent->Start(), "sw",
      94             :                              _ERROR_PREFIX "not sorted correctly" );
      95             : 
      96             :                 // check for overlapping redlines
      97             :                 SAL_WARN_IF( *pPrev->End() > *pCurrent->Start(), "sw",
      98             :                              _ERROR_PREFIX "overlapping redlines" );
      99             :             }
     100             : 
     101             :             assert(std::is_sorted(rTable.begin(), rTable.end(), CompareSwRedlineTable()));
     102             :         }
     103             :     }
     104             : 
     105             :     #define _CHECK_REDLINE( pDoc ) lcl_CheckRedline( pDoc );
     106             : 
     107             : #else
     108             : 
     109             :     #define _CHECK_REDLINE( pDoc )
     110             : 
     111             : #endif
     112             : 
     113             : namespace
     114             : {
     115          74 :     static inline bool IsPrevPos( const SwPosition & rPos1, const SwPosition & rPos2 )
     116             :     {
     117             :         const SwContentNode* pCNd;
     118          85 :         return 0 == rPos2.nContent.GetIndex() &&
     119          13 :                rPos2.nNode.GetIndex() - 1 == rPos1.nNode.GetIndex() &&
     120          78 :                0 != ( pCNd = rPos1.nNode.GetNode().GetContentNode() ) &&
     121          76 :                rPos1.nContent.GetIndex() == pCNd->Len();
     122             :     }
     123             : 
     124          10 :     static bool lcl_AcceptRedline( SwRedlineTable& rArr, sal_uInt16& rPos,
     125             :                             bool bCallDelete,
     126             :                             const SwPosition* pSttRng = 0,
     127             :                             const SwPosition* pEndRng = 0 )
     128             :     {
     129          10 :         bool bRet = true;
     130          10 :         SwRangeRedline* pRedl = rArr[ rPos ];
     131          10 :         SwPosition *pRStt = 0, *pREnd = 0;
     132          10 :         SwComparePosition eCmp = POS_OUTSIDE;
     133          10 :         if( pSttRng && pEndRng )
     134             :         {
     135           0 :             pRStt = pRedl->Start();
     136           0 :             pREnd = pRedl->End();
     137           0 :             eCmp = ComparePosition( *pSttRng, *pEndRng, *pRStt, *pREnd );
     138             :         }
     139             : 
     140          10 :         pRedl->InvalidateRange();
     141             : 
     142          10 :         switch( pRedl->GetType() )
     143             :         {
     144             :         case nsRedlineType_t::REDLINE_INSERT:
     145             :         case nsRedlineType_t::REDLINE_FORMAT:
     146             :             {
     147           5 :                 bool bCheck = false, bReplace = false;
     148           5 :                 switch( eCmp )
     149             :                 {
     150             :                 case POS_INSIDE:
     151           0 :                     if( *pSttRng == *pRStt )
     152           0 :                         pRedl->SetStart( *pEndRng, pRStt );
     153             :                     else
     154             :                     {
     155           0 :                         if( *pEndRng != *pREnd )
     156             :                         {
     157             :                             // split up
     158           0 :                             SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
     159           0 :                             pNew->SetStart( *pEndRng );
     160           0 :                             rArr.Insert( pNew ); ++rPos;
     161             :                         }
     162           0 :                         pRedl->SetEnd( *pSttRng, pREnd );
     163           0 :                         bCheck = true;
     164             :                     }
     165           0 :                     break;
     166             : 
     167             :                 case POS_OVERLAP_BEFORE:
     168           0 :                     pRedl->SetStart( *pEndRng, pRStt );
     169           0 :                     bReplace = true;
     170           0 :                     break;
     171             : 
     172             :                 case POS_OVERLAP_BEHIND:
     173           0 :                     pRedl->SetEnd( *pSttRng, pREnd );
     174           0 :                     bCheck = true;
     175           0 :                     break;
     176             : 
     177             :                 case POS_OUTSIDE:
     178             :                 case POS_EQUAL:
     179           5 :                     rArr.DeleteAndDestroy( rPos-- );
     180           5 :                     break;
     181             : 
     182             :                 default:
     183           0 :                     bRet = false;
     184             :                 }
     185             : 
     186           5 :                 if( bReplace || ( bCheck && !pRedl->HasValidRange() ))
     187             :                 {
     188             :                     // re-insert
     189           0 :                     rArr.Remove( pRedl );
     190           0 :                     rArr.Insert( pRedl );
     191             :                 }
     192             :             }
     193           5 :             break;
     194             :         case nsRedlineType_t::REDLINE_DELETE:
     195             :             {
     196           5 :                 SwDoc& rDoc = *pRedl->GetDoc();
     197           5 :                 const SwPosition *pDelStt = 0, *pDelEnd = 0;
     198           5 :                 bool bDelRedl = false;
     199           5 :                 switch( eCmp )
     200             :                 {
     201             :                 case POS_INSIDE:
     202           0 :                     if( bCallDelete )
     203             :                     {
     204           0 :                         pDelStt = pSttRng;
     205           0 :                         pDelEnd = pEndRng;
     206             :                     }
     207           0 :                     break;
     208             : 
     209             :                 case POS_OVERLAP_BEFORE:
     210           0 :                     if( bCallDelete )
     211             :                     {
     212           0 :                         pDelStt = pRStt;
     213           0 :                         pDelEnd = pEndRng;
     214             :                     }
     215           0 :                     break;
     216             :                 case POS_OVERLAP_BEHIND:
     217           0 :                     if( bCallDelete )
     218             :                     {
     219           0 :                         pDelStt = pREnd;
     220           0 :                         pDelEnd = pSttRng;
     221             :                     }
     222           0 :                     break;
     223             : 
     224             :                 case POS_OUTSIDE:
     225             :                 case POS_EQUAL:
     226             :                     {
     227           5 :                         rArr.Remove( rPos-- );
     228           5 :                         bDelRedl = true;
     229           5 :                         if( bCallDelete )
     230             :                         {
     231           5 :                             pDelStt = pRedl->Start();
     232           5 :                             pDelEnd = pRedl->End();
     233             :                         }
     234             :                     }
     235           5 :                     break;
     236             :                 default:
     237           0 :                     bRet = false;
     238             :                 }
     239             : 
     240           5 :                 if( pDelStt && pDelEnd )
     241             :                 {
     242           5 :                     SwPaM aPam( *pDelStt, *pDelEnd );
     243           5 :                     SwContentNode* pCSttNd = pDelStt->nNode.GetNode().GetContentNode();
     244           5 :                     SwContentNode* pCEndNd = pDelEnd->nNode.GetNode().GetContentNode();
     245             : 
     246           5 :                     if( bDelRedl )
     247           5 :                         delete pRedl;
     248             : 
     249           5 :                     RedlineMode_t eOld = rDoc.getIDocumentRedlineAccess().GetRedlineMode();
     250           5 :                     rDoc.getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE)));
     251             : 
     252           5 :                     if( pCSttNd && pCEndNd )
     253           5 :                         rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
     254             :                     else
     255             :                     {
     256           0 :                         rDoc.getIDocumentContentOperations().DeleteRange( aPam );
     257             : 
     258           0 :                         if( pCSttNd && !pCEndNd )
     259             :                         {
     260           0 :                             aPam.GetBound( true ).nContent.Assign( 0, 0 );
     261           0 :                             aPam.GetBound( false ).nContent.Assign( 0, 0 );
     262           0 :                             aPam.DeleteMark();
     263           0 :                             rDoc.getIDocumentContentOperations().DelFullPara( aPam );
     264             :                         }
     265             :                     }
     266           5 :                     rDoc.getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
     267             :                 }
     268           0 :                 else if( bDelRedl )
     269           0 :                     delete pRedl;
     270             :             }
     271           5 :             break;
     272             : 
     273             :         case nsRedlineType_t::REDLINE_FMTCOLL:
     274           0 :             rArr.DeleteAndDestroy( rPos-- );
     275           0 :             break;
     276             : 
     277             :         default:
     278           0 :             bRet = false;
     279             :         }
     280          10 :         return bRet;
     281             :     }
     282             : 
     283           0 :     static bool lcl_RejectRedline( SwRedlineTable& rArr, sal_uInt16& rPos,
     284             :                             bool bCallDelete,
     285             :                             const SwPosition* pSttRng = 0,
     286             :                             const SwPosition* pEndRng = 0 )
     287             :     {
     288           0 :         bool bRet = true;
     289           0 :         SwRangeRedline* pRedl = rArr[ rPos ];
     290           0 :         SwPosition *pRStt = 0, *pREnd = 0;
     291           0 :         SwComparePosition eCmp = POS_OUTSIDE;
     292           0 :         if( pSttRng && pEndRng )
     293             :         {
     294           0 :             pRStt = pRedl->Start();
     295           0 :             pREnd = pRedl->End();
     296           0 :             eCmp = ComparePosition( *pSttRng, *pEndRng, *pRStt, *pREnd );
     297             :         }
     298             : 
     299           0 :         pRedl->InvalidateRange();
     300             : 
     301           0 :         switch( pRedl->GetType() )
     302             :         {
     303             :         case nsRedlineType_t::REDLINE_INSERT:
     304             :             {
     305           0 :                 SwDoc& rDoc = *pRedl->GetDoc();
     306           0 :                 const SwPosition *pDelStt = 0, *pDelEnd = 0;
     307           0 :                 bool bDelRedl = false;
     308           0 :                 switch( eCmp )
     309             :                 {
     310             :                 case POS_INSIDE:
     311           0 :                     if( bCallDelete )
     312             :                     {
     313           0 :                         pDelStt = pSttRng;
     314           0 :                         pDelEnd = pEndRng;
     315             :                     }
     316           0 :                     break;
     317             : 
     318             :                 case POS_OVERLAP_BEFORE:
     319           0 :                     if( bCallDelete )
     320             :                     {
     321           0 :                         pDelStt = pRStt;
     322           0 :                         pDelEnd = pEndRng;
     323             :                     }
     324           0 :                     break;
     325             :                 case POS_OVERLAP_BEHIND:
     326           0 :                     if( bCallDelete )
     327             :                     {
     328           0 :                         pDelStt = pREnd;
     329           0 :                         pDelEnd = pSttRng;
     330             :                     }
     331           0 :                     break;
     332             :                 case POS_OUTSIDE:
     333             :                 case POS_EQUAL:
     334             :                     {
     335             :                         // delete the range again
     336           0 :                         rArr.Remove( rPos-- );
     337           0 :                         bDelRedl = true;
     338           0 :                         if( bCallDelete )
     339             :                         {
     340           0 :                             pDelStt = pRedl->Start();
     341           0 :                             pDelEnd = pRedl->End();
     342             :                         }
     343             :                     }
     344           0 :                     break;
     345             : 
     346             :                 default:
     347           0 :                     bRet = false;
     348             :                 }
     349           0 :                 if( pDelStt && pDelEnd )
     350             :                 {
     351           0 :                     SwPaM aPam( *pDelStt, *pDelEnd );
     352             : 
     353           0 :                     SwContentNode* pCSttNd = pDelStt->nNode.GetNode().GetContentNode();
     354           0 :                     SwContentNode* pCEndNd = pDelEnd->nNode.GetNode().GetContentNode();
     355             : 
     356           0 :                     if( bDelRedl )
     357           0 :                         delete pRedl;
     358             : 
     359           0 :                     RedlineMode_t eOld = rDoc.getIDocumentRedlineAccess().GetRedlineMode();
     360           0 :                     rDoc.getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE)));
     361             : 
     362           0 :                     if( pCSttNd && pCEndNd )
     363           0 :                         rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
     364             :                     else
     365             :                     {
     366           0 :                         rDoc.getIDocumentContentOperations().DeleteRange( aPam );
     367             : 
     368           0 :                         if( pCSttNd && !pCEndNd )
     369             :                         {
     370           0 :                             aPam.GetBound( true ).nContent.Assign( 0, 0 );
     371           0 :                             aPam.GetBound( false ).nContent.Assign( 0, 0 );
     372           0 :                             aPam.DeleteMark();
     373           0 :                             rDoc.getIDocumentContentOperations().DelFullPara( aPam );
     374             :                         }
     375             :                     }
     376           0 :                     rDoc.getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
     377             :                 }
     378           0 :                 else if( bDelRedl )
     379           0 :                     delete pRedl;
     380             :             }
     381           0 :             break;
     382             :         case nsRedlineType_t::REDLINE_DELETE:
     383             :             {
     384           0 :                 SwRangeRedline* pNew = 0;
     385           0 :                 bool bCheck = false, bReplace = false;
     386             : 
     387           0 :                 switch( eCmp )
     388             :                 {
     389             :                 case POS_INSIDE:
     390             :                     {
     391           0 :                         if( 1 < pRedl->GetStackCount() )
     392             :                         {
     393           0 :                             pNew = new SwRangeRedline( *pRedl );
     394           0 :                             pNew->PopData();
     395             :                         }
     396           0 :                         if( *pSttRng == *pRStt )
     397             :                         {
     398           0 :                             pRedl->SetStart( *pEndRng, pRStt );
     399           0 :                             bReplace = true;
     400           0 :                             if( pNew )
     401           0 :                                 pNew->SetEnd( *pEndRng );
     402             :                         }
     403             :                         else
     404             :                         {
     405           0 :                             if( *pEndRng != *pREnd )
     406             :                             {
     407             :                                 // split up
     408           0 :                                 SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
     409           0 :                                 pCpy->SetStart( *pEndRng );
     410           0 :                                 rArr.Insert( pCpy ); ++rPos;
     411           0 :                                 if( pNew )
     412           0 :                                     pNew->SetEnd( *pEndRng );
     413             :                             }
     414             : 
     415           0 :                             pRedl->SetEnd( *pSttRng, pREnd );
     416           0 :                             bCheck = true;
     417           0 :                             if( pNew )
     418           0 :                                 pNew->SetStart( *pSttRng );
     419             :                         }
     420             :                     }
     421           0 :                     break;
     422             : 
     423             :                 case POS_OVERLAP_BEFORE:
     424           0 :                     if( 1 < pRedl->GetStackCount() )
     425             :                     {
     426           0 :                         pNew = new SwRangeRedline( *pRedl );
     427           0 :                         pNew->PopData();
     428             :                     }
     429           0 :                     pRedl->SetStart( *pEndRng, pRStt );
     430           0 :                     bReplace = true;
     431           0 :                     if( pNew )
     432           0 :                         pNew->SetEnd( *pEndRng );
     433           0 :                     break;
     434             : 
     435             :                 case POS_OVERLAP_BEHIND:
     436           0 :                     if( 1 < pRedl->GetStackCount() )
     437             :                     {
     438           0 :                         pNew = new SwRangeRedline( *pRedl );
     439           0 :                         pNew->PopData();
     440             :                     }
     441           0 :                     pRedl->SetEnd( *pSttRng, pREnd );
     442           0 :                     bCheck = true;
     443           0 :                     if( pNew )
     444           0 :                         pNew->SetStart( *pSttRng );
     445           0 :                     break;
     446             : 
     447             :                 case POS_OUTSIDE:
     448             :                 case POS_EQUAL:
     449           0 :                     if( !pRedl->PopData() )
     450             :                         // deleting the RedlineObject is enough
     451           0 :                         rArr.DeleteAndDestroy( rPos-- );
     452           0 :                     break;
     453             : 
     454             :                 default:
     455           0 :                     bRet = false;
     456             :                 }
     457             : 
     458           0 :                 if( pNew )
     459             :                 {
     460           0 :                     rArr.Insert( pNew ); ++rPos;
     461             :                 }
     462             : 
     463           0 :                 if( bReplace || ( bCheck && !pRedl->HasValidRange() ))
     464             :                 {
     465             :                     // re-insert
     466           0 :                     rArr.Remove( pRedl );
     467           0 :                     rArr.Insert( pRedl );
     468             :                 }
     469             :             }
     470           0 :             break;
     471             : 
     472             :         case nsRedlineType_t::REDLINE_FORMAT:
     473             :         case nsRedlineType_t::REDLINE_FMTCOLL:
     474             :             {
     475           0 :                 if( pRedl->GetExtraData() )
     476           0 :                     pRedl->GetExtraData()->Reject( *pRedl );
     477           0 :                 rArr.DeleteAndDestroy( rPos-- );
     478             :             }
     479           0 :             break;
     480             : 
     481             :         default:
     482           0 :             bRet = false;
     483             :         }
     484           0 :         return bRet;
     485             :     }
     486             : 
     487             :     typedef bool (*Fn_AcceptReject)( SwRedlineTable& rArr, sal_uInt16& rPos,
     488             :                             bool bCallDelete,
     489             :                             const SwPosition* pSttRng,
     490             :                             const SwPosition* pEndRng);
     491             : 
     492             : 
     493           0 :     static int lcl_AcceptRejectRedl( Fn_AcceptReject fn_AcceptReject,
     494             :                                 SwRedlineTable& rArr, bool bCallDelete,
     495             :                                 const SwPaM& rPam)
     496             :     {
     497           0 :         sal_uInt16 n = 0;
     498           0 :         int nCount = 0;
     499             : 
     500           0 :         const SwPosition* pStt = rPam.Start(),
     501           0 :                         * pEnd = pStt == rPam.GetPoint() ? rPam.GetMark()
     502           0 :                                                          : rPam.GetPoint();
     503           0 :         const SwRangeRedline* pFnd = rArr.FindAtPosition( *pStt, n, true );
     504           0 :         if( pFnd &&     // Is new a part of it?
     505           0 :             ( *pFnd->Start() != *pStt || *pFnd->End() > *pEnd ))
     506             :         {
     507             :             // Only revoke the partial selection
     508           0 :             if( (*fn_AcceptReject)( rArr, n, bCallDelete, pStt, pEnd ))
     509           0 :                 nCount++;
     510           0 :             ++n;
     511             :         }
     512             : 
     513           0 :         for( ; n < rArr.size(); ++n )
     514             :         {
     515           0 :             SwRangeRedline* pTmp = rArr[ n ];
     516           0 :             if( pTmp->HasMark() && pTmp->IsVisible() )
     517             :             {
     518           0 :                 if( *pTmp->End() <= *pEnd )
     519             :                 {
     520           0 :                     if( (*fn_AcceptReject)( rArr, n, bCallDelete, 0, 0 ))
     521           0 :                         nCount++;
     522             :                 }
     523             :                 else
     524             :                 {
     525           0 :                     if( *pTmp->Start() < *pEnd )
     526             :                     {
     527             :                         // Only revoke the partial selection
     528           0 :                         if( (*fn_AcceptReject)( rArr, n, bCallDelete, pStt, pEnd ))
     529           0 :                             nCount++;
     530             :                     }
     531           0 :                     break;
     532             :                 }
     533             :             }
     534             :         }
     535           0 :         return nCount;
     536             :     }
     537             : 
     538           0 :     static void lcl_AdjustRedlineRange( SwPaM& rPam )
     539             :     {
     540             :         // The Selection is only in the ContentSection. If there are Redlines
     541             :         // to Non-ContentNodes before or after that, then the Selections
     542             :         // expand to them.
     543           0 :         SwPosition* pStt = rPam.Start(),
     544           0 :                   * pEnd = pStt == rPam.GetPoint() ? rPam.GetMark()
     545           0 :                                                    : rPam.GetPoint();
     546           0 :         SwDoc* pDoc = rPam.GetDoc();
     547           0 :         if( !pStt->nContent.GetIndex() &&
     548           0 :             !pDoc->GetNodes()[ pStt->nNode.GetIndex() - 1 ]->IsContentNode() )
     549             :         {
     550           0 :             const SwRangeRedline* pRedl = pDoc->getIDocumentRedlineAccess().GetRedline( *pStt, 0 );
     551           0 :             if( pRedl )
     552             :             {
     553           0 :                 const SwPosition* pRStt = pRedl->Start();
     554           0 :                 if( !pRStt->nContent.GetIndex() && pRStt->nNode.GetIndex() ==
     555           0 :                     pStt->nNode.GetIndex() - 1 )
     556           0 :                     *pStt = *pRStt;
     557             :             }
     558             :         }
     559           0 :         if( pEnd->nNode.GetNode().IsContentNode() &&
     560           0 :             !pDoc->GetNodes()[ pEnd->nNode.GetIndex() + 1 ]->IsContentNode() &&
     561           0 :             pEnd->nContent.GetIndex() == pEnd->nNode.GetNode().GetContentNode()->Len()    )
     562             :         {
     563           0 :             const SwRangeRedline* pRedl = pDoc->getIDocumentRedlineAccess().GetRedline( *pEnd, 0 );
     564           0 :             if( pRedl )
     565             :             {
     566           0 :                 const SwPosition* pREnd = pRedl->End();
     567           0 :                 if( !pREnd->nContent.GetIndex() && pREnd->nNode.GetIndex() ==
     568           0 :                     pEnd->nNode.GetIndex() + 1 )
     569           0 :                     *pEnd = *pREnd;
     570             :             }
     571             :         }
     572           0 :     }
     573             : }
     574             : 
     575             : namespace sw
     576             : {
     577             : 
     578        2958 : DocumentRedlineManager::DocumentRedlineManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ),
     579             :                                                                     meRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE)),
     580        2958 :                                                                     mpRedlineTable( new SwRedlineTable ),
     581        2958 :                                                                     mpExtraRedlineTable ( new SwExtraRedlineTable ),
     582             :                                                                     mpAutoFormatRedlnComment( 0 ),
     583             :                                                                     mbIsRedlineMove(false),
     584             :                                                                     mbReadlineChecked(false),
     585        8874 :                                                                     mnAutoFormatRedlnCommentNo( 0 )
     586             : {
     587        2958 : }
     588             : 
     589    48932470 : RedlineMode_t DocumentRedlineManager::GetRedlineMode() const
     590             : {
     591    48932470 :     return meRedlineMode;
     592             : }
     593             : 
     594       16081 : void DocumentRedlineManager::SetRedlineMode( RedlineMode_t eMode )
     595             : {
     596       16081 :     if( meRedlineMode != eMode )
     597             :     {
     598         610 :         if( (nsRedlineMode_t::REDLINE_SHOW_MASK & meRedlineMode) != (nsRedlineMode_t::REDLINE_SHOW_MASK & eMode)
     599         154 :             || 0 == (nsRedlineMode_t::REDLINE_SHOW_MASK & eMode) )
     600             :         {
     601         456 :             bool bSaveInXMLImportFlag = m_rDoc.IsInXMLImport();
     602         456 :             m_rDoc.SetInXMLImport( false );
     603             :             // and then hide/display everything
     604         456 :             void (SwRangeRedline::*pFnc)(sal_uInt16, size_t) = 0;
     605             : 
     606         456 :             switch( nsRedlineMode_t::REDLINE_SHOW_MASK & eMode )
     607             :             {
     608             :             case nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE :
     609         367 :                 pFnc = &SwRangeRedline::Show;
     610         367 :                 break;
     611             :             case nsRedlineMode_t::REDLINE_SHOW_INSERT:
     612          80 :                 pFnc = &SwRangeRedline::Hide;
     613          80 :                 break;
     614             :             case nsRedlineMode_t::REDLINE_SHOW_DELETE:
     615           5 :                 pFnc = &SwRangeRedline::ShowOriginal;
     616           5 :                 break;
     617             : 
     618             :             default:
     619           4 :                 pFnc = &SwRangeRedline::Hide;
     620           4 :                 eMode = (RedlineMode_t)(eMode | nsRedlineMode_t::REDLINE_SHOW_INSERT);
     621           4 :                 break;
     622             :             }
     623             : 
     624         456 :             CheckAnchoredFlyConsistency(m_rDoc);
     625             :             _CHECK_REDLINE( *this )
     626             : 
     627         456 :             if (pFnc)
     628             :             {
     629        1368 :                 for (sal_uInt16 nLoop = 1; nLoop <= 2; ++nLoop)
     630        1070 :                     for (size_t i = 0; i < mpRedlineTable->size(); ++i)
     631         158 :                         ((*mpRedlineTable)[i]->*pFnc)(nLoop, i);
     632             : 
     633             :                 //SwRangeRedline::MoveFromSection routinely changes
     634             :                 //the keys that mpRedlineTable is sorted by
     635         456 :                 mpRedlineTable->Resort();
     636             :             }
     637             : 
     638         456 :             CheckAnchoredFlyConsistency(m_rDoc);
     639             :             _CHECK_REDLINE( *this )
     640         456 :             m_rDoc.SetInXMLImport( bSaveInXMLImportFlag );
     641             :         }
     642         610 :         meRedlineMode = eMode;
     643         610 :         m_rDoc.getIDocumentState().SetModified();
     644             :     }
     645             : 
     646             :     // #TODO - add 'SwExtraRedlineTable' also ?
     647       16081 : }
     648             : 
     649      318923 : bool DocumentRedlineManager::IsRedlineOn() const
     650             : {
     651      318923 :     return IDocumentRedlineAccess::IsRedlineOn(meRedlineMode);
     652             : }
     653             : 
     654      190381 : bool DocumentRedlineManager::IsIgnoreRedline() const
     655             : {
     656      190381 :     return (nsRedlineMode_t::REDLINE_IGNORE & meRedlineMode);
     657             : }
     658             : 
     659        7799 : void DocumentRedlineManager::SetRedlineMode_intern(RedlineMode_t eMode)
     660             : {
     661        7799 :     meRedlineMode = eMode;
     662        7799 : }
     663             : 
     664    75494733 : const SwRedlineTable& DocumentRedlineManager::GetRedlineTable() const
     665             : {
     666    75494733 :     return *mpRedlineTable;
     667             : }
     668             : 
     669      560448 : SwRedlineTable& DocumentRedlineManager::GetRedlineTable()
     670             : {
     671      560448 :     return *mpRedlineTable;
     672             : }
     673             : 
     674           0 : const SwExtraRedlineTable& DocumentRedlineManager::GetExtraRedlineTable() const
     675             : {
     676           0 :     return *mpExtraRedlineTable;
     677             : }
     678             : 
     679        6873 : SwExtraRedlineTable& DocumentRedlineManager::GetExtraRedlineTable()
     680             : {
     681        6873 :     return *mpExtraRedlineTable;
     682             : }
     683             : 
     684        1110 : bool DocumentRedlineManager::HasExtraRedlineTable() const
     685             : {
     686        1110 :     return mpExtraRedlineTable != nullptr;
     687             : }
     688             : 
     689    11478389 : bool DocumentRedlineManager::IsInRedlines(const SwNode & rNode) const
     690             : {
     691    11478389 :     SwPosition aPos(rNode);
     692    11478389 :     SwNode & rEndOfRedlines = m_rDoc.GetNodes().GetEndOfRedlines();
     693    11478389 :     SwPaM aPam(SwPosition(*rEndOfRedlines.StartOfSectionNode()),
     694    34435167 :                SwPosition(rEndOfRedlines));
     695             : 
     696    22956778 :     return aPam.ContainsPosition(aPos);
     697             : }
     698             : 
     699       11422 : bool DocumentRedlineManager::IsRedlineMove() const
     700             : {
     701       11422 :     return mbIsRedlineMove;
     702             : }
     703             : 
     704         220 : void DocumentRedlineManager::SetRedlineMove(bool bFlag)
     705             : {
     706         220 :     mbIsRedlineMove = bFlag;
     707         220 : }
     708             : 
     709             : /*
     710             : Text means Text not "polluted" by Redlines.
     711             : 
     712             : Behaviour of Insert-Redline:
     713             :     - in the Text                       - insert Redline Object
     714             :     - in InsertRedline (own)            - ignore, existing is extended
     715             :     - in InsertRedline (others)         - split up InsertRedline and
     716             :                                           insert Redline Object
     717             :     - in DeleteRedline                  - split up DeleteRedline or
     718             :                                           move at the end/beginning
     719             : 
     720             : Behaviour of Delete-Redline:
     721             :     - in the Text                       - insert Redline Object
     722             :     - in DeleteRedline (own/others)     - ignore
     723             :     - in InsertRedline (own)            - ignore, but delete character
     724             :     - in InsertRedline (others)         - split up InsertRedline and
     725             :                                           insert Redline Object
     726             :     - Text and own Insert overlap       - delete Text in the own Insert,
     727             :                                           extend in the other Text
     728             :                                           (up to the Insert!)
     729             :     - Text and other Insert overlap     - insert Redline Object, the
     730             :                                           other Insert is overlapped by
     731             :                                           the Delete
     732             : */
     733        2582 : bool DocumentRedlineManager::AppendRedline( SwRangeRedline* pNewRedl, bool bCallDelete )
     734             : {
     735        2582 :     bool bMerged = false;
     736             :     _CHECK_REDLINE( *this )
     737             : 
     738        2582 :     if (IsRedlineOn() && !IsShowOriginal(meRedlineMode))
     739             :     {
     740        2254 :         pNewRedl->InvalidateRange();
     741             : 
     742        2254 :         if( m_rDoc.IsAutoFormatRedline() )
     743             :         {
     744           0 :             pNewRedl->SetAutoFormatFlag();
     745           0 :             if( mpAutoFormatRedlnComment && !mpAutoFormatRedlnComment->isEmpty() )
     746             :             {
     747           0 :                 pNewRedl->SetComment( *mpAutoFormatRedlnComment );
     748           0 :                 pNewRedl->SetSeqNo( mnAutoFormatRedlnCommentNo );
     749             :             }
     750             :         }
     751             : 
     752        2254 :         SwPosition* pStt = pNewRedl->Start(),
     753        3838 :                   * pEnd = pStt == pNewRedl->GetPoint() ? pNewRedl->GetMark()
     754        3838 :                                                         : pNewRedl->GetPoint();
     755             :         {
     756        2254 :             SwTextNode* pTextNode = pStt->nNode.GetNode().GetTextNode();
     757        2254 :             if( pTextNode == NULL )
     758             :             {
     759           0 :                 if( pStt->nContent > 0 )
     760             :                 {
     761             :                     OSL_ENSURE( false, "Redline start: non-text-node with content" );
     762           0 :                     pStt->nContent = 0;
     763             :                 }
     764             :             }
     765             :             else
     766             :             {
     767        2254 :                 if( pStt->nContent > pTextNode->Len() )
     768             :                 {
     769             :                     OSL_ENSURE( false, "Redline start: index after text" );
     770           1 :                     pStt->nContent = pTextNode->Len();
     771             :                 }
     772             :             }
     773        2254 :             pTextNode = pEnd->nNode.GetNode().GetTextNode();
     774        2254 :             if( pTextNode == NULL )
     775             :             {
     776           0 :                 if( pEnd->nContent > 0 )
     777             :                 {
     778             :                     OSL_ENSURE( false, "Redline end: non-text-node with content" );
     779           0 :                     pEnd->nContent = 0;
     780             :                 }
     781             :             }
     782             :             else
     783             :             {
     784        2254 :                 if( pEnd->nContent > pTextNode->Len() )
     785             :                 {
     786             :                     OSL_ENSURE( false, "Redline end: index after text" );
     787           0 :                     pEnd->nContent = pTextNode->Len();
     788             :                 }
     789             :             }
     790             :         }
     791        2377 :         if( ( *pStt == *pEnd ) &&
     792         123 :             ( pNewRedl->GetContentIdx() == NULL ) )
     793             :         {   // Do not insert empty redlines
     794         109 :             delete pNewRedl;
     795         109 :             return false;
     796             :         }
     797        2145 :         bool bCompress = false;
     798        2145 :         sal_uInt16 n = 0;
     799             :         // look up the first Redline for the starting position
     800        2145 :         if( !GetRedline( *pStt, &n ) && n )
     801        1437 :             --n;
     802        2145 :         bool bDec = false;
     803             : 
     804       84924 :         for( ; pNewRedl && n < mpRedlineTable->size(); bDec ? n : ++n )
     805             :         {
     806       82779 :             bDec = false;
     807             : 
     808       82779 :             SwRangeRedline* pRedl = (*mpRedlineTable)[ n ];
     809       82779 :             SwPosition* pRStt = pRedl->Start(),
     810      164695 :                       * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
     811      164695 :                                                            : pRedl->GetPoint();
     812             : 
     813             :             // #i8518# remove empty redlines while we're at it
     814       82791 :             if( ( *pRStt == *pREnd ) &&
     815          12 :                 ( pRedl->GetContentIdx() == NULL ) )
     816             :             {
     817           1 :                 mpRedlineTable->DeleteAndDestroy(n);
     818           1 :                 continue;
     819             :             }
     820             : 
     821       82778 :             SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
     822             : 
     823       82778 :             switch( pNewRedl->GetType() )
     824             :             {
     825             :             case nsRedlineType_t::REDLINE_INSERT:
     826         713 :                 switch( pRedl->GetType() )
     827             :                 {
     828             :                 case nsRedlineType_t::REDLINE_INSERT:
     829         657 :                     if( pRedl->IsOwnRedline( *pNewRedl ) )
     830             :                     {
     831         336 :                         bool bDelete = false;
     832             : 
     833             :                         // Merge if applicable?
     834         394 :                         if( (( POS_BEHIND == eCmpPos &&
     835         392 :                                IsPrevPos( *pREnd, *pStt ) ) ||
     836          72 :                              ( POS_COLLIDE_START == eCmpPos ) ||
     837         264 :                              ( POS_OVERLAP_BEHIND == eCmpPos ) ) &&
     838        1085 :                             pRedl->CanCombine( *pNewRedl ) &&
     839         250 :                             ( n+1 >= (sal_uInt16)mpRedlineTable->size() ||
     840           5 :                              ( *(*mpRedlineTable)[ n+1 ]->Start() >= *pEnd &&
     841           0 :                              *(*mpRedlineTable)[ n+1 ]->Start() != *pREnd ) ) )
     842             :                         {
     843         240 :                             pRedl->SetEnd( *pEnd, pREnd );
     844         240 :                             if( !pRedl->HasValidRange() )
     845             :                             {
     846             :                                 // re-insert
     847           0 :                                 mpRedlineTable->Remove( n );
     848           0 :                                 mpRedlineTable->Insert( pRedl );
     849             :                             }
     850             : 
     851         240 :                             bMerged = true;
     852         240 :                             bDelete = true;
     853             :                         }
     854         112 :                         else if( (( POS_BEFORE == eCmpPos &&
     855         112 :                                     IsPrevPos( *pEnd, *pRStt ) ) ||
     856          96 :                                    ( POS_COLLIDE_END == eCmpPos ) ||
     857           0 :                                   ( POS_OVERLAP_BEFORE == eCmpPos ) ) &&
     858          96 :                             pRedl->CanCombine( *pNewRedl ) &&
     859           0 :                             ( !n ||
     860           0 :                              *(*mpRedlineTable)[ n-1 ]->End() != *pRStt ))
     861             :                         {
     862           0 :                             pRedl->SetStart( *pStt, pRStt );
     863             :                             // re-insert
     864           0 :                             mpRedlineTable->Remove( n );
     865           0 :                             mpRedlineTable->Insert( pRedl );
     866             : 
     867           0 :                             bMerged = true;
     868           0 :                             bDelete = true;
     869             :                         }
     870          96 :                         else if ( POS_OUTSIDE == eCmpPos )
     871             :                         {
     872             :                             // own insert-over-insert redlines:
     873             :                             // just scrap the inside ones
     874           0 :                             mpRedlineTable->DeleteAndDestroy( n );
     875           0 :                             bDec = true;
     876             :                         }
     877          96 :                         else if( POS_OVERLAP_BEHIND == eCmpPos )
     878             :                         {
     879           0 :                             *pStt = *pREnd;
     880           0 :                             if( ( *pStt == *pEnd ) &&
     881           0 :                                 ( pNewRedl->GetContentIdx() == NULL ) )
     882           0 :                                 bDelete = true;
     883             :                         }
     884          96 :                         else if( POS_OVERLAP_BEFORE == eCmpPos )
     885             :                         {
     886           0 :                             *pEnd = *pRStt;
     887           0 :                             if( ( *pStt == *pEnd ) &&
     888           0 :                                 ( pNewRedl->GetContentIdx() == NULL ) )
     889           0 :                                 bDelete = true;
     890             :                         }
     891          96 :                         else if( POS_INSIDE == eCmpPos || POS_EQUAL == eCmpPos)
     892           0 :                             bDelete = true;
     893             : 
     894         336 :                         if( bDelete )
     895             :                         {
     896         240 :                             delete pNewRedl, pNewRedl = 0;
     897         240 :                             bCompress = true;
     898             :                         }
     899             :                     }
     900         321 :                     else if( POS_INSIDE == eCmpPos )
     901             :                     {
     902             :                         // split up
     903           0 :                         if( *pEnd != *pREnd )
     904             :                         {
     905           0 :                             SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
     906           0 :                             pCpy->SetStart( *pEnd );
     907           0 :                             mpRedlineTable->Insert( pCpy );
     908             :                         }
     909           0 :                         pRedl->SetEnd( *pStt, pREnd );
     910           0 :                         if( ( *pStt == *pRStt ) &&
     911           0 :                             ( pRedl->GetContentIdx() == NULL ) )
     912             :                         {
     913           0 :                             mpRedlineTable->DeleteAndDestroy( n );
     914           0 :                             bDec = true;
     915             :                         }
     916           0 :                         else if( !pRedl->HasValidRange() )
     917             :                         {
     918             :                             // re-insert
     919           0 :                             mpRedlineTable->Remove( n );
     920           0 :                             mpRedlineTable->Insert( pRedl );
     921             :                         }
     922             :                     }
     923         321 :                     else if ( POS_OUTSIDE == eCmpPos )
     924             :                     {
     925             :                         // handle overlapping redlines in broken documents
     926             : 
     927             :                         // split up the new redline, since it covers the
     928             :                         // existing redline. Insert the first part, and
     929             :                         // progress with the remainder as usual
     930           0 :                         SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
     931           0 :                         pSplit->SetEnd( *pRStt );
     932           0 :                         pNewRedl->SetStart( *pREnd );
     933           0 :                         mpRedlineTable->Insert( pSplit );
     934           0 :                         if( *pStt == *pEnd && pNewRedl->GetContentIdx() == NULL )
     935             :                         {
     936           0 :                             delete pNewRedl;
     937           0 :                             pNewRedl = 0;
     938           0 :                             bCompress = true;
     939             :                         }
     940             :                     }
     941         321 :                     else if ( POS_OVERLAP_BEHIND == eCmpPos )
     942             :                     {
     943             :                         // handle overlapping redlines in broken documents
     944           0 :                         pNewRedl->SetStart( *pREnd );
     945             :                     }
     946         321 :                     else if ( POS_OVERLAP_BEFORE == eCmpPos )
     947             :                     {
     948             :                         // handle overlapping redlines in broken documents
     949           0 :                         *pEnd = *pRStt;
     950           0 :                         if( ( *pStt == *pEnd ) &&
     951           0 :                             ( pNewRedl->GetContentIdx() == NULL ) )
     952             :                         {
     953           0 :                             delete pNewRedl;
     954           0 :                             pNewRedl = 0;
     955           0 :                             bCompress = true;
     956             :                         }
     957             :                     }
     958         657 :                     break;
     959             :                 case nsRedlineType_t::REDLINE_DELETE:
     960          28 :                     if( POS_INSIDE == eCmpPos )
     961             :                     {
     962             :                         // split up
     963           0 :                         if( *pEnd != *pREnd )
     964             :                         {
     965           0 :                             SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
     966           0 :                             pCpy->SetStart( *pEnd );
     967           0 :                             mpRedlineTable->Insert( pCpy );
     968             :                         }
     969           0 :                         pRedl->SetEnd( *pStt, pREnd );
     970           0 :                         if( ( *pStt == *pRStt ) &&
     971           0 :                             ( pRedl->GetContentIdx() == NULL ) )
     972             :                         {
     973           0 :                             mpRedlineTable->DeleteAndDestroy( n );
     974           0 :                             bDec = true;
     975             :                         }
     976           0 :                         else if( !pRedl->HasValidRange() )
     977             :                         {
     978             :                             // re-insert
     979           0 :                             mpRedlineTable->Remove( n );
     980           0 :                             mpRedlineTable->Insert( pRedl, n );
     981             :                         }
     982             :                     }
     983          28 :                     else if ( POS_OUTSIDE == eCmpPos )
     984             :                     {
     985             :                         // handle overlapping redlines in broken documents
     986             : 
     987             :                         // split up the new redline, since it covers the
     988             :                         // existing redline. Insert the first part, and
     989             :                         // progress with the remainder as usual
     990           0 :                         SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
     991           0 :                         pSplit->SetEnd( *pRStt );
     992           0 :                         pNewRedl->SetStart( *pREnd );
     993           0 :                         mpRedlineTable->Insert( pSplit );
     994           0 :                         if( *pStt == *pEnd && pNewRedl->GetContentIdx() == NULL )
     995             :                         {
     996           0 :                             delete pNewRedl;
     997           0 :                             pNewRedl = 0;
     998           0 :                             bCompress = true;
     999             :                         }
    1000             :                     }
    1001          28 :                     else if ( POS_EQUAL == eCmpPos )
    1002             :                     {
    1003             :                         // handle identical redlines in broken documents
    1004             :                         // delete old (delete) redline
    1005           0 :                         mpRedlineTable->DeleteAndDestroy( n );
    1006           0 :                         bDec = true;
    1007             :                     }
    1008          28 :                     else if ( POS_OVERLAP_BEHIND == eCmpPos )
    1009             :                     {   // Another workaround for broken redlines
    1010           0 :                         pNewRedl->SetStart( *pREnd );
    1011             :                     }
    1012          28 :                     break;
    1013             :                 case nsRedlineType_t::REDLINE_FORMAT:
    1014          27 :                     switch( eCmpPos )
    1015             :                     {
    1016             :                     case POS_OVERLAP_BEFORE:
    1017           0 :                         pRedl->SetStart( *pEnd, pRStt );
    1018             :                         // re-insert
    1019           0 :                         mpRedlineTable->Remove( n );
    1020           0 :                         mpRedlineTable->Insert( pRedl, n );
    1021           0 :                         bDec = true;
    1022           0 :                         break;
    1023             : 
    1024             :                     case POS_OVERLAP_BEHIND:
    1025           0 :                         pRedl->SetEnd( *pStt, pREnd );
    1026           0 :                         if( *pStt == *pRStt && pRedl->GetContentIdx() == NULL )
    1027             :                         {
    1028           0 :                             mpRedlineTable->DeleteAndDestroy( n );
    1029           0 :                             bDec = true;
    1030             :                         }
    1031           0 :                         break;
    1032             : 
    1033             :                     case POS_EQUAL:
    1034             :                     case POS_OUTSIDE:
    1035             :                         // Overlaps the current one completely or has the
    1036             :                         // same dimension, delete the old one
    1037          22 :                         mpRedlineTable->DeleteAndDestroy( n );
    1038          22 :                         bDec = true;
    1039          22 :                         break;
    1040             : 
    1041             :                     case POS_INSIDE:
    1042             :                         // Overlaps the current one completely,
    1043             :                         // split or shorten the new one
    1044           0 :                         if( *pEnd != *pREnd )
    1045             :                         {
    1046           0 :                             if( *pEnd != *pRStt )
    1047             :                             {
    1048           0 :                                 SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
    1049           0 :                                 pNew->SetStart( *pEnd );
    1050           0 :                                 pRedl->SetEnd( *pStt, pREnd );
    1051           0 :                                 if( *pStt == *pRStt && pRedl->GetContentIdx() == NULL )
    1052           0 :                                     mpRedlineTable->DeleteAndDestroy( n );
    1053           0 :                                 AppendRedline( pNew, bCallDelete );
    1054           0 :                                 n = 0;      // re-initialize
    1055           0 :                                 bDec = true;
    1056             :                             }
    1057             :                         }
    1058             :                         else
    1059           0 :                             pRedl->SetEnd( *pStt, pREnd );
    1060           0 :                         break;
    1061             :                     default:
    1062           5 :                         break;
    1063             :                     }
    1064          27 :                     break;
    1065             :                 default:
    1066           1 :                     break;
    1067             :                 }
    1068         713 :                 break;
    1069             : 
    1070             :             case nsRedlineType_t::REDLINE_DELETE:
    1071       81134 :                 switch( pRedl->GetType() )
    1072             :                 {
    1073             :                 case nsRedlineType_t::REDLINE_DELETE:
    1074       17059 :                     switch( eCmpPos )
    1075             :                     {
    1076             :                     case POS_OUTSIDE:
    1077             :                         {
    1078             :                             // Overlaps the current one completely,
    1079             :                             // split the new one
    1080           0 :                             if( *pEnd != *pREnd )
    1081             :                             {
    1082           0 :                                 SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
    1083           0 :                                 pNew->SetStart( *pREnd );
    1084           0 :                                 pNewRedl->SetEnd( *pRStt, pEnd );
    1085           0 :                                 AppendRedline( pNew, bCallDelete );
    1086           0 :                                 n = 0;      // re-initialize
    1087           0 :                                 bDec = true;
    1088             :                             }
    1089             :                             else
    1090           0 :                                 pNewRedl->SetEnd( *pRStt, pEnd );
    1091             :                         }
    1092           0 :                         break;
    1093             : 
    1094             :                     case POS_INSIDE:
    1095             :                     case POS_EQUAL:
    1096           0 :                         delete pNewRedl, pNewRedl = 0;
    1097           0 :                         bCompress = true;
    1098           0 :                         break;
    1099             : 
    1100             :                     case POS_OVERLAP_BEFORE:
    1101             :                     case POS_OVERLAP_BEHIND:
    1102           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1103           0 :                             pRedl->CanCombine( *pNewRedl ))
    1104             :                         {
    1105             :                             // If that's the case we can merge it, meaning
    1106             :                             // the new one covers this well
    1107           0 :                             if( POS_OVERLAP_BEHIND == eCmpPos )
    1108           0 :                                 pNewRedl->SetStart( *pRStt, pStt );
    1109             :                             else
    1110           0 :                                 pNewRedl->SetEnd( *pREnd, pEnd );
    1111           0 :                             mpRedlineTable->DeleteAndDestroy( n );
    1112           0 :                             bDec = true;
    1113             :                         }
    1114           0 :                         else if( POS_OVERLAP_BEHIND == eCmpPos )
    1115           0 :                             pNewRedl->SetStart( *pREnd, pStt );
    1116             :                         else
    1117           0 :                             pNewRedl->SetEnd( *pRStt, pEnd );
    1118           0 :                         break;
    1119             : 
    1120             :                     case POS_COLLIDE_START:
    1121             :                     case POS_COLLIDE_END:
    1122         750 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1123         375 :                             pRedl->CanCombine( *pNewRedl ) )
    1124             :                         {
    1125         355 :                             if( IsHideChanges( meRedlineMode ))
    1126             :                             {
    1127             :                                 // Before we can merge, we make it visible!
    1128             :                                 // We insert temporarily so that pNew is
    1129             :                                 // also dealt with when moving the indices.
    1130           0 :                                 mpRedlineTable->Insert(pNewRedl);
    1131           0 :                                 pRedl->Show(0, mpRedlineTable->GetPos(pRedl));
    1132           0 :                                 mpRedlineTable->Remove( pNewRedl );
    1133           0 :                                 pRStt = pRedl->Start();
    1134           0 :                                 pREnd = pRedl->End();
    1135             :                             }
    1136             : 
    1137             :                             // If that's the case we can merge it, meaning
    1138             :                             // the new one covers this well
    1139         355 :                             if( POS_COLLIDE_START == eCmpPos )
    1140         355 :                                 pNewRedl->SetStart( *pRStt, pStt );
    1141             :                             else
    1142           0 :                                 pNewRedl->SetEnd( *pREnd, pEnd );
    1143             : 
    1144             :                             // delete current (below), and restart process with
    1145             :                             // previous
    1146         355 :                             sal_uInt16 nToBeDeleted = n;
    1147         355 :                             bDec = true;
    1148             : 
    1149         355 :                             if( *(pNewRedl->Start()) <= *pREnd )
    1150             :                             {
    1151             :                                 // Whoooah, we just extended the new 'redline'
    1152             :                                 // beyond previous redlines, so better start
    1153             :                                 // again. Of course this is not supposed to
    1154             :                                 // happen, and in an ideal world it doesn't,
    1155             :                                 // but unfortunately this code is buggy and
    1156             :                                 // totally rotten so it does happen and we
    1157             :                                 // better fix it.
    1158         355 :                                 n = 0;
    1159         355 :                                 bDec = true;
    1160             :                             }
    1161             : 
    1162         355 :                             mpRedlineTable->DeleteAndDestroy( nToBeDeleted );
    1163             :                         }
    1164         375 :                         break;
    1165             :                     default:
    1166       16684 :                         break;
    1167             :                     }
    1168       17059 :                     break;
    1169             : 
    1170             :                 case nsRedlineType_t::REDLINE_INSERT:
    1171             :                 {
    1172             :                     // b62341295: Do not throw away redlines
    1173             :                     // even if they are not allowed to be combined
    1174        9503 :                     RedlineMode_t eOld = meRedlineMode;
    1175       19005 :                     if( !( eOld & nsRedlineMode_t::REDLINE_DONTCOMBINE_REDLINES ) &&
    1176        9502 :                         pRedl->IsOwnRedline( *pNewRedl ) )
    1177             :                     {
    1178             : 
    1179             :               // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
    1180             :               // The ShowMode needs to be retained!
    1181        9499 :               meRedlineMode = (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE));
    1182        9499 :                         switch( eCmpPos )
    1183             :                         {
    1184             :                         case POS_EQUAL:
    1185           0 :                             bCompress = true;
    1186           0 :                             mpRedlineTable->DeleteAndDestroy( n );
    1187           0 :                             bDec = true;
    1188             :                             // no break!
    1189             : 
    1190             :                         case POS_INSIDE:
    1191           0 :                             if( bCallDelete )
    1192             :                             {
    1193           0 :                               meRedlineMode = (RedlineMode_t)(meRedlineMode | nsRedlineMode_t::REDLINE_IGNOREDELETE_REDLINES);
    1194             : 
    1195             :                                 // DeleteAndJoin does not yield the
    1196             :                                 // desired result if there is no paragraph to
    1197             :                                 // join with, i.e. at the end of the document.
    1198             :                                 // For this case, we completely delete the
    1199             :                                 // paragraphs (if, of course, we also start on
    1200             :                                 // a paragraph boundary).
    1201           0 :                                 if( (pStt->nContent == 0) &&
    1202           0 :                                     pEnd->nNode.GetNode().IsEndNode() )
    1203             :                                 {
    1204           0 :                                     pEnd->nNode--;
    1205             :                                     pEnd->nContent.Assign(
    1206           0 :                                         pEnd->nNode.GetNode().GetTextNode(), 0);
    1207           0 :                                     m_rDoc.getIDocumentContentOperations().DelFullPara( *pNewRedl );
    1208             :                                 }
    1209             :                                 else
    1210           0 :                                     m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
    1211             : 
    1212           0 :                                 bCompress = true;
    1213             :                             }
    1214           0 :                             delete pNewRedl, pNewRedl = 0;
    1215           0 :                             break;
    1216             : 
    1217             :                         case POS_OUTSIDE:
    1218             :                             {
    1219           0 :                                 mpRedlineTable->Remove( n );
    1220           0 :                                 bDec = true;
    1221             :                                 // We insert temporarily so that pNew is
    1222             :                                 // also dealt with when moving the indices.
    1223           0 :                                 if( bCallDelete )
    1224             :                                 {
    1225           0 :                                     mpRedlineTable->Insert( pNewRedl );
    1226           0 :                                     m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pRedl );
    1227           0 :                                     if( !mpRedlineTable->Remove( pNewRedl ) )
    1228           0 :                                         pNewRedl = 0;
    1229             :                                 }
    1230           0 :                                 delete pRedl;
    1231             :                             }
    1232           0 :                             break;
    1233             : 
    1234             :                         case POS_OVERLAP_BEFORE:
    1235             :                             {
    1236           0 :                                 SwPaM aPam( *pRStt, *pEnd );
    1237             : 
    1238           0 :                                 if( *pEnd == *pREnd )
    1239           0 :                                     mpRedlineTable->DeleteAndDestroy( n );
    1240             :                                 else
    1241             :                                 {
    1242           0 :                                     pRedl->SetStart( *pEnd, pRStt );
    1243             :                                     // re-insert
    1244           0 :                                     mpRedlineTable->Remove( n );
    1245           0 :                                     mpRedlineTable->Insert( pRedl, n );
    1246             :                                 }
    1247             : 
    1248           0 :                                 if( bCallDelete )
    1249             :                                 {
    1250             :                                     // We insert temporarily so that pNew is
    1251             :                                     // also dealt with when moving the indices.
    1252           0 :                                     mpRedlineTable->Insert( pNewRedl );
    1253           0 :                                     m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
    1254           0 :                                     if( !mpRedlineTable->Remove( pNewRedl ) )
    1255           0 :                                         pNewRedl = 0;
    1256           0 :                                     n = 0;      // re-initialize
    1257             :                                 }
    1258           0 :                                 bDec = true;
    1259             :                             }
    1260           0 :                             break;
    1261             : 
    1262             :                         case POS_OVERLAP_BEHIND:
    1263             :                             {
    1264           0 :                                 SwPaM aPam( *pStt, *pREnd );
    1265             : 
    1266           0 :                                 if( *pStt == *pRStt )
    1267             :                                 {
    1268           0 :                                     mpRedlineTable->DeleteAndDestroy( n );
    1269           0 :                                     bDec = true;
    1270             :                                 }
    1271             :                                 else
    1272           0 :                                     pRedl->SetEnd( *pStt, pREnd );
    1273             : 
    1274           0 :                                 if( bCallDelete )
    1275             :                                 {
    1276             :                                     // We insert temporarily so that pNew is
    1277             :                                     // also dealt with when moving the indices.
    1278           0 :                                     mpRedlineTable->Insert( pNewRedl );
    1279           0 :                                     m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
    1280           0 :                                     if( !mpRedlineTable->Remove( pNewRedl ) )
    1281           0 :                                         pNewRedl = 0;
    1282           0 :                                     n = 0;      // re-initialize
    1283           0 :                                     bDec = true;
    1284           0 :                                 }
    1285             :                             }
    1286           0 :                             break;
    1287             :                         default:
    1288        9499 :                             break;
    1289             :                         }
    1290             : 
    1291        9499 :                         meRedlineMode = eOld;
    1292             :                     }
    1293             :                     else
    1294             :                     {
    1295             :                         // it may be necessary to split the existing redline in
    1296             :                         // two. In this case, pRedl will be changed to cover
    1297             :                         // only part of it's former range, and pNew will cover
    1298             :                         // the remainder.
    1299           4 :                         SwRangeRedline* pNew = 0;
    1300             : 
    1301           4 :                         switch( eCmpPos )
    1302             :                         {
    1303             :                         case POS_EQUAL:
    1304             :                             {
    1305           2 :                                 pRedl->PushData( *pNewRedl );
    1306           2 :                                 delete pNewRedl, pNewRedl = 0;
    1307           2 :                                 if( IsHideChanges( meRedlineMode ))
    1308             :                                 {
    1309           0 :                                     pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
    1310             :                                 }
    1311           2 :                                 bCompress = true;
    1312             :                             }
    1313           2 :                             break;
    1314             : 
    1315             :                         case POS_INSIDE:
    1316             :                             {
    1317           0 :                                 if( *pRStt == *pStt )
    1318             :                                 {
    1319             :                                     // #i97421#
    1320             :                                     // redline w/out extent loops
    1321           0 :                                     if (*pStt != *pEnd)
    1322             :                                     {
    1323           0 :                                         pNewRedl->PushData( *pRedl, false );
    1324           0 :                                         pRedl->SetStart( *pEnd, pRStt );
    1325             :                                         // re-insert
    1326           0 :                                         mpRedlineTable->Remove( n );
    1327           0 :                                         mpRedlineTable->Insert( pRedl, n );
    1328           0 :                                         bDec = true;
    1329             :                                     }
    1330             :                                 }
    1331             :                                 else
    1332             :                                 {
    1333           0 :                                     pNewRedl->PushData( *pRedl, false );
    1334           0 :                                     if( *pREnd != *pEnd )
    1335             :                                     {
    1336           0 :                                         pNew = new SwRangeRedline( *pRedl );
    1337           0 :                                         pNew->SetStart( *pEnd );
    1338             :                                     }
    1339           0 :                                     pRedl->SetEnd( *pStt, pREnd );
    1340           0 :                                     if( !pRedl->HasValidRange() )
    1341             :                                     {
    1342             :                                         // re-insert
    1343           0 :                                         mpRedlineTable->Remove( n );
    1344           0 :                                         mpRedlineTable->Insert( pRedl, n );
    1345             :                                     }
    1346             :                                 }
    1347             :                             }
    1348           0 :                             break;
    1349             : 
    1350             :                         case POS_OUTSIDE:
    1351             :                             {
    1352           0 :                                 pRedl->PushData( *pNewRedl );
    1353           0 :                                 if( *pEnd == *pREnd )
    1354           0 :                                     pNewRedl->SetEnd( *pRStt, pEnd );
    1355             :                                 else
    1356             :                                 {
    1357           0 :                                     pNew = new SwRangeRedline( *pNewRedl );
    1358           0 :                                     pNew->SetEnd( *pRStt );
    1359           0 :                                     pNewRedl->SetStart( *pREnd, pStt );
    1360             :                                 }
    1361           0 :                                 bCompress = true;
    1362             :                             }
    1363           0 :                             break;
    1364             : 
    1365             :                         case POS_OVERLAP_BEFORE:
    1366             :                             {
    1367           0 :                                 if( *pEnd == *pREnd )
    1368             :                                 {
    1369           0 :                                     pRedl->PushData( *pNewRedl );
    1370           0 :                                     pNewRedl->SetEnd( *pRStt, pEnd );
    1371           0 :                                     if( IsHideChanges( meRedlineMode ))
    1372             :                                     {
    1373           0 :                                         mpRedlineTable->Insert(pNewRedl);
    1374           0 :                                         pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
    1375           0 :                                         mpRedlineTable->Remove( pNewRedl );
    1376             :                                     }
    1377             :                                 }
    1378             :                                 else
    1379             :                                 {
    1380           0 :                                     pNew = new SwRangeRedline( *pRedl );
    1381           0 :                                     pNew->PushData( *pNewRedl );
    1382           0 :                                     pNew->SetEnd( *pEnd );
    1383           0 :                                     pNewRedl->SetEnd( *pRStt, pEnd );
    1384           0 :                                     pRedl->SetStart( *pNew->End(), pRStt ) ;
    1385             :                                     // re-insert
    1386           0 :                                     mpRedlineTable->Remove( n );
    1387           0 :                                     mpRedlineTable->Insert( pRedl );
    1388           0 :                                     bDec = true;
    1389             :                                 }
    1390             :                             }
    1391           0 :                             break;
    1392             : 
    1393             :                         case POS_OVERLAP_BEHIND:
    1394             :                             {
    1395           0 :                                 if( *pStt == *pRStt )
    1396             :                                 {
    1397           0 :                                     pRedl->PushData( *pNewRedl );
    1398           0 :                                     pNewRedl->SetStart( *pREnd, pStt );
    1399           0 :                                     if( IsHideChanges( meRedlineMode ))
    1400             :                                     {
    1401           0 :                                         mpRedlineTable->Insert( pNewRedl );
    1402           0 :                                         pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
    1403           0 :                                         mpRedlineTable->Remove( pNewRedl );
    1404             :                                     }
    1405             :                                 }
    1406             :                                 else
    1407             :                                 {
    1408           0 :                                     pNew = new SwRangeRedline( *pRedl );
    1409           0 :                                     pNew->PushData( *pNewRedl );
    1410           0 :                                     pNew->SetStart( *pStt );
    1411           0 :                                     pNewRedl->SetStart( *pREnd, pStt );
    1412           0 :                                     pRedl->SetEnd( *pNew->Start(), pREnd );
    1413           0 :                                     if( !pRedl->HasValidRange() )
    1414             :                                     {
    1415             :                                         // re-insert
    1416           0 :                                         mpRedlineTable->Remove( n );
    1417           0 :                                         mpRedlineTable->Insert( pRedl );
    1418             :                                     }
    1419             :                                 }
    1420             :                             }
    1421           0 :                             break;
    1422             :                         default:
    1423           2 :                             break;
    1424             :                         }
    1425             : 
    1426             :                         // insert the pNew part (if it exists)
    1427           4 :                         if( pNew )
    1428             :                         {
    1429           0 :                             mpRedlineTable->Insert( pNew );
    1430             : 
    1431             :                             // pNew must be deleted if Insert() wasn't
    1432             :                             // successful. But that can't happen, since pNew is
    1433             :                             // part of the original pRedl redline.
    1434             :                             // OSL_ENSURE( bRet, "Can't insert existing redline?" );
    1435             : 
    1436             :                             // restart (now with pRedl being split up)
    1437           0 :                             n = 0;
    1438           0 :                             bDec = true;
    1439             :                         }
    1440             :                     }
    1441             :                 }
    1442        9503 :                 break;
    1443             : 
    1444             :                 case nsRedlineType_t::REDLINE_FORMAT:
    1445       23820 :                     switch( eCmpPos )
    1446             :                     {
    1447             :                     case POS_OVERLAP_BEFORE:
    1448           0 :                         pRedl->SetStart( *pEnd, pRStt );
    1449             :                         // re-insert
    1450           0 :                         mpRedlineTable->Remove( n );
    1451           0 :                         mpRedlineTable->Insert( pRedl, n );
    1452           0 :                         bDec = true;
    1453           0 :                         break;
    1454             : 
    1455             :                     case POS_OVERLAP_BEHIND:
    1456           0 :                         pRedl->SetEnd( *pStt, pREnd );
    1457           0 :                         break;
    1458             : 
    1459             :                     case POS_EQUAL:
    1460             :                     case POS_OUTSIDE:
    1461             :                         // Overlaps the current one completely or has the
    1462             :                         // same dimension, delete the old one
    1463         299 :                         mpRedlineTable->DeleteAndDestroy( n );
    1464         299 :                         bDec = true;
    1465         299 :                         break;
    1466             : 
    1467             :                     case POS_INSIDE:
    1468             :                         // Overlaps the current one completely,
    1469             :                         // split or shorten the new one
    1470           0 :                         if( *pEnd != *pREnd )
    1471             :                         {
    1472           0 :                             if( *pEnd != *pRStt )
    1473             :                             {
    1474           0 :                                 SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
    1475           0 :                                 pNew->SetStart( *pEnd );
    1476           0 :                                 pRedl->SetEnd( *pStt, pREnd );
    1477           0 :                                 if( ( *pStt == *pRStt ) &&
    1478           0 :                                     ( pRedl->GetContentIdx() == NULL ) )
    1479           0 :                                     mpRedlineTable->DeleteAndDestroy( n );
    1480           0 :                                 AppendRedline( pNew, bCallDelete );
    1481           0 :                                 n = 0;      // re-initialize
    1482           0 :                                 bDec = true;
    1483             :                             }
    1484             :                         }
    1485             :                         else
    1486           0 :                             pRedl->SetEnd( *pStt, pREnd );
    1487           0 :                         break;
    1488             :                     default:
    1489       23521 :                         break;
    1490             :                     }
    1491       23820 :                     break;
    1492             :                 default:
    1493       30752 :                     break;
    1494             :                 }
    1495       81134 :                 break;
    1496             : 
    1497             :             case nsRedlineType_t::REDLINE_FORMAT:
    1498         457 :                 switch( pRedl->GetType() )
    1499             :                 {
    1500             :                 case nsRedlineType_t::REDLINE_INSERT:
    1501             :                 case nsRedlineType_t::REDLINE_DELETE:
    1502          59 :                     switch( eCmpPos )
    1503             :                     {
    1504             :                     case POS_OVERLAP_BEFORE:
    1505           0 :                         pNewRedl->SetEnd( *pRStt, pEnd );
    1506           0 :                         break;
    1507             : 
    1508             :                     case POS_OVERLAP_BEHIND:
    1509           0 :                         pNewRedl->SetStart( *pREnd, pStt );
    1510           0 :                         break;
    1511             : 
    1512             :                     case POS_EQUAL:
    1513             :                     case POS_INSIDE:
    1514           0 :                         delete pNewRedl, pNewRedl = 0;
    1515           0 :                         break;
    1516             : 
    1517             :                     case POS_OUTSIDE:
    1518             :                         // Overlaps the current one completely,
    1519             :                         // split or shorten the new one
    1520           0 :                         if( *pEnd != *pREnd )
    1521             :                         {
    1522           0 :                             if( *pEnd != *pRStt )
    1523             :                             {
    1524           0 :                                 SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
    1525           0 :                                 pNew->SetStart( *pREnd );
    1526           0 :                                 pNewRedl->SetEnd( *pRStt, pEnd );
    1527           0 :                                 AppendRedline( pNew, bCallDelete );
    1528           0 :                                 n = 0;      // re-initialize
    1529           0 :                                 bDec = true;
    1530             :                             }
    1531             :                         }
    1532             :                         else
    1533           0 :                             pNewRedl->SetEnd( *pRStt, pEnd );
    1534           0 :                         break;
    1535             :                     default:
    1536          59 :                         break;
    1537             :                     }
    1538          59 :                     break;
    1539             :                 case nsRedlineType_t::REDLINE_FORMAT:
    1540         131 :                     switch( eCmpPos )
    1541             :                     {
    1542             :                     case POS_OUTSIDE:
    1543             :                     case POS_EQUAL:
    1544             :                         {
    1545             :                             // Overlaps the current one completely or has the
    1546             :                             // same dimension, delete the old one
    1547           0 :                             mpRedlineTable->DeleteAndDestroy( n );
    1548           0 :                             bDec = true;
    1549             :                         }
    1550           0 :                         break;
    1551             : 
    1552             :                     case POS_INSIDE:
    1553           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1554           0 :                             pRedl->CanCombine( *pNewRedl ))
    1555             :                             // own one can be ignored completely
    1556           0 :                             delete pNewRedl, pNewRedl = 0;
    1557             : 
    1558           0 :                         else if( *pREnd == *pEnd )
    1559             :                             // or else only shorten the current one
    1560           0 :                             pRedl->SetEnd( *pStt, pREnd );
    1561           0 :                         else if( *pRStt == *pStt )
    1562             :                         {
    1563             :                             // or else only shorten the current one
    1564           0 :                             pRedl->SetStart( *pEnd, pRStt );
    1565             :                             // re-insert
    1566           0 :                             mpRedlineTable->Remove( n );
    1567           0 :                             mpRedlineTable->Insert( pRedl, n );
    1568           0 :                             bDec = true;
    1569             :                         }
    1570             :                         else
    1571             :                         {
    1572             :                             // If it lies completely within the current one
    1573             :                             // we need to split it
    1574           0 :                             SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
    1575           0 :                             pNew->SetStart( *pEnd );
    1576           0 :                             pRedl->SetEnd( *pStt, pREnd );
    1577           0 :                             AppendRedline( pNew, bCallDelete );
    1578           0 :                             n = 0;      // re-initialize
    1579           0 :                             bDec = true;
    1580             :                         }
    1581           0 :                         break;
    1582             : 
    1583             :                     case POS_OVERLAP_BEFORE:
    1584             :                     case POS_OVERLAP_BEHIND:
    1585           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1586           0 :                             pRedl->CanCombine( *pNewRedl ))
    1587             :                         {
    1588             :                             // If that's the case we can merge it, meaning
    1589             :                             // the new one covers this well
    1590           0 :                             if( POS_OVERLAP_BEHIND == eCmpPos )
    1591           0 :                                 pNewRedl->SetStart( *pRStt, pStt );
    1592             :                             else
    1593           0 :                                 pNewRedl->SetEnd( *pREnd, pEnd );
    1594           0 :                             mpRedlineTable->DeleteAndDestroy( n );
    1595           0 :                             bDec = false;
    1596             :                         }
    1597           0 :                         else if( POS_OVERLAP_BEHIND == eCmpPos )
    1598           0 :                             pNewRedl->SetStart( *pREnd, pStt );
    1599             :                         else
    1600           0 :                             pNewRedl->SetEnd( *pRStt, pEnd );
    1601           0 :                         break;
    1602             : 
    1603             :                     case POS_COLLIDE_END:
    1604           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1605           0 :                             pRedl->CanCombine( *pNewRedl ) && n &&
    1606           0 :                             *(*mpRedlineTable)[ n-1 ]->End() < *pStt )
    1607             :                         {
    1608             :                             // If that's the case we can merge it, meaning
    1609             :                             // the new one covers this well
    1610           0 :                             pNewRedl->SetEnd( *pREnd, pEnd );
    1611           0 :                             mpRedlineTable->DeleteAndDestroy( n );
    1612           0 :                             bDec = true;
    1613             :                         }
    1614           0 :                         break;
    1615             :                     case POS_COLLIDE_START:
    1616         315 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1617         178 :                             pRedl->CanCombine( *pNewRedl ) &&
    1618         178 :                             n+1 < (sal_uInt16)mpRedlineTable->size() &&
    1619           0 :                             *(*mpRedlineTable)[ n+1 ]->Start() < *pEnd )
    1620             :                         {
    1621             :                             // If that's the case we can merge it, meaning
    1622             :                             // the new one covers this well
    1623           0 :                             pNewRedl->SetStart( *pRStt, pStt );
    1624           0 :                             mpRedlineTable->DeleteAndDestroy( n );
    1625           0 :                             bDec = true;
    1626             :                         }
    1627         105 :                         break;
    1628             :                     default:
    1629          26 :                         break;
    1630             :                     }
    1631         131 :                     break;
    1632             :                 default:
    1633         267 :                     break;
    1634             :                 }
    1635         457 :                 break;
    1636             : 
    1637             :             case nsRedlineType_t::REDLINE_FMTCOLL:
    1638             :                 // How should we behave here?
    1639             :                 // insert as is
    1640           0 :                 break;
    1641             :             default:
    1642         474 :                 break;
    1643             :             }
    1644             :         }
    1645             : 
    1646        2145 :         if( pNewRedl )
    1647             :         {
    1648        1917 :             if( ( *pStt == *pEnd ) &&
    1649          14 :                 ( pNewRedl->GetContentIdx() == NULL ) )
    1650             :             {   // Do not insert empty redlines
    1651           0 :                 delete pNewRedl;
    1652           0 :                 pNewRedl = 0;
    1653             :             }
    1654             :             else
    1655        1903 :                 mpRedlineTable->Insert( pNewRedl );
    1656             :         }
    1657             : 
    1658        2145 :         if( bCompress )
    1659         242 :             CompressRedlines();
    1660             :     }
    1661             :     else
    1662             :     {
    1663         328 :         if( bCallDelete && nsRedlineType_t::REDLINE_DELETE == pNewRedl->GetType() )
    1664             :         {
    1665           0 :             RedlineMode_t eOld = meRedlineMode;
    1666             :             // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
    1667             :             // The ShowMode needs to be retained!
    1668           0 :             meRedlineMode = (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE));
    1669           0 :             m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
    1670           0 :             meRedlineMode = eOld;
    1671             :         }
    1672         328 :         delete pNewRedl, pNewRedl = 0;
    1673             :     }
    1674             :     _CHECK_REDLINE( *this )
    1675             : 
    1676        2473 :     return ( 0 != pNewRedl ) || bMerged;
    1677             : }
    1678             : 
    1679          28 : bool DocumentRedlineManager::AppendTableRowRedline( SwTableRowRedline* pNewRedl, bool bCallDelete )
    1680             : {
    1681             :     (void)bCallDelete;
    1682             : 
    1683             :     // #TODO - equivalent for 'SwTableRowRedline'
    1684          28 :     bool bMerged = false;
    1685             :     /*
    1686             :     _CHECK_REDLINE( this )
    1687             :     */
    1688             : 
    1689          28 :     if (IsRedlineOn() && !IsShowOriginal(meRedlineMode))
    1690             :     {
    1691             :         // #TODO - equivalent for 'SwTableRowRedline'
    1692             :         /*
    1693             :         pNewRedl->InvalidateRange();
    1694             :         */
    1695             : 
    1696             :         // Make equivalent of 'AppendRedline' checks inside here too
    1697             : 
    1698          28 :         mpExtraRedlineTable->Insert( pNewRedl );
    1699             :     }
    1700             :     else
    1701             :     {
    1702             :         // TO DO - equivalent for 'SwTableRowRedline'
    1703             :         /*
    1704             :         if( bCallDelete && nsRedlineType_t::REDLINE_DELETE == pNewRedl->GetType() )
    1705             :         {
    1706             :             RedlineMode_t eOld = meRedlineMode;
    1707             :             // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
    1708             :             // The ShowMode needs to be retained!
    1709             :             meRedlineMode = (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE));
    1710             :             DeleteAndJoin( *pNewRedl );
    1711             :             meRedlineMode = eOld;
    1712             :         }
    1713             :         delete pNewRedl, pNewRedl = 0;
    1714             :         */
    1715             :     }
    1716             :     // #TODO - equivalent for 'SwTableRowRedline'
    1717             :     /*
    1718             :     _CHECK_REDLINE( this )
    1719             :     */
    1720             : 
    1721          28 :     return ( 0 != pNewRedl ) || bMerged;
    1722             : }
    1723             : 
    1724           6 : bool DocumentRedlineManager::AppendTableCellRedline( SwTableCellRedline* pNewRedl, bool bCallDelete )
    1725             : {
    1726             :     (void)bCallDelete;
    1727             : 
    1728             :     // #TODO - equivalent for 'SwTableCellRedline'
    1729           6 :     bool bMerged = false;
    1730             :     /*
    1731             :     _CHECK_REDLINE( this )
    1732             :     */
    1733             : 
    1734           6 :     if (IsRedlineOn() && !IsShowOriginal(meRedlineMode))
    1735             :     {
    1736             :         // #TODO - equivalent for 'SwTableCellRedline'
    1737             :         /*
    1738             :         pNewRedl->InvalidateRange();
    1739             :         */
    1740             : 
    1741             :         // Make equivalent of 'AppendRedline' checks inside here too
    1742             : 
    1743           6 :         mpExtraRedlineTable->Insert( pNewRedl );
    1744             :     }
    1745             :     else
    1746             :     {
    1747             :         // TO DO - equivalent for 'SwTableCellRedline'
    1748             :         /*
    1749             :         if( bCallDelete && nsRedlineType_t::REDLINE_DELETE == pNewRedl->GetType() )
    1750             :         {
    1751             :             RedlineMode_t eOld = meRedlineMode;
    1752             :             // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
    1753             :             // The ShowMode needs to be retained!
    1754             :             meRedlineMode = (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE));
    1755             :             DeleteAndJoin( *pNewRedl );
    1756             :             meRedlineMode = eOld;
    1757             :         }
    1758             :         delete pNewRedl, pNewRedl = 0;
    1759             :         */
    1760             :     }
    1761             :     // #TODO - equivalent for 'SwTableCellRedline'
    1762             :     /*
    1763             :     _CHECK_REDLINE( this )
    1764             :     */
    1765             : 
    1766           6 :     return ( 0 != pNewRedl ) || bMerged;
    1767             : }
    1768             : 
    1769         367 : void DocumentRedlineManager::CompressRedlines()
    1770             : {
    1771             :     _CHECK_REDLINE( *this )
    1772             : 
    1773         367 :     void (SwRangeRedline::*pFnc)(sal_uInt16, size_t) = 0;
    1774         367 :     switch( nsRedlineMode_t::REDLINE_SHOW_MASK & meRedlineMode )
    1775             :     {
    1776             :     case nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE:
    1777         214 :         pFnc = &SwRangeRedline::Show;
    1778         214 :         break;
    1779             :     case nsRedlineMode_t::REDLINE_SHOW_INSERT:
    1780         127 :         pFnc = &SwRangeRedline::Hide;
    1781         127 :         break;
    1782             :     }
    1783             : 
    1784             :     // Try to merge identical ones
    1785        4100 :     for( size_t n = 1; n < mpRedlineTable->size(); ++n )
    1786             :     {
    1787        3733 :         SwRangeRedline* pPrev = (*mpRedlineTable)[ n-1 ],
    1788        3733 :                     * pCur = (*mpRedlineTable)[ n ];
    1789        3733 :         const SwPosition* pPrevStt = pPrev->Start(),
    1790        3733 :                         * pPrevEnd = pPrevStt == pPrev->GetPoint()
    1791        3733 :                             ? pPrev->GetMark() : pPrev->GetPoint();
    1792        3733 :         const SwPosition* pCurStt = pCur->Start(),
    1793        3733 :                         * pCurEnd = pCurStt == pCur->GetPoint()
    1794        3733 :                             ? pCur->GetMark() : pCur->GetPoint();
    1795       10288 :         if( *pPrevEnd == *pCurStt && pPrev->CanCombine( *pCur ) &&
    1796         478 :             pPrevStt->nNode.GetNode().StartOfSectionNode() ==
    1797        4689 :             pCurEnd->nNode.GetNode().StartOfSectionNode() &&
    1798         478 :             !pCurEnd->nNode.GetNode().StartOfSectionNode()->IsTableNode() )
    1799             :         {
    1800             :             // we then can merge them
    1801         478 :             size_t nPrevIndex = n-1;
    1802         478 :             pPrev->Show(0, nPrevIndex);
    1803         478 :             pCur->Show(0, n);
    1804             : 
    1805         478 :             pPrev->SetEnd( *pCur->End() );
    1806         478 :             mpRedlineTable->DeleteAndDestroy( n );
    1807         478 :             --n;
    1808         478 :             if( pFnc )
    1809         465 :                 (pPrev->*pFnc)(0, nPrevIndex);
    1810             :         }
    1811             :     }
    1812             :     _CHECK_REDLINE( *this )
    1813             : 
    1814             :     // #TODO - add 'SwExtraRedlineTable' also ?
    1815         367 : }
    1816             : 
    1817       12095 : bool DocumentRedlineManager::SplitRedline( const SwPaM& rRange )
    1818             : {
    1819       12095 :     bool bChg = false;
    1820       12095 :     sal_uInt16 n = 0;
    1821       12095 :     const SwPosition* pStt = rRange.Start();
    1822       12095 :     const SwPosition* pEnd = rRange.End();
    1823       12095 :     GetRedline( *pStt, &n );
    1824       12291 :     for ( ; n < mpRedlineTable->size(); ++n)
    1825             :     {
    1826         442 :         SwRangeRedline * pRedline = (*mpRedlineTable)[ n ];
    1827         442 :         SwPosition *const pRedlineStart = pRedline->Start();
    1828         442 :         SwPosition *const pRedlineEnd = pRedline->End();
    1829         926 :         if (*pRedlineStart <= *pStt && *pStt <= *pRedlineEnd &&
    1830         484 :             *pRedlineStart <= *pEnd && *pEnd <= *pRedlineEnd)
    1831             :         {
    1832           6 :             bChg = true;
    1833           6 :             int nn = 0;
    1834           6 :             if (*pStt == *pRedlineStart)
    1835           1 :                 nn += 1;
    1836           6 :             if (*pEnd == *pRedlineEnd)
    1837           5 :                 nn += 2;
    1838             : 
    1839           6 :             SwRangeRedline* pNew = 0;
    1840           6 :             switch( nn )
    1841             :             {
    1842             :             case 0:
    1843           1 :                 pNew = new SwRangeRedline( *pRedline );
    1844           1 :                 pRedline->SetEnd( *pStt, pRedlineEnd );
    1845           1 :                 pNew->SetStart( *pEnd );
    1846           1 :                 break;
    1847             : 
    1848             :             case 1:
    1849           0 :                 *pRedlineStart = *pEnd;
    1850           0 :                 break;
    1851             : 
    1852             :             case 2:
    1853           4 :                 *pRedlineEnd = *pStt;
    1854           4 :                 break;
    1855             : 
    1856             :             case 3:
    1857           1 :                 pRedline->InvalidateRange();
    1858           1 :                 mpRedlineTable->DeleteAndDestroy( n-- );
    1859           1 :                 pRedline = nullptr;
    1860           1 :                 break;
    1861             :             }
    1862           6 :             if (pRedline && !pRedline->HasValidRange())
    1863             :             {
    1864             :                 // re-insert
    1865           0 :                 mpRedlineTable->Remove( n );
    1866           0 :                 mpRedlineTable->Insert( pRedline, n );
    1867             :             }
    1868           6 :             if( pNew )
    1869           1 :                 mpRedlineTable->Insert( pNew, n );
    1870             :         }
    1871         436 :         else if (*pEnd < *pRedlineStart)
    1872         246 :             break;
    1873             :     }
    1874       12095 :     return bChg;
    1875             : 
    1876             :     // #TODO - add 'SwExtraRedlineTable' also ?
    1877             : }
    1878             : 
    1879        5264 : bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUndo,
    1880             :                             sal_uInt16 nDelType )
    1881             : {
    1882       15780 :     if( nsRedlineMode_t::REDLINE_IGNOREDELETE_REDLINES & meRedlineMode ||
    1883       10516 :         !rRange.HasMark() || *rRange.GetMark() == *rRange.GetPoint() )
    1884          12 :         return false;
    1885             : 
    1886        5252 :     bool bChg = false;
    1887             : 
    1888        5252 :     if (bSaveInUndo && m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    1889             :     {
    1890           7 :         SwUndoRedline* pUndo = new SwUndoRedline( UNDO_REDLINE, rRange );
    1891           7 :         if( pUndo->GetRedlSaveCount() )
    1892             :         {
    1893           0 :             m_rDoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
    1894             :         }
    1895             :         else
    1896           7 :             delete pUndo;
    1897             :     }
    1898             : 
    1899        5252 :     const SwPosition* pStt = rRange.Start(),
    1900        5252 :                     * pEnd = pStt == rRange.GetPoint() ? rRange.GetMark()
    1901        5252 :                                                        : rRange.GetPoint();
    1902        5252 :     sal_uInt16 n = 0;
    1903        5252 :     GetRedline( *pStt, &n );
    1904        5750 :     for( ; n < mpRedlineTable->size() ; ++n )
    1905             :     {
    1906         498 :         SwRangeRedline* pRedl = (*mpRedlineTable)[ n ];
    1907         498 :         if( USHRT_MAX != nDelType && nDelType != pRedl->GetType() )
    1908           0 :             continue;
    1909             : 
    1910         498 :         SwPosition* pRStt = pRedl->Start(),
    1911         623 :                   * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
    1912         623 :                                                        : pRedl->GetPoint();
    1913         498 :         switch( ComparePosition( *pStt, *pEnd, *pRStt, *pREnd ) )
    1914             :         {
    1915             :         case POS_EQUAL:
    1916             :         case POS_OUTSIDE:
    1917         368 :             pRedl->InvalidateRange();
    1918         368 :             mpRedlineTable->DeleteAndDestroy( n-- );
    1919         368 :             bChg = true;
    1920         368 :             break;
    1921             : 
    1922             :         case POS_OVERLAP_BEFORE:
    1923           0 :                 pRedl->InvalidateRange();
    1924           0 :                 pRedl->SetStart( *pEnd, pRStt );
    1925             :                 // re-insert
    1926           0 :                 mpRedlineTable->Remove( n );
    1927           0 :                 mpRedlineTable->Insert( pRedl );
    1928           0 :                 --n;
    1929           0 :             break;
    1930             : 
    1931             :         case POS_OVERLAP_BEHIND:
    1932           0 :                 pRedl->InvalidateRange();
    1933           0 :                 pRedl->SetEnd( *pStt, pREnd );
    1934           0 :                 if( !pRedl->HasValidRange() )
    1935             :                 {
    1936             :                     // re-insert
    1937           0 :                     mpRedlineTable->Remove( n );
    1938           0 :                     mpRedlineTable->Insert( pRedl );
    1939           0 :                     --n;
    1940             :                 }
    1941           0 :             break;
    1942             : 
    1943             :         case POS_INSIDE:
    1944             :             {
    1945             :                 // this one needs to be splitted
    1946           0 :                 pRedl->InvalidateRange();
    1947           0 :                 if( *pRStt == *pStt )
    1948             :                 {
    1949           0 :                     pRedl->SetStart( *pEnd, pRStt );
    1950             :                     // re-insert
    1951           0 :                     mpRedlineTable->Remove( n );
    1952           0 :                     mpRedlineTable->Insert( pRedl );
    1953           0 :                     --n;
    1954             :                 }
    1955             :                 else
    1956             :                 {
    1957             :                     SwRangeRedline* pCpy;
    1958           0 :                     if( *pREnd != *pEnd )
    1959             :                     {
    1960           0 :                         pCpy = new SwRangeRedline( *pRedl );
    1961           0 :                         pCpy->SetStart( *pEnd );
    1962             :                     }
    1963             :                     else
    1964           0 :                         pCpy = 0;
    1965           0 :                     pRedl->SetEnd( *pStt, pREnd );
    1966           0 :                     if( !pRedl->HasValidRange() )
    1967             :                     {
    1968             :                         // re-insert
    1969           0 :                         mpRedlineTable->Remove( n );
    1970           0 :                         mpRedlineTable->Insert( pRedl );
    1971           0 :                         --n;
    1972             :                     }
    1973           0 :                     if( pCpy )
    1974           0 :                         mpRedlineTable->Insert( pCpy );
    1975             :                 }
    1976             :             }
    1977           0 :             break;
    1978             : 
    1979             :         case POS_COLLIDE_END:
    1980             :         case POS_BEFORE:
    1981         130 :             n = mpRedlineTable->size();
    1982         130 :             break;
    1983             :         default:
    1984           0 :             break;
    1985             :         }
    1986             :     }
    1987             : 
    1988        5252 :     if( bChg )
    1989          36 :         m_rDoc.getIDocumentState().SetModified();
    1990             : 
    1991        5252 :     return bChg;
    1992             : 
    1993             :     // #TODO - add 'SwExtraRedlineTable' also ?
    1994             : }
    1995             : 
    1996        4847 : bool DocumentRedlineManager::DeleteRedline( const SwStartNode& rNode, bool bSaveInUndo,
    1997             :                             sal_uInt16 nDelType )
    1998             : {
    1999        4847 :     SwPaM aTemp(*rNode.EndOfSectionNode(), rNode);
    2000        4847 :     return DeleteRedline(aTemp, bSaveInUndo, nDelType);
    2001             : }
    2002             : 
    2003    48861616 : sal_uInt16 DocumentRedlineManager::GetRedlinePos( const SwNode& rNd, sal_uInt16 nType ) const
    2004             : {
    2005    48861616 :     const sal_uLong nNdIdx = rNd.GetIndex();
    2006    48985262 :     for( size_t n = 0; n < mpRedlineTable->size() ; ++n )
    2007             :     {
    2008      135403 :         const SwRangeRedline* pTmp = (*mpRedlineTable)[ n ];
    2009      135403 :         sal_uLong nPt = pTmp->GetPoint()->nNode.GetIndex(),
    2010      135403 :               nMk = pTmp->GetMark()->nNode.GetIndex();
    2011      135403 :         if( nPt < nMk ) { long nTmp = nMk; nMk = nPt; nPt = nTmp; }
    2012             : 
    2013      135403 :         if( ( USHRT_MAX == nType || nType == pTmp->GetType()) &&
    2014      262365 :             nMk <= nNdIdx && nNdIdx <= nPt )
    2015        3316 :             return n;
    2016             : 
    2017      132087 :         if( nMk > nNdIdx )
    2018        8441 :             break;
    2019             :     }
    2020    48858300 :     return USHRT_MAX;
    2021             : 
    2022             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2023             : }
    2024             : 
    2025       21985 : const SwRangeRedline* DocumentRedlineManager::GetRedline( const SwPosition& rPos,
    2026             :                                     sal_uInt16* pFndPos ) const
    2027             : {
    2028       21985 :     sal_uInt16 nO = mpRedlineTable->size(), nM, nU = 0;
    2029       21985 :     if( nO > 0 )
    2030             :     {
    2031        7838 :         nO--;
    2032       49210 :         while( nU <= nO )
    2033             :         {
    2034       34654 :             nM = nU + ( nO - nU ) / 2;
    2035       34654 :             const SwRangeRedline* pRedl = (*mpRedlineTable)[ nM ];
    2036       34654 :             const SwPosition* pStt = pRedl->Start();
    2037       34654 :             const SwPosition* pEnd = pStt == pRedl->GetPoint()
    2038       23306 :                                         ? pRedl->GetMark()
    2039       57960 :                                         : pRedl->GetPoint();
    2040       68343 :             if( pEnd == pStt
    2041             :                     ? *pStt == rPos
    2042       33689 :                     : ( *pStt <= rPos && rPos < *pEnd ) )
    2043             :             {
    2044        1885 :                 while( nM && rPos == *(*mpRedlineTable)[ nM - 1 ]->End() &&
    2045         523 :                     rPos == *(*mpRedlineTable)[ nM - 1 ]->Start() )
    2046             :                 {
    2047           0 :                     --nM;
    2048           0 :                     pRedl = (*mpRedlineTable)[ nM ];
    2049             :                 }
    2050             :                 // if there are format and insert changes in the same position
    2051             :                 // show insert change first.
    2052             :                 // since the redlines are sorted by position, only check the redline
    2053             :                 // before and after the current redline
    2054         681 :                 if( nsRedlineType_t::REDLINE_FORMAT == pRedl->GetType() )
    2055             :                 {
    2056         961 :                     if( nM && rPos >= *(*mpRedlineTable)[ nM - 1 ]->Start() &&
    2057         927 :                         rPos <= *(*mpRedlineTable)[ nM - 1 ]->End() &&
    2058         286 :                         ( nsRedlineType_t::REDLINE_INSERT == (*mpRedlineTable)[ nM - 1 ]->GetType() ) )
    2059             :                     {
    2060          23 :                         --nM;
    2061          23 :                         pRedl = (*mpRedlineTable)[ nM ];
    2062             :                     }
    2063        1124 :                     else if( ( nM + 1 ) <= nO && rPos >= *(*mpRedlineTable)[ nM + 1 ]->Start() &&
    2064         826 :                         rPos <= *(*mpRedlineTable)[ nM + 1 ]->End() &&
    2065         264 :                         ( nsRedlineType_t::REDLINE_INSERT == (*mpRedlineTable)[ nM + 1 ]->GetType() ) )
    2066             :                     {
    2067           0 :                         ++nM;
    2068           0 :                         pRedl = (*mpRedlineTable)[ nM ];
    2069             :                     }
    2070             :                 }
    2071             : 
    2072         681 :                 if( pFndPos )
    2073         681 :                     *pFndPos = nM;
    2074         681 :                 return pRedl;
    2075             :             }
    2076       33973 :             else if( *pEnd <= rPos )
    2077       29802 :                 nU = nM + 1;
    2078        4171 :             else if( nM == 0 )
    2079             :             {
    2080         439 :                 if( pFndPos )
    2081         437 :                     *pFndPos = nU;
    2082         439 :                 return 0;
    2083             :             }
    2084             :             else
    2085        3732 :                 nO = nM - 1;
    2086             :         }
    2087             :     }
    2088       20865 :     if( pFndPos )
    2089       19982 :         *pFndPos = nU;
    2090       20865 :     return 0;
    2091             : 
    2092             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2093             : }
    2094             : 
    2095          10 : bool DocumentRedlineManager::AcceptRedline( sal_uInt16 nPos, bool bCallDelete )
    2096             : {
    2097          10 :     bool bRet = false;
    2098             : 
    2099             :     // Switch to visible in any case
    2100          10 :     if( (nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE) !=
    2101          10 :         (nsRedlineMode_t::REDLINE_SHOW_MASK & meRedlineMode) )
    2102           0 :       SetRedlineMode( (RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE | meRedlineMode));
    2103             : 
    2104          10 :     SwRangeRedline* pTmp = (*mpRedlineTable)[ nPos ];
    2105          10 :     if( pTmp->HasMark() && pTmp->IsVisible() )
    2106             :     {
    2107          10 :         if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2108             :         {
    2109          10 :             SwRewriter aRewriter;
    2110             : 
    2111          10 :             aRewriter.AddRule(UndoArg1, pTmp->GetDescr());
    2112          10 :             m_rDoc.GetIDocumentUndoRedo().StartUndo(UNDO_ACCEPT_REDLINE, &aRewriter);
    2113             :         }
    2114             : 
    2115          10 :         int nLoopCnt = 2;
    2116          10 :         sal_uInt16 nSeqNo = pTmp->GetSeqNo();
    2117             : 
    2118          10 :         do {
    2119             : 
    2120          10 :             if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2121             :             {
    2122          10 :                 SwUndo *const pUndo( new SwUndoAcceptRedline(*pTmp) );
    2123          10 :                 m_rDoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
    2124             :             }
    2125             : 
    2126          10 :             bRet |= lcl_AcceptRedline( *mpRedlineTable, nPos, bCallDelete );
    2127             : 
    2128          10 :             if( nSeqNo )
    2129             :             {
    2130           0 :                 if( USHRT_MAX == nPos )
    2131           0 :                     nPos = 0;
    2132             :                 sal_uInt16 nFndPos = 2 == nLoopCnt
    2133           0 :                                     ? mpRedlineTable->FindNextSeqNo( nSeqNo, nPos )
    2134           0 :                                     : mpRedlineTable->FindPrevSeqNo( nSeqNo, nPos );
    2135           0 :                 if( USHRT_MAX != nFndPos || ( 0 != ( --nLoopCnt ) &&
    2136             :                     USHRT_MAX != ( nFndPos =
    2137           0 :                         mpRedlineTable->FindPrevSeqNo( nSeqNo, nPos ))) )
    2138           0 :                     pTmp = (*mpRedlineTable)[ nPos = nFndPos ];
    2139             :                 else
    2140           0 :                     nLoopCnt = 0;
    2141             :             }
    2142             :             else
    2143          10 :                 nLoopCnt = 0;
    2144             : 
    2145             :         } while( nLoopCnt );
    2146             : 
    2147          10 :         if( bRet )
    2148             :         {
    2149          10 :             CompressRedlines();
    2150          10 :             m_rDoc.getIDocumentState().SetModified();
    2151             :         }
    2152             : 
    2153          10 :         if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2154             :         {
    2155          10 :             m_rDoc.GetIDocumentUndoRedo().EndUndo(UNDO_END, 0);
    2156             :         }
    2157             :     }
    2158          10 :     return bRet;
    2159             : 
    2160             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2161             : }
    2162             : 
    2163           0 : bool DocumentRedlineManager::AcceptRedline( const SwPaM& rPam, bool bCallDelete )
    2164             : {
    2165             :     // Switch to visible in any case
    2166           0 :     if( (nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE) !=
    2167           0 :         (nsRedlineMode_t::REDLINE_SHOW_MASK & meRedlineMode) )
    2168           0 :       SetRedlineMode( (RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE | meRedlineMode));
    2169             : 
    2170             :     // The Selection is only in the ContentSection. If there are Redlines
    2171             :     // to Non-ContentNodes before or after that, then the Selections
    2172             :     // expand to them.
    2173           0 :     SwPaM aPam( *rPam.GetMark(), *rPam.GetPoint() );
    2174           0 :     lcl_AdjustRedlineRange( aPam );
    2175             : 
    2176           0 :     if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2177             :     {
    2178           0 :         m_rDoc.GetIDocumentUndoRedo().StartUndo( UNDO_ACCEPT_REDLINE, NULL );
    2179           0 :         m_rDoc.GetIDocumentUndoRedo().AppendUndo( new SwUndoAcceptRedline( aPam ));
    2180             :     }
    2181             : 
    2182             :     int nRet = lcl_AcceptRejectRedl( lcl_AcceptRedline, *mpRedlineTable,
    2183           0 :                                      bCallDelete, aPam );
    2184           0 :     if( nRet > 0 )
    2185             :     {
    2186           0 :         CompressRedlines();
    2187           0 :         m_rDoc.getIDocumentState().SetModified();
    2188             :     }
    2189           0 :     if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2190             :     {
    2191           0 :         OUString aTmpStr;
    2192             : 
    2193             :         {
    2194           0 :             SwRewriter aRewriter;
    2195           0 :             aRewriter.AddRule(UndoArg1, OUString::number(nRet));
    2196           0 :             aTmpStr = aRewriter.Apply(OUString(SW_RES(STR_N_REDLINES)));
    2197             :         }
    2198             : 
    2199           0 :         SwRewriter aRewriter;
    2200           0 :         aRewriter.AddRule(UndoArg1, aTmpStr);
    2201             : 
    2202           0 :         m_rDoc.GetIDocumentUndoRedo().EndUndo( UNDO_ACCEPT_REDLINE, &aRewriter );
    2203             :     }
    2204           0 :     return nRet != 0;
    2205             : 
    2206             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2207             : }
    2208             : 
    2209           0 : bool DocumentRedlineManager::RejectRedline( sal_uInt16 nPos, bool bCallDelete )
    2210             : {
    2211           0 :     bool bRet = false;
    2212             : 
    2213             :     // Switch to visible in any case
    2214           0 :     if( (nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE) !=
    2215           0 :         (nsRedlineMode_t::REDLINE_SHOW_MASK & meRedlineMode) )
    2216           0 :       SetRedlineMode( (RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE | meRedlineMode));
    2217             : 
    2218           0 :     SwRangeRedline* pTmp = (*mpRedlineTable)[ nPos ];
    2219           0 :     if( pTmp->HasMark() && pTmp->IsVisible() )
    2220             :     {
    2221           0 :         if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2222             :         {
    2223           0 :             SwRewriter aRewriter;
    2224             : 
    2225           0 :             aRewriter.AddRule(UndoArg1, pTmp->GetDescr());
    2226           0 :             m_rDoc.GetIDocumentUndoRedo().StartUndo(UNDO_REJECT_REDLINE, &aRewriter);
    2227             :         }
    2228             : 
    2229           0 :         int nLoopCnt = 2;
    2230           0 :         sal_uInt16 nSeqNo = pTmp->GetSeqNo();
    2231             : 
    2232           0 :         do {
    2233             : 
    2234           0 :             if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2235             :             {
    2236           0 :                 SwUndo *const pUndo( new SwUndoRejectRedline( *pTmp ) );
    2237           0 :                 m_rDoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
    2238             :             }
    2239             : 
    2240           0 :             bRet |= lcl_RejectRedline( *mpRedlineTable, nPos, bCallDelete );
    2241             : 
    2242           0 :             if( nSeqNo )
    2243             :             {
    2244           0 :                 if( USHRT_MAX == nPos )
    2245           0 :                     nPos = 0;
    2246             :                 sal_uInt16 nFndPos = 2 == nLoopCnt
    2247           0 :                                     ? mpRedlineTable->FindNextSeqNo( nSeqNo, nPos )
    2248           0 :                                     : mpRedlineTable->FindPrevSeqNo( nSeqNo, nPos );
    2249           0 :                 if( USHRT_MAX != nFndPos || ( 0 != ( --nLoopCnt ) &&
    2250             :                     USHRT_MAX != ( nFndPos =
    2251           0 :                             mpRedlineTable->FindPrevSeqNo( nSeqNo, nPos ))) )
    2252           0 :                     pTmp = (*mpRedlineTable)[ nPos = nFndPos ];
    2253             :                 else
    2254           0 :                     nLoopCnt = 0;
    2255             :             }
    2256             :             else
    2257           0 :                 nLoopCnt = 0;
    2258             : 
    2259             :         } while( nLoopCnt );
    2260             : 
    2261           0 :         if( bRet )
    2262             :         {
    2263           0 :             CompressRedlines();
    2264           0 :             m_rDoc.getIDocumentState().SetModified();
    2265             :         }
    2266             : 
    2267           0 :         if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2268             :         {
    2269           0 :             m_rDoc.GetIDocumentUndoRedo().EndUndo(UNDO_END, 0);
    2270             :         }
    2271             :     }
    2272           0 :     return bRet;
    2273             : 
    2274             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2275             : }
    2276             : 
    2277           0 : bool DocumentRedlineManager::RejectRedline( const SwPaM& rPam, bool bCallDelete )
    2278             : {
    2279             :     // Switch to visible in any case
    2280           0 :     if( (nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE) !=
    2281           0 :         (nsRedlineMode_t::REDLINE_SHOW_MASK & meRedlineMode) )
    2282           0 :       SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE | meRedlineMode));
    2283             : 
    2284             :     // The Selection is only in the ContentSection. If there are Redlines
    2285             :     // to Non-ContentNodes before or after that, then the Selections
    2286             :     // expand to them.
    2287           0 :     SwPaM aPam( *rPam.GetMark(), *rPam.GetPoint() );
    2288           0 :     lcl_AdjustRedlineRange( aPam );
    2289             : 
    2290           0 :     if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2291             :     {
    2292           0 :         m_rDoc.GetIDocumentUndoRedo().StartUndo( UNDO_REJECT_REDLINE, NULL );
    2293           0 :         m_rDoc.GetIDocumentUndoRedo().AppendUndo( new SwUndoRejectRedline(aPam) );
    2294             :     }
    2295             : 
    2296             :     int nRet = lcl_AcceptRejectRedl( lcl_RejectRedline, *mpRedlineTable,
    2297           0 :                                         bCallDelete, aPam );
    2298           0 :     if( nRet > 0 )
    2299             :     {
    2300           0 :         CompressRedlines();
    2301           0 :         m_rDoc.getIDocumentState().SetModified();
    2302             :     }
    2303           0 :     if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
    2304             :     {
    2305           0 :         OUString aTmpStr;
    2306             : 
    2307             :         {
    2308           0 :             SwRewriter aRewriter;
    2309           0 :             aRewriter.AddRule(UndoArg1, OUString::number(nRet));
    2310           0 :             aTmpStr = aRewriter.Apply(OUString(SW_RES(STR_N_REDLINES)));
    2311             :         }
    2312             : 
    2313           0 :         SwRewriter aRewriter;
    2314           0 :         aRewriter.AddRule(UndoArg1, aTmpStr);
    2315             : 
    2316           0 :         m_rDoc.GetIDocumentUndoRedo().EndUndo( UNDO_REJECT_REDLINE, &aRewriter );
    2317             :     }
    2318             : 
    2319           0 :     return nRet != 0;
    2320             : 
    2321             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2322             : }
    2323             : 
    2324           0 : const SwRangeRedline* DocumentRedlineManager::SelNextRedline( SwPaM& rPam ) const
    2325             : {
    2326           0 :     rPam.DeleteMark();
    2327           0 :     rPam.SetMark();
    2328             : 
    2329           0 :     SwPosition& rSttPos = *rPam.GetPoint();
    2330           0 :     SwPosition aSavePos( rSttPos );
    2331             :     bool bRestart;
    2332             : 
    2333             :     // If the starting position points to the last valid ContentNode,
    2334             :     // we take the next Redline in any case.
    2335           0 :     sal_uInt16 n = 0;
    2336           0 :     const SwRangeRedline* pFnd = GetRedlineTable().FindAtPosition( rSttPos, n, true );
    2337           0 :     if( pFnd )
    2338             :     {
    2339           0 :         const SwPosition* pEnd = pFnd->End();
    2340           0 :         if( !pEnd->nNode.GetNode().IsContentNode() )
    2341             :         {
    2342           0 :             SwNodeIndex aTmp( pEnd->nNode );
    2343           0 :             SwContentNode* pCNd = SwNodes::GoPrevSection( &aTmp );
    2344           0 :             if( !pCNd || ( aTmp == rSttPos.nNode &&
    2345           0 :                 pCNd->Len() == rSttPos.nContent.GetIndex() ))
    2346           0 :                 pFnd = 0;
    2347             :         }
    2348           0 :         if( pFnd )
    2349           0 :             rSttPos = *pFnd->End();
    2350             :     }
    2351             : 
    2352           0 :     do {
    2353           0 :         bRestart = false;
    2354             : 
    2355           0 :         for( ; !pFnd && n < mpRedlineTable->size(); ++n )
    2356             :         {
    2357           0 :             pFnd = (*mpRedlineTable)[ n ];
    2358           0 :             if( pFnd->HasMark() && pFnd->IsVisible() )
    2359             :             {
    2360           0 :                 *rPam.GetMark() = *pFnd->Start();
    2361           0 :                 rSttPos = *pFnd->End();
    2362           0 :                 break;
    2363             :             }
    2364             :             else
    2365           0 :                 pFnd = 0;
    2366             :         }
    2367             : 
    2368           0 :         if( pFnd )
    2369             :         {
    2370             :             // Merge all of the same type and author that are
    2371             :             // consecutive into one Selection.
    2372           0 :             const SwPosition* pPrevEnd = pFnd->End();
    2373           0 :             while( ++n < mpRedlineTable->size() )
    2374             :             {
    2375           0 :                 const SwRangeRedline* pTmp = (*mpRedlineTable)[ n ];
    2376           0 :                 if( pTmp->HasMark() && pTmp->IsVisible() )
    2377             :                 {
    2378             :                     const SwPosition *pRStt;
    2379           0 :                     if( pFnd->GetType() == pTmp->GetType() &&
    2380           0 :                         pFnd->GetAuthor() == pTmp->GetAuthor() &&
    2381           0 :                         ( *pPrevEnd == *( pRStt = pTmp->Start() ) ||
    2382           0 :                           IsPrevPos( *pPrevEnd, *pRStt )) )
    2383             :                     {
    2384           0 :                         pPrevEnd = pTmp->End();
    2385           0 :                         rSttPos = *pPrevEnd;
    2386             :                     }
    2387             :                     else
    2388           0 :                         break;
    2389             :                 }
    2390             :             }
    2391             :         }
    2392             : 
    2393           0 :         if( pFnd )
    2394             :         {
    2395           0 :             const SwRangeRedline* pSaveFnd = pFnd;
    2396             : 
    2397             :             SwContentNode* pCNd;
    2398           0 :             SwNodeIndex* pIdx = &rPam.GetMark()->nNode;
    2399           0 :             if( !pIdx->GetNode().IsContentNode() &&
    2400           0 :                 0 != ( pCNd = m_rDoc.GetNodes().GoNextSection( pIdx )) )
    2401             :             {
    2402           0 :                 if( *pIdx <= rPam.GetPoint()->nNode )
    2403           0 :                     rPam.GetMark()->nContent.Assign( pCNd, 0 );
    2404             :                 else
    2405           0 :                     pFnd = 0;
    2406             :             }
    2407             : 
    2408           0 :             if( pFnd )
    2409             :             {
    2410           0 :                 pIdx = &rPam.GetPoint()->nNode;
    2411           0 :                 if( !pIdx->GetNode().IsContentNode() &&
    2412             :                     0 != ( pCNd = SwNodes::GoPrevSection( pIdx )) )
    2413             :                 {
    2414           0 :                     if( *pIdx >= rPam.GetMark()->nNode )
    2415           0 :                         rPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
    2416             :                     else
    2417           0 :                         pFnd = 0;
    2418             :                 }
    2419             :             }
    2420             : 
    2421           0 :             if( !pFnd || *rPam.GetMark() == *rPam.GetPoint() )
    2422             :             {
    2423           0 :                 if( n < mpRedlineTable->size() )
    2424             :                 {
    2425           0 :                     bRestart = true;
    2426           0 :                     *rPam.GetPoint() = *pSaveFnd->End();
    2427             :                 }
    2428             :                 else
    2429             :                 {
    2430           0 :                     rPam.DeleteMark();
    2431           0 :                     *rPam.GetPoint() = aSavePos;
    2432             :                 }
    2433           0 :                 pFnd = 0;
    2434             :             }
    2435             :         }
    2436             :     } while( bRestart );
    2437             : 
    2438           0 :     return pFnd;
    2439             : 
    2440             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2441             : }
    2442             : 
    2443           0 : const SwRangeRedline* DocumentRedlineManager::SelPrevRedline( SwPaM& rPam ) const
    2444             : {
    2445           0 :     rPam.DeleteMark();
    2446           0 :     rPam.SetMark();
    2447             : 
    2448           0 :     SwPosition& rSttPos = *rPam.GetPoint();
    2449           0 :     SwPosition aSavePos( rSttPos );
    2450             :     bool bRestart;
    2451             : 
    2452             :     // If the starting position points to the last valid ContentNode,
    2453             :     // we take the previous Redline in any case.
    2454           0 :     sal_uInt16 n = 0;
    2455           0 :     const SwRangeRedline* pFnd = GetRedlineTable().FindAtPosition( rSttPos, n, false );
    2456           0 :     if( pFnd )
    2457             :     {
    2458           0 :         const SwPosition* pStt = pFnd->Start();
    2459           0 :         if( !pStt->nNode.GetNode().IsContentNode() )
    2460             :         {
    2461           0 :             SwNodeIndex aTmp( pStt->nNode );
    2462           0 :             SwContentNode* pCNd = m_rDoc.GetNodes().GoNextSection( &aTmp );
    2463           0 :             if( !pCNd || ( aTmp == rSttPos.nNode &&
    2464           0 :                 !rSttPos.nContent.GetIndex() ))
    2465           0 :                 pFnd = 0;
    2466             :         }
    2467           0 :         if( pFnd )
    2468           0 :             rSttPos = *pFnd->Start();
    2469             :     }
    2470             : 
    2471           0 :     do {
    2472           0 :         bRestart = false;
    2473             : 
    2474           0 :         while( !pFnd && 0 < n )
    2475             :         {
    2476           0 :             pFnd = (*mpRedlineTable)[ --n ];
    2477           0 :             if( pFnd->HasMark() && pFnd->IsVisible() )
    2478             :             {
    2479           0 :                 *rPam.GetMark() = *pFnd->End();
    2480           0 :                 rSttPos = *pFnd->Start();
    2481             :             }
    2482             :             else
    2483           0 :                 pFnd = 0;
    2484             :         }
    2485             : 
    2486           0 :         if( pFnd )
    2487             :         {
    2488             :             // Merge all of the same type and author that are
    2489             :             // consecutive into one Selection.
    2490           0 :             const SwPosition* pNextStt = pFnd->Start();
    2491           0 :             while( 0 < n )
    2492             :             {
    2493           0 :                 const SwRangeRedline* pTmp = (*mpRedlineTable)[ --n ];
    2494           0 :                 if( pTmp->HasMark() && pTmp->IsVisible() )
    2495             :                 {
    2496             :                     const SwPosition *pREnd;
    2497           0 :                     if( pFnd->GetType() == pTmp->GetType() &&
    2498           0 :                         pFnd->GetAuthor() == pTmp->GetAuthor() &&
    2499           0 :                         ( *pNextStt == *( pREnd = pTmp->End() ) ||
    2500           0 :                           IsPrevPos( *pREnd, *pNextStt )) )
    2501             :                     {
    2502           0 :                         pNextStt = pTmp->Start();
    2503           0 :                         rSttPos = *pNextStt;
    2504             :                     }
    2505             :                     else
    2506             :                     {
    2507           0 :                         ++n;
    2508           0 :                         break;
    2509             :                     }
    2510             :                 }
    2511             :             }
    2512             :         }
    2513             : 
    2514           0 :         if( pFnd )
    2515             :         {
    2516           0 :             const SwRangeRedline* pSaveFnd = pFnd;
    2517             : 
    2518             :             SwContentNode* pCNd;
    2519           0 :             SwNodeIndex* pIdx = &rPam.GetMark()->nNode;
    2520           0 :             if( !pIdx->GetNode().IsContentNode() &&
    2521             :                 0 != ( pCNd = SwNodes::GoPrevSection( pIdx )) )
    2522             :             {
    2523           0 :                 if( *pIdx >= rPam.GetPoint()->nNode )
    2524           0 :                     rPam.GetMark()->nContent.Assign( pCNd, pCNd->Len() );
    2525             :                 else
    2526           0 :                     pFnd = 0;
    2527             :             }
    2528             : 
    2529           0 :             if( pFnd )
    2530             :             {
    2531           0 :                 pIdx = &rPam.GetPoint()->nNode;
    2532           0 :                 if( !pIdx->GetNode().IsContentNode() &&
    2533           0 :                     0 != ( pCNd = m_rDoc.GetNodes().GoNextSection( pIdx )) )
    2534             :                 {
    2535           0 :                     if( *pIdx <= rPam.GetMark()->nNode )
    2536           0 :                         rPam.GetPoint()->nContent.Assign( pCNd, 0 );
    2537             :                     else
    2538           0 :                         pFnd = 0;
    2539             :                 }
    2540             :             }
    2541             : 
    2542           0 :             if( !pFnd || *rPam.GetMark() == *rPam.GetPoint() )
    2543             :             {
    2544           0 :                 if( n )
    2545             :                 {
    2546           0 :                     bRestart = true;
    2547           0 :                     *rPam.GetPoint() = *pSaveFnd->Start();
    2548             :                 }
    2549             :                 else
    2550             :                 {
    2551           0 :                     rPam.DeleteMark();
    2552           0 :                     *rPam.GetPoint() = aSavePos;
    2553             :                 }
    2554           0 :                 pFnd = 0;
    2555             :             }
    2556             :         }
    2557             :     } while( bRestart );
    2558             : 
    2559           0 :     return pFnd;
    2560             : 
    2561             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2562             : }
    2563             : 
    2564             : // Set comment at the Redline
    2565           0 : bool DocumentRedlineManager::SetRedlineComment( const SwPaM& rPaM, const OUString& rS )
    2566             : {
    2567           0 :     bool bRet = false;
    2568           0 :     const SwPosition* pStt = rPaM.Start(),
    2569           0 :                     * pEnd = pStt == rPaM.GetPoint() ? rPaM.GetMark()
    2570           0 :                                                      : rPaM.GetPoint();
    2571           0 :     sal_uInt16 n = 0;
    2572           0 :     if( GetRedlineTable().FindAtPosition( *pStt, n, true ) )
    2573             :     {
    2574           0 :         for( ; n < mpRedlineTable->size(); ++n )
    2575             :         {
    2576           0 :             bRet = true;
    2577           0 :             SwRangeRedline* pTmp = (*mpRedlineTable)[ n ];
    2578           0 :             if( pStt != pEnd && *pTmp->Start() > *pEnd )
    2579           0 :                 break;
    2580             : 
    2581           0 :             pTmp->SetComment( rS );
    2582           0 :             if( *pTmp->End() >= *pEnd )
    2583           0 :                 break;
    2584             :         }
    2585             :     }
    2586           0 :     if( bRet )
    2587           0 :         m_rDoc.getIDocumentState().SetModified();
    2588             : 
    2589           0 :     return bRet;
    2590             : 
    2591             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2592             : }
    2593             : 
    2594             : // Create a new author if necessary
    2595        1084 : sal_uInt16 DocumentRedlineManager::GetRedlineAuthor()
    2596             : {
    2597        1084 :     return SW_MOD()->GetRedlineAuthor();
    2598             : }
    2599             : 
    2600             : /// Insert new author into the Table for the Readers etc.
    2601        2901 : sal_uInt16 DocumentRedlineManager::InsertRedlineAuthor( const OUString& rNew )
    2602             : {
    2603        2901 :     return SW_MOD()->InsertRedlineAuthor(rNew);
    2604             : }
    2605             : 
    2606           0 : void DocumentRedlineManager::UpdateRedlineAttr()
    2607             : {
    2608           0 :     const SwRedlineTable& rTable = GetRedlineTable();
    2609           0 :     for( size_t n = 0; n < rTable.size(); ++n )
    2610             :     {
    2611           0 :         SwRangeRedline* pRedl = rTable[ n ];
    2612           0 :         if( pRedl->IsVisible() )
    2613           0 :             pRedl->InvalidateRange();
    2614             :     }
    2615             : 
    2616             :     // #TODO - add 'SwExtraRedlineTable' also ?
    2617           0 : }
    2618             : 
    2619         446 : const uno::Sequence <sal_Int8>& DocumentRedlineManager::GetRedlinePassword() const
    2620             : {
    2621         446 :     return maRedlinePasswd;
    2622             : }
    2623             : 
    2624         360 : void DocumentRedlineManager::SetRedlinePassword(
    2625             :             /*[in]*/const uno::Sequence <sal_Int8>& rNewPassword)
    2626             : {
    2627         360 :     maRedlinePasswd = rNewPassword;
    2628         360 :     m_rDoc.getIDocumentState().SetModified();
    2629         360 : }
    2630             : 
    2631             : /// Set comment text for the Redline, which is inserted later on via
    2632             : /// AppendRedline. Is used by Autoformat.
    2633             : /// A null pointer resets the mode. The pointer is not copied, so it
    2634             : /// needs to stay valid!
    2635           0 : void DocumentRedlineManager::SetAutoFormatRedlineComment( const OUString* pText, sal_uInt16 nSeqNo )
    2636             : {
    2637           0 :     m_rDoc.SetAutoFormatRedline( 0 != pText );
    2638           0 :     if( pText )
    2639             :     {
    2640           0 :         if( !mpAutoFormatRedlnComment )
    2641           0 :             mpAutoFormatRedlnComment = new OUString( *pText );
    2642             :         else
    2643           0 :             *mpAutoFormatRedlnComment = *pText;
    2644             :     }
    2645             :     else
    2646           0 :         delete mpAutoFormatRedlnComment, mpAutoFormatRedlnComment = 0;
    2647             : 
    2648           0 :     mnAutoFormatRedlnCommentNo = nSeqNo;
    2649           0 : }
    2650             : 
    2651             : #define MAX_REDLINE_COUNT   250
    2652             : 
    2653         241 : void DocumentRedlineManager::checkRedlining(RedlineMode_t& _rReadlineMode)
    2654             : {
    2655         241 :     const SwRedlineTable& rRedlineTable = GetRedlineTable();
    2656         241 :     SwEditShell* pEditShell = m_rDoc.GetEditShell();
    2657         241 :     vcl::Window* pParent = pEditShell ? pEditShell->GetWin() : NULL;
    2658         241 :     if ( pParent && !mbReadlineChecked && rRedlineTable.size() > MAX_REDLINE_COUNT
    2659         241 :         && !((_rReadlineMode & nsRedlineMode_t::REDLINE_SHOW_DELETE) == nsRedlineMode_t::REDLINE_SHOW_DELETE) )
    2660             :     {
    2661           0 :         ScopedVclPtrInstance< MessageDialog > aQuery(pParent, "QueryShowChangesDialog", "modules/swriter/ui/queryshowchangesdialog.ui");
    2662           0 :         sal_uInt16 nResult = aQuery->Execute();
    2663           0 :         mbReadlineChecked = true;
    2664           0 :         if ( nResult == RET_YES )
    2665             :         {
    2666           0 :             sal_Int32 nMode = (sal_Int32)_rReadlineMode;
    2667           0 :             nMode |= nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE;
    2668           0 :             _rReadlineMode = (RedlineMode_t)nMode;
    2669           0 :         }
    2670             :     }
    2671         241 : }
    2672             : 
    2673        8847 : DocumentRedlineManager::~DocumentRedlineManager()
    2674             : {
    2675        2949 :     delete mpRedlineTable; mpRedlineTable = 0;
    2676        2949 :     delete mpExtraRedlineTable; mpExtraRedlineTable = 0;
    2677        2949 :     delete mpAutoFormatRedlnComment; mpAutoFormatRedlnComment = 0;
    2678        5898 : }
    2679             : 
    2680         177 : }
    2681             : 
    2682             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11