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

Generated by: LCOV version 1.10