LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/doc - docredln.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 411 1926 21.3 %
Date: 2012-12-27 Functions: 48 110 43.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <hintids.hxx>
      21             : #include <tools/shl.hxx>
      22             : #include <svl/itemiter.hxx>
      23             : #include <sfx2/app.hxx>
      24             : #include <editeng/colritem.hxx>
      25             : #include <editeng/udlnitem.hxx>
      26             : #include <editeng/crsditem.hxx>
      27             : #include <swmodule.hxx>
      28             : #include <doc.hxx>
      29             : #include <IDocumentUndoRedo.hxx>
      30             : #include <docary.hxx>
      31             : #include <ndtxt.hxx>
      32             : #include <redline.hxx>
      33             : #include <swundo.hxx>
      34             : #include <UndoCore.hxx>
      35             : #include <UndoRedline.hxx>
      36             : #include <hints.hxx>
      37             : #include <pamtyp.hxx>
      38             : #include <poolfmt.hxx>
      39             : #include <viewsh.hxx>
      40             : #include <rootfrm.hxx>
      41             : 
      42             : #include <comcore.hrc>
      43             : 
      44             : using namespace com::sun::star;
      45             : 
      46           0 : TYPEINIT1(SwRedlineHint, SfxHint);
      47             : 
      48             : #ifdef DBG_UTIL
      49             : 
      50             :     #define _ERROR_PREFIX "redline table corrupted: "
      51             : 
      52             :     // helper function for lcl_CheckRedline
      53             :     // 1. make sure that pPos->nContent points into pPos->nNode
      54             :     //    (or into the 'special' no-content-node-IndexReg)
      55             :     // 2. check that position is valid and doesn't point behind text
      56             :     static void lcl_CheckPosition( const SwPosition* pPos )
      57             :     {
      58             :         SwPosition aComparePos( *pPos );
      59             :         aComparePos.nContent.Assign(
      60             :             aComparePos.nNode.GetNode().GetCntntNode(), 0 );
      61             :         OSL_ENSURE( pPos->nContent.GetIdxReg() ==
      62             :                     aComparePos.nContent.GetIdxReg(),
      63             :                     _ERROR_PREFIX "illegal position" );
      64             : 
      65             :         SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode();
      66             :         if( pTxtNode == NULL )
      67             :         {
      68             :             OSL_ENSURE( pPos->nContent == 0,
      69             :                         _ERROR_PREFIX "non-text-node with content" );
      70             :         }
      71             :         else
      72             :         {
      73             :             OSL_ENSURE( pPos->nContent >= 0  &&
      74             :                         pPos->nContent <= pTxtNode->Len(),
      75             :                         _ERROR_PREFIX "index behind text" );
      76             :         }
      77             :     }
      78             : 
      79             :     static void lcl_CheckPam( const SwPaM* pPam )
      80             :     {
      81             :         OSL_ENSURE( pPam != NULL, _ERROR_PREFIX "illegal argument" );
      82             :         lcl_CheckPosition( pPam->GetPoint() );
      83             :         lcl_CheckPosition( pPam->GetMark() );
      84             :     }
      85             : 
      86             :     // check validity of the redline table. Checks redline bounds, and make
      87             :     // sure the redlines are sorted and non-overlapping.
      88             :     static void lcl_CheckRedline( const SwDoc* pDoc )
      89             :     {
      90             :         const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
      91             : 
      92             :         // verify valid redline positions
      93             :         for( sal_uInt16 i = 0; i < rTbl.size(); ++i )
      94             :             lcl_CheckPam( rTbl[ i ] );
      95             : 
      96             :         for( sal_uInt16 j = 0; j < rTbl.size(); ++j )
      97             :         {
      98             :             // check for empty redlines
      99             :             OSL_ENSURE( ( *(rTbl[j]->GetPoint()) != *(rTbl[j]->GetMark()) ) ||
     100             :                         ( rTbl[j]->GetContentIdx() != NULL ),
     101             :                         _ERROR_PREFIX "empty redline" );
     102             :          }
     103             : 
     104             :         // verify proper redline sorting
     105             :         for( sal_uInt16 n = 1; n < rTbl.size(); ++n )
     106             :         {
     107             :             const SwRedline* pPrev = rTbl[ n-1 ];
     108             :             const SwRedline* pCurrent = rTbl[ n ];
     109             : 
     110             :             // check redline sorting
     111             :             SAL_WARN_IF( *pPrev->Start() > *pCurrent->Start(), "sw",
     112             :                          _ERROR_PREFIX "not sorted correctly" );
     113             : 
     114             :             // check for overlapping redlines
     115             :             SAL_WARN_IF( *pPrev->End() > *pCurrent->Start(), "sw",
     116             :                          _ERROR_PREFIX "overlapping redlines" );
     117             :         }
     118             :     }
     119             : 
     120             :     #define _CHECK_REDLINE( pDoc ) lcl_CheckRedline( pDoc );
     121             : 
     122             :     void sw_DebugRedline( const SwDoc* pDoc )
     123             :     {
     124             :         static sal_uInt16 nWatch = 0;
     125             :         const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
     126             :         for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
     127             :         {
     128             :             sal_uInt16 nDummy = 0;
     129             :             const SwRedline* pCurrent = rTbl[ n ];
     130             :             const SwRedline* pNext = n+1 < (sal_uInt16)rTbl.size() ? rTbl[ n+1 ] : 0;
     131             :             if( pCurrent == pNext )
     132             :                 ++nDummy;
     133             :             if( n == nWatch )
     134             :                 ++nDummy; // Possible debugger breakpoint
     135             :         }
     136             :     }
     137             : 
     138             :     #define _DEBUG_REDLINE( pDoc ) sw_DebugRedline( pDoc );
     139             : 
     140             : 
     141             : #else
     142             : 
     143             :     #define _CHECK_REDLINE( pDoc )
     144             :     #define _DEBUG_REDLINE( pDoc )
     145             : 
     146             : #endif
     147             : 
     148        8950 : RedlineMode_t SwDoc::GetRedlineMode() const
     149             : {
     150        8950 :     return eRedlineMode;
     151             : }
     152             : 
     153         277 : void SwDoc::SetRedlineMode( RedlineMode_t eMode )
     154             : {
     155         277 :     if( eRedlineMode != eMode )
     156             :     {
     157          34 :         if( (nsRedlineMode_t::REDLINE_SHOW_MASK & eRedlineMode) != (nsRedlineMode_t::REDLINE_SHOW_MASK & eMode)
     158             :             || 0 == (nsRedlineMode_t::REDLINE_SHOW_MASK & eMode) )
     159             :         {
     160          32 :             bool bSaveInXMLImportFlag = IsInXMLImport();
     161          32 :             SetInXMLImport( false );
     162             :             // and then hide/display everything
     163          32 :             void (SwRedline::*pFnc)( sal_uInt16 ) = 0;
     164             : 
     165          32 :             switch( nsRedlineMode_t::REDLINE_SHOW_MASK & eMode )
     166             :             {
     167             :             case nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE :
     168          23 :                 pFnc = &SwRedline::Show;
     169          23 :                 break;
     170             :             case nsRedlineMode_t::REDLINE_SHOW_INSERT:
     171           4 :                 pFnc = &SwRedline::Hide;
     172           4 :                 break;
     173             :             case nsRedlineMode_t::REDLINE_SHOW_DELETE:
     174           1 :                 pFnc = &SwRedline::ShowOriginal;
     175           1 :                 break;
     176             : 
     177             :             default:
     178           4 :                 pFnc = &SwRedline::Hide;
     179           4 :                 eMode = (RedlineMode_t)(eMode | nsRedlineMode_t::REDLINE_SHOW_INSERT);
     180           4 :                 break;
     181             :             }
     182             : 
     183             :             _CHECK_REDLINE( this )
     184             : 
     185          32 :             if( pFnc )
     186          96 :                 for( sal_uInt16 nLoop = 1; nLoop <= 2; ++nLoop )
     187          66 :                     for( sal_uInt16 i = 0; i < pRedlineTbl->size(); ++i )
     188           2 :                         ((*pRedlineTbl)[ i ]->*pFnc)( nLoop );
     189             :             _CHECK_REDLINE( this )
     190          32 :             SetInXMLImport( bSaveInXMLImportFlag );
     191             :         }
     192          34 :         eRedlineMode = eMode;
     193          34 :         SetModified();
     194             :     }
     195         277 : }
     196             : 
     197       62100 : bool SwDoc::IsRedlineOn() const
     198             : {
     199       62100 :     return IDocumentRedlineAccess::IsRedlineOn(eRedlineMode);
     200             : }
     201             : 
     202       47682 : bool SwDoc::IsIgnoreRedline() const
     203             : {
     204       47682 :     return (nsRedlineMode_t::REDLINE_IGNORE & eRedlineMode);
     205             : }
     206             : 
     207         734 : void SwDoc::SetRedlineMode_intern(RedlineMode_t eMode)
     208             : {
     209         734 :     eRedlineMode = eMode;
     210         734 : }
     211             : 
     212       57502 : const SwRedlineTbl& SwDoc::GetRedlineTbl() const
     213             : {
     214       57502 :     return *pRedlineTbl;
     215             : }
     216             : 
     217          48 : bool SwDoc::IsRedlineMove() const
     218             : {
     219          48 :     return mbIsRedlineMove;
     220             : }
     221             : 
     222          30 : void SwDoc::SetRedlineMove(bool bFlag)
     223             : {
     224          30 :     mbIsRedlineMove = bFlag;
     225          30 : }
     226             : 
     227          20 : const uno::Sequence <sal_Int8>& SwDoc::GetRedlinePassword() const
     228             : {
     229          20 :     return aRedlinePasswd;
     230             : }
     231             : 
     232          40 : inline bool IsPrevPos( const SwPosition rPos1, const SwPosition rPos2 )
     233             : {
     234             :     const SwCntntNode* pCNd;
     235          40 :     return 0 == rPos2.nContent.GetIndex() &&
     236           0 :             rPos2.nNode.GetIndex() - 1 == rPos1.nNode.GetIndex() &&
     237           0 :             0 != ( pCNd = rPos1.nNode.GetNode().GetCntntNode() )
     238           0 :                 ? rPos1.nContent.GetIndex() == pCNd->Len()
     239          40 :                 : false;
     240             : }
     241             : 
     242             : #if OSL_DEBUG_LEVEL > 0
     243             : bool CheckPosition( const SwPosition* pStt, const SwPosition* pEnd )
     244             : {
     245             :     int nError = 0;
     246             :     SwNode* pSttNode = &pStt->nNode.GetNode();
     247             :     SwNode* pEndNode = &pEnd->nNode.GetNode();
     248             :     SwNode* pSttTab = pSttNode->StartOfSectionNode()->FindTableNode();
     249             :     SwNode* pEndTab = pEndNode->StartOfSectionNode()->FindTableNode();
     250             :     SwNode* pSttStart = pSttNode;
     251             :     while( pSttStart && (!pSttStart->IsStartNode() || pSttStart->IsSectionNode() ||
     252             :         pSttStart->IsTableNode() ) )
     253             :         pSttStart = pSttStart->StartOfSectionNode();
     254             :     SwNode* pEndStart = pEndNode;
     255             :     while( pEndStart && (!pEndStart->IsStartNode() || pEndStart->IsSectionNode() ||
     256             :         pEndStart->IsTableNode() ) )
     257             :         pEndStart = pEndStart->StartOfSectionNode();
     258             :     if( pSttTab != pEndTab )
     259             :         nError = 1;
     260             :     if( !pSttTab && pSttStart != pEndStart )
     261             :         nError |= 2;
     262             :     if( nError )
     263             :         nError += 10;
     264             :     return nError != 0;
     265             : }
     266             : #endif
     267             : 
     268             : /*
     269             : 
     270             : Text means Text not "polluted" by Redlines.
     271             : 
     272             : Behaviour of Insert-Redline:
     273             : 
     274             :     - in the Text                       - insert Redline Object
     275             :     - in InsertRedline (own)            - ignore, existing is extended
     276             :     - in InsertRedline (others)         - split up InsertRedline and
     277             :                                           insert Redline Object
     278             :     - in DeleteRedline                  - split up DeleteRedline or
     279             :                                           move at the end/beginning
     280             : 
     281             : Behaviour of Delete-Redline:
     282             :     - in the Text                       - insert Redline Object
     283             :     - in DeleteRedline (own/others)     - ignore
     284             :     - in InsertRedline (own)            - ignore, but delete character
     285             :     - in InsertRedline (others)         - split up InsertRedline and
     286             :                                           insert Redline Object
     287             :     - Text and own Insert overlap       - delete Text in the own Insert,
     288             :                                           extend in the other Text
     289             :                                           (up to the Insert!)
     290             :     - Text and other Insert overlap     - insert Redline Object, the
     291             :                                           other Insert is overlapped by
     292             :                                           the Delete
     293             : */
     294             : 
     295         819 : bool SwDoc::AppendRedline( SwRedline* pNewRedl, bool bCallDelete )
     296             : {
     297         819 :     bool bError = true;
     298             :     _CHECK_REDLINE( this )
     299             : 
     300        1364 :     if( IsRedlineOn() && !IsShowOriginal( eRedlineMode ) &&
     301         545 :          pNewRedl->GetAuthorString().Len() )
     302             :     {
     303         545 :         pNewRedl->InvalidateRange();
     304             : 
     305         545 :         if( mbIsAutoFmtRedline )
     306             :         {
     307           0 :             pNewRedl->SetAutoFmtFlag();
     308           0 :             if( pAutoFmtRedlnComment && pAutoFmtRedlnComment->Len() )
     309             :             {
     310           0 :                 pNewRedl->SetComment( *pAutoFmtRedlnComment );
     311           0 :                 pNewRedl->SetSeqNo( nAutoFmtRedlnCommentNo );
     312             :             }
     313             :         }
     314             : 
     315         545 :         SwPosition* pStt = pNewRedl->Start(),
     316         629 :                   * pEnd = pStt == pNewRedl->GetPoint() ? pNewRedl->GetMark()
     317         629 :                                                         : pNewRedl->GetPoint();
     318             :         {
     319         545 :             SwTxtNode* pTxtNode = pStt->nNode.GetNode().GetTxtNode();
     320         545 :             if( pTxtNode == NULL )
     321             :             {
     322           0 :                 if( pStt->nContent > 0 )
     323             :                 {
     324             :                     OSL_ENSURE( false, "Redline start: non-text-node with content" );
     325           0 :                     pStt->nContent = 0;
     326             :                 }
     327             :             }
     328             :             else
     329             :             {
     330         545 :                 if( pStt->nContent > pTxtNode->Len() )
     331             :                 {
     332             :                     OSL_ENSURE( false, "Redline start: index behind text" );
     333           0 :                     pStt->nContent = pTxtNode->Len();
     334             :                 }
     335             :             }
     336         545 :             pTxtNode = pEnd->nNode.GetNode().GetTxtNode();
     337         545 :             if( pTxtNode == NULL )
     338             :             {
     339           0 :                 if( pEnd->nContent > 0 )
     340             :                 {
     341             :                     OSL_ENSURE( false, "Redline end: non-text-node with content" );
     342           0 :                     pEnd->nContent = 0;
     343             :                 }
     344             :             }
     345             :             else
     346             :             {
     347         545 :                 if( pEnd->nContent > pTxtNode->Len() )
     348             :                 {
     349             :                     OSL_ENSURE( false, "Redline end: index behind text" );
     350           0 :                     pEnd->nContent = pTxtNode->Len();
     351             :                 }
     352             :             }
     353             :         }
     354         615 :         if( ( *pStt == *pEnd ) &&
     355          70 :             ( pNewRedl->GetContentIdx() == NULL ) )
     356             :         {   // Do not insert empty redlines
     357          70 :             delete pNewRedl;
     358          70 :             return false;
     359             :         }
     360         475 :         bool bCompress = false;
     361         475 :         sal_uInt16 n = 0;
     362             :         // look up the first Redline for the starting position
     363         475 :         if( !GetRedline( *pStt, &n ) && n )
     364         442 :             --n;
     365         475 :         bool bDec = false;
     366             : 
     367         918 :         for( ; pNewRedl && n < pRedlineTbl->size(); bDec ? n : ++n )
     368             :         {
     369         443 :             bDec = false;
     370             : 
     371         443 :             SwRedline* pRedl = (*pRedlineTbl)[ n ];
     372         443 :             SwPosition* pRStt = pRedl->Start(),
     373         465 :                       * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
     374         465 :                                                            : pRedl->GetPoint();
     375             : 
     376             :             // #i8518# remove empty redlines while we're at it
     377         444 :             if( ( *pRStt == *pREnd ) &&
     378           1 :                 ( pRedl->GetContentIdx() == NULL ) )
     379             :             {
     380           0 :                 pRedlineTbl->DeleteAndDestroy(n);
     381           0 :                 continue;
     382             :             }
     383             : 
     384         443 :             SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
     385             : 
     386         443 :             switch( pNewRedl->GetType() )
     387             :             {
     388             :             case nsRedlineType_t::REDLINE_INSERT:
     389         443 :                 switch( pRedl->GetType() )
     390             :                 {
     391             :                 case nsRedlineType_t::REDLINE_INSERT:
     392         442 :                     if( pRedl->IsOwnRedline( *pNewRedl ) )
     393             :                     {
     394         195 :                         bool bDelete = false;
     395             : 
     396             :                         // Merge if applicable?
     397         820 :                         if( (( POS_BEHIND == eCmpPos &&
     398         315 :                                IsPrevPos( *pREnd, *pStt ) ) ||
     399             :                              ( POS_COLLIDE_START == eCmpPos ) ||
     400             :                              ( POS_OVERLAP_BEHIND == eCmpPos ) ) &&
     401         155 :                             pRedl->CanCombine( *pNewRedl ) &&
     402         155 :                             ( n+1 >= (sal_uInt16)pRedlineTbl->size() ||
     403           0 :                              ( *(*pRedlineTbl)[ n+1 ]->Start() >= *pEnd &&
     404           0 :                              *(*pRedlineTbl)[ n+1 ]->Start() != *pREnd ) ) )
     405             :                         {
     406         155 :                             pRedl->SetEnd( *pEnd, pREnd );
     407         155 :                             if( !pRedl->HasValidRange() )
     408             :                             {
     409             :                                 // re-insert
     410           0 :                                 pRedlineTbl->Remove( n );
     411           0 :                                 pRedlineTbl->Insert( pRedl );
     412             :                             }
     413             : 
     414         155 :                             bError = false;
     415         155 :                             bDelete = true;
     416             :                         }
     417          80 :                         else if( (( POS_BEFORE == eCmpPos &&
     418          40 :                                     IsPrevPos( *pEnd, *pRStt ) ) ||
     419             :                                    ( POS_COLLIDE_END == eCmpPos ) ||
     420             :                                   ( POS_OVERLAP_BEFORE == eCmpPos ) ) &&
     421           0 :                             pRedl->CanCombine( *pNewRedl ) &&
     422           0 :                             ( !n ||
     423           0 :                              *(*pRedlineTbl)[ n-1 ]->End() != *pRStt ))
     424             :                         {
     425           0 :                             pRedl->SetStart( *pStt, pRStt );
     426             :                             // re-insert
     427           0 :                             pRedlineTbl->Remove( n );
     428           0 :                             pRedlineTbl->Insert( pRedl );
     429             : 
     430           0 :                             bError = false;
     431           0 :                             bDelete = true;
     432             :                         }
     433          40 :                         else if ( POS_OUTSIDE == eCmpPos )
     434             :                         {
     435             :                             // own insert-over-insert redlines:
     436             :                             // just scrap the inside ones
     437           0 :                             pRedlineTbl->Remove( n );
     438           0 :                             bDec = true;
     439             :                         }
     440          40 :                         else if( POS_OVERLAP_BEHIND == eCmpPos )
     441             :                         {
     442           0 :                             *pStt = *pREnd;
     443           0 :                             if( ( *pStt == *pEnd ) &&
     444           0 :                                 ( pNewRedl->GetContentIdx() == NULL ) )
     445           0 :                                 bDelete = true;
     446             :                         }
     447          40 :                         else if( POS_OVERLAP_BEFORE == eCmpPos )
     448             :                         {
     449           0 :                             *pEnd = *pRStt;
     450           0 :                             if( ( *pStt == *pEnd ) &&
     451           0 :                                 ( pNewRedl->GetContentIdx() == NULL ) )
     452           0 :                                 bDelete = true;
     453             :                         }
     454          40 :                         else if( POS_INSIDE == eCmpPos || POS_EQUAL == eCmpPos)
     455           0 :                             bDelete = true;
     456             : 
     457         195 :                         if( bDelete )
     458             :                         {
     459         155 :                             delete pNewRedl, pNewRedl = 0;
     460         155 :                             bCompress = true;
     461             :                         }
     462             :                     }
     463         247 :                     else if( POS_INSIDE == eCmpPos )
     464             :                     {
     465             :                         // split up
     466           0 :                         if( *pEnd != *pREnd )
     467             :                         {
     468           0 :                             SwRedline* pCpy = new SwRedline( *pRedl );
     469           0 :                             pCpy->SetStart( *pEnd );
     470           0 :                             pRedlineTbl->Insert( pCpy );
     471             :                         }
     472           0 :                         pRedl->SetEnd( *pStt, pREnd );
     473           0 :                         if( ( *pStt == *pRStt ) &&
     474           0 :                             ( pRedl->GetContentIdx() == NULL ) )
     475             :                         {
     476           0 :                             pRedlineTbl->DeleteAndDestroy( n );
     477           0 :                             bDec = true;
     478             :                         }
     479           0 :                         else if( !pRedl->HasValidRange() )
     480             :                         {
     481             :                             // re-insert
     482           0 :                             pRedlineTbl->Remove( n );
     483           0 :                             pRedlineTbl->Insert( pRedl );
     484             :                         }
     485             :                     }
     486         247 :                     else if ( POS_OUTSIDE == eCmpPos )
     487             :                     {
     488             :                         // handle overlapping redlines in broken documents
     489             : 
     490             :                         // split up the new redline, since it covers the
     491             :                         // existing redline. Insert the first part, and
     492             :                         // progress with the remainder as usual
     493           0 :                         SwRedline* pSplit = new SwRedline( *pNewRedl );
     494           0 :                         pSplit->SetEnd( *pRStt );
     495           0 :                         pNewRedl->SetStart( *pREnd );
     496           0 :                         pRedlineTbl->Insert( pSplit );
     497           0 :                         if( *pStt == *pEnd && pNewRedl->GetContentIdx() == NULL )
     498             :                         {
     499           0 :                             delete pNewRedl;
     500           0 :                             pNewRedl = 0;
     501           0 :                             bCompress = true;
     502             :                         }
     503             :                     }
     504         247 :                     else if ( POS_OVERLAP_BEHIND == eCmpPos )
     505             :                     {
     506             :                         // handle overlapping redlines in broken documents
     507           0 :                         pNewRedl->SetStart( *pREnd );
     508             :                     }
     509         247 :                     else if ( POS_OVERLAP_BEFORE == eCmpPos )
     510             :                     {
     511             :                         // handle overlapping redlines in broken documents
     512           0 :                         *pEnd = *pRStt;
     513           0 :                         if( ( *pStt == *pEnd ) &&
     514           0 :                             ( pNewRedl->GetContentIdx() == NULL ) )
     515             :                         {
     516           0 :                             delete pNewRedl;
     517           0 :                             pNewRedl = 0;
     518           0 :                             bCompress = true;
     519             :                         }
     520             :                     }
     521         442 :                     break;
     522             :                 case nsRedlineType_t::REDLINE_DELETE:
     523           1 :                     if( POS_INSIDE == eCmpPos )
     524             :                     {
     525             :                         // split up
     526           0 :                         if( *pEnd != *pREnd )
     527             :                         {
     528           0 :                             SwRedline* pCpy = new SwRedline( *pRedl );
     529           0 :                             pCpy->SetStart( *pEnd );
     530           0 :                             pRedlineTbl->Insert( pCpy );
     531             :                         }
     532           0 :                         pRedl->SetEnd( *pStt, pREnd );
     533           0 :                         if( ( *pStt == *pRStt ) &&
     534           0 :                             ( pRedl->GetContentIdx() == NULL ) )
     535             :                         {
     536           0 :                             pRedlineTbl->DeleteAndDestroy( n );
     537           0 :                             bDec = true;
     538             :                         }
     539           0 :                         else if( !pRedl->HasValidRange() )
     540             :                         {
     541             :                             // re-insert
     542           0 :                             pRedlineTbl->Remove( n );
     543           0 :                             pRedlineTbl->Insert( pRedl, n );
     544             :                         }
     545             :                     }
     546           1 :                     else if ( POS_OUTSIDE == eCmpPos )
     547             :                     {
     548             :                         // handle overlapping redlines in broken documents
     549             : 
     550             :                         // split up the new redline, since it covers the
     551             :                         // existing redline. Insert the first part, and
     552             :                         // progress with the remainder as usual
     553           0 :                         SwRedline* pSplit = new SwRedline( *pNewRedl );
     554           0 :                         pSplit->SetEnd( *pRStt );
     555           0 :                         pNewRedl->SetStart( *pREnd );
     556           0 :                         pRedlineTbl->Insert( pSplit );
     557           0 :                         if( *pStt == *pEnd && pNewRedl->GetContentIdx() == NULL )
     558             :                         {
     559           0 :                             delete pNewRedl;
     560           0 :                             pNewRedl = 0;
     561           0 :                             bCompress = true;
     562             :                         }
     563             :                     }
     564           1 :                     else if ( POS_EQUAL == eCmpPos )
     565             :                     {
     566             :                         // handle identical redlines in broken documents
     567             :                         // delete old (delete) redline
     568           0 :                         pRedlineTbl->DeleteAndDestroy( n );
     569           0 :                         bDec = true;
     570             :                     }
     571           1 :                     else if ( POS_OVERLAP_BEHIND == eCmpPos )
     572             :                     {   // Another workaround for broken redlines
     573           0 :                         pNewRedl->SetStart( *pREnd );
     574             :                     }
     575           1 :                     break;
     576             :                 case nsRedlineType_t::REDLINE_FORMAT:
     577           0 :                     switch( eCmpPos )
     578             :                     {
     579             :                     case POS_OVERLAP_BEFORE:
     580           0 :                         pRedl->SetStart( *pEnd, pRStt );
     581             :                         // re-insert
     582           0 :                         pRedlineTbl->Remove( n );
     583           0 :                         pRedlineTbl->Insert( pRedl, n );
     584           0 :                         bDec = true;
     585           0 :                         break;
     586             : 
     587             :                     case POS_OVERLAP_BEHIND:
     588           0 :                         pRedl->SetEnd( *pStt, pREnd );
     589           0 :                         if( *pStt == *pRStt && pRedl->GetContentIdx() == NULL )
     590             :                         {
     591           0 :                             pRedlineTbl->DeleteAndDestroy( n );
     592           0 :                             bDec = true;
     593             :                         }
     594           0 :                         break;
     595             : 
     596             :                     case POS_EQUAL:
     597             :                     case POS_OUTSIDE:
     598             :                         // Overlaps the current one completely or has the
     599             :                         // same dimension, delete the old one
     600           0 :                         pRedlineTbl->DeleteAndDestroy( n );
     601           0 :                         bDec = true;
     602           0 :                         break;
     603             : 
     604             :                     case POS_INSIDE:
     605             :                         // Overlaps the current one completely,
     606             :                         // split or shorten the new one
     607           0 :                         if( *pEnd != *pREnd )
     608             :                         {
     609           0 :                             if( *pEnd != *pRStt )
     610             :                             {
     611           0 :                                 SwRedline* pNew = new SwRedline( *pRedl );
     612           0 :                                 pNew->SetStart( *pEnd );
     613           0 :                                 pRedl->SetEnd( *pStt, pREnd );
     614           0 :                                 if( *pStt == *pRStt && pRedl->GetContentIdx() == NULL )
     615           0 :                                     pRedlineTbl->DeleteAndDestroy( n );
     616           0 :                                 AppendRedline( pNew, bCallDelete );
     617           0 :                                 n = 0;      // re-initialize
     618           0 :                                 bDec = true;
     619             :                             }
     620             :                         }
     621             :                         else
     622           0 :                             pRedl->SetEnd( *pStt, pREnd );
     623           0 :                         break;
     624             :                     default:
     625           0 :                         break;
     626             :                     }
     627           0 :                     break;
     628             :                 default:
     629           0 :                     break;
     630             :                 }
     631         443 :                 break;
     632             : 
     633             :             case nsRedlineType_t::REDLINE_DELETE:
     634           0 :                 switch( pRedl->GetType() )
     635             :                 {
     636             :                 case nsRedlineType_t::REDLINE_DELETE:
     637           0 :                     switch( eCmpPos )
     638             :                     {
     639             :                     case POS_OUTSIDE:
     640             :                         {
     641             :                             // Overlaps the current one completely,
     642             :                             // split the new one
     643           0 :                             if( *pEnd != *pREnd )
     644             :                             {
     645           0 :                                 SwRedline* pNew = new SwRedline( *pNewRedl );
     646           0 :                                 pNew->SetStart( *pREnd );
     647           0 :                                 pNewRedl->SetEnd( *pRStt, pEnd );
     648           0 :                                 AppendRedline( pNew, bCallDelete );
     649           0 :                                 n = 0;      // re-initialize
     650           0 :                                 bDec = true;
     651             :                             }
     652             :                             else
     653           0 :                                 pNewRedl->SetEnd( *pRStt, pEnd );
     654             :                         }
     655           0 :                         break;
     656             : 
     657             :                     case POS_INSIDE:
     658             :                     case POS_EQUAL:
     659           0 :                         delete pNewRedl, pNewRedl = 0;
     660           0 :                         bCompress = true;
     661           0 :                         break;
     662             : 
     663             :                     case POS_OVERLAP_BEFORE:
     664             :                     case POS_OVERLAP_BEHIND:
     665           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
     666             : //                          1 == pRedl->GetStackCount() &&
     667           0 :                             pRedl->CanCombine( *pNewRedl ))
     668             :                         {
     669             :                             // If that's the case we can merge it, meaning
     670             :                             // the new one covers this well
     671           0 :                             if( POS_OVERLAP_BEHIND == eCmpPos )
     672           0 :                                 pNewRedl->SetStart( *pRStt, pStt );
     673             :                             else
     674           0 :                                 pNewRedl->SetEnd( *pREnd, pEnd );
     675           0 :                             pRedlineTbl->DeleteAndDestroy( n );
     676           0 :                             bDec = true;
     677             :                         }
     678           0 :                         else if( POS_OVERLAP_BEHIND == eCmpPos )
     679           0 :                             pNewRedl->SetStart( *pREnd, pStt );
     680             :                         else
     681           0 :                             pNewRedl->SetEnd( *pRStt, pEnd );
     682           0 :                         break;
     683             : 
     684             :                     case POS_COLLIDE_START:
     685             :                     case POS_COLLIDE_END:
     686           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
     687           0 :                             pRedl->CanCombine( *pNewRedl ) )
     688             :                         {
     689           0 :                             if( IsHideChanges( eRedlineMode ))
     690             :                             {
     691             :                                 // Before we can merge, we make it visible!
     692             :                                 // We insert temporarily so that pNew is
     693             :                                 // also dealt with when moving the indices.
     694           0 :                                 pRedlineTbl->Insert( pNewRedl );
     695           0 :                                 pRedl->Show();
     696           0 :                                 pRedlineTbl->Remove( pNewRedl );
     697           0 :                                 pRStt = pRedl->Start();
     698           0 :                                 pREnd = pRedl->End();
     699             :                             }
     700             : 
     701             :                             // If that's the case we can merge it, meaning
     702             :                             // the new one covers this well
     703           0 :                             if( POS_COLLIDE_START == eCmpPos )
     704           0 :                                 pNewRedl->SetStart( *pRStt, pStt );
     705             :                             else
     706           0 :                                 pNewRedl->SetEnd( *pREnd, pEnd );
     707             : 
     708             :                             // delete current (below), and restart process with
     709             :                             // previous
     710           0 :                             sal_uInt16 nToBeDeleted = n;
     711           0 :                             bDec = true;
     712             : 
     713           0 :                             if( *(pNewRedl->Start()) <= *pREnd )
     714             :                             {
     715             :                                 // Whoooah, we just extended the new 'redline'
     716             :                                 // beyond previous redlines, so better start
     717             :                                 // again. Of course this is not supposed to
     718             :                                 // happen, and in an ideal world it doesn't,
     719             :                                 // but unfortunately this code is buggy and
     720             :                                 // totally rotten so it does happen and we
     721             :                                 // better fix it.
     722           0 :                                 n = 0;
     723           0 :                                 bDec = true;
     724             :                             }
     725             : 
     726           0 :                             pRedlineTbl->DeleteAndDestroy( nToBeDeleted );
     727             :                         }
     728           0 :                         break;
     729             :                     default:
     730           0 :                         break;
     731             :                     }
     732           0 :                     break;
     733             : 
     734             :                 case nsRedlineType_t::REDLINE_INSERT:
     735             :                 {
     736             :                     // b62341295: Do not throw away redlines
     737             :                     // even if they are not allowed to be combined
     738           0 :                     RedlineMode_t eOld = eRedlineMode;
     739           0 :                     if( !( eOld & nsRedlineMode_t::REDLINE_DONTCOMBINE_REDLINES ) &&
     740           0 :                         pRedl->IsOwnRedline( *pNewRedl ) )
     741             :                     {
     742             : 
     743             :               // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
     744             :               // The ShowMode needs to be retained!
     745           0 :               eRedlineMode = (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE));
     746           0 :                         switch( eCmpPos )
     747             :                         {
     748             :                         case POS_EQUAL:
     749           0 :                             bCompress = true;
     750           0 :                             pRedlineTbl->DeleteAndDestroy( n );
     751           0 :                             bDec = true;
     752             :                             // no break!
     753             : 
     754             :                         case POS_INSIDE:
     755           0 :                             if( bCallDelete )
     756             :                             {
     757           0 :                               eRedlineMode = (RedlineMode_t)(eRedlineMode | nsRedlineMode_t::REDLINE_IGNOREDELETE_REDLINES);
     758             : 
     759             :                                 // DeleteAndJoin does not yield the
     760             :                                 // desired result if there is no paragraph to
     761             :                                 // join with, i.e. at the end of the document.
     762             :                                 // For this case, we completely delete the
     763             :                                 // paragraphs (if, of course, we also start on
     764             :                                 // a paragraph boundary).
     765           0 :                                 if( (pStt->nContent == 0) &&
     766           0 :                                     pEnd->nNode.GetNode().IsEndNode() )
     767             :                                 {
     768           0 :                                     pEnd->nNode--;
     769             :                                     pEnd->nContent.Assign(
     770           0 :                                         pEnd->nNode.GetNode().GetTxtNode(), 0);
     771           0 :                                     DelFullPara( *pNewRedl );
     772             :                                 }
     773             :                                 else
     774           0 :                                     DeleteAndJoin( *pNewRedl );
     775             : 
     776           0 :                                 bCompress = true;
     777             :                             }
     778           0 :                             delete pNewRedl, pNewRedl = 0;
     779           0 :                             break;
     780             : 
     781             :                         case POS_OUTSIDE:
     782             :                             {
     783           0 :                                 pRedlineTbl->Remove( n );
     784           0 :                                 bDec = true;
     785             :                                 // We insert temporarily so that pNew is
     786             :                                 // also dealt with when moving the indices.
     787           0 :                                 if( bCallDelete )
     788             :                                 {
     789           0 :                                     pRedlineTbl->Insert( pNewRedl );
     790           0 :                                     DeleteAndJoin( *pRedl );
     791           0 :                                     if( !pRedlineTbl->Remove( pNewRedl ) )
     792           0 :                                         pNewRedl = 0;
     793             :                                 }
     794           0 :                                 delete pRedl;
     795             :                             }
     796           0 :                             break;
     797             : 
     798             :                         case POS_OVERLAP_BEFORE:
     799             :                             {
     800           0 :                                 SwPaM aPam( *pRStt, *pEnd );
     801             : 
     802           0 :                                 if( *pEnd == *pREnd )
     803           0 :                                     pRedlineTbl->DeleteAndDestroy( n );
     804             :                                 else
     805             :                                 {
     806           0 :                                     pRedl->SetStart( *pEnd, pRStt );
     807             :                                     // re-insert
     808           0 :                                     pRedlineTbl->Remove( n );
     809           0 :                                     pRedlineTbl->Insert( pRedl, n );
     810             :                                 }
     811             : 
     812           0 :                                 if( bCallDelete )
     813             :                                 {
     814             :                                     // We insert temporarily so that pNew is
     815             :                                     // also dealt with when moving the indices.
     816           0 :                                     pRedlineTbl->Insert( pNewRedl );
     817           0 :                                     DeleteAndJoin( aPam );
     818           0 :                                     if( !pRedlineTbl->Remove( pNewRedl ) )
     819           0 :                                         pNewRedl = 0;
     820           0 :                                     n = 0;      // re-initialize
     821             :                                 }
     822           0 :                                 bDec = true;
     823             :                             }
     824           0 :                             break;
     825             : 
     826             :                         case POS_OVERLAP_BEHIND:
     827             :                             {
     828           0 :                                 SwPaM aPam( *pStt, *pREnd );
     829             : 
     830           0 :                                 if( *pStt == *pRStt )
     831             :                                 {
     832           0 :                                     pRedlineTbl->DeleteAndDestroy( n );
     833           0 :                                     bDec = true;
     834             :                                 }
     835             :                                 else
     836           0 :                                     pRedl->SetEnd( *pStt, pREnd );
     837             : 
     838           0 :                                 if( bCallDelete )
     839             :                                 {
     840             :                                     // We insert temporarily so that pNew is
     841             :                                     // also dealt with when moving the indices.
     842           0 :                                     pRedlineTbl->Insert( pNewRedl );
     843           0 :                                     DeleteAndJoin( aPam );
     844           0 :                                     if( !pRedlineTbl->Remove( pNewRedl ) )
     845           0 :                                         pNewRedl = 0;
     846           0 :                                     n = 0;      // re-initialize
     847           0 :                                     bDec = true;
     848           0 :                                 }
     849             :                             }
     850           0 :                             break;
     851             :                         default:
     852           0 :                             break;
     853             :                         }
     854             : 
     855           0 :                         eRedlineMode = eOld;
     856             :                     }
     857             :                     else
     858             :                     {
     859             :                         // it may be necessary to split the existing redline in
     860             :                         // two. In this case, pRedl will be changed to cover
     861             :                         // only part of it's former range, and pNew will cover
     862             :                         // the remainder.
     863           0 :                         SwRedline* pNew = 0;
     864             : 
     865           0 :                         switch( eCmpPos )
     866             :                         {
     867             :                         case POS_EQUAL:
     868             :                             {
     869           0 :                                 pRedl->PushData( *pNewRedl );
     870           0 :                                 delete pNewRedl, pNewRedl = 0;
     871           0 :                                 if( IsHideChanges( eRedlineMode ))
     872           0 :                                     pRedl->Hide();
     873           0 :                                 bCompress = true;
     874             :                             }
     875           0 :                             break;
     876             : 
     877             :                         case POS_INSIDE:
     878             :                             {
     879           0 :                                 if( *pRStt == *pStt )
     880             :                                 {
     881             :                                     // #i97421#
     882             :                                     // redline w/out extent loops
     883           0 :                                     if (*pStt != *pEnd)
     884             :                                     {
     885           0 :                                         pNewRedl->PushData( *pRedl, sal_False );
     886           0 :                                         pRedl->SetStart( *pEnd, pRStt );
     887             :                                         // re-insert
     888           0 :                                         pRedlineTbl->Remove( n );
     889           0 :                                         pRedlineTbl->Insert( pRedl, n );
     890           0 :                                         bDec = true;
     891             :                                     }
     892             :                                 }
     893             :                                 else
     894             :                                 {
     895           0 :                                     pNewRedl->PushData( *pRedl, sal_False );
     896           0 :                                     if( *pREnd != *pEnd )
     897             :                                     {
     898           0 :                                         pNew = new SwRedline( *pRedl );
     899           0 :                                         pNew->SetStart( *pEnd );
     900             :                                     }
     901           0 :                                     pRedl->SetEnd( *pStt, pREnd );
     902           0 :                                     if( !pRedl->HasValidRange() )
     903             :                                     {
     904             :                                         // re-insert
     905           0 :                                         pRedlineTbl->Remove( n );
     906           0 :                                         pRedlineTbl->Insert( pRedl, n );
     907             :                                     }
     908             :                                 }
     909             :                             }
     910           0 :                             break;
     911             : 
     912             :                         case POS_OUTSIDE:
     913             :                             {
     914           0 :                                 pRedl->PushData( *pNewRedl );
     915           0 :                                 if( *pEnd == *pREnd )
     916           0 :                                     pNewRedl->SetEnd( *pRStt, pEnd );
     917             :                                 else
     918             :                                 {
     919           0 :                                     pNew = new SwRedline( *pNewRedl );
     920           0 :                                     pNew->SetEnd( *pRStt );
     921           0 :                                     pNewRedl->SetStart( *pREnd, pStt );
     922             :                                 }
     923           0 :                                 bCompress = true;
     924             :                             }
     925           0 :                             break;
     926             : 
     927             :                         case POS_OVERLAP_BEFORE:
     928             :                             {
     929           0 :                                 if( *pEnd == *pREnd )
     930             :                                 {
     931           0 :                                     pRedl->PushData( *pNewRedl );
     932           0 :                                     pNewRedl->SetEnd( *pRStt, pEnd );
     933           0 :                                     if( IsHideChanges( eRedlineMode ))
     934             :                                     {
     935           0 :                                         pRedlineTbl->Insert( pNewRedl );
     936           0 :                                         pRedl->Hide();
     937           0 :                                         pRedlineTbl->Remove( pNewRedl );
     938             :                                     }
     939             :                                 }
     940             :                                 else
     941             :                                 {
     942           0 :                                     pNew = new SwRedline( *pRedl );
     943           0 :                                     pNew->PushData( *pNewRedl );
     944           0 :                                     pNew->SetEnd( *pEnd );
     945           0 :                                     pNewRedl->SetEnd( *pRStt, pEnd );
     946           0 :                                     pRedl->SetStart( *pNew->End(), pRStt ) ;
     947             :                                     // re-insert
     948           0 :                                     pRedlineTbl->Remove( n );
     949           0 :                                     pRedlineTbl->Insert( pRedl );
     950           0 :                                     bDec = true;
     951             :                                 }
     952             :                             }
     953           0 :                             break;
     954             : 
     955             :                         case POS_OVERLAP_BEHIND:
     956             :                             {
     957           0 :                                 if( *pStt == *pRStt )
     958             :                                 {
     959           0 :                                     pRedl->PushData( *pNewRedl );
     960           0 :                                     pNewRedl->SetStart( *pREnd, pStt );
     961           0 :                                     if( IsHideChanges( eRedlineMode ))
     962             :                                     {
     963           0 :                                         pRedlineTbl->Insert( pNewRedl );
     964           0 :                                         pRedl->Hide();
     965           0 :                                         pRedlineTbl->Remove( pNewRedl );
     966             :                                     }
     967             :                                 }
     968             :                                 else
     969             :                                 {
     970           0 :                                     pNew = new SwRedline( *pRedl );
     971           0 :                                     pNew->PushData( *pNewRedl );
     972           0 :                                     pNew->SetStart( *pStt );
     973           0 :                                     pNewRedl->SetStart( *pREnd, pStt );
     974           0 :                                     pRedl->SetEnd( *pNew->Start(), pREnd );
     975           0 :                                     if( !pRedl->HasValidRange() )
     976             :                                     {
     977             :                                         // re-insert
     978           0 :                                         pRedlineTbl->Remove( n );
     979           0 :                                         pRedlineTbl->Insert( pRedl );
     980             :                                     }
     981             :                                 }
     982             :                             }
     983           0 :                             break;
     984             :                         default:
     985           0 :                             break;
     986             :                         }
     987             : 
     988             :                         // insert the pNew part (if it exists)
     989           0 :                         if( pNew )
     990             :                         {
     991           0 :                             pRedlineTbl->Insert( pNew );
     992             : 
     993             :                             // pNew must be deleted if Insert() wasn't
     994             :                             // successful. But that can't happen, since pNew is
     995             :                             // part of the original pRedl redline.
     996             :                             // OSL_ENSURE( bRet, "Can't insert existing redline?" );
     997             : 
     998             :                             // restart (now with pRedl being split up)
     999           0 :                             n = 0;
    1000           0 :                             bDec = true;
    1001             :                         }
    1002             :                     }
    1003             :                 }
    1004           0 :                 break;
    1005             : 
    1006             :                 case nsRedlineType_t::REDLINE_FORMAT:
    1007           0 :                     switch( eCmpPos )
    1008             :                     {
    1009             :                     case POS_OVERLAP_BEFORE:
    1010           0 :                         pRedl->SetStart( *pEnd, pRStt );
    1011             :                         // re-insert
    1012           0 :                         pRedlineTbl->Remove( n );
    1013           0 :                         pRedlineTbl->Insert( pRedl, n );
    1014           0 :                         bDec = true;
    1015           0 :                         break;
    1016             : 
    1017             :                     case POS_OVERLAP_BEHIND:
    1018           0 :                         pRedl->SetEnd( *pStt, pREnd );
    1019           0 :                         break;
    1020             : 
    1021             :                     case POS_EQUAL:
    1022             :                     case POS_OUTSIDE:
    1023             :                         // Overlaps the current one completely or has the
    1024             :                         // same dimension, delete the old one
    1025           0 :                         pRedlineTbl->DeleteAndDestroy( n );
    1026           0 :                         bDec = true;
    1027           0 :                         break;
    1028             : 
    1029             :                     case POS_INSIDE:
    1030             :                         // Overlaps the current one completely,
    1031             :                         // split or shorten the new one
    1032           0 :                         if( *pEnd != *pREnd )
    1033             :                         {
    1034           0 :                             if( *pEnd != *pRStt )
    1035             :                             {
    1036           0 :                                 SwRedline* pNew = new SwRedline( *pRedl );
    1037           0 :                                 pNew->SetStart( *pEnd );
    1038           0 :                                 pRedl->SetEnd( *pStt, pREnd );
    1039           0 :                                 if( ( *pStt == *pRStt ) &&
    1040           0 :                                     ( pRedl->GetContentIdx() == NULL ) )
    1041           0 :                                     pRedlineTbl->DeleteAndDestroy( n );
    1042           0 :                                 AppendRedline( pNew, bCallDelete );
    1043           0 :                                 n = 0;      // re-initialize
    1044           0 :                                 bDec = true;
    1045             :                             }
    1046             :                         }
    1047             :                         else
    1048           0 :                             pRedl->SetEnd( *pStt, pREnd );
    1049           0 :                         break;
    1050             :                     default:
    1051           0 :                         break;
    1052             :                     }
    1053           0 :                     break;
    1054             :                 default:
    1055           0 :                     break;
    1056             :                 }
    1057           0 :                 break;
    1058             : 
    1059             :             case nsRedlineType_t::REDLINE_FORMAT:
    1060           0 :                 switch( pRedl->GetType() )
    1061             :                 {
    1062             :                 case nsRedlineType_t::REDLINE_INSERT:
    1063             :                 case nsRedlineType_t::REDLINE_DELETE:
    1064           0 :                     switch( eCmpPos )
    1065             :                     {
    1066             :                     case POS_OVERLAP_BEFORE:
    1067           0 :                         pNewRedl->SetEnd( *pRStt, pEnd );
    1068           0 :                         break;
    1069             : 
    1070             :                     case POS_OVERLAP_BEHIND:
    1071           0 :                         pNewRedl->SetStart( *pREnd, pStt );
    1072           0 :                         break;
    1073             : 
    1074             :                     case POS_EQUAL:
    1075             :                     case POS_INSIDE:
    1076           0 :                         delete pNewRedl, pNewRedl = 0;
    1077           0 :                         break;
    1078             : 
    1079             :                     case POS_OUTSIDE:
    1080             :                         // Overlaps the current one completely,
    1081             :                         // split or shorten the new one
    1082           0 :                         if( *pEnd != *pREnd )
    1083             :                         {
    1084           0 :                             if( *pEnd != *pRStt )
    1085             :                             {
    1086           0 :                                 SwRedline* pNew = new SwRedline( *pNewRedl );
    1087           0 :                                 pNew->SetStart( *pREnd );
    1088           0 :                                 pNewRedl->SetEnd( *pRStt, pEnd );
    1089           0 :                                 AppendRedline( pNew, bCallDelete );
    1090           0 :                                 n = 0;      // re-initialize
    1091           0 :                                 bDec = true;
    1092             :                             }
    1093             :                         }
    1094             :                         else
    1095           0 :                             pNewRedl->SetEnd( *pRStt, pEnd );
    1096           0 :                         break;
    1097             :                     default:
    1098           0 :                         break;
    1099             :                     }
    1100           0 :                     break;
    1101             :                 case nsRedlineType_t::REDLINE_FORMAT:
    1102           0 :                     switch( eCmpPos )
    1103             :                     {
    1104             :                     case POS_OUTSIDE:
    1105             :                     case POS_EQUAL:
    1106             :                         {
    1107             :                             // Overlaps the current one completely or has the
    1108             :                             // same dimension, delete the old one
    1109           0 :                             pRedlineTbl->DeleteAndDestroy( n );
    1110           0 :                             bDec = true;
    1111             :                         }
    1112           0 :                         break;
    1113             : 
    1114             :                     case POS_INSIDE:
    1115           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1116           0 :                             pRedl->CanCombine( *pNewRedl ))
    1117             :                             // own one can be ignored completely
    1118           0 :                             delete pNewRedl, pNewRedl = 0;
    1119             : 
    1120           0 :                         else if( *pREnd == *pEnd )
    1121             :                             // or else only shorten the current one
    1122           0 :                             pRedl->SetEnd( *pStt, pREnd );
    1123           0 :                         else if( *pRStt == *pStt )
    1124             :                         {
    1125             :                             // or else only shorten the current one
    1126           0 :                             pRedl->SetStart( *pEnd, pRStt );
    1127             :                             // re-insert
    1128           0 :                             pRedlineTbl->Remove( n );
    1129           0 :                             pRedlineTbl->Insert( pRedl, n );
    1130           0 :                             bDec = true;
    1131             :                         }
    1132             :                         else
    1133             :                         {
    1134             :                             // If it lies completely within the current one
    1135             :                             // we need to split it
    1136           0 :                             SwRedline* pNew = new SwRedline( *pRedl );
    1137           0 :                             pNew->SetStart( *pEnd );
    1138           0 :                             pRedl->SetEnd( *pStt, pREnd );
    1139           0 :                             AppendRedline( pNew, bCallDelete );
    1140           0 :                             n = 0;      // re-initialize
    1141           0 :                             bDec = true;
    1142             :                         }
    1143           0 :                         break;
    1144             : 
    1145             :                     case POS_OVERLAP_BEFORE:
    1146             :                     case POS_OVERLAP_BEHIND:
    1147           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1148           0 :                             pRedl->CanCombine( *pNewRedl ))
    1149             :                         {
    1150             :                             // If that's the case we can merge it, meaning
    1151             :                             // the new one covers this well
    1152           0 :                             if( POS_OVERLAP_BEHIND == eCmpPos )
    1153           0 :                                 pNewRedl->SetStart( *pRStt, pStt );
    1154             :                             else
    1155           0 :                                 pNewRedl->SetEnd( *pREnd, pEnd );
    1156           0 :                             pRedlineTbl->DeleteAndDestroy( n );
    1157           0 :                             bDec = 0;
    1158             :                         }
    1159           0 :                         else if( POS_OVERLAP_BEHIND == eCmpPos )
    1160           0 :                             pNewRedl->SetStart( *pREnd, pStt );
    1161             :                         else
    1162           0 :                             pNewRedl->SetEnd( *pRStt, pEnd );
    1163           0 :                         break;
    1164             : 
    1165             :                     case POS_COLLIDE_END:
    1166           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1167           0 :                             pRedl->CanCombine( *pNewRedl ) && n &&
    1168           0 :                             *(*pRedlineTbl)[ n-1 ]->End() < *pStt )
    1169             :                         {
    1170             :                             // If that's the case we can merge it, meaning
    1171             :                             // the new one covers this well
    1172           0 :                             pNewRedl->SetEnd( *pREnd, pEnd );
    1173           0 :                             pRedlineTbl->DeleteAndDestroy( n );
    1174           0 :                             bDec = true;
    1175             :                         }
    1176           0 :                         break;
    1177             :                     case POS_COLLIDE_START:
    1178           0 :                         if( pRedl->IsOwnRedline( *pNewRedl ) &&
    1179           0 :                             pRedl->CanCombine( *pNewRedl ) &&
    1180           0 :                             n+1 < (sal_uInt16)pRedlineTbl->size() &&
    1181           0 :                             *(*pRedlineTbl)[ n+1 ]->Start() < *pEnd )
    1182             :                         {
    1183             :                             // If that's the case we can merge it, meaning
    1184             :                             // the new one covers this well
    1185           0 :                             pNewRedl->SetStart( *pRStt, pStt );
    1186           0 :                             pRedlineTbl->DeleteAndDestroy( n );
    1187           0 :                             bDec = true;
    1188             :                         }
    1189           0 :                         break;
    1190             :                     default:
    1191           0 :                         break;
    1192             :                     }
    1193           0 :                     break;
    1194             :                 default:
    1195           0 :                     break;
    1196             :                 }
    1197           0 :                 break;
    1198             : 
    1199             : 
    1200             :             case nsRedlineType_t::REDLINE_FMTCOLL:
    1201             :                 // How should we behave here?
    1202             :                 // insert as is
    1203           0 :                 break;
    1204             :             default:
    1205           0 :                 break;
    1206             :             }
    1207             :         }
    1208             : 
    1209         475 :         if( pNewRedl )
    1210             :         {
    1211         320 :             if( ( *pStt == *pEnd ) &&
    1212           0 :                 ( pNewRedl->GetContentIdx() == NULL ) )
    1213             :             {   // Do not insert empty redlines
    1214           0 :                 delete pNewRedl;
    1215           0 :                 pNewRedl = 0;
    1216             :             }
    1217             :             else
    1218         320 :                 pRedlineTbl->Insert( pNewRedl );
    1219             :         }
    1220             : 
    1221         475 :         if( bCompress )
    1222         155 :             CompressRedlines();
    1223             :     }
    1224             :     else
    1225             :     {
    1226         274 :         if( bCallDelete && nsRedlineType_t::REDLINE_DELETE == pNewRedl->GetType() )
    1227             :         {
    1228           0 :             RedlineMode_t eOld = eRedlineMode;
    1229             :             // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
    1230             :             // The ShowMode needs to be retained!
    1231           0 :             eRedlineMode = (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE));
    1232           0 :             DeleteAndJoin( *pNewRedl );
    1233           0 :             eRedlineMode = eOld;
    1234             :         }
    1235         274 :         delete pNewRedl, pNewRedl = 0;
    1236             :     }
    1237             :     _CHECK_REDLINE( this )
    1238             : 
    1239         749 :     return ( 0 != pNewRedl ) || !bError;
    1240             : }
    1241             : 
    1242         159 : void SwDoc::CompressRedlines()
    1243             : {
    1244             :     _CHECK_REDLINE( this )
    1245             : 
    1246         159 :     void (SwRedline::*pFnc)(sal_uInt16) = 0;
    1247         159 :     switch( nsRedlineMode_t::REDLINE_SHOW_MASK & eRedlineMode )
    1248             :     {
    1249             :     case nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE:
    1250          56 :         pFnc = &SwRedline::Show;
    1251          56 :         break;
    1252             :     case nsRedlineMode_t::REDLINE_SHOW_INSERT:
    1253         103 :         pFnc = &SwRedline::Hide;
    1254         103 :         break;
    1255             :     }
    1256             : 
    1257             :     // Try to merge identical ones
    1258        1060 :     for( sal_uInt16 n = 1; n < pRedlineTbl->size(); ++n )
    1259             :     {
    1260         901 :         SwRedline* pPrev = (*pRedlineTbl)[ n-1 ],
    1261         901 :                     * pCur = (*pRedlineTbl)[ n ];
    1262         901 :         const SwPosition* pPrevStt = pPrev->Start(),
    1263         901 :                         * pPrevEnd = pPrevStt == pPrev->GetPoint()
    1264         901 :                             ? pPrev->GetMark() : pPrev->GetPoint();
    1265         901 :         const SwPosition* pCurStt = pCur->Start(),
    1266         901 :                         * pCurEnd = pCurStt == pCur->GetPoint()
    1267         901 :                             ? pCur->GetMark() : pCur->GetPoint();
    1268         901 :         if( *pPrevEnd == *pCurStt && pPrev->CanCombine( *pCur ) &&
    1269           0 :             pPrevStt->nNode.GetNode().StartOfSectionNode() ==
    1270           0 :             pCurEnd->nNode.GetNode().StartOfSectionNode() &&
    1271           0 :             !pCurEnd->nNode.GetNode().StartOfSectionNode()->IsTableNode() )
    1272             :         {
    1273             :             // we then can merge them
    1274           0 :             pPrev->Show();
    1275           0 :             pCur->Show();
    1276             : 
    1277           0 :             pPrev->SetEnd( *pCur->End() );
    1278           0 :             pRedlineTbl->DeleteAndDestroy( n );
    1279           0 :             --n;
    1280           0 :             if( pFnc )
    1281           0 :                 (pPrev->*pFnc)(0);
    1282             :         }
    1283             :     }
    1284             :     _CHECK_REDLINE( this )
    1285         159 : }
    1286             : 
    1287           4 : bool SwDoc::SplitRedline( const SwPaM& rRange )
    1288             : {
    1289           4 :     bool bChg = false;
    1290           4 :     sal_uInt16 n = 0;
    1291           4 :     const SwPosition* pStt = rRange.Start(),
    1292           4 :                   * pEnd = pStt == rRange.GetPoint() ? rRange.GetMark()
    1293           4 :                                                      : rRange.GetPoint();
    1294           4 :     GetRedline( *pStt, &n );
    1295           4 :     for( ; n < pRedlineTbl->size() ; ++n )
    1296             :     {
    1297           0 :         SwRedline* pTmp = (*pRedlineTbl)[ n ];
    1298           0 :         SwPosition* pTStt = pTmp->Start(),
    1299           0 :                   * pTEnd = pTStt == pTmp->GetPoint() ? pTmp->GetMark()
    1300           0 :                                                       : pTmp->GetPoint();
    1301           0 :         if( *pTStt <= *pStt && *pStt <= *pTEnd &&
    1302           0 :             *pTStt <= *pEnd && *pEnd <= *pTEnd )
    1303             :         {
    1304           0 :             bChg = true;
    1305           0 :             int nn = 0;
    1306           0 :             if( *pStt == *pTStt )
    1307           0 :                 nn += 1;
    1308           0 :             if( *pEnd == *pTEnd )
    1309           0 :                 nn += 2;
    1310             : 
    1311           0 :             SwRedline* pNew = 0;
    1312           0 :             switch( nn )
    1313             :             {
    1314             :             case 0:
    1315           0 :                 pNew = new SwRedline( *pTmp );
    1316           0 :                 pTmp->SetEnd( *pStt, pTEnd );
    1317           0 :                 pNew->SetStart( *pEnd );
    1318           0 :                 break;
    1319             : 
    1320             :             case 1:
    1321           0 :                 *pTStt = *pEnd;
    1322           0 :                 break;
    1323             : 
    1324             :             case 2:
    1325           0 :                 *pTEnd = *pStt;
    1326           0 :                 break;
    1327             : 
    1328             :             case 3:
    1329           0 :                 pTmp->InvalidateRange();
    1330           0 :                 pRedlineTbl->DeleteAndDestroy( n-- );
    1331           0 :                 pTmp = 0;
    1332           0 :                 break;
    1333             :             }
    1334           0 :             if( pTmp && !pTmp->HasValidRange() )
    1335             :             {
    1336             :                 // re-insert
    1337           0 :                 pRedlineTbl->Remove( n );
    1338           0 :                 pRedlineTbl->Insert( pTmp, n );
    1339             :             }
    1340           0 :             if( pNew )
    1341           0 :                 pRedlineTbl->Insert( pNew, n );
    1342             :         }
    1343           0 :         else if( *pEnd < *pTStt )
    1344           0 :             break;
    1345             :     }
    1346           4 :     return bChg;
    1347             : }
    1348             : 
    1349         418 : bool SwDoc::DeleteRedline( const SwPaM& rRange, bool bSaveInUndo,
    1350             :                             sal_uInt16 nDelType )
    1351             : {
    1352        1254 :     if( nsRedlineMode_t::REDLINE_IGNOREDELETE_REDLINES & eRedlineMode ||
    1353         836 :         !rRange.HasMark() || *rRange.GetMark() == *rRange.GetPoint() )
    1354           0 :         return sal_False;
    1355             : 
    1356         418 :     bool bChg = false;
    1357             : 
    1358         418 :     if (bSaveInUndo && GetIDocumentUndoRedo().DoesUndo())
    1359             :     {
    1360           0 :         SwUndoRedline* pUndo = new SwUndoRedline( UNDO_REDLINE, rRange );
    1361           0 :         if( pUndo->GetRedlSaveCount() )
    1362             :         {
    1363           0 :             GetIDocumentUndoRedo().AppendUndo(pUndo);
    1364             :         }
    1365             :         else
    1366           0 :             delete pUndo;
    1367             :     }
    1368             : 
    1369         418 :     const SwPosition* pStt = rRange.Start(),
    1370         418 :                     * pEnd = pStt == rRange.GetPoint() ? rRange.GetMark()
    1371         418 :                                                        : rRange.GetPoint();
    1372         418 :     sal_uInt16 n = 0;
    1373         418 :     GetRedline( *pStt, &n );
    1374         673 :     for( ; n < pRedlineTbl->size() ; ++n )
    1375             :     {
    1376         255 :         SwRedline* pRedl = (*pRedlineTbl)[ n ];
    1377         255 :         if( USHRT_MAX != nDelType && nDelType != pRedl->GetType() )
    1378           0 :             continue;
    1379             : 
    1380         255 :         SwPosition* pRStt = pRedl->Start(),
    1381         257 :                   * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
    1382         257 :                                                        : pRedl->GetPoint();
    1383         255 :         switch( ComparePosition( *pStt, *pEnd, *pRStt, *pREnd ) )
    1384             :         {
    1385             :         case POS_EQUAL:
    1386             :         case POS_OUTSIDE:
    1387         253 :             pRedl->InvalidateRange();
    1388         253 :             pRedlineTbl->DeleteAndDestroy( n-- );
    1389         253 :             bChg = true;
    1390         253 :             break;
    1391             : 
    1392             :         case POS_OVERLAP_BEFORE:
    1393           0 :                 pRedl->InvalidateRange();
    1394           0 :                 pRedl->SetStart( *pEnd, pRStt );
    1395             :                 // re-insert
    1396           0 :                 pRedlineTbl->Remove( n );
    1397           0 :                 pRedlineTbl->Insert( pRedl );
    1398           0 :                 --n;
    1399           0 :             break;
    1400             : 
    1401             :         case POS_OVERLAP_BEHIND:
    1402           0 :                 pRedl->InvalidateRange();
    1403           0 :                 pRedl->SetEnd( *pStt, pREnd );
    1404           0 :                 if( !pRedl->HasValidRange() )
    1405             :                 {
    1406             :                     // re-insert
    1407           0 :                     pRedlineTbl->Remove( n );
    1408           0 :                     pRedlineTbl->Insert( pRedl );
    1409           0 :                     --n;
    1410             :                 }
    1411           0 :             break;
    1412             : 
    1413             :         case POS_INSIDE:
    1414             :             {
    1415             :                 // this one needs to be splitted
    1416           0 :                 pRedl->InvalidateRange();
    1417           0 :                 if( *pRStt == *pStt )
    1418             :                 {
    1419           0 :                     pRedl->SetStart( *pEnd, pRStt );
    1420             :                     // re-insert
    1421           0 :                     pRedlineTbl->Remove( n );
    1422           0 :                     pRedlineTbl->Insert( pRedl );
    1423           0 :                     --n;
    1424             :                 }
    1425             :                 else
    1426             :                 {
    1427             :                     SwRedline* pCpy;
    1428           0 :                     if( *pREnd != *pEnd )
    1429             :                     {
    1430           0 :                         pCpy = new SwRedline( *pRedl );
    1431           0 :                         pCpy->SetStart( *pEnd );
    1432             :                     }
    1433             :                     else
    1434           0 :                         pCpy = 0;
    1435           0 :                     pRedl->SetEnd( *pStt, pREnd );
    1436           0 :                     if( !pRedl->HasValidRange() )
    1437             :                     {
    1438             :                         // re-insert
    1439           0 :                         pRedlineTbl->Remove( pRedl );
    1440           0 :                         pRedlineTbl->Insert( pRedl );
    1441           0 :                         --n;
    1442             :                     }
    1443           0 :                     if( pCpy )
    1444           0 :                         pRedlineTbl->Insert( pCpy );
    1445             :                 }
    1446             :             }
    1447           0 :             break;
    1448             : 
    1449             :         case POS_COLLIDE_END:
    1450             :         case POS_BEFORE:
    1451           2 :             n = pRedlineTbl->size();
    1452           2 :             break;
    1453             :         default:
    1454           0 :             break;
    1455             :         }
    1456             :     }
    1457             : 
    1458         418 :     if( bChg )
    1459          25 :         SetModified();
    1460             : 
    1461         418 :     return bChg;
    1462             : }
    1463             : 
    1464         181 : bool SwDoc::DeleteRedline( const SwStartNode& rNode, bool bSaveInUndo,
    1465             :                             sal_uInt16 nDelType )
    1466             : {
    1467         181 :     SwPaM aTemp(*rNode.EndOfSectionNode(), rNode);
    1468         181 :     return DeleteRedline(aTemp, bSaveInUndo, nDelType);
    1469             : }
    1470             : 
    1471        7604 : sal_uInt16 SwDoc::GetRedlinePos( const SwNode& rNd, sal_uInt16 nType ) const
    1472             : {
    1473        7604 :     const sal_uLong nNdIdx = rNd.GetIndex();
    1474        7604 :     for( sal_uInt16 n = 0; n < pRedlineTbl->size() ; ++n )
    1475             :     {
    1476          37 :         const SwRedline* pTmp = (*pRedlineTbl)[ n ];
    1477          37 :         sal_uLong nPt = pTmp->GetPoint()->nNode.GetIndex(),
    1478          37 :               nMk = pTmp->GetMark()->nNode.GetIndex();
    1479          37 :         if( nPt < nMk ) { long nTmp = nMk; nMk = nPt; nPt = nTmp; }
    1480             : 
    1481          37 :         if( ( USHRT_MAX == nType || nType == pTmp->GetType()) &&
    1482             :             nMk <= nNdIdx && nNdIdx <= nPt )
    1483          37 :             return n;
    1484             : 
    1485           0 :         if( nMk > nNdIdx )
    1486           0 :             break;
    1487             :     }
    1488        7567 :     return USHRT_MAX;
    1489             : }
    1490             : 
    1491         927 : const SwRedline* SwDoc::GetRedline( const SwPosition& rPos,
    1492             :                                     sal_uInt16* pFndPos ) const
    1493             : {
    1494         927 :     sal_uInt16 nO = pRedlineTbl->size(), nM, nU = 0;
    1495         927 :     if( nO > 0 )
    1496             :     {
    1497         685 :         nO--;
    1498        3555 :         while( nU <= nO )
    1499             :         {
    1500        2214 :             nM = nU + ( nO - nU ) / 2;
    1501        2214 :             const SwRedline* pRedl = (*pRedlineTbl)[ nM ];
    1502        2214 :             const SwPosition* pStt = pRedl->Start();
    1503        2214 :             const SwPosition* pEnd = pStt == pRedl->GetPoint()
    1504          52 :                                         ? pRedl->GetMark()
    1505        2266 :                                         : pRedl->GetPoint();
    1506        6532 :             if( pEnd == pStt
    1507             :                     ? *pStt == rPos
    1508        4318 :                     : ( *pStt <= rPos && rPos < *pEnd ) )
    1509             :             {
    1510           8 :                 while( nM && rPos == *(*pRedlineTbl)[ nM - 1 ]->End() &&
    1511           0 :                     rPos == *(*pRedlineTbl)[ nM - 1 ]->Start() )
    1512             :                 {
    1513           0 :                     --nM;
    1514           0 :                     pRedl = (*pRedlineTbl)[ nM ];
    1515             :                 }
    1516             :                 // if there are format and insert changes in the same position
    1517             :                 // show insert change first.
    1518             :                 // since the redlines are sorted by position, only check the redline
    1519             :                 // before and after the current redline
    1520           4 :                 if( nsRedlineType_t::REDLINE_FORMAT == pRedl->GetType() )
    1521             :                 {
    1522           0 :                     if( nM && rPos >= *(*pRedlineTbl)[ nM - 1 ]->Start() &&
    1523           0 :                         rPos <= *(*pRedlineTbl)[ nM - 1 ]->End() &&
    1524           0 :                         ( nsRedlineType_t::REDLINE_INSERT == (*pRedlineTbl)[ nM - 1 ]->GetType() ) )
    1525             :                     {
    1526           0 :                         --nM;
    1527           0 :                         pRedl = (*pRedlineTbl)[ nM ];
    1528             :                     }
    1529           0 :                     else if( ( nM + 1 ) <= nO && rPos >= *(*pRedlineTbl)[ nM + 1 ]->Start() &&
    1530           0 :                         rPos <= *(*pRedlineTbl)[ nM + 1 ]->End() &&
    1531           0 :                         ( nsRedlineType_t::REDLINE_INSERT == (*pRedlineTbl)[ nM + 1 ]->GetType() ) )
    1532             :                     {
    1533           0 :                         ++nM;
    1534           0 :                         pRedl = (*pRedlineTbl)[ nM ];
    1535             :                     }
    1536             :                 }
    1537             : 
    1538           4 :                 if( pFndPos )
    1539           4 :                     *pFndPos = nM;
    1540           4 :                 return pRedl;
    1541             :             }
    1542        2210 :             else if( *pEnd <= rPos )
    1543        2144 :                 nU = nM + 1;
    1544          66 :             else if( nM == 0 )
    1545             :             {
    1546          25 :                 if( pFndPos )
    1547          25 :                     *pFndPos = nU;
    1548          25 :                 return 0;
    1549             :             }
    1550             :             else
    1551          41 :                 nO = nM - 1;
    1552             :         }
    1553             :     }
    1554         898 :     if( pFndPos )
    1555         869 :         *pFndPos = nU;
    1556         898 :     return 0;
    1557             : }
    1558             : 
    1559             : typedef sal_Bool (*Fn_AcceptReject)( SwRedlineTbl& rArr, sal_uInt16& rPos,
    1560             :                         sal_Bool bCallDelete,
    1561             :                         const SwPosition* pSttRng,
    1562             :                         const SwPosition* pEndRng);
    1563             : 
    1564           0 : static sal_Bool lcl_AcceptRedline( SwRedlineTbl& rArr, sal_uInt16& rPos,
    1565             :                         sal_Bool bCallDelete,
    1566             :                         const SwPosition* pSttRng = 0,
    1567             :                         const SwPosition* pEndRng = 0 )
    1568             : {
    1569           0 :     sal_Bool bRet = sal_True;
    1570           0 :     SwRedline* pRedl = rArr[ rPos ];
    1571           0 :     SwPosition *pRStt = 0, *pREnd = 0;
    1572           0 :     SwComparePosition eCmp = POS_OUTSIDE;
    1573           0 :     if( pSttRng && pEndRng )
    1574             :     {
    1575           0 :         pRStt = pRedl->Start();
    1576           0 :         pREnd = pRedl->End();
    1577           0 :         eCmp = ComparePosition( *pSttRng, *pEndRng, *pRStt, *pREnd );
    1578             :     }
    1579             : 
    1580           0 :     pRedl->InvalidateRange();
    1581             : 
    1582           0 :     switch( pRedl->GetType() )
    1583             :     {
    1584             :     case nsRedlineType_t::REDLINE_INSERT:
    1585             :     case nsRedlineType_t::REDLINE_FORMAT:
    1586             :         {
    1587           0 :             bool bCheck = false, bReplace = false;
    1588           0 :             switch( eCmp )
    1589             :             {
    1590             :             case POS_INSIDE:
    1591           0 :                 if( *pSttRng == *pRStt )
    1592           0 :                     pRedl->SetStart( *pEndRng, pRStt );
    1593             :                 else
    1594             :                 {
    1595           0 :                     if( *pEndRng != *pREnd )
    1596             :                     {
    1597             :                         // split up
    1598           0 :                         SwRedline* pNew = new SwRedline( *pRedl );
    1599           0 :                         pNew->SetStart( *pEndRng );
    1600           0 :                         rArr.Insert( pNew ); ++rPos;
    1601             :                     }
    1602           0 :                     pRedl->SetEnd( *pSttRng, pREnd );
    1603           0 :                     bCheck = true;
    1604             :                 }
    1605           0 :                 break;
    1606             : 
    1607             :             case POS_OVERLAP_BEFORE:
    1608           0 :                 pRedl->SetStart( *pEndRng, pRStt );
    1609           0 :                 bReplace = true;
    1610           0 :                 break;
    1611             : 
    1612             :             case POS_OVERLAP_BEHIND:
    1613           0 :                 pRedl->SetEnd( *pSttRng, pREnd );
    1614           0 :                 bCheck = true;
    1615           0 :                 break;
    1616             : 
    1617             :             case POS_OUTSIDE:
    1618             :             case POS_EQUAL:
    1619           0 :                 rArr.DeleteAndDestroy( rPos-- );
    1620           0 :                 break;
    1621             : 
    1622             :             default:
    1623           0 :                 bRet = sal_False;
    1624             :             }
    1625             : 
    1626           0 :             if( bReplace || ( bCheck && !pRedl->HasValidRange() ))
    1627             :             {
    1628             :                 // re-insert
    1629           0 :                 rArr.Remove( pRedl );
    1630           0 :                 rArr.Insert( pRedl );
    1631             :             }
    1632             :         }
    1633           0 :         break;
    1634             :     case nsRedlineType_t::REDLINE_DELETE:
    1635             :         {
    1636           0 :             SwDoc& rDoc = *pRedl->GetDoc();
    1637           0 :             const SwPosition *pDelStt = 0, *pDelEnd = 0;
    1638           0 :             bool bDelRedl = false;
    1639           0 :             switch( eCmp )
    1640             :             {
    1641             :             case POS_INSIDE:
    1642           0 :                 if( bCallDelete )
    1643             :                 {
    1644           0 :                     pDelStt = pSttRng;
    1645           0 :                     pDelEnd = pEndRng;
    1646             :                 }
    1647           0 :                 break;
    1648             : 
    1649             :             case POS_OVERLAP_BEFORE:
    1650           0 :                 if( bCallDelete )
    1651             :                 {
    1652           0 :                     pDelStt = pRStt;
    1653           0 :                     pDelEnd = pEndRng;
    1654             :                 }
    1655           0 :                 break;
    1656             :             case POS_OVERLAP_BEHIND:
    1657           0 :                 if( bCallDelete )
    1658             :                 {
    1659           0 :                     pDelStt = pREnd;
    1660           0 :                     pDelEnd = pSttRng;
    1661             :                 }
    1662           0 :                 break;
    1663             : 
    1664             :             case POS_OUTSIDE:
    1665             :             case POS_EQUAL:
    1666             :                 {
    1667           0 :                     rArr.Remove( rPos-- );
    1668           0 :                     bDelRedl = true;
    1669           0 :                     if( bCallDelete )
    1670             :                     {
    1671           0 :                         pDelStt = pRedl->Start();
    1672           0 :                         pDelEnd = pRedl->End();
    1673             :                     }
    1674             :                 }
    1675           0 :                 break;
    1676             :             default:
    1677           0 :                 bRet = sal_False;
    1678             :             }
    1679             : 
    1680           0 :             if( pDelStt && pDelEnd )
    1681             :             {
    1682           0 :                 SwPaM aPam( *pDelStt, *pDelEnd );
    1683           0 :                 SwCntntNode* pCSttNd = pDelStt->nNode.GetNode().GetCntntNode();
    1684           0 :                 SwCntntNode* pCEndNd = pDelEnd->nNode.GetNode().GetCntntNode();
    1685             : 
    1686           0 :                 if( bDelRedl )
    1687           0 :                     delete pRedl;
    1688             : 
    1689           0 :                 RedlineMode_t eOld = rDoc.GetRedlineMode();
    1690           0 :                 rDoc.SetRedlineMode_intern( (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE)));
    1691             : 
    1692           0 :                 if( pCSttNd && pCEndNd )
    1693           0 :                     rDoc.DeleteAndJoin( aPam );
    1694             :                 else
    1695             :                 {
    1696           0 :                     rDoc.DeleteRange( aPam );
    1697             : 
    1698           0 :                     if( pCSttNd && !pCEndNd )
    1699             :                     {
    1700           0 :                         aPam.GetBound( sal_True ).nContent.Assign( 0, 0 );
    1701           0 :                         aPam.GetBound( sal_False ).nContent.Assign( 0, 0 );
    1702           0 :                         aPam.DeleteMark();
    1703           0 :                         rDoc.DelFullPara( aPam );
    1704             :                     }
    1705             :                 }
    1706           0 :                 rDoc.SetRedlineMode_intern( eOld );
    1707             :             }
    1708           0 :             else if( bDelRedl )
    1709           0 :                 delete pRedl;
    1710             :         }
    1711           0 :         break;
    1712             : 
    1713             :     case nsRedlineType_t::REDLINE_FMTCOLL:
    1714           0 :         rArr.DeleteAndDestroy( rPos-- );
    1715           0 :         break;
    1716             : 
    1717             :     default:
    1718           0 :         bRet = sal_False;
    1719             :     }
    1720           0 :     return bRet;
    1721             : }
    1722             : 
    1723           0 : static sal_Bool lcl_RejectRedline( SwRedlineTbl& rArr, sal_uInt16& rPos,
    1724             :                         sal_Bool bCallDelete,
    1725             :                         const SwPosition* pSttRng = 0,
    1726             :                         const SwPosition* pEndRng = 0 )
    1727             : {
    1728           0 :     sal_Bool bRet = sal_True;
    1729           0 :     SwRedline* pRedl = rArr[ rPos ];
    1730           0 :     SwPosition *pRStt = 0, *pREnd = 0;
    1731           0 :     SwComparePosition eCmp = POS_OUTSIDE;
    1732           0 :     if( pSttRng && pEndRng )
    1733             :     {
    1734           0 :         pRStt = pRedl->Start();
    1735           0 :         pREnd = pRedl->End();
    1736           0 :         eCmp = ComparePosition( *pSttRng, *pEndRng, *pRStt, *pREnd );
    1737             :     }
    1738             : 
    1739           0 :     pRedl->InvalidateRange();
    1740             : 
    1741           0 :     switch( pRedl->GetType() )
    1742             :     {
    1743             :     case nsRedlineType_t::REDLINE_INSERT:
    1744             :         {
    1745           0 :             SwDoc& rDoc = *pRedl->GetDoc();
    1746           0 :             const SwPosition *pDelStt = 0, *pDelEnd = 0;
    1747           0 :             bool bDelRedl = false;
    1748           0 :             switch( eCmp )
    1749             :             {
    1750             :             case POS_INSIDE:
    1751           0 :                 if( bCallDelete )
    1752             :                 {
    1753           0 :                     pDelStt = pSttRng;
    1754           0 :                     pDelEnd = pEndRng;
    1755             :                 }
    1756           0 :                 break;
    1757             : 
    1758             :             case POS_OVERLAP_BEFORE:
    1759           0 :                 if( bCallDelete )
    1760             :                 {
    1761           0 :                     pDelStt = pRStt;
    1762           0 :                     pDelEnd = pEndRng;
    1763             :                 }
    1764           0 :                 break;
    1765             :             case POS_OVERLAP_BEHIND:
    1766           0 :                 if( bCallDelete )
    1767             :                 {
    1768           0 :                     pDelStt = pREnd;
    1769           0 :                     pDelEnd = pSttRng;
    1770             :                 }
    1771           0 :                 break;
    1772             :             case POS_OUTSIDE:
    1773             :             case POS_EQUAL:
    1774             :                 {
    1775             :                     // delete the range again
    1776           0 :                     rArr.Remove( rPos-- );
    1777           0 :                     bDelRedl = true;
    1778           0 :                     if( bCallDelete )
    1779             :                     {
    1780           0 :                         pDelStt = pRedl->Start();
    1781           0 :                         pDelEnd = pRedl->End();
    1782             :                     }
    1783             :                 }
    1784           0 :                 break;
    1785             : 
    1786             :             default:
    1787           0 :                 bRet = sal_False;
    1788             :             }
    1789           0 :             if( pDelStt && pDelEnd )
    1790             :             {
    1791           0 :                 SwPaM aPam( *pDelStt, *pDelEnd );
    1792             : 
    1793           0 :                 SwCntntNode* pCSttNd = pDelStt->nNode.GetNode().GetCntntNode();
    1794           0 :                 SwCntntNode* pCEndNd = pDelEnd->nNode.GetNode().GetCntntNode();
    1795             : 
    1796           0 :                 if( bDelRedl )
    1797           0 :                     delete pRedl;
    1798             : 
    1799           0 :                 RedlineMode_t eOld = rDoc.GetRedlineMode();
    1800           0 :                 rDoc.SetRedlineMode_intern( (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE)));
    1801             : 
    1802           0 :                 if( pCSttNd && pCEndNd )
    1803           0 :                     rDoc.DeleteAndJoin( aPam );
    1804             :                 else
    1805             :                 {
    1806           0 :                     rDoc.DeleteRange( aPam );
    1807             : 
    1808           0 :                     if( pCSttNd && !pCEndNd )
    1809             :                     {
    1810           0 :                         aPam.GetBound( sal_True ).nContent.Assign( 0, 0 );
    1811           0 :                         aPam.GetBound( sal_False ).nContent.Assign( 0, 0 );
    1812           0 :                         aPam.DeleteMark();
    1813           0 :                         rDoc.DelFullPara( aPam );
    1814             :                     }
    1815             :                 }
    1816           0 :                 rDoc.SetRedlineMode_intern( eOld );
    1817             :             }
    1818           0 :             else if( bDelRedl )
    1819           0 :                 delete pRedl;
    1820             :         }
    1821           0 :         break;
    1822             :     case nsRedlineType_t::REDLINE_DELETE:
    1823             :         {
    1824           0 :             SwRedline* pNew = 0;
    1825           0 :             bool bCheck = false, bReplace = false;
    1826             : 
    1827           0 :             switch( eCmp )
    1828             :             {
    1829             :             case POS_INSIDE:
    1830             :                 {
    1831           0 :                     if( 1 < pRedl->GetStackCount() )
    1832             :                     {
    1833           0 :                         pNew = new SwRedline( *pRedl );
    1834           0 :                         pNew->PopData();
    1835             :                     }
    1836           0 :                     if( *pSttRng == *pRStt )
    1837             :                     {
    1838           0 :                         pRedl->SetStart( *pEndRng, pRStt );
    1839           0 :                         bReplace = true;
    1840           0 :                         if( pNew )
    1841           0 :                             pNew->SetEnd( *pEndRng );
    1842             :                     }
    1843             :                     else
    1844             :                     {
    1845           0 :                         if( *pEndRng != *pREnd )
    1846             :                         {
    1847             :                             // split up
    1848           0 :                             SwRedline* pCpy = new SwRedline( *pRedl );
    1849           0 :                             pCpy->SetStart( *pEndRng );
    1850           0 :                             rArr.Insert( pCpy ); ++rPos;
    1851           0 :                             if( pNew )
    1852           0 :                                 pNew->SetEnd( *pEndRng );
    1853             :                         }
    1854             : 
    1855           0 :                         pRedl->SetEnd( *pSttRng, pREnd );
    1856           0 :                         bCheck = true;
    1857           0 :                         if( pNew )
    1858           0 :                             pNew->SetStart( *pSttRng );
    1859             :                     }
    1860             :                 }
    1861           0 :                 break;
    1862             : 
    1863             :             case POS_OVERLAP_BEFORE:
    1864           0 :                 if( 1 < pRedl->GetStackCount() )
    1865             :                 {
    1866           0 :                     pNew = new SwRedline( *pRedl );
    1867           0 :                     pNew->PopData();
    1868             :                 }
    1869           0 :                 pRedl->SetStart( *pEndRng, pRStt );
    1870           0 :                 bReplace = true;
    1871           0 :                 if( pNew )
    1872           0 :                     pNew->SetEnd( *pEndRng );
    1873           0 :                 break;
    1874             : 
    1875             :             case POS_OVERLAP_BEHIND:
    1876           0 :                 if( 1 < pRedl->GetStackCount() )
    1877             :                 {
    1878           0 :                     pNew = new SwRedline( *pRedl );
    1879           0 :                     pNew->PopData();
    1880             :                 }
    1881           0 :                 pRedl->SetEnd( *pSttRng, pREnd );
    1882           0 :                 bCheck = true;
    1883           0 :                 if( pNew )
    1884           0 :                     pNew->SetStart( *pSttRng );
    1885           0 :                 break;
    1886             : 
    1887             :             case POS_OUTSIDE:
    1888             :             case POS_EQUAL:
    1889           0 :                 if( !pRedl->PopData() )
    1890             :                     // deleting the RedlineObject is enough
    1891           0 :                     rArr.DeleteAndDestroy( rPos-- );
    1892           0 :                 break;
    1893             : 
    1894             :             default:
    1895           0 :                 bRet = sal_False;
    1896             :             }
    1897             : 
    1898           0 :             if( pNew )
    1899             :             {
    1900           0 :                 rArr.Insert( pNew ); ++rPos;
    1901             :             }
    1902             : 
    1903           0 :             if( bReplace || ( bCheck && !pRedl->HasValidRange() ))
    1904             :             {
    1905             :                 // re-insert
    1906           0 :                 rArr.Remove( pRedl );
    1907           0 :                 rArr.Insert( pRedl );
    1908             :             }
    1909             :         }
    1910           0 :         break;
    1911             : 
    1912             :     case nsRedlineType_t::REDLINE_FORMAT:
    1913             :     case nsRedlineType_t::REDLINE_FMTCOLL:
    1914             :         {
    1915           0 :             if( pRedl->GetExtraData() )
    1916           0 :                 pRedl->GetExtraData()->Reject( *pRedl );
    1917           0 :             rArr.DeleteAndDestroy( rPos-- );
    1918             :         }
    1919           0 :         break;
    1920             : 
    1921             :     default:
    1922           0 :         bRet = sal_False;
    1923             :     }
    1924           0 :     return bRet;
    1925             : }
    1926             : 
    1927             : 
    1928           0 : static const SwRedline* lcl_FindCurrRedline( const SwPosition& rSttPos,
    1929             :                                         sal_uInt16& rPos,
    1930             :                                         bool bNext = true )
    1931             : {
    1932           0 :     const SwRedline* pFnd = 0;
    1933           0 :     const SwRedlineTbl& rArr = rSttPos.nNode.GetNode().GetDoc()->GetRedlineTbl();
    1934           0 :     for( ; rPos < rArr.size() ; ++rPos )
    1935             :     {
    1936           0 :         const SwRedline* pTmp = rArr[ rPos ];
    1937           0 :         if( pTmp->HasMark() && pTmp->IsVisible() )
    1938             :         {
    1939           0 :             const SwPosition* pRStt = pTmp->Start(),
    1940           0 :                       * pREnd = pRStt == pTmp->GetPoint() ? pTmp->GetMark()
    1941           0 :                                                           : pTmp->GetPoint();
    1942           0 :             if( bNext ? *pRStt <= rSttPos : *pRStt < rSttPos )
    1943             :             {
    1944           0 :                 if( bNext ? *pREnd > rSttPos : *pREnd >= rSttPos )
    1945             :                 {
    1946           0 :                     pFnd = pTmp;
    1947           0 :                     break;
    1948             :                 }
    1949             :             }
    1950             :             else
    1951           0 :                 break;
    1952             :         }
    1953             :     }
    1954           0 :     return pFnd;
    1955             : }
    1956             : 
    1957           0 : static int lcl_AcceptRejectRedl( Fn_AcceptReject fn_AcceptReject,
    1958             :                             SwRedlineTbl& rArr, sal_Bool bCallDelete,
    1959             :                             const SwPaM& rPam)
    1960             : {
    1961           0 :     sal_uInt16 n = 0;
    1962           0 :     int nCount = 0;
    1963             : 
    1964           0 :     const SwPosition* pStt = rPam.Start(),
    1965           0 :                     * pEnd = pStt == rPam.GetPoint() ? rPam.GetMark()
    1966           0 :                                                      : rPam.GetPoint();
    1967           0 :     const SwRedline* pFnd = lcl_FindCurrRedline( *pStt, n, true );
    1968           0 :     if( pFnd &&     // Is new a part of it?
    1969           0 :         ( *pFnd->Start() != *pStt || *pFnd->End() > *pEnd ))
    1970             :     {
    1971             :         // Only revoke the partial selection
    1972           0 :         if( (*fn_AcceptReject)( rArr, n, bCallDelete, pStt, pEnd ))
    1973           0 :             nCount++;
    1974           0 :         ++n;
    1975             :     }
    1976             : 
    1977           0 :     for( ; n < rArr.size(); ++n )
    1978             :     {
    1979           0 :         SwRedline* pTmp = rArr[ n ];
    1980           0 :         if( pTmp->HasMark() && pTmp->IsVisible() )
    1981             :         {
    1982           0 :             if( *pTmp->End() <= *pEnd )
    1983             :             {
    1984           0 :                 if( (*fn_AcceptReject)( rArr, n, bCallDelete, 0, 0 ))
    1985           0 :                     nCount++;
    1986             :             }
    1987             :             else
    1988             :             {
    1989           0 :                 if( *pTmp->Start() < *pEnd )
    1990             :                 {
    1991             :                     // Only revoke the partial selection
    1992           0 :                     if( (*fn_AcceptReject)( rArr, n, bCallDelete, pStt, pEnd ))
    1993           0 :                         nCount++;
    1994             :                 }
    1995           0 :                 break;
    1996             :             }
    1997             :         }
    1998             :     }
    1999           0 :     return nCount;
    2000             : }
    2001             : 
    2002           0 : static void lcl_AdjustRedlineRange( SwPaM& rPam )
    2003             : {
    2004             :     // The Selection is only in the ContentSection. If there are Redlines
    2005             :     // to Non-ContentNodes before or after that, then the Selections
    2006             :     // expand to them.
    2007           0 :     SwPosition* pStt = rPam.Start(),
    2008           0 :               * pEnd = pStt == rPam.GetPoint() ? rPam.GetMark()
    2009           0 :                                                : rPam.GetPoint();
    2010           0 :     SwDoc* pDoc = rPam.GetDoc();
    2011           0 :     if( !pStt->nContent.GetIndex() &&
    2012           0 :         !pDoc->GetNodes()[ pStt->nNode.GetIndex() - 1 ]->IsCntntNode() )
    2013             :     {
    2014           0 :         const SwRedline* pRedl = pDoc->GetRedline( *pStt, 0 );
    2015           0 :         if( pRedl )
    2016             :         {
    2017           0 :             const SwPosition* pRStt = pRedl->Start();
    2018           0 :             if( !pRStt->nContent.GetIndex() && pRStt->nNode.GetIndex() ==
    2019           0 :                 pStt->nNode.GetIndex() - 1 )
    2020           0 :                 *pStt = *pRStt;
    2021             :         }
    2022             :     }
    2023           0 :     if( pEnd->nNode.GetNode().IsCntntNode() &&
    2024           0 :         !pDoc->GetNodes()[ pEnd->nNode.GetIndex() + 1 ]->IsCntntNode() &&
    2025           0 :         pEnd->nContent.GetIndex() == pEnd->nNode.GetNode().GetCntntNode()->Len()    )
    2026             :     {
    2027           0 :         const SwRedline* pRedl = pDoc->GetRedline( *pEnd, 0 );
    2028           0 :         if( pRedl )
    2029             :         {
    2030           0 :             const SwPosition* pREnd = pRedl->End();
    2031           0 :             if( !pREnd->nContent.GetIndex() && pREnd->nNode.GetIndex() ==
    2032           0 :                 pEnd->nNode.GetIndex() + 1 )
    2033           0 :                 *pEnd = *pREnd;
    2034             :         }
    2035             :     }
    2036           0 : }
    2037             : 
    2038             : 
    2039           0 : bool SwDoc::AcceptRedline( sal_uInt16 nPos, bool bCallDelete )
    2040             : {
    2041           0 :     sal_Bool bRet = sal_False;
    2042             : 
    2043             :     // Switch to visible in any case
    2044           0 :     if( (nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE) !=
    2045             :         (nsRedlineMode_t::REDLINE_SHOW_MASK & eRedlineMode) )
    2046           0 :       SetRedlineMode( (RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE | eRedlineMode));
    2047             : 
    2048           0 :     SwRedline* pTmp = (*pRedlineTbl)[ nPos ];
    2049           0 :     if( pTmp->HasMark() && pTmp->IsVisible() )
    2050             :     {
    2051           0 :         if (GetIDocumentUndoRedo().DoesUndo())
    2052             :         {
    2053           0 :             SwRewriter aRewriter;
    2054             : 
    2055           0 :             aRewriter.AddRule(UndoArg1, pTmp->GetDescr());
    2056           0 :             GetIDocumentUndoRedo().StartUndo(UNDO_ACCEPT_REDLINE, &aRewriter);
    2057             :         }
    2058             : 
    2059           0 :         int nLoopCnt = 2;
    2060           0 :         sal_uInt16 nSeqNo = pTmp->GetSeqNo();
    2061             : 
    2062           0 :         do {
    2063             : 
    2064           0 :             if (GetIDocumentUndoRedo().DoesUndo())
    2065             :             {
    2066           0 :                 SwUndo *const pUndo( new SwUndoAcceptRedline(*pTmp) );
    2067           0 :                 GetIDocumentUndoRedo().AppendUndo(pUndo);
    2068             :             }
    2069             : 
    2070           0 :             bRet |= lcl_AcceptRedline( *pRedlineTbl, nPos, bCallDelete );
    2071             : 
    2072           0 :             if( nSeqNo )
    2073             :             {
    2074           0 :                 if( USHRT_MAX == nPos )
    2075           0 :                     nPos = 0;
    2076             :                 sal_uInt16 nFndPos = 2 == nLoopCnt
    2077           0 :                                     ? pRedlineTbl->FindNextSeqNo( nSeqNo, nPos )
    2078           0 :                                     : pRedlineTbl->FindPrevSeqNo( nSeqNo, nPos );
    2079           0 :                 if( USHRT_MAX != nFndPos || ( 0 != ( --nLoopCnt ) &&
    2080             :                     USHRT_MAX != ( nFndPos =
    2081           0 :                         pRedlineTbl->FindPrevSeqNo( nSeqNo, nPos ))) )
    2082           0 :                     pTmp = (*pRedlineTbl)[ nPos = nFndPos ];
    2083             :                 else
    2084           0 :                     nLoopCnt = 0;
    2085             :             }
    2086             :             else
    2087           0 :                 nLoopCnt = 0;
    2088             : 
    2089             :         } while( nLoopCnt );
    2090             : 
    2091           0 :         if( bRet )
    2092             :         {
    2093           0 :             CompressRedlines();
    2094           0 :             SetModified();
    2095             :         }
    2096             : 
    2097           0 :         if (GetIDocumentUndoRedo().DoesUndo())
    2098             :         {
    2099           0 :             GetIDocumentUndoRedo().EndUndo(UNDO_END, 0);
    2100             :         }
    2101             :     }
    2102           0 :     return bRet;
    2103             : }
    2104             : 
    2105           0 : bool SwDoc::AcceptRedline( const SwPaM& rPam, bool bCallDelete )
    2106             : {
    2107             :     // Switch to visible in any case
    2108           0 :     if( (nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE) !=
    2109             :         (nsRedlineMode_t::REDLINE_SHOW_MASK & eRedlineMode) )
    2110           0 :       SetRedlineMode( (RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE | eRedlineMode));
    2111             : 
    2112             :     // The Selection is only in the ContentSection. If there are Redlines
    2113             :     // to Non-ContentNodes before or after that, then the Selections
    2114             :     // expand to them.
    2115           0 :     SwPaM aPam( *rPam.GetMark(), *rPam.GetPoint() );
    2116           0 :     lcl_AdjustRedlineRange( aPam );
    2117             : 
    2118           0 :     if (GetIDocumentUndoRedo().DoesUndo())
    2119             :     {
    2120           0 :         GetIDocumentUndoRedo().StartUndo( UNDO_ACCEPT_REDLINE, NULL );
    2121           0 :         GetIDocumentUndoRedo().AppendUndo( new SwUndoAcceptRedline( aPam ));
    2122             :     }
    2123             : 
    2124             :     int nRet = lcl_AcceptRejectRedl( lcl_AcceptRedline, *pRedlineTbl,
    2125           0 :                                      bCallDelete, aPam );
    2126           0 :     if( nRet > 0 )
    2127             :     {
    2128           0 :         CompressRedlines();
    2129           0 :         SetModified();
    2130             :     }
    2131           0 :     if (GetIDocumentUndoRedo().DoesUndo())
    2132             :     {
    2133           0 :         String aTmpStr;
    2134             : 
    2135             :         {
    2136           0 :             SwRewriter aRewriter;
    2137           0 :             aRewriter.AddRule(UndoArg1, String::CreateFromInt32(nRet));
    2138           0 :             aTmpStr = aRewriter.Apply(String(SW_RES(STR_N_REDLINES)));
    2139             :         }
    2140             : 
    2141           0 :         SwRewriter aRewriter;
    2142           0 :         aRewriter.AddRule(UndoArg1, aTmpStr);
    2143             : 
    2144           0 :         GetIDocumentUndoRedo().EndUndo( UNDO_ACCEPT_REDLINE, &aRewriter );
    2145             :     }
    2146           0 :     return nRet != 0;
    2147             : }
    2148             : 
    2149           0 : bool SwDoc::RejectRedline( sal_uInt16 nPos, bool bCallDelete )
    2150             : {
    2151           0 :     sal_Bool bRet = sal_False;
    2152             : 
    2153             :     // Switch to visible in any case
    2154           0 :     if( (nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE) !=
    2155             :         (nsRedlineMode_t::REDLINE_SHOW_MASK & eRedlineMode) )
    2156           0 :       SetRedlineMode( (RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE | eRedlineMode));
    2157             : 
    2158           0 :     SwRedline* pTmp = (*pRedlineTbl)[ nPos ];
    2159           0 :     if( pTmp->HasMark() && pTmp->IsVisible() )
    2160             :     {
    2161           0 :         if (GetIDocumentUndoRedo().DoesUndo())
    2162             :         {
    2163           0 :             SwRewriter aRewriter;
    2164             : 
    2165           0 :             aRewriter.AddRule(UndoArg1, pTmp->GetDescr());
    2166           0 :             GetIDocumentUndoRedo().StartUndo(UNDO_REJECT_REDLINE, &aRewriter);
    2167             :         }
    2168             : 
    2169           0 :         int nLoopCnt = 2;
    2170           0 :         sal_uInt16 nSeqNo = pTmp->GetSeqNo();
    2171             : 
    2172           0 :         do {
    2173             : 
    2174           0 :             if (GetIDocumentUndoRedo().DoesUndo())
    2175             :             {
    2176           0 :                 SwUndo *const pUndo( new SwUndoRejectRedline( *pTmp ) );
    2177           0 :                 GetIDocumentUndoRedo().AppendUndo(pUndo);
    2178             :             }
    2179             : 
    2180           0 :             bRet |= lcl_RejectRedline( *pRedlineTbl, nPos, bCallDelete );
    2181             : 
    2182           0 :             if( nSeqNo )
    2183             :             {
    2184           0 :                 if( USHRT_MAX == nPos )
    2185           0 :                     nPos = 0;
    2186             :                 sal_uInt16 nFndPos = 2 == nLoopCnt
    2187           0 :                                     ? pRedlineTbl->FindNextSeqNo( nSeqNo, nPos )
    2188           0 :                                     : pRedlineTbl->FindPrevSeqNo( nSeqNo, nPos );
    2189           0 :                 if( USHRT_MAX != nFndPos || ( 0 != ( --nLoopCnt ) &&
    2190             :                     USHRT_MAX != ( nFndPos =
    2191           0 :                             pRedlineTbl->FindPrevSeqNo( nSeqNo, nPos ))) )
    2192           0 :                     pTmp = (*pRedlineTbl)[ nPos = nFndPos ];
    2193             :                 else
    2194           0 :                     nLoopCnt = 0;
    2195             :             }
    2196             :             else
    2197           0 :                 nLoopCnt = 0;
    2198             : 
    2199             :         } while( nLoopCnt );
    2200             : 
    2201           0 :         if( bRet )
    2202             :         {
    2203           0 :             CompressRedlines();
    2204           0 :             SetModified();
    2205             :         }
    2206             : 
    2207           0 :         if (GetIDocumentUndoRedo().DoesUndo())
    2208             :         {
    2209           0 :             GetIDocumentUndoRedo().EndUndo(UNDO_END, 0);
    2210             :         }
    2211             :     }
    2212           0 :     return bRet;
    2213             : }
    2214             : 
    2215           0 : bool SwDoc::RejectRedline( const SwPaM& rPam, bool bCallDelete )
    2216             : {
    2217             :     // Switch to visible in any case
    2218           0 :     if( (nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE) !=
    2219             :         (nsRedlineMode_t::REDLINE_SHOW_MASK & eRedlineMode) )
    2220           0 :       SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE | eRedlineMode));
    2221             : 
    2222             :     // The Selection is only in the ContentSection. If there are Redlines
    2223             :     // to Non-ContentNodes before or after that, then the Selections
    2224             :     // expand to them.
    2225           0 :     SwPaM aPam( *rPam.GetMark(), *rPam.GetPoint() );
    2226           0 :     lcl_AdjustRedlineRange( aPam );
    2227             : 
    2228           0 :     if (GetIDocumentUndoRedo().DoesUndo())
    2229             :     {
    2230           0 :         GetIDocumentUndoRedo().StartUndo( UNDO_REJECT_REDLINE, NULL );
    2231           0 :         GetIDocumentUndoRedo().AppendUndo( new SwUndoRejectRedline(aPam) );
    2232             :     }
    2233             : 
    2234             :     int nRet = lcl_AcceptRejectRedl( lcl_RejectRedline, *pRedlineTbl,
    2235           0 :                                         bCallDelete, aPam );
    2236           0 :     if( nRet > 0 )
    2237             :     {
    2238           0 :         CompressRedlines();
    2239           0 :         SetModified();
    2240             :     }
    2241           0 :     if (GetIDocumentUndoRedo().DoesUndo())
    2242             :     {
    2243           0 :         String aTmpStr;
    2244             : 
    2245             :         {
    2246           0 :             SwRewriter aRewriter;
    2247           0 :             aRewriter.AddRule(UndoArg1, String::CreateFromInt32(nRet));
    2248           0 :             aTmpStr = aRewriter.Apply(String(SW_RES(STR_N_REDLINES)));
    2249             :         }
    2250             : 
    2251           0 :         SwRewriter aRewriter;
    2252           0 :         aRewriter.AddRule(UndoArg1, aTmpStr);
    2253             : 
    2254           0 :         GetIDocumentUndoRedo().EndUndo( UNDO_REJECT_REDLINE, &aRewriter );
    2255             :     }
    2256             : 
    2257           0 :     return nRet != 0;
    2258             : }
    2259             : 
    2260           0 : const SwRedline* SwDoc::SelNextRedline( SwPaM& rPam ) const
    2261             : {
    2262           0 :     rPam.DeleteMark();
    2263           0 :     rPam.SetMark();
    2264             : 
    2265           0 :     SwPosition& rSttPos = *rPam.GetPoint();
    2266           0 :     SwPosition aSavePos( rSttPos );
    2267             :     bool bRestart;
    2268             : 
    2269             :     // If the starting positon points to the last valid ContentNode,
    2270             :     // we take the next Redline in any case.
    2271           0 :     sal_uInt16 n = 0;
    2272           0 :     const SwRedline* pFnd = lcl_FindCurrRedline( rSttPos, n, true );
    2273           0 :     if( pFnd )
    2274             :     {
    2275           0 :         const SwPosition* pEnd = pFnd->End();
    2276           0 :         if( !pEnd->nNode.GetNode().IsCntntNode() )
    2277             :         {
    2278           0 :             SwNodeIndex aTmp( pEnd->nNode );
    2279           0 :             SwCntntNode* pCNd = GetNodes().GoPrevSection( &aTmp );
    2280           0 :             if( !pCNd || ( aTmp == rSttPos.nNode &&
    2281           0 :                 pCNd->Len() == rSttPos.nContent.GetIndex() ))
    2282           0 :                 pFnd = 0;
    2283             :         }
    2284           0 :         if( pFnd )
    2285           0 :             rSttPos = *pFnd->End();
    2286             :     }
    2287             : 
    2288           0 :     do {
    2289           0 :         bRestart = false;
    2290             : 
    2291           0 :         for( ; !pFnd && n < pRedlineTbl->size(); ++n )
    2292             :         {
    2293           0 :             pFnd = (*pRedlineTbl)[ n ];
    2294           0 :             if( pFnd->HasMark() && pFnd->IsVisible() )
    2295             :             {
    2296           0 :                 *rPam.GetMark() = *pFnd->Start();
    2297           0 :                 rSttPos = *pFnd->End();
    2298           0 :                 break;
    2299             :             }
    2300             :             else
    2301           0 :                 pFnd = 0;
    2302             :         }
    2303             : 
    2304           0 :         if( pFnd )
    2305             :         {
    2306             :             // Merge all of the same type and author that are
    2307             :             // consecutive into one Selection.
    2308           0 :             const SwPosition* pPrevEnd = pFnd->End();
    2309           0 :             while( ++n < pRedlineTbl->size() )
    2310             :             {
    2311           0 :                 const SwRedline* pTmp = (*pRedlineTbl)[ n ];
    2312           0 :                 if( pTmp->HasMark() && pTmp->IsVisible() )
    2313             :                 {
    2314             :                     const SwPosition *pRStt;
    2315           0 :                     if( pFnd->GetType() == pTmp->GetType() &&
    2316           0 :                         pFnd->GetAuthor() == pTmp->GetAuthor() &&
    2317           0 :                         ( *pPrevEnd == *( pRStt = pTmp->Start() ) ||
    2318           0 :                           IsPrevPos( *pPrevEnd, *pRStt )) )
    2319             :                     {
    2320           0 :                         pPrevEnd = pTmp->End();
    2321           0 :                         rSttPos = *pPrevEnd;
    2322             :                     }
    2323             :                     else
    2324           0 :                         break;
    2325             :                 }
    2326             :             }
    2327             :         }
    2328             : 
    2329           0 :         if( pFnd )
    2330             :         {
    2331           0 :             const SwRedline* pSaveFnd = pFnd;
    2332             : 
    2333             :             SwCntntNode* pCNd;
    2334           0 :             SwNodeIndex* pIdx = &rPam.GetMark()->nNode;
    2335           0 :             if( !pIdx->GetNode().IsCntntNode() &&
    2336           0 :                 0 != ( pCNd = GetNodes().GoNextSection( pIdx )) )
    2337             :             {
    2338           0 :                 if( *pIdx <= rPam.GetPoint()->nNode )
    2339           0 :                     rPam.GetMark()->nContent.Assign( pCNd, 0 );
    2340             :                 else
    2341           0 :                     pFnd = 0;
    2342             :             }
    2343             : 
    2344           0 :             if( pFnd )
    2345             :             {
    2346           0 :                 pIdx = &rPam.GetPoint()->nNode;
    2347           0 :                 if( !pIdx->GetNode().IsCntntNode() &&
    2348           0 :                     0 != ( pCNd = GetNodes().GoPrevSection( pIdx )) )
    2349             :                 {
    2350           0 :                     if( *pIdx >= rPam.GetMark()->nNode )
    2351           0 :                         rPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
    2352             :                     else
    2353           0 :                         pFnd = 0;
    2354             :                 }
    2355             :             }
    2356             : 
    2357           0 :             if( !pFnd || *rPam.GetMark() == *rPam.GetPoint() )
    2358             :             {
    2359           0 :                 if( n < pRedlineTbl->size() )
    2360             :                 {
    2361           0 :                     bRestart = true;
    2362           0 :                     *rPam.GetPoint() = *pSaveFnd->End();
    2363             :                 }
    2364             :                 else
    2365             :                 {
    2366           0 :                     rPam.DeleteMark();
    2367           0 :                     *rPam.GetPoint() = aSavePos;
    2368             :                 }
    2369           0 :                 pFnd = 0;
    2370             :             }
    2371             :         }
    2372             :     } while( bRestart );
    2373             : 
    2374           0 :     return pFnd;
    2375             : }
    2376             : 
    2377           0 : const SwRedline* SwDoc::SelPrevRedline( SwPaM& rPam ) const
    2378             : {
    2379           0 :     rPam.DeleteMark();
    2380           0 :     rPam.SetMark();
    2381             : 
    2382           0 :     SwPosition& rSttPos = *rPam.GetPoint();
    2383           0 :     SwPosition aSavePos( rSttPos );
    2384             :     bool bRestart;
    2385             : 
    2386             :     // If the starting positon points to the last valid ContentNode,
    2387             :     // we take the previous Redline in any case.
    2388           0 :     sal_uInt16 n = 0;
    2389           0 :     const SwRedline* pFnd = lcl_FindCurrRedline( rSttPos, n, false );
    2390           0 :     if( pFnd )
    2391             :     {
    2392           0 :         const SwPosition* pStt = pFnd->Start();
    2393           0 :         if( !pStt->nNode.GetNode().IsCntntNode() )
    2394             :         {
    2395           0 :             SwNodeIndex aTmp( pStt->nNode );
    2396           0 :             SwCntntNode* pCNd = GetNodes().GoNextSection( &aTmp );
    2397           0 :             if( !pCNd || ( aTmp == rSttPos.nNode &&
    2398           0 :                 !rSttPos.nContent.GetIndex() ))
    2399           0 :                 pFnd = 0;
    2400             :         }
    2401           0 :         if( pFnd )
    2402           0 :             rSttPos = *pFnd->Start();
    2403             :     }
    2404             : 
    2405           0 :     do {
    2406           0 :         bRestart = false;
    2407             : 
    2408           0 :         while( !pFnd && 0 < n )
    2409             :         {
    2410           0 :             pFnd = (*pRedlineTbl)[ --n ];
    2411           0 :             if( pFnd->HasMark() && pFnd->IsVisible() )
    2412             :             {
    2413           0 :                 *rPam.GetMark() = *pFnd->End();
    2414           0 :                 rSttPos = *pFnd->Start();
    2415             :             }
    2416             :             else
    2417           0 :                 pFnd = 0;
    2418             :         }
    2419             : 
    2420           0 :         if( pFnd )
    2421             :         {
    2422             :             // Merge all of the same type and author that are
    2423             :             // consecutive into one Selection.
    2424           0 :             const SwPosition* pNextStt = pFnd->Start();
    2425           0 :             while( 0 < n )
    2426             :             {
    2427           0 :                 const SwRedline* pTmp = (*pRedlineTbl)[ --n ];
    2428           0 :                 if( pTmp->HasMark() && pTmp->IsVisible() )
    2429             :                 {
    2430             :                     const SwPosition *pREnd;
    2431           0 :                     if( pFnd->GetType() == pTmp->GetType() &&
    2432           0 :                         pFnd->GetAuthor() == pTmp->GetAuthor() &&
    2433           0 :                         ( *pNextStt == *( pREnd = pTmp->End() ) ||
    2434           0 :                           IsPrevPos( *pREnd, *pNextStt )) )
    2435             :                     {
    2436           0 :                         pNextStt = pTmp->Start();
    2437           0 :                         rSttPos = *pNextStt;
    2438             :                     }
    2439             :                     else
    2440             :                     {
    2441           0 :                         ++n;
    2442           0 :                         break;
    2443             :                     }
    2444             :                 }
    2445             :             }
    2446             :         }
    2447             : 
    2448           0 :         if( pFnd )
    2449             :         {
    2450           0 :             const SwRedline* pSaveFnd = pFnd;
    2451             : 
    2452             :             SwCntntNode* pCNd;
    2453           0 :             SwNodeIndex* pIdx = &rPam.GetMark()->nNode;
    2454           0 :             if( !pIdx->GetNode().IsCntntNode() &&
    2455           0 :                 0 != ( pCNd = GetNodes().GoPrevSection( pIdx )) )
    2456             :             {
    2457           0 :                 if( *pIdx >= rPam.GetPoint()->nNode )
    2458           0 :                     rPam.GetMark()->nContent.Assign( pCNd, pCNd->Len() );
    2459             :                 else
    2460           0 :                     pFnd = 0;
    2461             :             }
    2462             : 
    2463           0 :             if( pFnd )
    2464             :             {
    2465           0 :                 pIdx = &rPam.GetPoint()->nNode;
    2466           0 :                 if( !pIdx->GetNode().IsCntntNode() &&
    2467           0 :                     0 != ( pCNd = GetNodes().GoNextSection( pIdx )) )
    2468             :                 {
    2469           0 :                     if( *pIdx <= rPam.GetMark()->nNode )
    2470           0 :                         rPam.GetPoint()->nContent.Assign( pCNd, 0 );
    2471             :                     else
    2472           0 :                         pFnd = 0;
    2473             :                 }
    2474             :             }
    2475             : 
    2476           0 :             if( !pFnd || *rPam.GetMark() == *rPam.GetPoint() )
    2477             :             {
    2478           0 :                 if( n )
    2479             :                 {
    2480           0 :                     bRestart = true;
    2481           0 :                     *rPam.GetPoint() = *pSaveFnd->Start();
    2482             :                 }
    2483             :                 else
    2484             :                 {
    2485           0 :                     rPam.DeleteMark();
    2486           0 :                     *rPam.GetPoint() = aSavePos;
    2487             :                 }
    2488           0 :                 pFnd = 0;
    2489             :             }
    2490             :         }
    2491             :     } while( bRestart );
    2492             : 
    2493           0 :     return pFnd;
    2494             : }
    2495             : 
    2496             : // Set comment at the Redline
    2497           0 : bool SwDoc::SetRedlineComment( const SwPaM& rPaM, const String& rS )
    2498             : {
    2499           0 :     bool bRet = false;
    2500           0 :     const SwPosition* pStt = rPaM.Start(),
    2501           0 :                     * pEnd = pStt == rPaM.GetPoint() ? rPaM.GetMark()
    2502           0 :                                                      : rPaM.GetPoint();
    2503           0 :     sal_uInt16 n = 0;
    2504           0 :     if( lcl_FindCurrRedline( *pStt, n, true ) )
    2505             :     {
    2506           0 :         for( ; n < pRedlineTbl->size(); ++n )
    2507             :         {
    2508           0 :             bRet = true;
    2509           0 :             SwRedline* pTmp = (*pRedlineTbl)[ n ];
    2510           0 :             if( pStt != pEnd && *pTmp->Start() > *pEnd )
    2511           0 :                 break;
    2512             : 
    2513           0 :             pTmp->SetComment( rS );
    2514           0 :             if( *pTmp->End() >= *pEnd )
    2515           0 :                 break;
    2516             :         }
    2517             :     }
    2518           0 :     if( bRet )
    2519           0 :         SetModified();
    2520             : 
    2521           0 :     return bRet;
    2522             : }
    2523             : 
    2524             : // Create a new author if necessary
    2525         817 : sal_uInt16 SwDoc::GetRedlineAuthor()
    2526             : {
    2527         817 :     return SW_MOD()->GetRedlineAuthor();
    2528             : }
    2529             : 
    2530             : // Insert new author into the Table for the Readers etc.
    2531       16668 : sal_uInt16 SwDoc::InsertRedlineAuthor( const String& rNew )
    2532             : {
    2533       16668 :     return SW_MOD()->InsertRedlineAuthor(rNew);
    2534             : }
    2535             : 
    2536           0 : void SwDoc::UpdateRedlineAttr()
    2537             : {
    2538           0 :     const SwRedlineTbl& rTbl = GetRedlineTbl();
    2539           0 :     for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
    2540             :     {
    2541           0 :         SwRedline* pRedl = rTbl[ n ];
    2542           0 :         if( pRedl->IsVisible() )
    2543           0 :             pRedl->InvalidateRange();
    2544             :     }
    2545           0 : }
    2546             : 
    2547             : // Set comment text for the Redline, which is inserted later on via
    2548             : // AppendRedline. Is used by Autoformat.
    2549             : // A null pointer resets the mode. The pointer is not copied, so it
    2550             : // needs to stay valid!
    2551           0 : void SwDoc::SetAutoFmtRedlineComment( const String* pTxt, sal_uInt16 nSeqNo )
    2552             : {
    2553           0 :     mbIsAutoFmtRedline = 0 != pTxt;
    2554           0 :     if( pTxt )
    2555             :     {
    2556           0 :         if( !pAutoFmtRedlnComment )
    2557           0 :             pAutoFmtRedlnComment = new String( *pTxt );
    2558             :         else
    2559           0 :             *pAutoFmtRedlnComment = *pTxt;
    2560             :     }
    2561             :     else
    2562           0 :         delete pAutoFmtRedlnComment, pAutoFmtRedlnComment = 0;
    2563             : 
    2564           0 :     nAutoFmtRedlnCommentNo = nSeqNo;
    2565           0 : }
    2566             : 
    2567          18 : void SwDoc::SetRedlinePassword(
    2568             :             /*[in]*/const uno::Sequence <sal_Int8>& rNewPassword)
    2569             : {
    2570          18 :     aRedlinePasswd = rNewPassword;
    2571          18 :     SetModified();
    2572          18 : }
    2573             : 
    2574             : 
    2575         320 : bool SwRedlineTbl::Insert( SwRedline* p, bool bIns )
    2576             : {
    2577         320 :     bool bRet = false;
    2578         320 :     if( p->HasValidRange() )
    2579             :     {
    2580         320 :         bRet = insert( p ).second;
    2581         320 :         p->CallDisplayFunc();
    2582             :     }
    2583           0 :     else if( bIns )
    2584           0 :         bRet = InsertWithValidRanges( p );
    2585             :     else
    2586             :     {
    2587             :         OSL_ENSURE( !this, "Redline: wrong range" );
    2588             :     }
    2589         320 :     return bRet;
    2590             : }
    2591             : 
    2592           0 : bool SwRedlineTbl::Insert( SwRedline* p, sal_uInt16& rP, bool bIns )
    2593             : {
    2594           0 :     bool bRet = false;
    2595           0 :     if( p->HasValidRange() )
    2596             :     {
    2597           0 :         std::pair<_SwRedlineTbl::const_iterator, bool> rv = insert( p );
    2598           0 :         rP = rv.first - begin();
    2599           0 :         bRet = rv.second;
    2600           0 :         p->CallDisplayFunc();
    2601             :     }
    2602           0 :     else if( bIns )
    2603           0 :         bRet = InsertWithValidRanges( p, &rP );
    2604             :     else
    2605             :     {
    2606             :         OSL_ENSURE( !this, "Redline: wrong range" );
    2607             :     }
    2608           0 :     return bRet;
    2609             : }
    2610             : 
    2611           0 : bool SwRedlineTbl::InsertWithValidRanges( SwRedline* p, sal_uInt16* pInsPos )
    2612             : {
    2613             :     // Create valid "sub-ranges" from the Selection
    2614           0 :     bool bAnyIns = false;
    2615           0 :     SwPosition* pStt = p->Start(),
    2616           0 :               * pEnd = pStt == p->GetPoint() ? p->GetMark() : p->GetPoint();
    2617           0 :     SwPosition aNewStt( *pStt );
    2618           0 :     SwNodes& rNds = aNewStt.nNode.GetNodes();
    2619             :     SwCntntNode* pC;
    2620             : 
    2621           0 :     if( !aNewStt.nNode.GetNode().IsCntntNode() )
    2622             :     {
    2623           0 :         pC = rNds.GoNext( &aNewStt.nNode );
    2624           0 :         if( pC )
    2625           0 :             aNewStt.nContent.Assign( pC, 0 );
    2626             :         else
    2627           0 :             aNewStt.nNode = rNds.GetEndOfContent();
    2628             :     }
    2629             : 
    2630           0 :     SwRedline* pNew = 0;
    2631             :     sal_uInt16 nInsPos;
    2632             : 
    2633           0 :     if( aNewStt < *pEnd )
    2634           0 :         do {
    2635           0 :             if( !pNew )
    2636           0 :                 pNew = new SwRedline( p->GetRedlineData(), aNewStt );
    2637             :             else
    2638             :             {
    2639           0 :                 pNew->DeleteMark();
    2640           0 :                 *pNew->GetPoint() = aNewStt;
    2641             :             }
    2642             : 
    2643           0 :             pNew->SetMark();
    2644           0 :             GoEndSection( pNew->GetPoint() );
    2645             :             // i60396: If the redlines starts before a table but the table is the last member
    2646             :             // of the section, the GoEndSection will end inside the table.
    2647             :             // This will result in an incorrect redline, so we've to go back
    2648           0 :             SwNode* pTab = pNew->GetPoint()->nNode.GetNode().StartOfSectionNode()->FindTableNode();
    2649             :             // We end in a table when pTab != 0
    2650           0 :             if( pTab && !pNew->GetMark()->nNode.GetNode().StartOfSectionNode()->FindTableNode() )
    2651             :             { // but our Mark was outside the table => Correction
    2652           0 :                 do
    2653             :                 {
    2654             :                     // We want to be before the table
    2655           0 :                     *pNew->GetPoint() = SwPosition(*pTab);
    2656           0 :                     pC = GoPreviousNds( &pNew->GetPoint()->nNode, sal_False ); // here we are.
    2657           0 :                     if( pC )
    2658           0 :                         pNew->GetPoint()->nContent.Assign( pC, 0 );
    2659           0 :                     pTab = pNew->GetPoint()->nNode.GetNode().StartOfSectionNode()->FindTableNode();
    2660             :                 }while( pTab ); // If there is another table we have to repeat our step backwards
    2661             :             }
    2662             : 
    2663           0 :             if( *pNew->GetPoint() > *pEnd )
    2664             :             {
    2665           0 :                 pC = 0;
    2666           0 :                 if( aNewStt.nNode != pEnd->nNode )
    2667           0 :                     do {
    2668           0 :                         SwNode& rCurNd = aNewStt.nNode.GetNode();
    2669           0 :                         if( rCurNd.IsStartNode() )
    2670             :                         {
    2671           0 :                             if( rCurNd.EndOfSectionIndex() < pEnd->nNode.GetIndex() )
    2672           0 :                                 aNewStt.nNode = *rCurNd.EndOfSectionNode();
    2673             :                             else
    2674           0 :                                 break;
    2675             :                         }
    2676           0 :                         else if( rCurNd.IsCntntNode() )
    2677           0 :                             pC = rCurNd.GetCntntNode();
    2678           0 :                         aNewStt.nNode++;
    2679           0 :                     } while( aNewStt.nNode.GetIndex() < pEnd->nNode.GetIndex() );
    2680             : 
    2681           0 :                 if( aNewStt.nNode == pEnd->nNode )
    2682           0 :                     aNewStt.nContent = pEnd->nContent;
    2683           0 :                 else if( pC )
    2684             :                 {
    2685           0 :                     aNewStt.nNode = *pC;
    2686           0 :                     aNewStt.nContent.Assign( pC, pC->Len() );
    2687             :                 }
    2688             : 
    2689           0 :                 if( aNewStt <= *pEnd )
    2690           0 :                     *pNew->GetPoint() = aNewStt;
    2691             :             }
    2692             :             else
    2693           0 :                 aNewStt = *pNew->GetPoint();
    2694             : #if OSL_DEBUG_LEVEL > 0
    2695             :             CheckPosition( pNew->GetPoint(), pNew->GetMark() );
    2696             : #endif
    2697           0 :             if( *pNew->GetPoint() != *pNew->GetMark() &&
    2698           0 :                 Insert( pNew, nInsPos ) )
    2699             :             {
    2700           0 :                 pNew->CallDisplayFunc();
    2701           0 :                 bAnyIns = true;
    2702           0 :                 pNew = 0;
    2703           0 :                 if( pInsPos && *pInsPos < nInsPos )
    2704           0 :                     *pInsPos = nInsPos;
    2705             :             }
    2706             : 
    2707           0 :             if( aNewStt >= *pEnd ||
    2708             :                 0 == (pC = rNds.GoNext( &aNewStt.nNode )) )
    2709           0 :                 break;
    2710             : 
    2711           0 :             aNewStt.nContent.Assign( pC, 0 );
    2712             : 
    2713             :         } while( aNewStt < *pEnd );
    2714             : 
    2715           0 :     delete pNew;
    2716           0 :     delete p, p = 0;
    2717           0 :     return bAnyIns;
    2718             : }
    2719             : 
    2720         756 : bool CompareSwRedlineTbl::operator()(SwRedline* const &lhs, SwRedline* const &rhs) const
    2721             : {
    2722         756 :     return *lhs < *rhs;
    2723             : }
    2724             : 
    2725         204 : _SwRedlineTbl::~_SwRedlineTbl()
    2726             : {
    2727         102 :     DeleteAndDestroyAll();
    2728         102 : }
    2729             : 
    2730           0 : sal_uInt16 SwRedlineTbl::GetPos(const SwRedline* p) const
    2731             : {
    2732           0 :     const_iterator it = find(const_cast<SwRedline* const>(p));
    2733           0 :     if( it == end() )
    2734           0 :         return USHRT_MAX;
    2735           0 :     return it - begin();
    2736             : }
    2737             : 
    2738           0 : bool SwRedlineTbl::Remove( const SwRedline* p )
    2739             : {
    2740           0 :     sal_uInt16 nPos = GetPos(p);
    2741           0 :     if (nPos != USHRT_MAX)
    2742           0 :         Remove(nPos);
    2743           0 :     return nPos != USHRT_MAX;
    2744             : }
    2745             : 
    2746           0 : void SwRedlineTbl::Remove( sal_uInt16 nP )
    2747             : {
    2748           0 :     SwDoc* pDoc = 0;
    2749           0 :     if( !nP && 1 == size() )
    2750           0 :         pDoc = front()->GetDoc();
    2751             : 
    2752           0 :     erase( begin() + nP );
    2753             : 
    2754             :     ViewShell* pSh;
    2755           0 :     if( pDoc && !pDoc->IsInDtor() &&
    2756           0 :         0 != ( pSh = pDoc->GetCurrentViewShell()) ) //swmod 071108//swmod 071225
    2757           0 :         pSh->InvalidateWindows( SwRect( 0, 0, LONG_MAX, LONG_MAX ) );
    2758           0 : }
    2759             : 
    2760           8 : void SwRedlineTbl::DeleteAndDestroyAll()
    2761             : {
    2762           8 :     DeleteAndDestroy(0, size());
    2763           8 : }
    2764             : 
    2765         261 : void SwRedlineTbl::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL )
    2766             : {
    2767         261 :     SwDoc* pDoc = 0;
    2768         261 :     if( !nP && nL && nL == size() )
    2769          28 :         pDoc = front()->GetDoc();
    2770             : 
    2771         576 :     for( const_iterator it = begin() + nP; it != begin() + nP + nL; ++it )
    2772         315 :         delete *it;
    2773         261 :     erase( begin() + nP, begin() + nP + nL );
    2774             : 
    2775             :     ViewShell* pSh;
    2776         289 :     if( pDoc && !pDoc->IsInDtor() &&
    2777          28 :         0 != ( pSh = pDoc->GetCurrentViewShell() ) )    //swmod 071108//swmod 071225
    2778           0 :         pSh->InvalidateWindows( SwRect( 0, 0, LONG_MAX, LONG_MAX ) );
    2779         261 : }
    2780             : 
    2781             : // Find the next or preceding Redline with the same seq.no.
    2782             : // We can limit the search using look ahead.
    2783             : // 0 or USHRT_MAX searches the whole array.
    2784           0 : sal_uInt16 SwRedlineTbl::FindNextOfSeqNo( sal_uInt16 nSttPos, sal_uInt16 nLookahead ) const
    2785             : {
    2786           0 :     return nSttPos + 1 < (sal_uInt16)size()
    2787           0 :                 ? FindNextSeqNo( operator[]( nSttPos )->GetSeqNo(), nSttPos+1, nLookahead )
    2788           0 :                 : USHRT_MAX;
    2789             : }
    2790             : 
    2791           0 : sal_uInt16 SwRedlineTbl::FindPrevOfSeqNo( sal_uInt16 nSttPos, sal_uInt16 nLookahead ) const
    2792             : {
    2793           0 :     return nSttPos ? FindPrevSeqNo( operator[]( nSttPos )->GetSeqNo(), nSttPos-1, nLookahead )
    2794           0 :                    : USHRT_MAX;
    2795             : }
    2796             : 
    2797           0 : sal_uInt16 SwRedlineTbl::FindNextSeqNo( sal_uInt16 nSeqNo, sal_uInt16 nSttPos,
    2798             :                                     sal_uInt16 nLookahead ) const
    2799             : {
    2800           0 :     sal_uInt16 nRet = USHRT_MAX, nEnd;
    2801           0 :     if( nSeqNo && nSttPos < size() )
    2802             :     {
    2803           0 :         nEnd = size();
    2804           0 :         if( nLookahead && USHRT_MAX != nLookahead &&
    2805           0 :             static_cast<size_t>(nSttPos + nLookahead) < size() )
    2806           0 :             nEnd = nSttPos + nLookahead;
    2807             : 
    2808           0 :         for( ; nSttPos < nEnd; ++nSttPos )
    2809           0 :             if( nSeqNo == operator[]( nSttPos )->GetSeqNo() )
    2810             :             {
    2811           0 :                 nRet = nSttPos;
    2812           0 :                 break;
    2813             :             }
    2814             :     }
    2815           0 :     return nRet;
    2816             : }
    2817             : 
    2818           0 : sal_uInt16 SwRedlineTbl::FindPrevSeqNo( sal_uInt16 nSeqNo, sal_uInt16 nSttPos,
    2819             :                                     sal_uInt16 nLookahead ) const
    2820             : {
    2821           0 :     sal_uInt16 nRet = USHRT_MAX, nEnd;
    2822           0 :     if( nSeqNo && nSttPos < size() )
    2823             :     {
    2824           0 :         nEnd = 0;
    2825           0 :         if( nLookahead && USHRT_MAX != nLookahead && nSttPos > nLookahead )
    2826           0 :             nEnd = nSttPos - nLookahead;
    2827             : 
    2828           0 :         ++nSttPos;
    2829           0 :         while( nSttPos > nEnd )
    2830           0 :             if( nSeqNo == operator[]( --nSttPos )->GetSeqNo() )
    2831             :             {
    2832           0 :                 nRet = nSttPos;
    2833           0 :                 break;
    2834             :             }
    2835             :     }
    2836           0 :     return nRet;
    2837             : }
    2838             : 
    2839             : 
    2840           0 : SwRedlineExtraData::~SwRedlineExtraData()
    2841             : {
    2842           0 : }
    2843             : 
    2844           0 : void SwRedlineExtraData::Accept( SwPaM& ) const
    2845             : {
    2846           0 : }
    2847             : 
    2848           0 : void SwRedlineExtraData::Reject( SwPaM& ) const
    2849             : {
    2850           0 : }
    2851             : 
    2852           0 : int SwRedlineExtraData::operator == ( const SwRedlineExtraData& ) const
    2853             : {
    2854           0 :     return sal_False;
    2855             : }
    2856             : 
    2857             : 
    2858           0 : SwRedlineExtraData_FmtColl::SwRedlineExtraData_FmtColl( const String& rColl,
    2859             :                                                 sal_uInt16 nPoolFmtId,
    2860             :                                                 const SfxItemSet* pItemSet )
    2861           0 :     : sFmtNm(rColl), pSet(0), nPoolId(nPoolFmtId)
    2862             : {
    2863           0 :     if( pItemSet && pItemSet->Count() )
    2864           0 :         pSet = new SfxItemSet( *pItemSet );
    2865           0 : }
    2866             : 
    2867           0 : SwRedlineExtraData_FmtColl::~SwRedlineExtraData_FmtColl()
    2868             : {
    2869           0 :     delete pSet;
    2870           0 : }
    2871             : 
    2872           0 : SwRedlineExtraData* SwRedlineExtraData_FmtColl::CreateNew() const
    2873             : {
    2874           0 :     return new SwRedlineExtraData_FmtColl( sFmtNm, nPoolId, pSet );
    2875             : }
    2876             : 
    2877           0 : void SwRedlineExtraData_FmtColl::Reject( SwPaM& rPam ) const
    2878             : {
    2879           0 :     SwDoc* pDoc = rPam.GetDoc();
    2880             : 
    2881             :     // What about Undo? Is it turned off?
    2882             :     SwTxtFmtColl* pColl = USHRT_MAX == nPoolId
    2883           0 :                             ? pDoc->FindTxtFmtCollByName( sFmtNm )
    2884           0 :                             : pDoc->GetTxtCollFromPool( nPoolId );
    2885           0 :     if( pColl )
    2886           0 :         pDoc->SetTxtFmtColl( rPam, pColl, false );
    2887             : 
    2888           0 :     if( pSet )
    2889             :     {
    2890           0 :         rPam.SetMark();
    2891           0 :         SwPosition& rMark = *rPam.GetMark();
    2892           0 :         SwTxtNode* pTNd = rMark.nNode.GetNode().GetTxtNode();
    2893           0 :         if( pTNd )
    2894             :         {
    2895           0 :             rMark.nContent.Assign( pTNd, pTNd->GetTxt().Len() );
    2896             : 
    2897           0 :             if( pTNd->HasSwAttrSet() )
    2898             :             {
    2899             :                 // Only set those that are not there anymore. Others
    2900             :                 // could have changed, but we don't touch these.
    2901           0 :                 SfxItemSet aTmp( *pSet );
    2902           0 :                 aTmp.Differentiate( *pTNd->GetpSwAttrSet() );
    2903           0 :                 pDoc->InsertItemSet( rPam, aTmp, 0 );
    2904             :             }
    2905             :             else
    2906             :             {
    2907           0 :                 pDoc->InsertItemSet( rPam, *pSet, 0 );
    2908             :             }
    2909             :         }
    2910           0 :         rPam.DeleteMark();
    2911             :     }
    2912           0 : }
    2913             : 
    2914           0 : int SwRedlineExtraData_FmtColl::operator == ( const SwRedlineExtraData& r) const
    2915             : {
    2916           0 :     const SwRedlineExtraData_FmtColl& rCmp = (SwRedlineExtraData_FmtColl&)r;
    2917           0 :     return sFmtNm == rCmp.sFmtNm && nPoolId == rCmp.nPoolId &&
    2918           0 :             ( ( !pSet && !rCmp.pSet ) ||
    2919           0 :                ( pSet && rCmp.pSet && *pSet == *rCmp.pSet ) );
    2920             : }
    2921             : 
    2922           0 : void SwRedlineExtraData_FmtColl::SetItemSet( const SfxItemSet& rSet )
    2923             : {
    2924           0 :     delete pSet;
    2925           0 :     if( rSet.Count() )
    2926           0 :         pSet = new SfxItemSet( rSet );
    2927             :     else
    2928           0 :         pSet = 0;
    2929           0 : }
    2930             : 
    2931             : 
    2932           0 : SwRedlineExtraData_Format::SwRedlineExtraData_Format( const SfxItemSet& rSet )
    2933             : {
    2934           0 :     SfxItemIter aIter( rSet );
    2935           0 :     const SfxPoolItem* pItem = aIter.FirstItem();
    2936           0 :     while( sal_True )
    2937             :     {
    2938           0 :         aWhichIds.push_back( pItem->Which() );
    2939           0 :         if( aIter.IsAtEnd() )
    2940           0 :             break;
    2941           0 :         pItem = aIter.NextItem();
    2942           0 :     }
    2943           0 : }
    2944             : 
    2945           0 : SwRedlineExtraData_Format::SwRedlineExtraData_Format(
    2946             :         const SwRedlineExtraData_Format& rCpy )
    2947           0 :     : SwRedlineExtraData()
    2948             : {
    2949           0 :     aWhichIds.insert( aWhichIds.begin(), rCpy.aWhichIds.begin(), rCpy.aWhichIds.end() );
    2950           0 : }
    2951             : 
    2952           0 : SwRedlineExtraData_Format::~SwRedlineExtraData_Format()
    2953             : {
    2954           0 : }
    2955             : 
    2956           0 : SwRedlineExtraData* SwRedlineExtraData_Format::CreateNew() const
    2957             : {
    2958           0 :     return new SwRedlineExtraData_Format( *this );
    2959             : }
    2960             : 
    2961           0 : void SwRedlineExtraData_Format::Reject( SwPaM& rPam ) const
    2962             : {
    2963           0 :     SwDoc* pDoc = rPam.GetDoc();
    2964             : 
    2965           0 :     RedlineMode_t eOld = pDoc->GetRedlineMode();
    2966           0 :     pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE)));
    2967             : 
    2968             :     // Actually we need to reset the Attribute here!
    2969           0 :     std::vector<sal_uInt16>::const_iterator it;
    2970           0 :     for( it = aWhichIds.begin(); it != aWhichIds.end(); ++it )
    2971             :     {
    2972           0 :         pDoc->InsertPoolItem( rPam, *GetDfltAttr( *it ),
    2973           0 :                 nsSetAttrMode::SETATTR_DONTEXPAND );
    2974             :     }
    2975             : 
    2976           0 :     pDoc->SetRedlineMode_intern( eOld );
    2977           0 : }
    2978             : 
    2979           0 : int SwRedlineExtraData_Format::operator == ( const SwRedlineExtraData& rCmp ) const
    2980             : {
    2981           0 :     int nRet = 1;
    2982           0 :     size_t nEnd = aWhichIds.size();
    2983           0 :     if( nEnd != ((SwRedlineExtraData_Format&)rCmp).aWhichIds.size() )
    2984           0 :         nRet = 0;
    2985             :     else
    2986           0 :         for( size_t n = 0; n < nEnd; ++n )
    2987           0 :             if( ((SwRedlineExtraData_Format&)rCmp).aWhichIds[n] != aWhichIds[n])
    2988             :             {
    2989           0 :                 nRet = 0;
    2990           0 :                 break;
    2991             :             }
    2992           0 :     return nRet;
    2993             : }
    2994             : 
    2995         819 : SwRedlineData::SwRedlineData( RedlineType_t eT, sal_uInt16 nAut )
    2996             :     : pNext( 0 ), pExtraData( 0 ),
    2997             :     aStamp( DateTime::SYSTEM ),
    2998         819 :     eType( eT ), nAuthor( nAut ), nSeqNo( 0 )
    2999             : {
    3000         819 :     aStamp.SetSec( 0 );
    3001         819 :     aStamp.Set100Sec( 0 );
    3002         819 : }
    3003             : 
    3004           2 : SwRedlineData::SwRedlineData( const SwRedlineData& rCpy, sal_Bool bCpyNext )
    3005             :     :
    3006           0 :     pNext( (bCpyNext && rCpy.pNext) ? new SwRedlineData( *rCpy.pNext ) : 0 ),
    3007           0 :     pExtraData( rCpy.pExtraData ? rCpy.pExtraData->CreateNew() : 0 ),
    3008             :     sComment( rCpy.sComment ), aStamp( rCpy.aStamp ), eType( rCpy.eType ),
    3009           2 :     nAuthor( rCpy.nAuthor ), nSeqNo( rCpy.nSeqNo )
    3010             : {
    3011           2 : }
    3012             : 
    3013             : // For sw3io: We now own pNext!
    3014           0 : SwRedlineData::SwRedlineData(RedlineType_t eT, sal_uInt16 nAut, const DateTime& rDT,
    3015             :     const String& rCmnt, SwRedlineData *pNxt, SwRedlineExtraData* pData)
    3016             :     : pNext(pNxt), pExtraData(pData), sComment(rCmnt), aStamp(rDT),
    3017           0 :     eType(eT), nAuthor(nAut), nSeqNo(0)
    3018             : {
    3019           0 : }
    3020             : 
    3021        1642 : SwRedlineData::~SwRedlineData()
    3022             : {
    3023         821 :     delete pExtraData;
    3024         821 :     delete pNext;
    3025         821 : }
    3026             : 
    3027             : // ExtraData is copied. The Pointer's ownership is thus NOT transferred
    3028             : // to the Redline Object!
    3029           0 : void SwRedlineData::SetExtraData( const SwRedlineExtraData* pData )
    3030             : {
    3031           0 :     delete pExtraData;
    3032             : 
    3033           0 :     if( pData )
    3034           0 :         pExtraData = pData->CreateNew();
    3035             :     else
    3036           0 :         pExtraData = 0;
    3037           0 : }
    3038             : 
    3039           0 : String SwRedlineData::GetDescr() const
    3040             : {
    3041           0 :     String aResult;
    3042             : 
    3043           0 :     aResult += String(SW_RES(STR_REDLINE_INSERT + GetType()));
    3044             : 
    3045           0 :     return aResult;
    3046             : }
    3047             : 
    3048         817 : SwRedline::SwRedline(RedlineType_t eTyp, const SwPaM& rPam )
    3049         817 :     : SwPaM( *rPam.GetMark(), *rPam.GetPoint() ),
    3050        1634 :     pRedlineData( new SwRedlineData( eTyp, GetDoc()->GetRedlineAuthor() ) ),
    3051        2451 :     pCntntSect( 0 )
    3052             : {
    3053         817 :     bDelLastPara = bIsLastParaDelete = sal_False;
    3054         817 :     bIsVisible = sal_True;
    3055         817 :     if( !rPam.HasMark() )
    3056           0 :         DeleteMark();
    3057         817 : }
    3058             : 
    3059           2 : SwRedline::SwRedline( const SwRedlineData& rData, const SwPaM& rPam )
    3060           2 :     : SwPaM( *rPam.GetMark(), *rPam.GetPoint() ),
    3061           2 :     pRedlineData( new SwRedlineData( rData )),
    3062           4 :     pCntntSect( 0 )
    3063             : {
    3064           2 :     bDelLastPara = bIsLastParaDelete = sal_False;
    3065           2 :     bIsVisible = sal_True;
    3066           2 :     if( !rPam.HasMark() )
    3067           0 :         DeleteMark();
    3068           2 : }
    3069             : 
    3070           0 : SwRedline::SwRedline( const SwRedlineData& rData, const SwPosition& rPos )
    3071             :     : SwPaM( rPos ),
    3072           0 :     pRedlineData( new SwRedlineData( rData )),
    3073           0 :     pCntntSect( 0 )
    3074             : {
    3075           0 :     bDelLastPara = bIsLastParaDelete = sal_False;
    3076           0 :     bIsVisible = sal_True;
    3077           0 : }
    3078             : 
    3079           0 : SwRedline::SwRedline( const SwRedline& rCpy )
    3080           0 :     : SwPaM( *rCpy.GetMark(), *rCpy.GetPoint() ),
    3081           0 :     pRedlineData( new SwRedlineData( *rCpy.pRedlineData )),
    3082           0 :     pCntntSect( 0 )
    3083             : {
    3084           0 :     bDelLastPara = bIsLastParaDelete = sal_False;
    3085           0 :     bIsVisible = sal_True;
    3086           0 :     if( !rCpy.HasMark() )
    3087           0 :         DeleteMark();
    3088           0 : }
    3089             : 
    3090        2457 : SwRedline::~SwRedline()
    3091             : {
    3092         819 :     if( pCntntSect )
    3093             :     {
    3094             :         // delete the ContentSection
    3095           1 :         if( !GetDoc()->IsInDtor() )
    3096           0 :             GetDoc()->DeleteSection( &pCntntSect->GetNode() );
    3097           1 :         delete pCntntSect;
    3098             :     }
    3099         819 :     delete pRedlineData;
    3100        1638 : }
    3101             : 
    3102             : // Do we have a valid Selection?
    3103         475 : sal_Bool SwRedline::HasValidRange() const
    3104             : {
    3105         475 :     const SwNode* pPtNd = &GetPoint()->nNode.GetNode(),
    3106         475 :                 * pMkNd = &GetMark()->nNode.GetNode();
    3107        1856 :     if( pPtNd->StartOfSectionNode() == pMkNd->StartOfSectionNode() &&
    3108         475 :         !pPtNd->StartOfSectionNode()->IsTableNode() &&
    3109             :         // invalid if points on the end of content
    3110             :         // end-of-content only invalid if no content index exists
    3111         453 :         ( pPtNd != pMkNd || GetContentIdx() != NULL ||
    3112         453 :           pPtNd != &pPtNd->GetNodes().GetEndOfContent() )
    3113             :         )
    3114         475 :         return sal_True;
    3115           0 :     return sal_False;
    3116             : }
    3117             : 
    3118         320 : void SwRedline::CallDisplayFunc( sal_uInt16 nLoop )
    3119             : {
    3120         320 :     switch( nsRedlineMode_t::REDLINE_SHOW_MASK & GetDoc()->GetRedlineMode() )
    3121             :     {
    3122             :     case nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE:
    3123         115 :         Show( nLoop );
    3124         115 :         break;
    3125             :     case nsRedlineMode_t::REDLINE_SHOW_INSERT:
    3126         203 :         Hide( nLoop );
    3127         203 :         break;
    3128             :     case nsRedlineMode_t::REDLINE_SHOW_DELETE:
    3129           0 :         ShowOriginal( nLoop );
    3130           0 :         break;
    3131             :     }
    3132         320 : }
    3133             : 
    3134         115 : void SwRedline::Show( sal_uInt16 nLoop )
    3135             : {
    3136         115 :     if( 1 <= nLoop )
    3137             :     {
    3138           0 :         SwDoc* pDoc = GetDoc();
    3139           0 :         RedlineMode_t eOld = pDoc->GetRedlineMode();
    3140           0 :         pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
    3141           0 :         ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
    3142             : 
    3143           0 :         switch( GetType() )
    3144             :         {
    3145             :         case nsRedlineType_t::REDLINE_INSERT:           // Content has been inserted
    3146           0 :             bIsVisible = sal_True;
    3147           0 :             MoveFromSection();
    3148           0 :             break;
    3149             : 
    3150             :         case nsRedlineType_t::REDLINE_DELETE:           // Content has been deleted
    3151           0 :             bIsVisible = sal_True;
    3152           0 :             MoveFromSection();
    3153           0 :             break;
    3154             : 
    3155             :         case nsRedlineType_t::REDLINE_FORMAT:           // Attributes have been applied
    3156             :         case nsRedlineType_t::REDLINE_TABLE:            // Table structure has been modified
    3157           0 :             InvalidateRange();
    3158           0 :             break;
    3159             :         default:
    3160           0 :             break;
    3161             :         }
    3162           0 :         pDoc->SetRedlineMode_intern( eOld );
    3163             :     }
    3164         115 : }
    3165             : 
    3166         205 : void SwRedline::Hide( sal_uInt16 nLoop )
    3167             : {
    3168         205 :     SwDoc* pDoc = GetDoc();
    3169         205 :     RedlineMode_t eOld = pDoc->GetRedlineMode();
    3170         205 :     pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
    3171         205 :     ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
    3172             : 
    3173         205 :     switch( GetType() )
    3174             :     {
    3175             :     case nsRedlineType_t::REDLINE_INSERT:           // Content has been inserted
    3176         203 :         bIsVisible = sal_True;
    3177         203 :         if( 1 <= nLoop )
    3178           0 :             MoveFromSection();
    3179         203 :         break;
    3180             : 
    3181             :     case nsRedlineType_t::REDLINE_DELETE:           // Content has been deleted
    3182           2 :         bIsVisible = sal_False;
    3183           2 :         switch( nLoop )
    3184             :         {
    3185           0 :         case 0: MoveToSection();    break;
    3186           1 :         case 1: CopyToSection();    break;
    3187           1 :         case 2: DelCopyOfSection(); break;
    3188             :         }
    3189           2 :         break;
    3190             : 
    3191             :     case nsRedlineType_t::REDLINE_FORMAT:           // Attributes have been applied
    3192             :     case nsRedlineType_t::REDLINE_TABLE:            // Table structure has been modified
    3193           0 :         if( 1 <= nLoop )
    3194           0 :             InvalidateRange();
    3195           0 :         break;
    3196             :     default:
    3197           0 :         break;
    3198             :     }
    3199         205 :     pDoc->SetRedlineMode_intern( eOld );
    3200         205 : }
    3201             : 
    3202           0 : void SwRedline::ShowOriginal( sal_uInt16 nLoop )
    3203             : {
    3204           0 :     SwDoc* pDoc = GetDoc();
    3205           0 :     RedlineMode_t eOld = pDoc->GetRedlineMode();
    3206             :     SwRedlineData* pCur;
    3207             : 
    3208           0 :     pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
    3209           0 :     ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
    3210             : 
    3211             :     // Determine the Type, it's the first on Stack
    3212           0 :     for( pCur = pRedlineData; pCur->pNext; )
    3213           0 :         pCur = pCur->pNext;
    3214             : 
    3215           0 :     switch( pCur->eType )
    3216             :     {
    3217             :     case nsRedlineType_t::REDLINE_INSERT:           // Content has been inserted
    3218           0 :         bIsVisible = sal_False;
    3219           0 :         switch( nLoop )
    3220             :         {
    3221           0 :         case 0: MoveToSection();    break;
    3222           0 :         case 1: CopyToSection();    break;
    3223           0 :         case 2: DelCopyOfSection(); break;
    3224             :         }
    3225           0 :         break;
    3226             : 
    3227             :     case nsRedlineType_t::REDLINE_DELETE:           // Inhalt wurde eingefuegt
    3228           0 :         bIsVisible = sal_True;
    3229           0 :         if( 1 <= nLoop )
    3230           0 :             MoveFromSection();
    3231           0 :         break;
    3232             : 
    3233             :     case nsRedlineType_t::REDLINE_FORMAT:           // Attributes have been applied
    3234             :     case nsRedlineType_t::REDLINE_TABLE:            // Table structure has been modified
    3235           0 :         if( 1 <= nLoop )
    3236           0 :             InvalidateRange();
    3237           0 :         break;
    3238             :     default:
    3239           0 :         break;
    3240             :     }
    3241           0 :     pDoc->SetRedlineMode_intern( eOld );
    3242           0 : }
    3243             : 
    3244             : 
    3245         798 : void SwRedline::InvalidateRange()       // trigger the Layout
    3246             : {
    3247         798 :     sal_uLong nSttNd = GetMark()->nNode.GetIndex(),
    3248         798 :             nEndNd = GetPoint()->nNode.GetIndex();
    3249         798 :     sal_uInt16 nSttCnt = GetMark()->nContent.GetIndex(),
    3250         798 :             nEndCnt = GetPoint()->nContent.GetIndex();
    3251             : 
    3252         798 :     if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
    3253             :     {
    3254          14 :         sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
    3255          14 :         nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (sal_uInt16)nTmp;
    3256             :     }
    3257             : 
    3258         798 :     SwUpdateAttr aHt( 0, 0, RES_FMT_CHG );
    3259         798 :     SwNodes& rNds = GetDoc()->GetNodes();
    3260        1607 :     for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
    3261             :     {
    3262         809 :         SwNode* pNd = rNds[n];
    3263         809 :         if( pNd->IsTxtNode() )
    3264             :         {
    3265         809 :             aHt.nStart = n == nSttNd ? nSttCnt : 0;
    3266         809 :             aHt.nEnd = n == nEndNd ? nEndCnt : ((SwTxtNode*)pNd)->GetTxt().Len();
    3267         809 :             ((SwTxtNode*)pNd)->ModifyNotification( &aHt, &aHt );
    3268             :         }
    3269         798 :     }
    3270         798 : }
    3271             : 
    3272             : /*************************************************************************
    3273             :  * SwRedline::CalcStartEnd()
    3274             :  * Calculates the start and end position of the intersection rTmp and
    3275             :  * text node nNdIdx
    3276             :  *************************************************************************/
    3277             : 
    3278          55 : void SwRedline::CalcStartEnd( sal_uLong nNdIdx, sal_uInt16& nStart, sal_uInt16& nEnd ) const
    3279             : {
    3280          55 :     const SwPosition *pRStt = Start(), *pREnd = End();
    3281          55 :     if( pRStt->nNode < nNdIdx )
    3282             :     {
    3283           0 :         if( pREnd->nNode > nNdIdx )
    3284             :         {
    3285           0 :             nStart = 0;             // Paragraph is completely enclosed
    3286           0 :             nEnd = STRING_LEN;
    3287             :         }
    3288             :         else
    3289             :         {
    3290             :             OSL_ENSURE( pREnd->nNode == nNdIdx,
    3291             :                 "SwRedlineItr::Seek: GetRedlinePos Error" );
    3292           0 :             nStart = 0;             // Paragraph is overlapped in the beginning
    3293           0 :             nEnd = pREnd->nContent.GetIndex();
    3294             :         }
    3295             :     }
    3296          55 :     else if( pRStt->nNode == nNdIdx )
    3297             :     {
    3298          55 :         nStart = pRStt->nContent.GetIndex();
    3299          55 :         if( pREnd->nNode == nNdIdx )
    3300          55 :             nEnd = pREnd->nContent.GetIndex(); // Within the Paragraph
    3301             :         else
    3302           0 :             nEnd = STRING_LEN;      // Paragraph is overlapped in the end
    3303             :     }
    3304             :     else
    3305             :     {
    3306           0 :         nStart = STRING_LEN;
    3307           0 :         nEnd = STRING_LEN;
    3308             :     }
    3309          55 : }
    3310             : 
    3311           0 : void SwRedline::MoveToSection()
    3312             : {
    3313           0 :     if( !pCntntSect )
    3314             :     {
    3315           0 :         const SwPosition* pStt = Start(),
    3316           0 :                         * pEnd = pStt == GetPoint() ? GetMark() : GetPoint();
    3317             : 
    3318           0 :         SwDoc* pDoc = GetDoc();
    3319           0 :         SwPaM aPam( *pStt, *pEnd );
    3320           0 :         SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode();
    3321           0 :         SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
    3322             : 
    3323           0 :         if( !pCSttNd )
    3324             :         {
    3325             :             // In order to not move other Redlines' indices, we set them
    3326             :             // to the end (is exclusive)
    3327           0 :             const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
    3328           0 :             for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
    3329             :             {
    3330           0 :                 SwRedline* pRedl = rTbl[ n ];
    3331           0 :                 if( pRedl->GetBound(sal_True) == *pStt )
    3332           0 :                     pRedl->GetBound(sal_True) = *pEnd;
    3333           0 :                 if( pRedl->GetBound(sal_False) == *pStt )
    3334           0 :                     pRedl->GetBound(sal_False) = *pEnd;
    3335             :             }
    3336             :         }
    3337             : 
    3338             :         SwStartNode* pSttNd;
    3339           0 :         SwNodes& rNds = pDoc->GetNodes();
    3340           0 :         if( pCSttNd || pCEndNd )
    3341             :         {
    3342           0 :             SwTxtFmtColl* pColl = (pCSttNd && pCSttNd->IsTxtNode() )
    3343             :                                     ? ((SwTxtNode*)pCSttNd)->GetTxtColl()
    3344           0 :                                     : (pCEndNd && pCEndNd->IsTxtNode() )
    3345             :                                         ? ((SwTxtNode*)pCEndNd)->GetTxtColl()
    3346             :                                         : pDoc->GetTxtCollFromPool(
    3347           0 :                                                 RES_POOLCOLL_STANDARD );
    3348             : 
    3349           0 :             pSttNd = rNds.MakeTextSection( SwNodeIndex( rNds.GetEndOfRedlines() ),
    3350           0 :                                             SwNormalStartNode, pColl );
    3351           0 :             SwTxtNode* pTxtNd = rNds[ pSttNd->GetIndex() + 1 ]->GetTxtNode();
    3352             : 
    3353           0 :             SwNodeIndex aNdIdx( *pTxtNd );
    3354           0 :             SwPosition aPos( aNdIdx, SwIndex( pTxtNd ));
    3355           0 :             if( pCSttNd && pCEndNd )
    3356           0 :                 pDoc->MoveAndJoin( aPam, aPos, IDocumentContentOperations::DOC_MOVEDEFAULT );
    3357             :             else
    3358             :             {
    3359           0 :                 if( pCSttNd && !pCEndNd )
    3360           0 :                     bDelLastPara = sal_True;
    3361             :                 pDoc->MoveRange( aPam, aPos,
    3362           0 :                     IDocumentContentOperations::DOC_MOVEDEFAULT );
    3363           0 :             }
    3364             :         }
    3365             :         else
    3366             :         {
    3367           0 :             pSttNd = rNds.MakeEmptySection( SwNodeIndex( rNds.GetEndOfRedlines() ),
    3368           0 :                                             SwNormalStartNode );
    3369             : 
    3370           0 :             SwPosition aPos( *pSttNd->EndOfSectionNode() );
    3371             :             pDoc->MoveRange( aPam, aPos,
    3372           0 :                 IDocumentContentOperations::DOC_MOVEDEFAULT );
    3373             :         }
    3374           0 :         pCntntSect = new SwNodeIndex( *pSttNd );
    3375             : 
    3376           0 :         if( pStt == GetPoint() )
    3377           0 :             Exchange();
    3378             : 
    3379           0 :         DeleteMark();
    3380             :     }
    3381             :     else
    3382           0 :         InvalidateRange();
    3383           0 : }
    3384             : 
    3385           1 : void SwRedline::CopyToSection()
    3386             : {
    3387           1 :     if( !pCntntSect )
    3388             :     {
    3389           1 :         const SwPosition* pStt = Start(),
    3390           1 :                         * pEnd = pStt == GetPoint() ? GetMark() : GetPoint();
    3391             : 
    3392           1 :         SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode();
    3393           1 :         SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
    3394             : 
    3395             :         SwStartNode* pSttNd;
    3396           1 :         SwDoc* pDoc = GetDoc();
    3397           1 :         SwNodes& rNds = pDoc->GetNodes();
    3398             : 
    3399           1 :         sal_Bool bSaveCopyFlag = pDoc->IsCopyIsMove(),
    3400           1 :              bSaveRdlMoveFlg = pDoc->IsRedlineMove();
    3401           1 :         pDoc->SetCopyIsMove( sal_True );
    3402             : 
    3403             :         // The IsRedlineMove() flag causes the behaviour of the
    3404             :         // SwDoc::_CopyFlyInFly method to change, which will eventually be
    3405             :         // called by the pDoc->Copy line below (through SwDoc::_Copy,
    3406             :         // SwDoc::CopyWithFlyInFly). This rather obscure bugfix
    3407             :         // apparently never really worked.
    3408           1 :         pDoc->SetRedlineMove( pStt->nContent == 0 );
    3409             : 
    3410           1 :         if( pCSttNd )
    3411             :         {
    3412           1 :             SwTxtFmtColl* pColl = (pCSttNd && pCSttNd->IsTxtNode() )
    3413             :                                     ? ((SwTxtNode*)pCSttNd)->GetTxtColl()
    3414             :                                     : pDoc->GetTxtCollFromPool(
    3415           2 :                                                 RES_POOLCOLL_STANDARD );
    3416             : 
    3417           1 :             pSttNd = rNds.MakeTextSection( SwNodeIndex( rNds.GetEndOfRedlines() ),
    3418           1 :                                             SwNormalStartNode, pColl );
    3419             : 
    3420           1 :             SwNodeIndex aNdIdx( *pSttNd, 1 );
    3421           1 :             SwTxtNode* pTxtNd = aNdIdx.GetNode().GetTxtNode();
    3422           1 :             SwPosition aPos( aNdIdx, SwIndex( pTxtNd ));
    3423           1 :             pDoc->CopyRange( *this, aPos, false );
    3424             : 
    3425             :             // Take over the style from the EndNode if needed
    3426             :             // We don't want this in Doc::Copy
    3427           1 :             if( pCEndNd && pCEndNd != pCSttNd )
    3428             :             {
    3429           0 :                 SwCntntNode* pDestNd = aPos.nNode.GetNode().GetCntntNode();
    3430           0 :                 if( pDestNd )
    3431             :                 {
    3432           0 :                     if( pDestNd->IsTxtNode() && pCEndNd->IsTxtNode() )
    3433             :                         ((SwTxtNode*)pCEndNd)->CopyCollFmt(
    3434           0 :                                             *(SwTxtNode*)pDestNd );
    3435             :                     else
    3436           0 :                         pDestNd->ChgFmtColl( pCEndNd->GetFmtColl() );
    3437             :                 }
    3438           1 :             }
    3439             :         }
    3440             :         else
    3441             :         {
    3442           0 :             pSttNd = rNds.MakeEmptySection( SwNodeIndex( rNds.GetEndOfRedlines() ),
    3443           0 :                                             SwNormalStartNode );
    3444             : 
    3445           0 :             if( pCEndNd )
    3446             :             {
    3447           0 :                 SwPosition aPos( *pSttNd->EndOfSectionNode() );
    3448           0 :                 pDoc->CopyRange( *this, aPos, false );
    3449             :             }
    3450             :             else
    3451             :             {
    3452           0 :                 SwNodeIndex aInsPos( *pSttNd->EndOfSectionNode() );
    3453           0 :                 SwNodeRange aRg( pStt->nNode, 0, pEnd->nNode, 1 );
    3454           0 :                 pDoc->CopyWithFlyInFly( aRg, 0, aInsPos );
    3455             :             }
    3456             :         }
    3457           1 :         pCntntSect = new SwNodeIndex( *pSttNd );
    3458             : 
    3459           1 :         pDoc->SetCopyIsMove( bSaveCopyFlag );
    3460           1 :         pDoc->SetRedlineMove( bSaveRdlMoveFlg );
    3461             :     }
    3462           1 : }
    3463             : 
    3464           1 : void SwRedline::DelCopyOfSection()
    3465             : {
    3466           1 :     if( pCntntSect )
    3467             :     {
    3468           1 :         const SwPosition* pStt = Start(),
    3469           1 :                         * pEnd = pStt == GetPoint() ? GetMark() : GetPoint();
    3470             : 
    3471           1 :         SwDoc* pDoc = GetDoc();
    3472           1 :         SwPaM aPam( *pStt, *pEnd );
    3473           1 :         SwCntntNode* pCSttNd = pStt->nNode.GetNode().GetCntntNode();
    3474           1 :         SwCntntNode* pCEndNd = pEnd->nNode.GetNode().GetCntntNode();
    3475             : 
    3476           1 :         if( !pCSttNd )
    3477             :         {
    3478             :             // In order to not move other Redlines' indices, we set them
    3479             :             // to the end (is exclusive)
    3480           0 :             const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
    3481           0 :             for( sal_uInt16 n = 0; n < rTbl.size(); ++n )
    3482             :             {
    3483           0 :                 SwRedline* pRedl = rTbl[ n ];
    3484           0 :                 if( pRedl->GetBound(sal_True) == *pStt )
    3485           0 :                     pRedl->GetBound(sal_True) = *pEnd;
    3486           0 :                 if( pRedl->GetBound(sal_False) == *pStt )
    3487           0 :                     pRedl->GetBound(sal_False) = *pEnd;
    3488             :             }
    3489             :         }
    3490             : 
    3491           1 :         if( pCSttNd && pCEndNd )
    3492             :         {
    3493             :             // #i100466# - force a <join next> on <delete and join> operation
    3494           1 :             pDoc->DeleteAndJoin( aPam, true );
    3495             :         }
    3496           0 :         else if( pCSttNd || pCEndNd )
    3497             :         {
    3498           0 :             if( pCSttNd && !pCEndNd )
    3499           0 :                 bDelLastPara = sal_True;
    3500           0 :             pDoc->DeleteRange( aPam );
    3501             : 
    3502           0 :             if( bDelLastPara )
    3503             :             {
    3504             :                 // To prevent dangling references to the paragraph to
    3505             :                 // be deleted, redline that point into this paragraph should be
    3506             :                 // moved to the new end position. Since redlines in the redline
    3507             :                 // table are sorted and the pEnd position is an endnode (see
    3508             :                 // bDelLastPara condition above), only redlines before the
    3509             :                 // current ones can be affected.
    3510           0 :                 const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
    3511           0 :                 sal_uInt16 n = rTbl.GetPos( this );
    3512             :                 OSL_ENSURE( n != USHRT_MAX, "How strange. We don't exist!" );
    3513           0 :                 for( bool bBreak = false; !bBreak && n > 0; )
    3514             :                 {
    3515           0 :                     --n;
    3516           0 :                     bBreak = true;
    3517           0 :                     if( rTbl[ n ]->GetBound(sal_True) == *aPam.GetPoint() )
    3518             :                     {
    3519           0 :                         rTbl[ n ]->GetBound(sal_True) = *pEnd;
    3520           0 :                         bBreak = false;
    3521             :                     }
    3522           0 :                     if( rTbl[ n ]->GetBound(sal_False) == *aPam.GetPoint() )
    3523             :                     {
    3524           0 :                         rTbl[ n ]->GetBound(sal_False) = *pEnd;
    3525           0 :                         bBreak = false;
    3526             :                     }
    3527             :                 }
    3528             : 
    3529           0 :                 SwPosition aEnd( *pEnd );
    3530           0 :                 *GetPoint() = *pEnd;
    3531           0 :                 *GetMark() = *pEnd;
    3532           0 :                 DeleteMark();
    3533             : 
    3534           0 :                 aPam.GetBound( sal_True ).nContent.Assign( 0, 0 );
    3535           0 :                 aPam.GetBound( sal_False ).nContent.Assign( 0, 0 );
    3536           0 :                 aPam.DeleteMark();
    3537           0 :                 pDoc->DelFullPara( aPam );
    3538           0 :             }
    3539             :         }
    3540             :         else
    3541             :         {
    3542           0 :             pDoc->DeleteRange( aPam );
    3543             :         }
    3544             : 
    3545           1 :         if( pStt == GetPoint() )
    3546           1 :             Exchange();
    3547             : 
    3548           1 :         DeleteMark();
    3549             :     }
    3550           1 : }
    3551             : 
    3552           0 : void SwRedline::MoveFromSection()
    3553             : {
    3554           0 :     if( pCntntSect )
    3555             :     {
    3556           0 :         SwDoc* pDoc = GetDoc();
    3557           0 :         const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
    3558           0 :         std::vector<SwPosition*> aBeforeArr, aBehindArr;
    3559           0 :         sal_uInt16 nMyPos = rTbl.GetPos( this );
    3560             :         OSL_ENSURE( this, "this is not in the array?" );
    3561           0 :         bool bBreak = false;
    3562             :         sal_uInt16 n;
    3563             : 
    3564           0 :         for( n = nMyPos+1; !bBreak && n < rTbl.size(); ++n )
    3565             :         {
    3566           0 :             bBreak = true;
    3567           0 :             if( rTbl[ n ]->GetBound(sal_True) == *GetPoint() )
    3568             :             {
    3569           0 :                 aBehindArr.push_back( &rTbl[ n ]->GetBound(sal_True) );
    3570           0 :                 bBreak = false;
    3571             :             }
    3572           0 :             if( rTbl[ n ]->GetBound(sal_False) == *GetPoint() )
    3573             :             {
    3574           0 :                 aBehindArr.push_back( &rTbl[ n ]->GetBound(sal_False) );
    3575           0 :                 bBreak = false;
    3576             :             }
    3577             :         }
    3578           0 :         for( bBreak = false, n = nMyPos; !bBreak && n ; )
    3579             :         {
    3580           0 :             --n;
    3581           0 :             bBreak = true;
    3582           0 :             if( rTbl[ n ]->GetBound(sal_True) == *GetPoint() )
    3583             :             {
    3584           0 :                 aBeforeArr.push_back( &rTbl[ n ]->GetBound(sal_True) );
    3585           0 :                 bBreak = false;
    3586             :             }
    3587           0 :             if( rTbl[ n ]->GetBound(sal_False) == *GetPoint() )
    3588             :             {
    3589           0 :                 aBeforeArr.push_back( &rTbl[ n ]->GetBound(sal_False) );
    3590           0 :                 bBreak = false;
    3591             :             }
    3592             :         }
    3593             : 
    3594           0 :         const SwNode* pKeptCntntSectNode( &pCntntSect->GetNode() ); // #i95711#
    3595             :         {
    3596           0 :             SwPaM aPam( pCntntSect->GetNode(),
    3597           0 :                         *pCntntSect->GetNode().EndOfSectionNode(), 1,
    3598           0 :                         ( bDelLastPara ? -2 : -1 ) );
    3599           0 :             SwCntntNode* pCNd = aPam.GetCntntNode();
    3600           0 :             if( pCNd )
    3601           0 :                 aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
    3602             :             else
    3603           0 :                 aPam.GetPoint()->nNode++;
    3604             : 
    3605           0 :             SwFmtColl* pColl = pCNd && pCNd->Len() && aPam.GetPoint()->nNode !=
    3606           0 :                                         aPam.GetMark()->nNode
    3607           0 :                                 ? pCNd->GetFmtColl() : 0;
    3608             : 
    3609           0 :             SwNodeIndex aNdIdx( GetPoint()->nNode, -1 );
    3610           0 :             sal_uInt16 nPos = GetPoint()->nContent.GetIndex();
    3611             : 
    3612           0 :             SwPosition aPos( *GetPoint() );
    3613           0 :             if( bDelLastPara && *aPam.GetPoint() == *aPam.GetMark() )
    3614             :             {
    3615           0 :                 aPos.nNode--;
    3616             : 
    3617           0 :                 pDoc->AppendTxtNode( aPos );
    3618             :             }
    3619             :             else
    3620             :             {
    3621             :                 pDoc->MoveRange( aPam, aPos,
    3622           0 :                     IDocumentContentOperations::DOC_MOVEALLFLYS );
    3623             :             }
    3624             : 
    3625           0 :             SetMark();
    3626           0 :             *GetPoint() = aPos;
    3627           0 :             GetMark()->nNode = aNdIdx.GetIndex() + 1;
    3628           0 :             pCNd = GetMark()->nNode.GetNode().GetCntntNode();
    3629           0 :             GetMark()->nContent.Assign( pCNd, nPos );
    3630             : 
    3631           0 :             if( bDelLastPara )
    3632             :             {
    3633           0 :                 GetPoint()->nNode++;
    3634           0 :                 GetPoint()->nContent.Assign( pCNd = GetCntntNode(), 0 );
    3635           0 :                 bDelLastPara = sal_False;
    3636             :             }
    3637           0 :             else if( pColl )
    3638           0 :                 pCNd = GetCntntNode();
    3639             : 
    3640           0 :             if( pColl && pCNd )
    3641           0 :                 pCNd->ChgFmtColl( pColl );
    3642             :         }
    3643             :         // #i95771#
    3644             :         // Under certain conditions the previous <SwDoc::Move(..)> has already
    3645             :         // removed the change tracking section of this <SwRedline> instance from
    3646             :         // the change tracking nodes area.
    3647             :         // Thus, check if <pCntntSect> still points to the change tracking section
    3648             :         // by comparing it with the "indexed" <SwNode> instance copied before
    3649             :         // perform the intrinsic move.
    3650             :         // Note: Such condition is e.g. a "delete" change tracking only containing a table.
    3651           0 :         if ( &pCntntSect->GetNode() == pKeptCntntSectNode )
    3652             :         {
    3653           0 :             pDoc->DeleteSection( &pCntntSect->GetNode() );
    3654             :         }
    3655           0 :         delete pCntntSect, pCntntSect = 0;
    3656             : 
    3657             :         // adjustment of redline table positions must take start and
    3658             :         // end into account, not point and mark.
    3659           0 :         for( n = 0; n < aBeforeArr.size(); ++n )
    3660           0 :             *aBeforeArr[ n ] = *Start();
    3661           0 :         for( n = 0; n < aBehindArr.size(); ++n )
    3662           0 :             *aBehindArr[ n ] = *End();
    3663             :     }
    3664             :     else
    3665           0 :         InvalidateRange();
    3666           0 : }
    3667             : 
    3668             : // for Undo
    3669           0 : void SwRedline::SetContentIdx( const SwNodeIndex* pIdx )
    3670             : {
    3671           0 :     if( pIdx && !pCntntSect )
    3672             :     {
    3673           0 :         pCntntSect = new SwNodeIndex( *pIdx );
    3674           0 :         bIsVisible = sal_False;
    3675             :     }
    3676           0 :     else if( !pIdx && pCntntSect )
    3677             :     {
    3678           0 :         delete pCntntSect, pCntntSect = 0;
    3679           0 :         bIsVisible = sal_False;
    3680             :     }
    3681             :     else
    3682             :     {
    3683             :         OSL_FAIL("SwRedline::SetContentIdx: invalid state");
    3684             :     }
    3685           0 : }
    3686             : 
    3687         618 : sal_Bool SwRedline::CanCombine( const SwRedline& rRedl ) const
    3688             : {
    3689        1215 :     return  IsVisible() && rRedl.IsVisible() &&
    3690        1215 :             pRedlineData->CanCombine( *rRedl.pRedlineData );
    3691             : }
    3692             : 
    3693           0 : void SwRedline::PushData( const SwRedline& rRedl, sal_Bool bOwnAsNext )
    3694             : {
    3695           0 :     SwRedlineData* pNew = new SwRedlineData( *rRedl.pRedlineData, sal_False );
    3696           0 :     if( bOwnAsNext )
    3697             :     {
    3698           0 :         pNew->pNext = pRedlineData;
    3699           0 :         pRedlineData = pNew;
    3700             :     }
    3701             :     else
    3702             :     {
    3703           0 :         pNew->pNext = pRedlineData->pNext;
    3704           0 :         pRedlineData->pNext = pNew;
    3705             :     }
    3706           0 : }
    3707             : 
    3708           0 : sal_Bool SwRedline::PopData()
    3709             : {
    3710           0 :     if( !pRedlineData->pNext )
    3711           0 :         return sal_False;
    3712           0 :     SwRedlineData* pCur = pRedlineData;
    3713           0 :     pRedlineData = pCur->pNext;
    3714           0 :     pCur->pNext = 0;
    3715           0 :     delete pCur;
    3716           0 :     return sal_True;
    3717             : }
    3718             : 
    3719           5 : sal_uInt16 SwRedline::GetStackCount() const
    3720             : {
    3721           5 :     sal_uInt16 nRet = 1;
    3722           5 :     for( SwRedlineData* pCur = pRedlineData; pCur->pNext; ++nRet )
    3723           0 :         pCur = pCur->pNext;
    3724           5 :     return nRet;
    3725             : }
    3726             : 
    3727         889 : sal_uInt16 SwRedline::GetAuthor( sal_uInt16 nPos ) const
    3728             : {
    3729         889 :     return GetRedlineData(nPos).nAuthor;
    3730             : }
    3731             : 
    3732         545 : const String& SwRedline::GetAuthorString( sal_uInt16 nPos ) const
    3733             : {
    3734         545 :     return SW_MOD()->GetRedlineAuthor(GetRedlineData(nPos).nAuthor);
    3735             : }
    3736             : 
    3737           0 : const DateTime& SwRedline::GetTimeStamp( sal_uInt16 nPos ) const
    3738             : {
    3739           0 :     return GetRedlineData(nPos).aStamp;
    3740             : }
    3741             : 
    3742        1378 : RedlineType_t SwRedline::GetRealType( sal_uInt16 nPos ) const
    3743             : {
    3744        1378 :     return GetRedlineData(nPos).eType;
    3745             : }
    3746             : 
    3747           0 : const String& SwRedline::GetComment( sal_uInt16 nPos ) const
    3748             : {
    3749           0 :     return GetRedlineData(nPos).sComment;
    3750             : }
    3751             : 
    3752           0 : int SwRedline::operator==( const SwRedline& rCmp ) const
    3753             : {
    3754           0 :     return this == &rCmp;
    3755             : }
    3756             : 
    3757         756 : int SwRedline::operator<( const SwRedline& rCmp ) const
    3758             : {
    3759         756 :     sal_Bool nResult = sal_False;
    3760             : 
    3761         756 :     if (*Start() < *rCmp.Start())
    3762         755 :         nResult = sal_True;
    3763           1 :     else if (*Start() == *rCmp.Start())
    3764           1 :         if (*End() < *rCmp.End())
    3765           1 :             nResult = sal_True;
    3766             : 
    3767         756 :     return nResult;
    3768             : }
    3769             : 
    3770        2814 : const SwRedlineData & SwRedline::GetRedlineData(sal_uInt16 nPos) const
    3771             : {
    3772        2814 :     SwRedlineData * pCur = pRedlineData;
    3773             : 
    3774        5628 :     while (nPos > 0 && NULL != pCur->pNext)
    3775             :     {
    3776           0 :         pCur = pCur->pNext;
    3777             : 
    3778           0 :         nPos--;
    3779             :     }
    3780             : 
    3781             :     OSL_ENSURE( 0 == nPos, "Pos is too big" );
    3782             : 
    3783        2814 :     return *pCur;
    3784             : }
    3785             : 
    3786           0 : String SwRedline::GetDescr(sal_uInt16 nPos)
    3787             : {
    3788           0 :     String aResult;
    3789             : 
    3790             :     // get description of redline data (e.g.: "insert $1")
    3791           0 :     aResult = GetRedlineData(nPos).GetDescr();
    3792             : 
    3793           0 :     SwPaM * pPaM = NULL;
    3794           0 :     bool bDeletePaM = false;
    3795             : 
    3796             :     // if this redline is visible the content is in this PaM
    3797           0 :     if (NULL == pCntntSect)
    3798             :     {
    3799           0 :         pPaM = this;
    3800             :     }
    3801             :     else // otherwise it is saved in pCntntSect
    3802             :     {
    3803           0 :         SwNodeIndex aTmpIdx( *pCntntSect->GetNode().EndOfSectionNode() );
    3804           0 :         pPaM = new SwPaM(*pCntntSect, aTmpIdx );
    3805           0 :         bDeletePaM = true;
    3806             :     }
    3807             : 
    3808             :     // replace $1 in description by description of the redlines text
    3809           0 :     String aTmpStr;
    3810           0 :     aTmpStr += String(SW_RES(STR_START_QUOTE));
    3811             :     aTmpStr += ShortenString(pPaM->GetTxt(), nUndoStringLength,
    3812           0 :                              String(SW_RES(STR_LDOTS)));
    3813           0 :     aTmpStr += String(SW_RES(STR_END_QUOTE));
    3814             : 
    3815           0 :     SwRewriter aRewriter;
    3816           0 :     aRewriter.AddRule(UndoArg1, aTmpStr);
    3817             : 
    3818           0 :     aResult = aRewriter.Apply(aResult);
    3819             : 
    3820           0 :     if (bDeletePaM)
    3821           0 :         delete pPaM;
    3822             : 
    3823           0 :     return aResult;
    3824             : }
    3825             : 
    3826             : 
    3827        4262 : bool SwDoc::IsInRedlines(const SwNode & rNode) const
    3828             : {
    3829        4262 :     SwPosition aPos(rNode);
    3830        4262 :     SwNode & rEndOfRedlines = GetNodes().GetEndOfRedlines();
    3831        4262 :     SwPaM aPam(SwPosition(*rEndOfRedlines.StartOfSectionNode()),
    3832        8524 :                SwPosition(rEndOfRedlines));
    3833             : 
    3834        4262 :     return aPam.ContainsPosition(aPos) ? true : false;
    3835             : }
    3836             : 
    3837             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10