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