/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"


#define _SVSTDARR_STRINGSSORTDTOR
#define _SVSTDARR_USHORTSSORT
#define _SVSTDARR_USHORTS


#include <redline.hxx>
#include <tools/datetime.hxx>
#include <vcl/msgbox.hxx>
#include <svl/svstdarr.hxx>
#include <svl/eitem.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
#include <svx/ctredlin.hxx>
#include <svx/postattr.hxx>
#include <swtypes.hxx>
#include <wrtsh.hxx>
#include <view.hxx>
#include <swmodule.hxx>
#ifndef _REDLNDLG_HXX
#define _REDLNACCEPTDLG
#include <redlndlg.hxx>
#endif
#include <swwait.hxx>
#include <uitool.hxx>

#include <helpid.h>
#include <cmdid.h>
#include <misc.hrc>
#include <redlndlg.hrc>
#include <shells.hrc>

// -> #111827#
#include <comcore.hrc>
#include <swundo.hxx>
#include <SwRewriter.hxx>
// <- #111827#

#include <vector>
#include <svx/svxdlg.hxx>
#include <svx/dialogs.hrc>

#include <unomid.h>

#include <docsh.hxx>

#include <IDocumentRedlineAccess.hxx>

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

SFX_IMPL_MODELESSDIALOG( SwRedlineAcceptChild, FN_REDLINE_ACCEPT )

SV_IMPL_PTRARR(SwRedlineDataParentArr, SwRedlineDataParentPtr)
SV_IMPL_OP_PTRARR_SORT(SwRedlineDataParentSortArr, SwRedlineDataParentPtr)
SV_IMPL_PTRARR(SwRedlineDataChildArr, SwRedlineDataChildPtr)
SV_IMPL_PTRARR(SvLBoxEntryArr, SvLBoxEntryPtr)

static sal_uInt16 nSortMode = 0xffff;
static sal_Bool   bSortDir = sal_True;

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

SwRedlineAcceptChild::SwRedlineAcceptChild( Window* _pParent,
											sal_uInt16 nId,
											SfxBindings* pBindings,
											SfxChildWinInfo* pInfo ) :
    SwChildWinWrapper( _pParent, nId )
{
    pWindow = new SwModelessRedlineAcceptDlg( pBindings, this, _pParent);

	((SwModelessRedlineAcceptDlg *)pWindow)->Initialize(pInfo);
}

/*--------------------------------------------------------------------
	Beschreibung: Nach Dok-Wechsel Dialog neu initialisieren
 --------------------------------------------------------------------*/

sal_Bool SwRedlineAcceptChild::ReInitDlg(SwDocShell *pDocSh)
{
	sal_Bool bRet;

	if ((bRet = SwChildWinWrapper::ReInitDlg(pDocSh)) == sal_True)	// Sofort aktualisieren, Dok-Wechsel
		((SwModelessRedlineAcceptDlg*)GetWindow())->Activate();

	return bRet;
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

SwModelessRedlineAcceptDlg::SwModelessRedlineAcceptDlg( SfxBindings* _pBindings,
														SwChildWinWrapper* pChild,
                                                        Window *_pParent) :
    SfxModelessDialog(_pBindings, pChild, _pParent, SW_RES(DLG_REDLINE_ACCEPT)),
	pChildWin		(pChild)
{
	pImplDlg = new SwRedlineAcceptDlg(this);

	FreeResource();
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

void SwModelessRedlineAcceptDlg::Activate()
{
	SwView *pView = ::GetActiveView();

	if (!pView)	// Kann passieren, wenn man auf eine andere App umschaltet, wenn
		return;	// vorher eine Listbox im Dialog den Focus hatte (eigentlich THs Bug)

	SwDocShell *pDocSh = pView->GetDocShell();

	if (pChildWin->GetOldDocShell() != pDocSh)
	{	// Dok-Wechsel
		SwWait aWait( *pDocSh, sal_False );
		SwWrtShell* pSh = pView->GetWrtShellPtr();

		pChildWin->SetOldDocShell(pDocSh);	// Rekursion vermeiden (durch Modified-Hdl)

		sal_Bool bMod = pSh->IsModified();
		SfxBoolItem aShow(FN_REDLINE_SHOW, sal_True);
		pSh->GetView().GetViewFrame()->GetDispatcher()->Execute(
			FN_REDLINE_SHOW, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD, &aShow, 0L);
		if (!bMod)
			pSh->ResetModified();
		pImplDlg->Init();

		return;
	}

	pImplDlg->Activate();
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

void SwModelessRedlineAcceptDlg::Initialize(SfxChildWinInfo *pInfo)
{
	String aStr;
	if (pInfo != NULL)
		pImplDlg->Initialize(pInfo->aExtraString);

	SfxModelessDialog::Initialize(pInfo);
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

void SwModelessRedlineAcceptDlg::FillInfo(SfxChildWinInfo& rInfo) const
{
	SfxModelessDialog::FillInfo(rInfo);
	pImplDlg->FillInfo(rInfo.aExtraString);
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

void SwModelessRedlineAcceptDlg::Resize()
{
	pImplDlg->Resize();
	SfxModelessDialog::Resize();
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

SwModelessRedlineAcceptDlg::~SwModelessRedlineAcceptDlg()
{
	delete pImplDlg;
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

SwRedlineAcceptDlg::SwRedlineAcceptDlg(Dialog *pParent, sal_Bool bAutoFmt) :
	pParentDlg		(pParent),
    aTabPagesCTRL   (pParent, SW_RES(CTRL_TABPAGES)),
    aPopup          (SW_RES(MN_REDLINE_POPUP)),
    sInserted       (SW_RES(STR_REDLINE_INSERTED)),
    sDeleted        (SW_RES(STR_REDLINE_DELETED)),
    sFormated       (SW_RES(STR_REDLINE_FORMATED)),
    sTableChgd      (SW_RES(STR_REDLINE_TABLECHG)),
    sFmtCollSet     (SW_RES(STR_REDLINE_FMTCOLLSET)),
    sAutoFormat     (SW_RES(STR_REDLINE_AUTOFMT)),
	bOnlyFormatedRedlines( sal_False ),
	bHasReadonlySel	( sal_False ),
	bRedlnAutoFmt	(bAutoFmt),
    bInhibitActivate( false )
{
	aTabPagesCTRL.SetHelpId(HID_REDLINE_CTRL);
	pTPView = aTabPagesCTRL.GetViewPage();
	pTable = pTPView->GetTableControl();

	pTPView->InsertWriterHeader();
	pTPView->SetAcceptClickHdl(LINK(this, SwRedlineAcceptDlg, AcceptHdl));
	pTPView->SetAcceptAllClickHdl(LINK(this, SwRedlineAcceptDlg, AcceptAllHdl));
	pTPView->SetRejectClickHdl(LINK(this, SwRedlineAcceptDlg, RejectHdl));
	pTPView->SetRejectAllClickHdl(LINK(this, SwRedlineAcceptDlg, RejectAllHdl));
	pTPView->SetUndoClickHdl(LINK(this, SwRedlineAcceptDlg, UndoHdl));

	aTabPagesCTRL.GetFilterPage()->SetReadyHdl(LINK(this, SwRedlineAcceptDlg, FilterChangedHdl));

	ListBox *pActLB = aTabPagesCTRL.GetFilterPage()->GetLbAction();
	pActLB->InsertEntry(sInserted);
	pActLB->InsertEntry(sDeleted);
	pActLB->InsertEntry(sFormated);
	pActLB->InsertEntry(sTableChgd);

	if (HasRedlineAutoFmt())
	{
		pActLB->InsertEntry(sFmtCollSet);
		pActLB->InsertEntry(sAutoFormat);
		pTPView->ShowUndo(sal_True);
		pTPView->DisableUndo();		// Noch gibts keine UNDO-Events
	}

	pActLB->SelectEntryPos(0);

	pTable->SetStyle(pTable->GetStyle()|WB_HASLINES|WB_CLIPCHILDREN|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL);
	pTable->SetNodeDefaultImages();
	pTable->SetSelectionMode(MULTIPLE_SELECTION);
	pTable->SetHighlightRange(1);

	static long aStaticTabs[]=
	{
		4,10,70,120,170
	};

	pTable->SetTabs(aStaticTabs);

	// Minimalgroesse setzen
	Size aMinSz(aTabPagesCTRL.GetMinSizePixel());
	Point aPos(aTabPagesCTRL.GetPosPixel());

	aMinSz.Width() += (aPos.X() * 2 - 1);
	aMinSz.Height() += (aPos.Y() * 2 - 1);
	pParentDlg->SetMinOutputSizePixel(aMinSz);

	if (pParentDlg->GetOutputSizePixel().Width() < aMinSz.Width())
		pParentDlg->SetOutputSizePixel(Size(aMinSz.Width(), pParentDlg->GetOutputSizePixel().Height()));
	if (pParentDlg->GetOutputSizePixel().Height() < aMinSz.Height())
		pParentDlg->SetOutputSizePixel(Size(pParentDlg->GetOutputSizePixel().Width(), aMinSz.Height()));

	pTable->SortByCol(nSortMode, bSortDir);

	aOldSelectHdl = pTable->GetSelectHdl();
	aOldDeselectHdl = pTable->GetDeselectHdl();
	pTable->SetSelectHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl));
	pTable->SetDeselectHdl(LINK(this, SwRedlineAcceptDlg, DeselectHdl));
	pTable->SetCommandHdl(LINK(this, SwRedlineAcceptDlg, CommandHdl));

	// Flackern der Buttons vermeiden:
	aDeselectTimer.SetTimeout(100);
	aDeselectTimer.SetTimeoutHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl));

	// Mehrfachselektion der selben Texte vermeiden:
	aSelectTimer.SetTimeout(100);
	aSelectTimer.SetTimeoutHdl(LINK(this, SwRedlineAcceptDlg, GotoHdl));
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

SwRedlineAcceptDlg::~SwRedlineAcceptDlg()
{
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

void SwRedlineAcceptDlg::Init(sal_uInt16 nStart)
{
	SwWait aWait( *::GetActiveView()->GetDocShell(), sal_False );
	pTable->SetUpdateMode(sal_False);
	aUsedSeqNo.Remove((sal_uInt16)0, aUsedSeqNo.Count());

	if (nStart)
		RemoveParents(nStart, aRedlineParents.Count() - 1);
	else
	{
		pTable->Clear();
		aRedlineChilds.DeleteAndDestroy(0, aRedlineChilds.Count());
		aRedlineParents.DeleteAndDestroy(nStart, aRedlineParents.Count() - nStart);
	}

	// Parents einfuegen
	InsertParents(nStart);
	InitAuthors();

	pTable->SetUpdateMode(sal_True);
    // #i69618# this moves the list box to the right position, visually
    SvLBoxEntry* pSelEntry = pTable->FirstSelected();
    if( pSelEntry )
        pTable->MakeVisible( pSelEntry, sal_True ); //#i70937#, force the scroll
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

void SwRedlineAcceptDlg::InitAuthors()
{
	SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();

	SvxTPFilter *pFilterPage = aTabPagesCTRL.GetFilterPage();

	String sAuthor;
	SvStringsSortDtor aStrings;
	String sOldAuthor(pFilterPage->GetSelectedAuthor());
	pFilterPage->ClearAuthors();

	String sParent;
	sal_uInt16 nCount = pSh->GetRedlineCount();

	bOnlyFormatedRedlines = sal_True;
	bHasReadonlySel = sal_False;
	sal_Bool bIsNotFormated = sal_False;
	sal_uInt16 i;

	// Autoren ermitteln
	for ( i = 0; i < nCount; i++)
	{
		const SwRedline& rRedln = pSh->GetRedline(i);

		if( bOnlyFormatedRedlines && nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType() )
			bOnlyFormatedRedlines = sal_False;

//JP 27.9.2001: make no sense if we handle readonly sections
//		if( !bHasReadonlySel && rRedln.HasReadonlySel() )
//			bHasReadonlySel = sal_True;

		String *pAuthor = new String(rRedln.GetAuthorString());
		if (!aStrings.Insert(pAuthor))
			delete pAuthor;

		for (sal_uInt16 nStack = 1; nStack < rRedln.GetStackCount(); nStack++)
		{
			pAuthor = new String(rRedln.GetAuthorString(nStack));
			if (!aStrings.Insert(pAuthor))
				delete pAuthor;
		}
	}

	for (i = 0; i < aStrings.Count(); i++)
		pFilterPage->InsertAuthor(*aStrings[i]);

	if (pFilterPage->SelectAuthor(sOldAuthor) == LISTBOX_ENTRY_NOTFOUND && aStrings.Count())
		pFilterPage->SelectAuthor(*aStrings[0]);

    sal_Bool bEnable = pTable->GetEntryCount() != 0 && !pSh->getIDocumentRedlineAccess()->GetRedlinePassword().getLength();
	sal_Bool bSel = pTable->FirstSelected() != 0;

	SvLBoxEntry* pSelEntry = pTable->FirstSelected();
	while (pSelEntry)
	{
		sal_uInt16 nPos = GetRedlinePos(*pSelEntry);
		const SwRedline& rRedln = pSh->GetRedline( nPos );

		bIsNotFormated |= nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType();
		pSelEntry = pTable->NextSelected(pSelEntry);
	}

	pTPView->EnableAccept( bEnable && bSel );
	pTPView->EnableReject( bEnable && bIsNotFormated && bSel );
	pTPView->EnableAcceptAll( bEnable && !bHasReadonlySel );
	pTPView->EnableRejectAll( bEnable && !bHasReadonlySel &&
								!bOnlyFormatedRedlines );
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

String SwRedlineAcceptDlg::GetRedlineText( const SwRedline& rRedln,
										DateTime &rDateTime, sal_uInt16 nStack)
{
	String sEntry(GetActionText(rRedln, nStack));
	sEntry += '\t';
	sEntry += rRedln.GetAuthorString(nStack);
	sEntry += '\t';

	const DateTime &rDT = rRedln.GetTimeStamp(nStack);
	rDateTime = rDT;

	sEntry += GetAppLangDateTimeString( rDT );
	sEntry += '\t';

	sEntry += rRedln.GetComment(nStack);

	return sEntry;
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

const String &SwRedlineAcceptDlg::GetActionText(const SwRedline& rRedln, sal_uInt16 nStack)
{
	switch( rRedln.GetType(nStack) )
	{
		case nsRedlineType_t::REDLINE_INSERT:	return sInserted;
		case nsRedlineType_t::REDLINE_DELETE:	return sDeleted;
		case nsRedlineType_t::REDLINE_FORMAT:	return sFormated;
		case nsRedlineType_t::REDLINE_TABLE: 	return sTableChgd;
		case nsRedlineType_t::REDLINE_FMTCOLL: 	return sFmtCollSet;
        default:;//prevent warning
	}

	return aEmptyStr;
}

/*------------------------------------------------------------------------
	Beschreibung:
------------------------------------------------------------------------*/

void SwRedlineAcceptDlg::Resize()
{
	Size aSz(pParentDlg->GetOutputSizePixel());

	Point aPos(aTabPagesCTRL.GetPosPixel());

	aSz.Width() -= (aPos.X() * 2 - 1);
	aSz.Height() -= (aPos.Y() * 2 - 1);

	aTabPagesCTRL.SetOutputSizePixel(aSz);
}

/*--------------------------------------------------------------------
	Beschreibung: Nach Aktivierung neu initialisieren
 --------------------------------------------------------------------*/

void SwRedlineAcceptDlg::Activate()
{
    // prevent update if flag is set (#102547#)
    if( bInhibitActivate )
        return;

	SwView *pView = ::GetActiveView();
	SwWait aWait( *pView->GetDocShell(), sal_False );

	aUsedSeqNo.Remove((sal_uInt16)0, aUsedSeqNo.Count());

	if (!pView)	// Kann passieren, wenn man auf eine andere App umschaltet, wenn
		return;	// vorher eine Listbox im Dialog den Focus hatte (eigentlich THs Bug)

/*	if (HasRedlineAutoFmt())
	{
		Init();
		return;
	}*/

	// Hat sich was geaendert?
	SwWrtShell* pSh = pView->GetWrtShellPtr();
	sal_uInt16 nCount = pSh->GetRedlineCount();

	// Anzahl und Pointer ueberpruefen
	SwRedlineDataParent *pParent = 0;
	sal_uInt16 i;

	for ( i = 0; i < nCount; i++)
	{
		const SwRedline& rRedln = pSh->GetRedline(i);

		if (i >= aRedlineParents.Count())
		{
			// Neue Eintraege wurden angehaengt
			Init(i);
			return;
		}

		pParent = aRedlineParents[i];
		if (&rRedln.GetRedlineData() != pParent->pData)
		{
			// Redline-Parents wurden eingefuegt, geaendert oder geloescht
			if ((i = CalcDiff(i, sal_False)) == USHRT_MAX)
				return;
			continue;
		}

		const SwRedlineData *pRedlineData = rRedln.GetRedlineData().Next();
		const SwRedlineDataChild *pBackupData = pParent->pNext;

		if (!pRedlineData && pBackupData)
		{
			// Redline-Childs wurden geloescht
			if ((i = CalcDiff(i, sal_True)) == USHRT_MAX)
				return;
			continue;
		}
		else
		{
			while (pRedlineData)
			{
				if (pRedlineData != pBackupData->pChild)
				{
					// Redline-Childs wurden eingefuegt, geaendert oder geloescht
					if ((i = CalcDiff(i, sal_True)) == USHRT_MAX)
						return;
					continue;
				}
				if (pBackupData)
					pBackupData = pBackupData->pNext;
				pRedlineData = pRedlineData->Next();
			}
		}
	}

	if (nCount != aRedlineParents.Count())
	{
		// Redlines wurden am Ende geloescht
		Init(nCount);
		return;
	}

	// Kommentar ueberpruefen
	for (i = 0; i < nCount; i++)
	{
		const SwRedline& rRedln = pSh->GetRedline(i);
		pParent = aRedlineParents[i];

		if(!rRedln.GetComment().Equals(pParent->sComment))
		{
			if (pParent->pTLBParent)
			{
				// Nur Kommentar aktualisieren
				String sComment(rRedln.GetComment());
				sComment.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' ');
				pTable->SetEntryText(sComment, pParent->pTLBParent, 3);
			}
			pParent->sComment = rRedln.GetComment();
		}
	}

	InitAuthors();
}

/* -----------------05.06.98 13:06-------------------
 *
 * --------------------------------------------------*/

sal_uInt16 SwRedlineAcceptDlg::CalcDiff(sal_uInt16 nStart, sal_Bool bChild)
{
	if (!nStart)
	{
		Init();
		return USHRT_MAX;
	}

	pTable->SetUpdateMode(sal_False);
	SwView *pView	= ::GetActiveView();
	SwWrtShell* pSh	= pView->GetWrtShellPtr();
    sal_uInt16 nAutoFmt = HasRedlineAutoFmt() ? nsRedlineType_t::REDLINE_FORM_AUTOFMT : 0;
    SwRedlineDataParent *pParent = aRedlineParents[nStart];
	const SwRedline& rRedln = pSh->GetRedline(nStart);

	if (bChild)		// Sollte eigentlich nie vorkommen, aber sicher ist sicher...
	{
		// Alle Childs des Eintrags wegwerfen und neu initialisieren
		SwRedlineDataChildPtr pBackupData = (SwRedlineDataChildPtr)pParent->pNext;
		SwRedlineDataChildPtr pNext;

		while (pBackupData)
		{
			pNext = (SwRedlineDataChildPtr)pBackupData->pNext;
			if (pBackupData->pTLBChild)
                pTable->RemoveEntry(pBackupData->pTLBChild);

			aRedlineChilds.DeleteAndDestroy(aRedlineChilds.GetPos(pBackupData), 1);
			pBackupData = pNext;
		}
		pParent->pNext = 0;

		// Neue Childs einfuegen
		InsertChilds(pParent, rRedln, nAutoFmt);

		pTable->SetUpdateMode(sal_True);
		return nStart;
	}

	// Wurden Eintraege geloescht?
	const SwRedlineData *pRedlineData = &rRedln.GetRedlineData();
	sal_uInt16 i;
	for ( i = nStart + 1; i < aRedlineParents.Count(); i++)
	{
		if (aRedlineParents[i]->pData == pRedlineData)
		{
			// Eintraege von nStart bis i-1 entfernen
			RemoveParents(nStart, i - 1);
			pTable->SetUpdateMode(sal_True);
			return nStart - 1;
		}
	}

	// Wurden Eintraege eingefuegt?
	sal_uInt16 nCount = pSh->GetRedlineCount();
	pRedlineData = aRedlineParents[nStart]->pData;

	for (i = nStart + 1; i < nCount; i++)
	{
		if (&pSh->GetRedline(i).GetRedlineData() == pRedlineData)
		{
			// Eintraege von nStart bis i-1 einfuegen
			InsertParents(nStart, i - 1);
			pTable->SetUpdateMode(sal_True);
			return nStart - 1;
		}
	}

	pTable->SetUpdateMode(sal_True);
	Init(nStart);	// Alle Eintraege bis zum Ende abgleichen
	return USHRT_MAX;
}

/* -----------------05.06.98 13:57-------------------
 *
 * --------------------------------------------------*/

void SwRedlineAcceptDlg::InsertChilds(SwRedlineDataParent *pParent, const SwRedline& rRedln, const sal_uInt16 nAutoFmt)
{
	String sChild;
	SwRedlineDataChild *pLastRedlineChild = 0;
	const SwRedlineData *pRedlineData = &rRedln.GetRedlineData();
	sal_Bool bAutoFmt = (rRedln.GetRealType() & nAutoFmt) != 0;

	const String *pAction = &GetActionText(rRedln);
	sal_Bool bValidParent = !sFilterAction.Len() || sFilterAction == *pAction;
	bValidParent = bValidParent && pTable->IsValidEntry(&rRedln.GetAuthorString(), &rRedln.GetTimeStamp(), &rRedln.GetComment());
	if (nAutoFmt)
	{
		sal_uInt16 nPos;

		if (pParent->pData->GetSeqNo() && !aUsedSeqNo.Insert(pParent, nPos))	// Gibts schon
		{
			if (pParent->pTLBParent)
			{
				pTable->SetEntryText(sAutoFormat, aUsedSeqNo[nPos]->pTLBParent, 0);
                pTable->RemoveEntry(pParent->pTLBParent);
				pParent->pTLBParent = 0;
			}
			return;
		}
		bValidParent = bValidParent && bAutoFmt;
	}
	sal_Bool bValidTree = bValidParent;

	for (sal_uInt16 nStack = 1; nStack < rRedln.GetStackCount(); nStack++)
	{
		pRedlineData = pRedlineData->Next();

		SwRedlineDataChildPtr pRedlineChild = new SwRedlineDataChild;
		pRedlineChild->pChild = pRedlineData;
		aRedlineChilds.Insert(pRedlineChild, aRedlineChilds.Count());

		if ( pLastRedlineChild )
			pLastRedlineChild->pNext = pRedlineChild;
		else
			pParent->pNext = pRedlineChild;

		pAction = &GetActionText(rRedln, nStack);
		sal_Bool bValidChild = !sFilterAction.Len() || sFilterAction == *pAction;
		bValidChild = bValidChild && pTable->IsValidEntry(&rRedln.GetAuthorString(nStack), &rRedln.GetTimeStamp(nStack), &rRedln.GetComment());
		if (nAutoFmt)
			bValidChild = bValidChild && bAutoFmt;
		bValidTree |= bValidChild;

		if (bValidChild)
		{
			RedlinData *pData = new RedlinData;
			pData->pData = pRedlineChild;
			pData->bDisabled = sal_True;
			sChild = GetRedlineText(rRedln, pData->aDateTime, nStack);

			SvLBoxEntry* pChild = pTable->InsertEntry(sChild, pData, pParent->pTLBParent);

			pRedlineChild->pTLBChild = pChild;
			if (!bValidParent)
				pTable->Expand(pParent->pTLBParent);
		}
		else
			pRedlineChild->pTLBChild = 0;

		pLastRedlineChild = pRedlineChild;
	}

	if (pLastRedlineChild)
		pLastRedlineChild->pNext = 0;

	if (!bValidTree && pParent->pTLBParent)
	{
        pTable->RemoveEntry(pParent->pTLBParent);
		pParent->pTLBParent = 0;
		if (nAutoFmt)
			aUsedSeqNo.Remove(pParent);
	}
}

/* -----------------05.06.98 15:20-------------------
 *
 * --------------------------------------------------*/

void SwRedlineAcceptDlg::RemoveParents(sal_uInt16 nStart, sal_uInt16 nEnd)
{
	SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
	sal_uInt16 nCount = pSh->GetRedlineCount();

	SvLBoxEntryArr aLBoxArr;

	// Wegen Bug der TLB, die bei Remove den SelectHandler IMMER ruft:
	pTable->SetSelectHdl(aOldSelectHdl);
	pTable->SetDeselectHdl(aOldDeselectHdl);
	sal_Bool bChildsRemoved = sal_False;
	pTable->SelectAll(sal_False);

	// Hinter dem letzten Eintrag Cursor setzen, da sonst Performance-Problem in TLB.
	// TLB wuerde sonst bei jedem Remove den Cursor erneut umsetzen (teuer)
	sal_uInt16 nPos = Min((sal_uInt16)nCount, (sal_uInt16)aRedlineParents.Count());
	SvLBoxEntry *pCurEntry = NULL;
	while( ( pCurEntry == NULL ) && ( nPos > 0 ) )
	{
		--nPos;
		pCurEntry = aRedlineParents[nPos]->pTLBParent;
	}

	if (pCurEntry)
		pTable->SetCurEntry(pCurEntry);

	SvLBoxTreeList*	pModel = pTable->GetModel();

	for (sal_uInt16 i = nStart; i <= nEnd; i++)
	{
		if (!bChildsRemoved && aRedlineParents[i]->pNext)
		{
			SwRedlineDataChildPtr pChildPtr = (SwRedlineDataChildPtr)aRedlineParents[i]->pNext;
            sal_uInt16 nChildPos = aRedlineChilds.GetPos(pChildPtr);

            if (nChildPos != USHRT_MAX)
			{
				sal_uInt16 nChilds = 0;

				while (pChildPtr)
				{
					pChildPtr = (SwRedlineDataChildPtr)pChildPtr->pNext;
					nChilds++;
				}

                aRedlineChilds.DeleteAndDestroy(nChildPos, nChilds);
				bChildsRemoved = sal_True;
			}
		}
		SvLBoxEntry *pEntry = aRedlineParents[i]->pTLBParent;
		if (pEntry)
		{
            long nIdx = aLBoxArr.Count() - 1L;
			sal_uLong nAbsPos = pModel->GetAbsPos(pEntry);
			while (nIdx >= 0 &&
                    pModel->GetAbsPos(aLBoxArr[ static_cast< sal_uInt16 >(nIdx) ]) > nAbsPos)
				nIdx--;
            aLBoxArr.Insert( pEntry, static_cast< sal_uInt16 >(++nIdx) );
		}
	}

	// TLB von hinten abraeumen
	long nIdx = (long)aLBoxArr.Count() - 1L;
	while (nIdx >= 0)
        pTable->RemoveEntry(aLBoxArr[ static_cast< sal_uInt16 >(nIdx--) ]);

	pTable->SetSelectHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl));
	pTable->SetDeselectHdl(LINK(this, SwRedlineAcceptDlg, DeselectHdl));
	// Durch Remove wurde leider wieder dauernd von der TLB selektiert...
	pTable->SelectAll(sal_False);

	aRedlineParents.DeleteAndDestroy( nStart, nEnd - nStart + 1);
}

/* -----------------05.06.98 15:20-------------------
 *
 * --------------------------------------------------*/

void SwRedlineAcceptDlg::InsertParents(sal_uInt16 nStart, sal_uInt16 nEnd)
{
	SwView *pView	= ::GetActiveView();
	SwWrtShell* pSh	= pView->GetWrtShellPtr();
	sal_uInt16 nAutoFmt	= HasRedlineAutoFmt() ? nsRedlineType_t::REDLINE_FORM_AUTOFMT : 0;

	String sParent;
	sal_uInt16 nCount = pSh->GetRedlineCount();
	nEnd = Min((sal_uInt16)nEnd, (sal_uInt16)(nCount - 1));	// Handelt auch nEnd=USHRT_MAX (bis zum Ende) ab

	if (nEnd == USHRT_MAX)
		return;		// Keine Redlines im Dokument

	RedlinData *pData;
    SvLBoxEntry *pParent;
	SwRedlineDataParentPtr pRedlineParent;
	const SwRedline* pCurrRedline;
	if( !nStart && !pTable->FirstSelected() )
	{
		pCurrRedline = pSh->GetCurrRedline();
		if( !pCurrRedline )
		{
			pSh->SwCrsrShell::Push();
			if( 0 == (pCurrRedline = pSh->SelNextRedline()))
				pCurrRedline = pSh->SelPrevRedline();
			pSh->SwCrsrShell::Pop( sal_False );
		}
	}
	else
		pCurrRedline = 0;

	for (sal_uInt16 i = nStart; i <= nEnd; i++)
	{
		const SwRedline& rRedln = pSh->GetRedline(i);
		const SwRedlineData *pRedlineData = &rRedln.GetRedlineData();

		pRedlineParent = new SwRedlineDataParent;
		pRedlineParent->pData	 = pRedlineData;
		pRedlineParent->pNext	 = 0;
		String sComment(rRedln.GetComment());
		sComment.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' ');
		pRedlineParent->sComment = sComment;
		aRedlineParents.Insert(pRedlineParent, i);

		pData = new RedlinData;
		pData->pData = pRedlineParent;
		pData->bDisabled = sal_False;

		sParent = GetRedlineText(rRedln, pData->aDateTime);
		pParent = pTable->InsertEntry(sParent, pData, 0, i);
		if( pCurrRedline == &rRedln )
		{
			pTable->SetCurEntry( pParent );
			pTable->Select( pParent );
			pTable->MakeVisible( pParent );
		}

		pRedlineParent->pTLBParent = pParent;

		InsertChilds(pRedlineParent, rRedln, nAutoFmt);
	}
}

/* -----------------05.06.98 13:06-------------------
 *
 * --------------------------------------------------*/

void SwRedlineAcceptDlg::CallAcceptReject( sal_Bool bSelect, sal_Bool bAccept )
{
	SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
	SvLBoxEntry* pEntry = bSelect ? pTable->FirstSelected() : pTable->First();
	sal_uLong nPos = LONG_MAX;

    typedef std::vector<SvLBoxEntry*> ListBoxEntries_t;
    ListBoxEntries_t aRedlines;

    // don't activate
    DBG_ASSERT( bInhibitActivate == false,
                "recursive call of CallAcceptReject?");
    bInhibitActivate = true;

    // collect redlines-to-be-accepted/rejected in aRedlines vector
	while( pEntry )
	{
		if( !pTable->GetParent( pEntry ) )
		{
			if( bSelect && LONG_MAX == nPos )
				nPos = pTable->GetModel()->GetAbsPos( pEntry );

			RedlinData *pData = (RedlinData *)pEntry->GetUserData();

			if( !pData->bDisabled )
				aRedlines.push_back( pEntry );
		}

		pEntry = bSelect ? pTable->NextSelected(pEntry) : pTable->Next(pEntry);
	}

	sal_Bool (SwEditShell:: *FnAccRej)( sal_uInt16 ) = &SwEditShell::AcceptRedline;
	if( !bAccept )
		FnAccRej = &SwEditShell::RejectRedline;

	SwWait aWait( *pSh->GetView().GetDocShell(), sal_True );
	pSh->StartAction();

    // #111827#
    if (aRedlines.size() > 1)
    {
        String aTmpStr;
        {
            SwRewriter aRewriter;
            aRewriter.AddRule(UNDO_ARG1,
                              String::CreateFromInt32(aRedlines.size()));
            aTmpStr = aRewriter.Apply(String(SW_RES(STR_N_REDLINES)));
        }

        SwRewriter aRewriter;
        aRewriter.AddRule(UNDO_ARG1, aTmpStr);

        pSh->StartUndo(bAccept? UNDO_ACCEPT_REDLINE : UNDO_REJECT_REDLINE,
                       &aRewriter);
    }

    // accept/reject the the redlines in aRedlines. The absolute
    // position may change during the process (e.g. when two redlines
    // are merged in result of another one being deleted), so the
    // position must be resolved late and checked before using it.
    // (cf #102547#)
    ListBoxEntries_t::iterator aEnd = aRedlines.end();
	for( ListBoxEntries_t::iterator aIter = aRedlines.begin();
         aIter != aEnd;
         aIter++ )
    {
        sal_uInt16 nPosition = GetRedlinePos( **aIter );
        if( nPosition != USHRT_MAX )
            (pSh->*FnAccRej)( nPosition );
    }

    // #111827#
    if (aRedlines.size() > 1)
    {
        pSh->EndUndo();
    }

	pSh->EndAction();

    bInhibitActivate = false;
	Activate();

	if( ULONG_MAX != nPos && pTable->GetEntryCount() )
	{
		if( nPos >= pTable->GetEntryCount() )
			nPos = pTable->GetEntryCount() - 1;
		pEntry = pTable->GetEntry( nPos );
		if( !pEntry && nPos-- )
			pEntry = pTable->GetEntry( nPos );
		if( pEntry )
		{
			pTable->Select( pEntry );
			pTable->MakeVisible( pEntry );
			pTable->SetCurEntry(pEntry);
		}
	}
	pTPView->EnableUndo();
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

sal_uInt16 SwRedlineAcceptDlg::GetRedlinePos( const SvLBoxEntry& rEntry ) const
{
	SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
	return pSh->FindRedlineOfData( *((SwRedlineDataParent*)((RedlinData *)
									rEntry.GetUserData())->pData)->pData );
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, AcceptHdl, void*, EMPTYARG)
{
	CallAcceptReject( sal_True, sal_True );
	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, AcceptAllHdl, void*, EMPTYARG )
{
	CallAcceptReject( sal_False, sal_True );
	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, RejectHdl, void*, EMPTYARG )
{
	CallAcceptReject( sal_True, sal_False );
	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, RejectAllHdl, void*, EMPTYARG )
{
	CallAcceptReject( sal_False, sal_False );
	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, UndoHdl, void*, EMPTYARG )
{
	SwView * pView = ::GetActiveView();
	pView->GetViewFrame()->GetDispatcher()->
				Execute(SID_UNDO, SFX_CALLMODE_SYNCHRON);
	pTPView->EnableUndo(pView->GetSlotState(SID_UNDO) != 0);

	Activate();

	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, FilterChangedHdl, void*, EMPTYARG )
{
	SvxTPFilter *pFilterTP = aTabPagesCTRL.GetFilterPage();

	if (pFilterTP->IsAction())
		sFilterAction = pFilterTP->GetLbAction()->GetSelectEntry();
	else
		sFilterAction = aEmptyStr;

	Init();

	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, DeselectHdl, void*, EMPTYARG )
{
	// Flackern der Buttons vermeiden:
	aDeselectTimer.Start();

	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, SelectHdl, void*, EMPTYARG )
{
	aDeselectTimer.Stop();
	aSelectTimer.Start();

	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, GotoHdl, void*, EMPTYARG )
{
	SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
	aSelectTimer.Stop();

	sal_Bool bIsNotFormated = sal_False;
	sal_Bool bSel = sal_False;
//  sal_Bool bReadonlySel = sal_False;

    //#98883# don't select redlines while the dialog is not focussed
    //#107938# But not only ask pTable if it has the focus. To move
    //         the selection to the selected redline any child of pParentDlg
    //         may the focus.
    SvLBoxEntry* pSelEntry = 0;

    if (pParentDlg->HasChildPathFocus())
        pSelEntry = pTable->FirstSelected();

    if( pSelEntry )
	{
		SvLBoxEntry* pActEntry = pSelEntry;
		pSh->StartAction();
		pSh->EnterStdMode();
		pSh->SetCareWin(pParentDlg);

		while (pSelEntry)
		{
			if (pTable->GetParent(pSelEntry))
			{
				pActEntry = pTable->GetParent(pSelEntry);

				if (pTable->IsSelected(pActEntry))
				{
					pSelEntry = pActEntry = pTable->NextSelected(pSelEntry);
					continue;	// Nicht zweimal selektieren
				}
			}
			else
				bSel = sal_True;

			// #98864# find the selected redline (ignore, if the redline is already gone)
			sal_uInt16 nPos = GetRedlinePos(*pActEntry);
			if( nPos != USHRT_MAX )
			{

				const SwRedline& rRedln = pSh->GetRedline( nPos );
				bIsNotFormated |= nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType();

//JP 27.9.2001: make no sense if we handle readonly sections
//			if( !bReadonlySel && rRedln.HasReadonlySel() )
//				bReadonlySel = sal_True;

				if (pSh->GotoRedline(nPos, sal_True))
				{
					pSh->SetInSelect();
					pSh->EnterAddMode();
				}
			}

            pSelEntry = pActEntry = pTable->NextSelected(pSelEntry);
		}

		pSh->LeaveAddMode();
		pSh->EndAction();
		pSh->SetCareWin(NULL);
	}
    sal_Bool bEnable = !pSh->getIDocumentRedlineAccess()->GetRedlinePassword().getLength();
    pTPView->EnableAccept( bEnable && bSel /*&& !bReadonlySel*/ );
    pTPView->EnableReject( bEnable && bSel && bIsNotFormated /*&& !bReadonlySel*/ );
    pTPView->EnableRejectAll( bEnable && !bOnlyFormatedRedlines && !bHasReadonlySel );

	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwRedlineAcceptDlg, CommandHdl, void*, EMPTYARG )
{
	const CommandEvent aCEvt(pTable->GetCommandEvent());

	switch ( aCEvt.GetCommand() )
	{
		case COMMAND_CONTEXTMENU:
		{
			SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
			SvLBoxEntry* pEntry = pTable->FirstSelected();
			const SwRedline *pRed = 0;

			if (pEntry)
			{
				SvLBoxEntry* pTopEntry = pEntry;

				if (pTable->GetParent(pEntry))
					pTopEntry = pTable->GetParent(pEntry);

				sal_uInt16 nPos = GetRedlinePos(*pTopEntry);

				// Bei geschuetzten Bereichen kommentieren disablen
				if ((pRed = pSh->GotoRedline(nPos, sal_True)) != 0)
				{
					if( pSh->IsCrsrPtAtEnd() )
						pSh->SwapPam();
					pSh->SetInSelect();
				}
			}

			aPopup.EnableItem( MN_EDIT_COMMENT, pEntry && pRed &&
											!pTable->GetParent(pEntry) &&
											!pTable->NextSelected(pEntry)
//JP 27.9.2001: make no sense if we handle readonly sections
//											&& pRed->HasReadonlySel()
											);

			aPopup.EnableItem( MN_SUB_SORT, pTable->First() != 0 );
			sal_uInt16 nColumn = pTable->GetSortedCol();
			if (nColumn == 0xffff)
				nColumn = 4;

			PopupMenu *pSubMenu = aPopup.GetPopupMenu(MN_SUB_SORT);
			if (pSubMenu)
			{
				for (sal_uInt16 i = MN_SORT_ACTION; i < MN_SORT_ACTION + 5; i++)
					pSubMenu->CheckItem(i, sal_False);

				pSubMenu->CheckItem(nColumn + MN_SORT_ACTION);
			}

			sal_uInt16 nRet = aPopup.Execute(pTable, aCEvt.GetMousePosPixel());

			switch( nRet )
			{
				case MN_EDIT_COMMENT:
				{
					String sComment;
					if (pEntry)
					{
						if (pTable->GetParent(pEntry))
							pEntry = pTable->GetParent(pEntry);

						sal_uInt16 nPos = GetRedlinePos(*pEntry);
						const SwRedline &rRedline = pSh->GetRedline(nPos);


						/* enable again once we have redline comments in the margin
						sComment = rRedline.GetComment();
						if ( sComment == String(::rtl::OUString::createFromAscii("")) )
							GetActiveView()->GetDocShell()->Broadcast(SwRedlineHint(&rRedline,SWREDLINE_INSERTED));
						const_cast<SwRedline&>(rRedline).Broadcast(SwRedlineHint(&rRedline,SWREDLINE_FOCUS));
						*/

						sComment = rRedline.GetComment();
						SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
                        DBG_ASSERT(pFact, "Dialogdiet fail!");
						::DialogGetRanges fnGetRange = pFact->GetDialogGetRangesFunc( RID_SVXDLG_POSTIT );
                        DBG_ASSERT(fnGetRange, "Dialogdiet fail! GetRanges()");
						SfxItemSet aSet( pSh->GetAttrPool(), fnGetRange() );

						aSet.Put(SvxPostItTextItem(sComment.ConvertLineEnd(), SID_ATTR_POSTIT_TEXT));
						aSet.Put(SvxPostItAuthorItem(rRedline.GetAuthorString(), SID_ATTR_POSTIT_AUTHOR));

						aSet.Put(SvxPostItDateItem( GetAppLangDateTimeString(
									rRedline.GetRedlineData().GetTimeStamp() ),
									SID_ATTR_POSTIT_DATE ));

                        AbstractSvxPostItDialog* pDlg = pFact->CreateSvxPostItDialog( pParentDlg, aSet, sal_False );
                        DBG_ASSERT(pDlg, "Dialogdiet fail!");

						pDlg->HideAuthor();

						sal_uInt16 nResId = 0;
						switch( rRedline.GetType() )
						{
						case nsRedlineType_t::REDLINE_INSERT:
							nResId = STR_REDLINE_INSERTED;
							break;
						case nsRedlineType_t::REDLINE_DELETE:
							nResId = STR_REDLINE_DELETED;
							break;
						case nsRedlineType_t::REDLINE_FORMAT:
							nResId = STR_REDLINE_FORMATED;
							break;
						case nsRedlineType_t::REDLINE_TABLE:
							nResId = STR_REDLINE_TABLECHG;
							break;
                        default:;//prevent warning
						}
						String sTitle(SW_RES(STR_REDLINE_COMMENT));
						if( nResId )
							sTitle += SW_RESSTR( nResId );
						pDlg->SetText(sTitle);

						pSh->SetCareWin(pDlg->GetWindow());

						if ( pDlg->Execute() == RET_OK )
						{
							const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
							String sMsg(((const SvxPostItTextItem&)pOutSet->Get(SID_ATTR_POSTIT_TEXT)).GetValue());

							// Kommentar einfuegen bzw aendern
							pSh->SetRedlineComment(sMsg);
							sMsg.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' ');
							pTable->SetEntryText(sMsg, pEntry, 3);
						}

						delete pDlg;
						pSh->SetCareWin(NULL);
					}

				}
				break;

			case MN_SORT_ACTION:
			case MN_SORT_AUTHOR:
			case MN_SORT_DATE:
			case MN_SORT_COMMENT:
			case MN_SORT_POSITION:
				{
					bSortDir = sal_True;
					if (nRet - MN_SORT_ACTION == 4 && pTable->GetSortedCol() == 0xffff)
						break;	// Haben wir schon

					nSortMode = nRet - MN_SORT_ACTION;
					if (nSortMode == 4)
						nSortMode = 0xffff;	// unsortiert bzw sortiert nach Position

					if (pTable->GetSortedCol() == nSortMode)
						bSortDir = !pTable->GetSortDirection();

					SwWait aWait( *::GetActiveView()->GetDocShell(), sal_False );
					pTable->SortByCol(nSortMode, bSortDir);
					if (nSortMode == 0xffff)
						Init();				// Alles neu fuellen
				}
				break;
			}
		}
		break;
	}

	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

void SwRedlineAcceptDlg::Initialize(const String& rExtraData)
{
	if (rExtraData.Len())
	{
		sal_uInt16 nPos = rExtraData.Search(C2S("AcceptChgDat:"));

		// Versuche, den Alignment-String "ALIGN:(...)" einzulesen; wenn
		// er nicht vorhanden ist, liegt eine "altere Version vor
		if (nPos != STRING_NOTFOUND)
		{
			sal_uInt16 n1 = rExtraData.Search('(', nPos);
			if (n1 != STRING_NOTFOUND)
			{
				sal_uInt16 n2 = rExtraData.Search(')', n1);
				if (n2 != STRING_NOTFOUND)
				{
					// Alignment-String herausschneiden
					String aStr = rExtraData.Copy(nPos, n2 - nPos + 1);
					aStr.Erase(0, n1 - nPos + 1);

					if (aStr.Len())
					{
                        sal_uInt16 nCount = static_cast< sal_uInt16 >(aStr.ToInt32());

						for (sal_uInt16 i = 0; i < nCount; i++)
						{
                            sal_uInt16 n3 = aStr.Search(';');
                            aStr.Erase(0, n3 + 1);
							pTable->SetTab(i, aStr.ToInt32(), MAP_PIXEL);
						}
					}
				}
			}
		}
	}
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

void SwRedlineAcceptDlg::FillInfo(String &rExtraData) const
{
	rExtraData.AppendAscii("AcceptChgDat:(");

	sal_uInt16	nCount = pTable->TabCount();

	rExtraData += String::CreateFromInt32(nCount);
	rExtraData += ';';
	for(sal_uInt16 i = 0; i < nCount; i++)
	{
		rExtraData += String::CreateFromInt32( pTable->GetTab(i) );
		rExtraData += ';';
	}
	rExtraData += ')';
}
