/**************************************************************
 * 
 * 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"

#include <UndoTable.hxx>

#include <UndoRedline.hxx>
#include <UndoDelete.hxx>
#include <UndoSplitMove.hxx>
#include <UndoCore.hxx>
#include <hintids.hxx>
#include <hints.hxx>
#include <editeng/brkitem.hxx>
#include <fmtornt.hxx>
#include <fmtpdsc.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <editsh.hxx>
#include <docary.hxx>
#include <ndtxt.hxx>
#include <swtable.hxx>
#include <pam.hxx>
#include <cntfrm.hxx>
#include <tblsel.hxx>
#include <swundo.hxx>			// fuer die UndoIds
#include <rolbck.hxx>
#include <ddefld.hxx>
#include <tabcol.hxx>
#include <tabfrm.hxx>
#include <rowfrm.hxx>
#include <cellfrm.hxx>
#include <swcache.hxx>
#include <tblafmt.hxx>
#include <poolfmt.hxx>
#include <mvsave.hxx>
#include <cellatr.hxx>
#include <swtblfmt.hxx>
#include <swddetbl.hxx>
#include <redline.hxx>
#include <node2lay.hxx>
#include <tblrwcl.hxx>
#include <fmtanchr.hxx>
#include <comcore.hrc>
#include <unochart.hxx>
#include <switerator.hxx>

#ifndef DBG_UTIL
#define CHECK_TABLE(t)
#else
#ifdef DEBUG
#define CHECK_TABLE(t) (t).CheckConsistency();
#else
#define CHECK_TABLE(t)
#endif
#endif

#ifndef DBG_UTIL
    #define _DEBUG_REDLINE( pDoc )
#else
	void lcl_DebugRedline( const SwDoc* pDoc );
	#define _DEBUG_REDLINE( pDoc ) lcl_DebugRedline( pDoc );
#endif

extern void ClearFEShellTabCols();

typedef SfxItemSet* SfxItemSetPtr;
SV_DECL_PTRARR_DEL( SfxItemSets, SfxItemSetPtr, 10, 5 )

typedef SwUndoSaveSection* SwUndoSaveSectionPtr;
SV_DECL_PTRARR_DEL( SwUndoSaveSections, SwUndoSaveSectionPtr, 0, 10 )

typedef SwUndoMove* SwUndoMovePtr;
SV_DECL_PTRARR_DEL( SwUndoMoves, SwUndoMovePtr, 0, 10 )

struct SwTblToTxtSave;
typedef SwTblToTxtSave* SwTblToTxtSavePtr;
SV_DECL_PTRARR_DEL( SwTblToTxtSaves, SwTblToTxtSavePtr, 0, 10 )

struct _UndoTblCpyTbl_Entry
{
	sal_uLong nBoxIdx, nOffset;
	SfxItemSet* pBoxNumAttr;
	SwUndo* pUndo;

    // Was the last paragraph of the new and the first paragraph of the old content joined?
    bool bJoin; // For redlining only

    _UndoTblCpyTbl_Entry( const SwTableBox& rBox );
	~_UndoTblCpyTbl_Entry();
};
typedef _UndoTblCpyTbl_Entry* _UndoTblCpyTbl_EntryPtr;
SV_DECL_PTRARR_DEL( _UndoTblCpyTbl_Entries, _UndoTblCpyTbl_EntryPtr, 0, 10 )

class _SaveBox;
class _SaveLine;

class _SaveTable
{
	friend class _SaveBox;
	friend class _SaveLine;
	SfxItemSet aTblSet;
	_SaveLine* pLine;
	const SwTable* pSwTable;
	SfxItemSets aSets;
	SwFrmFmts aFrmFmts;
	sal_uInt16 nLineCount;
	sal_Bool bModifyBox : 1;
	sal_Bool bSaveFormula : 1;
    sal_Bool bNewModel : 1;

public:
	_SaveTable( const SwTable& rTbl, sal_uInt16 nLnCnt = USHRT_MAX,
				sal_Bool bSaveFml = sal_True );
	~_SaveTable();

	sal_uInt16 AddFmt( SwFrmFmt* pFmt, bool bIsLine );
	void NewFrmFmt( const SwTableLine* , const SwTableBox*, sal_uInt16 nFmtPos,
					SwFrmFmt* pOldFmt );

	void RestoreAttr( SwTable& rTbl, sal_Bool bModifyBox = sal_False );
	void SaveCntntAttrs( SwDoc* pDoc );
	void CreateNew( SwTable& rTbl, sal_Bool bCreateFrms = sal_True,
					sal_Bool bRestoreChart = sal_True );
    sal_Bool IsNewModel() const { return bNewModel; }
};

class _SaveLine
{
	friend class _SaveTable;
	friend class _SaveBox;

	_SaveLine* pNext;
	_SaveBox* pBox;
	sal_uInt16 nItemSet;

public:

	_SaveLine( _SaveLine* pPrev, const SwTableLine& rLine, _SaveTable& rSTbl );
	~_SaveLine();

	void RestoreAttr( SwTableLine& rLine, _SaveTable& rSTbl );
	void SaveCntntAttrs( SwDoc* pDoc );

	void CreateNew( SwTable& rTbl, SwTableBox& rParent, _SaveTable& rSTbl  );
};

class _SaveBox
{
	friend class _SaveLine;

	_SaveBox* pNext;
	sal_uLong nSttNode;
    long nRowSpan;
	sal_uInt16 nItemSet;
	union
	{
		SfxItemSets* pCntntAttrs;
		_SaveLine* pLine;
	} Ptrs;

public:
	_SaveBox( _SaveBox* pPrev, const SwTableBox& rBox, _SaveTable& rSTbl );
	~_SaveBox();

	void RestoreAttr( SwTableBox& rBox, _SaveTable& rSTbl );
	void SaveCntntAttrs( SwDoc* pDoc );

	void CreateNew( SwTable& rTbl, SwTableLine& rParent, _SaveTable& rSTbl );
};

void InsertSort( SvUShorts& rArr, sal_uInt16 nIdx, sal_uInt16* pInsPos = 0 );
void InsertSort( SvULongs& rArr, sal_uLong nIdx, sal_uInt16* pInsPos = 0 );

#if defined( JP_DEBUG ) && defined(DBG_UTIL)
#include "shellio.hxx"
void DumpDoc( SwDoc* pDoc, const String& rFileNm );
void CheckTable( const SwTable& );
#define DUMPDOC(p,s)	DumpDoc( p, s);
#define CHECKTABLE(t) CheckTable( t );
#else
#define DUMPDOC(p,s)
#define CHECKTABLE(t)
#endif

/* #130880: Crash in undo of table to text when the table has (freshly) merged cells
The order of cell content nodes in the nodes array is not given by the recursive table structure.
The algorithmn must not rely on this even it holds for a fresh loaded table in odt file format.
So we need to remember not only the start node position but the end node position as well.
*/

struct SwTblToTxtSave
{
    sal_uLong m_nSttNd;
    sal_uLong m_nEndNd;
    xub_StrLen m_nCntnt;
    SwHistory* m_pHstry;
    // metadata references for first and last paragraph in cell
    ::boost::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoStart;
    ::boost::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoEnd;

    SwTblToTxtSave( SwDoc& rDoc, sal_uLong nNd, sal_uLong nEndIdx, xub_StrLen nCntnt );
    ~SwTblToTxtSave() { delete m_pHstry; }
};

SV_IMPL_PTRARR( SfxItemSets, SfxItemSetPtr )
SV_IMPL_PTRARR( SwUndoSaveSections, SwUndoSaveSectionPtr )
SV_IMPL_PTRARR( SwUndoMoves, SwUndoMovePtr )
SV_IMPL_PTRARR( SwTblToTxtSaves, SwTblToTxtSavePtr )
SV_IMPL_PTRARR( _UndoTblCpyTbl_Entries, _UndoTblCpyTbl_EntryPtr )

sal_uInt16 __FAR_DATA aSave_BoxCntntSet[] = {
	RES_CHRATR_COLOR, RES_CHRATR_CROSSEDOUT,
	RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
	RES_CHRATR_POSTURE,	RES_CHRATR_POSTURE,
	RES_CHRATR_SHADOWED, RES_CHRATR_WEIGHT,
	RES_PARATR_ADJUST, RES_PARATR_ADJUST,
	0 };



SwUndoInsTbl::SwUndoInsTbl( const SwPosition& rPos, sal_uInt16 nCl, sal_uInt16 nRw,
                            sal_uInt16 nAdj, const SwInsertTableOptions& rInsTblOpts,
							const SwTableAutoFmt* pTAFmt,
							const SvUShorts* pColArr,
                            const String & rName)
	: SwUndo( UNDO_INSTABLE ),
    aInsTblOpts( rInsTblOpts ), pDDEFldType( 0 ), pColWidth( 0 ), pRedlData( 0 ), pAutoFmt( 0 ),
	nSttNode( rPos.nNode.GetIndex() ), nRows( nRw ), nCols( nCl ), nAdjust( nAdj )
{
	if( pColArr )
	{
		pColWidth = new SvUShorts( 0, 1 );
		pColWidth->Insert( pColArr, 0 );
	}
	if( pTAFmt )
		pAutoFmt = new SwTableAutoFmt( *pTAFmt );

	// Redline beachten
	SwDoc& rDoc = *rPos.nNode.GetNode().GetDoc();
	if( rDoc.IsRedlineOn() )
	{
		pRedlData = new SwRedlineData( nsRedlineType_t::REDLINE_INSERT, rDoc.GetRedlineAuthor() );
		SetRedlineMode( rDoc.GetRedlineMode() );
	}

	sTblNm = rName;
}


SwUndoInsTbl::~SwUndoInsTbl()
{
	delete pDDEFldType;
	delete pColWidth;
	delete pRedlData;
	delete pAutoFmt;
}

void SwUndoInsTbl::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
	SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );

	SwTableNode* pTblNd = aIdx.GetNode().GetTableNode();
	ASSERT( pTblNd, "kein TabellenNode" );
	pTblNd->DelFrms();

	if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
		rDoc.DeleteRedline( *pTblNd, true, USHRT_MAX );
	RemoveIdxFromSection( rDoc, nSttNode );

	// harte SeitenUmbrueche am nachfolgenden Node verschieben
	SwCntntNode* pNextNd = rDoc.GetNodes()[ pTblNd->EndOfSectionIndex()+1 ]->GetCntntNode();
	if( pNextNd )
	{
		SwFrmFmt* pTableFmt = pTblNd->GetTable().GetFrmFmt();
		const SfxPoolItem *pItem;

		if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
			sal_False, &pItem ) )
			pNextNd->SetAttr( *pItem );

		if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
			sal_False, &pItem ) )
			pNextNd->SetAttr( *pItem );
	}


	sTblNm = pTblNd->GetTable().GetFrmFmt()->GetName();
	if( dynamic_cast< SwDDETable* >(&pTblNd->GetTable()))
		pDDEFldType = (SwDDEFieldType*)((SwDDETable&)pTblNd->GetTable()).
										GetDDEFldType()->Copy();

	rDoc.GetNodes().Delete( aIdx, pTblNd->EndOfSectionIndex() -
								aIdx.GetIndex() + 1 );

    SwPaM & rPam( rContext.GetCursorSupplier().CreateNewShellCursor() );
    rPam.DeleteMark();
    rPam.GetPoint()->nNode = aIdx;
    rPam.GetPoint()->nContent.Assign( rPam.GetCntntNode(), 0 );
}


void SwUndoInsTbl::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();

    SwPosition const aPos(SwNodeIndex(rDoc.GetNodes(), nSttNode));
    const SwTable* pTbl = rDoc.InsertTable( aInsTblOpts, aPos, nRows, nCols,
                                            nAdjust,
                                            pAutoFmt, pColWidth );
	((SwFrmFmt*)pTbl->GetFrmFmt())->SetName( sTblNm );
	SwTableNode* pTblNode = (SwTableNode*)rDoc.GetNodes()[nSttNode]->GetTableNode();

	if( pDDEFldType )
	{
		SwDDEFieldType* pNewType = (SwDDEFieldType*)rDoc.InsertFldType(
															*pDDEFldType);
		SwDDETable* pDDETbl = new SwDDETable( pTblNode->GetTable(), pNewType );
		pTblNode->SetNewTable( pDDETbl );		// setze die DDE-Tabelle
		delete pDDEFldType, pDDEFldType = 0;
	}

	if( (pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) ||
		( !( nsRedlineMode_t::REDLINE_IGNORE & GetRedlineMode() ) &&
			rDoc.GetRedlineTbl().Count() ))
	{
		SwPaM aPam( *pTblNode->EndOfSectionNode(), *pTblNode, 1 );
		SwCntntNode* pCNd = aPam.GetCntntNode( sal_False );
		if( pCNd )
			aPam.GetMark()->nContent.Assign( pCNd, 0 );

		if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
		{
			RedlineMode_t eOld = rDoc.GetRedlineMode();
			rDoc.SetRedlineMode_intern((RedlineMode_t)(eOld & ~nsRedlineMode_t::REDLINE_IGNORE));

			rDoc.AppendRedline( new SwRedline( *pRedlData, aPam ), true);
			rDoc.SetRedlineMode_intern( eOld );
		}
		else
			rDoc.SplitRedline( aPam );
	}
}


void SwUndoInsTbl::RepeatImpl(::sw::RepeatContext & rContext)
{
    rContext.GetDoc().InsertTable(
            aInsTblOpts, *rContext.GetRepeatPaM().GetPoint(),
            nRows, nCols, nAdjust, pAutoFmt, pColWidth );
}

SwRewriter SwUndoInsTbl::GetRewriter() const
{
    SwRewriter aRewriter;

    aRewriter.AddRule(UNDO_ARG1, SW_RES(STR_START_QUOTE));
    aRewriter.AddRule(UNDO_ARG2, sTblNm);
    aRewriter.AddRule(UNDO_ARG3, SW_RES(STR_END_QUOTE));

    return aRewriter;
}

// -----------------------------------------------------

SwTblToTxtSave::SwTblToTxtSave( SwDoc& rDoc, sal_uLong nNd, sal_uLong nEndIdx, xub_StrLen nCnt )
    : m_nSttNd( nNd ), m_nEndNd( nEndIdx), m_nCntnt( nCnt ), m_pHstry( 0 )
{
	// Attributierung des gejointen Node merken.
	SwTxtNode* pNd = rDoc.GetNodes()[ nNd ]->GetTxtNode();
	if( pNd )
	{
		m_pHstry = new SwHistory;

		m_pHstry->Add( pNd->GetTxtColl(), nNd, ND_TEXTNODE );
        if ( pNd->GetpSwpHints() )
        {
            m_pHstry->CopyAttr( pNd->GetpSwpHints(), nNd, 0,
                        pNd->GetTxt().Len(), false );
        }
        if( pNd->HasSwAttrSet() )
            m_pHstry->CopyFmtAttr( *pNd->GetpSwAttrSet(), nNd );

		if( !m_pHstry->Count() )
			delete m_pHstry, m_pHstry = 0;

        // METADATA: store
        m_pMetadataUndoStart = pNd->CreateUndo();
    }

    // we also need to store the metadata reference of the _last_ paragraph
    // we subtract 1 to account for the removed cell start/end node pair
    // (after SectionUp, the end of the range points to the node after the cell)
    if ( nEndIdx - 1 > nNd )
    {
        SwTxtNode* pLastNode( rDoc.GetNodes()[ nEndIdx - 1 ]->GetTxtNode() );
        if( pLastNode )
        {
            // METADATA: store
            m_pMetadataUndoEnd = pLastNode->CreateUndo();
        }
    }
}

SwUndoTblToTxt::SwUndoTblToTxt( const SwTable& rTbl, sal_Unicode cCh )
    : SwUndo( UNDO_TABLETOTEXT ),
    sTblNm( rTbl.GetFrmFmt()->GetName() ), pDDEFldType( 0 ), pHistory( 0 ),
	nSttNd( 0 ), nEndNd( 0 ),
    nAdjust( static_cast<sal_uInt16>(rTbl.GetFrmFmt()->GetHoriOrient().GetHoriOrient()) ),
	cTrenner( cCh ), nHdlnRpt( rTbl.GetRowsToRepeat() )
{
	pTblSave = new _SaveTable( rTbl );
	pBoxSaves = new SwTblToTxtSaves( (sal_uInt8)rTbl.GetTabSortBoxes().Count() );

	if( dynamic_cast< const SwDDETable* >(&rTbl) )
		pDDEFldType = (SwDDEFieldType*)((SwDDETable&)rTbl).GetDDEFldType()->Copy();

	bCheckNumFmt = rTbl.GetFrmFmt()->GetDoc()->IsInsTblFormatNum();

	pHistory = new SwHistory;
	const SwTableNode* pTblNd = rTbl.GetTableNode();
	sal_uLong nTblStt = pTblNd->GetIndex(), nTblEnd = pTblNd->EndOfSectionIndex();

	const SwSpzFrmFmts& rFrmFmtTbl = *pTblNd->GetDoc()->GetSpzFrmFmts();
	for( sal_uInt16 n = 0; n < rFrmFmtTbl.Count(); ++n )
	{
        SwFrmFmt* pFmt = rFrmFmtTbl[ n ];
        SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
        SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
        if (pAPos &&
            ((FLY_AT_CHAR == pAnchor->GetAnchorId()) ||
             (FLY_AT_PARA == pAnchor->GetAnchorId())) &&
			nTblStt <= pAPos->nNode.GetIndex() &&
			pAPos->nNode.GetIndex() < nTblEnd )
		{
			pHistory->Add( *pFmt );
		}
	}

	if( !pHistory->Count() )
		delete pHistory, pHistory = 0;
}


SwUndoTblToTxt::~SwUndoTblToTxt()
{
	delete pDDEFldType;
	delete pTblSave;
	delete pBoxSaves;
	delete pHistory;
}



void SwUndoTblToTxt::UndoImpl(::sw::UndoRedoContext & rContext)
{
	SwDoc & rDoc = rContext.GetDoc();
    SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());

	SwNodeIndex aFrmIdx( rDoc.GetNodes(), nSttNd );
	SwNodeIndex aEndIdx( rDoc.GetNodes(), nEndNd );

	pPam->GetPoint()->nNode = aFrmIdx;
	pPam->SetMark();
	pPam->GetPoint()->nNode = aEndIdx;
	rDoc.DelNumRules( *pPam );
	pPam->DeleteMark();

	// dann sammel mal alle Uppers ein
	SwNode2Layout aNode2Layout( aFrmIdx.GetNode() );

	// erzeuge die TabelleNode Structur
	SwTableNode* pTblNd = rDoc.GetNodes().UndoTableToText( nSttNd, nEndNd, *pBoxSaves );
    pTblNd->GetTable().SetTableModel( pTblSave->IsNewModel() );
	SwTableFmt* pTableFmt = rDoc.MakeTblFrmFmt( sTblNm, rDoc.GetDfltFrmFmt() );
    pTblNd->GetTable().RegisterToFormat( *pTableFmt );
    pTblNd->GetTable().SetRowsToRepeat( nHdlnRpt );

	// erzeuge die alte Tabellen Struktur
	pTblSave->CreateNew( pTblNd->GetTable() );

	if( pDDEFldType )
	{
		SwDDEFieldType* pNewType = (SwDDEFieldType*)rDoc.InsertFldType(
															*pDDEFldType);
		SwDDETable* pDDETbl = new SwDDETable( pTblNd->GetTable(), pNewType );
		pTblNd->SetNewTable( pDDETbl, sal_False );		// setze die DDE-Tabelle
		delete pDDEFldType, pDDEFldType = 0;
	}

	if( bCheckNumFmt )
	{
		SwTableSortBoxes& rBxs = pTblNd->GetTable().GetTabSortBoxes();
		for( sal_uInt16 nBoxes = rBxs.Count(); nBoxes; )
			rDoc.ChkBoxNumFmt( *rBxs[ --nBoxes ], sal_False );
	}

	if( pHistory )
	{
		sal_uInt16 nTmpEnd = pHistory->GetTmpEnd();
		pHistory->TmpRollback( &rDoc, 0 );
		pHistory->SetTmpEnd( nTmpEnd );
	}

	aNode2Layout.RestoreUpperFrms( rDoc.GetNodes(),
								   pTblNd->GetIndex(), pTblNd->GetIndex()+1 );

	// will man eine TabellenSelektion ??
	pPam->DeleteMark();
	pPam->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
	pPam->SetMark();
	pPam->GetPoint()->nNode = *pPam->GetNode()->StartOfSectionNode();
	pPam->Move( fnMoveForward, fnGoCntnt );
	pPam->Exchange();
	pPam->Move( fnMoveBackward, fnGoCntnt );

	ClearFEShellTabCols();
}

	// steht im untbl.cxx und darf nur vom Undoobject gerufen werden
SwTableNode* SwNodes::UndoTableToText( sal_uLong nSttNd, sal_uLong nEndNd,
								const SwTblToTxtSaves& rSavedData )
{
	SwNodeIndex aSttIdx( *this, nSttNd );
	SwNodeIndex aEndIdx( *this, nEndNd+1 );

	SwTableNode * pTblNd = new SwTableNode( aSttIdx );
	SwEndNode* pEndNd = new SwEndNode( aEndIdx, *pTblNd  );

	aEndIdx = *pEndNd;

	/* Set pTblNd as start of section for all nodes in [nSttNd, nEndNd].
       Delete all Frames attached to the nodes in that range. */
	SwNode* pNd;
	{
		sal_uLong n, nTmpEnd = aEndIdx.GetIndex();
		for( n = pTblNd->GetIndex() + 1; n < nTmpEnd; ++n )
        {
			if( ( pNd = (*this)[ n ] )->IsCntntNode() )
				((SwCntntNode*)pNd)->DelFrms();
            pNd->pStartOfSection = pTblNd;
        }
	}

	// dann die Tabellen Struktur teilweise aufbauen. Erstmal eine Line
	// in der alle Boxen stehen! Die korrekte Struktur kommt dann aus der
	// SaveStruct
	SwTableBoxFmt* pBoxFmt = GetDoc()->MakeTableBoxFmt();
	SwTableLineFmt* pLineFmt = GetDoc()->MakeTableLineFmt();
	SwTableLine* pLine = new SwTableLine( pLineFmt, rSavedData.Count(), 0 );
	pTblNd->GetTable().GetTabLines().C40_INSERT( SwTableLine, pLine, 0 );

	SvULongs aBkmkArr( 0, 4 );
	for( sal_uInt16 n = rSavedData.Count(); n; )
	{
		SwTblToTxtSave* pSave = rSavedData[ --n ];
        // if the start node was merged with last from prev. cell,
        // subtract 1 from index to get the merged paragraph, and split that
		aSttIdx = pSave->m_nSttNd - ( ( USHRT_MAX != pSave->m_nCntnt ) ? 1 : 0);
		SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode();

		if( USHRT_MAX != pSave->m_nCntnt )
		{
			// an der ContentPosition splitten, das vorherige Zeichen
			// loeschen (ist der Trenner!)
			ASSERT( pTxtNd, "Wo ist der TextNode geblieben?" );
			SwIndex aCntPos( pTxtNd, pSave->m_nCntnt - 1 );

            pTxtNd->EraseText( aCntPos, 1 );
            SwCntntNode* pNewNd = pTxtNd->SplitCntntNode(
										SwPosition( aSttIdx, aCntPos ));
			if( aBkmkArr.Count() )
				_RestoreCntntIdx( aBkmkArr, *pNewNd, pSave->m_nCntnt,
													 pSave->m_nCntnt + 1 );
		}
		else
		{
			if( aBkmkArr.Count() )
				aBkmkArr.Remove( 0, aBkmkArr.Count() );
			if( pTxtNd )
				_SaveCntntIdx( GetDoc(), aSttIdx.GetIndex(),
								pTxtNd->GetTxt().Len(), aBkmkArr );
		}

		if( pTxtNd )
		{
            // METADATA: restore
            pTxtNd->GetTxtNode()->RestoreMetadata(pSave->m_pMetadataUndoStart);
            if( pTxtNd->HasSwAttrSet() )
				pTxtNd->ResetAllAttr();

			if( pTxtNd->GetpSwpHints() )
                pTxtNd->ClearSwpHintsArr( false );
		}

        if( pSave->m_pHstry )
        {
            sal_uInt16 nTmpEnd = pSave->m_pHstry->GetTmpEnd();
            pSave->m_pHstry->TmpRollback( GetDoc(), 0 );
            pSave->m_pHstry->SetTmpEnd( nTmpEnd );
        }

        // METADATA: restore
        // end points to node after cell
        if ( pSave->m_nEndNd - 1 > pSave->m_nSttNd )
        {
            SwTxtNode* pLastNode = (*this)[ pSave->m_nEndNd - 1 ]->GetTxtNode();
            if (pLastNode)
            {
                pLastNode->RestoreMetadata(pSave->m_pMetadataUndoEnd);
            }
        }

        aEndIdx = pSave->m_nEndNd;
		SwStartNode* pSttNd = new SwStartNode( aSttIdx, ND_STARTNODE,
												SwTableBoxStartNode );
		pSttNd->pStartOfSection = pTblNd;
		new SwEndNode( aEndIdx, *pSttNd );

		for( sal_uLong i = aSttIdx.GetIndex(); i < aEndIdx.GetIndex()-1; ++i )
		{
			pNd = (*this)[ i ];
			pNd->pStartOfSection = pSttNd;
			if( pNd->IsStartNode() )
				i = pNd->EndOfSectionIndex();
		}

		SwTableBox* pBox = new SwTableBox( pBoxFmt, *pSttNd, pLine );
		pLine->GetTabBoxes().C40_INSERT( SwTableBox, pBox, 0 );
	}
	return pTblNd;
}


void SwUndoTblToTxt::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
    SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());

	pPam->GetPoint()->nNode = nSttNd;
	pPam->GetPoint()->nContent.Assign( 0, 0 );
	SwNodeIndex aSaveIdx( pPam->GetPoint()->nNode, -1 );

	pPam->SetMark();            // alle Indizies abmelden
	pPam->DeleteMark();

	SwTableNode* pTblNd = pPam->GetNode()->GetTableNode();
	ASSERT( pTblNd, "keinen TableNode gefunden" );

	if( dynamic_cast< SwDDETable* >(&pTblNd->GetTable()) )
		pDDEFldType = (SwDDEFieldType*)((SwDDETable&)pTblNd->GetTable()).
												GetDDEFldType()->Copy();

	rDoc.TableToText( pTblNd, cTrenner );

	aSaveIdx++;
	SwCntntNode* pCNd = aSaveIdx.GetNode().GetCntntNode();
	if( !pCNd && 0 == ( pCNd = rDoc.GetNodes().GoNext( &aSaveIdx ) ) &&
		0 == ( pCNd = rDoc.GetNodes().GoPrevious( &aSaveIdx )) )
    {
		ASSERT( sal_False, "wo steht denn nun der TextNode" );
    }

	pPam->GetPoint()->nNode = aSaveIdx;
	pPam->GetPoint()->nContent.Assign( pCNd, 0 );

	pPam->SetMark();            // alle Indizies abmelden
	pPam->DeleteMark();
}


void SwUndoTblToTxt::RepeatImpl(::sw::RepeatContext & rContext)
{
    SwPaM *const pPam = & rContext.GetRepeatPaM();
    SwTableNode *const pTblNd = pPam->GetNode()->FindTableNode();
	if( pTblNd )
    {
        // move cursor out of table
		pPam->GetPoint()->nNode = *pTblNd->EndOfSectionNode();
		pPam->Move( fnMoveForward, fnGoCntnt );
		pPam->SetMark();
		pPam->DeleteMark();

        rContext.GetDoc().TableToText( pTblNd, cTrenner );
    }
}

void SwUndoTblToTxt::SetRange( const SwNodeRange& rRg )
{
	nSttNd = rRg.aStart.GetIndex();
	nEndNd = rRg.aEnd.GetIndex();
}

void SwUndoTblToTxt::AddBoxPos( SwDoc& rDoc, sal_uLong nNdIdx, sal_uLong nEndIdx, xub_StrLen nCntntIdx )
{
	SwTblToTxtSave* pNew = new SwTblToTxtSave( rDoc, nNdIdx, nEndIdx, nCntntIdx );
	pBoxSaves->Insert( pNew, pBoxSaves->Count() );
}

// -----------------------------------------------------

SwUndoTxtToTbl::SwUndoTxtToTbl( const SwPaM& rRg,
                                const SwInsertTableOptions& rInsTblOpts,
                                sal_Unicode cCh, sal_uInt16 nAdj,
                                const SwTableAutoFmt* pAFmt )
    : SwUndo( UNDO_TEXTTOTABLE ), SwUndRng( rRg ), aInsTblOpts( rInsTblOpts ),
      pDelBoxes( 0 ), pAutoFmt( 0 ),
      pHistory( 0 ), cTrenner( cCh ), nAdjust( nAdj )
{
	if( pAFmt )
		pAutoFmt = new SwTableAutoFmt( *pAFmt );

	const SwPosition* pEnd = rRg.End();
	SwNodes& rNds = rRg.GetDoc()->GetNodes();
	bSplitEnd = pEnd->nContent.GetIndex() && ( pEnd->nContent.GetIndex()
						!= pEnd->nNode.GetNode().GetCntntNode()->Len() ||
				pEnd->nNode.GetIndex() >= rNds.GetEndOfContent().GetIndex()-1 );
}

SwUndoTxtToTbl::~SwUndoTxtToTbl()
{
	delete pDelBoxes;
	delete pAutoFmt;
}

void SwUndoTxtToTbl::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();

	sal_uLong nTblNd = nSttNode;
	if( nSttCntnt )
		++nTblNd;		// Node wurde vorher gesplittet
	SwNodeIndex aIdx( rDoc.GetNodes(), nTblNd );
    SwTableNode *const pTNd = aIdx.GetNode().GetTableNode();
    OSL_ENSURE( pTNd, "SwUndoTxtToTbl: no TableNode" );

	RemoveIdxFromSection( rDoc, nTblNd );

	sTblNm = pTNd->GetTable().GetFrmFmt()->GetName();

	if( pHistory )
	{
		pHistory->TmpRollback( &rDoc, 0 );
		pHistory->SetTmpEnd( pHistory->Count() );
	}

	if( pDelBoxes )
	{
		SwTable& rTbl = pTNd->GetTable();
		for( sal_uInt16 n = pDelBoxes->Count(); n; )
		{
			SwTableBox* pBox = rTbl.GetTblBox( (*pDelBoxes)[ --n ] );
			if( pBox )
				::_DeleteBox( rTbl, pBox, 0, sal_False, sal_False );
			else {
				ASSERT( !this, "Wo ist die Box geblieben?" );
            }
		}
	}

	SwNodeIndex aEndIdx( *pTNd->EndOfSectionNode() );
	rDoc.TableToText( pTNd, 0x0b == cTrenner ? 0x09 : cTrenner );

    // join again at start?
    SwPaM aPam(rDoc.GetNodes().GetEndOfContent());
    SwPosition *const pPos = aPam.GetPoint();
	if( nSttCntnt )
	{
		pPos->nNode = nTblNd;
        pPos->nContent.Assign(pPos->nNode.GetNode().GetCntntNode(), 0);
        if (aPam.Move(fnMoveBackward, fnGoCntnt))
        {
            SwNodeIndex & rIdx = aPam.GetPoint()->nNode;

			// dann die Crsr/etc. nochmal relativ verschieben
			RemoveIdxRel( rIdx.GetIndex()+1, *pPos );

			rIdx.GetNode().GetCntntNode()->JoinNext();
		}
	}

    // join again at end?
	if( bSplitEnd )
	{
		SwNodeIndex& rIdx = pPos->nNode;
		rIdx = nEndNode;
		SwTxtNode* pTxtNd = rIdx.GetNode().GetTxtNode();
		if( pTxtNd && pTxtNd->CanJoinNext() )
        {
            aPam.GetMark()->nContent.Assign( 0, 0 );
            aPam.GetPoint()->nContent.Assign( 0, 0 );

			// dann die Crsr/etc. nochmal relativ verschieben
			pPos->nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
			RemoveIdxRel( nEndNode + 1, *pPos );

			pTxtNd->JoinNext();
		}
	}

    AddUndoRedoPaM(rContext);
}


void SwUndoTxtToTbl::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwPaM & rPam( AddUndoRedoPaM(rContext) );
    RemoveIdxFromRange(rPam, false);
    SetPaM(rPam);

    SwTable const*const pTable = rContext.GetDoc().TextToTable(
                aInsTblOpts, rPam, cTrenner, nAdjust, pAutoFmt );
	((SwFrmFmt*)pTable->GetFrmFmt())->SetName( sTblNm );
}


void SwUndoTxtToTbl::RepeatImpl(::sw::RepeatContext & rContext)
{
    // no Table In Table
    if (!rContext.GetRepeatPaM().GetNode()->FindTableNode())
    {
        rContext.GetDoc().TextToTable( aInsTblOpts, rContext.GetRepeatPaM(),
                                        cTrenner, nAdjust,
                                        pAutoFmt );
    }
}

void SwUndoTxtToTbl::AddFillBox( const SwTableBox& rBox )
{
	if( !pDelBoxes )
		pDelBoxes = new SvULongs;
	pDelBoxes->Insert( rBox.GetSttIdx(), pDelBoxes->Count() );
}

SwHistory& SwUndoTxtToTbl::GetHistory()
{
	if( !pHistory )
		pHistory = new SwHistory;
	return *pHistory;
}

// -----------------------------------------------------

SwUndoTblHeadline::SwUndoTblHeadline( const SwTable& rTbl, sal_uInt16 nOldHdl,
                                      sal_uInt16 nNewHdl )
	: SwUndo( UNDO_TABLEHEADLINE ),
    nOldHeadline( nOldHdl ),
    nNewHeadline( nNewHdl )
{
	ASSERT( rTbl.GetTabSortBoxes().Count(), "Tabelle ohne Inhalt" );
	const SwStartNode *pSttNd = rTbl.GetTabSortBoxes()[ 0 ]->GetSttNd();
	ASSERT( pSttNd, "Box ohne Inhalt" );

	nTblNd = pSttNd->StartOfSectionIndex();
}

void SwUndoTblHeadline::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
	SwTableNode* pTNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
	ASSERT( pTNd, "keinen Tabellen-Node gefunden" );

    rDoc.SetRowsToRepeat( pTNd->GetTable(), nOldHeadline );
}

void SwUndoTblHeadline::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();

	SwTableNode* pTNd = rDoc.GetNodes()[ nTblNd ]->GetTableNode();
	ASSERT( pTNd, "keinen Tabellen-Node gefunden" );

    rDoc.SetRowsToRepeat( pTNd->GetTable(), nNewHeadline );
}

void SwUndoTblHeadline::RepeatImpl(::sw::RepeatContext & rContext)
{
    SwTableNode *const pTblNd =
        rContext.GetRepeatPaM().GetNode()->FindTableNode();
	if( pTblNd )
    {
        rContext.GetDoc().SetRowsToRepeat( pTblNd->GetTable(), nNewHeadline );
    }
}


//////////////////////////////////////////////////////////////////////////


_SaveTable::_SaveTable( const SwTable& rTbl, sal_uInt16 nLnCnt, sal_Bool bSaveFml )
	: aTblSet( *rTbl.GetFrmFmt()->GetAttrSet().GetPool(), aTableSetRange ),
	pSwTable( &rTbl ), nLineCount( nLnCnt ), bSaveFormula( bSaveFml )
{
	bModifyBox = sal_False;
    bNewModel = rTbl.IsNewModel();
	aTblSet.Put( rTbl.GetFrmFmt()->GetAttrSet() );
	pLine = new _SaveLine( 0, *rTbl.GetTabLines()[ 0 ], *this );

	_SaveLine* pLn = pLine;
	if( USHRT_MAX == nLnCnt )
		nLnCnt = rTbl.GetTabLines().Count();
	for( sal_uInt16 n = 1; n < nLnCnt; ++n )
		pLn = new _SaveLine( pLn, *rTbl.GetTabLines()[ n ], *this );

	aFrmFmts.Remove( 0, aFrmFmts.Count() );
	pSwTable = 0;
}


_SaveTable::~_SaveTable()
{
	delete pLine;
}


sal_uInt16 _SaveTable::AddFmt( SwFrmFmt* pFmt, bool bIsLine )
{
	sal_uInt16 nRet = aFrmFmts.GetPos( pFmt );
	if( USHRT_MAX == nRet )
	{
		// Kopie vom ItemSet anlegen
		SfxItemSet* pSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
            bIsLine ? aTableLineSetRange : aTableBoxSetRange );
		pSet->Put( pFmt->GetAttrSet() );
		//JP 20.04.98: Bug 49502 - wenn eine Formel gesetzt ist, nie den
		//				Value mit sichern. Der muss gegebenfalls neu
		//				errechnet werden!
		//JP 30.07.98: Bug 54295 - Formeln immer im Klartext speichern
		const SfxPoolItem* pItem;
		if( SFX_ITEM_SET == pSet->GetItemState( RES_BOXATR_FORMULA, sal_True, &pItem ))
		{
			pSet->ClearItem( RES_BOXATR_VALUE );
			if( pSwTable && bSaveFormula )
			{
				SwTableFmlUpdate aMsgHnt( pSwTable );
				aMsgHnt.eFlags = TBL_BOXNAME;
				((SwTblBoxFormula*)pItem)->ChgDefinedIn( pFmt );
				((SwTblBoxFormula*)pItem)->ChangeState( &aMsgHnt );
				((SwTblBoxFormula*)pItem)->ChgDefinedIn( 0 );
			}
		}
		aSets.Insert( pSet, (nRet = aSets.Count() ) );
		aFrmFmts.Insert( pFmt, nRet );
	}
	return nRet;
}


void _SaveTable::RestoreAttr( SwTable& rTbl, sal_Bool bMdfyBox )
{
	sal_uInt16 n;

	bModifyBox = bMdfyBox;

	// zuerst die Attribute des TabellenFrmFormates zurueck holen
	SwFrmFmt* pFmt = rTbl.GetFrmFmt();
	SfxItemSet& rFmtSet  = (SfxItemSet&)pFmt->GetAttrSet();
	rFmtSet.ClearItem();
	rFmtSet.Put( aTblSet );

	if( pFmt->IsInCache() )
	{
		SwFrm::GetCache().Delete( pFmt );
		pFmt->SetInCache( sal_False );
	}

	// zur Sicherheit alle Tableframes invalidieren
	SwIterator<SwTabFrm,SwFmt> aIter( *pFmt );
	for( SwTabFrm* pLast = aIter.First(); pLast; pLast = aIter.Next() )
		if( pLast->GetTable() == &rTbl )
		{
			pLast->InvalidateAll();
			pLast->SetCompletePaint();
		}

	// FrmFmts mit Defaults (0) fuellen
	pFmt = 0;
	for( n = aSets.Count(); n; --n )
		aFrmFmts.Insert( pFmt, aFrmFmts.Count() );

	sal_uInt16 nLnCnt = nLineCount;
	if( USHRT_MAX == nLnCnt )
		nLnCnt = rTbl.GetTabLines().Count();

	_SaveLine* pLn = pLine;
	for( n = 0; n < nLnCnt; ++n, pLn = pLn->pNext )
	{
		if( !pLn )
		{
			ASSERT( !this, "Anzahl der Lines hat sich veraendert" );
			break;
		}

		pLn->RestoreAttr( *rTbl.GetTabLines()[ n ], *this );
	}

	aFrmFmts.Remove( 0, aFrmFmts.Count() );
	bModifyBox = sal_False;
}


void _SaveTable::SaveCntntAttrs( SwDoc* pDoc )
{
	pLine->SaveCntntAttrs( pDoc );
}


void _SaveTable::CreateNew( SwTable& rTbl, sal_Bool bCreateFrms,
							sal_Bool bRestoreChart )
{
	sal_uInt16 n;

	_FndBox aTmpBox( 0, 0 );
	//if( bRestoreChart )
    //    // ? TL_CHART2: notification or locking of controller required ?
	aTmpBox.DelFrms( rTbl );

    // zuerst die Attribute des TabellenFrmFormates zurueck holen
	SwFrmFmt* pFmt = rTbl.GetFrmFmt();
	SfxItemSet& rFmtSet  = (SfxItemSet&)pFmt->GetAttrSet();
	rFmtSet.ClearItem();
	rFmtSet.Put( aTblSet );

	if( pFmt->IsInCache() )
	{
		SwFrm::GetCache().Delete( pFmt );
		pFmt->SetInCache( sal_False );
	}

	// SwTableBox muss ein Format haben!!
	SwTableBox aParent( (SwTableBoxFmt*)pFmt, rTbl.GetTabLines().Count(), 0 );

	// FrmFmts mit Defaults (0) fuellen
	pFmt = 0;
	for( n = aSets.Count(); n; --n )
		aFrmFmts.Insert( pFmt, aFrmFmts.Count() );

	pLine->CreateNew( rTbl, aParent, *this );
	aFrmFmts.Remove( 0, aFrmFmts.Count() );

	// die neuen Lines eintragen, die alten loeschen
	sal_uInt16 nOldLines = nLineCount;
	if( USHRT_MAX == nLineCount )
		nOldLines = rTbl.GetTabLines().Count();

    SwDoc *pDoc = rTbl.GetFrmFmt()->GetDoc();
    SwChartDataProvider *pPCD = pDoc->GetChartDataProvider();
    for( n = 0; n < aParent.GetTabLines().Count(); ++n )
    {
        SwTableLine* pLn = aParent.GetTabLines()[ n ];
        pLn->SetUpper( 0 );
        if( n < nOldLines )
        {
            SwTableLine* pOld = rTbl.GetTabLines()[ n ];

            // TL_CHART2: notify chart about boxes to be removed
            const SwTableBoxes &rBoxes = pOld->GetTabBoxes();
            sal_uInt16 nBoxes = rBoxes.Count();
            for (sal_uInt16 k = 0;  k < nBoxes;  ++k)
            {
                SwTableBox *pBox = rBoxes[k];
                if (pPCD)
                    pPCD->DeleteBox( &rTbl, *pBox );
            }

            rTbl.GetTabLines().C40_REPLACE( SwTableLine, pLn, n );
            delete pOld;
        }
        else
            rTbl.GetTabLines().C40_INSERT( SwTableLine, pLn, n );
    }

    if( n < nOldLines )
    {
        // remove remaining lines...

        for (sal_uInt16 k1 = 0; k1 < nOldLines - n;  ++k1)
        {
            const SwTableBoxes &rBoxes = rTbl.GetTabLines()[n + k1]->GetTabBoxes();
            sal_uInt16 nBoxes = rBoxes.Count();
            for (sal_uInt16 k2 = 0;  k2 < nBoxes;  ++k2)
            {
                SwTableBox *pBox = rBoxes[k2];
                // TL_CHART2: notify chart about boxes to be removed
                if (pPCD)
                    pPCD->DeleteBox( &rTbl, *pBox );
            }
        }

        rTbl.GetTabLines().DeleteAndDestroy( n, nOldLines - n );
    }

	aParent.GetTabLines().Remove( 0, n );

	if( bCreateFrms )
		aTmpBox.MakeFrms( rTbl );
	if( bRestoreChart )
    {
		// TL_CHART2: need to inform chart of probably changed cell names
        pDoc->UpdateCharts( rTbl.GetFrmFmt()->GetName() );
    }
}


void _SaveTable::NewFrmFmt( const SwTableLine* pTblLn, const SwTableBox* pTblBx,
							sal_uInt16 nFmtPos, SwFrmFmt* pOldFmt )
{
	SwDoc* pDoc = pOldFmt->GetDoc();

	SwFrmFmt* pFmt = aFrmFmts[ nFmtPos ];
	if( !pFmt )
	{
		if( pTblLn )
			pFmt = pDoc->MakeTableLineFmt();
		else
			pFmt = pDoc->MakeTableBoxFmt();
        pFmt->SetFmtAttr( *aSets[ nFmtPos ] );
		aFrmFmts.Replace( pFmt, nFmtPos );
	}

	//Erstmal die Frms ummelden.
	SwIterator<SwTabFrm,SwFmt> aIter( *pOldFmt );
	for( SwFrm* pLast = aIter.First(); pLast; pLast = aIter.Next() )
    {
		if( pTblLn ? ((SwRowFrm*)pLast)->GetTabLine() == pTblLn
					: ((SwCellFrm*)pLast)->GetTabBox() == pTblBx )
		{
			pLast->RegisterToFormat(*pFmt);
			pLast->InvalidateAll();
			pLast->ReinitializeFrmSizeAttrFlags();
            if ( !pTblLn )
            {
                ((SwCellFrm*)pLast)->SetDerivedVert( sal_False );
                ((SwCellFrm*)pLast)->CheckDirChange();
            }
		}
    }

	//Jetzt noch mich selbst ummelden.
    if ( pTblLn )
        const_cast<SwTableLine*>(pTblLn)->RegisterToFormat( *pFmt );
    else if ( pTblBx )
        const_cast<SwTableBox*>(pTblBx)->RegisterToFormat( *pFmt );

	if( bModifyBox && !pTblLn )
	{
        const SfxPoolItem& rOld = pOldFmt->GetFmtAttr( RES_BOXATR_FORMAT ),
                         & rNew = pFmt->GetFmtAttr( RES_BOXATR_FORMAT );
		if( rOld != rNew )
			pFmt->ModifyNotification( (SfxPoolItem*)&rOld, (SfxPoolItem*)&rNew );
	}

	if( !pOldFmt->GetDepends() )
		delete pOldFmt;

}


_SaveLine::_SaveLine( _SaveLine* pPrev, const SwTableLine& rLine, _SaveTable& rSTbl )
	: pNext( 0 )
{
	if( pPrev )
		pPrev->pNext = this;

	nItemSet = rSTbl.AddFmt( rLine.GetFrmFmt(), true );

	pBox = new _SaveBox( 0, *rLine.GetTabBoxes()[ 0 ], rSTbl );
	_SaveBox* pBx = pBox;
	for( sal_uInt16 n = 1; n < rLine.GetTabBoxes().Count(); ++n )
		pBx = new _SaveBox( pBx, *rLine.GetTabBoxes()[ n ], rSTbl );
}


_SaveLine::~_SaveLine()
{
	delete pBox;
	delete pNext;
}


void _SaveLine::RestoreAttr( SwTableLine& rLine, _SaveTable& rSTbl )
{
	rSTbl.NewFrmFmt( &rLine, 0, nItemSet, rLine.GetFrmFmt() );

	_SaveBox* pBx = pBox;
	for( sal_uInt16 n = 0; n < rLine.GetTabBoxes().Count(); ++n, pBx = pBx->pNext )
	{
		if( !pBx )
		{
			ASSERT( !this, "Anzahl der Boxen hat sich veraendert" );
			break;
		}
		pBx->RestoreAttr( *rLine.GetTabBoxes()[ n ], rSTbl );
	}
}


void _SaveLine::SaveCntntAttrs( SwDoc* pDoc )
{
	pBox->SaveCntntAttrs( pDoc );
	if( pNext )
		pNext->SaveCntntAttrs( pDoc );
}


void _SaveLine::CreateNew( SwTable& rTbl, SwTableBox& rParent, _SaveTable& rSTbl )
{
	SwTableLineFmt* pFmt = (SwTableLineFmt*)rSTbl.aFrmFmts[ nItemSet ];
	if( !pFmt )
	{
		SwDoc* pDoc = rTbl.GetFrmFmt()->GetDoc();
		pFmt = pDoc->MakeTableLineFmt();
        pFmt->SetFmtAttr( *rSTbl.aSets[ nItemSet ] );
		rSTbl.aFrmFmts.Replace( pFmt, nItemSet );
	}
	SwTableLine* pNew = new SwTableLine( pFmt, 1, &rParent );

    rParent.GetTabLines().C40_INSERT( SwTableLine, pNew, rParent.GetTabLines().Count() );

    // HB, #127868# robustness: in some cases - which I
    // cannot reproduce nor see from the code - pNew seems
    // to be set to NULL in C40_INSERT.
    ASSERT(pNew, "Table line just created set to NULL in C40_INSERT");

    if (pNew)
    {
        pBox->CreateNew( rTbl, *pNew, rSTbl );
    }

	if( pNext )
		pNext->CreateNew( rTbl, rParent, rSTbl );
}


_SaveBox::_SaveBox( _SaveBox* pPrev, const SwTableBox& rBox, _SaveTable& rSTbl )
	: pNext( 0 ), nSttNode( ULONG_MAX ), nRowSpan(0)
{
	Ptrs.pLine = 0;

	if( pPrev )
		pPrev->pNext = this;

	nItemSet = rSTbl.AddFmt( rBox.GetFrmFmt(), false );

	if( rBox.GetSttNd() )
    {
		nSttNode = rBox.GetSttIdx();
        nRowSpan = rBox.getRowSpan();
    }
	else
	{
		Ptrs.pLine = new _SaveLine( 0, *rBox.GetTabLines()[ 0 ], rSTbl );

		_SaveLine* pLn = Ptrs.pLine;
		for( sal_uInt16 n = 1; n < rBox.GetTabLines().Count(); ++n )
			pLn = new _SaveLine( pLn, *rBox.GetTabLines()[ n ], rSTbl );
	}
}


_SaveBox::~_SaveBox()
{
	if( ULONG_MAX == nSttNode )		// keine EndBox
		delete Ptrs.pLine;
	else
		delete Ptrs.pCntntAttrs;
	delete pNext;
}


void _SaveBox::RestoreAttr( SwTableBox& rBox, _SaveTable& rSTbl )
{
	rSTbl.NewFrmFmt( 0, &rBox, nItemSet, rBox.GetFrmFmt() );

	if( ULONG_MAX == nSttNode )		// keine EndBox
	{
		if( !rBox.GetTabLines().Count() )
		{
			ASSERT( !this, "Anzahl der Lines hat sich veraendert" );
		}
		else
		{
			_SaveLine* pLn = Ptrs.pLine;
			for( sal_uInt16 n = 0; n < rBox.GetTabLines().Count(); ++n, pLn = pLn->pNext )
			{
				if( !pLn )
				{
					ASSERT( !this, "Anzahl der Lines hat sich veraendert" );
					break;
				}

				pLn->RestoreAttr( *rBox.GetTabLines()[ n ], rSTbl );
			}
		}
	}
	else if( rBox.GetSttNd() && rBox.GetSttIdx() == nSttNode )
	{
		if( Ptrs.pCntntAttrs )
		{
			SwNodes& rNds = rBox.GetFrmFmt()->GetDoc()->GetNodes();
			sal_uInt16 nSet = 0;
			sal_uLong nEnd = rBox.GetSttNd()->EndOfSectionIndex();
			for( sal_uLong n = nSttNode + 1; n < nEnd; ++n )
			{
				SwCntntNode* pCNd = rNds[ n ]->GetCntntNode();
				if( pCNd )
				{
					SfxItemSet* pSet = (*Ptrs.pCntntAttrs)[ nSet++ ];
					if( pSet )
					{
						sal_uInt16 *pRstAttr = aSave_BoxCntntSet;
						while( *pRstAttr )
						{
							pCNd->ResetAttr( *pRstAttr, *(pRstAttr+1) );
							pRstAttr += 2;
						}
						pCNd->SetAttr( *pSet );
					}
					else
						pCNd->ResetAllAttr();
				}
			}
		}
	}
	else
	{
		ASSERT( !this, "Box nicht mehr am gleichen Node" );
	}
}


void _SaveBox::SaveCntntAttrs( SwDoc* pDoc )
{
	if( ULONG_MAX == nSttNode )		// keine EndBox
	{
		// weiter in der Line
		Ptrs.pLine->SaveCntntAttrs( pDoc );
	}
	else
	{
		sal_uLong nEnd = pDoc->GetNodes()[ nSttNode ]->EndOfSectionIndex();
		Ptrs.pCntntAttrs = new SfxItemSets( (sal_uInt8)(nEnd - nSttNode - 1 ), 5 );
		for( sal_uLong n = nSttNode + 1; n < nEnd; ++n )
		{
			SwCntntNode* pCNd = pDoc->GetNodes()[ n ]->GetCntntNode();
			if( pCNd )
			{
				SfxItemSet* pSet = 0;
                if( pCNd->HasSwAttrSet() )
				{
					pSet = new SfxItemSet( pDoc->GetAttrPool(),
											aSave_BoxCntntSet );
					pSet->Put( *pCNd->GetpSwAttrSet() );
				}

				Ptrs.pCntntAttrs->Insert( pSet, Ptrs.pCntntAttrs->Count() );
			}
		}
	}
	if( pNext )
		pNext->SaveCntntAttrs( pDoc );
}


void _SaveBox::CreateNew( SwTable& rTbl, SwTableLine& rParent, _SaveTable& rSTbl )
{
	SwTableBoxFmt* pFmt = (SwTableBoxFmt*)rSTbl.aFrmFmts[ nItemSet ];
	if( !pFmt )
	{
		SwDoc* pDoc = rTbl.GetFrmFmt()->GetDoc();
		pFmt = pDoc->MakeTableBoxFmt();
        pFmt->SetFmtAttr( *rSTbl.aSets[ nItemSet ] );
		rSTbl.aFrmFmts.Replace( pFmt, nItemSet );
	}

	if( ULONG_MAX == nSttNode )		// keine EndBox
	{
		SwTableBox* pNew = new SwTableBox( pFmt, 1, &rParent );
		rParent.GetTabBoxes().C40_INSERT( SwTableBox, pNew, rParent.GetTabBoxes().Count() );

		Ptrs.pLine->CreateNew( rTbl, *pNew, rSTbl );
	}
	else
	{
		// Box zum StartNode in der alten Tabelle suchen
		SwTableBox* pBox = rTbl.GetTblBox( nSttNode );
		ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );

		SwFrmFmt* pOld = pBox->GetFrmFmt();
        pBox->RegisterToFormat( *pFmt );
		if( !pOld->GetDepends() )
			delete pOld;

        pBox->setRowSpan( nRowSpan );

		SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
		pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pBox ) );

		pBox->SetUpper( &rParent );
		pTBoxes = &rParent.GetTabBoxes();
		pTBoxes->C40_INSERT( SwTableBox, pBox, pTBoxes->Count() );
	}

	if( pNext )
		pNext->CreateNew( rTbl, rParent, rSTbl );
}


//////////////////////////////////////////////////////////////////////////

// UndoObject fuer Attribut Aenderung an der Tabelle


SwUndoAttrTbl::SwUndoAttrTbl( const SwTableNode& rTblNd, sal_Bool bClearTabCols )
	: SwUndo( UNDO_TABLE_ATTR ),
	nSttNode( rTblNd.GetIndex() )
{
	bClearTabCol = bClearTabCols;
	pSaveTbl = new _SaveTable( rTblNd.GetTable() );
}

SwUndoAttrTbl::~SwUndoAttrTbl()
{
	delete pSaveTbl;
}

void SwUndoAttrTbl::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
	SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
	ASSERT( pTblNd, "kein TabellenNode" );

    if (pTblNd)
    {
        _SaveTable* pOrig = new _SaveTable( pTblNd->GetTable() );
        pSaveTbl->RestoreAttr( pTblNd->GetTable() );
        delete pSaveTbl;
        pSaveTbl = pOrig;
    }

	if( bClearTabCol )
		ClearFEShellTabCols();
}

void SwUndoAttrTbl::RedoImpl(::sw::UndoRedoContext & rContext)
{
    UndoImpl(rContext);
}


//////////////////////////////////////////////////////////////////////////

// UndoObject fuer AutoFormat an der Tabelle


SwUndoTblAutoFmt::SwUndoTblAutoFmt( const SwTableNode& rTblNd,
									const SwTableAutoFmt& rAFmt )
	: SwUndo( UNDO_TABLE_AUTOFMT ),
    nSttNode( rTblNd.GetIndex() ),
	bSaveCntntAttr( sal_False )
{
	pSaveTbl = new _SaveTable( rTblNd.GetTable() );

	if( rAFmt.IsFont() || rAFmt.IsJustify() )
	{
		// dann auch noch ueber die ContentNodes der EndBoxen und
		// und alle Absatz-Attribute zusammen sammeln
		pSaveTbl->SaveCntntAttrs( (SwDoc*)rTblNd.GetDoc() );
		bSaveCntntAttr = sal_True;
	}
}

SwUndoTblAutoFmt::~SwUndoTblAutoFmt()
{
	delete pSaveTbl;
}

void SwUndoTblAutoFmt::SaveBoxCntnt( const SwTableBox& rBox )
{
    ::boost::shared_ptr<SwUndoTblNumFmt> const p(new SwUndoTblNumFmt(rBox));
    m_Undos.push_back(p);
}


void
SwUndoTblAutoFmt::UndoRedo(bool const bUndo, ::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
	SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
	ASSERT( pTblNd, "kein TabellenNode" );

	_SaveTable* pOrig = new _SaveTable( pTblNd->GetTable() );
		// dann auch noch ueber die ContentNodes der EndBoxen und
		// und alle Absatz-Attribute zusammen sammeln
	if( bSaveCntntAttr )
		pOrig->SaveCntntAttrs( &rDoc );

    if (bUndo)
    {
        for (size_t n = m_Undos.size(); 0 < n; --n)
        {
            m_Undos.at(n-1)->UndoImpl(rContext);
        }
    }

	pSaveTbl->RestoreAttr( pTblNd->GetTable(), !bUndo );
	delete pSaveTbl;
	pSaveTbl = pOrig;
}

void SwUndoTblAutoFmt::UndoImpl(::sw::UndoRedoContext & rContext)
{
    UndoRedo(true, rContext);
}

void SwUndoTblAutoFmt::RedoImpl(::sw::UndoRedoContext & rContext)
{
    UndoRedo(false, rContext);
}


//////////////////////////////////////////////////////////////////////////

SwUndoTblNdsChg::SwUndoTblNdsChg( SwUndoId nAction,
									const SwSelBoxes& rBoxes,
									const SwTableNode& rTblNd,
                                    long nMn, long nMx,
                                    sal_uInt16 nCnt, sal_Bool bFlg, sal_Bool bSmHght )
	: SwUndo( nAction ),
	aBoxes( rBoxes.Count() < 255 ? (sal_uInt8)rBoxes.Count() : 255, 10 ),
    nMin( nMn ), nMax( nMx ),
	nSttNode( rTblNd.GetIndex() ), nCurrBox( 0 ),
	nCount( nCnt ), nRelDiff( 0 ), nAbsDiff( 0 ),
	nSetColType( USHRT_MAX ),
    bFlag( bFlg ),
    bSameHeight( bSmHght )
{
	Ptrs.pNewSttNds = 0;

	const SwTable& rTbl = rTblNd.GetTable();
	pSaveTbl = new _SaveTable( rTbl );

	// und die Selektion merken
	for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
		aBoxes.Insert( rBoxes[n]->GetSttIdx(), n );
}


SwUndoTblNdsChg::SwUndoTblNdsChg( SwUndoId nAction,
									const SwSelBoxes& rBoxes,
									const SwTableNode& rTblNd )
	: SwUndo( nAction ),
	aBoxes( rBoxes.Count() < 255 ? (sal_uInt8)rBoxes.Count() : 255, 10 ),
    nMin( 0 ), nMax( 0 ),
	nSttNode( rTblNd.GetIndex() ), nCurrBox( 0 ),
	nCount( 0 ), nRelDiff( 0 ), nAbsDiff( 0 ),
	nSetColType( USHRT_MAX ),
	bFlag( sal_False ),
	bSameHeight( sal_False )
{
	Ptrs.pNewSttNds = 0;

	const SwTable& rTbl = rTblNd.GetTable();
	pSaveTbl = new _SaveTable( rTbl );

	// und die Selektion merken
	for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
		aBoxes.Insert( rBoxes[n]->GetSttIdx(), n );
}

void SwUndoTblNdsChg::ReNewBoxes( const SwSelBoxes& rBoxes )
{
    if( rBoxes.Count() != aBoxes.Count() )
    {
        aBoxes.Remove( 0, aBoxes.Count() );
        for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
            aBoxes.Insert( rBoxes[n]->GetSttIdx(), n );
    }
}

SwUndoTblNdsChg::~SwUndoTblNdsChg()
{
	delete pSaveTbl;

	if( IsDelBox() )
		delete Ptrs.pDelSects;
	else
		delete Ptrs.pNewSttNds;
}

void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode& rTblNd,
									const SwTableSortBoxes& rOld )
{
	const SwTable& rTbl = rTblNd.GetTable();
	const SwTableSortBoxes& rTblBoxes = rTbl.GetTabSortBoxes();
	sal_uInt16 n;
	sal_uInt16 i;

	ASSERT( ! IsDelBox(), "falsche Action" );
	Ptrs.pNewSttNds = new SvULongs( (sal_uInt8)(rTblBoxes.Count() - rOld.Count()), 5 );

	for( n = 0, i = 0; n < rOld.Count(); ++i )
	{
		if( rOld[ n ] == rTblBoxes[ i ] )
			++n;
		else
			// neue Box: sortiert einfuegen!!
			InsertSort( *Ptrs.pNewSttNds, rTblBoxes[ i ]->GetSttIdx() );
	}

	for( ; i < rTblBoxes.Count(); ++i )
		// neue Box: sortiert einfuegen!!
		InsertSort( *Ptrs.pNewSttNds, rTblBoxes[ i ]->GetSttIdx() );
}


SwTableLine* lcl_FindTableLine( const SwTable& rTable,
                                const SwTableBox& rBox )
{
    SwTableLine* pRet = NULL;
    // i63949: For nested cells we have to take nLineNo - 1, too, not 0!
    const SwTableLines &rTableLines = ( rBox.GetUpper()->GetUpper() != NULL ) ?
                                  rBox.GetUpper()->GetUpper()->GetTabLines()
                                : rTable.GetTabLines();
    const SwTableLine* pLine = rBox.GetUpper();
    sal_uInt16 nLineNo = rTableLines.C40_GETPOS( SwTableLine, pLine );
    pRet = rTableLines[nLineNo - 1];

    return pRet;
}

const SwTableLines& lcl_FindParentLines( const SwTable& rTable,
				                       const SwTableBox& rBox )
{
    const SwTableLines& rRet =
		( rBox.GetUpper()->GetUpper() != NULL ) ?
			rBox.GetUpper()->GetUpper()->GetTabLines() :
			rTable.GetTabLines();

	return rRet;
}


void SwUndoTblNdsChg::SaveNewBoxes( const SwTableNode& rTblNd,
									const SwTableSortBoxes& rOld,
									const SwSelBoxes& rBoxes,
									const SvULongs& rNodeCnts )
{
	const SwTable& rTbl = rTblNd.GetTable();
	const SwTableSortBoxes& rTblBoxes = rTbl.GetTabSortBoxes();

	ASSERT( ! IsDelBox(), "falsche Action" );
	Ptrs.pNewSttNds = new SvULongs( (sal_uInt8)(rTblBoxes.Count() - rOld.Count()), 5 );

	ASSERT( rTbl.IsNewModel() || rOld.Count() + nCount * rBoxes.Count() == rTblBoxes.Count(),
		"unexpected boxes" );
	ASSERT( rOld.Count() <= rTblBoxes.Count(), "more unexpected boxes" );
	for( sal_uInt16 n = 0, i = 0; i < rTblBoxes.Count(); ++i )
	{
		if( ( n < rOld.Count() ) &&
			( rOld[ n ] == rTblBoxes[ i ] ) )
        {
            // box already known? Then nothing to be done.
			++n;
        }
		else
		{
			// new box found: insert (obey sort order)
			sal_uInt16 nInsPos;
			const SwTableBox* pBox = rTblBoxes[ i ];
			InsertSort( *Ptrs.pNewSttNds, pBox->GetSttIdx(), &nInsPos );

			// find the source box. It must be one in rBoxes.
            // We found the right one if it's in the same column as pBox.
            // No, if more than one selected cell in the same column has been splitted,
            // we have to look for the nearest one (i65201)!
			const SwTableBox* pSourceBox = NULL;
			const SwTableBox* pCheckBox = NULL;
			const SwTableLine* pBoxLine = pBox->GetUpper();
			sal_uInt16 nLineDiff = lcl_FindParentLines(rTbl,*pBox).C40_GETPOS(SwTableLine,pBoxLine);
            sal_uInt16 nLineNo = 0;
            for( sal_uInt16 j = 0; j < rBoxes.Count(); ++j )
            {
				pCheckBox = rBoxes[j];
                if( pCheckBox->GetUpper()->GetUpper() == pBox->GetUpper()->GetUpper() )
                {
                    const SwTableLine* pCheckLine = pCheckBox->GetUpper();
                    sal_uInt16 nCheckLine = lcl_FindParentLines( rTbl, *pCheckBox ).
                    C40_GETPOS( SwTableLine, pCheckLine );
                    if( ( !pSourceBox || nCheckLine > nLineNo ) && nCheckLine < nLineDiff )
                    {
                        nLineNo = nCheckLine;
                        pSourceBox = pCheckBox;
                    }
                }
			}

			// find the line number difference
            // (to help determine bNodesMoved flag below)
			nLineDiff = nLineDiff - nLineNo;
            ASSERT( pSourceBox, "Splitted source box not found!" );
            // find out how many nodes the source box used to have
            // (to help determine bNodesMoved flag below)
            sal_uInt16 nNdsPos = 0;
            while( rBoxes[ nNdsPos ] != pSourceBox )
                ++nNdsPos;
            sal_uLong nNodes = rNodeCnts[ nNdsPos ];

            // When a new table cell is created, it either gets a new
            // node, or it gets node(s) from elsewhere. The undo must
            // know, of course, and thus we must determine here just
            // where pBox's nodes are from:
            // If 1) the source box has lost nodes, and
            //    2) we're in the node range that got nodes
            // then pBox received nodes from elsewhere.
            // If bNodesMoved is set for pBox the undo must move the
            // boxes back, otherwise it must delete them.
            // The bNodesMoved flag is stored in a separate array
            // which mirrors Ptrs.pNewSttNds, i.e. Ptrs.pNewSttNds[i]
            // and aMvBoxes[i] belong together.
            sal_Bool bNodesMoved =
                ( nNodes != ( pSourceBox->GetSttNd()->EndOfSectionIndex() -
                              pSourceBox->GetSttIdx() ) )
                && ( nNodes - 1 > nLineDiff );
			aMvBoxes.insert( aMvBoxes.begin() + nInsPos, bNodesMoved );
		}
	}
}


void SwUndoTblNdsChg::SaveSection( SwStartNode* pSttNd )
{
	ASSERT( IsDelBox(), "falsche Action" );
	if( !Ptrs.pDelSects )
		Ptrs.pDelSects = new SwUndoSaveSections( 10, 5 );

	SwTableNode* pTblNd = pSttNd->FindTableNode();
	SwUndoSaveSection* pSave = new SwUndoSaveSection;
	pSave->SaveSection( pSttNd->GetDoc(), SwNodeIndex( *pSttNd ));

	Ptrs.pDelSects->Insert( pSave, Ptrs.pDelSects->Count() );
	nSttNode = pTblNd->GetIndex();
}


void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
	SwNodeIndex aIdx( rDoc.GetNodes(), nSttNode );

    SwTableNode *const pTblNd = aIdx.GetNode().GetTableNode();
    OSL_ENSURE( pTblNd, "SwUndoTblNdsChg: no TableNode" );

	SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
	aMsgHnt.eFlags = TBL_BOXPTR;
	rDoc.UpdateTblFlds( &aMsgHnt );

    CHECK_TABLE( pTblNd->GetTable() )

	_FndBox aTmpBox( 0, 0 );
    // ? TL_CHART2: notification or locking of controller required ?

    SwChartDataProvider *pPCD = rDoc.GetChartDataProvider();
    std::vector< SwTableBox* > aDelBoxes;
	if( IsDelBox() )
	{
		// Trick: die fehlenden Boxen in irgendeine Line einfuegen, beim
		// CreateNew werden sie korrekt verbunden.
		SwTableBox* pCpyBox = pTblNd->GetTable().GetTabSortBoxes()[0];
		SwTableBoxes& rLnBoxes = pCpyBox->GetUpper()->GetTabBoxes();

		// die Sections wieder herstellen
		for( sal_uInt16 n = Ptrs.pDelSects->Count(); n; )
		{
			SwUndoSaveSection* pSave = (*Ptrs.pDelSects)[ --n ];
			pSave->RestoreSection( &rDoc, &aIdx, SwTableBoxStartNode );
			if( pSave->GetHistory() )
				pSave->GetHistory()->Rollback( &rDoc );
			SwTableBox* pBox = new SwTableBox( (SwTableBoxFmt*)pCpyBox->GetFrmFmt(), aIdx,
												pCpyBox->GetUpper() );
			rLnBoxes.C40_INSERT( SwTableBox, pBox, rLnBoxes.Count() );
		}
		Ptrs.pDelSects->DeleteAndDestroy( 0, Ptrs.pDelSects->Count() );
	}
	else if( !aMvBoxes.empty() )
	{
		// dann muessen Nodes verschoben und nicht geloescht werden!
		// Dafuer brauchen wir aber ein temp Array
		SvULongs aTmp( 0, 5);
		aTmp.Insert( Ptrs.pNewSttNds, 0 );

		// von hinten anfangen
		for( sal_uInt16 n = aTmp.Count(); n; )
		{
			// Box aus der Tabellen-Struktur entfernen
			sal_uLong nIdx = aTmp[ --n ];
			SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nIdx );
			ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );

			// TL_CHART2: notify chart about box to be removed
            if (pPCD)
                pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );

			if( aMvBoxes[ n ] )
			{
				SwNodeRange aRg( *pBox->GetSttNd(), 1,
							*pBox->GetSttNd()->EndOfSectionNode() );

				SwTableLine* pLine = lcl_FindTableLine( pTblNd->GetTable(), *pBox );
				SwNodeIndex aInsPos( *(pLine->GetTabBoxes()[0]->GetSttNd()), 2 );

				// alle StartNode Indizies anpassen
				sal_uInt16 i = n;
				sal_uLong nSttIdx = aInsPos.GetIndex() - 2,
					   nNdCnt = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex();
				while( i && aTmp[ --i ] > nSttIdx )
					aTmp[ i ] += nNdCnt;

				// erst die Box loeschen
				delete pBox;
				// dann die Nodes verschieben,
				rDoc.GetNodes()._MoveNodes( aRg, rDoc.GetNodes(), aInsPos, sal_False );
			}
			else
				rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
            aDelBoxes.insert( aDelBoxes.end(), pBox );
		}
	}
	else
    {
		// Remove nodes from nodes array (backwards!)
		for( sal_uInt16 n = Ptrs.pNewSttNds->Count(); n; )
		{
			sal_uLong nIdx = (*Ptrs.pNewSttNds)[ --n ];
			SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nIdx );
			ASSERT( pBox, "Where's my table box?" );
			// TL_CHART2: notify chart about box to be removed
            if (pPCD)
                pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
            aDelBoxes.insert( aDelBoxes.end(), pBox );
			rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
        }
    }
    // Remove boxes from table structure
    for( sal_uInt16 n = 0; n < aDelBoxes.size(); ++n )
    {
        SwTableBox* pCurrBox = aDelBoxes[n];
        SwTableBoxes* pTBoxes = &pCurrBox->GetUpper()->GetTabBoxes();
        pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pCurrBox ) );
        delete pCurrBox;
    }

	pSaveTbl->CreateNew( pTblNd->GetTable(), sal_True, sal_False );

	// TL_CHART2: need to inform chart of probably changed cell names
    rDoc.UpdateCharts( pTblNd->GetTable().GetFrmFmt()->GetName() );

	if( IsDelBox() )
		nSttNode = pTblNd->GetIndex();
	ClearFEShellTabCols();
    CHECK_TABLE( pTblNd->GetTable() )
}


void SwUndoTblNdsChg::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();

	SwTableNode* pTblNd = rDoc.GetNodes()[ nSttNode ]->GetTableNode();
	ASSERT( pTblNd, "kein TabellenNode" );
    CHECK_TABLE( pTblNd->GetTable() )

	SwSelBoxes aSelBoxes;
	for( sal_uInt16 n = 0; n < aBoxes.Count(); ++n )
	{
		SwTableBox* pBox = pTblNd->GetTable().GetTblBox( aBoxes[ n ] );
		aSelBoxes.Insert( pBox );
	}

	// SelBoxes erzeugen und InsertCell/-Row/SplitTbl aufrufen
	switch( GetId() )
	{
	case UNDO_TABLE_INSCOL:
		if( USHRT_MAX == nSetColType )
			rDoc.InsertCol( aSelBoxes, nCount, bFlag );
		else
		{
			SwTableBox* pBox = pTblNd->GetTable().GetTblBox( nCurrBox );
			rDoc.SetColRowWidthHeight( *pBox, nSetColType, nAbsDiff,
										nRelDiff );
		}
		break;

	case UNDO_TABLE_INSROW:
		if( USHRT_MAX == nSetColType )
			rDoc.InsertRow( aSelBoxes, nCount, bFlag );
		else
		{
			SwTable& rTbl = pTblNd->GetTable();
			SwTableBox* pBox = rTbl.GetTblBox( nCurrBox );
			TblChgMode eOldMode = rTbl.GetTblChgMode();
			rTbl.SetTblChgMode( (TblChgMode)nCount );
			rDoc.SetColRowWidthHeight( *pBox, nSetColType, nAbsDiff, nRelDiff );
			rTbl.SetTblChgMode( eOldMode );
		}
		break;

	case UNDO_TABLE_SPLIT:
        rDoc.SplitTbl( aSelBoxes, bFlag, nCount, bSameHeight );
		break;
	case UNDO_TABLE_DELBOX:
    case UNDO_ROW_DELETE:
    case UNDO_COL_DELETE:
		if( USHRT_MAX == nSetColType )
		{
			SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
			aMsgHnt.eFlags = TBL_BOXPTR;
			rDoc.UpdateTblFlds( &aMsgHnt );
            SwTable &rTable = pTblNd->GetTable();
            if( nMax > nMin && rTable.IsNewModel() )
                rTable.PrepareDeleteCol( nMin, nMax );
			rTable.DeleteSel( &rDoc, aSelBoxes, 0, this, sal_True, sal_True );
		}
		else
		{
			SwTable& rTbl = pTblNd->GetTable();

			SwTableFmlUpdate aMsgHnt( &rTbl );
			aMsgHnt.eFlags = TBL_BOXPTR;
			rDoc.UpdateTblFlds( &aMsgHnt );

			SwTableBox* pBox = rTbl.GetTblBox( nCurrBox );
			TblChgMode eOldMode = rTbl.GetTblChgMode();
			rTbl.SetTblChgMode( (TblChgMode)nCount );

            // need the SaveSections!
            rDoc.GetIDocumentUndoRedo().DoUndo( true );
			SwUndoTblNdsChg* pUndo = 0;

			switch( nSetColType & 0xff )
			{
			case nsTblChgWidthHeightType::WH_COL_LEFT:
			case nsTblChgWidthHeightType::WH_COL_RIGHT:
			case nsTblChgWidthHeightType::WH_CELL_LEFT:
			case nsTblChgWidthHeightType::WH_CELL_RIGHT:
				 rTbl.SetColWidth( *pBox, nSetColType, nAbsDiff,
									nRelDiff, (SwUndo**)&pUndo );
				break;
			case nsTblChgWidthHeightType::WH_ROW_TOP:
			case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
			case nsTblChgWidthHeightType::WH_CELL_TOP:
			case nsTblChgWidthHeightType::WH_CELL_BOTTOM:
				rTbl.SetRowHeight( *pBox, nSetColType, nAbsDiff,
									nRelDiff, (SwUndo**)&pUndo );
				break;
			}

			if( pUndo )
			{
				Ptrs.pDelSects->Insert( pUndo->Ptrs.pDelSects, 0 );
				pUndo->Ptrs.pDelSects->Remove( 0, pUndo->Ptrs.pDelSects->Count() );

				delete pUndo;
			}
            rDoc.GetIDocumentUndoRedo().DoUndo( false );

			rTbl.SetTblChgMode( eOldMode );
		}
		nSttNode = pTblNd->GetIndex();
		break;
    default:
        ;
	}
	ClearFEShellTabCols();
    CHECK_TABLE( pTblNd->GetTable() )
}


//////////////////////////////////////////////////////////////////////////

SwUndoTblMerge::SwUndoTblMerge( const SwPaM& rTblSel )
	: SwUndo( UNDO_TABLE_MERGE ), SwUndRng( rTblSel ), pHistory( 0 )
{
	const SwTableNode* pTblNd = rTblSel.GetNode()->FindTableNode();
	ASSERT( pTblNd, "Wo ist TabllenNode" )
	pSaveTbl = new _SaveTable( pTblNd->GetTable() );
	pMoves = new SwUndoMoves;
	nTblNode = pTblNd->GetIndex();
}

SwUndoTblMerge::~SwUndoTblMerge()
{
	delete pSaveTbl;
	delete pMoves;
	delete pHistory;
}

void SwUndoTblMerge::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
	SwNodeIndex aIdx( rDoc.GetNodes(), nTblNode );

    SwTableNode *const pTblNd = aIdx.GetNode().GetTableNode();
    OSL_ENSURE( pTblNd, "SwUndoTblMerge: no TableNode" );

	SwTableFmlUpdate aMsgHnt( &pTblNd->GetTable() );
	aMsgHnt.eFlags = TBL_BOXPTR;
	rDoc.UpdateTblFlds( &aMsgHnt );

    _FndBox aTmpBox( 0, 0 );
    // ? TL_CHART2: notification or locking of controller required ?


	// 1. die geloeschten Boxen wiederherstellen:

	// Trick: die fehlenden Boxen in irgendeine Line einfuegen, beim
	// CreateNew werden sie korrekt verbunden.
	SwTableBox *pBox, *pCpyBox = pTblNd->GetTable().GetTabSortBoxes()[0];
	SwTableBoxes& rLnBoxes = pCpyBox->GetUpper()->GetTabBoxes();

DUMPDOC( &rDoc, "d:\\tmp\\tab_a.db" )
CHECKTABLE(pTblNd->GetTable())

	SwSelBoxes aSelBoxes;
	SwTxtFmtColl* pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_STANDARD );
	sal_uInt16 n;

	for( n = 0; n < aBoxes.Count(); ++n )
	{
		aIdx = aBoxes[ n ];
		SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection( aIdx,
											SwTableBoxStartNode, pColl );
		pBox = new SwTableBox( (SwTableBoxFmt*)pCpyBox->GetFrmFmt(), *pSttNd,
								pCpyBox->GetUpper() );
		rLnBoxes.C40_INSERT( SwTableBox, pBox, rLnBoxes.Count() );

		aSelBoxes.Insert( pBox );
	}

DUMPDOC( &rDoc, "d:\\tmp\\tab_b.db" )
CHECKTABLE(pTblNd->GetTable())

    SwChartDataProvider *pPCD = rDoc.GetChartDataProvider();
	// 2. die eingefuegten Boxen loeschen
	// die Nodes loeschen (von Hinten!!)
	for( n = aNewSttNds.Count(); n; )
	{
		// Box aus der Tabellen-Struktur entfernen
		sal_uLong nIdx = aNewSttNds[ --n ];

		if( !nIdx && n )
		{
			nIdx = aNewSttNds[ --n ];
			pBox = pTblNd->GetTable().GetTblBox( nIdx );
			ASSERT( pBox, "Wo ist meine TabellenBox geblieben?" );

            if( !pSaveTbl->IsNewModel() )
                rDoc.GetNodes().MakeTxtNode( SwNodeIndex(
					*pBox->GetSttNd()->EndOfSectionNode() ), pColl );

			// das war der Trenner, -> die verschobenen herstellen
			for( sal_uInt16 i = pMoves->Count(); i; )
			{
				SwTxtNode* pTxtNd = 0;
				sal_uInt16 nDelPos = 0;
				SwUndoMove* pUndo = (*pMoves)[ --i ];
				if( !pUndo->IsMoveRange() )
				{
					pTxtNd = rDoc.GetNodes()[ pUndo->GetDestSttNode() ]->GetTxtNode();
					nDelPos = pUndo->GetDestSttCntnt() - 1;
                }
                pUndo->UndoImpl(rContext);
                if( pUndo->IsMoveRange() )
                {
                    // den ueberfluessigen Node loeschen
                    aIdx = pUndo->GetEndNode();
                    SwCntntNode *pCNd = aIdx.GetNode().GetCntntNode();
                    if( pCNd )
                    {
                        SwNodeIndex aTmp( aIdx, -1 );
                        SwCntntNode *pMove = aTmp.GetNode().GetCntntNode();
                        if( pMove )
                            pCNd->MoveTo( *pMove );
                    }
                    rDoc.GetNodes().Delete( aIdx, 1 );
                }
                else if( pTxtNd )
                {
                    // evt. noch ueberflussige Attribute loeschen
                    SwIndex aTmpIdx( pTxtNd, nDelPos );
                    if( pTxtNd->GetpSwpHints() && pTxtNd->GetpSwpHints()->Count() )
                        pTxtNd->RstTxtAttr( aTmpIdx, pTxtNd->GetTxt().Len() - nDelPos + 1 );
                    // das Trennzeichen loeschen
                    pTxtNd->EraseText( aTmpIdx, 1 );
                }
DUMPDOC( &rDoc, String( "d:\\tmp\\tab_") + String( aNewSttNds.Count() - i ) +
				String(".db") )
			}
			nIdx = pBox->GetSttIdx();
		}
		else
			pBox = pTblNd->GetTable().GetTblBox( nIdx );

        if( !pSaveTbl->IsNewModel() )
        {
            // TL_CHART2: notify chart about box to be removed
            if (pPCD)
                pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );

            SwTableBoxes* pTBoxes = &pBox->GetUpper()->GetTabBoxes();
            pTBoxes->Remove( pTBoxes->C40_GETPOS( SwTableBox, pBox ) );


            // Indizies aus dem Bereich loeschen
            {
                SwNodeIndex aTmpIdx( *pBox->GetSttNd() );
                rDoc.CorrAbs( SwNodeIndex( aTmpIdx, 1 ),
                            SwNodeIndex( *aTmpIdx.GetNode().EndOfSectionNode() ),
                            SwPosition( aTmpIdx, SwIndex( 0, 0 )), sal_True );
            }

            delete pBox;
            rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
        }
	}
DUMPDOC( &rDoc, "d:\\tmp\\tab_z.db" )
CHECKTABLE(pTblNd->GetTable())


	pSaveTbl->CreateNew( pTblNd->GetTable(), sal_True, sal_False );

    // TL_CHART2: need to inform chart of probably changed cell names
    rDoc.UpdateCharts( pTblNd->GetTable().GetFrmFmt()->GetName() );

	if( pHistory )
	{
		pHistory->TmpRollback( &rDoc, 0 );
		pHistory->SetTmpEnd( pHistory->Count() );
	}
//	nTblNode = pTblNd->GetIndex();

    SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
	pPam->DeleteMark();
	pPam->GetPoint()->nNode = nSttNode;
	pPam->GetPoint()->nContent.Assign( pPam->GetCntntNode(), nSttCntnt );
	pPam->SetMark();
	pPam->DeleteMark();

CHECKTABLE(pTblNd->GetTable())
	ClearFEShellTabCols();
}

void SwUndoTblMerge::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
    SwPaM & rPam( AddUndoRedoPaM(rContext) );
    rDoc.MergeTbl(rPam);
}

void SwUndoTblMerge::MoveBoxCntnt( SwDoc* pDoc, SwNodeRange& rRg, SwNodeIndex& rPos )
{
	SwNodeIndex aTmp( rRg.aStart, -1 ), aTmp2( rPos, -1 );
	SwUndoMove* pUndo = new SwUndoMove( pDoc, rRg, rPos );
    ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
    pDoc->MoveNodeRange( rRg, rPos, (pSaveTbl->IsNewModel()) ?
        IDocumentContentOperations::DOC_NO_DELFRMS :
        IDocumentContentOperations::DOC_MOVEDEFAULT );
	aTmp++;
	aTmp2++;
	pUndo->SetDestRange( aTmp2, rPos, aTmp );

	pMoves->Insert( pUndo, pMoves->Count() );
}

void SwUndoTblMerge::SetSelBoxes( const SwSelBoxes& rBoxes )
{
	// die Selektion merken
	for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
		InsertSort( aBoxes, rBoxes[n]->GetSttIdx() );

	// als Trennung fuers einfuegen neuer Boxen nach dem Verschieben!
	aNewSttNds.Insert( (sal_uLong)0, aNewSttNds.Count() );

     // The new table model does not delete overlapped cells (by row span),
     // so the rBoxes array might be empty even some cells have been merged.
    if( rBoxes.Count() )
        nTblNode = rBoxes[ 0 ]->GetSttNd()->FindTableNode()->GetIndex();
}

void SwUndoTblMerge::SaveCollection( const SwTableBox& rBox )
{
	if( !pHistory )
		pHistory = new SwHistory;

	SwNodeIndex aIdx( *rBox.GetSttNd(), 1 );
	SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
	if( !pCNd )
		pCNd = aIdx.GetNodes().GoNext( &aIdx );

	pHistory->Add( pCNd->GetFmtColl(), aIdx.GetIndex(), pCNd->GetNodeType());
    if( pCNd->HasSwAttrSet() )
        pHistory->CopyFmtAttr( *pCNd->GetpSwAttrSet(), aIdx.GetIndex() );
}


//////////////////////////////////////////////////////////////////////////

SwUndoTblNumFmt::SwUndoTblNumFmt( const SwTableBox& rBox,
									const SfxItemSet* pNewSet )
	: SwUndo( UNDO_TBLNUMFMT ),
	pBoxSet( 0 ), pHistory( 0 ), nFmtIdx( NUMBERFORMAT_TEXT )
{
	bNewFmt = bNewFml = bNewValue = sal_False;
	nNode = rBox.GetSttIdx();

	nNdPos = rBox.IsValidNumTxtNd( 0 == pNewSet );
    SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();

	if( ULONG_MAX != nNdPos )
	{
		SwTxtNode* pTNd = pDoc->GetNodes()[ nNdPos ]->GetTxtNode();

		pHistory = new SwHistory;
		SwRegHistory aRHst( *rBox.GetSttNd(), pHistory );
        // always save all text atttibutes because of possibly overlapping
        // areas of on/off
        pHistory->CopyAttr( pTNd->GetpSwpHints(), nNdPos, 0,
                            pTNd->GetTxt().Len(), true );

        if( pTNd->HasSwAttrSet() )
            pHistory->CopyFmtAttr( *pTNd->GetpSwAttrSet(), nNdPos );

		aStr = pTNd->GetTxt();
		if( pTNd->GetpSwpHints() )
			pTNd->GetpSwpHints()->DeRegister();
    }

    pBoxSet = new SfxItemSet( pDoc->GetAttrPool(), aTableBoxSetRange );
    pBoxSet->Put( rBox.GetFrmFmt()->GetAttrSet() );

    if( pNewSet )
    {
        const SfxPoolItem* pItem;
        if( SFX_ITEM_SET == pNewSet->GetItemState( RES_BOXATR_FORMAT,
                sal_False, &pItem ))
        {
            bNewFmt = sal_True;
            nNewFmtIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
        }
        if( SFX_ITEM_SET == pNewSet->GetItemState( RES_BOXATR_FORMULA,
                sal_False, &pItem ))
        {
            bNewFml = sal_True;
            aNewFml = ((SwTblBoxFormula*)pItem)->GetFormula();
        }
        if( SFX_ITEM_SET == pNewSet->GetItemState( RES_BOXATR_VALUE,
                sal_False, &pItem ))
        {
            bNewValue = sal_True;
            fNewNum = ((SwTblBoxValue*)pItem)->GetValue();
        }
	}

	// wird die History ueberhaupt benoetigt ??
	if( pHistory && !pHistory->Count() )
		DELETEZ( pHistory );
}

SwUndoTblNumFmt::~SwUndoTblNumFmt()
{
	delete pHistory;
	delete pBoxSet;
}

void SwUndoTblNumFmt::UndoImpl(::sw::UndoRedoContext & rContext)
{
	ASSERT( pBoxSet, "Where's the stored item set?" )

    SwDoc & rDoc = rContext.GetDoc();
	SwStartNode* pSttNd = rDoc.GetNodes()[ nNode ]->
							FindSttNodeByType( SwTableBoxStartNode );
	ASSERT( pSttNd, "ohne StartNode kein TabellenBox" );
	SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().GetTblBox(
									pSttNd->GetIndex() );
	ASSERT( pBox, "keine TabellenBox gefunden" );

	SwTableBoxFmt* pFmt = rDoc.MakeTableBoxFmt();
    pFmt->SetFmtAttr( *pBoxSet );
	pBox->ChgFrmFmt( pFmt );

    if( ULONG_MAX == nNdPos )
        return;

	SwTxtNode* pTxtNd = rDoc.GetNodes()[ nNdPos ]->GetTxtNode();
	// wenn mehr als ein Node geloescht wurde, dann wurden auch
	// alle "Node"-Attribute gespeichert
    if( pTxtNd->HasSwAttrSet() )
		pTxtNd->ResetAllAttr();

	if( pTxtNd->GetpSwpHints() && aStr.Len() )
        pTxtNd->ClearSwpHintsArr( true );

    // ChgTextToNum(..) only acts when the strings are different. We
    // need to do the same here.
    if( pTxtNd->GetTxt() != aStr )
    {
        rDoc.DeleteRedline( *( pBox->GetSttNd() ), false, USHRT_MAX );

        SwIndex aIdx( pTxtNd, 0 );
        if( aStr.Len() )
        {
            pTxtNd->EraseText( aIdx );
            pTxtNd->InsertText( aStr, aIdx,
                IDocumentContentOperations::INS_NOHINTEXPAND );
        }
    }

	if( pHistory )
	{
		sal_uInt16 nTmpEnd = pHistory->GetTmpEnd();
		pHistory->TmpRollback( &rDoc, 0 );
		pHistory->SetTmpEnd( nTmpEnd );
	}

    SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
	pPam->DeleteMark();
	pPam->GetPoint()->nNode = nNode + 1;
	pPam->GetPoint()->nContent.Assign( pTxtNd, 0 );
}

/** switch the RedlineMode on the given document, using
 * SetRedlineMode_intern. This class set the mode in the constructor,
 * and changes it back in the destructor, i.e. it uses the
 * initialization-is-resource-acquisition idiom.
 */
class RedlineModeInternGuard
{
    SwDoc& mrDoc;
    RedlineMode_t meOldRedlineMode;

public:
    RedlineModeInternGuard(
        SwDoc& rDoc,                      /// change mode of this document
        RedlineMode_t eNewRedlineMode,    /// new redline mode
        RedlineMode_t eRedlineModeMask  = (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE /*change only bits set in this mask*/));

    ~RedlineModeInternGuard();
};

RedlineModeInternGuard::RedlineModeInternGuard(
    SwDoc& rDoc,
    RedlineMode_t eNewRedlineMode,
    RedlineMode_t eRedlineModeMask )
    : mrDoc( rDoc ),
      meOldRedlineMode( rDoc.GetRedlineMode() )
{
    mrDoc.SetRedlineMode_intern((RedlineMode_t)( ( meOldRedlineMode & ~eRedlineModeMask ) |
									 ( eNewRedlineMode & eRedlineModeMask ) ));
}

RedlineModeInternGuard::~RedlineModeInternGuard()
{
    mrDoc.SetRedlineMode_intern( meOldRedlineMode );
}



void SwUndoTblNumFmt::RedoImpl(::sw::UndoRedoContext & rContext)
{
	// konnte die Box veraendert werden ?
	if( !pBoxSet )
		return ;

    SwDoc & rDoc = rContext.GetDoc();
    SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());

	pPam->DeleteMark();
	pPam->GetPoint()->nNode = nNode;

    SwNode * pNd = & pPam->GetPoint()->nNode.GetNode();
	SwStartNode* pSttNd = pNd->FindSttNodeByType( SwTableBoxStartNode );
	ASSERT( pSttNd, "ohne StartNode kein TabellenBox" );
	SwTableBox* pBox = pSttNd->FindTableNode()->GetTable().GetTblBox(
									pSttNd->GetIndex() );
	ASSERT( pBox, "keine TabellenBox gefunden" );

	SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
	if(	bNewFmt || bNewFml || bNewValue )
	{
		SfxItemSet aBoxSet( rDoc.GetAttrPool(),
								RES_BOXATR_FORMAT, RES_BOXATR_VALUE );

		// JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
		//				Sorge dafuer, das der Text auch entsprechend
		//				formatiert wird!
		pBoxFmt->LockModify();

		if( bNewFml )
			aBoxSet.Put( SwTblBoxFormula( aNewFml ));
		else
            pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMULA );
		if( bNewFmt )
			aBoxSet.Put( SwTblBoxNumFormat( nNewFmtIdx ));
		else
            pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
		if( bNewValue )
			aBoxSet.Put( SwTblBoxValue( fNewNum ));
		else
            pBoxFmt->ResetFmtAttr( RES_BOXATR_VALUE );
		pBoxFmt->UnlockModify();

        // dvo: When redlining is (was) enabled, setting the attribute
        // will also change the cell content. To allow this, the
        // REDLINE_IGNORE flag must be removed during Redo. #108450#
        RedlineModeInternGuard aGuard( rDoc, nsRedlineMode_t::REDLINE_NONE, nsRedlineMode_t::REDLINE_IGNORE );
        pBoxFmt->SetFmtAttr( aBoxSet );
	}
	else if( NUMBERFORMAT_TEXT != nFmtIdx )
	{
		SfxItemSet aBoxSet( rDoc.GetAttrPool(),
							RES_BOXATR_FORMAT, RES_BOXATR_VALUE );

		aBoxSet.Put( SwTblBoxNumFormat( nFmtIdx ));
		aBoxSet.Put( SwTblBoxValue( fNum ));

		// JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
		//				Sorge dafuer, das der Text auch entsprechend
		//				formatiert wird!
		pBoxFmt->LockModify();
        pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMULA );
		pBoxFmt->UnlockModify();

        // dvo: When redlining is (was) enabled, setting the attribute
        // will also change the cell content. To allow this, the
        // REDLINE_IGNORE flag must be removed during Redo. #108450#
        RedlineModeInternGuard aGuard( rDoc, nsRedlineMode_t::REDLINE_NONE, nsRedlineMode_t::REDLINE_IGNORE );
        pBoxFmt->SetFmtAttr( aBoxSet );
	}
	else
	{
		// es ist keine Zahl

		// JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht.
		//				Sorge dafuer, das der Text auch entsprechend
		//				formatiert wird!
        pBoxFmt->SetFmtAttr( *GetDfltAttr( RES_BOXATR_FORMAT ));

        pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
	}

	if( bNewFml )
	{
		// egal was gesetzt wurde, ein Update der Tabelle macht sich immer gut
		SwTableFmlUpdate aTblUpdate( &pSttNd->FindTableNode()->GetTable() );
		rDoc.UpdateTblFlds( &aTblUpdate );
	}

	if( !pNd->IsCntntNode() )
		pNd = rDoc.GetNodes().GoNext( &pPam->GetPoint()->nNode );
	pPam->GetPoint()->nContent.Assign( (SwCntntNode*)pNd, 0 );
}

void SwUndoTblNumFmt::SetBox( const SwTableBox& rBox )
{
	nNode = rBox.GetSttIdx();
}


//////////////////////////////////////////////////////////////////////////

_UndoTblCpyTbl_Entry::_UndoTblCpyTbl_Entry( const SwTableBox& rBox )
	: nBoxIdx( rBox.GetSttIdx() ), nOffset( 0 ),
	pBoxNumAttr( 0 ), pUndo( 0 ), bJoin( false )
{
}

_UndoTblCpyTbl_Entry::~_UndoTblCpyTbl_Entry()
{
	delete pUndo;
	delete pBoxNumAttr;
}


SwUndoTblCpyTbl::SwUndoTblCpyTbl()
	: SwUndo( UNDO_TBLCPYTBL ), pInsRowUndo( 0 )
{
	pArr = new _UndoTblCpyTbl_Entries;
}

SwUndoTblCpyTbl::~SwUndoTblCpyTbl()
{
	delete pArr;
	delete pInsRowUndo;
}

void SwUndoTblCpyTbl::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
    _DEBUG_REDLINE( &rDoc )

	SwTableNode* pTblNd = 0;
	for( sal_uInt16 n = pArr->Count(); n; )
	{
		_UndoTblCpyTbl_Entry* pEntry = (*pArr)[ --n ];
		sal_uLong nSttPos = pEntry->nBoxIdx + pEntry->nOffset;
        SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->StartOfSectionNode();
		if( !pTblNd )
			pTblNd = pSNd->FindTableNode();

		SwTableBox& rBox = *pTblNd->GetTable().GetTblBox( nSttPos );

		SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
		rDoc.GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)rDoc.GetDfltTxtFmtColl() );

        // b62341295: Redline for copying tables
        const SwNode *pEndNode = rBox.GetSttNd()->EndOfSectionNode();
		SwPaM aPam( aInsIdx.GetNode(), *pEndNode );
        SwUndoDelete* pUndo = 0;

        if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
        {
            bool bDeleteCompleteParagraph = false;
            bool bShiftPam = false;
            // There are a couple of different situations to consider during redlining
            if( pEntry->pUndo )
            {
                SwUndoDelete *const pUndoDelete =
                    dynamic_cast<SwUndoDelete*>(pEntry->pUndo);
                SwUndoRedlineDelete *const pUndoRedlineDelete =
                    dynamic_cast<SwUndoRedlineDelete*>(pEntry->pUndo);
                OSL_ASSERT(pUndoDelete || pUndoRedlineDelete);
                if (pUndoRedlineDelete)
                {
                    // The old content was not empty or he has been merged with the new content
                    bDeleteCompleteParagraph = !pEntry->bJoin; // bJoin is set when merged
                    // Set aTmpIdx to the beginning fo the old content
                    SwNodeIndex aTmpIdx( *pEndNode,
                            pUndoRedlineDelete->NodeDiff()-1 );
                    SwTxtNode *pTxt = aTmpIdx.GetNode().GetTxtNode();
                    if( pTxt )
                    {
                        aPam.GetPoint()->nNode = *pTxt;
                        aPam.GetPoint()->nContent.Assign( pTxt,
                                pUndoRedlineDelete->ContentStart() );
                    }
                    else
                        *aPam.GetPoint() = SwPosition( aTmpIdx );
                }
                else if (pUndoDelete && pUndoDelete->IsDelFullPara())
                {
                    // When the old content was an empty paragraph, but could not be joined
                    // with the new content (e.g. because of a section or table)
                    // We "save" the aPam.Point, we go one step backwards (because later on the
                    // empty paragraph will be inserted by the undo) and set the "ShiftPam-flag
                    // for step forward later on.
                    bDeleteCompleteParagraph = true;
                    bShiftPam = true;
                    SwNodeIndex aTmpIdx( *pEndNode, -1 );
                    SwTxtNode *pTxt = aTmpIdx.GetNode().GetTxtNode();
                    if( pTxt )
                    {
                        aPam.GetPoint()->nNode = *pTxt;
                        aPam.GetPoint()->nContent.Assign( pTxt, 0 );
                    }
                    else
                        *aPam.GetPoint() = SwPosition( aTmpIdx );
                }
            }
            rDoc.DeleteRedline( aPam, true, USHRT_MAX );

            if( pEntry->pUndo )
            {
                pEntry->pUndo->UndoImpl(rContext);
                delete pEntry->pUndo;
                pEntry->pUndo = 0;
            }
            if( bShiftPam )
            {
                // The aPam.Point is at the moment at the last position of the new content and has to be
                // moved to the first postion of the old content for the SwUndoDelete operation
                SwNodeIndex aTmpIdx( aPam.GetPoint()->nNode, 1 );
                SwTxtNode *pTxt = aTmpIdx.GetNode().GetTxtNode();
                if( pTxt )
                {
                    aPam.GetPoint()->nNode = *pTxt;
                    aPam.GetPoint()->nContent.Assign( pTxt, 0 );
                }
                else
                    *aPam.GetPoint() = SwPosition( aTmpIdx );
            }
            pUndo = new SwUndoDelete( aPam, bDeleteCompleteParagraph, sal_True );
        }
        else
        {
            pUndo = new SwUndoDelete( aPam, true );
            if( pEntry->pUndo )
            {
                pEntry->pUndo->UndoImpl(rContext);
                delete pEntry->pUndo;
                pEntry->pUndo = 0;
            }
        }
		pEntry->pUndo = pUndo;

		aInsIdx = rBox.GetSttIdx() + 1;
		rDoc.GetNodes().Delete( aInsIdx, 1 );

		SfxItemSet aTmpSet( rDoc.GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
												RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
		aTmpSet.Put( rBox.GetFrmFmt()->GetAttrSet() );
		if( aTmpSet.Count() )
		{
			SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
            pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
            pBoxFmt->ResetFmtAttr( RES_VERT_ORIENT );
		}

		if( pEntry->pBoxNumAttr )
		{
            rBox.ClaimFrmFmt()->SetFmtAttr( *pEntry->pBoxNumAttr );
			delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
		}

		if( aTmpSet.Count() )
		{
			pEntry->pBoxNumAttr = new SfxItemSet( rDoc.GetAttrPool(),
									RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
									RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
			pEntry->pBoxNumAttr->Put( aTmpSet );
		}

		pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
	}

	if( pInsRowUndo )
    {
        pInsRowUndo->UndoImpl(rContext);
    }
    _DEBUG_REDLINE( &rDoc )
}

void SwUndoTblCpyTbl::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
    _DEBUG_REDLINE( &rDoc )

	if( pInsRowUndo )
    {
        pInsRowUndo->RedoImpl(rContext);
    }

	SwTableNode* pTblNd = 0;
	for( sal_uInt16 n = 0; n < pArr->Count(); ++n )
	{
		_UndoTblCpyTbl_Entry* pEntry = (*pArr)[ n ];
		sal_uLong nSttPos = pEntry->nBoxIdx + pEntry->nOffset;
        SwStartNode* pSNd = rDoc.GetNodes()[ nSttPos ]->StartOfSectionNode();
		if( !pTblNd )
			pTblNd = pSNd->FindTableNode();

		SwTableBox& rBox = *pTblNd->GetTable().GetTblBox( nSttPos );

		SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );

        // b62341295: Redline for copying tables - Start.
		rDoc.GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)rDoc.GetDfltTxtFmtColl() );
		SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode());
        SwUndo* pUndo = IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) ? 0 : new SwUndoDelete( aPam, sal_True );
		if( pEntry->pUndo )
        {
            pEntry->pUndo->UndoImpl(rContext);
            if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ) )
            {
                // PrepareRedline has to be called with the beginning of the old content
                // When new and old content has been joined, the rIter.pAktPam has been set
                // by the Undo operation to this point.
                // Otherwise aInsIdx has been moved during the Undo operation
                if( pEntry->bJoin )
                {
                    SwPaM const& rLastPam =
                        rContext.GetCursorSupplier().GetCurrentShellCursor();
                    pUndo = PrepareRedline( &rDoc, rBox, *rLastPam.GetPoint(),
                                            pEntry->bJoin, true );
                }
                else
                {
                    SwPosition aTmpPos( aInsIdx );
                    pUndo = PrepareRedline( &rDoc, rBox, aTmpPos, pEntry->bJoin, true );
                }
            }
			delete pEntry->pUndo;
            pEntry->pUndo = 0;
		}
		pEntry->pUndo = pUndo;
        // b62341295: Redline for copying tables - End.

		aInsIdx = rBox.GetSttIdx() + 1;
		rDoc.GetNodes().Delete( aInsIdx, 1 );

		SfxItemSet aTmpSet( rDoc.GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
												RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
		aTmpSet.Put( rBox.GetFrmFmt()->GetAttrSet() );
		if( aTmpSet.Count() )
		{
			SwFrmFmt* pBoxFmt = rBox.ClaimFrmFmt();
            pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
            pBoxFmt->ResetFmtAttr( RES_VERT_ORIENT );
		}
		if( pEntry->pBoxNumAttr )
		{
            rBox.ClaimFrmFmt()->SetFmtAttr( *pEntry->pBoxNumAttr );
			delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
		}

		if( aTmpSet.Count() )
		{
			pEntry->pBoxNumAttr = new SfxItemSet( rDoc.GetAttrPool(),
									RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
									RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
			pEntry->pBoxNumAttr->Put( aTmpSet );
		}

		pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
	}
    _DEBUG_REDLINE( &rDoc )
}

void SwUndoTblCpyTbl::AddBoxBefore( const SwTableBox& rBox, sal_Bool bDelCntnt )
{
    if( pArr->Count() && !bDelCntnt )
		return;

	_UndoTblCpyTbl_Entry* pEntry = new _UndoTblCpyTbl_Entry( rBox );
	pArr->Insert( pEntry, pArr->Count() );

	SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
    _DEBUG_REDLINE( pDoc )
	if( bDelCntnt )
	{
		SwNodeIndex aInsIdx( *rBox.GetSttNd(), 1 );
		pDoc->GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl() );
		SwPaM aPam( aInsIdx.GetNode(), *rBox.GetSttNd()->EndOfSectionNode() );

        if( !pDoc->IsRedlineOn() )
            pEntry->pUndo = new SwUndoDelete( aPam, sal_True );
	}

	pEntry->pBoxNumAttr = new SfxItemSet( pDoc->GetAttrPool(),
									RES_BOXATR_FORMAT, RES_BOXATR_VALUE,
									RES_VERT_ORIENT, RES_VERT_ORIENT, 0 );
	pEntry->pBoxNumAttr->Put( rBox.GetFrmFmt()->GetAttrSet() );
	if( !pEntry->pBoxNumAttr->Count() )
		delete pEntry->pBoxNumAttr, pEntry->pBoxNumAttr = 0;
    _DEBUG_REDLINE( pDoc )
}

void SwUndoTblCpyTbl::AddBoxAfter( const SwTableBox& rBox, const SwNodeIndex& rIdx, sal_Bool bDelCntnt )
{
	_UndoTblCpyTbl_Entry* pEntry = (*pArr)[ pArr->Count() - 1 ];

	// wurde der Inhalt geloescht, so loesche jetzt auch noch den temp.
	// erzeugten Node
	if( bDelCntnt )
	{
        SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
        _DEBUG_REDLINE( pDoc )

        if( pDoc->IsRedlineOn() )
        {
            SwPosition aTmpPos( rIdx );
            pEntry->pUndo = PrepareRedline( pDoc, rBox, aTmpPos, pEntry->bJoin, false );
        }
		SwNodeIndex aDelIdx( *rBox.GetSttNd(), 1 );
		rBox.GetFrmFmt()->GetDoc()->GetNodes().Delete( aDelIdx, 1 );
        _DEBUG_REDLINE( pDoc )
    }

	pEntry->nOffset = rBox.GetSttIdx() - pEntry->nBoxIdx;
}

// PrepareRedline is called from AddBoxAfter() and from Redo() in slightly different situations.
// bRedo is set by calling from Redo()
// rJoin is false by calling from AddBoxAfter() and will be set if the old and new content has
// been merged.
// rJoin is true if Redo() is calling and the content has already been merged

SwUndo* SwUndoTblCpyTbl::PrepareRedline( SwDoc* pDoc, const SwTableBox& rBox,
    const SwPosition& rPos, bool& rJoin, bool bRedo )
{
    SwUndo *pUndo = 0;
    // b62341295: Redline for copying tables
    // What's to do?
    // Mark the cell content before rIdx as insertion,
    // mark the cell content behind rIdx as deletion
    // merge text nodes at rIdx if possible
    RedlineMode_t eOld = pDoc->GetRedlineMode();
    pDoc->SetRedlineMode_intern((RedlineMode_t)( ( eOld | nsRedlineMode_t::REDLINE_DONTCOMBINE_REDLINES ) &
									 ~nsRedlineMode_t::REDLINE_IGNORE ));
    SwPosition aInsertEnd( rPos );
    SwTxtNode* pTxt;
    if( !rJoin )
    {
        // If the content is not merged, the end of the insertion is at the end of the node
        // _before_ the given position rPos
        --aInsertEnd.nNode;
        pTxt = aInsertEnd.nNode.GetNode().GetTxtNode();
        if( pTxt )
        {
            aInsertEnd.nContent.Assign( pTxt, pTxt->GetTxt().Len() );
            if( !bRedo && rPos.nNode.GetNode().GetTxtNode() )
            {   // Try to merge, if not called by Redo()
                rJoin = true;
                pTxt->JoinNext();
            }
        }
        else
            aInsertEnd.nContent = SwIndex( 0 );
    }
    // For joined (merged) contents the start of deletionm and end of insertion are identical
    // otherwise adjacent nodes.
    SwPosition aDeleteStart( rJoin ? aInsertEnd : rPos );
    if( !rJoin )
    {
        pTxt = aDeleteStart.nNode.GetNode().GetTxtNode();
        if( pTxt )
            aDeleteStart.nContent.Assign( pTxt, 0 );
    }
    SwPosition aCellEnd( SwNodeIndex( *rBox.GetSttNd()->EndOfSectionNode(), -1 ) );
    pTxt = aCellEnd.nNode.GetNode().GetTxtNode();
    if( pTxt )
        aCellEnd.nContent.Assign( pTxt, pTxt->GetTxt().Len() );
    if( aDeleteStart != aCellEnd )
    {   // If the old (deleted) part is not empty, here we are...
        SwPaM aDeletePam( aDeleteStart, aCellEnd );
        pUndo = new SwUndoRedlineDelete( aDeletePam, UNDO_DELETE );
        pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_DELETE, aDeletePam ), true );
    }
    else if( !rJoin ) // If the old part is empty and joined, we are finished
    {   // if it is not joined, we have to delete this empty paragraph
        aCellEnd = SwPosition(
            SwNodeIndex( *rBox.GetSttNd()->EndOfSectionNode() ));
        SwPaM aTmpPam( aDeleteStart, aCellEnd );
        pUndo = new SwUndoDelete( aTmpPam, sal_True );
    }
    SwPosition aCellStart( SwNodeIndex( *rBox.GetSttNd(), 2 ) );
    pTxt = aCellStart.nNode.GetNode().GetTxtNode();
    if( pTxt )
        aCellStart.nContent.Assign( pTxt, 0 );
    if( aCellStart != aInsertEnd ) // An empty insertion will not been marked
    {
        SwPaM aTmpPam( aCellStart, aInsertEnd );
        pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, aTmpPam ), true );
    }

    pDoc->SetRedlineMode_intern( eOld );
    return pUndo;
}


sal_Bool SwUndoTblCpyTbl::InsertRow( SwTable& rTbl, const SwSelBoxes& rBoxes,
								sal_uInt16 nCnt )
{
	SwTableNode* pTblNd = (SwTableNode*)rTbl.GetTabSortBoxes()[0]->
								GetSttNd()->FindTableNode();

	SwTableSortBoxes aTmpLst( 0, 5 );
	pInsRowUndo = new SwUndoTblNdsChg( UNDO_TABLE_INSROW, rBoxes, *pTblNd,
									   0, 0, nCnt, sal_True, sal_False );
	aTmpLst.Insert( &rTbl.GetTabSortBoxes(), 0, rTbl.GetTabSortBoxes().Count() );

	sal_Bool bRet = rTbl.InsertRow( rTbl.GetFrmFmt()->GetDoc(), rBoxes, nCnt, sal_True );
	if( bRet )
		pInsRowUndo->SaveNewBoxes( *pTblNd, aTmpLst );
	else
		delete pInsRowUndo, pInsRowUndo = 0;
	return bRet;
}

sal_Bool SwUndoTblCpyTbl::IsEmpty() const
{
	return !pInsRowUndo && !pArr->Count();
}


//////////////////////////////////////////////////////////////////////////

SwUndoCpyTbl::SwUndoCpyTbl()
	: SwUndo( UNDO_CPYTBL ), pDel( 0 ), nTblNode( 0 )
{
}

SwUndoCpyTbl::~SwUndoCpyTbl()
{
	delete pDel;
}

void SwUndoCpyTbl::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc & rDoc = rContext.GetDoc();
	SwTableNode* pTNd = rDoc.GetNodes()[ nTblNode ]->GetTableNode();

	// harte SeitenUmbrueche am nachfolgenden Node verschieben
	SwCntntNode* pNextNd = rDoc.GetNodes()[ pTNd->EndOfSectionIndex()+1 ]->GetCntntNode();
	if( pNextNd )
	{
		SwFrmFmt* pTableFmt = pTNd->GetTable().GetFrmFmt();
		const SfxPoolItem *pItem;

		if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_PAGEDESC,
			sal_False, &pItem ) )
			pNextNd->SetAttr( *pItem );

		if( SFX_ITEM_SET == pTableFmt->GetItemState( RES_BREAK,
			sal_False, &pItem ) )
			pNextNd->SetAttr( *pItem );
	}

	SwPaM aPam( *pTNd, *pTNd->EndOfSectionNode(), 0 , 1 );
	pDel = new SwUndoDelete( aPam, sal_True );
}

void SwUndoCpyTbl::RedoImpl(::sw::UndoRedoContext & rContext)
{
    pDel->UndoImpl(rContext);
	delete pDel, pDel = 0;
}


//////////////////////////////////////////////////////////////////////////

SwUndoSplitTbl::SwUndoSplitTbl( const SwTableNode& rTblNd,
    SwSaveRowSpan* pRowSp, sal_uInt16 eMode, sal_Bool bNewSize )
	: SwUndo( UNDO_SPLIT_TABLE ),
    nTblNode( rTblNd.GetIndex() ), nOffset( 0 ), mpSaveRowSpan( pRowSp ), pSavTbl( 0 ),
	pHistory( 0 ), nMode( eMode ), nFmlEnd( 0 ), bCalcNewSize( bNewSize )
{
	switch( nMode )
	{
	case HEADLINE_BOXATRCOLLCOPY:
			pHistory = new SwHistory;
			// kein break;
	case HEADLINE_BORDERCOPY:
	case HEADLINE_BOXATTRCOPY:
		pSavTbl = new _SaveTable( rTblNd.GetTable(), 1, sal_False );
		break;
	}
}

SwUndoSplitTbl::~SwUndoSplitTbl()
{
	delete pSavTbl;
	delete pHistory;
    delete mpSaveRowSpan;
}

void SwUndoSplitTbl::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc *const pDoc = & rContext.GetDoc();
    SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());

	pPam->DeleteMark();
	SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
	rIdx = nTblNode + nOffset;

	//Den implizit erzeugten Absatz wieder entfernen.
	pDoc->GetNodes().Delete( rIdx, 1 );

	rIdx = nTblNode + nOffset;
	SwTableNode* pTblNd = rIdx.GetNode().GetTableNode();
	SwTable& rTbl = pTblNd->GetTable();

	SwTableFmlUpdate aMsgHnt( &rTbl );
	aMsgHnt.eFlags = TBL_BOXPTR;
	pDoc->UpdateTblFlds( &aMsgHnt );

	switch( nMode )
	{
	case HEADLINE_BOXATRCOLLCOPY:
		if( pHistory )
			pHistory->TmpRollback( pDoc, nFmlEnd );

		// kein break
	case HEADLINE_BOXATTRCOPY:
	case HEADLINE_BORDERCOPY:
		{
			pSavTbl->CreateNew( rTbl, sal_False );
			pSavTbl->RestoreAttr( rTbl );
		}
		break;

	case HEADLINE_CNTNTCOPY:
		// die erzeugte 1. Line muss wieder entfernt werden
		{
			SwSelBoxes aSelBoxes;
			SwTableBox* pBox = rTbl.GetTblBox( nTblNode + nOffset + 1 );
			rTbl.SelLineFromBox( pBox, aSelBoxes, sal_True );
            _FndBox aTmpBox( 0, 0 );
            aTmpBox.SetTableLines( aSelBoxes, rTbl );
            aTmpBox.DelFrms( rTbl );
			rTbl.DeleteSel( pDoc, aSelBoxes, 0, 0, sal_False, sal_False );
		}
		break;
	}

	pDoc->GetNodes().MergeTable( rIdx );

	if( pHistory )
	{
		pHistory->TmpRollback( pDoc, 0 );
		pHistory->SetTmpEnd( pHistory->Count() );
	}
    if( mpSaveRowSpan )
    {
        pTblNd = rIdx.GetNode().FindTableNode();
        if( pTblNd )
            pTblNd->GetTable().RestoreRowSpan( *mpSaveRowSpan );
    }
	ClearFEShellTabCols();
}

void SwUndoSplitTbl::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc *const pDoc = & rContext.GetDoc();
    SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());

	pPam->DeleteMark();
	pPam->GetPoint()->nNode = nTblNode;
	pDoc->SplitTable( *pPam->GetPoint(), nMode, bCalcNewSize );

	ClearFEShellTabCols();
}

void SwUndoSplitTbl::RepeatImpl(::sw::RepeatContext & rContext)
{
    SwPaM *const pPam = & rContext.GetRepeatPaM();
    SwDoc *const pDoc = & rContext.GetDoc();

	pDoc->SplitTable( *pPam->GetPoint(), nMode, bCalcNewSize );
	ClearFEShellTabCols();
}

void SwUndoSplitTbl::SaveFormula( SwHistory& rHistory )
{
	if( !pHistory )
		pHistory = new SwHistory;

	nFmlEnd = rHistory.Count();
	pHistory->Move( 0, &rHistory );
}


//////////////////////////////////////////////////////////////////////////

SwUndoMergeTbl::SwUndoMergeTbl( const SwTableNode& rTblNd,
								const SwTableNode& rDelTblNd,
								sal_Bool bWithPrv, sal_uInt16 nMd )
	: SwUndo( UNDO_MERGE_TABLE ), pSavTbl( 0 ),
	pHistory( 0 ), nMode( nMd ), bWithPrev( bWithPrv )
{
	// Endnode der letzen Tabellenzelle merken, die auf der Position verbleibt
	if( bWithPrev )
		nTblNode = rDelTblNd.EndOfSectionIndex() - 1;
	else
		nTblNode = rTblNd.EndOfSectionIndex() - 1;

	aName = rDelTblNd.GetTable().GetFrmFmt()->GetName();
	pSavTbl = new _SaveTable( rDelTblNd.GetTable() );

	pSavHdl = bWithPrev ? new _SaveTable( rTblNd.GetTable(), 1 ) : 0;
}

SwUndoMergeTbl::~SwUndoMergeTbl()
{
	delete pSavTbl;
	delete pSavHdl;
	delete pHistory;
}

void SwUndoMergeTbl::UndoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc *const pDoc = & rContext.GetDoc();
    SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());

	pPam->DeleteMark();
	SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
	rIdx = nTblNode;

	SwTableNode* pTblNd = rIdx.GetNode().FindTableNode();
	SwTable* pTbl = &pTblNd->GetTable();

	SwTableFmlUpdate aMsgHnt( pTbl );
	aMsgHnt.eFlags = TBL_BOXPTR;
	pDoc->UpdateTblFlds( &aMsgHnt );

	//Lines fuer das Layout-Update herausuchen.
	_FndBox aFndBox( 0, 0 );
	aFndBox.SetTableLines( *pTbl );
	aFndBox.DelFrms( *pTbl );
    // ? TL_CHART2: notification or locking of controller required ?

	SwTableNode* pNew = pDoc->GetNodes().SplitTable( rIdx, sal_True, sal_False );

	//Layout updaten
	aFndBox.MakeFrms( *pTbl );
    // ? TL_CHART2: notification or locking of controller required ?

	if( bWithPrev )
	{
		// den Namen umsetzen
		pNew->GetTable().GetFrmFmt()->SetName( pTbl->GetFrmFmt()->GetName() );
		pSavHdl->RestoreAttr( pNew->GetTable() );
	}
	else
		pTbl = &pNew->GetTable();
	pTbl->GetFrmFmt()->SetName( aName );

//	pSavTbl->CreateNew( *pTbl, sal_False );
	pSavTbl->RestoreAttr( *pTbl );


	if( pHistory )
	{
		pHistory->TmpRollback( pDoc, 0 );
		pHistory->SetTmpEnd( pHistory->Count() );
	}

	// fuer die neue Tabelle die Frames anlegen
	SwNodeIndex aTmpIdx( *pNew );
	pNew->MakeFrms( &aTmpIdx );

	// Cursor  irgendwo in den Content stellen
	SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &rIdx );
	pPam->GetPoint()->nContent.Assign( pCNd, 0 );

	ClearFEShellTabCols();

    // TL_CHART2: need to inform chart of probably changed cell names
    SwChartDataProvider *pPCD = pDoc->GetChartDataProvider();
    if (pPCD)
    {
        pDoc->UpdateCharts( pTbl->GetFrmFmt()->GetName() );
        pDoc->UpdateCharts( pNew->GetTable().GetFrmFmt()->GetName() );
    }
}

void SwUndoMergeTbl::RedoImpl(::sw::UndoRedoContext & rContext)
{
    SwDoc *const pDoc = & rContext.GetDoc();
    SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());

	pPam->DeleteMark();
	pPam->GetPoint()->nNode = nTblNode;
	if( bWithPrev )
		pPam->GetPoint()->nNode = nTblNode + 3;
	else
		pPam->GetPoint()->nNode = nTblNode;

	pDoc->MergeTable( *pPam->GetPoint(), bWithPrev, nMode );

	ClearFEShellTabCols();
}

void SwUndoMergeTbl::RepeatImpl(::sw::RepeatContext & rContext)
{
    SwDoc *const pDoc = & rContext.GetDoc();
    SwPaM *const pPam = & rContext.GetRepeatPaM();

	pDoc->MergeTable( *pPam->GetPoint(), bWithPrev, nMode );
	ClearFEShellTabCols();
}

void SwUndoMergeTbl::SaveFormula( SwHistory& rHistory )
{
	if( !pHistory )
		pHistory = new SwHistory;
	pHistory->Move( 0, &rHistory );
}


//////////////////////////////////////////////////////////////////////////

void InsertSort( SvUShorts& rArr, sal_uInt16 nIdx, sal_uInt16* pInsPos )
{
	sal_uInt16 nO	= rArr.Count(), nM, nU = 0;
	if( nO > 0 )
	{
		nO--;
		while( nU <= nO )
		{
			nM = nU + ( nO - nU ) / 2;
			if( *(rArr.GetData() + nM) == nIdx )
			{
				ASSERT( sal_False, "Index ist schon vorhanden, darf nie sein!" );
				return;
			}
			if( *(rArr.GetData() + nM) < nIdx )
				nU = nM + 1;
			else if( nM == 0 )
				break;
			else
				nO = nM - 1;
		}
	}
	rArr.Insert( nIdx, nU );
	if( pInsPos )
		*pInsPos = nU;
}

void InsertSort( SvULongs& rArr, sal_uLong nIdx, sal_uInt16* pInsPos )
{
	sal_uInt16 nO	= rArr.Count(), nM, nU = 0;
	if( nO > 0 )
	{
		nO--;
		while( nU <= nO )
		{
			nM = nU + ( nO - nU ) / 2;
			if( *(rArr.GetData() + nM) == nIdx )
			{
				ASSERT( sal_False, "Index ist schon vorhanden, darf nie sein!" );
				return;
			}
			if( *(rArr.GetData() + nM) < nIdx )
				nU = nM + 1;
			else if( nM == 0 )
				break;
			else
				nO = nM - 1;
		}
	}
	rArr.Insert( nIdx, nU );
	if( pInsPos )
		*pInsPos = nU;
}

#if defined( JP_DEBUG ) && defined(DBG_UTIL)


void DumpDoc( SwDoc* pDoc, const String& rFileNm )
{
	Writer* pWrt = SwIoSystem::GetWriter( "DEBUG" );
	if( pWrt )
	{
		SvFileStream aStream( rFileNm, STREAM_STD_WRITE );
		SwPaM* pPam = new SwPaM( pDoc, SwPosition( pDoc->GetNodes().EndOfContent ,
												 pDoc->GetNodes().EndOfContent ));
		pPam->Move( fnMoveBackward, fnGoDoc );
		pPam->SetMark();
		pPam->Move( fnMoveForward, fnGoDoc );

		pWrt->Write( pPam, *pDoc, aStream, rFileNm.GetStr() );

		delete pPam;
	}
}
void CheckTable( const SwTable& rTbl )
{
	const SwNodes& rNds = rTbl.GetFrmFmt()->GetDoc()->GetNodes();
	const SwTableSortBoxes& rSrtArr = pTblNd->GetTable().GetTabSortBoxes();
	for( sal_uInt16 n = 0; n < rSrtArr.Count(); ++n )
	{
		const SwTableBox* pBox = rSrtArr[ n ];
		const SwNode* pNd = pBox->GetSttNd();
		ASSERT( rNds[ *pBox->GetSttIdx() ] == pNd, "Box mit falchem StartNode"  );
	}
}
#endif


