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

Generated by: LCOV version 1.10