/**************************************************************
 *
 * 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_sc.hxx"

// INCLUDE ---------------------------------------------------------------

#include <sfx2/app.hxx>

#include "undodat.hxx"
#include "undoutil.hxx"
#include "undoolk.hxx"
#include "document.hxx"
#include "docsh.hxx"
#include "tabvwsh.hxx"
#include "olinetab.hxx"
#include "dbcolect.hxx"
#include "rangenam.hxx"
#include "pivot.hxx"
#include "globstr.hrc"
#include "global.hxx"
#include "target.hxx"
#include "chartarr.hxx"
#include "dbdocfun.hxx"
#include "olinefun.hxx"
#include "dpobject.hxx"
#include "attrib.hxx"
#include "hints.hxx"
#include "sc.hrc"

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

TYPEINIT1(ScUndoDoOutline,          ScSimpleUndo);
TYPEINIT1(ScUndoMakeOutline,        ScSimpleUndo);
TYPEINIT1(ScUndoOutlineLevel,       ScSimpleUndo);
TYPEINIT1(ScUndoOutlineBlock,       ScSimpleUndo);
TYPEINIT1(ScUndoRemoveAllOutlines,  ScSimpleUndo);
TYPEINIT1(ScUndoAutoOutline,        ScSimpleUndo);
TYPEINIT1(ScUndoSubTotals,          ScDBFuncUndo);
TYPEINIT1(ScUndoSort,               ScDBFuncUndo);
TYPEINIT1(ScUndoQuery,              ScDBFuncUndo);
TYPEINIT1(ScUndoAutoFilter,         ScDBFuncUndo);
TYPEINIT1(ScUndoDBData,             ScSimpleUndo);
TYPEINIT1(ScUndoImportData,         ScSimpleUndo);
TYPEINIT1(ScUndoRepeatDB,           ScSimpleUndo);
//UNUSED2008-05  TYPEINIT1(ScUndoPivot,              ScSimpleUndo);
TYPEINIT1(ScUndoDataPilot,          ScSimpleUndo);
TYPEINIT1(ScUndoConsolidate,        ScSimpleUndo);
TYPEINIT1(ScUndoChartData,          ScSimpleUndo);

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


//
//		Outline-Gruppen ein- oder ausblenden
//

ScUndoDoOutline::ScUndoDoOutline( ScDocShell* pNewDocShell,
							SCCOLROW nNewStart, SCCOLROW nNewEnd, SCTAB nNewTab,
							ScDocument* pNewUndoDoc, sal_Bool bNewColumns,
							sal_uInt16 nNewLevel, sal_uInt16 nNewEntry, sal_Bool bNewShow ) :
	ScSimpleUndo( pNewDocShell ),
	nStart( nNewStart ),
	nEnd( nNewEnd ),
	nTab( nNewTab ),
	pUndoDoc( pNewUndoDoc ),
	bColumns( bNewColumns ),
	nLevel( nNewLevel ),
	nEntry( nNewEntry ),
	bShow( bNewShow )
{
}

__EXPORT ScUndoDoOutline::~ScUndoDoOutline()
{
	delete pUndoDoc;
}

String __EXPORT ScUndoDoOutline::GetComment() const
{	// Detail einblenden" "Detail ausblenden"
	return bShow ?
		ScGlobal::GetRscString( STR_UNDO_DOOUTLINE ) :
		ScGlobal::GetRscString( STR_UNDO_REDOOUTLINE );
}

void __EXPORT ScUndoDoOutline::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	//	Tabelle muss vorher umgeschaltet sein (#46952#) !!!

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	//	inverse Funktion ausfuehren

	if (bShow)
		pViewShell->HideOutline( bColumns, nLevel, nEntry, sal_False, sal_False );
	else
		pViewShell->ShowOutline( bColumns, nLevel, nEntry, sal_False, sal_False );

	//	Original Spalten-/Zeilenstatus

	if (bColumns)
        pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
                static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False, pDoc);
	else
		pUndoDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pDoc );

	pViewShell->UpdateScrollBars();

	pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP);

	EndUndo();
}

void __EXPORT ScUndoDoOutline::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	//	Tabelle muss vorher umgeschaltet sein (#46952#) !!!

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	if (bShow)
		pViewShell->ShowOutline( bColumns, nLevel, nEntry, sal_False );
	else
		pViewShell->HideOutline( bColumns, nLevel, nEntry, sal_False );

	EndRedo();
}

void __EXPORT ScUndoDoOutline::Repeat(SfxRepeatTarget& /* rTarget */)
{
}

sal_Bool __EXPORT ScUndoDoOutline::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
	return sal_False;						// geht nicht
}

//
//		Outline-Gruppen erzeugen oder loeschen
//

ScUndoMakeOutline::ScUndoMakeOutline( ScDocShell* pNewDocShell,
							SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
							SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
							ScOutlineTable* pNewUndoTab, sal_Bool bNewColumns, sal_Bool bNewMake ) :
	ScSimpleUndo( pNewDocShell ),
	aBlockStart( nStartX, nStartY, nStartZ ),
	aBlockEnd( nEndX, nEndY, nEndZ ),
	pUndoTable( pNewUndoTab ),
	bColumns( bNewColumns ),
	bMake( bNewMake )
{
}

__EXPORT ScUndoMakeOutline::~ScUndoMakeOutline()
{
	delete pUndoTable;
}

String __EXPORT ScUndoMakeOutline::GetComment() const
{	// "Gruppierung" "Gruppierung aufheben"
	return bMake ?
		ScGlobal::GetRscString( STR_UNDO_MAKEOUTLINE ) :
		ScGlobal::GetRscString( STR_UNDO_REMAKEOUTLINE );
}

void __EXPORT ScUndoMakeOutline::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	SCTAB nTab = aBlockStart.Tab();

	ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart, aBlockEnd );

	pDoc->SetOutlineTable( nTab, pUndoTable );

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);

	EndUndo();
}

void __EXPORT ScUndoMakeOutline::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart, aBlockEnd );

	if (bMake)
		pViewShell->MakeOutline( bColumns, sal_False );
	else
		pViewShell->RemoveOutline( bColumns, sal_False );

	pDocShell->PostPaint(0,0,aBlockStart.Tab(),MAXCOL,MAXROW,aBlockEnd.Tab(),PAINT_GRID);

	EndRedo();
}

void __EXPORT ScUndoMakeOutline::Repeat(SfxRepeatTarget& rTarget)
{
	if (rTarget.ISA(ScTabViewTarget))
	{
		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();

		if (bMake)
			rViewShell.MakeOutline( bColumns, sal_True );
		else
			rViewShell.RemoveOutline( bColumns, sal_True );
	}
}

sal_Bool __EXPORT ScUndoMakeOutline::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return (rTarget.ISA(ScTabViewTarget));
}

//
//		Outline-Ebene auswaehlen
//

ScUndoOutlineLevel::ScUndoOutlineLevel( ScDocShell* pNewDocShell,
						SCCOLROW nNewStart, SCCOLROW nNewEnd, SCTAB nNewTab,
						ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
						sal_Bool bNewColumns, sal_uInt16 nNewLevel ) :
	ScSimpleUndo( pNewDocShell ),
	nStart( nNewStart ),
	nEnd( nNewEnd ),
	nTab( nNewTab ),
	pUndoDoc( pNewUndoDoc ),
	pUndoTable( pNewUndoTab ),
	bColumns( bNewColumns ),
	nLevel( nNewLevel )
{
}

__EXPORT ScUndoOutlineLevel::~ScUndoOutlineLevel()
{
	delete pUndoDoc;
	delete pUndoTable;
}

String __EXPORT ScUndoOutlineLevel::GetComment() const
{	// "Gliederungsebene auswaehlen";
	return ScGlobal::GetRscString( STR_UNDO_OUTLINELEVEL );
}

void __EXPORT ScUndoOutlineLevel::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	//	Original Outline-Table

	pDoc->SetOutlineTable( nTab, pUndoTable );

	//	Original Spalten-/Zeilenstatus

	if (bColumns)
        pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
                static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False, pDoc);
	else
		pUndoDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pDoc );

	pDoc->UpdatePageBreaks( nTab );

	pViewShell->UpdateScrollBars();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP);

	EndUndo();
}

void __EXPORT ScUndoOutlineLevel::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	//	Tabelle muss vorher umgeschaltet sein (#46952#) !!!

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	pViewShell->SelectLevel( bColumns, nLevel, sal_False );

	EndRedo();
}

void __EXPORT ScUndoOutlineLevel::Repeat(SfxRepeatTarget& rTarget)
{
	if (rTarget.ISA(ScTabViewTarget))
		((ScTabViewTarget&)rTarget).GetViewShell()->SelectLevel( bColumns, nLevel, sal_True );
}

sal_Bool __EXPORT ScUndoOutlineLevel::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return (rTarget.ISA(ScTabViewTarget));
}

//
//		Outline ueber Blockmarken ein- oder ausblenden
//

ScUndoOutlineBlock::ScUndoOutlineBlock( ScDocShell* pNewDocShell,
						SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
						SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
						ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab, sal_Bool bNewShow ) :
	ScSimpleUndo( pNewDocShell ),
	aBlockStart( nStartX, nStartY, nStartZ ),
	aBlockEnd( nEndX, nEndY, nEndZ ),
	pUndoDoc( pNewUndoDoc ),
	pUndoTable( pNewUndoTab ),
	bShow( bNewShow )
{
}

__EXPORT ScUndoOutlineBlock::~ScUndoOutlineBlock()
{
	delete pUndoDoc;
	delete pUndoTable;
}

String __EXPORT ScUndoOutlineBlock::GetComment() const
{	// "Detail einblenden" "Detail ausblenden"
	return bShow ?
		ScGlobal::GetRscString( STR_UNDO_DOOUTLINEBLK ) :
		ScGlobal::GetRscString( STR_UNDO_REDOOUTLINEBLK );
}

void __EXPORT ScUndoOutlineBlock::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	SCTAB nTab = aBlockStart.Tab();

	//	Original Outline-Table

	pDoc->SetOutlineTable( nTab, pUndoTable );

	//	Original Spalten-/Zeilenstatus

	SCCOLROW	nStartCol = aBlockStart.Col();
	SCCOLROW	nEndCol = aBlockEnd.Col();
	SCCOLROW	nStartRow = aBlockStart.Row();
	SCCOLROW	nEndRow = aBlockEnd.Row();

	if (!bShow)
	{								//	Groesse des ausgeblendeten Blocks
		sal_uInt16 nLevel;
		pUndoTable->GetColArray()->FindTouchedLevel( nStartCol, nEndCol, nLevel );
		pUndoTable->GetColArray()->ExtendBlock( nLevel, nStartCol, nEndCol );
		pUndoTable->GetRowArray()->FindTouchedLevel( nStartRow, nEndRow, nLevel );
		pUndoTable->GetRowArray()->ExtendBlock( nLevel, nStartRow, nEndRow );
	}

    pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStartCol), 0, nTab,
            static_cast<SCCOL>(nEndCol), MAXROW, nTab, IDF_NONE, sal_False, pDoc );
	pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, sal_False, pDoc );

	pDoc->UpdatePageBreaks( nTab );

	pViewShell->UpdateScrollBars();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP);

	EndUndo();
}

void __EXPORT ScUndoOutlineBlock::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart, aBlockEnd );
	if (bShow)
		pViewShell->ShowMarkedOutlines( sal_False );
	else
		pViewShell->HideMarkedOutlines( sal_False );

	EndRedo();
}

void __EXPORT ScUndoOutlineBlock::Repeat(SfxRepeatTarget& rTarget)
{
	if (rTarget.ISA(ScTabViewTarget))
	{
		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();

		if (bShow)
			rViewShell.ShowMarkedOutlines( sal_True );
		else
			rViewShell.HideMarkedOutlines( sal_True );
	}
}

sal_Bool __EXPORT ScUndoOutlineBlock::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return (rTarget.ISA(ScTabViewTarget));
}

//
//		alle Outlines loeschen
//

ScUndoRemoveAllOutlines::ScUndoRemoveAllOutlines( ScDocShell* pNewDocShell,
									SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
									SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
									ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab ) :
	ScSimpleUndo( pNewDocShell ),
	aBlockStart( nStartX, nStartY, nStartZ ),
	aBlockEnd( nEndX, nEndY, nEndZ ),
	pUndoDoc( pNewUndoDoc ),
	pUndoTable( pNewUndoTab )
{
}

__EXPORT ScUndoRemoveAllOutlines::~ScUndoRemoveAllOutlines()
{
	delete pUndoDoc;
	delete pUndoTable;
}

String __EXPORT ScUndoRemoveAllOutlines::GetComment() const
{	// "Gliederung entfernen"
	return ScGlobal::GetRscString( STR_UNDO_REMOVEALLOTLNS );
}

void __EXPORT ScUndoRemoveAllOutlines::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	SCTAB nTab = aBlockStart.Tab();

	//	Original Outline-Table

	pDoc->SetOutlineTable( nTab, pUndoTable );

	//	Original Spalten-/Zeilenstatus

	SCCOL	nStartCol = aBlockStart.Col();
	SCCOL	nEndCol = aBlockEnd.Col();
	SCROW	nStartRow = aBlockStart.Row();
	SCROW	nEndRow = aBlockEnd.Row();

	pUndoDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, sal_False, pDoc );
	pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, sal_False, pDoc );

	pDoc->UpdatePageBreaks( nTab );

	pViewShell->UpdateScrollBars();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);

	EndUndo();
}

void __EXPORT ScUndoRemoveAllOutlines::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	//	Tabelle muss vorher umgeschaltet sein (#46952#) !!!

	SCTAB nTab = aBlockStart.Tab();
	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	pViewShell->RemoveAllOutlines( sal_False );

	EndRedo();
}

void __EXPORT ScUndoRemoveAllOutlines::Repeat(SfxRepeatTarget& rTarget)
{
	if (rTarget.ISA(ScTabViewTarget))
		((ScTabViewTarget&)rTarget).GetViewShell()->RemoveAllOutlines( sal_True );
}

sal_Bool __EXPORT ScUndoRemoveAllOutlines::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return (rTarget.ISA(ScTabViewTarget));
}

//
//		Auto-Outline
//

ScUndoAutoOutline::ScUndoAutoOutline( ScDocShell* pNewDocShell,
									SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
									SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
									ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab ) :
	ScSimpleUndo( pNewDocShell ),
	aBlockStart( nStartX, nStartY, nStartZ ),
	aBlockEnd( nEndX, nEndY, nEndZ ),
	pUndoDoc( pNewUndoDoc ),
	pUndoTable( pNewUndoTab )
{
}

__EXPORT ScUndoAutoOutline::~ScUndoAutoOutline()
{
	delete pUndoDoc;
	delete pUndoTable;
}

String __EXPORT ScUndoAutoOutline::GetComment() const
{	// "Auto-Gliederung"
	return ScGlobal::GetRscString( STR_UNDO_AUTOOUTLINE );
}

void __EXPORT ScUndoAutoOutline::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	SCTAB nTab = aBlockStart.Tab();

	//	Original Outline-Table

	pDoc->SetOutlineTable( nTab, pUndoTable );

	//	Original Spalten-/Zeilenstatus

	if (pUndoDoc && pUndoTable)
	{
		SCCOLROW nStartCol;
		SCCOLROW nStartRow;
		SCCOLROW nEndCol;
		SCCOLROW nEndRow;
		pUndoTable->GetColArray()->GetRange( nStartCol, nEndCol );
		pUndoTable->GetRowArray()->GetRange( nStartRow, nEndRow );

        pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStartCol), 0, nTab,
                static_cast<SCCOL>(nEndCol), MAXROW, nTab, IDF_NONE, sal_False,
                pDoc);
		pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, sal_False, pDoc );

		pViewShell->UpdateScrollBars();
	}

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);

	EndUndo();
}

void __EXPORT ScUndoAutoOutline::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	SCTAB nTab = aBlockStart.Tab();
	if (pViewShell)
	{
		//	Tabelle muss vorher umgeschaltet sein (#46952#) !!!

		SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
		if ( nVisTab != nTab )
			pViewShell->SetTabNo( nTab );
	}

	ScRange aRange( aBlockStart.Col(), aBlockStart.Row(), nTab,
					aBlockEnd.Col(),   aBlockEnd.Row(),   nTab );
	ScOutlineDocFunc aFunc( *pDocShell );
	aFunc.AutoOutline( aRange, sal_False, sal_False );

	//	auf der View markieren
	//	Wenn's beim Aufruf eine Mehrfachselektion war, ist es jetzt der
	//	umschliessende Bereich...

	if (pViewShell)
		pViewShell->MarkRange( aRange );

	EndRedo();
}

void __EXPORT ScUndoAutoOutline::Repeat(SfxRepeatTarget& rTarget)
{
	if (rTarget.ISA(ScTabViewTarget))
		((ScTabViewTarget&)rTarget).GetViewShell()->AutoOutline( sal_True );
}

sal_Bool __EXPORT ScUndoAutoOutline::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return (rTarget.ISA(ScTabViewTarget));
}

//
//		Zwischenergebnisse
//

ScUndoSubTotals::ScUndoSubTotals( ScDocShell* pNewDocShell, SCTAB nNewTab,
								const ScSubTotalParam& rNewParam, SCROW nNewEndY,
								ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
								ScRangeName* pNewUndoRange, ScDBCollection* pNewUndoDB ) :
	ScDBFuncUndo( pNewDocShell, ScRange( rNewParam.nCol1, rNewParam.nRow1, nNewTab,
	                                     rNewParam.nCol2, rNewParam.nRow2, nNewTab ) ),
	nTab( nNewTab ),
	aParam( rNewParam ),
	nNewEndRow( nNewEndY ),
	pUndoDoc( pNewUndoDoc ),
	pUndoTable( pNewUndoTab ),
	pUndoRange( pNewUndoRange ),
	pUndoDB( pNewUndoDB )
{
}

__EXPORT ScUndoSubTotals::~ScUndoSubTotals()
{
	delete pUndoDoc;
	delete pUndoTable;
	delete pUndoRange;
	delete pUndoDB;
}

String __EXPORT ScUndoSubTotals::GetComment() const
{	// "Teilergebnisse"
	return ScGlobal::GetRscString( STR_UNDO_SUBTOTALS );
}

void __EXPORT ScUndoSubTotals::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	//	um einzelnen DB-Bereich anzupassen
/*	ScDBData* pOldDBData = ScUndoUtil::GetOldDBData( pUndoDBData, pDoc, nTab,
										aParam.nCol1, aParam.nRow1, aParam.nCol2, nNewEndRow );
*/

	if (nNewEndRow > aParam.nRow2)
	{
		pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, aParam.nRow2+1, static_cast<SCSIZE>(nNewEndRow-aParam.nRow2) );
	}
	else if (nNewEndRow < aParam.nRow2)
	{
		pDoc->InsertRow( 0,nTab, MAXCOL,nTab, nNewEndRow+1, static_cast<SCSIZE>(aParam.nRow2-nNewEndRow) );
	}


	//	Original Outline-Table

	pDoc->SetOutlineTable( nTab, pUndoTable );

	//	Original Spalten-/Zeilenstatus

	if (pUndoDoc && pUndoTable)
	{
		SCCOLROW nStartCol;
		SCCOLROW nStartRow;
		SCCOLROW nEndCol;
		SCCOLROW nEndRow;
		pUndoTable->GetColArray()->GetRange( nStartCol, nEndCol );
		pUndoTable->GetRowArray()->GetRange( nStartRow, nEndRow );

        pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStartCol), 0, nTab,
                static_cast<SCCOL>(nEndCol), MAXROW, nTab, IDF_NONE, sal_False,
                pDoc);
		pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, sal_False, pDoc );

		pViewShell->UpdateScrollBars();
	}

	//	Original-Daten & Referenzen

	ScUndoUtil::MarkSimpleBlock( pDocShell, 0, aParam.nRow1+1, nTab,
											MAXCOL, aParam.nRow2, nTab );

	pDoc->DeleteAreaTab( 0,aParam.nRow1+1, MAXCOL,aParam.nRow2, nTab, IDF_ALL );

	pUndoDoc->CopyToDocument( 0, aParam.nRow1+1, nTab, MAXCOL, aParam.nRow2, nTab,
															IDF_NONE, sal_False, pDoc );	// Flags
	pUndoDoc->UndoToDocument( 0, aParam.nRow1+1, nTab, MAXCOL, aParam.nRow2, nTab,
															IDF_ALL, sal_False, pDoc );

	ScUndoUtil::MarkSimpleBlock( pDocShell, aParam.nCol1,aParam.nRow1,nTab,
											aParam.nCol2,aParam.nRow2,nTab );

/*	if (pUndoDBData)
		*pOldDBData = *pUndoDBData;
*/
	if (pUndoRange)
		pDoc->SetRangeName( new ScRangeName( *pUndoRange ) );
	if (pUndoDB)
		pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), sal_True );

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);
	pDocShell->PostDataChanged();

	EndUndo();
}

void __EXPORT ScUndoSubTotals::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	ScUndoUtil::MarkSimpleBlock( pDocShell, aParam.nCol1,aParam.nRow1,nTab,
											aParam.nCol2,aParam.nRow2,nTab );
	pViewShell->DoSubTotals( aParam, sal_False );

	EndRedo();
}

void __EXPORT ScUndoSubTotals::Repeat(SfxRepeatTarget& /* rTarget */)
{
}

sal_Bool __EXPORT ScUndoSubTotals::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
	return sal_False;						// geht nicht wegen Spaltennummern
}

//
//		Sortieren
//

ScUndoSort::ScUndoSort( ScDocShell* pNewDocShell,
						SCTAB nNewTab, const ScSortParam& rParam,
						sal_Bool bQuery, ScDocument* pNewUndoDoc, ScDBCollection* pNewUndoDB,
						const ScRange* pDest ) :
	ScDBFuncUndo( pNewDocShell, ScRange( rParam.nCol1, rParam.nRow1, nNewTab,
	                                     rParam.nCol2, rParam.nRow2, nNewTab ) ),
	nTab( nNewTab ),
	aSortParam( rParam ),
	bRepeatQuery( bQuery ),
	pUndoDoc( pNewUndoDoc ),
	pUndoDB( pNewUndoDB ),
	bDestArea( sal_False )
{
	if ( pDest )
	{
		bDestArea = sal_True;
		aDestRange = *pDest;
	}
}

__EXPORT ScUndoSort::~ScUndoSort()
{
	delete pUndoDoc;
	delete pUndoDB;
}

String __EXPORT ScUndoSort::GetComment() const
{
	return ScGlobal::GetRscString( STR_UNDO_SORT );
}

void __EXPORT ScUndoSort::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	SCCOL nStartCol = aSortParam.nCol1;
	SCROW nStartRow = aSortParam.nRow1;
	SCCOL nEndCol	 = aSortParam.nCol2;
	SCROW nEndRow	 = aSortParam.nRow2;
	SCTAB nSortTab  = nTab;
	if ( !aSortParam.bInplace )
	{
		nStartCol = aSortParam.nDestCol;
		nStartRow = aSortParam.nDestRow;
		nEndCol   = nStartCol + ( aSortParam.nCol2 - aSortParam.nCol1 );
		nEndRow   = nStartRow + ( aSortParam.nRow2 - aSortParam.nRow1 );
		nSortTab  = aSortParam.nDestTab;
	}

	ScUndoUtil::MarkSimpleBlock( pDocShell, nStartCol, nStartRow, nSortTab,
								 nEndCol, nEndRow, nSortTab );

    // do not delete/copy note captions, they are handled in drawing undo (ScDBFuncUndo::mpDrawUndo)
    pDoc->DeleteAreaTab( nStartCol,nStartRow, nEndCol,nEndRow, nSortTab, IDF_ALL|IDF_NOCAPTIONS );
	pUndoDoc->CopyToDocument( nStartCol, nStartRow, nSortTab, nEndCol, nEndRow, nSortTab,
                                IDF_ALL|IDF_NOCAPTIONS, sal_False, pDoc );

	if (bDestArea)
	{
        // do not delete/copy note captions, they are handled in drawing undo (ScDBFuncUndo::mpDrawUndo)
        pDoc->DeleteAreaTab( aDestRange, IDF_ALL|IDF_NOCAPTIONS );
        pUndoDoc->CopyToDocument( aDestRange, IDF_ALL|IDF_NOCAPTIONS, sal_False, pDoc );
	}

	//	Zeilenhoehen immer (wegen automatischer Anpassung)
	//!	auf ScBlockUndo umstellen
//	if (bRepeatQuery)
		pUndoDoc->CopyToDocument( 0, nStartRow, nSortTab, MAXCOL, nEndRow, nSortTab,
								IDF_NONE, sal_False, pDoc );

	if (pUndoDB)
		pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), sal_True );

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nSortTab )
		pViewShell->SetTabNo( nSortTab );

	pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);
	pDocShell->PostDataChanged();

	EndUndo();
}

void __EXPORT ScUndoSort::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

//	pViewShell->DoneBlockMode();
//	pViewShell->InitOwnBlockMode();
//	pViewShell->GetViewData()->GetMarkData() = aMarkData;	// CopyMarksTo

	pViewShell->MarkRange( ScRange( aSortParam.nCol1, aSortParam.nRow1, nTab,
									  aSortParam.nCol2, aSortParam.nRow2, nTab ) );

	pViewShell->Sort( aSortParam, sal_False );

	//	Quellbereich painten wegen Markierung
	if ( !aSortParam.bInplace )
		pDocShell->PostPaint( aSortParam.nCol1, aSortParam.nRow1, nTab,
							  aSortParam.nCol2, aSortParam.nRow2, nTab, PAINT_GRID );

	EndRedo();
}

void __EXPORT ScUndoSort::Repeat(SfxRepeatTarget& /* rTarget */)
{
}

sal_Bool __EXPORT ScUndoSort::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
	return sal_False;						// geht nicht wegen Spaltennummern
}

//
//		Filtern
//

ScUndoQuery::ScUndoQuery( ScDocShell* pNewDocShell, SCTAB nNewTab, const ScQueryParam& rParam,
							ScDocument* pNewUndoDoc, ScDBCollection* pNewUndoDB,
							const ScRange* pOld, sal_Bool bSize, const ScRange* pAdvSrc ) :
	ScDBFuncUndo( pNewDocShell, ScRange( rParam.nCol1, rParam.nRow1, nNewTab,
	                                     rParam.nCol2, rParam.nRow2, nNewTab ) ),
	pDrawUndo( NULL ),
	nTab( nNewTab ),
	aQueryParam( rParam ),
	pUndoDoc( pNewUndoDoc ),
//	pUndoDBData( pNewData )
	pUndoDB( pNewUndoDB ),
	bIsAdvanced( sal_False ),
	bDestArea( sal_False ),
	bDoSize( bSize )
{
	if ( pOld )
	{
		bDestArea = sal_True;
		aOldDest = *pOld;
	}
	if ( pAdvSrc )
	{
		bIsAdvanced = sal_True;
		aAdvSource = *pAdvSrc;
	}

    pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
}

__EXPORT ScUndoQuery::~ScUndoQuery()
{
	delete pUndoDoc;
//	delete pUndoDBData;
	delete pUndoDB;
    DeleteSdrUndoAction( pDrawUndo );
}

String __EXPORT ScUndoQuery::GetComment() const
{	// "Filtern";
	return ScGlobal::GetRscString( STR_UNDO_QUERY );
}

void __EXPORT ScUndoQuery::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	sal_Bool bCopy = !aQueryParam.bInplace;
	SCCOL nDestEndCol = 0;
	SCROW nDestEndRow = 0;
	if (bCopy)
	{
		nDestEndCol = aQueryParam.nDestCol + ( aQueryParam.nCol2-aQueryParam.nCol1 );
		nDestEndRow = aQueryParam.nDestRow + ( aQueryParam.nRow2-aQueryParam.nRow1 );

		ScDBData* pData = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
												aQueryParam.nDestTab, sal_True );
		if (pData)
		{
			ScRange aNewDest;
			pData->GetArea( aNewDest );
			nDestEndCol = aNewDest.aEnd.Col();
			nDestEndRow = aNewDest.aEnd.Row();
		}

		if ( bDoSize && bDestArea )
		{
			//	aDestRange ist der alte Bereich
			pDoc->FitBlock( ScRange(
								aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
								nDestEndCol, nDestEndRow, aQueryParam.nDestTab ),
							aOldDest );
		}

		ScUndoUtil::MarkSimpleBlock( pDocShell,
									aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
									nDestEndCol, nDestEndRow, aQueryParam.nDestTab );
		pDoc->DeleteAreaTab( aQueryParam.nDestCol, aQueryParam.nDestRow,
							nDestEndCol, nDestEndRow, aQueryParam.nDestTab, IDF_ALL );

		pViewShell->DoneBlockMode();

		pUndoDoc->CopyToDocument( aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
									nDestEndCol, nDestEndRow, aQueryParam.nDestTab,
									IDF_ALL, sal_False, pDoc );
		//	Attribute werden immer mitkopiert (#49287#)

		//	Rest von altem Bereich
		if ( bDestArea && !bDoSize )
		{
			pDoc->DeleteAreaTab( aOldDest, IDF_ALL );
			pUndoDoc->CopyToDocument( aOldDest, IDF_ALL, sal_False, pDoc );
		}
	}
	else
		pUndoDoc->CopyToDocument( 0, aQueryParam.nRow1, nTab, MAXCOL, aQueryParam.nRow2, nTab,
										IDF_NONE, sal_False, pDoc );

	if (pUndoDB)
		pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), sal_True );

	if (!bCopy)
    {
        pDoc->InvalidatePageBreaks(nTab);
		pDoc->UpdatePageBreaks( nTab );
    }

    ScRange aDirtyRange( 0 , aQueryParam.nRow1, nTab,
        MAXCOL, aQueryParam.nRow2, nTab );
    pDoc->SetDirty( aDirtyRange );

    DoSdrUndoAction( pDrawUndo, pDoc );

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

		//	Paint

	if (bCopy)
	{
		SCCOL nEndX = nDestEndCol;
		SCROW nEndY = nDestEndRow;
		if (bDestArea)
		{
			if ( aOldDest.aEnd.Col() > nEndX )
				nEndX = aOldDest.aEnd.Col();
			if ( aOldDest.aEnd.Row() > nEndY )
				nEndY = aOldDest.aEnd.Row();
		}
		if (bDoSize)
			nEndY = MAXROW;
		pDocShell->PostPaint( aQueryParam.nDestCol, aQueryParam.nDestRow, aQueryParam.nDestTab,
									nEndX, nEndY, aQueryParam.nDestTab, PAINT_GRID );
	}
	else
		pDocShell->PostPaint( 0, aQueryParam.nRow1, nTab, MAXCOL, MAXROW, nTab,
													PAINT_GRID | PAINT_LEFT );
	pDocShell->PostDataChanged();

	EndUndo();
}

void __EXPORT ScUndoQuery::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	if ( bIsAdvanced )
		pViewShell->Query( aQueryParam, &aAdvSource, sal_False );
	else
		pViewShell->Query( aQueryParam, NULL, sal_False );

	EndRedo();
}

void __EXPORT ScUndoQuery::Repeat(SfxRepeatTarget& /* rTarget */)
{
}

sal_Bool __EXPORT ScUndoQuery::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
	return sal_False;						// geht nicht wegen Spaltennummern
}

//
//      Show or hide AutoFilter buttons (doesn't include filter settings)
//

ScUndoAutoFilter::ScUndoAutoFilter( ScDocShell* pNewDocShell, const ScRange& rRange,
                                    const String& rName, sal_Bool bSet ) :
    ScDBFuncUndo( pNewDocShell, rRange ),
    aDBName( rName ),
    bFilterSet( bSet )
{
}

ScUndoAutoFilter::~ScUndoAutoFilter()
{
}

String ScUndoAutoFilter::GetComment() const
{
    return ScGlobal::GetRscString( STR_UNDO_QUERY );    // same as ScUndoQuery
}

void ScUndoAutoFilter::DoChange( sal_Bool bUndo )
{
    sal_Bool bNewFilter = bUndo ? !bFilterSet : bFilterSet;

    sal_uInt16 nIndex;
    ScDocument* pDoc = pDocShell->GetDocument();
    ScDBCollection* pColl = pDoc->GetDBCollection();
    if ( pColl->SearchName( aDBName, nIndex ) )
    {
        ScDBData* pDBData = (*pColl)[nIndex];
        pDBData->SetAutoFilter( bNewFilter );

        SCCOL nRangeX1;
        SCROW nRangeY1;
        SCCOL nRangeX2;
        SCROW nRangeY2;
        SCTAB nRangeTab;
        pDBData->GetArea( nRangeTab, nRangeX1, nRangeY1, nRangeX2, nRangeY2 );

        if ( bNewFilter )
            pDoc->ApplyFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, SC_MF_AUTO );
        else
            pDoc->RemoveFlagsTab( nRangeX1, nRangeY1, nRangeX2, nRangeY1, nRangeTab, SC_MF_AUTO );

        pDocShell->PostPaint( nRangeX1, nRangeY1, nRangeTab, nRangeX2, nRangeY1, nRangeTab, PAINT_GRID );
    }
}

void ScUndoAutoFilter::Undo()
{
    BeginUndo();
    DoChange( sal_True );
    EndUndo();
}

void ScUndoAutoFilter::Redo()
{
    BeginRedo();
    DoChange( sal_False );
    EndRedo();
}

void ScUndoAutoFilter::Repeat(SfxRepeatTarget& /* rTarget */)
{
}

sal_Bool ScUndoAutoFilter::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
    return sal_False;
}

//
//		Datenbankbereiche aendern (Dialog)
//

ScUndoDBData::ScUndoDBData( ScDocShell* pNewDocShell,
							ScDBCollection* pNewUndoColl, ScDBCollection* pNewRedoColl ) :
	ScSimpleUndo( pNewDocShell ),
	pUndoColl( pNewUndoColl ),
	pRedoColl( pNewRedoColl )
{
}

__EXPORT ScUndoDBData::~ScUndoDBData()
{
	delete pUndoColl;
	delete pRedoColl;
}

String __EXPORT ScUndoDBData::GetComment() const
{	// "Datenbankbereiche aendern";
	return ScGlobal::GetRscString( STR_UNDO_DBDATA );
}

void __EXPORT ScUndoDBData::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();

	sal_Bool bOldAutoCalc = pDoc->GetAutoCalc();
	pDoc->SetAutoCalc( sal_False );			// unnoetige Berechnungen vermeiden
	pDoc->CompileDBFormula( sal_True );		// CreateFormulaString
	pDoc->SetDBCollection( new ScDBCollection(*pUndoColl), sal_True );
	pDoc->CompileDBFormula( sal_False );	// CompileFormulaString
	pDoc->SetAutoCalc( bOldAutoCalc );

	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );

	EndUndo();
}

void __EXPORT ScUndoDBData::Redo()
{
	BeginRedo();

	ScDocument* pDoc = pDocShell->GetDocument();

	sal_Bool bOldAutoCalc = pDoc->GetAutoCalc();
	pDoc->SetAutoCalc( sal_False );			// unnoetige Berechnungen vermeiden
	pDoc->CompileDBFormula( sal_True );		// CreateFormulaString
	pDoc->SetDBCollection( new ScDBCollection(*pRedoColl), sal_True );
	pDoc->CompileDBFormula( sal_False );	// CompileFormulaString
	pDoc->SetAutoCalc( bOldAutoCalc );

	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );

	EndRedo();
}

void __EXPORT ScUndoDBData::Repeat(SfxRepeatTarget& /* rTarget */)
{
}

sal_Bool __EXPORT ScUndoDBData::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
	return sal_False;						// geht nicht
}

//
//		Import
//

ScUndoImportData::ScUndoImportData( ScDocShell* pNewDocShell, SCTAB nNewTab,
								const ScImportParam& rParam, SCCOL nNewEndX, SCROW nNewEndY,
								SCCOL nNewFormula,
								ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
								ScDBData* pNewUndoData, ScDBData* pNewRedoData ) :
	ScSimpleUndo( pNewDocShell ),
	nTab( nNewTab ),
	aImportParam( rParam ),
	nEndCol( nNewEndX ),
	nEndRow( nNewEndY ),
	pUndoDoc( pNewUndoDoc ),
	pRedoDoc( pNewRedoDoc ),
	pUndoDBData( pNewUndoData ),
	pRedoDBData( pNewRedoData ),
	nFormulaCols( nNewFormula ),
	bRedoFilled( sal_False )
{
	// redo doc doesn't contain imported data (but everything else)
}

__EXPORT ScUndoImportData::~ScUndoImportData()
{
	delete pUndoDoc;
	delete pRedoDoc;
	delete pUndoDBData;
	delete pRedoDBData;
}

String __EXPORT ScUndoImportData::GetComment() const
{	// "Importieren";
	return ScGlobal::GetRscString( STR_UNDO_IMPORTDATA );
}

void __EXPORT ScUndoImportData::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	ScUndoUtil::MarkSimpleBlock( pDocShell, aImportParam.nCol1,aImportParam.nRow1,nTab,
														nEndCol,nEndRow,nTab );

	SCTAB nTable;
	SCCOL nCol1, nCol2;
	SCROW nRow1, nRow2;
	ScDBData* pCurrentData = NULL;
	if (pUndoDBData && pRedoDBData)
	{
		pRedoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
		pCurrentData = ScUndoUtil::GetOldDBData( pRedoDBData, pDoc, nTab,
													nCol1, nRow1, nCol2, nRow2 );

		if ( !bRedoFilled )
		{
			//	read redo data from document at first undo
			//	imported data is deleted later anyway,
			//	so now delete each column after copying to save memory (#41216#)

			sal_Bool bOldAutoCalc = pDoc->GetAutoCalc();
			pDoc->SetAutoCalc( sal_False );				// outside of the loop
			for (SCCOL nCopyCol = nCol1; nCopyCol <= nCol2; nCopyCol++)
			{
				pDoc->CopyToDocument( nCopyCol,nRow1,nTab, nCopyCol,nRow2,nTab,
                                        IDF_CONTENTS & ~IDF_NOTE, sal_False, pRedoDoc );
                pDoc->DeleteAreaTab( nCopyCol,nRow1, nCopyCol,nRow2, nTab, IDF_CONTENTS & ~IDF_NOTE );
				pDoc->DoColResize( nTab, nCopyCol, nCopyCol, 0 );
			}
			pDoc->SetAutoCalc( bOldAutoCalc );
			bRedoFilled = sal_True;
		}
	}
	sal_Bool bMoveCells = pUndoDBData && pRedoDBData &&
						pRedoDBData->IsDoSize();		// in alt und neu gleich
	if (bMoveCells)
	{
		//	Undo: erst die neuen Daten loeschen, dann FitBlock rueckwaerts

		ScRange aOld, aNew;
		pUndoDBData->GetArea( aOld );
		pRedoDBData->GetArea( aNew );

		pDoc->DeleteAreaTab( aNew.aStart.Col(), aNew.aStart.Row(),
                                aNew.aEnd.Col(), aNew.aEnd.Row(), nTab, IDF_ALL & ~IDF_NOTE );

		aOld.aEnd.SetCol( aOld.aEnd.Col() + nFormulaCols );		// FitBlock auch fuer Formeln
		aNew.aEnd.SetCol( aNew.aEnd.Col() + nFormulaCols );
		pDoc->FitBlock( aNew, aOld, sal_False );					// rueckwaerts
	}
	else
		pDoc->DeleteAreaTab( aImportParam.nCol1,aImportParam.nRow1,
                                nEndCol,nEndRow, nTab, IDF_ALL & ~IDF_NOTE );

	pUndoDoc->CopyToDocument( aImportParam.nCol1,aImportParam.nRow1,nTab,
								nEndCol+nFormulaCols,nEndRow,nTab,
                                IDF_ALL & ~IDF_NOTE, sal_False, pDoc );

	if (pCurrentData)
	{
		*pCurrentData = *pUndoDBData;

		pUndoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
		ScUndoUtil::MarkSimpleBlock( pDocShell, nCol1, nRow1, nTable, nCol2, nRow2, nTable );
	}

// erack! it's broadcasted
//	pDoc->SetDirty();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	if (bMoveCells)
		pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
	else
		pDocShell->PostPaint( aImportParam.nCol1,aImportParam.nRow1,nTab,
								nEndCol,nEndRow,nTab, PAINT_GRID );
	pDocShell->PostDataChanged();

	EndUndo();
}

void __EXPORT ScUndoImportData::Redo()
{
	BeginRedo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	ScUndoUtil::MarkSimpleBlock( pDocShell, aImportParam.nCol1,aImportParam.nRow1,nTab,
														nEndCol,nEndRow,nTab );

	SCTAB nTable;
	SCCOL nCol1, nCol2;
	SCROW nRow1, nRow2;
	ScDBData* pCurrentData = NULL;
	if (pUndoDBData && pRedoDBData)
	{
		pUndoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
		pCurrentData = ScUndoUtil::GetOldDBData( pUndoDBData, pDoc, nTab,
													nCol1, nRow1, nCol2, nRow2 );
	}
	sal_Bool bMoveCells = pUndoDBData && pRedoDBData &&
						pRedoDBData->IsDoSize();		// in alt und neu gleich
	if (bMoveCells)
	{
		//	Redo: FitBlock, dann Daten loeschen (noetig fuer CopyToDocument)

		ScRange aOld, aNew;
		pUndoDBData->GetArea( aOld );
		pRedoDBData->GetArea( aNew );

		aOld.aEnd.SetCol( aOld.aEnd.Col() + nFormulaCols );		// FitBlock auch fuer Formeln
		aNew.aEnd.SetCol( aNew.aEnd.Col() + nFormulaCols );
		pDoc->FitBlock( aOld, aNew );

		pDoc->DeleteAreaTab( aNew.aStart.Col(), aNew.aStart.Row(),
                                aNew.aEnd.Col(), aNew.aEnd.Row(), nTab, IDF_ALL & ~IDF_NOTE );

        pRedoDoc->CopyToDocument( aNew, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );        // incl. Formeln
	}
	else
	{
		pDoc->DeleteAreaTab( aImportParam.nCol1,aImportParam.nRow1,
                                nEndCol,nEndRow, nTab, IDF_ALL & ~IDF_NOTE );
		pRedoDoc->CopyToDocument( aImportParam.nCol1,aImportParam.nRow1,nTab,
                                nEndCol,nEndRow,nTab, IDF_ALL & ~IDF_NOTE, sal_False, pDoc );
	}

	if (pCurrentData)
	{
		*pCurrentData = *pRedoDBData;

		pRedoDBData->GetArea( nTable, nCol1, nRow1, nCol2, nRow2 );
		ScUndoUtil::MarkSimpleBlock( pDocShell, nCol1, nRow1, nTable, nCol2, nRow2, nTable );
	}

// erack! it's broadcasted
//	pDoc->SetDirty();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	if (bMoveCells)
		pDocShell->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
	else
		pDocShell->PostPaint( aImportParam.nCol1,aImportParam.nRow1,nTab,
								nEndCol,nEndRow,nTab, PAINT_GRID );
	pDocShell->PostDataChanged();

	EndRedo();
}

void __EXPORT ScUndoImportData::Repeat(SfxRepeatTarget& rTarget)
{
	if (rTarget.ISA(ScTabViewTarget))
	{
		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();

		SCTAB nDummy;
		ScImportParam aNewParam(aImportParam);
		ScDBData* pDBData = rViewShell.GetDBData();
		pDBData->GetArea( nDummy, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );

		rViewShell.ImportData( aNewParam );
	}
}

sal_Bool __EXPORT ScUndoImportData::CanRepeat(SfxRepeatTarget& rTarget) const
{
	//	Repeat nur fuer Import per DB-Bereich, dann ist pUndoDBData gesetzt

	if (pUndoDBData)
		return (rTarget.ISA(ScTabViewTarget));
	else
		return sal_False;		// Adressbuch
}

//
//		Operationen wiederholen
//

ScUndoRepeatDB::ScUndoRepeatDB( ScDocShell* pNewDocShell, SCTAB nNewTab,
								SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
								SCROW nResultEndRow, SCCOL nCurX, SCROW nCurY,
								ScDocument* pNewUndoDoc, ScOutlineTable* pNewUndoTab,
								ScRangeName* pNewUndoRange, ScDBCollection* pNewUndoDB,
								const ScRange* pOldQ, const ScRange* pNewQ ) :
	ScSimpleUndo( pNewDocShell ),
	aBlockStart( nStartX,nStartY,nNewTab ),
	aBlockEnd( nEndX,nEndY,nNewTab ),
	nNewEndRow( nResultEndRow ),
	aCursorPos( nCurX,nCurY,nNewTab ),
	pUndoDoc( pNewUndoDoc ),
	pUndoTable( pNewUndoTab ),
	pUndoRange( pNewUndoRange ),
	pUndoDB( pNewUndoDB ),
	bQuerySize( sal_False )
{
	if ( pOldQ && pNewQ )
	{
		aOldQuery = *pOldQ;
		aNewQuery = *pNewQ;
		bQuerySize = sal_True;
	}
}

__EXPORT ScUndoRepeatDB::~ScUndoRepeatDB()
{
	delete pUndoDoc;
	delete pUndoTable;
	delete pUndoRange;
	delete pUndoDB;
}

String __EXPORT ScUndoRepeatDB::GetComment() const
{	// "Wiederholen";       //! bessere Beschreibung!
	return ScGlobal::GetRscString( STR_UNDO_REPEATDB );
}

void __EXPORT ScUndoRepeatDB::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	SCTAB nTab = aBlockStart.Tab();

	if (bQuerySize)
	{
		pDoc->FitBlock( aNewQuery, aOldQuery, sal_False );

		if ( aNewQuery.aEnd.Col() == aOldQuery.aEnd.Col() )
		{
			SCCOL nFormulaCols = 0;
			SCCOL nCol = aOldQuery.aEnd.Col() + 1;
			SCROW nRow = aOldQuery.aStart.Row() + 1;		//! Header testen
			while ( nCol <= MAXCOL &&
					pDoc->GetCellType(ScAddress( nCol, nRow, nTab )) == CELLTYPE_FORMULA )
				++nCol, ++nFormulaCols;

			if ( nFormulaCols > 0 )
			{
				ScRange aOldForm = aOldQuery;
				aOldForm.aStart.SetCol( aOldQuery.aEnd.Col() + 1 );
				aOldForm.aEnd.SetCol( aOldQuery.aEnd.Col() + nFormulaCols );
				ScRange aNewForm = aOldForm;
				aNewForm.aEnd.SetRow( aNewQuery.aEnd.Row() );
				pDoc->FitBlock( aNewForm, aOldForm, sal_False );
			}
		}
	}

	//!		Daten von Filter in anderen Bereich fehlen noch	!!!!!!!!!!!!!!!!!

	if (nNewEndRow > aBlockEnd.Row())
	{
		pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, aBlockEnd.Row()+1, static_cast<SCSIZE>(nNewEndRow-aBlockEnd.Row()) );
	}
	else if (nNewEndRow < aBlockEnd.Row())
	{
		pDoc->InsertRow( 0,nTab, MAXCOL,nTab, nNewEndRow+1, static_cast<SCSIZE>(nNewEndRow-aBlockEnd.Row()) );
	}

	//	Original Outline-Table

	pDoc->SetOutlineTable( nTab, pUndoTable );

	//	Original Spalten-/Zeilenstatus

	if (pUndoDoc && pUndoTable)
	{
		SCCOLROW nStartCol;
		SCCOLROW nStartRow;
		SCCOLROW nEndCol;
		SCCOLROW nEndRow;
		pUndoTable->GetColArray()->GetRange( nStartCol, nEndCol );
		pUndoTable->GetRowArray()->GetRange( nStartRow, nEndRow );

        pUndoDoc->CopyToDocument( static_cast<SCCOL>(nStartCol), 0, nTab,
                static_cast<SCCOL>(nEndCol), MAXROW, nTab, IDF_NONE, sal_False,
                pDoc );
		pUndoDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, sal_False, pDoc );

		pViewShell->UpdateScrollBars();
	}

	//	Original-Daten & Referenzen

	ScUndoUtil::MarkSimpleBlock( pDocShell, 0, aBlockStart.Row(), nTab,
											MAXCOL, aBlockEnd.Row(), nTab );
	pDoc->DeleteAreaTab( 0, aBlockStart.Row(),
							MAXCOL, aBlockEnd.Row(), nTab, IDF_ALL );

	pUndoDoc->CopyToDocument( 0, aBlockStart.Row(), nTab, MAXCOL, aBlockEnd.Row(), nTab,
															IDF_NONE, sal_False, pDoc );			// Flags
	pUndoDoc->UndoToDocument( 0, aBlockStart.Row(), nTab, MAXCOL, aBlockEnd.Row(), nTab,
															IDF_ALL, sal_False, pDoc );

	ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart.Col(),aBlockStart.Row(),nTab,
											aBlockEnd.Col(),aBlockEnd.Row(),nTab );

	if (pUndoRange)
		pDoc->SetRangeName( new ScRangeName( *pUndoRange ) );
	if (pUndoDB)
		pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), sal_True );

// erack! it's broadcasted
//	pDoc->SetDirty();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	pDocShell->PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_GRID|PAINT_LEFT|PAINT_TOP|PAINT_SIZE);
	pDocShell->PostDataChanged();

	EndUndo();
}

void __EXPORT ScUndoRepeatDB::Redo()
{
	BeginRedo();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	SCTAB nTab = aBlockStart.Tab();

	SCTAB nVisTab = pViewShell->GetViewData()->GetTabNo();
	if ( nVisTab != nTab )
		pViewShell->SetTabNo( nTab );

	ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockStart.Col(),aBlockStart.Row(),nTab,
											aBlockEnd.Col(),aBlockEnd.Row(),nTab );
	pViewShell->SetCursor( aCursorPos.Col(), aCursorPos.Row() );

	pViewShell->RepeatDB( sal_False );

	EndRedo();
}

void __EXPORT ScUndoRepeatDB::Repeat(SfxRepeatTarget& rTarget)
{
	if (rTarget.ISA(ScTabViewTarget))
		((ScTabViewTarget&)rTarget).GetViewShell()->RepeatDB( sal_True );
}

sal_Bool __EXPORT ScUndoRepeatDB::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return (rTarget.ISA(ScTabViewTarget));
}

//UNUSED2008-05  //
//UNUSED2008-05  //		Pivot-Tabellen
//UNUSED2008-05  //
//UNUSED2008-05
//UNUSED2008-05  ScUndoPivot::ScUndoPivot( ScDocShell* pNewDocShell,
//UNUSED2008-05                              const ScArea& rOld, const ScArea& rNew,
//UNUSED2008-05                              ScDocument* pOldDoc, ScDocument* pNewDoc,
//UNUSED2008-05                              const ScPivot* pOldPivot, const ScPivot* pNewPivot ) :
//UNUSED2008-05      ScSimpleUndo( pNewDocShell ),
//UNUSED2008-05      aOldArea( rOld ),
//UNUSED2008-05      aNewArea( rNew ),
//UNUSED2008-05      pOldUndoDoc( pOldDoc ),
//UNUSED2008-05      pNewUndoDoc( pNewDoc )
//UNUSED2008-05  {
//UNUSED2008-05      if (pNewPivot)
//UNUSED2008-05      {
//UNUSED2008-05          pNewPivot->GetParam( aNewParam, aNewQuery, aNewSrc );
//UNUSED2008-05          aNewName = pNewPivot->GetName();
//UNUSED2008-05          aNewTag = pNewPivot->GetTag();
//UNUSED2008-05      }
//UNUSED2008-05      if (pOldPivot)
//UNUSED2008-05      {
//UNUSED2008-05          pOldPivot->GetParam( aOldParam, aOldQuery, aOldSrc );
//UNUSED2008-05          aOldName = pOldPivot->GetName();
//UNUSED2008-05          aOldTag = pOldPivot->GetTag();
//UNUSED2008-05      }
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  __EXPORT ScUndoPivot::~ScUndoPivot()
//UNUSED2008-05  {
//UNUSED2008-05      delete pOldUndoDoc;
//UNUSED2008-05      delete pNewUndoDoc;
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  String __EXPORT ScUndoPivot::GetComment() const
//UNUSED2008-05  {
//UNUSED2008-05      sal_uInt16 nIndex;
//UNUSED2008-05      if ( pOldUndoDoc && pNewUndoDoc )
//UNUSED2008-05          nIndex = STR_UNDO_PIVOT_MODIFY;
//UNUSED2008-05      else if ( pNewUndoDoc )
//UNUSED2008-05          nIndex = STR_UNDO_PIVOT_NEW;
//UNUSED2008-05      else
//UNUSED2008-05          nIndex = STR_UNDO_PIVOT_DELETE;
//UNUSED2008-05
//UNUSED2008-05      return ScGlobal::GetRscString( nIndex );
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  void __EXPORT ScUndoPivot::Undo()
//UNUSED2008-05  {
//UNUSED2008-05      BeginUndo();
//UNUSED2008-05
//UNUSED2008-05      ScDocument* pDoc = pDocShell->GetDocument();
//UNUSED2008-05
//UNUSED2008-05      if (pNewUndoDoc)
//UNUSED2008-05      {
//UNUSED2008-05          pDoc->DeleteAreaTab( aNewArea.nColStart,aNewArea.nRowStart,
//UNUSED2008-05                              aNewArea.nColEnd,aNewArea.nRowEnd, aNewArea.nTab, IDF_ALL );
//UNUSED2008-05          pNewUndoDoc->CopyToDocument( aNewArea.nColStart, aNewArea.nRowStart, aNewArea.nTab,
//UNUSED2008-05                                  aNewArea.nColEnd, aNewArea.nRowEnd, aNewArea.nTab,
//UNUSED2008-05                                  IDF_ALL, sal_False, pDoc );
//UNUSED2008-05      }
//UNUSED2008-05      if (pOldUndoDoc)
//UNUSED2008-05      {
//UNUSED2008-05          pDoc->DeleteAreaTab( aOldArea.nColStart,aOldArea.nRowStart,
//UNUSED2008-05                              aOldArea.nColEnd,aOldArea.nRowEnd, aOldArea.nTab, IDF_ALL );
//UNUSED2008-05          pOldUndoDoc->CopyToDocument( aOldArea.nColStart, aOldArea.nRowStart, aOldArea.nTab,
//UNUSED2008-05                                  aOldArea.nColEnd, aOldArea.nRowEnd, aOldArea.nTab,
//UNUSED2008-05                                  IDF_ALL, sal_False, pDoc );
//UNUSED2008-05      }
//UNUSED2008-05
//UNUSED2008-05      ScPivotCollection* pPivotCollection = pDoc->GetPivotCollection();
//UNUSED2008-05      if ( pNewUndoDoc )
//UNUSED2008-05      {
//UNUSED2008-05          ScPivot* pNewPivot = pPivotCollection->GetPivotAtCursor(
//UNUSED2008-05                                  aNewParam.nCol, aNewParam.nRow, aNewParam.nTab );
//UNUSED2008-05          if (pNewPivot)
//UNUSED2008-05              pPivotCollection->Free( pNewPivot );
//UNUSED2008-05      }
//UNUSED2008-05      if ( pOldUndoDoc )
//UNUSED2008-05      {
//UNUSED2008-05          ScPivot* pOldPivot = new ScPivot( pDoc );
//UNUSED2008-05          pOldPivot->SetParam( aOldParam, aOldQuery, aOldSrc );
//UNUSED2008-05          pOldPivot->SetName( aOldName );
//UNUSED2008-05          pOldPivot->SetTag( aOldTag );
//UNUSED2008-05          if (pOldPivot->CreateData())                            // Felder berechnen
//UNUSED2008-05              pOldPivot->ReleaseData();
//UNUSED2008-05          pPivotCollection->Insert( pOldPivot );
//UNUSED2008-05      }
//UNUSED2008-05
//UNUSED2008-05  // erack! it's broadcasted
//UNUSED2008-05  //	pDoc->SetDirty();
//UNUSED2008-05      if (pNewUndoDoc)
//UNUSED2008-05          pDocShell->PostPaint( aNewArea.nColStart, aNewArea.nRowStart, aNewArea.nTab,
//UNUSED2008-05                                  aNewArea.nColEnd, aNewArea.nRowEnd, aNewArea.nTab,
//UNUSED2008-05                                  PAINT_GRID, SC_PF_LINES );
//UNUSED2008-05      if (pOldUndoDoc)
//UNUSED2008-05          pDocShell->PostPaint( aOldArea.nColStart, aOldArea.nRowStart, aOldArea.nTab,
//UNUSED2008-05                                  aOldArea.nColEnd, aOldArea.nRowEnd, aOldArea.nTab,
//UNUSED2008-05                                  PAINT_GRID, SC_PF_LINES );
//UNUSED2008-05      pDocShell->PostDataChanged();
//UNUSED2008-05
//UNUSED2008-05      ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
//UNUSED2008-05      if (pViewShell)
//UNUSED2008-05      {
//UNUSED2008-05          SCTAB nTab = pViewShell->GetViewData()->GetTabNo();
//UNUSED2008-05          if ( pOldUndoDoc )
//UNUSED2008-05          {
//UNUSED2008-05              if ( nTab != aOldArea.nTab )
//UNUSED2008-05                  pViewShell->SetTabNo( aOldArea.nTab );
//UNUSED2008-05          }
//UNUSED2008-05          else if ( pNewUndoDoc )
//UNUSED2008-05          {
//UNUSED2008-05              if ( nTab != aNewArea.nTab )
//UNUSED2008-05                  pViewShell->SetTabNo( aNewArea.nTab );
//UNUSED2008-05          }
//UNUSED2008-05      }
//UNUSED2008-05
//UNUSED2008-05      EndUndo();
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  void __EXPORT ScUndoPivot::Redo()
//UNUSED2008-05  {
//UNUSED2008-05      BeginRedo();
//UNUSED2008-05
//UNUSED2008-05      ScDocument* pDoc = pDocShell->GetDocument();
//UNUSED2008-05      ScPivotCollection* pPivotCollection = pDoc->GetPivotCollection();
//UNUSED2008-05      ScPivot* pOldPivot = pPivotCollection->GetPivotAtCursor(
//UNUSED2008-05                                              aOldParam.nCol, aOldParam.nRow, aOldParam.nTab );
//UNUSED2008-05
//UNUSED2008-05      ScPivot* pNewPivot = NULL;
//UNUSED2008-05      if (pNewUndoDoc)
//UNUSED2008-05      {
//UNUSED2008-05          pNewPivot = new ScPivot( pDoc );
//UNUSED2008-05          pNewPivot->SetParam( aNewParam, aNewQuery, aNewSrc );
//UNUSED2008-05          pNewPivot->SetName( aNewName );
//UNUSED2008-05          pNewPivot->SetTag( aNewTag );
//UNUSED2008-05      }
//UNUSED2008-05
//UNUSED2008-05      pDocShell->PivotUpdate( pOldPivot, pNewPivot, sal_False );
//UNUSED2008-05
//UNUSED2008-05      EndRedo();
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  void __EXPORT ScUndoPivot::Repeat(SfxRepeatTarget& rTarget)
//UNUSED2008-05  {
//UNUSED2008-05      //  Wiederholen: nur loeschen
//UNUSED2008-05
//UNUSED2008-05      if ( pOldUndoDoc && !pNewUndoDoc && rTarget.ISA(ScTabViewTarget) )
//UNUSED2008-05          ((ScTabViewTarget&)rTarget).GetViewShell()->DeletePivotTable();
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  sal_Bool __EXPORT ScUndoPivot::CanRepeat(SfxRepeatTarget& rTarget) const
//UNUSED2008-05  {
//UNUSED2008-05      //  Wiederholen: nur loeschen
//UNUSED2008-05
//UNUSED2008-05      return ( pOldUndoDoc && !pNewUndoDoc && rTarget.ISA(ScTabViewTarget) );
//UNUSED2008-05  }

//
//		data pilot
//

ScUndoDataPilot::ScUndoDataPilot( ScDocShell* pNewDocShell,
							ScDocument* pOldDoc, ScDocument* pNewDoc,
							const ScDPObject* pOldObj, const ScDPObject* pNewObj, sal_Bool bMove ) :
	ScSimpleUndo( pNewDocShell ),
	pOldUndoDoc( pOldDoc ),
	pNewUndoDoc( pNewDoc ),
	pOldDPObject( NULL ),
	pNewDPObject( NULL ),
	bAllowMove( bMove )
{
	if (pOldObj)
		pOldDPObject = new ScDPObject( *pOldObj );
	if (pNewObj)
		pNewDPObject = new ScDPObject( *pNewObj );
}

__EXPORT ScUndoDataPilot::~ScUndoDataPilot()
{
	delete pOldDPObject;
	delete pNewDPObject;
	delete pOldUndoDoc;
	delete pNewUndoDoc;
}

String __EXPORT ScUndoDataPilot::GetComment() const
{
	sal_uInt16 nIndex;
	if ( pOldUndoDoc && pNewUndoDoc )
		nIndex = STR_UNDO_PIVOT_MODIFY;
	else if ( pNewUndoDoc )
		nIndex = STR_UNDO_PIVOT_NEW;
	else
		nIndex = STR_UNDO_PIVOT_DELETE;

	return ScGlobal::GetRscString( nIndex );
}

void __EXPORT ScUndoDataPilot::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();

	ScRange aOldRange;
	ScRange aNewRange;

	if ( pNewDPObject && pNewUndoDoc )
	{
		aNewRange = pNewDPObject->GetOutRange();
		pDoc->DeleteAreaTab( aNewRange, IDF_ALL );
		pNewUndoDoc->CopyToDocument( aNewRange, IDF_ALL, sal_False, pDoc );
	}
	if ( pOldDPObject && pOldUndoDoc )
	{
		aOldRange = pOldDPObject->GetOutRange();
		pDoc->DeleteAreaTab( aOldRange, IDF_ALL );
		pOldUndoDoc->CopyToDocument( aOldRange, IDF_ALL, sal_False, pDoc );
	}

	//	update objects in collection

	if ( pNewDPObject )
	{
		//	find updated object
		//!	find by name!

		ScDPObject* pDocObj = pDoc->GetDPAtCursor(
							aNewRange.aStart.Col(), aNewRange.aStart.Row(), aNewRange.aStart.Tab() );
		DBG_ASSERT(pDocObj, "DPObject not found");
		if (pDocObj)
		{
			if ( pOldDPObject )
			{
				//	restore old settings
				pOldDPObject->WriteSourceDataTo( *pDocObj );
				ScDPSaveData* pData = pOldDPObject->GetSaveData();
				if (pData)
					pDocObj->SetSaveData(*pData);
				pDocObj->SetOutRange( pOldDPObject->GetOutRange() );
				pOldDPObject->WriteTempDataTo( *pDocObj );
			}
			else
			{
				//	delete inserted object
                pDoc->GetDPCollection()->FreeTable(pDocObj);
			}
		}
	}
	else if ( pOldDPObject )
	{
		//	re-insert deleted object

		ScDPObject* pDestObj = new ScDPObject( *pOldDPObject );
		pDestObj->SetAlive(sal_True);
		if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) )
		{
			DBG_ERROR("cannot insert DPObject");
			DELETEZ( pDestObj );
		}
	}

	if (pNewUndoDoc)
		pDocShell->PostPaint( aNewRange, PAINT_GRID, SC_PF_LINES );
	if (pOldUndoDoc)
		pDocShell->PostPaint( aOldRange, PAINT_GRID, SC_PF_LINES );
	pDocShell->PostDataChanged();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	if (pViewShell)
	{
		//!	set current sheet
	}

    if (pNewDPObject)
    {
        // notify API objects
        pDoc->BroadcastUno( ScDataPilotModifiedHint( pNewDPObject->GetName() ) );
    }

	EndUndo();
}

void __EXPORT ScUndoDataPilot::Redo()
{
	BeginRedo();

	//!	copy output data instead of repeating the change,
	//!	in case external data have changed!

	ScDocument* pDoc = pDocShell->GetDocument();

	ScDPObject* pSourceObj = NULL;
	if ( pOldDPObject )
	{
		//	find object to modify
		//!	find by name!

		ScRange aOldRange = pOldDPObject->GetOutRange();
		pSourceObj = pDoc->GetDPAtCursor(
						aOldRange.aStart.Col(), aOldRange.aStart.Row(), aOldRange.aStart.Tab() );
		DBG_ASSERT(pSourceObj, "DPObject not found");
	}

	ScDBDocFunc aFunc( *pDocShell );
	aFunc.DataPilotUpdate( pSourceObj, pNewDPObject, sal_False, sal_False, bAllowMove );	// no new undo action

	EndRedo();
}

void __EXPORT ScUndoDataPilot::Repeat(SfxRepeatTarget& /* rTarget */)
{
	//!	allow deletion
}

sal_Bool __EXPORT ScUndoDataPilot::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
	//!	allow deletion
	return sal_False;
}


//
//		Konsolidieren
//

ScUndoConsolidate::ScUndoConsolidate( ScDocShell* pNewDocShell, const ScArea& rArea,
					const ScConsolidateParam& rPar, ScDocument* pNewUndoDoc,
					sal_Bool bReference, SCROW nInsCount, ScOutlineTable* pTab,
					ScDBData* pData ) :
	ScSimpleUndo( pNewDocShell ),
	aDestArea( rArea ),
	pUndoDoc( pNewUndoDoc ),
	aParam( rPar ),
	bInsRef( bReference ),
	nInsertCount( nInsCount ),
	pUndoTab( pTab ),
	pUndoData( pData )
{
}

__EXPORT ScUndoConsolidate::~ScUndoConsolidate()
{
	delete pUndoDoc;
	delete pUndoTab;
	delete pUndoData;
}

String __EXPORT ScUndoConsolidate::GetComment() const
{
	return ScGlobal::GetRscString( STR_UNDO_CONSOLIDATE );
}

void __EXPORT ScUndoConsolidate::Undo()
{
	BeginUndo();

	ScDocument* pDoc = pDocShell->GetDocument();
	SCTAB nTab = aDestArea.nTab;

	ScRange aOldRange;
	if (pUndoData)
		pUndoData->GetArea(aOldRange);

	if (bInsRef)
	{
		//	Zeilen loeschen
		pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, aDestArea.nRowStart, nInsertCount );

		//	Outlines
		pDoc->SetOutlineTable( nTab, pUndoTab );

		//	Zeilenstatus
		pUndoDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, sal_False, pDoc );

		//	Daten & Referenzen
		pDoc->DeleteAreaTab( 0,aDestArea.nRowStart, MAXCOL,aDestArea.nRowEnd, nTab, IDF_ALL );
		pUndoDoc->UndoToDocument( 0, aDestArea.nRowStart, nTab,
									MAXCOL, aDestArea.nRowEnd, nTab,
									IDF_ALL, sal_False, pDoc );

		//	Original-Bereich
		if (pUndoData)
		{
			pDoc->DeleteAreaTab(aOldRange, IDF_ALL);
			pUndoDoc->CopyToDocument(aOldRange, IDF_ALL, sal_False, pDoc);
		}

		pDocShell->PostPaint( 0,aDestArea.nRowStart,nTab, MAXCOL,MAXROW,nTab,
								PAINT_GRID | PAINT_LEFT | PAINT_SIZE );
	}
	else
	{
		pDoc->DeleteAreaTab( aDestArea.nColStart,aDestArea.nRowStart,
								aDestArea.nColEnd,aDestArea.nRowEnd, nTab, IDF_ALL );
		pUndoDoc->CopyToDocument( aDestArea.nColStart, aDestArea.nRowStart, nTab,
									aDestArea.nColEnd, aDestArea.nRowEnd, nTab,
									IDF_ALL, sal_False, pDoc );

		//	Original-Bereich
		if (pUndoData)
		{
			pDoc->DeleteAreaTab(aOldRange, IDF_ALL);
			pUndoDoc->CopyToDocument(aOldRange, IDF_ALL, sal_False, pDoc);
		}

		SCCOL nEndX = aDestArea.nColEnd;
		SCROW nEndY = aDestArea.nRowEnd;
		if ( pUndoData )
		{
			if ( aOldRange.aEnd.Col() > nEndX )
				nEndX = aOldRange.aEnd.Col();
			if ( aOldRange.aEnd.Row() > nEndY )
				nEndY = aOldRange.aEnd.Row();
		}
		pDocShell->PostPaint( aDestArea.nColStart, aDestArea.nRowStart, nTab,
									nEndX, nEndY, nTab, PAINT_GRID );
	}

	//	DB-Bereich wieder anpassen
	if (pUndoData)
	{
		ScDBCollection*	pColl = pDoc->GetDBCollection();
		if (pColl)
		{
			sal_uInt16 nIndex;
			if (pColl->SearchName( pUndoData->GetName(), nIndex ))
			{
				ScDBData* pDocData = (*pColl)[nIndex];
				if (pDocData)
					*pDocData = *pUndoData;
			}
			else
			{
				DBG_ERROR("alte DB-Daten nicht gefunden");
			}
		}
	}

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	if (pViewShell)
	{
		SCTAB nViewTab = pViewShell->GetViewData()->GetTabNo();
		if ( nViewTab != nTab )
			pViewShell->SetTabNo( nTab );
	}

	EndUndo();
}

void __EXPORT ScUndoConsolidate::Redo()
{
	BeginRedo();

	pDocShell->DoConsolidate( aParam, sal_False );

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	if (pViewShell)
	{
		SCTAB nViewTab = pViewShell->GetViewData()->GetTabNo();
		if ( nViewTab != aParam.nTab )
			pViewShell->SetTabNo( aParam.nTab );
	}

	EndRedo();
}

void __EXPORT ScUndoConsolidate::Repeat(SfxRepeatTarget& /* rTarget */)
{
}

sal_Bool __EXPORT ScUndoConsolidate::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
	return sal_False;
}


//
//		Quell-Daten von Chart aendern
//

void ScUndoChartData::Init()
{
	ScDocument* pDoc = pDocShell->GetDocument();
    aOldRangeListRef = new ScRangeList;
    pDoc->GetOldChartParameters( aChartName, *aOldRangeListRef, bOldColHeaders, bOldRowHeaders );
}

ScUndoChartData::ScUndoChartData( ScDocShell* pNewDocShell, const String& rName,
									const ScRange& rNew, sal_Bool bColHdr, sal_Bool bRowHdr,
									sal_Bool bAdd ) :
	ScSimpleUndo( pNewDocShell ),
	aChartName( rName ),
	bNewColHeaders( bColHdr ),
	bNewRowHeaders( bRowHdr ),
	bAddRange( bAdd )
{
	aNewRangeListRef = new ScRangeList;
	aNewRangeListRef->Append( rNew );

	Init();
}

ScUndoChartData::ScUndoChartData( ScDocShell* pNewDocShell, const String& rName,
									const ScRangeListRef& rNew, sal_Bool bColHdr, sal_Bool bRowHdr,
									sal_Bool bAdd ) :
	ScSimpleUndo( pNewDocShell ),
	aChartName( rName ),
	aNewRangeListRef( rNew ),
	bNewColHeaders( bColHdr ),
	bNewRowHeaders( bRowHdr ),
	bAddRange( bAdd )
{
	Init();
}

__EXPORT ScUndoChartData::~ScUndoChartData()
{
}

String __EXPORT ScUndoChartData::GetComment() const
{
	return ScGlobal::GetRscString( STR_UNDO_CHARTDATA );
}

void __EXPORT ScUndoChartData::Undo()
{
	BeginUndo();

	pDocShell->GetDocument()->UpdateChartArea( aChartName, aOldRangeListRef,
								bOldColHeaders, bOldRowHeaders, sal_False );

	EndUndo();
}

void __EXPORT ScUndoChartData::Redo()
{
	BeginRedo();

	pDocShell->GetDocument()->UpdateChartArea( aChartName, aNewRangeListRef,
								bNewColHeaders, bNewRowHeaders, bAddRange );

	EndRedo();
}

void __EXPORT ScUndoChartData::Repeat(SfxRepeatTarget& /* rTarget */)
{
}

sal_Bool __EXPORT ScUndoChartData::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
	return sal_False;
}
