summaryrefslogtreecommitdiff
path: root/binfilter/bf_sw/source/core/sw3io/sw_sw3redln.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sw/source/core/sw3io/sw_sw3redln.cxx')
-rw-r--r--binfilter/bf_sw/source/core/sw3io/sw_sw3redln.cxx786
1 files changed, 786 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/sw3io/sw_sw3redln.cxx b/binfilter/bf_sw/source/core/sw3io/sw_sw3redln.cxx
new file mode 100644
index 000000000000..b0a286b72ef9
--- /dev/null
+++ b/binfilter/bf_sw/source/core/sw3io/sw_sw3redln.cxx
@@ -0,0 +1,786 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#ifndef _DOC_HXX //autogen
+
+#include <horiornt.hxx>
+
+#include <doc.hxx>
+#endif
+
+#include <errhdl.hxx>
+
+#include <redline.hxx>
+
+
+#include "sw3marks.hxx"
+#include "sw3imp.hxx"
+namespace binfilter {
+
+
+// lokaler Record in SWG_REDLINES
+#define SWG_REDLINE_LCL 'R'
+
+// lokaler Record in SWG_REDLINE
+#define SWG_REDLINEDATA_LCL 'D'
+
+/*N*/ void Sw3StringPool::SetupRedlines( SwDoc& rDoc )
+/*N*/ {
+/*N*/ const SwRedlineTbl& rRedlines = rDoc.GetRedlineTbl();
+/*N*/ for( USHORT i=0; i<rRedlines.Count(); i++ )
+/*N*/ {
+/*?*/ const SwRedline *pRedline = rRedlines[i];
+ for( USHORT j=0; j<pRedline->GetStackCount(); j++ )
+ Add( pRedline->GetAuthorString(j), USHRT_MAX );
+/*N*/ }
+/*N*/ }
+
+/* */
+
+// REDLINE:
+// BYTE Flags
+// 0x10 - visisble Flags
+// UINT16 Anzahl REDLINEDATA
+// REDLINEDTA*
+//
+// REDLINEDATA:
+// BYTE Flags
+// BYTE Redline-Typ
+// UINT16 String-Pool-Index des Autors
+// UINT32 Datum
+// UINT32 Uhrzeit
+// String Kommentar
+
+/*N*/ void Sw3IoImp::InRedline() //SW50.SDW
+/*N*/ {
+/*N*/ OpenRec( SWG_REDLINE_LCL );
+/*N*/
+/*N*/ BYTE cFlags = OpenFlagRec();
+/*N*/
+/*N*/ UINT16 nCount;
+/*N*/ *pStrm >> nCount;
+/*N*/
+/*N*/ CloseFlagRec();
+/*N*/
+/*N*/ SwRedlineData *pData = 0;
+/*N*/ for( USHORT i=0; i<nCount; i++ )
+/*N*/ {
+/*N*/ OpenRec( SWG_REDLINEDATA_LCL );
+/*N*/
+/*N*/ BYTE cDFlags = OpenFlagRec();
+/*N*/
+/*N*/ BYTE cType;
+/*N*/ UINT16 nStrIdx;
+/*N*/
+/*N*/ *pStrm >> cType
+/*N*/ >> nStrIdx;
+/*N*/ CloseFlagRec();
+/*N*/
+/*N*/ UINT32 nDate, nTime;
+/*N*/ String aComment;
+/*N*/ *pStrm >> nDate
+/*N*/ >> nTime;
+/*N*/ InString( *pStrm, aComment );
+/*N*/
+/*N*/ // Das oberste Element des Stack wurde als letztes geschrieben.
+/*N*/ USHORT nAuthorIdx;
+/*N*/ if( bNormal && !bInsert )
+/*N*/ nAuthorIdx = pDoc->InsertRedlineAuthor(aStringPool.Find(nStrIdx));
+/*N*/ else
+/*N*/ nAuthorIdx = pDoc->GetRedlineAuthor();
+/*N*/
+/*N*/ pData = new SwRedlineData( (SwRedlineType)cType, nAuthorIdx,
+/*N*/ DateTime( nDate, nTime ), aComment,
+/*N*/ pData );
+/*N*/
+/*N*/ CloseRec( SWG_REDLINEDATA_LCL );
+/*N*/ }
+/*N*/
+/*N*/ // Der PaM ist erstmal egal und wird erst spaeter gesetzt
+/*N*/ SwPosition aDummyPos( pDoc->GetNodes().GetEndOfExtras() );
+/*N*/ BOOL bVisible = (cFlags & 0x10) != 0;
+/*N*/ SwRedline *pRedline =
+/*N*/ new SwRedline( pData, aDummyPos, (cFlags & 0x10) != 0,
+/*N*/ (cFlags & 0x20) != 0, (cFlags & 0x40) != 0 );
+/*N*/
+/*N*/ // Weil der PaM noch nicht gueltig ist, merken wir uns die Redline
+/*N*/ // erstmal so und fuegen sie erst spaeter in das Dokument ein.
+/*N*/ if( !pRedlines )
+/*N*/ pRedlines = new Sw3Redlines;
+/*N*/ pRedlines->Insert( pRedline, pRedlines->Count() );
+/*N*/
+/*N*/ CloseRec( SWG_REDLINE_LCL );
+/*N*/ }
+
+
+void Sw3IoImp::OutRedline( const SwRedline& rRedline )
+{
+ ASSERT( !IsSw31Or40Export(), "Redlines werden nicht exportiert!" );
+
+ OpenRec( SWG_REDLINE_LCL );
+
+ BYTE cFlags = 0x02; // Count
+
+ if( rRedline.IsVisible() )
+ cFlags += 0x10;
+ if( rRedline.IsDelLastPara() )
+ cFlags += 0x20;
+ if( rRedline.IsLastParaDelete() )
+ cFlags += 0x40;
+
+ USHORT i = rRedline.GetStackCount();
+
+ *pStrm << (BYTE) cFlags
+ << (UINT16)i;
+
+ // Die Redline-Data-Objekte werden von hinten nach vorne geschrieben,
+ // das macht das Verketten beim Einlesen leichter.
+ while( i )
+ {
+ i--;
+
+ OpenRec( SWG_REDLINEDATA_LCL );
+
+ cFlags = 0x03; // Type + StrPool-Index des Autors
+ UINT16 nStrIdx = aStringPool.Find( rRedline.GetAuthorString(i),
+ USHRT_MAX );
+ *pStrm << (BYTE) cFlags
+ << (BYTE) rRedline.GetType( i )
+ << (UINT16)nStrIdx;
+
+ const DateTime& rDateTime = rRedline.GetTimeStamp( i );
+ *pStrm << (UINT32)rDateTime.GetDate()
+ << (UINT32)rDateTime.GetTime();
+ OutString( *pStrm, rRedline.GetComment( i ) );
+
+ CloseRec( SWG_REDLINEDATA_LCL );
+ }
+
+ CloseRec( SWG_REDLINE_LCL );
+}
+
+/* */
+
+// REDLINES:
+// REDLINE*
+
+/*N*/ void Sw3IoImp::InRedlines() //SW50.SDW
+/*N*/ {
+/*N*/ if( pRedlines )
+/*N*/ {
+/*N*/ delete pRedlines;
+/*N*/ pRedlines = 0;
+/*N*/ }
+/*N*/
+/*N*/ OpenRec( SWG_REDLINES );
+/*N*/
+/*N*/ while( BytesLeft() )
+/*N*/ InRedline();
+/*N*/
+/*N*/ CloseRec( SWG_REDLINES );
+/*N*/ }
+
+/*N*/ void Sw3IoImp::OutRedlines( BOOL bPageStyles )
+/*N*/ {
+/*N*/ ASSERT( !IsSw31Or40Export(), "Redlines werden nicht exportiert!" );
+/*N*/
+/*N*/ if( !pRedlines )
+/*N*/ return;
+/*N*/
+/*?*/ ASSERT( !bBlock, "In Textbausteinen darf es keine Redlines geben!" );
+/*?*/
+/*?*/ USHORT nArrLen = pRedlines->Count();
+/*?*/ if( nArrLen && bPageStyles )
+/*?*/ {
+/*?*/ ASSERT( nCntntRedlineStart <= nArrLen,
+/*?*/ "Mehr Redlines in Page-Styles als ueberhaupt vorhanden?" );
+/*?*/ nArrLen = nCntntRedlineStart;
+/*?*/ }
+/*?*/ ASSERT( bPageStyles || nCntntRedlineStart==0,
+/*?*/ "Wieso sind da noch Bookmarks aus Seitenvorlagen?" );
+/*?*/ if( !nArrLen )
+/*?*/ return;
+/*?*/
+/*?*/ OpenRec( SWG_REDLINES );
+/*?*/
+/*?*/ for( USHORT i = 0; i < nArrLen; i++ )
+ OutRedline( *(*pRedlines)[i] );
+/*?*/
+/*?*/ CloseRec( SWG_REDLINES );
+/*N*/
+/*N*/ // Die Redlines eines Page-Styles muessen noch geloescht werden. Das
+/*N*/ // darf aber noch nicht hier passieren, weil wir die Redlines noch
+/*N*/ // beim rausschreiben der Markierungen brauchen.
+/*N*/ }
+
+/* */
+
+xub_StrLen lcl_sw3io_getNodeOff( const SwNodeIndex& rNdIdx, xub_StrLen nCntntIdx )
+{
+ // Hier tricksen wir ein wenig: Da Redlines auch auf Start- oder
+ // Endnodes anfangen koennen, muessen wir die Positionen auch dann
+ // Speichern, wenn Sections gespeichert werden. Um zu Unterscheiden,
+ // ob der Start- oder der Endnode gemeint ist, nutzen wir die dann
+ // unbenutzte Content-Position.
+ const SwNode& rNode = rNdIdx.GetNode();
+ if( rNode.IsCntntNode() )
+ {
+ if( nCntntIdx > STRING_MAXLEN52 )
+ return STRING_MAXLEN52;
+ else
+ return nCntntIdx;
+ }
+
+ if( rNode.IsStartNode() )
+ return 0;
+
+ ASSERT( rNode.IsEndNode(), "Was ist denn das fuer ein Node?" );
+ return USHRT_MAX;
+}
+
+/*N*/ void Sw3IoImp::CollectRedlines( SwPaM* pPaM, BOOL bPageOnly )
+/*N*/ {
+/*N*/ ASSERT( !IsSw31Or40Export(), "Redlines werden nicht exportiert!" );
+/*N*/
+/*N*/ delete pRedlines;
+/*N*/ pRedlines = new Sw3Redlines;
+/*N*/ nCntntRedlineStart = 0;
+/*N*/
+/*N*/ const SwPosition *pPaMStart = pPaM ? pPaM->Start() : 0;
+/*N*/ const SwPosition *pPaMEnd = pPaM ? pPaM->End() : 0;
+/*N*/ ULONG nEndOfExtras = pDoc->GetNodes().GetEndOfExtras().GetIndex();
+/*N*/
+/*N*/ const SwRedlineTbl& rRedlines = pDoc->GetRedlineTbl();
+ USHORT i=0;
+/*N*/ for( i=0; i<rRedlines.Count(); i++ )
+/*N*/ {
+/*?*/ SwRedline *pRedline = rRedlines[i];
+/*?*/ const SwPosition *pPos = pRedline->Start();
+/*?*/ const SwPosition *pEndPos = pRedline->End();
+/*?*/ if( !pRedline->GetContentIdx() && *pPos == *pEndPos )
+/*?*/ {
+/*?*/ // "Leere" Redlines werden nicht gespeichert!
+/*?*/ ASSERT( !this, "Redline in leer" );
+/*?*/ continue;
+/*?*/ }
+/*?*/
+/*?*/ // If the redline is within one node and starts behind the
+/*?*/ // last position that is possible within the 5.2 version,
+/*?*/ // it will be ignored.
+/*?*/ if( pPos->nContent.GetIndex() > STRING_MAXLEN52 &&
+/*?*/ pPos->nNode.GetIndex() == pEndPos->nNode.GetIndex() &&
+/*?*/ pEndPos->nContent.GetIndex() > STRING_MAXLEN52 )
+/*?*/ continue;
+/*?*/
+/*?*/ if( pDoc->IsInHeaderFooter( pPos->nNode ) )
+/*?*/ {
+/*?*/ pRedlines->Insert( pRedline, nCntntRedlineStart );
+/*?*/ nCntntRedlineStart++;
+/*?*/ }
+/*?*/ else if( !bPageOnly )
+/*?*/ {
+/*?*/ // Bei gegebenen PaM alle Redlines mitnehmen, die in
+/*?*/ // Sonderbereichen liegen oder ganz oder teilweise im PaM.
+/*?*/ const SwPosition *pStart = pRedline->Start();
+/*?*/ SwComparePosition eCmp =
+/*?*/ bSaveAll || !pPaM || pStart->nNode.GetIndex() <= nEndOfExtras
+/*?*/ ? POS_INSIDE
+/*?*/ : ComparePosition( *pStart, *pRedline->End(),
+/*?*/ *pPaMStart, *pPaMEnd );
+/*?*/ if( POS_BEFORE != eCmp && POS_BEHIND != eCmp &&
+/*?*/ POS_COLLIDE_END != eCmp && POS_COLLIDE_START != eCmp )
+/*?*/ pRedlines->Insert( pRedline, pRedlines->Count() );
+/*?*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( !pRedlines->Count() )
+/*N*/ {
+/*N*/ // Keine Redlines? Dann nicht weiter.
+/*N*/ delete pRedlines;
+/*N*/ pRedlines = 0;
+/*N*/ return;
+/*N*/ }
+/*N*/
+/*?*/ ASSERT( !bBlock, "In Textbausteinen darf es keine Redlines geben!" );
+/*?*/
+/*?*/ Sw3Mark aMark;
+/*?*/ USHORT nArrLen = pRedlines->Count();
+/*?*/
+/*?*/ if( !pRedlineMarks )
+/*?*/ pRedlineMarks = new Sw3Marks( 2*nArrLen, 2 );
+/*?*/
+/*?*/ for( i = 0; i < nArrLen; i++ )
+ {
+/*?*/ const SwRedline* pRedline = pRedlines->GetObject( i );
+/*?*/
+/*?*/ if( i >= nCntntRedlineStart )
+/*?*/ aMark.SetId( i - nCntntRedlineStart );
+/*?*/ else
+/*?*/ aMark.SetId( i );
+/*?*/
+/*?*/ // Bei gegebenen Redlines die Positionen auf den PaM reduzieren
+/*?*/ const SwPosition *pStart = pRedline->Start();
+/*?*/ const SwPosition *pEnd = pRedline->End();
+/*?*/ SwComparePosition eCmp =
+/*?*/ bSaveAll || !pPaM || pStart->nNode.GetIndex() <= nEndOfExtras
+/*?*/ ? POS_INSIDE
+/*?*/ : ComparePosition( *pStart, *pEnd, *pPaMStart, *pPaMEnd );
+/*?*/
+/*?*/ ASSERT( POS_BEFORE != eCmp && POS_BEHIND != eCmp &&
+/*?*/ POS_COLLIDE_END != eCmp && POS_COLLIDE_START != eCmp,
+/*?*/ "Redline mit ungeultigem Bereich" );
+/*?*/
+/*?*/ if( POS_OUTSIDE == eCmp || POS_OVERLAP_BEFORE == eCmp )
+/*?*/ pStart = pPaMStart;
+/*?*/ if( POS_OUTSIDE == eCmp || POS_OVERLAP_BEHIND == eCmp )
+/*?*/ pEnd = pPaMEnd;
+/*?*/
+/*?*/ aMark.SetType( SW3_REDLINE_START );
+/*?*/ aMark.SetNodePos( pStart->nNode.GetIndex() );
+/*?*/ aMark.SetNodeOff( lcl_sw3io_getNodeOff( pStart->nNode,
+/*?*/ pStart->nContent.GetIndex() ) );
+/*?*/ pRedlineMarks->Insert( new Sw3Mark(aMark) );
+/*?*/
+/*?*/ if( pRedline->HasMark() )
+/*?*/ {
+/*?*/ // Wenn der PaM ein Mark besitzt, dann End die jeweils
+/*?*/ // andere Position.
+/*?*/ aMark.SetType( SW3_REDLINE_END );
+/*?*/ aMark.SetNodePos( pEnd->nNode.GetIndex() );
+/*?*/ aMark.SetNodeOff( lcl_sw3io_getNodeOff( pEnd->nNode,
+/*?*/ pEnd->nContent.GetIndex() ) );
+/*?*/ pRedlineMarks->Insert( new Sw3Mark(aMark) );
+/*?*/ }
+/*?*/ }
+/*N*/ }
+
+/* */
+
+// NODEREDLINE:
+// BYTE Flags
+// 0x01 - End-Position einer Redline, sonst Start-Positiom
+// 0x02 - Redline besitzt Section
+// UINT16 Id der Redline (Array-Position)
+// UINT16 Content-Position bzw. USHRT_MAX, wenn die Psoition dem zu
+// einem Start-Node gehoerenden ENd-Node bezeichnet.
+// CONTENT? Section (optional)
+
+/*N*/ void Sw3IoImp::InNodeRedline( const SwNodeIndex& rNodeIdx, INT32& nCntntOff, //SW50.SDW
+/*N*/ BYTE nInsFirstPara )
+/*N*/ {
+/*N*/ OpenRec( SWG_NODEREDLINE );
+/*N*/
+/*N*/ BYTE cFlags = OpenFlagRec();
+/*N*/ UINT16 nId, nNodeOff;
+/*N*/ *pStrm >> nId >> nNodeOff;
+/*N*/ CloseFlagRec();
+/*N*/
+/*N*/ ASSERT( pRedlines && nId < pRedlines->Count(), "Ungueltige Redline-Id" );
+/*N*/ if( !pRedlines || nId >= pRedlines->Count() )
+/*N*/ {
+/*N*/ Error();
+/*N*/ CloseRec( SWG_NODEREDLINE );
+/*N*/ return;
+/*N*/ }
+/*N*/
+/*N*/ SwRedline *pRedline = (*pRedlines)[nId];
+/*N*/ SwRedlineType eType = pRedline ? pRedline->GetType() : REDLINE_FLAG_MASK;
+/*N*/ if( REDLINE_INSERT != eType && REDLINE_DELETE != eType &&
+/*N*/ REDLINE_FORMAT != eType )
+/*N*/ {
+/*N*/ // Unbekannter oder noch nicht implementierter Redline-Typ:
+/*N*/ // Da ist es besser, wir ignorieren sie, denn wir koennen ja
+/*N*/ // sowieso nichts damit anfangen.
+/*N*/ ASSERT( !pRedline, "nicht implementierter Redline-Typ" );
+/*N*/ Warning();
+/*N*/ CloseRec( SWG_NODEREDLINE );
+/*N*/ return;
+/*N*/ }
+/*N*/
+/*N*/ // Position setzen
+/*N*/ SwPosition *pPos;
+/*N*/ if( 0x10 & cFlags )
+/*N*/ {
+/*N*/ // bei End-Positionen Mark setzen
+/*N*/ pRedline->SetMark();
+/*N*/ pPos = pRedline->GetMark();
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // sonst Point
+/*N*/ pPos = pRedline->GetPoint();
+/*N*/ }
+/*N*/
+/*N*/ SwNode& rNode = rNodeIdx.GetNode();
+/*N*/
+/*N*/ // Beim Einfuegen in den ersten Absatz sollten wir eine Content-Node
+/*N*/ // haben, in den wir an der uebergeben Position einfuegen.
+/*N*/ if( nInsFirstPara )
+/*N*/ {
+/*N*/ ASSERT( rNode.IsCntntNode(), "Content-Node beim Einf. erwartet" );
+/*N*/ ASSERT( USHRT_MAX==nNodeOff, "End-Node-Position beim Einf. erwartet" );
+/*N*/ nNodeOff = 0; // Im IsCntntNode-Zweig gibts so die richtige Pos.
+/*N*/ }
+/*N*/
+/*N*/ sal_Bool bInvalid = sal_False;
+/*N*/ // Positionen koennen auch auf Start- oder End-Nodes fallen.
+/*N*/ if( rNode.IsCntntNode() )
+/*N*/ {
+/*N*/ pPos->nNode = rNodeIdx;
+/*N*/ xub_StrLen nLen = rNode.GetCntntNode()->Len();
+/*N*/ xub_StrLen nIdx = static_cast< xub_StrLen >( nNodeOff+nCntntOff );
+/*N*/ ASSERT( nIdx>=0 && nIdx<=nLen, "ungueltiger Cntnt-Offset" );
+/*N*/ if( nIdx<0 || nIdx > nLen )
+/*N*/ {
+/*N*/ bInvalid = sal_True;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ pPos->nContent.Assign( rNode.GetCntntNode(), nIdx );
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ ASSERT( rNode.IsStartNode(), "Start-Node erwartet" );
+/*N*/ if( USHRT_MAX==nNodeOff )
+/*N*/ {
+/*N*/ pPos->nNode = rNode.EndOfSectionIndex();
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ pPos->nNode = rNodeIdx;
+/*N*/
+/*N*/ ASSERT( 0==nNodeOff,
+/*N*/ "ungeueltige Content-Position fuer Start-Node" );
+/*N*/ if( 0 != nNodeOff )
+/*N*/ Warning();
+/*N*/ }
+/*N*/ pPos->nContent.Assign( 0, 0 );
+/*N*/ }
+/*N*/
+/*N*/ if( cFlags & 0x20 )
+/*N*/ {
+/*N*/ if( (bNormal && bInsert) || bPageDescs )
+/*N*/ {
+/*N*/ if( REDLINE_INSERT == eType )
+/*N*/ {
+/*N*/ // Ein einefuegter Text wird nicht angezeigt. Dann muss der
+/*N*/ // eingefuegt Text an der entsprechenden Position eingfuegt
+/*N*/ // werden.
+/*N*/ if( !nInsFirstPara && !pPos->nNode.GetNode().IsCntntNode() &&
+/*N*/ pRedline->IsDelLastPara() )
+/*N*/ {
+/*N*/ // Wenn das DelLastPara-Flag gsetzt ist, wird
+/*N*/ // versucht in den Absatz davor einzufuegen, denn
+/*N*/ // der soll ja geloescht werden.
+/*N*/ pPos->nNode--;
+/*N*/ SwCntntNode *pCNd = pPos->nNode.GetNode().GetCntntNode();
+/*N*/ ASSERT( pCNd, "Kein Content-Node trotz DelLastPara" );
+/*N*/ if( pCNd )
+/*N*/ pPos->nContent.Assign( pCNd, pCNd->Len() );
+/*N*/ else
+/*N*/ pPos->nNode++;
+/*N*/ }
+/*N*/ const SwNode& rNewNode = pPos->nNode.GetNode();
+/*N*/ if( rNewNode.IsCntntNode() )
+/*N*/ {
+/*N*/ xub_StrLen nCntntIdx = pPos->nContent.GetIndex();
+/*N*/
+/*N*/ InContents( pPos->nNode, nCntntIdx );
+/*N*/
+/*N*/ // Den Offset noch an die Verschiebung der
+/*N*/ // Content-Position anpassen.
+/*N*/ nCntntOff += pPos->nContent.GetIndex();
+/*N*/ nCntntOff -= nCntntIdx;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ InContents( pPos->nNode, 0, FALSE, 0, TRUE );
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ SkipRec();
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ SwNodeIndex aStart( pDoc->GetNodes().GetEndOfRedlines() );
+/*N*/ SwStartNode* pSttNd =
+/*N*/ pDoc->GetNodes().MakeEmptySection( aStart,SwNormalStartNode );
+/*N*/ aStart = *pSttNd->EndOfSectionNode();
+/*N*/ InContents( aStart, 0, FALSE );
+/*N*/ aStart = pSttNd->GetIndex();
+/*N*/ pRedline->SetContentIdx( &aStart );
+/*N*/ if( pSttNd->EndOfSectionIndex() - aStart.GetIndex() == 1 )
+/*N*/ bInvalid = sal_True;
+/*N*/ ASSERT( !bInvalid, "empty redline section imported" );
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ const SwRedlineTbl& rRedlineTbl = pDoc->GetRedlineTbl();
+/*N*/ if( !bInvalid )
+/*N*/ {
+/*N*/ // Check for nested redlines.
+/*N*/ sal_Bool bHasMark = pRedline->HasMark() &&
+/*N*/ *pRedline->GetPoint() != *pRedline->GetMark();
+/*N*/ const SwPosition *pStt = bHasMark ? pRedline->Start() : 0;
+/*N*/ const SwPosition *pEnd = bHasMark ? pRedline->End() : 0;
+/*N*/ sal_uInt16 nCount = rRedlineTbl.Count();
+/*N*/ for( sal_uInt16 i=0; !bInvalid && i<nCount; i++ )
+/*N*/ {
+/*N*/ const SwRedline *pTest = rRedlineTbl[i];
+/*N*/ if( pTest != pRedline )
+/*N*/ {
+/*N*/
+/*N*/ // Is the ineew position is inside an existing
+/*N*/ // redline then it is invalid.
+/*N*/ const SwPosition *pTestStt = pTest->Start();
+/*N*/ const SwPosition *pTestEnd = pTest->HasMark() ? pTest->End() : 0;
+/*N*/ bInvalid = pTestEnd != 0 && *pPos > *pTestStt && *pPos < *pTestEnd;
+/*N*/
+/*N*/ // If the start or end of and existing redline is inside the
+/*N*/ // redline then the new redline is invalid as well;
+/*N*/ if( !bInvalid && bHasMark )
+/*N*/ bInvalid = *pTestStt > *pStt && *pTestStt < *pEnd;
+/*N*/ if( !bInvalid && bHasMark && pTestEnd != 0 )
+/*N*/ bInvalid = *pTestEnd > *pStt && *pTestEnd < *pEnd;
+/*N*/
+/*N*/ ASSERT( !bInvalid, "overlapping redline" );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( bNormal && !bInsert )
+/*N*/ {
+/*N*/ if( (0x10 & cFlags) == 0 )
+/*N*/ {
+/*N*/ // Die Redline darf jetzt eingefuegt werden. Das Redline-Objekt
+/*N*/ // geht in den Besitz des Dokuments ueber.
+/*N*/
+/*N*/ if( !bInvalid )
+/*N*/ bInvalid = !const_cast< SwRedlineTbl& >(rRedlineTbl).Insert(
+/*N*/ pRedline, (BOOL)FALSE );
+/*N*/ }
+/*N*/ else if (bInvalid )
+/*N*/ {
+/*N*/ // The redline is is inserted already and has to be removed from the
+/*N*/ // table;
+/*N*/
+/*N*/ sal_uInt16 nPos = rRedlineTbl.GetPos( pRedline );
+/*N*/ ASSERT( USHRT_MAX != nPos, "inserted invalid redline not found" );
+/*N*/ if( USHRT_MAX != nPos )
+/*N*/ const_cast< SwRedlineTbl& >(rRedlineTbl).Remove( nPos );
+/*N*/ }
+/*N*/
+/*N*/ if( bInvalid )
+/*N*/ {
+/*N*/ // JP 18.5.2001: Bug 87222 - then delete this invalid redline
+/*N*/ delete pRedline;
+/*N*/ pRedlines->Replace( 0, nId );
+/*N*/ Warning();
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ CloseRec( SWG_NODEREDLINE );
+/*N*/ }
+
+/*N*/ void Sw3IoImp::OutNodeRedlines( ULONG nIdx )
+/*N*/ {
+/*N*/ ASSERT( !IsSw31Or40Export(), "Redlines werden nicht exportiert!" );
+/*N*/
+/*N*/ if( pRedlineMarks )
+/*N*/ {
+/*?*/ for( USHORT nPos = 0; nPos < pRedlineMarks->Count(); ++nPos )
+/*?*/ {
+/*?*/ Sw3Mark *pMark = (*pRedlineMarks)[ nPos ];
+/*?*/ if( pMark->GetNodePos() == nIdx )
+/*?*/ {
+/*?*/ ASSERT( pMark->GetId() < pRedlines->Count(),
+/*?*/ "ungeuletige Redline-Id" );
+/*?*/ Sw3MarkType eMarkType = pMark->GetType();
+/*?*/ SwRedline *pRedline = (*pRedlines)[pMark->GetId()];
+/*?*/ const SwNodeIndex *pContentIdx = pRedline->GetContentIdx();
+/*?*/
+/*?*/ OpenRec( SWG_NODEREDLINE );
+/*?*/
+/*?*/ BYTE cFlags = 0x04;
+/*?*/ if( SW3_REDLINE_END == eMarkType )
+/*?*/ cFlags |= 0x10;
+/*?*/ else if( pContentIdx )
+/*?*/ cFlags |= 0x20;
+/*?*/
+/*?*/ xub_StrLen nOffs = pMark->GetNodeOff();
+/*?*/ if( pDoc->GetNodes()[nIdx]->IsCntntNode() &&
+/*?*/ nOffs > STRING_MAXLEN52 )
+/*?*/ nOffs = STRING_MAXLEN52;
+/*?*/ *pStrm << (BYTE) cFlags
+/*?*/ << (UINT16)pMark->GetId()
+/*?*/ << (UINT16)nOffs;
+/*?*/
+/*?*/ if( pContentIdx )
+/*?*/ {
+/*?*/ ASSERT( pContentIdx->GetNode().EndOfSectionIndex() -
+/*?*/ pContentIdx->GetIndex(),
+/*?*/ "empty redline section exported" );
+/*?*/ OutContents( *pContentIdx );
+/*?*/ }
+/*?*/
+/*?*/ CloseRec( SWG_NODEREDLINE );
+/*?*/
+/*?*/ pRedlineMarks->Remove( nPos-- );
+/*?*/ delete pMark;
+/*?*/ if( !pRedlineMarks->Count() )
+/*?*/ {
+/*?*/ delete pRedlineMarks;
+/*?*/ pRedlineMarks = NULL;
+/*?*/ break;
+/*?*/ }
+/*?*/ }
+/*?*/ else if( pMark->GetNodePos() > nIdx )
+/*?*/ break;
+/*?*/ }
+/*N*/ }
+/*N*/ }
+
+ /* */
+/*N*/ namespace
+/*N*/ {
+/*N*/ void CorrRedline( SwRedline& rRedline,
+/*N*/ const SwPosition& rOldPos,
+/*N*/ const SwPosition& rNewPos )
+/*N*/ {
+/*N*/ sal_uInt32 nOldNodeIdx = rOldPos.nNode.GetIndex();
+/*N*/ if( rRedline.GetPoint()->nNode.GetIndex() == nOldNodeIdx )
+/*N*/ {
+/*N*/ xub_StrLen nOffset = rRedline.GetPoint()->nContent.GetIndex() -
+/*N*/ rOldPos.nContent.GetIndex();
+/*N*/ rRedline.GetPoint()->nNode = rNewPos.nNode;
+/*N*/ rRedline.GetPoint()->nContent.Assign(
+/*N*/ rNewPos.nNode.GetNode().GetCntntNode(),
+/*N*/ rNewPos.nContent.GetIndex() + nOffset );
+/*N*/ }
+/*N*/ if( rRedline.GetMark()->nNode.GetIndex() == nOldNodeIdx )
+/*N*/ {
+/*N*/ xub_StrLen nOffset = rRedline.GetMark()->nContent.GetIndex() -
+/*N*/ rOldPos.nContent.GetIndex();
+/*N*/ rRedline.GetMark()->nNode = rNewPos.nNode;
+/*N*/ rRedline.GetMark()->nContent.Assign(
+/*N*/ rNewPos.nNode.GetNode().GetCntntNode(),
+/*N*/ rNewPos.nContent.GetIndex() + nOffset );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ void Sw3IoImp::CleanupRedlines()
+/*N*/ {
+/*N*/ if( !pRedlines || !pRedlines->Count() )
+/*N*/ return;
+/*N*/
+/*N*/ // Bisher muss hier nur was beim Einfugen und Laden von Seiten-Vorlagen
+/*N*/ // passieren.
+/*N*/ if( (bNormal && bInsert) || bPageDescs )
+/*N*/ {
+/*N*/ // Alle geloeschten-Redlines, die angezeigt werden, muessen noch
+/*N*/ // geloescht werden.
+/*N*/
+/*N*/ // In a first step, delete the redline objects that are not deletions.
+/*N*/ sal_uInt16 i=0;
+/*N*/ while( i < pRedlines->Count() )
+/*N*/ {
+/*N*/ SwRedline *pRedline = (*pRedlines)[i];
+/*N*/ if( pRedline )
+/*N*/ {
+/*N*/ if( REDLINE_DELETE != pRedline->GetType() ||
+/*N*/ pRedline->GetContentIdx() != 0 )
+/*N*/ {
+/*N*/ delete pRedline;
+/*N*/ pRedlines->Remove( i );
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ ++i;
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ pRedlines->Remove( i );
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ // now process the remaining redlines
+/*N*/ sal_uInt16 nCount = pRedlines->Count();
+/*N*/ for( i=0; i<nCount; ++i )
+/*N*/ {
+/*N*/ SwRedline *pRedline = (*pRedlines)[i];
+/*N*/ ASSERT( REDLINE_DELETE == pRedline->GetType() &&
+/*N*/ !pRedline->GetContentIdx(), "wrong redline type" );
+/*N*/ SwRedlineMode eOld = pDoc->GetRedlineMode();
+/*N*/ pDoc->SetRedlineMode_intern( eOld & ~(REDLINE_ON | REDLINE_IGNORE) );
+/*N*/ {
+/*N*/ // If the end node of the redline is deleted (and not joined
+/*N*/ // with the next one), then we have to make sure that none of
+/*N*/ // the remaining redlines starts in that node.
+/*N*/ // The end node of the redline is deleted if the PaM's point
+/*N*/ // or if it is the PaM mark, but in this later case, the whole
+/*N*/ // last node has to be selected.
+/*N*/ const SwPosition& rPointPos = *pRedline->GetPoint();
+/*N*/ const SwPosition& rMarkPos = *pRedline->GetMark();
+/*N*/ if( rPointPos.nNode.GetNode().IsCntntNode() &&
+/*N*/ rMarkPos.nNode.GetNode().IsCntntNode() &&
+/*N*/ ( rPointPos.nNode.GetIndex() > rMarkPos.nNode.GetIndex() ||
+/*N*/ (rMarkPos.nNode.GetIndex() > rPointPos.nNode.GetIndex() &&
+/*N*/ rMarkPos.nContent.GetIndex() == rMarkPos.nNode.GetNode().GetCntntNode()->Len()) ) )
+/*N*/ {
+/*N*/ for( sal_uInt16 j= i+1; j < nCount; ++j )
+/*N*/ {
+/*N*/ SwRedline *pTestRedline = (*pRedlines)[j];
+/*N*/ CorrRedline( *pTestRedline, *pRedline->End(),
+/*N*/ *pRedline->Start() );
+/*N*/ }
+/*N*/ }
+/*N*/ pDoc->DeleteAndJoin( *pRedline );
+/*N*/ pDoc->SetRedlineMode_intern( eOld );
+/*N*/ }
+/*N*/ delete pRedline;
+/*N*/ }
+/*N*/ // Das Array wird zwar auch im CloseStreams geloscht, da wir
+/*N*/ // die Objekte aber schon geloescht haben, ist es besser, das
+/*N*/ // Array gleich zu loeschen.
+/*N*/ pRedlines->Remove( 0, pRedlines->Count() );
+/*N*/ delete pRedlines; pRedlines = 0;
+/*N*/ }
+/*N*/ }
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */