/**************************************************************
 * 
 * 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 "scitems.hxx"
#include <editeng/eeitem.hxx>

#include <editeng/editobj.hxx>
#include <svl/zforlist.hxx>
#include <sfx2/app.hxx>

#include "undocell.hxx"
#include "document.hxx"
#include "docpool.hxx"
#include "patattr.hxx"
#include "docsh.hxx"
#include "tabvwsh.hxx"
#include "globstr.hrc"
#include "global.hxx"
#include "cell.hxx"
#include "target.hxx"
#include "undoolk.hxx"
#include "detdata.hxx"
#include "stlpool.hxx"
#include "printfun.hxx"
#include "rangenam.hxx"
#include "chgtrack.hxx"
#include "sc.hrc"
#include "docuno.hxx"

// -----------------------------------------------------------------------
//
//		Attribute auf Cursor anwenden
//

ScUndoCursorAttr::ScUndoCursorAttr( ScDocShell* pNewDocShell,
			SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
			const ScPatternAttr* pOldPat, const ScPatternAttr* pNewPat,
			const ScPatternAttr* pApplyPat, sal_Bool bAutomatic ) :
	ScSimpleUndo( pNewDocShell ),
	nCol( nNewCol ),
	nRow( nNewRow ),
	nTab( nNewTab ),
	bIsAutomatic( bAutomatic )
{
	ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
	pNewPattern = (ScPatternAttr*) &pPool->Put( *pNewPat );
	pOldPattern = (ScPatternAttr*) &pPool->Put( *pOldPat );
	pApplyPattern = (ScPatternAttr*) &pPool->Put( *pApplyPat );
}

__EXPORT ScUndoCursorAttr::~ScUndoCursorAttr()
{
	ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
	pPool->Remove(*pNewPattern);
	pPool->Remove(*pOldPattern);
	pPool->Remove(*pApplyPattern);
}

String __EXPORT ScUndoCursorAttr::GetComment() const
{
	//!	eigener Text fuer automatische Attributierung

	sal_uInt16 nId = STR_UNDO_CURSORATTR;		 // "Attribute"
	return ScGlobal::GetRscString( nId );
}

void ScUndoCursorAttr::DoChange( const ScPatternAttr* pWhichPattern ) const
{
	pDocShell->GetDocument()->SetPattern( nCol, nRow, nTab, *pWhichPattern, sal_True );

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	if (pViewShell)
	{
		pViewShell->SetTabNo( nTab );
		pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
		pViewShell->AdjustBlockHeight();
	}

	const SfxItemSet& rApplySet = pApplyPattern->GetItemSet();
	sal_Bool bPaintExt = ( rApplySet.GetItemState( ATTR_SHADOW, sal_True ) != SFX_ITEM_DEFAULT ||
					   rApplySet.GetItemState( ATTR_CONDITIONAL, sal_True ) != SFX_ITEM_DEFAULT );
	sal_Bool bPaintRows = ( rApplySet.GetItemState( ATTR_HOR_JUSTIFY, sal_True ) != SFX_ITEM_DEFAULT );

	sal_uInt16 nFlags = SC_PF_TESTMERGE;
	if (bPaintExt)
		nFlags |= SC_PF_LINES;
	if (bPaintRows)
		nFlags |= SC_PF_WHOLEROWS;
	pDocShell->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, nFlags );
}

void __EXPORT ScUndoCursorAttr::Undo()
{
	BeginUndo();
	DoChange(pOldPattern);

	if ( bIsAutomatic )
	{
		//	wenn automatische Formatierung rueckgaengig gemacht wird,
		//	soll auch nicht weiter automatisch formatiert werden:

		ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
		if (pViewShell)
			pViewShell->ForgetFormatArea();
	}

	EndUndo();
}

void __EXPORT ScUndoCursorAttr::Redo()
{
	BeginRedo();
	DoChange(pNewPattern);
	EndRedo();
}

void __EXPORT ScUndoCursorAttr::Repeat(SfxRepeatTarget& rTarget)
{
	ScTabViewTarget* pScTabViewTarget = dynamic_cast< ScTabViewTarget* >(&rTarget);

	if (pScTabViewTarget)
		pScTabViewTarget->GetViewShell()->ApplySelectionPattern( *pApplyPattern );
}

sal_Bool __EXPORT ScUndoCursorAttr::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return 0 != dynamic_cast< ScTabViewTarget* >(&rTarget);
}


// -----------------------------------------------------------------------
//
//		Daten eingeben
//

ScUndoEnterData::ScUndoEnterData( ScDocShell* pNewDocShell,
			SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
			SCTAB nNewCount, SCTAB* pNewTabs, ScBaseCell** ppOldData,
			sal_Bool* pHasForm, sal_uLong* pOldForm,
			const String& rNewStr, EditTextObject* pObj ) :
	ScSimpleUndo( pNewDocShell ),
	aNewString( rNewStr ),
	pTabs( pNewTabs ),
	ppOldCells( ppOldData ),
	pHasFormat( pHasForm ),
	pOldFormats( pOldForm ),
	pNewEditData( pObj ),
	nCol( nNewCol ),
	nRow( nNewRow ),
	nTab( nNewTab ),
	nCount( nNewCount )
{
	SetChangeTrack();
}

__EXPORT ScUndoEnterData::~ScUndoEnterData()
{
	for (sal_uInt16 i=0; i<nCount; i++)
		if (ppOldCells[i])
			ppOldCells[i]->Delete();
	delete[] ppOldCells;

	delete[] pHasFormat;
	delete[] pOldFormats;
	delete[] pTabs;

	delete pNewEditData;
}

String __EXPORT ScUndoEnterData::GetComment() const
{
	return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
}

void ScUndoEnterData::DoChange() const
{
	//	Zeilenhoehe anpassen
	//!	nur wenn noetig (alte oder neue EditZelle, oder Attribute) ??
	for (sal_uInt16 i=0; i<nCount; i++)
		pDocShell->AdjustRowHeight( nRow, nRow, pTabs[i] );

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	if (pViewShell)
	{
		pViewShell->SetTabNo( nTab );
		pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
	}

	pDocShell->PostDataChanged();
}

void ScUndoEnterData::SetChangeTrack()
{
	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
	if ( pChangeTrack )
	{
		nEndChangeAction = pChangeTrack->GetActionMax() + 1;
		ScAddress aPos( nCol, nRow, nTab );
		for (sal_uInt16 i=0; i<nCount; i++)
		{
			aPos.SetTab( pTabs[i] );
			sal_uLong nFormat = 0;
			if ( pHasFormat && pOldFormats )
			{
				if ( pHasFormat[i] )
					nFormat = pOldFormats[i];
			}
			pChangeTrack->AppendContent( aPos, ppOldCells[i], nFormat );
		}
		if ( nEndChangeAction > pChangeTrack->GetActionMax() )
			nEndChangeAction = 0;		// nichts appended
	}
	else
		nEndChangeAction = 0;
}

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

	ScDocument* pDoc = pDocShell->GetDocument();
	for (sal_uInt16 i=0; i<nCount; i++)
	{
        ScBaseCell* pNewCell = ppOldCells[i] ? ppOldCells[i]->CloneWithoutNote( *pDoc, SC_CLONECELL_STARTLISTENING ) : 0;
		pDoc->PutCell( nCol, nRow, pTabs[i], pNewCell );

		if (pHasFormat && pOldFormats)
		{
			if ( pHasFormat[i] )
				pDoc->ApplyAttr( nCol, nRow, pTabs[i],
									SfxUInt32Item( ATTR_VALUE_FORMAT, pOldFormats[i] ) );
			else
			{
				ScPatternAttr aPattern( *pDoc->GetPattern( nCol, nRow, pTabs[i] ) );
				aPattern.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
				pDoc->SetPattern( nCol, nRow, pTabs[i], aPattern, sal_True );
			}
		}
		pDocShell->PostPaintCell( nCol, nRow, pTabs[i] );
	}

	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
    if ( pChangeTrack && nEndChangeAction >= sal::static_int_cast<sal_uLong>(nCount) )
		pChangeTrack->Undo( nEndChangeAction - nCount + 1, nEndChangeAction );

	DoChange();
	EndUndo();

    // #i97876# Spreadsheet data changes are not notified
    ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
    if ( pModelObj && pModelObj->HasChangesListeners() )
    {
        ScRangeList aChangeRanges;
        for ( sal_uInt16 i = 0; i < nCount; ++i )
        {
            aChangeRanges.Append( ScRange( nCol, nRow, pTabs[i] ) );
        }
        pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
    }
}

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

	ScDocument* pDoc = pDocShell->GetDocument();
	for (sal_uInt16 i=0; i<nCount; i++)
	{
		if (pNewEditData)
			pDoc->PutCell( nCol, nRow, pTabs[i], new ScEditCell( pNewEditData,
				pDoc, NULL ) );
		else
			pDoc->SetString( nCol, nRow, pTabs[i], aNewString );
		pDocShell->PostPaintCell( nCol, nRow, pTabs[i] );
	}

	SetChangeTrack();

	DoChange();
	EndRedo();

    // #i97876# Spreadsheet data changes are not notified
    ScModelObj* pModelObj = ScModelObj::getImplementation( pDocShell->GetModel() );
    if ( pModelObj && pModelObj->HasChangesListeners() )
    {
        ScRangeList aChangeRanges;
        for ( sal_uInt16 i = 0; i < nCount; ++i )
        {
            aChangeRanges.Append( ScRange( nCol, nRow, pTabs[i] ) );
        }
        pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
    }
}

void __EXPORT ScUndoEnterData::Repeat(SfxRepeatTarget& rTarget)
{
	ScTabViewTarget* pScTabViewTarget = dynamic_cast< ScTabViewTarget* >(&rTarget);

	if (pScTabViewTarget)
	{
		String aTemp = aNewString;
		pScTabViewTarget->GetViewShell()->EnterDataAtCursor( aTemp );
	}
}

sal_Bool __EXPORT ScUndoEnterData::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return 0 != dynamic_cast< ScTabViewTarget* >(&rTarget);
}


// -----------------------------------------------------------------------
//
//		Wert aendern
//

ScUndoEnterValue::ScUndoEnterValue( ScDocShell* pNewDocShell, const ScAddress& rNewPos,
									ScBaseCell* pUndoCell, double nVal, sal_Bool bHeight ) :
	ScSimpleUndo( pNewDocShell ),
	aPos		( rNewPos ),
	pOldCell	( pUndoCell ),
	nValue		( nVal ),
	bNeedHeight	( bHeight )
{
	SetChangeTrack();
}

__EXPORT ScUndoEnterValue::~ScUndoEnterValue()
{
	if (pOldCell)
		pOldCell->Delete();
}

String __EXPORT ScUndoEnterValue::GetComment() const
{
	return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
}

void ScUndoEnterValue::SetChangeTrack()
{
	ScDocument* pDoc = pDocShell->GetDocument();
	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
	if ( pChangeTrack )
	{
		nEndChangeAction = pChangeTrack->GetActionMax() + 1;
		pChangeTrack->AppendContent( aPos, pOldCell );
		if ( nEndChangeAction > pChangeTrack->GetActionMax() )
			nEndChangeAction = 0;		// nichts appended
	}
	else
		nEndChangeAction = 0;
}

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

	ScDocument* pDoc = pDocShell->GetDocument();
    ScBaseCell* pNewCell = pOldCell ? pOldCell->CloneWithoutNote( *pDoc, SC_CLONECELL_STARTLISTENING ) : 0;

	pDoc->PutCell( aPos, pNewCell );

	pDocShell->PostPaintCell( aPos );

	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
	if ( pChangeTrack )
		pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );

	EndUndo();
}

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

	ScDocument* pDoc = pDocShell->GetDocument();
	pDoc->SetValue( aPos.Col(), aPos.Row(), aPos.Tab(), nValue );
	pDocShell->PostPaintCell( aPos );

	SetChangeTrack();

	EndRedo();
}

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

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


// -----------------------------------------------------------------------
//
//		Beliebige Zelle eingeben
//

ScUndoPutCell::ScUndoPutCell( ScDocShell* pNewDocShell, const ScAddress& rNewPos,
							ScBaseCell* pUndoCell, ScBaseCell* pRedoCell, sal_Bool bHeight ) :
	ScSimpleUndo( pNewDocShell ),
	aPos		( rNewPos ),
	pOldCell	( pUndoCell ),
	pEnteredCell( pRedoCell ),
	bNeedHeight	( bHeight )
{
	SetChangeTrack();
}

__EXPORT ScUndoPutCell::~ScUndoPutCell()
{
	if (pOldCell)
		pOldCell->Delete();
	if (pEnteredCell)
		pEnteredCell->Delete();
}

String __EXPORT ScUndoPutCell::GetComment() const
{
	return ScGlobal::GetRscString( STR_UNDO_ENTERDATA ); // "Eingabe"
}

void ScUndoPutCell::SetChangeTrack()
{
	ScDocument* pDoc = pDocShell->GetDocument();
	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
	if ( pChangeTrack )
	{
		nEndChangeAction = pChangeTrack->GetActionMax() + 1;
		pChangeTrack->AppendContent( aPos, pOldCell );
		if ( nEndChangeAction > pChangeTrack->GetActionMax() )
			nEndChangeAction = 0;		// nichts appended
	}
	else
		nEndChangeAction = 0;
}

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

	ScDocument* pDoc = pDocShell->GetDocument();
    ScBaseCell* pNewCell = pOldCell ? pOldCell->CloneWithoutNote( *pDoc, aPos, SC_CLONECELL_STARTLISTENING ) : 0;

	pDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pNewCell );

	pDocShell->PostPaintCell( aPos );

	ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
	if ( pChangeTrack )
		pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );

	EndUndo();
}

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

	ScDocument* pDoc = pDocShell->GetDocument();
    ScBaseCell* pNewCell = pEnteredCell ? pEnteredCell->CloneWithoutNote( *pDoc, aPos, SC_CLONECELL_STARTLISTENING ) : 0;

	pDoc->PutCell( aPos.Col(), aPos.Row(), aPos.Tab(), pNewCell );

	pDocShell->PostPaintCell( aPos );

	SetChangeTrack();

	EndRedo();
}

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

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


// -----------------------------------------------------------------------
//
//		Seitenumbrueche
//

ScUndoPageBreak::ScUndoPageBreak( ScDocShell* pNewDocShell,
			SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
			sal_Bool bNewColumn, sal_Bool bNewInsert ) :
	ScSimpleUndo( pNewDocShell ),
	nCol( nNewCol ),
	nRow( nNewRow ),
	nTab( nNewTab ),
	bColumn( bNewColumn ),
	bInsert( bNewInsert )
{
}

__EXPORT ScUndoPageBreak::~ScUndoPageBreak()
{
}

String __EXPORT ScUndoPageBreak::GetComment() const
{
	//"Spaltenumbruch" | "Zeilenumbruch"  "einfuegen" | "loeschen"
	return String ( bColumn ?
		( bInsert ?
			ScGlobal::GetRscString( STR_UNDO_INSCOLBREAK ) :
			ScGlobal::GetRscString( STR_UNDO_DELCOLBREAK )
		) :
		( bInsert ?
			ScGlobal::GetRscString( STR_UNDO_INSROWBREAK ) :
			ScGlobal::GetRscString( STR_UNDO_DELROWBREAK )
		) );
}

void ScUndoPageBreak::DoChange( sal_Bool bInsertP ) const
{
	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();

	if (pViewShell)
	{
		pViewShell->SetTabNo( nTab );
		pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );

        if (bInsertP)
			pViewShell->InsertPageBreak(bColumn, sal_False);
		else
			pViewShell->DeletePageBreak(bColumn, sal_False);

        pDocShell->GetDocument()->InvalidatePageBreaks(nTab);
	}
}

void __EXPORT ScUndoPageBreak::Undo()
{
	BeginUndo();
	DoChange(!bInsert);
	EndUndo();
}

void __EXPORT ScUndoPageBreak::Redo()
{
	BeginRedo();
	DoChange(bInsert);
	EndRedo();
}

void __EXPORT ScUndoPageBreak::Repeat(SfxRepeatTarget& rTarget)
{
	ScTabViewTarget* pScTabViewTarget = dynamic_cast< ScTabViewTarget* >(&rTarget);

	if (pScTabViewTarget)
	{
		ScTabViewShell& rViewShell = *pScTabViewTarget->GetViewShell();

		if (bInsert)
			rViewShell.InsertPageBreak(bColumn, sal_True);
		else
			rViewShell.DeletePageBreak(bColumn, sal_True);
	}
}

sal_Bool __EXPORT ScUndoPageBreak::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return 0 != dynamic_cast< ScTabViewTarget* >(&rTarget);
}

// -----------------------------------------------------------------------
//
//		Druck-Skalierung
//

ScUndoPrintZoom::ScUndoPrintZoom( ScDocShell* pNewDocShell,
			SCTAB nT, sal_uInt16 nOS, sal_uInt16 nOP, sal_uInt16 nNS, sal_uInt16 nNP ) :
	ScSimpleUndo( pNewDocShell ),
	nTab( nT ),
	nOldScale( nOS ),
	nOldPages( nOP ),
	nNewScale( nNS ),
	nNewPages( nNP )
{
}

__EXPORT ScUndoPrintZoom::~ScUndoPrintZoom()
{
}

String __EXPORT ScUndoPrintZoom::GetComment() const
{
	return ScGlobal::GetRscString( STR_UNDO_PRINTSCALE );
}

void ScUndoPrintZoom::DoChange( sal_Bool bUndo )
{
	sal_uInt16 nScale = bUndo ? nOldScale : nNewScale;
	sal_uInt16 nPages = bUndo ? nOldPages : nNewPages;

	ScDocument* pDoc = pDocShell->GetDocument();
	String aStyleName = pDoc->GetPageStyle( nTab );
	ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
	SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
	DBG_ASSERT( pStyleSheet, "PageStyle not found" );
	if ( pStyleSheet )
	{
		SfxItemSet& rSet = pStyleSheet->GetItemSet();
		rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) );
		rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) );

		ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
		aPrintFunc.UpdatePages();
	}
}

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

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

void __EXPORT ScUndoPrintZoom::Repeat(SfxRepeatTarget& rTarget)
{
	ScTabViewTarget* pScTabViewTarget = dynamic_cast< ScTabViewTarget* >(&rTarget);

	if (pScTabViewTarget)
	{
		ScTabViewShell& rViewShell = *pScTabViewTarget->GetViewShell();
		ScViewData* pViewData = rViewShell.GetViewData();
		pViewData->GetDocShell()->SetPrintZoom( pViewData->GetTabNo(), nNewScale, nNewPages );
	}
}

sal_Bool __EXPORT ScUndoPrintZoom::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return 0 != dynamic_cast< ScTabViewTarget* >(&rTarget);
}


// -----------------------------------------------------------------------
//
//		Thesaurus
//

ScUndoThesaurus::ScUndoThesaurus( ScDocShell* pNewDocShell,
								  SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
								  const String& rNewUndoStr, const EditTextObject* pUndoTObj,
								  const String& rNewRedoStr, const EditTextObject* pRedoTObj) :
	ScSimpleUndo( pNewDocShell ),
	nCol( nNewCol ),
	nRow( nNewRow ),
	nTab( nNewTab ),
	aUndoStr( rNewUndoStr ),
	aRedoStr( rNewRedoStr )
{
	pUndoTObject = (pUndoTObj) ? pUndoTObj->Clone() : NULL;
	pRedoTObject = (pRedoTObj) ? pRedoTObj->Clone() : NULL;

	ScBaseCell* pOldCell;
	if ( pUndoTObject )
		pOldCell = new ScEditCell( pUndoTObject, pDocShell->GetDocument(), NULL );
	else
		pOldCell = new ScStringCell( aUndoStr );
	SetChangeTrack( pOldCell );
	pOldCell->Delete();
}

__EXPORT ScUndoThesaurus::~ScUndoThesaurus()
{
	delete pUndoTObject;
	delete pRedoTObject;
}

String __EXPORT ScUndoThesaurus::GetComment() const
{
	return ScGlobal::GetRscString( STR_UNDO_THESAURUS );	// "Thesaurus"
}

void ScUndoThesaurus::SetChangeTrack( ScBaseCell* pOldCell )
{
	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
	if ( pChangeTrack )
	{
		nEndChangeAction = pChangeTrack->GetActionMax() + 1;
		pChangeTrack->AppendContent( ScAddress( nCol, nRow, nTab ), pOldCell );
		if ( nEndChangeAction > pChangeTrack->GetActionMax() )
			nEndChangeAction = 0;		// nichts appended
	}
	else
		nEndChangeAction = 0;
}

void __EXPORT ScUndoThesaurus::DoChange( sal_Bool bUndo, const String& rStr,
			const EditTextObject* pTObj )
{
	ScDocument* pDoc = pDocShell->GetDocument();

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	if (pViewShell)
	{
		pViewShell->SetTabNo( nTab );
		pViewShell->MoveCursorAbs( nCol, nRow, SC_FOLLOW_JUMP, sal_False, sal_False );
	}

	if (pTObj)
	{
		ScBaseCell* pCell;
		pDoc->GetCell( nCol, nRow, nTab, pCell );
		if (pCell)
		{
			if (pCell->GetCellType() == CELLTYPE_EDIT )
			{
				ScEditCell* pNewCell = new ScEditCell( pTObj, pDoc, NULL );
				pDoc->PutCell( nCol, nRow, nTab, pNewCell );
				if ( !bUndo )
					SetChangeTrack( pCell );
			}
			else
			{
				DBG_ERROR("Nicht CELLTYPE_EDIT bei Un/RedoThesaurus");
			}
		}
	}
	else
	{
        ScBaseCell* pCell = NULL;
		if ( !bUndo )
			pDoc->GetCell( nCol, nRow, nTab, pCell );
		pDoc->SetString( nCol, nRow, nTab, rStr );
		if ( !bUndo )
			SetChangeTrack( pCell );
	}

	pDocShell->PostPaintCell( nCol, nRow, nTab );
}

void __EXPORT ScUndoThesaurus::Undo()
{
	BeginUndo();
	DoChange( sal_True, aUndoStr, pUndoTObject );
	ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
	if ( pChangeTrack )
		pChangeTrack->Undo( nEndChangeAction, nEndChangeAction );
	EndUndo();
}

void __EXPORT ScUndoThesaurus::Redo()
{
	BeginRedo();
	DoChange( sal_False, aRedoStr, pRedoTObject );
	EndRedo();
}

void __EXPORT ScUndoThesaurus::Repeat(SfxRepeatTarget& rTarget)
{
	ScTabViewTarget* pScTabViewTarget = dynamic_cast< ScTabViewTarget* >(&rTarget);

	if (pScTabViewTarget)
	{
		pScTabViewTarget->GetViewShell()->DoThesaurus( sal_True );
	}
}

sal_Bool __EXPORT ScUndoThesaurus::CanRepeat(SfxRepeatTarget& rTarget) const
{
	return 0 != dynamic_cast< ScTabViewTarget* >(&rTarget);
}


// ============================================================================

ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
        const ScNoteData& rNoteData, bool bInsert, SdrUndoAction* pDrawUndo ) :
    ScSimpleUndo( &rDocShell ),
    maPos( rPos ),
    mpDrawUndo( pDrawUndo )
{
    DBG_ASSERT( rNoteData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note caption" );
    (bInsert ? maNewData : maOldData) = rNoteData;
}

ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos,
        const ScNoteData& rOldData, const ScNoteData& rNewData, SdrUndoAction* pDrawUndo ) :
    ScSimpleUndo( &rDocShell ),
    maPos( rPos ),
    maOldData( rOldData ),
    maNewData( rNewData ),
    mpDrawUndo( pDrawUndo )
{
    DBG_ASSERT( maOldData.mpCaption || maNewData.mpCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note captions" );
    DBG_ASSERT( !maOldData.mxInitData.get() && !maNewData.mxInitData.get(), "ScUndoReplaceNote::ScUndoReplaceNote - unexpected unitialized note" );
}

ScUndoReplaceNote::~ScUndoReplaceNote()
{
    DeleteSdrUndoAction( mpDrawUndo );
}

void ScUndoReplaceNote::Undo()
{
	BeginUndo();
    DoSdrUndoAction( mpDrawUndo, pDocShell->GetDocument() );
    /*  Undo insert -> remove new note.
        Undo remove -> insert old note.
        Undo replace -> remove new note, insert old note. */
    DoRemoveNote( maNewData );
    DoInsertNote( maOldData );
    pDocShell->PostPaintCell( maPos );
	EndUndo();
}

void ScUndoReplaceNote::Redo()
{
	BeginRedo();
    RedoSdrUndoAction( mpDrawUndo );
    /*  Redo insert -> insert new note.
        Redo remove -> remove old note.
        Redo replace -> remove old note, insert new note. */
    DoRemoveNote( maOldData );
    DoInsertNote( maNewData );
    pDocShell->PostPaintCell( maPos );
	EndRedo();
}

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

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

String ScUndoReplaceNote::GetComment() const
{
    return ScGlobal::GetRscString( maNewData.mpCaption ?
        (maOldData.mpCaption ? STR_UNDO_EDITNOTE : STR_UNDO_INSERTNOTE) : STR_UNDO_DELETENOTE );
}

void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData )
{
    if( rNoteData.mpCaption )
    {
        ScDocument& rDoc = *pDocShell->GetDocument();
        DBG_ASSERT( !rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" );
        ScPostIt* pNote = new ScPostIt( rDoc, maPos, rNoteData, false );
        rDoc.TakeNote( maPos, pNote );
    }
}

void ScUndoReplaceNote::DoRemoveNote( const ScNoteData& rNoteData )
{
    if( rNoteData.mpCaption )
    {
        ScDocument& rDoc = *pDocShell->GetDocument();
        DBG_ASSERT( rDoc.GetNote( maPos ), "ScUndoReplaceNote::DoRemoveNote - missing cell note" );
        if( ScPostIt* pNote = rDoc.ReleaseNote( maPos ) )
        {
            /*  Forget pointer to caption object to suppress removing the
                caption object from the drawing layer while deleting pNote
                (removing the caption is done by a drawing undo action). */
            pNote->ForgetCaption();
            delete pNote;
        }
    }
}

// ============================================================================

ScUndoShowHideNote::ScUndoShowHideNote( ScDocShell& rDocShell, const ScAddress& rPos, bool bShow ) :
	ScSimpleUndo( &rDocShell ),
	maPos( rPos ),
	mbShown( bShow )
{
}

ScUndoShowHideNote::~ScUndoShowHideNote()
{
}

void ScUndoShowHideNote::Undo()
{
	BeginUndo();
	if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
        pNote->ShowCaption( maPos, !mbShown );
	EndUndo();
}

void ScUndoShowHideNote::Redo()
{
	BeginRedo();
	if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( maPos ) )
        pNote->ShowCaption( maPos, mbShown );
	EndRedo();
}

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

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

String ScUndoShowHideNote::GetComment() const
{
    return ScGlobal::GetRscString( mbShown ? STR_UNDO_SHOWNOTE : STR_UNDO_HIDENOTE );
}

// ============================================================================

// -----------------------------------------------------------------------
//
//		Detektiv
//

ScUndoDetective::ScUndoDetective( ScDocShell* pNewDocShell,
									SdrUndoAction* pDraw, const ScDetOpData* pOperation,
									ScDetOpList* pUndoList ) :
	ScSimpleUndo( pNewDocShell ),
	pOldList	( pUndoList ),
	nAction		( 0 ),
	pDrawUndo	( pDraw )
{
	bIsDelete = ( pOperation == NULL );
	if (!bIsDelete)
	{
		nAction = (sal_uInt16) pOperation->GetOperation();
		aPos = pOperation->GetPos();
	}
}

__EXPORT ScUndoDetective::~ScUndoDetective()
{
	DeleteSdrUndoAction( pDrawUndo );
	delete pOldList;
}

String __EXPORT ScUndoDetective::GetComment() const
{
	sal_uInt16 nId = STR_UNDO_DETDELALL;
	if ( !bIsDelete )
		switch ( (ScDetOpType) nAction )
		{
			case SCDETOP_ADDSUCC:	nId = STR_UNDO_DETADDSUCC;	break;
			case SCDETOP_DELSUCC:	nId = STR_UNDO_DETDELSUCC;	break;
			case SCDETOP_ADDPRED:	nId = STR_UNDO_DETADDPRED;	break;
			case SCDETOP_DELPRED:	nId = STR_UNDO_DETDELPRED;	break;
			case SCDETOP_ADDERROR:	nId = STR_UNDO_DETADDERROR;	break;
		}

	return ScGlobal::GetRscString( nId );
}


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

	ScDocument* pDoc = pDocShell->GetDocument();
    DoSdrUndoAction(pDrawUndo, pDoc);

	if (bIsDelete)
	{
		if ( pOldList )
			pDoc->SetDetOpList( new ScDetOpList(*pOldList) );
	}
	else
	{
		//	Eintrag aus der Liste loeschen

		ScDetOpList* pList = pDoc->GetDetOpList();
		if (pList && pList->Count())
		{
			sal_uInt16 nPos = pList->Count() - 1;
			ScDetOpData* pData = (*pList)[nPos];
			if ( pData->GetOperation() == (ScDetOpType) nAction && pData->GetPos() == aPos )
				pList->DeleteAndDestroy( nPos, 1 );
			else
			{
				DBG_ERROR("Detektiv-Eintrag in der Liste nicht gefunden");
			}
		}
	}

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	if (pViewShell)
		pViewShell->RecalcPPT();	//! use broadcast instead?

	EndUndo();
}

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

    RedoSdrUndoAction(pDrawUndo);

	ScDocument* pDoc = pDocShell->GetDocument();

	if (bIsDelete)
		pDoc->ClearDetectiveOperations();
	else
		pDoc->AddDetectiveOperation( ScDetOpData( aPos, (ScDetOpType) nAction ) );

	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
	if (pViewShell)
		pViewShell->RecalcPPT();	//! use broadcast instead?

	EndRedo();
}

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

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

// -----------------------------------------------------------------------
//
//		Benannte Bereiche
//

ScUndoRangeNames::ScUndoRangeNames( ScDocShell* pNewDocShell,
									ScRangeName* pOld, ScRangeName* pNew ) :
	ScSimpleUndo( pNewDocShell ),
	pOldRanges	( pOld ),
	pNewRanges	( pNew )
{
}

__EXPORT ScUndoRangeNames::~ScUndoRangeNames()
{
	delete pOldRanges;
	delete pNewRanges;
}

String __EXPORT ScUndoRangeNames::GetComment() const
{
	return ScGlobal::GetRscString( STR_UNDO_RANGENAMES );
}

void ScUndoRangeNames::DoChange( sal_Bool bUndo )
{
	ScDocument* pDoc = pDocShell->GetDocument();
	pDoc->CompileNameFormula( sal_True );	// CreateFormulaString

	if ( bUndo )
		pDoc->SetRangeName( new ScRangeName( *pOldRanges ) );
	else
		pDoc->SetRangeName( new ScRangeName( *pNewRanges ) );

	pDoc->CompileNameFormula( sal_False );	// CompileFormulaString

	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
}

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

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

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

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




