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

#include <sfx2/app.hxx>
#include <editeng/editobj.hxx>
#include <sfx2/linkmgr.hxx>
#include <svx/svdundo.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/printer.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/sound.hxx>
#include <vcl/virdev.hxx>
#include <vcl/waitobj.hxx>
#include <svl/zforlist.hxx>
#include <svl/PasswordHelper.hxx>

#include <basic/sbstar.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/script/ModuleType.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>

#include <list>

#include "docfunc.hxx"

#include "sc.hrc"

#include "arealink.hxx"
#include "attrib.hxx"
#include "dociter.hxx"
#include "autoform.hxx"
#include "cell.hxx"
#include "detdata.hxx"
#include "detfunc.hxx"
#include "docpool.hxx"
#include "docsh.hxx"
#include "drwlayer.hxx"
#include "editutil.hxx"
#include "globstr.hrc"
//CHINA001 #include "namecrea.hxx"		// NAME_TOP etc.
#include "olinetab.hxx"
#include "patattr.hxx"
#include "rangenam.hxx"
#include "rangeutl.hxx"
#include "refundo.hxx"
#include "scresid.hxx"
#include "stlpool.hxx"
#include "stlsheet.hxx"
#include "tablink.hxx"
#include "tabvwsh.hxx"
#include "uiitems.hxx"
#include "undoblk.hxx"
#include "undocell.hxx"
#include "undodraw.hxx"
#include "undotab.hxx"
#include "waitoff.hxx"
#include "sizedev.hxx"
#include "scmod.hxx"
#include "inputhdl.hxx"
#include "inputwin.hxx"
#include "editable.hxx"
#include "compiler.hxx"
#include "scui_def.hxx" //CHINA001
#include "tabprotection.hxx"
#include "clipparam.hxx"
#include "externalrefmgr.hxx"

#include <memory>
#include <basic/basmgr.hxx>
#include <boost/scoped_ptr.hpp>

using namespace com::sun::star;
using ::com::sun::star::uno::Sequence;

// STATIC DATA -----------------------------------------------------------

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

IMPL_LINK( ScDocFunc, NotifyDrawUndo, SdrUndoAction*, pUndoAction )
{
    // #i101118# if drawing layer collects the undo actions, add it there
    ScDrawLayer* pDrawLayer = rDocShell.GetDocument()->GetDrawLayer();
    if( pDrawLayer && pDrawLayer->IsUndoAllowed() && pDrawLayer->IsRecording() )
        pDrawLayer->AddCalcUndo( pUndoAction );
    else
        rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDraw( pUndoAction, &rDocShell ) );
	rDocShell.SetDrawModified();

    // the affected sheet isn't known, so all stream positions are invalidated
    ScDocument* pDoc = rDocShell.GetDocument();
    SCTAB nTabCount = pDoc->GetTableCount();
    for (SCTAB nTab=0; nTab<nTabCount; nTab++)
        if (pDoc->IsStreamValid(nTab))
            pDoc->SetStreamValid(nTab, sal_False);

	return 0;
}

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

//	Zeile ueber dem Range painten (fuer Linien nach AdjustRowHeight)

void lcl_PaintAbove( ScDocShell& rDocShell, const ScRange& rRange )
{
	SCROW nRow = rRange.aStart.Row();
	if ( nRow > 0 )
	{
		SCTAB nTab = rRange.aStart.Tab();	//! alle?
		--nRow;
		rDocShell.PostPaint( ScRange(0,nRow,nTab, MAXCOL,nRow,nTab), PAINT_GRID );
	}
}

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

sal_Bool ScDocFunc::AdjustRowHeight( const ScRange& rRange, sal_Bool bPaint )
{
	ScDocument* pDoc = rDocShell.GetDocument();
	if ( pDoc->IsImportingXML() )
	{
		//	for XML import, all row heights are updated together after importing
		return sal_False;
	}
    if ( !pDoc->IsAdjustHeightEnabled() )
    {
        return sal_False;
    }

	SCTAB nTab      = rRange.aStart.Tab();
	SCROW nStartRow = rRange.aStart.Row();
	SCROW nEndRow   = rRange.aEnd.Row();

	ScSizeDeviceProvider aProv( &rDocShell );
	Fraction aOne(1,1);

	sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
											aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, sal_False );

	if ( bPaint && bChanged )
		rDocShell.PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
											PAINT_GRID | PAINT_LEFT );

	return bChanged;
}


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

sal_Bool ScDocFunc::DetectiveAddPred(const ScAddress& rPos)
{
	ScDocShellModificator aModificator( rDocShell );

	rDocShell.MakeDrawLayer();
	ScDocument* pDoc = rDocShell.GetDocument();
	sal_Bool bUndo (pDoc->IsUndoEnabled());
	ScDrawLayer* pModel = pDoc->GetDrawLayer();
	SCCOL nCol = rPos.Col();
	SCROW nRow = rPos.Row();
	SCTAB nTab = rPos.Tab();

	if (bUndo)
		pModel->BeginCalcUndo(false);
	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).ShowPred( nCol, nRow );
	SdrUndoGroup* pUndo = NULL;
	if (bUndo)
		pUndo = pModel->GetCalcUndo();
	if (bDone)
	{
		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDPRED );
		pDoc->AddDetectiveOperation( aOperation );
		if (bUndo)
		{
			rDocShell.GetUndoManager()->AddUndoAction(
						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
		}
		aModificator.SetDocumentModified();
		SfxBindings* pBindings = rDocShell.GetViewBindings();
		if (pBindings)
			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
	}
	else
		delete pUndo;

	return bDone;
}

sal_Bool ScDocFunc::DetectiveDelPred(const ScAddress& rPos)
{
	ScDocument* pDoc = rDocShell.GetDocument();

	sal_Bool bUndo(pDoc->IsUndoEnabled());
	ScDrawLayer* pModel = pDoc->GetDrawLayer();
	if (!pModel)
		return sal_False;

	ScDocShellModificator aModificator( rDocShell );

	SCCOL nCol = rPos.Col();
	SCROW nRow = rPos.Row();
	SCTAB nTab = rPos.Tab();

	if (bUndo)
		pModel->BeginCalcUndo(false);
	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).DeletePred( nCol, nRow );
	SdrUndoGroup* pUndo = NULL;
	if (bUndo)
		pUndo = pModel->GetCalcUndo();
	if (bDone)
	{
		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELPRED );
		pDoc->AddDetectiveOperation( aOperation );
		if (bUndo)
		{
			rDocShell.GetUndoManager()->AddUndoAction(
						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
		}
		aModificator.SetDocumentModified();
		SfxBindings* pBindings = rDocShell.GetViewBindings();
		if (pBindings)
			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
	}
	else
		delete pUndo;

	return bDone;
}

sal_Bool ScDocFunc::DetectiveAddSucc(const ScAddress& rPos)
{
	ScDocShellModificator aModificator( rDocShell );

	rDocShell.MakeDrawLayer();
	ScDocument* pDoc = rDocShell.GetDocument();

	sal_Bool bUndo(pDoc->IsUndoEnabled());
	ScDrawLayer* pModel = pDoc->GetDrawLayer();
	SCCOL nCol = rPos.Col();
	SCROW nRow = rPos.Row();
	SCTAB nTab = rPos.Tab();

	if (bUndo)
		pModel->BeginCalcUndo(false);
	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).ShowSucc( nCol, nRow );
	SdrUndoGroup* pUndo = NULL;
	if (bUndo)
		pUndo = pModel->GetCalcUndo();
	if (bDone)
	{
		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDSUCC );
		pDoc->AddDetectiveOperation( aOperation );
		if (bUndo)
		{
			rDocShell.GetUndoManager()->AddUndoAction(
						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
		}
		aModificator.SetDocumentModified();
		SfxBindings* pBindings = rDocShell.GetViewBindings();
		if (pBindings)
			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
	}
	else
		delete pUndo;

	return bDone;
}

sal_Bool ScDocFunc::DetectiveDelSucc(const ScAddress& rPos)
{
	ScDocument* pDoc = rDocShell.GetDocument();

	sal_Bool bUndo (pDoc->IsUndoEnabled());
	ScDrawLayer* pModel = pDoc->GetDrawLayer();
	if (!pModel)
		return sal_False;

	ScDocShellModificator aModificator( rDocShell );

	SCCOL nCol = rPos.Col();
	SCROW nRow = rPos.Row();
	SCTAB nTab = rPos.Tab();

	if (bUndo)
		pModel->BeginCalcUndo(false);
	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).DeleteSucc( nCol, nRow );
	SdrUndoGroup* pUndo = NULL;
	if (bUndo)
		pUndo = pModel->GetCalcUndo();
	if (bDone)
	{
		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELSUCC );
		pDoc->AddDetectiveOperation( aOperation );
		if (bUndo)
		{
			rDocShell.GetUndoManager()->AddUndoAction(
						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
		}
		aModificator.SetDocumentModified();
		SfxBindings* pBindings = rDocShell.GetViewBindings();
		if (pBindings)
			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
	}
	else
		delete pUndo;

	return bDone;
}

sal_Bool ScDocFunc::DetectiveAddError(const ScAddress& rPos)
{
	ScDocShellModificator aModificator( rDocShell );

	rDocShell.MakeDrawLayer();
	ScDocument* pDoc = rDocShell.GetDocument();

	sal_Bool bUndo (pDoc->IsUndoEnabled());
	ScDrawLayer* pModel = pDoc->GetDrawLayer();
	SCCOL nCol = rPos.Col();
	SCROW nRow = rPos.Row();
	SCTAB nTab = rPos.Tab();

	if (bUndo)
		pModel->BeginCalcUndo(false);
	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).ShowError( nCol, nRow );
	SdrUndoGroup* pUndo = NULL;
	if (bUndo)
		pUndo = pModel->GetCalcUndo();
	if (bDone)
	{
		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDERROR );
		pDoc->AddDetectiveOperation( aOperation );
		if (bUndo)
		{
			rDocShell.GetUndoManager()->AddUndoAction(
						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
		}
		aModificator.SetDocumentModified();
		SfxBindings* pBindings = rDocShell.GetViewBindings();
		if (pBindings)
			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
	}
	else
		delete pUndo;

	return bDone;
}

sal_Bool ScDocFunc::DetectiveMarkInvalid(SCTAB nTab)
{
	ScDocShellModificator aModificator( rDocShell );

	rDocShell.MakeDrawLayer();
	ScDocument* pDoc = rDocShell.GetDocument();

	sal_Bool bUndo (pDoc->IsUndoEnabled());
	ScDrawLayer* pModel = pDoc->GetDrawLayer();

	Window* pWaitWin = rDocShell.GetActiveDialogParent();
	if (pWaitWin)
		pWaitWin->EnterWait();
	if (bUndo)
		pModel->BeginCalcUndo(false);
	sal_Bool bOverflow;
	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).MarkInvalid( bOverflow );
	SdrUndoGroup* pUndo = NULL;
	if (bUndo)
		pUndo = pModel->GetCalcUndo();
	if (pWaitWin)
		pWaitWin->LeaveWait();
	if (bDone)
	{
		if (pUndo && bUndo)
		{
			pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETINVALID ) );
			rDocShell.GetUndoManager()->AddUndoAction( pUndo );
		}
		aModificator.SetDocumentModified();
		if ( bOverflow )
		{
			InfoBox( NULL,
					ScGlobal::GetRscString( STR_DETINVALID_OVERFLOW ) ).Execute();
		}
	}
	else
		delete pUndo;

	return bDone;
}

sal_Bool ScDocFunc::DetectiveDelAll(SCTAB nTab)
{
	ScDocument* pDoc = rDocShell.GetDocument();

	sal_Bool bUndo (pDoc->IsUndoEnabled());
	ScDrawLayer* pModel = pDoc->GetDrawLayer();
	if (!pModel)
		return sal_False;

	ScDocShellModificator aModificator( rDocShell );

	if (bUndo)
		pModel->BeginCalcUndo(false);
	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_DETECTIVE );
	SdrUndoGroup* pUndo = NULL;
	if (bUndo)
		pUndo = pModel->GetCalcUndo();
	if (bDone)
	{
		ScDetOpList* pOldList = pDoc->GetDetOpList();
		ScDetOpList* pUndoList = NULL;
		if (bUndo)
			pUndoList = pOldList ? new ScDetOpList(*pOldList) : NULL;

		pDoc->ClearDetectiveOperations();

		if (bUndo)
		{
			rDocShell.GetUndoManager()->AddUndoAction(
						new ScUndoDetective( &rDocShell, pUndo, NULL, pUndoList ) );
		}
		aModificator.SetDocumentModified();
		SfxBindings* pBindings = rDocShell.GetViewBindings();
		if (pBindings)
			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
	}
	else
		delete pUndo;

	return bDone;
}

sal_Bool ScDocFunc::DetectiveRefresh( sal_Bool bAutomatic )
{
	sal_Bool bDone = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();

	sal_Bool bUndo (pDoc->IsUndoEnabled());
	ScDetOpList* pList = pDoc->GetDetOpList();
	if ( pList && pList->Count() )
	{
		rDocShell.MakeDrawLayer();
		ScDrawLayer* pModel = pDoc->GetDrawLayer();
		if (bUndo)
			pModel->BeginCalcUndo(false);

		//	Loeschen auf allen Tabellen

		SCTAB nTabCount = pDoc->GetTableCount();
		for (SCTAB nTab=0; nTab<nTabCount; nTab++)
			ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_ARROWS );	// don't remove circles

		//	Wiederholen

		sal_uInt16 nCount = pList->Count();
		for (sal_uInt16 i=0; i<nCount; i++)
		{
			ScDetOpData* pData = (*pList)[i];
			if (pData)
			{
				ScAddress aPos = pData->GetPos();
				ScDetectiveFunc aFunc( pDoc, aPos.Tab() );
				SCCOL nCol = aPos.Col();
				SCROW nRow = aPos.Row();
				switch (pData->GetOperation())
				{
					case SCDETOP_ADDSUCC:
						aFunc.ShowSucc( nCol, nRow );
						break;
					case SCDETOP_DELSUCC:
						aFunc.DeleteSucc( nCol, nRow );
						break;
					case SCDETOP_ADDPRED:
						aFunc.ShowPred( nCol, nRow );
						break;
					case SCDETOP_DELPRED:
						aFunc.DeletePred( nCol, nRow );
						break;
					case SCDETOP_ADDERROR:
						aFunc.ShowError( nCol, nRow );
						break;
					default:
						DBG_ERROR("falsche Op bei DetectiveRefresh");
				}
			}
		}

		if (bUndo)
		{
			SdrUndoGroup* pUndo = pModel->GetCalcUndo();
			if (pUndo)
			{
				pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETREFRESH ) );
				//	wenn automatisch, an letzte Aktion anhaengen
				rDocShell.GetUndoManager()->AddUndoAction(
												new ScUndoDraw( pUndo, &rDocShell ),
												bAutomatic );
			}
		}
		rDocShell.SetDrawModified();
		bDone = sal_True;
	}
	return bDone;
}

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

sal_Bool ScDocFunc::DeleteContents( const ScMarkData& rMark, sal_uInt16 nFlags,
									sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
	{
		DBG_ERROR("ScDocFunc::DeleteContents ohne Markierung");
		return sal_False;
	}

	ScDocument* pDoc = rDocShell.GetDocument();

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScEditableTester aTester( pDoc, rMark );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	ScRange aMarkRange;
	sal_Bool bSimple = sal_False;

	ScMarkData aMultiMark = rMark;
	aMultiMark.SetMarking(sal_False);		// fuer MarkToMulti

	ScDocument* pUndoDoc = NULL;
	sal_Bool bMulti = !bSimple && aMultiMark.IsMultiMarked();
	if (!bSimple)
	{
		aMultiMark.MarkToMulti();
		aMultiMark.GetMultiMarkArea( aMarkRange );
	}
	ScRange aExtendedRange(aMarkRange);
	if (!bSimple)
	{
		if ( pDoc->ExtendMerge( aExtendedRange, sal_True ) )
			bMulti = sal_False;
	}

	// keine Objekte auf geschuetzten Tabellen
	sal_Bool bObjects = sal_False;
	if ( nFlags & IDF_OBJECTS )
	{
		bObjects = sal_True;
		SCTAB nTabCount = pDoc->GetTableCount();
		for (SCTAB nTab=0; nTab<nTabCount; nTab++)
			if (aMultiMark.GetTableSelect(nTab) && pDoc->IsTabProtected(nTab))
				bObjects = sal_False;
	}

	sal_uInt16 nExtFlags = 0;		// extra flags are needed only if attributes are deleted
	if ( nFlags & IDF_ATTRIB )
		rDocShell.UpdatePaintExt( nExtFlags, aMarkRange );

	//	Reihenfolge:
	//	1) BeginDrawUndo
	//	2) Objekte loeschen (DrawUndo wird gefuellt)
	//	3) Inhalte fuer Undo kopieren und Undo-Aktion anlegen
	//	4) Inhalte loeschen

    bool bDrawUndo = bObjects || (nFlags & IDF_NOTE);
    if (bRecord && bDrawUndo)
        pDoc->BeginDrawUndo();

	if (bObjects)
	{
		if (bMulti)
			pDoc->DeleteObjectsInSelection( aMultiMark );
		else
			pDoc->DeleteObjectsInArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
									   aMarkRange.aEnd.Col(),   aMarkRange.aEnd.Row(),
									   aMultiMark );
	}

	if ( bRecord )
	{
		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, aMarkRange.aStart.Tab(), aMarkRange.aEnd.Tab() );

		//	bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
		//	nur mit IDF_HARDATTR zu langsam ist:
		sal_uInt16 nUndoDocFlags = nFlags;
		if (nFlags & IDF_ATTRIB)
			nUndoDocFlags |= IDF_ATTRIB;
		if (nFlags & IDF_EDITATTR)			// Edit-Engine-Attribute
			nUndoDocFlags |= IDF_STRING;	// -> Zellen werden geaendert
		if (nFlags & IDF_NOTE)
			nUndoDocFlags |= IDF_CONTENTS;	// #68795# copy all cells with their notes
        // note captions are handled in drawing undo
        nUndoDocFlags |= IDF_NOCAPTIONS;
		pDoc->CopyToDocument( aExtendedRange, nUndoDocFlags, bMulti, pUndoDoc, &aMultiMark );
	}

//!	HideAllCursors();	// falls Zusammenfassung aufgehoben wird
	if (bSimple)
		pDoc->DeleteArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
						  aMarkRange.aEnd.Col(),   aMarkRange.aEnd.Row(),
						  aMultiMark, nFlags );
	else
	{
		pDoc->DeleteSelection( nFlags, aMultiMark );
//       aMultiMark.MarkToSimple();
	}

    // add undo action after drawing undo is complete (objects and note captions)
    if( bRecord )
        rDocShell.GetUndoManager()->AddUndoAction(
            new ScUndoDeleteContents( &rDocShell, aMultiMark, aExtendedRange,
                                      pUndoDoc, bMulti, nFlags, bDrawUndo ) );

	if (!AdjustRowHeight( aExtendedRange ))
		rDocShell.PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
	else if (nExtFlags & SC_PF_LINES)
		lcl_PaintAbove( rDocShell, aExtendedRange );	// fuer Linien ueber dem Bereich

//	rDocShell.UpdateOle(GetViewData());		//! an der View?
	aModificator.SetDocumentModified();
//!	CellContentChanged();
//!	ShowAllCursors();

#if 0
	//!	muss an der View bleiben !!!!
	if ( nFlags & IDF_ATTRIB )
	{
		if ( nFlags & IDF_CONTENTS )
			ForgetFormatArea();
		else
			StartFormatArea();				// Attribute loeschen ist auch Attributierung
	}
#endif

	return sal_True;
}

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

sal_Bool ScDocFunc::TransliterateText( const ScMarkData& rMark, sal_Int32 nType,
									sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScEditableTester aTester( pDoc, rMark );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	ScRange aMarkRange;
	ScMarkData aMultiMark = rMark;
	aMultiMark.SetMarking(sal_False);		// for MarkToMulti
	aMultiMark.MarkToMulti();
	aMultiMark.GetMultiMarkArea( aMarkRange );

	if (bRecord)
	{
		SCTAB nStartTab = aMarkRange.aStart.Tab();
		SCTAB nTabCount = pDoc->GetTableCount();

		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
		for (SCTAB i=0; i<nTabCount; i++)
			if (i != nStartTab && rMark.GetTableSelect(i))
				pUndoDoc->AddUndoTab( i, i );

		ScRange aCopyRange = aMarkRange;
		aCopyRange.aStart.SetTab(0);
		aCopyRange.aEnd.SetTab(nTabCount-1);
		pDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, sal_True, pUndoDoc, &aMultiMark );

		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoTransliterate( &rDocShell, aMultiMark, pUndoDoc, nType ) );
	}

	pDoc->TransliterateText( aMultiMark, nType );

	if (!AdjustRowHeight( aMarkRange ))
		rDocShell.PostPaint( aMarkRange, PAINT_GRID );

	aModificator.SetDocumentModified();

	return sal_True;
}

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

sal_Bool ScDocFunc::SetNormalString( const ScAddress& rPos, const String& rText, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );
	ScDocument* pDoc = rDocShell.GetDocument();

	sal_Bool bUndo(pDoc->IsUndoEnabled());
	ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	SCTAB* pTabs = NULL;
	ScBaseCell** ppOldCells = NULL;
	sal_Bool* pHasFormat = NULL;
	sal_uLong* pOldFormats = NULL;
	ScBaseCell* pDocCell = pDoc->GetCell( rPos );
	sal_Bool bEditDeleted = (pDocCell && pDocCell->GetCellType() == CELLTYPE_EDIT);
	if (bUndo)
	{
		pTabs = new SCTAB[1];
		pTabs[0] = rPos.Tab();
		ppOldCells	= new ScBaseCell*[1];
        ppOldCells[0] = pDocCell ? pDocCell->CloneWithoutNote( *pDoc ) : 0;

		pHasFormat = new sal_Bool[1];
		pOldFormats = new sal_uLong[1];
		const SfxPoolItem* pItem;
		const ScPatternAttr* pPattern = pDoc->GetPattern( rPos.Col(),rPos.Row(),rPos.Tab() );
		if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState(
								ATTR_VALUE_FORMAT,sal_False,&pItem) )
		{
			pHasFormat[0] = sal_True;
			pOldFormats[0] = ((const SfxUInt32Item*)pItem)->GetValue();
		}
		else
			pHasFormat[0] = sal_False;
	}

	pDoc->SetString( rPos.Col(), rPos.Row(), rPos.Tab(), rText );

	if (bUndo)
	{
		//	wegen ChangeTracking darf UndoAction erst nach SetString angelegt werden
		rDocShell.GetUndoManager()->AddUndoAction(new ScUndoEnterData( &rDocShell, rPos.Col(),rPos.Row(),rPos.Tab(), 1,pTabs,
									 ppOldCells, pHasFormat, pOldFormats, rText, NULL ) );
	}

	if ( bEditDeleted || pDoc->HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) )
		AdjustRowHeight( ScRange(rPos) );

	rDocShell.PostPaintCell( rPos );
	aModificator.SetDocumentModified();

    // #107160# notify input handler here the same way as in PutCell
    if (bApi)
        NotifyInputHandler( rPos );

	return sal_True;
}

sal_Bool ScDocFunc::PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, sal_Bool bApi )
{
    ScDocShellModificator aModificator( rDocShell );
	ScDocument* pDoc = rDocShell.GetDocument();
	sal_Bool bUndo (pDoc->IsUndoEnabled());
    sal_Bool bXMLLoading(pDoc->IsImportingXML());

    // #i925#; it is not necessary to test whether the cell is editable on loading a XML document
    if (!bXMLLoading)
    {
	    ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
	    if (!aTester.IsEditable())
	    {
		    if (!bApi)
			    rDocShell.ErrorMessage(aTester.GetMessageId());
		    pNewCell->Delete();
		    return sal_False;
	    }
    }

    sal_Bool bEditCell = ( pNewCell->GetCellType() == CELLTYPE_EDIT );
	ScBaseCell* pDocCell = pDoc->GetCell( rPos );
	sal_Bool bEditDeleted = (pDocCell && pDocCell->GetCellType() == CELLTYPE_EDIT);
	sal_Bool bHeight = ( bEditDeleted || bEditCell ||
					pDoc->HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) );

    ScBaseCell* pUndoCell = (bUndo && pDocCell) ? pDocCell->CloneWithoutNote( *pDoc, rPos ) : 0;
    ScBaseCell* pRedoCell = (bUndo && pNewCell) ? pNewCell->CloneWithoutNote( *pDoc, rPos ) : 0;

	pDoc->PutCell( rPos, pNewCell );

	//	wegen ChangeTracking darf UndoAction erst nach PutCell angelegt werden
	if (bUndo)
	{
		rDocShell.GetUndoManager()->AddUndoAction(
				new ScUndoPutCell( &rDocShell, rPos, pUndoCell, pRedoCell, bHeight ) );
	}

	if (bHeight)
		AdjustRowHeight( ScRange(rPos) );

    if (!bXMLLoading)
    	rDocShell.PostPaintCell( rPos );

    aModificator.SetDocumentModified();

    // #i925#; it is not necessary to notify on loading a XML document
    // #103934#; notify editline and cell in edit mode
    if (bApi && !bXMLLoading)
        NotifyInputHandler( rPos );

	return sal_True;
}

void ScDocFunc::NotifyInputHandler( const ScAddress& rPos )
{
    ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
    if ( pViewSh && pViewSh->GetViewData()->GetDocShell() == &rDocShell )
    {
        ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
        if ( pInputHdl && pInputHdl->GetCursorPos() == rPos )
        {
            sal_Bool bIsEditMode(pInputHdl->IsEditMode());

            // set modified if in editmode, because so the string is not set in the InputWindow like in the cell
            // (the cell shows the same like the InputWindow)
            if (bIsEditMode)
                pInputHdl->SetModified();
            pViewSh->UpdateInputHandler(sal_False, !bIsEditMode);
        }
    }
}

		struct ScMyRememberItem
		{
			sal_uInt32		nIndex;
			SfxItemSet	aItemSet;

			ScMyRememberItem(const SfxItemSet& rItemSet, sal_uInt32 nTempIndex) :
                nIndex(nTempIndex), aItemSet(rItemSet) {}
		};

		typedef ::std::list<ScMyRememberItem*> ScMyRememberItemList;

sal_Bool ScDocFunc::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, sal_Bool bInterpret, sal_Bool bApi )
{
	//	PutData ruft PutCell oder SetNormalString

	sal_Bool bRet = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	ScEditAttrTester aTester( &rEngine );
	sal_Bool bEditCell = aTester.NeedsObject();
	if ( bEditCell )
	{
        // #i61702# With bLoseContent set, the content of rEngine isn't restored
        // (used in loading XML, where after the removeActionLock call the API object's
        // EditEngine isn't accessed again.
        sal_Bool bLoseContent = pDoc->IsImportingXML();

		sal_Bool bUpdateMode(rEngine.GetUpdateMode());
		if (bUpdateMode)
			rEngine.SetUpdateMode(sal_False);

		ScMyRememberItemList aRememberItems;
		ScMyRememberItem* pRememberItem = NULL;

		//	All paragraph attributes must be removed before calling CreateTextObject,
		//	not only alignment, so the object doesn't contain the cell attributes as
		//	paragraph attributes. Before remove the attributes store they in a list to
		//	set they back to the EditEngine.
		sal_uInt32 nCount = rEngine.GetParagraphCount();
		for (sal_uInt32 i=0; i<nCount; i++)
		{
			const SfxItemSet& rOld = rEngine.GetParaAttribs( i );
			if ( rOld.Count() )
			{
                if ( !bLoseContent )
                {
                    pRememberItem = new ScMyRememberItem(rEngine.GetParaAttribs(i), i);
                    aRememberItems.push_back(pRememberItem);
                }
				rEngine.SetParaAttribs( i, SfxItemSet( *rOld.GetPool(), rOld.GetRanges() ) );
			}
		}

		EditTextObject* pNewData = rEngine.CreateTextObject();
		bRet = PutCell( rPos,
						new ScEditCell( pNewData, pDoc, rEngine.GetEditTextObjectPool() ),
						bApi );
		delete pNewData;

		// Set the paragraph attributes back to the EditEngine.
		if (!aRememberItems.empty())
		{
//            ScMyRememberItem* pRememberItem = NULL;
			ScMyRememberItemList::iterator aItr = aRememberItems.begin();
			while (aItr != aRememberItems.end())
			{
				pRememberItem = *aItr;
				rEngine.SetParaAttribs(pRememberItem->nIndex, pRememberItem->aItemSet);
				delete pRememberItem;
				aItr = aRememberItems.erase(aItr);
			}
		}

        // #i61702# if the content isn't accessed, there's no need to set the UpdateMode again
        if ( bUpdateMode && !bLoseContent )
			rEngine.SetUpdateMode(sal_True);
	}
	else
	{
		String aText = rEngine.GetText();
		if ( bInterpret || !aText.Len() )
			bRet = SetNormalString( rPos, aText, bApi );
		else
			bRet = PutCell( rPos, new ScStringCell( aText ), bApi );
	}

	if ( bRet && aTester.NeedsCellAttr() )
	{
		const SfxItemSet& rEditAttr = aTester.GetAttribs();
		ScPatternAttr aPattern( pDoc->GetPool() );
		aPattern.GetFromEditItemSet( &rEditAttr );
		aPattern.DeleteUnchanged( pDoc->GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() ) );
		aPattern.GetItemSet().ClearItem( ATTR_HOR_JUSTIFY );	// wasn't removed above if no edit object
		if ( aPattern.GetItemSet().Count() > 0 )
		{
			ScMarkData aMark;
			aMark.SelectTable( rPos.Tab(), sal_True );
			aMark.SetMarkArea( ScRange( rPos ) );
			ApplyAttributes( aMark, aPattern, sal_True, bApi );
		}
	}

	return bRet;
}


ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
{
	ScTokenArray* pCode = new ScTokenArray;
    pCode->AddString( rText );
    if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && (rFormulaNmsp.Len() > 0) )
        pCode->AddString( rFormulaNmsp );
	return pCode;
}


ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos,
        const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar, short* pRetFormatType )
{
	ScDocument* pDoc = rDocShell.GetDocument();
	ScBaseCell* pNewCell = NULL;

	if ( rText.Len() > 1 && rText.GetChar(0) == '=' )
	{
		ScTokenArray* pCode;
		if ( pDoc->IsImportingXML() )
		{	// temporary formula string as string tokens
            pCode = lcl_ScDocFunc_CreateTokenArrayXML( rText, rFormulaNmsp, eGrammar );
            pDoc->IncXMLImportedFormulaCount( rText.Len() );
		}
		else
		{
			ScCompiler aComp( pDoc, rPos );
            aComp.SetGrammar(eGrammar);
			pCode = aComp.CompileString( rText );
		}
		pNewCell = new ScFormulaCell( pDoc, rPos, pCode, eGrammar, MM_NONE );
		delete pCode;	// Zell-ctor hat das TokenArray kopiert
	}
	else if ( rText.Len() > 1 && rText.GetChar(0) == '\'' )
	{
		//	for bEnglish, "'" at the beginning is always interpreted as text
		//	marker and stripped
		pNewCell = ScBaseCell::CreateTextCell( rText.Copy( 1 ), pDoc );
	}
	else		// (nur) auf englisches Zahlformat testen
	{
		SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
		sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
		double fVal;
		if ( pFormatter->IsNumberFormat( rText, nEnglish, fVal ) )
        {
			pNewCell = new ScValueCell( fVal );
            // return the format type from the English format, so a localized format can be created
            if ( pRetFormatType )
                *pRetFormatType = pFormatter->GetType( nEnglish );
        }
		else if ( rText.Len() )
			pNewCell = ScBaseCell::CreateTextCell( rText, pDoc );

		//	das (englische) Zahlformat wird nicht gesetzt
		//!	passendes lokales Format suchen und setzen???
	}

	return pNewCell;
}


sal_Bool ScDocFunc::SetCellText( const ScAddress& rPos, const String& rText,
        sal_Bool bInterpret, sal_Bool bEnglish, sal_Bool bApi,
        const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
{
	//	SetCellText ruft PutCell oder SetNormalString

	ScDocument* pDoc = rDocShell.GetDocument();
	ScBaseCell* pNewCell = NULL;
	if ( bInterpret )
	{
		if ( bEnglish )
		{
            ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard;
            if (bApi)
                pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(pDoc));

			//	code moved to own method InterpretEnglishString because it is also used in
			//	ScCellRangeObj::setFormulaArray

            pNewCell = InterpretEnglishString( rPos, rText, rFormulaNmsp, eGrammar );
		}
		// sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat
	}
	else if ( rText.Len() )
    {
        OSL_ENSURE( rFormulaNmsp.Len() == 0, "ScDocFunc::SetCellText - formula namespace, but do not interpret?" );
		pNewCell = ScBaseCell::CreateTextCell( rText, pDoc );	// immer Text
    }

	if (pNewCell)
		return PutCell( rPos, pNewCell, bApi );
	else
		return SetNormalString( rPos, rText, bApi );
}

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

bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow )
{
	ScDocument& rDoc = *rDocShell.GetDocument();
	ScPostIt* pNote = rDoc.GetNote( rPos );
    if( !pNote || (bShow == pNote->IsCaptionShown()) ) return false;

    // move the caption to internal or hidden layer and create undo action
    pNote->ShowCaption( rPos, bShow );
    if( rDoc.IsUndoEnabled() )
        rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell, rPos, bShow ) );

    if (rDoc.IsStreamValid(rPos.Tab()))
        rDoc.SetStreamValid(rPos.Tab(), sal_False);

    rDocShell.SetDocumentModified();

    return true;
}

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

bool ScDocFunc::SetNoteText( const ScAddress& rPos, const String& rText, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
        return false;
	}

	String aNewText = rText;
	aNewText.ConvertLineEnd();		//! ist das noetig ???

    if( ScPostIt* pNote = (aNewText.Len() > 0) ? pDoc->GetOrCreateNote( rPos ) : pDoc->GetNote( rPos ) )
        pNote->SetText( rPos, aNewText );

	//!	Undo !!!

    if (pDoc->IsStreamValid(rPos.Tab()))
        pDoc->SetStreamValid(rPos.Tab(), sal_False);

	rDocShell.PostPaintCell( rPos );
	aModificator.SetDocumentModified();

    return true;
}

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

bool ScDocFunc::ReplaceNote( const ScAddress& rPos, const String& rNoteText, const String* pAuthor, const String* pDate, sal_Bool bApi )
{
    bool bDone = false;

    ScDocShellModificator aModificator( rDocShell );
    ScDocument& rDoc = *rDocShell.GetDocument();
    ScEditableTester aTester( &rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
    if (aTester.IsEditable())
    {
        ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
        ::svl::IUndoManager* pUndoMgr = (pDrawLayer && rDoc.IsUndoEnabled()) ? rDocShell.GetUndoManager() : 0;

        ScNoteData aOldData;
        ScPostIt* pOldNote = rDoc.ReleaseNote( rPos );
        if( pOldNote )
        {
            // ensure existing caption object before draw undo tracking starts
            pOldNote->GetOrCreateCaption( rPos );
            // rescue note data for undo
            aOldData = pOldNote->GetNoteData();
        }

        // collect drawing undo actions for deleting/inserting caption objects
        if( pUndoMgr )
            pDrawLayer->BeginCalcUndo(false);

        // delete the note (creates drawing undo action for the caption object)
        delete pOldNote;

        // create new note (creates drawing undo action for the new caption object)
        ScNoteData aNewData;
        if( ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false, true ) )
        {
            if( pAuthor ) pNewNote->SetAuthor( *pAuthor );
            if( pDate ) pNewNote->SetDate( *pDate );
            // rescue note data for undo
            aNewData = pNewNote->GetNoteData();
        }

        // create the undo action
        if( pUndoMgr && (aOldData.mpCaption || aNewData.mpCaption) )
            pUndoMgr->AddUndoAction( new ScUndoReplaceNote( rDocShell, rPos, aOldData, aNewData, pDrawLayer->GetCalcUndo() ) );

        // repaint cell (to make note marker visible)
        rDocShell.PostPaintCell( rPos );

        if (rDoc.IsStreamValid(rPos.Tab()))
            rDoc.SetStreamValid(rPos.Tab(), sal_False);

        aModificator.SetDocumentModified();
        bDone = true;
    }
    else if (!bApi)
    {
        rDocShell.ErrorMessage(aTester.GetMessageId());
    }

    return bDone;
}

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

sal_Bool ScDocFunc::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
									sal_Bool bRecord, sal_Bool bApi )
{
	ScDocument* pDoc = rDocShell.GetDocument();
	if ( bRecord && !pDoc->IsUndoEnabled() )
		bRecord = sal_False;

    sal_Bool bImportingXML = pDoc->IsImportingXML();
    // Cell formats can still be set if the range isn't editable only because of matrix formulas.
    // #i62483# When loading XML, the check can be skipped altogether.
	sal_Bool bOnlyNotBecauseOfMatrix;
    if ( !bImportingXML && !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
			&& !bOnlyNotBecauseOfMatrix )
	{
		if (!bApi)
			rDocShell.ErrorMessage(STR_PROTECTIONERR);
		return sal_False;
	}

	ScDocShellModificator aModificator( rDocShell );

	//!	Umrandung

	ScRange aMultiRange;
	sal_Bool bMulti = rMark.IsMultiMarked();
	if ( bMulti )
		rMark.GetMultiMarkArea( aMultiRange );
	else
		rMark.GetMarkArea( aMultiRange );

	if ( bRecord )
	{
		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, aMultiRange.aStart.Tab(), aMultiRange.aEnd.Tab() );
		pDoc->CopyToDocument( aMultiRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );

		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoSelectionAttr(
					&rDocShell, rMark,
					aMultiRange.aStart.Col(), aMultiRange.aStart.Row(), aMultiRange.aStart.Tab(),
					aMultiRange.aEnd.Col(), aMultiRange.aEnd.Row(), aMultiRange.aEnd.Tab(),
					pUndoDoc, bMulti, &rPattern ) );
	}

	// While loading XML it is not necessary to ask HasAttrib. It needs too much time.
	sal_uInt16 nExtFlags = 0;
	if ( !bImportingXML )
		rDocShell.UpdatePaintExt( nExtFlags, aMultiRange );		// content before the change
	pDoc->ApplySelectionPattern( rPattern, rMark );
	if ( !bImportingXML )
		rDocShell.UpdatePaintExt( nExtFlags, aMultiRange );		// content after the change

	if (!AdjustRowHeight( aMultiRange ))
		rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags );
	else if (nExtFlags & SC_PF_LINES)
		lcl_PaintAbove( rDocShell, aMultiRange );	// fuer Linien ueber dem Bereich

	aModificator.SetDocumentModified();

	return sal_True;
}


sal_Bool ScDocFunc::ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
									sal_Bool bRecord, sal_Bool bApi )
{
	ScDocument* pDoc = rDocShell.GetDocument();
	if ( bRecord && !pDoc->IsUndoEnabled() )
		bRecord = sal_False;

    sal_Bool bImportingXML = pDoc->IsImportingXML();
    // Cell formats can still be set if the range isn't editable only because of matrix formulas.
    // #i62483# When loading XML, the check can be skipped altogether.
	sal_Bool bOnlyNotBecauseOfMatrix;
    if ( !bImportingXML && !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
			&& !bOnlyNotBecauseOfMatrix )
	{
		if (!bApi)
			rDocShell.ErrorMessage(STR_PROTECTIONERR);
		return sal_False;
	}

	ScStyleSheet* pStyleSheet = (ScStyleSheet*) pDoc->GetStyleSheetPool()->Find(
												rStyleName, SFX_STYLE_FAMILY_PARA );
	if (!pStyleSheet)
		return sal_False;

	ScDocShellModificator aModificator( rDocShell );

	ScRange aMultiRange;
	sal_Bool bMulti = rMark.IsMultiMarked();
	if ( bMulti )
		rMark.GetMultiMarkArea( aMultiRange );
	else
		rMark.GetMarkArea( aMultiRange );

	if ( bRecord )
	{
		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		SCTAB nStartTab = aMultiRange.aStart.Tab();
		SCTAB nTabCount = pDoc->GetTableCount();
		pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
		for (SCTAB i=0; i<nTabCount; i++)
			if (i != nStartTab && rMark.GetTableSelect(i))
				pUndoDoc->AddUndoTab( i, i );

		ScRange aCopyRange = aMultiRange;
		aCopyRange.aStart.SetTab(0);
		aCopyRange.aEnd.SetTab(nTabCount-1);
		pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );

		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoSelectionStyle(
					&rDocShell, rMark, aMultiRange, rStyleName, pUndoDoc ) );

	}

//	sal_Bool bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT );
//	pDoc->ApplySelectionPattern( rPattern, rMark );

	pDoc->ApplySelectionStyle( (ScStyleSheet&)*pStyleSheet, rMark );

//	if (!bPaintExt)
//		bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT );
//	sal_uInt16 nExtFlags = bPaintExt ? SC_PF_LINES : 0;
	sal_uInt16 nExtFlags = 0;
	if (!AdjustRowHeight( aMultiRange ))
		rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags );
	else if (nExtFlags & SC_PF_LINES)
		lcl_PaintAbove( rDocShell, aMultiRange );	// fuer Linien ueber dem Bereich

	aModificator.SetDocumentModified();

	return sal_True;
}

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

sal_Bool ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark, InsCellCmd eCmd,
								sal_Bool bRecord, sal_Bool bApi, sal_Bool bPartOfPaste )
{
	ScDocShellModificator aModificator( rDocShell );

	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCTAB nStartTab = rRange.aStart.Tab();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nEndTab = rRange.aEnd.Tab();

	if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
	{
		DBG_ERROR("invalid row in InsertCells");
		return sal_False;
	}

	ScDocument* pDoc = rDocShell.GetDocument();
	SCTAB nTabCount = pDoc->GetTableCount();
	SCCOL nPaintStartX = nStartCol;
	SCROW nPaintStartY = nStartRow;
	SCCOL nPaintEndX = nEndCol;
	SCROW nPaintEndY = nEndRow;
	sal_uInt16 nPaintFlags = PAINT_GRID;
	sal_Bool bSuccess;
    SCTAB i;

    ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();  //preserve current cursor position
    SCCOL nCursorCol = 0;
    SCROW nCursorRow = 0;
    if( pViewSh )
    {
        nCursorCol = pViewSh->GetViewData()->GetCurX();
        nCursorRow = pViewSh->GetViewData()->GetCurY();
    }

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

    ScMarkData aMark;
    if (pTabMark)
        aMark = *pTabMark;
    else
    {
        SCTAB nCount = 0;
        for( i=0; i<nTabCount; i++ )
        {
            if( !pDoc->IsScenario(i) )
            {
                nCount++;
                if( nCount == nEndTab+1 )
                {
                    aMark.SelectTable( i, sal_True );
                    break;
                }
            }
        }
    }

    ScMarkData aFullMark( aMark );          // including scenario sheets
    for( i=0; i<nTabCount; i++ )
        if( aMark.GetTableSelect( i ) )
        {
            for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
                aFullMark.SelectTable( j, sal_True );
        }

    SCTAB nSelCount = aMark.GetSelectCount();

	//	zugehoerige Szenarien auch anpassen
	// Test zusammengefasste

	SCCOL nMergeTestStartX = nStartCol;
	SCROW nMergeTestStartY = nStartRow;
	SCCOL nMergeTestEndX = nEndCol;
	SCROW nMergeTestEndY = nEndRow;

    ScRange aExtendMergeRange( rRange );

    if( rRange.aStart == rRange.aEnd && pDoc->HasAttrib(rRange, HASATTR_MERGED) )
    {
        pDoc->ExtendMerge( aExtendMergeRange );
        pDoc->ExtendOverlapped( aExtendMergeRange );
        nMergeTestEndX = aExtendMergeRange.aEnd.Col();
        nMergeTestEndY = aExtendMergeRange.aEnd.Row();
        nPaintEndX = nMergeTestEndX;
        nPaintEndY = nMergeTestEndY;
    }

	if ( eCmd == INS_INSROWS )
	{
		nMergeTestStartX = 0;
		nMergeTestEndX = MAXCOL;
	}
	if ( eCmd == INS_INSCOLS )
	{
		nMergeTestStartY = 0;
		nMergeTestEndY = MAXROW;
	}
	if ( eCmd == INS_CELLSDOWN )
		nMergeTestEndY = MAXROW;
	if ( eCmd == INS_CELLSRIGHT )
		nMergeTestEndX = MAXCOL;

	sal_Bool bNeedRefresh = sal_False;

	SCCOL nEditTestEndX = (eCmd==INS_INSCOLS) ? MAXCOL : nMergeTestEndX;
	SCROW nEditTestEndY = (eCmd==INS_INSROWS) ? MAXROW : nMergeTestEndY;
    ScEditableTester aTester( pDoc, nMergeTestStartX, nMergeTestStartY, nEditTestEndX, nEditTestEndY, aMark );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	WaitObject aWait( rDocShell.GetActiveDialogParent() );		// wichtig wegen TrackFormulas bei UpdateReference

	ScDocument* pRefUndoDoc = NULL;
	ScRefUndoData* pUndoData = NULL;
	if ( bRecord )
	{
		pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, sal_False, sal_False );

		// pRefUndoDoc is filled in InsertCol / InsertRow

		pUndoData = new ScRefUndoData( pDoc );

		pDoc->BeginDrawUndo();
	}

    // #i8302 : we unmerge overwhelming ranges, before insertion all the actions are put in the same ListAction
    // the patch comes from mloiseleur and maoyg
    sal_Bool bInsertMerge = sal_False;
    std::vector<ScRange> qIncreaseRange;
    String aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTCELLS );
    if (bRecord)
        rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );

    for( i=0; i<nTabCount; i++ )
    {
        if( aMark.GetTableSelect(i) )
        {
            if( pDoc->HasAttrib( nMergeTestStartX, nMergeTestStartY, i, nMergeTestEndX, nMergeTestEndY, i, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
            {
                if (eCmd==INS_CELLSRIGHT)
                    bNeedRefresh = sal_True;

                SCCOL nMergeStartX = nMergeTestStartX;
                SCROW nMergeStartY = nMergeTestStartY;
                SCCOL nMergeEndX   = nMergeTestEndX;
                SCROW nMergeEndY   = nMergeTestEndY;

                pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
                pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );

                if(( eCmd == INS_CELLSDOWN && ( nMergeStartX != nMergeTestStartX || nMergeEndX != nMergeTestEndX )) ||
                    (eCmd == INS_CELLSRIGHT && ( nMergeStartY != nMergeTestStartY || nMergeEndY != nMergeTestEndY )) )
                {
                    if (!bApi)
                        rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
                    rDocShell.GetUndoManager()->LeaveListAction();
                    return sal_False;
                }

                SCCOL nTestCol = -1;
                SCROW nTestRow1 = -1;
                SCROW nTestRow2 = -1;

                ScDocAttrIterator aTestIter( pDoc, i, nMergeTestStartX, nMergeTestStartY, nMergeTestEndX, nMergeTestEndY );
                ScRange aExtendRange( nMergeTestStartX, nMergeTestStartY, i, nMergeTestEndX, nMergeTestEndY, i );
                const ScPatternAttr* pPattern = NULL;
                const ScMergeAttr* pMergeFlag = NULL;
                const ScMergeFlagAttr* pMergeFlagAttr = NULL;
                while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
                {
                    pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem(ATTR_MERGE);
                    pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
                    sal_Int16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
                    if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
                    {
                        ScRange aRange( nTestCol, nTestRow1, i );
                        pDoc->ExtendOverlapped(aRange);
                        pDoc->ExtendMerge(aRange, sal_True, sal_True);

                        if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
                        {
                            for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
                            {
                                ScRange aTestRange( nTestCol, nTestRow, i );
                                pDoc->ExtendOverlapped( aTestRange );
                                pDoc->ExtendMerge( aTestRange, sal_True, sal_True);
                                ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
                                if( !aExtendRange.In( aMergeRange ) )
                                {
                                    qIncreaseRange.push_back( aTestRange );
                                    bInsertMerge = sal_True;
                                }
                            }
                        }
                        else
                        {
                            ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
                            if( !aExtendRange.In( aMergeRange ) )
                            {
                                qIncreaseRange.push_back( aRange );
                            }
                            bInsertMerge = sal_True;
                        }
                    }
                }

                if( bInsertMerge )
                {
                    if( eCmd == INS_INSROWS || eCmd == INS_CELLSDOWN )
                    {
                        nStartRow = aExtendMergeRange.aStart.Row();
                        nEndRow = aExtendMergeRange.aEnd.Row();

                        if( eCmd == INS_CELLSDOWN )
                            nEndCol = nMergeTestEndX;
                        else
                        {
                            nStartCol = 0;
                            nEndCol = MAXCOL;
                        }
                    }
                    else if( eCmd == INS_CELLSRIGHT || eCmd == INS_INSCOLS )
                    {

                        nStartCol = aExtendMergeRange.aStart.Col();
                        nEndCol = aExtendMergeRange.aEnd.Col();
                        if( eCmd == INS_CELLSRIGHT )
                        {
                            nEndRow = nMergeTestEndY;
                        }
                        else
                        {
                            nStartRow = 0;
                            nEndRow = MAXROW;
                        }
                    }

                    if( !qIncreaseRange.empty() )
                    {
                        for( ::std::vector<ScRange>::const_iterator iIter( qIncreaseRange.begin()); iIter != qIncreaseRange.end(); iIter++ )
                        {
                            ScRange aRange( *iIter );
                            if( pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
                            {
                                UnmergeCells( aRange, sal_True, sal_True );
                            }
                        }
                    }
                }
                else
                {
                    if (!bApi)
                        rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
                    rDocShell.GetUndoManager()->LeaveListAction();
                    return sal_False;
                }
            }
        }
    }

	switch (eCmd)
	{
		case INS_CELLSDOWN:
            bSuccess = pDoc->InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
			nPaintEndY = MAXROW;
			break;
		case INS_INSROWS:
            bSuccess = pDoc->InsertRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
			nPaintStartX = 0;
			nPaintEndX = MAXCOL;
			nPaintEndY = MAXROW;
			nPaintFlags |= PAINT_LEFT;
			break;
		case INS_CELLSRIGHT:
            bSuccess = pDoc->InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
			nPaintEndX = MAXCOL;
			break;
		case INS_INSCOLS:
            bSuccess = pDoc->InsertCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
			nPaintStartY = 0;
			nPaintEndY = MAXROW;
			nPaintEndX = MAXCOL;
			nPaintFlags |= PAINT_TOP;
			break;
		default:
			DBG_ERROR("Falscher Code beim Einfuegen");
			bSuccess = sal_False;
			break;
	}

	if ( bSuccess )
	{
        SCTAB* pTabs      = NULL;
        SCTAB* pScenarios = NULL;
        SCTAB  nUndoPos  = 0;

        if ( bRecord )
        {
            pTabs       = new SCTAB[nSelCount];
            pScenarios  = new SCTAB[nSelCount];
            nUndoPos    = 0;
            for( i=0; i<nTabCount; i++ )
            {
                if( aMark.GetTableSelect( i ) )
                {
                    SCTAB nCount = 0;
                    for( SCTAB j=i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
                        nCount ++;

                    pScenarios[nUndoPos] = nCount;
                    pTabs[nUndoPos] = i;
                    nUndoPos ++;
                }
            }

            if( !bInsertMerge )
            {
                rDocShell.GetUndoManager()->LeaveListAction();
            }

            rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertCells(
                &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),
                nUndoPos, pTabs, pScenarios, eCmd, pRefUndoDoc, pUndoData, bPartOfPaste ) );
        }

        // #i8302 : we remerge growing ranges, with the new part inserted

        while( !qIncreaseRange.empty() )
        {
            ScRange aRange = qIncreaseRange.back();
            if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
            {
                switch (eCmd)
                {
                    case INS_CELLSDOWN:
                    case INS_INSROWS:
                        aRange.aEnd.IncRow(static_cast<SCsCOL>(nEndRow-nStartRow+1));
                        break;
                    case INS_CELLSRIGHT:
                    case INS_INSCOLS:
                        aRange.aEnd.IncCol(static_cast<SCsCOL>(nEndCol-nStartCol+1));
                        break;
                    default:
                        break;
                }
                MergeCells(aRange, sal_False, sal_True, sal_True);
            }
            qIncreaseRange.pop_back();
        }

        if( bInsertMerge )
            rDocShell.GetUndoManager()->LeaveListAction();

        for( i=0; i<nTabCount; i++ )
        {
            if( aMark.GetTableSelect( i ) )
            {
		        if (bNeedRefresh)
			        pDoc->ExtendMerge( nMergeTestStartX, nMergeTestStartY, nMergeTestEndX, nMergeTestEndY, i, sal_True );
		        else
			        pDoc->RefreshAutoFilter( nMergeTestStartX, nMergeTestStartY, nMergeTestEndX, nMergeTestEndY, i );

		        if ( eCmd == INS_INSROWS || eCmd == INS_INSCOLS )
			        pDoc->UpdatePageBreaks( i );

		        sal_uInt16 nExtFlags = 0;
		        rDocShell.UpdatePaintExt( nExtFlags, nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i );

                SCTAB nScenarioCount = 0;

                for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
                    nScenarioCount ++;

		        sal_Bool bAdjusted = ( eCmd == INS_INSROWS ) ? AdjustRowHeight(ScRange(0, nStartRow, i, MAXCOL, nEndRow, i+nScenarioCount )) :
				                                           AdjustRowHeight(ScRange(0, nPaintStartY, i, MAXCOL, nPaintEndY, i+nScenarioCount ));
		        if (bAdjusted)
		        {
			        //	paint only what is not done by AdjustRowHeight
			        if (nPaintFlags & PAINT_TOP)
				        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, PAINT_TOP );
		        }
		        else
			        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, nPaintFlags, nExtFlags );
            }
        }
		//aModificator.SetDocumentModified();
	}
	else
	{
        if( bInsertMerge )
        {
            while( !qIncreaseRange.empty() )
            {
                ScRange aRange = qIncreaseRange.back();
                MergeCells(aRange, sal_False, sal_True, sal_True);
                qIncreaseRange.pop_back();
            }

            if( pViewSh )
            {
                pViewSh->MarkRange( rRange, sal_False );
                pViewSh->SetCursor( nCursorCol, nCursorRow );
            }
        }

        rDocShell.GetUndoManager()->LeaveListAction();
        rDocShell.GetUndoManager()->RemoveLastUndoAction();

		delete pRefUndoDoc;
		delete pUndoData;
		if (!bApi)
			rDocShell.ErrorMessage(STR_INSERT_FULL);		// Spalte/Zeile voll
	}

    aModificator.SetDocumentModified();

    SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
	return bSuccess;
}

sal_Bool ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, DelCellCmd eCmd,
                             sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCTAB nStartTab = rRange.aStart.Tab();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nEndTab = rRange.aEnd.Tab();

	if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
	{
		DBG_ERROR("invalid row in DeleteCells");
		return sal_False;
	}

	ScDocument* pDoc = rDocShell.GetDocument();
	SCTAB nTabCount = pDoc->GetTableCount();
	SCCOL nPaintStartX = nStartCol;
	SCROW nPaintStartY = nStartRow;
	SCCOL nPaintEndX = nEndCol;
	SCROW nPaintEndY = nEndRow;
	sal_uInt16 nPaintFlags = PAINT_GRID;
    SCTAB i;

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

    ScMarkData aMark;
    if (pTabMark)
        aMark = *pTabMark;
    else
    {
        SCTAB nCount = 0;
        for( i=0; i<nTabCount; i++ )
        {
            if( !pDoc->IsScenario(i) )
            {
                nCount++;
                if( nCount == nEndTab+1 )
                {
                    aMark.SelectTable( i, sal_True );
                    break;
                }
            }
        }
    }

    ScMarkData aFullMark( aMark );          // including scenario sheets
    for( i=0; i<nTabCount; i++ )
        if( aMark.GetTableSelect( i ) )
        {
            for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
                aFullMark.SelectTable( j, sal_True );
        }

    SCTAB nSelCount = aMark.GetSelectCount();

	SCCOL nUndoStartX = nStartCol;
	SCROW nUndoStartY = nStartRow;
	SCCOL nUndoEndX = nEndCol;
	SCROW nUndoEndY = nEndRow;

    ScRange aExtendMergeRange( rRange );

    if( rRange.aStart == rRange.aEnd && pDoc->HasAttrib(rRange, HASATTR_MERGED) )
    {
        pDoc->ExtendMerge( aExtendMergeRange );
        pDoc->ExtendOverlapped( aExtendMergeRange );
        nUndoEndX = aExtendMergeRange.aEnd.Col();
        nUndoEndY = aExtendMergeRange.aEnd.Row();
        nPaintEndX = nUndoEndX;
        nPaintEndY = nUndoEndY;
    }

	if (eCmd==DEL_DELROWS)
	{
		nUndoStartX = 0;
		nUndoEndX = MAXCOL;
	}
	if (eCmd==DEL_DELCOLS)
	{
		nUndoStartY = 0;
		nUndoEndY = MAXROW;
	}
					// Test Zellschutz

	SCCOL nEditTestEndX = nUndoEndX;
	if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
        nEditTestEndX = MAXCOL;
	SCROW nEditTestEndY = nUndoEndY;
	if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
        nEditTestEndY = MAXROW;
	ScEditableTester aTester( pDoc, nUndoStartX, nUndoStartY, nEditTestEndX, nEditTestEndY, aMark );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

					// Test zusammengefasste

	SCCOL nMergeTestEndX = (eCmd==DEL_CELLSLEFT) ? MAXCOL : nUndoEndX;
	SCROW nMergeTestEndY = (eCmd==DEL_CELLSUP)   ? MAXROW : nUndoEndY;
    SCCOL nExtendStartCol = nUndoStartX;
    SCROW nExtendStartRow = nUndoStartY;
	sal_Bool bNeedRefresh = sal_False;

    //Issue 8302 want to be able to insert into the middle of merged cells
    //the patch comes from maoyg
    ::std::vector<ScRange> qDecreaseRange;
    sal_Bool bDeletingMerge = sal_False;
    String aUndo = ScGlobal::GetRscString( STR_UNDO_DELETECELLS );
    if (bRecord)
        rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );

    for( i=0; i<nTabCount; i++ )
    {
        if( aMark.GetTableSelect(i) )
        {
	        if ( pDoc->HasAttrib( nUndoStartX, nUndoStartY, i, nMergeTestEndX, nMergeTestEndY, i, HASATTR_MERGED | HASATTR_OVERLAPPED ))
            {
		        SCCOL nMergeStartX = nUndoStartX;
		        SCROW nMergeStartY = nUndoStartY;
		        SCCOL nMergeEndX   = nMergeTestEndX;
		        SCROW nMergeEndY   = nMergeTestEndY;

		        pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
		        pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
                if( ( eCmd == DEL_CELLSUP && ( nMergeStartX != nUndoStartX || nMergeEndX != nMergeTestEndX))||
                    ( eCmd == DEL_CELLSLEFT && ( nMergeStartY != nUndoStartY || nMergeEndY != nMergeTestEndY)))
                {
                    if (!bApi)
                        rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
                    rDocShell.GetUndoManager()->LeaveListAction();
                    return sal_False;
                }

                nExtendStartCol = nMergeStartX;
                nExtendStartRow = nMergeStartY;
                SCCOL nTestCol = -1;
                SCROW nTestRow1 = -1;
                SCROW nTestRow2 = -1;

                ScDocAttrIterator aTestIter( pDoc, i, nUndoStartX, nUndoStartY, nMergeTestEndX, nMergeTestEndY );
                ScRange aExtendRange( nUndoStartX, nUndoStartY, i, nMergeTestEndX, nMergeTestEndY, i );
                const ScPatternAttr* pPattern = NULL;
                const ScMergeAttr* pMergeFlag = NULL;
                const ScMergeFlagAttr* pMergeFlagAttr = NULL;
                while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
                {
                    pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
                    pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem( ATTR_MERGE_FLAG );
                    sal_Int16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
                    if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
                    {
                        ScRange aRange( nTestCol, nTestRow1, i );
                        pDoc->ExtendOverlapped( aRange );
                        pDoc->ExtendMerge( aRange, sal_True, sal_True );

                        if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
                        {
                            for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
                            {
                                ScRange aTestRange( nTestCol, nTestRow, i );
                                pDoc->ExtendOverlapped( aTestRange );
                                pDoc->ExtendMerge( aTestRange, sal_True, sal_True);
                                ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
                                if( !aExtendRange.In( aMergeRange ) )
                                {
                                    qDecreaseRange.push_back( aTestRange );
                                    bDeletingMerge = sal_True;
                                }
                            }
                        }
                        else
                        {
                            ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
                            if( !aExtendRange.In( aMergeRange ) )
                            {
                                qDecreaseRange.push_back( aRange );
                            }
                            bDeletingMerge = sal_True;
                        }
                    }
                }

                if( bDeletingMerge )
                {

                    if( eCmd == DEL_DELROWS || eCmd == DEL_CELLSUP )
                    {
                        nStartRow = aExtendMergeRange.aStart.Row();
                        nEndRow = aExtendMergeRange.aEnd.Row();
                        bNeedRefresh = sal_True;

                        if( eCmd == DEL_CELLSUP )
                        {
                            nEndCol = aExtendMergeRange.aEnd.Col();
                        }
                        else
                        {
                            nStartCol = 0;
                            nEndCol = MAXCOL;
                        }
                    }
                    else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
                    {

                        nStartCol = aExtendMergeRange.aStart.Col();
                        nEndCol = aExtendMergeRange.aEnd.Col();
                        if( eCmd == DEL_CELLSLEFT )
                        {
                            nEndRow = aExtendMergeRange.aEnd.Row();
                            bNeedRefresh = sal_True;
                        }
                        else
                        {
                            nStartRow = 0;
                            nEndRow = MAXROW;
                        }
                    }

                    if( !qDecreaseRange.empty() )
                    {
                        for( ::std::vector<ScRange>::const_iterator iIter( qDecreaseRange.begin()); iIter != qDecreaseRange.end(); iIter++ )
                        {
                            ScRange aRange( *iIter );
                            if( pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
                            {
                                UnmergeCells( aRange, sal_True, sal_True );
                            }
                        }
                    }
                }
                else
                {
                    if (!bApi)
                        rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
                    rDocShell.GetUndoManager()->LeaveListAction();
                    return sal_False;
                }
	        }
        }
    }

	//
	//		ausfuehren
	//

	WaitObject aWait( rDocShell.GetActiveDialogParent() );		// wichtig wegen TrackFormulas bei UpdateReference

	ScDocument* pUndoDoc = NULL;
	ScDocument* pRefUndoDoc = NULL;
	ScRefUndoData* pUndoData = NULL;
	if ( bRecord )
	{
        // With the fix for #101329#, UpdateRef always puts cells into pRefUndoDoc at their old position,
        // so it's no longer necessary to copy more than the deleted range into pUndoDoc.

		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, 0, nTabCount-1, (eCmd==DEL_DELCOLS), (eCmd==DEL_DELROWS) );
        for( i=0; i<nTabCount; i++ )
        {
            if( aMark.GetTableSelect( i ) )
            {
                SCTAB nScenarioCount = 0;

                for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
                    nScenarioCount ++;

                pDoc->CopyToDocument( nUndoStartX, nUndoStartY, i, nUndoEndX, nUndoEndY, i+nScenarioCount,
                    IDF_ALL | IDF_NOCAPTIONS, sal_False, pUndoDoc );
            }
        }

		pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, sal_False, sal_False );

		pUndoData = new ScRefUndoData( pDoc );

		pDoc->BeginDrawUndo();
	}

	sal_uInt16 nExtFlags = 0;
    for( i=0; i<nTabCount; i++ )
    {
        if( aMark.GetTableSelect( i ) )
            rDocShell.UpdatePaintExt( nExtFlags, nStartCol, nStartRow, i, nEndCol, nEndRow, i );
    }

	sal_Bool bUndoOutline = sal_False;
	switch (eCmd)
	{
		case DEL_CELLSUP:
            pDoc->DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, NULL, &aFullMark );
			nPaintEndY = MAXROW;
			break;
		case DEL_DELROWS:
            pDoc->DeleteRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
			nPaintStartX = 0;
			nPaintEndX = MAXCOL;
			nPaintEndY = MAXROW;
			nPaintFlags |= PAINT_LEFT;
			break;
		case DEL_CELLSLEFT:
            pDoc->DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, NULL, &aFullMark );
			nPaintEndX = MAXCOL;
			break;
		case DEL_DELCOLS:
            pDoc->DeleteCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
			nPaintStartY = 0;
			nPaintEndY = MAXROW;
			nPaintEndX = MAXCOL;
			nPaintFlags |= PAINT_TOP;
			break;
		default:
			DBG_ERROR("Falscher Code beim Loeschen");
			break;
	}

	//!	Test, ob Outline in Groesse geaendert

	if ( bRecord )
	{
        for( i=0; i<nTabCount; i++ )
            if( aFullMark.GetTableSelect( i ) )
                pRefUndoDoc->DeleteAreaTab(nUndoStartX,nUndoStartY,nUndoEndX,nUndoEndY, i, IDF_ALL);

			//	alle Tabellen anlegen, damit Formeln kopiert werden koennen:
		pUndoDoc->AddUndoTab( 0, nTabCount-1, sal_False, sal_False );

			//	kopieren mit bColRowFlags=sal_False (#54194#)
		pRefUndoDoc->CopyToDocument(0,0,0,MAXCOL,MAXROW,MAXTAB,IDF_FORMULA,sal_False,pUndoDoc,NULL,sal_False);
		delete pRefUndoDoc;

        SCTAB* pTabs      = new SCTAB[nSelCount];
        SCTAB* pScenarios = new SCTAB[nSelCount];
        SCTAB   nUndoPos  = 0;

        for( i=0; i<nTabCount; i++ )
        {
            if( aMark.GetTableSelect( i ) )
            {
                SCTAB nCount = 0;
                for( SCTAB j=i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
                    nCount ++;

                pScenarios[nUndoPos] = nCount;
                pTabs[nUndoPos] = i;
                nUndoPos ++;
            }
        }

        if( !bDeletingMerge )
        {
            rDocShell.GetUndoManager()->LeaveListAction();
        }

		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
            &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),nUndoPos, pTabs, pScenarios,
			eCmd, pUndoDoc, pUndoData ) );
	}

    // #i8302 want to be able to insert into the middle of merged cells
    // the patch comes from maoyg

    while( !qDecreaseRange.empty() )
    {
        ScRange aRange = qDecreaseRange.back();

        long nDecreaseRowCount = 0;
        long nDecreaseColCount = 0;
        if( eCmd == DEL_CELLSUP || eCmd == DEL_DELROWS )
        {
            if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
                nDecreaseRowCount = nEndRow-nStartRow+1;
            else if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow >= aRange.aStart.Row() && nEndRow >= aRange.aEnd.Row() )
                nDecreaseRowCount = aRange.aEnd.Row()-nStartRow+1;
            else if( nStartRow >= aRange.aStart.Row() && nStartRow >= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
                nDecreaseRowCount = aRange.aEnd.Row()-nEndRow+1;
        }
        else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
        {
            if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
                nDecreaseColCount = nEndCol-nStartCol+1;
            else if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol >= aRange.aStart.Col() && nEndCol >= aRange.aEnd.Col() )
                nDecreaseColCount = aRange.aEnd.Col()-nStartCol+1;
            else if( nStartCol >= aRange.aStart.Col() && nStartCol >= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
                nDecreaseColCount = aRange.aEnd.Col()-nEndCol+1;
        }

        switch (eCmd)
        {
            case DEL_CELLSUP:
            case DEL_DELROWS:
                aRange.aEnd.SetRow(static_cast<SCsCOL>( aRange.aEnd.Row()-nDecreaseRowCount));
                break;
            case DEL_CELLSLEFT:
            case DEL_DELCOLS:
                aRange.aEnd.SetCol(static_cast<SCsCOL>( aRange.aEnd.Col()-nDecreaseColCount));
                break;
            default:
                break;
        }

        if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
        {
            MergeCells( aRange, sal_False, sal_True, sal_True );
        }
        qDecreaseRange.pop_back();
    }

    if( bDeletingMerge )
        rDocShell.GetUndoManager()->LeaveListAction();

	if ( bNeedRefresh )
	{
        // #i51445# old merge flag attributes must be deleted also for single cells,
        // not only for whole columns/rows

        if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
            nMergeTestEndX = MAXCOL;
        if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
            nMergeTestEndY = MAXROW;
		ScPatternAttr aPattern( pDoc->GetPool() );
		aPattern.GetItemSet().Put( ScMergeFlagAttr() );

        pDoc->ApplyPatternArea( nExtendStartCol, nExtendStartRow, nMergeTestEndX, nMergeTestEndY, aMark, aPattern );

        for( i=0; i<nTabCount; i++ )
        {
            if( aMark.GetTableSelect( i ) )
            {
                SCTAB nScenarioCount = 0;

                for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
                    nScenarioCount ++;

                ScRange aMergedRange( nExtendStartCol, nExtendStartRow, i, nMergeTestEndX, nMergeTestEndY, i+nScenarioCount );
                pDoc->ExtendMerge( aMergedRange, sal_True );
            }
        }
	}

    for( i=0; i<nTabCount; i++ )
    {
        if( aMark.GetTableSelect( i ) )
        {
	        if ( eCmd == DEL_DELCOLS || eCmd == DEL_DELROWS )
                pDoc->UpdatePageBreaks( i );

	        rDocShell.UpdatePaintExt( nExtFlags, nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i );

            SCTAB nScenarioCount = 0;

            for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
                nScenarioCount ++;

	        //	ganze Zeilen loeschen: nichts anpassen
	        if ( eCmd == DEL_DELROWS || !AdjustRowHeight(ScRange( 0, nPaintStartY, i, MAXCOL, nPaintEndY, i+nScenarioCount )) )
		        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, nPaintFlags,  nExtFlags );
    	    else
	        {
		        //	paint only what is not done by AdjustRowHeight
		        if (nExtFlags & SC_PF_LINES)
			        lcl_PaintAbove( rDocShell, ScRange( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount) );
		        if (nPaintFlags & PAINT_TOP)
			        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, PAINT_TOP );
	        }
        }
    }
	aModificator.SetDocumentModified();

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

	return sal_True;
}

sal_Bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
								sal_Bool bCut, sal_Bool bRecord, sal_Bool bPaint, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	SCCOL nStartCol = rSource.aStart.Col();
	SCROW nStartRow = rSource.aStart.Row();
	SCTAB nStartTab = rSource.aStart.Tab();
	SCCOL nEndCol = rSource.aEnd.Col();
	SCROW nEndRow = rSource.aEnd.Row();
	SCTAB nEndTab = rSource.aEnd.Tab();
	SCCOL nDestCol = rDestPos.Col();
	SCROW nDestRow = rDestPos.Row();
	SCTAB nDestTab = rDestPos.Tab();

	if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) || !ValidRow(nDestRow) )
	{
		DBG_ERROR("invalid row in MoveBlock");
		return sal_False;
	}

	//	zugehoerige Szenarien auch anpassen - nur wenn innerhalb einer Tabelle verschoben wird!
	sal_Bool bScenariosAdded = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	SCTAB nTabCount = pDoc->GetTableCount();
	if ( nDestTab == nStartTab && !pDoc->IsScenario(nEndTab) )
		while ( nEndTab+1 < nTabCount && pDoc->IsScenario(nEndTab+1) )
		{
			++nEndTab;
			bScenariosAdded = sal_True;
		}

	SCTAB nSrcTabCount = nEndTab-nStartTab+1;
	SCTAB nDestEndTab = nDestTab+nSrcTabCount-1;
	SCTAB nTab;

	ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );

	ScMarkData aSourceMark;
	for (nTab=nStartTab; nTab<=nEndTab; nTab++)
		aSourceMark.SelectTable( nTab, sal_True );		// Source selektieren
	aSourceMark.SetMarkArea( rSource );

	ScDocShellRef aDragShellRef;
	if ( pDoc->HasOLEObjectsInArea( rSource ) )
	{
		aDragShellRef = new ScDocShell;		// DocShell needs a Ref immediately
		aDragShellRef->DoInitNew(NULL);
	}
	ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);

    ScClipParam aClipParam(ScRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nStartTab), bCut);
    pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bScenariosAdded, true);

	ScDrawLayer::SetGlobalDrawPersist(NULL);

	SCCOL nOldEndCol = nEndCol;
	SCROW nOldEndRow = nEndRow;
	sal_Bool bClipOver = sal_False;
	for (nTab=nStartTab; nTab<=nEndTab; nTab++)
	{
		SCCOL nTmpEndCol = nOldEndCol;
		SCROW nTmpEndRow = nOldEndRow;
		if (pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab ))
			bClipOver = sal_True;
		if ( nTmpEndCol > nEndCol ) nEndCol = nTmpEndCol;
		if ( nTmpEndRow > nEndRow ) nEndRow = nTmpEndRow;
	}

	SCCOL nDestEndCol = nDestCol + ( nOldEndCol-nStartCol );
	SCROW nDestEndRow = nDestRow + ( nOldEndRow-nStartRow );

	SCCOL nUndoEndCol = nDestCol + ( nEndCol-nStartCol );		// erweitert im Zielblock
	SCROW nUndoEndRow = nDestRow + ( nEndRow-nStartRow );

	sal_Bool bIncludeFiltered = bCut;
	if ( !bIncludeFiltered )
	{
		//	adjust sizes to include only non-filtered rows

        SCCOL nClipX;
        SCROW nClipY;
        pClipDoc->GetClipArea( nClipX, nClipY, sal_False );
		SCROW nUndoAdd = nUndoEndRow - nDestEndRow;
		nDestEndRow = nDestRow + nClipY;
		nUndoEndRow = nDestEndRow + nUndoAdd;
	}

	if (!ValidCol(nUndoEndCol) || !ValidRow(nUndoEndRow))
	{
		if (!bApi)
			rDocShell.ErrorMessage(STR_PASTE_FULL);
		delete pClipDoc;
		return sal_False;
	}

	//	Test auf Zellschutz

	ScEditableTester aTester;
	for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
		aTester.TestBlock( pDoc, nTab, nDestCol,nDestRow, nUndoEndCol,nUndoEndRow );
	if (bCut)
		for (nTab=nStartTab; nTab<=nEndTab; nTab++)
			aTester.TestBlock( pDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );

	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		delete pClipDoc;
		return sal_False;
	}

	//	Test auf zusammengefasste - beim Verschieben erst nach dem Loeschen

	if (bClipOver && !bCut)
		if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab, nUndoEndCol,nUndoEndRow,nDestEndTab,
								HASATTR_MERGED | HASATTR_OVERLAPPED ))
		{		// "Zusammenfassen nicht verschachteln !"
			if (!bApi)
				rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
			delete pClipDoc;
			return sal_False;
		}

	//	Are there borders in the cells? (for painting)

	sal_uInt16 nSourceExt = 0;
	rDocShell.UpdatePaintExt( nSourceExt, nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab );
	sal_uInt16 nDestExt = 0;
	rDocShell.UpdatePaintExt( nDestExt, nDestCol,nDestRow,nDestTab, nDestEndCol,nDestEndRow,nDestEndTab );

	//
	//	ausfuehren
	//

	ScDocument* pUndoDoc = NULL;
	ScDocument* pRefUndoDoc = NULL;
	ScRefUndoData* pUndoData = NULL;
	if (bRecord)
	{
		sal_Bool bWholeCols = ( nStartRow == 0 && nEndRow == MAXROW );
		sal_Bool bWholeRows = ( nStartCol == 0 && nEndCol == MAXCOL );
        sal_uInt16 nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;

		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bWholeCols, bWholeRows );

		if (bCut)
		{
			pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
                                    nUndoFlags, sal_False, pUndoDoc );
			pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, sal_False, sal_False );
		}

		if ( nDestTab != nStartTab )
			pUndoDoc->AddUndoTab( nDestTab, nDestEndTab, bWholeCols, bWholeRows );
		pDoc->CopyToDocument( nDestCol, nDestRow, nDestTab,
									nDestEndCol, nDestEndRow, nDestEndTab,
                                    nUndoFlags, sal_False, pUndoDoc );

		pUndoData = new ScRefUndoData( pDoc );

		pDoc->BeginDrawUndo();
	}

	sal_Bool bSourceHeight = sal_False;		// Hoehen angepasst?
	if (bCut)
	{
		ScMarkData aDelMark;	// only for tables
		for (nTab=nStartTab; nTab<=nEndTab; nTab++)
		{
			pDoc->DeleteAreaTab( nStartCol,nStartRow, nOldEndCol,nOldEndRow, nTab, IDF_ALL );
			aDelMark.SelectTable( nTab, sal_True );
		}
		pDoc->DeleteObjectsInArea( nStartCol,nStartRow, nOldEndCol,nOldEndRow, aDelMark );

		//	Test auf zusammengefasste

		if (bClipOver)
			if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab,
									nUndoEndCol,nUndoEndRow,nDestEndTab,
									HASATTR_MERGED | HASATTR_OVERLAPPED ))
			{
				pDoc->CopyFromClip( rSource, aSourceMark, IDF_ALL, pRefUndoDoc, pClipDoc );
				for (nTab=nStartTab; nTab<=nEndTab; nTab++)
				{
					SCCOL nTmpEndCol = nEndCol;
					SCROW nTmpEndRow = nEndRow;
					pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab, sal_True );
				}

				//	Fehlermeldung erst nach dem Wiederherstellen des Inhalts
				if (!bApi)		// "Zusammenfassen nicht verschachteln !"
					rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);

				delete pUndoDoc;
				delete pRefUndoDoc;
				delete pUndoData;
				delete pClipDoc;
				return sal_False;
			}

		bSourceHeight = AdjustRowHeight( rSource, sal_False );
	}

	ScRange aPasteDest( nDestCol, nDestRow, nDestTab, nDestEndCol, nDestEndRow, nDestEndTab );

	ScMarkData aDestMark;
	for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
		aDestMark.SelectTable( nTab, sal_True );		// Destination selektieren
	aDestMark.SetMarkArea( aPasteDest );

    /*  Do not copy cell notes and drawing objects here. While pasting, the
        function ScDocument::UpdateReference() is called which calls
        ScDrawLayer::MoveCells() which may move away inserted objects to wrong
        positions (e.g. if source and destination range overlaps). Cell notes
        and drawing objects are pasted below after doing all adjusting. */
    pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_ALL & ~(IDF_NOTE | IDF_OBJECTS),
						pRefUndoDoc, pClipDoc, sal_True, sal_False, bIncludeFiltered );

	// skipped rows and merged cells don't mix
	if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
		UnmergeCells( aPasteDest, sal_False, sal_True );

	VirtualDevice aVirtDev;
	sal_Bool bDestHeight = AdjustRowHeight(
							ScRange( 0,nDestRow,nDestTab, MAXCOL,nDestEndRow,nDestEndTab ),
							sal_False );

    /*  Paste cell notes and drawing objects after adjusting formula references
        and row heights. There are no cell notes or drawing objects, if the
        clipdoc does not contain a drawing layer.
        #i102056# Passing IDF_NOTE only would overwrite cell contents with
        empty note cells, therefore the special modifier IDF_ADDNOTES is passed
        here too which changes the behavior of ScColumn::CopyFromClip() to not
        touch existing cells. */
	if ( pClipDoc->GetDrawLayer() )
        pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_ADDNOTES | IDF_OBJECTS,
							pRefUndoDoc, pClipDoc, sal_True, sal_False, bIncludeFiltered );

	if (bRecord)
	{
		if (pRefUndoDoc)
		{
				//	alle Tabellen anlegen, damit Formeln kopiert werden koennen:
			pUndoDoc->AddUndoTab( 0, nTabCount-1, sal_False, sal_False );

			pRefUndoDoc->DeleteArea( nDestCol, nDestRow, nDestEndCol, nDestEndRow, aSourceMark, IDF_ALL );
			//	kopieren mit bColRowFlags=sal_False (#54194#)
			pRefUndoDoc->CopyToDocument( 0, 0, 0, MAXCOL, MAXROW, MAXTAB,
											IDF_FORMULA, sal_False, pUndoDoc, NULL, sal_False );
			delete pRefUndoDoc;
		}

		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoDragDrop( &rDocShell, ScRange(
									nStartCol, nStartRow, nStartTab,
									nOldEndCol, nOldEndRow, nEndTab ),
								ScAddress( nDestCol, nDestRow, nDestTab ),
								bCut, pUndoDoc, pUndoData, bScenariosAdded ) );
	}

	SCCOL nDestPaintEndCol = nDestEndCol;
	SCROW nDestPaintEndRow = nDestEndRow;
	for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
	{
		SCCOL nTmpEndCol = nDestEndCol;
		SCROW nTmpEndRow = nDestEndRow;
		pDoc->ExtendMerge( nDestCol, nDestRow, nTmpEndCol, nTmpEndRow, nTab, sal_True );
		if (nTmpEndCol > nDestPaintEndCol) nDestPaintEndCol = nTmpEndCol;
		if (nTmpEndRow > nDestPaintEndRow) nDestPaintEndRow = nTmpEndRow;
	}

	if (bCut)
		for (nTab=nStartTab; nTab<=nEndTab; nTab++)
			pDoc->RefreshAutoFilter( nStartCol, nStartRow, nEndCol, nEndRow, nTab );

	if (bPaint)
	{
			//	Zielbereich:

		SCCOL nPaintStartX = nDestCol;
		SCROW nPaintStartY = nDestRow;
		SCCOL nPaintEndX = nDestPaintEndCol;
		SCROW nPaintEndY = nDestPaintEndRow;
		sal_uInt16 nFlags = PAINT_GRID;

		if ( nStartRow==0 && nEndRow==MAXROW )		// Breiten mitkopiert?
		{
			nPaintEndX = MAXCOL;
			nPaintStartY = 0;
			nPaintEndY = MAXROW;
			nFlags |= PAINT_TOP;
		}
		if ( bDestHeight || ( nStartCol == 0 && nEndCol == MAXCOL ) )
		{
			nPaintEndY = MAXROW;
			nPaintStartX = 0;
			nPaintEndX = MAXCOL;
			nFlags |= PAINT_LEFT;
		}
		if ( bScenariosAdded )
		{
			nPaintStartX = 0;
            nPaintStartY = 0;
			nPaintEndX = MAXCOL;
			nPaintEndY = MAXROW;
		}

		rDocShell.PostPaint( nPaintStartX,nPaintStartY,nDestTab,
							nPaintEndX,nPaintEndY,nDestEndTab, nFlags, nSourceExt | nDestExt );

		if ( bCut )
		{
				//	Quellbereich:

			nPaintStartX = nStartCol;
			nPaintStartY = nStartRow;
			nPaintEndX = nEndCol;
			nPaintEndY = nEndRow;
			nFlags = PAINT_GRID;

			if ( bSourceHeight )
			{
				nPaintEndY = MAXROW;
				nPaintStartX = 0;
				nPaintEndX = MAXCOL;
				nFlags |= PAINT_LEFT;
			}
			if ( bScenariosAdded )
			{
				nPaintStartX = 0;
                nPaintStartY = 0;
				nPaintEndX = MAXCOL;
				nPaintEndY = MAXROW;
			}

			rDocShell.PostPaint( nPaintStartX,nPaintStartY,nStartTab,
								nPaintEndX,nPaintEndY,nEndTab, nFlags, nSourceExt );
		}
	}

	aModificator.SetDocumentModified();

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

	delete pClipDoc;
	return sal_True;
}

//------------------------------------------------------------------------
uno::Reference< uno::XInterface > GetDocModuleObject( SfxObjectShell& rDocSh, String& sCodeName )
{
    uno::Reference< lang::XMultiServiceFactory> xSF(rDocSh.GetModel(), uno::UNO_QUERY);
    uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess;
    uno::Reference< uno::XInterface > xDocModuleApiObject;
    if ( xSF.is() )
    {
        xVBACodeNamedObjectAccess.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY );
        xDocModuleApiObject.set( xVBACodeNamedObjectAccess->getByName( sCodeName ), uno::UNO_QUERY );
    }
    return xDocModuleApiObject;

}

script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, String& sModule )
{
    script::ModuleInfo sModuleInfo;
    sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
    sModuleInfo.ModuleObject = GetDocModuleObject( rDocSh, sModule );
    return sModuleInfo;
}

void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sSource )
{
    SfxObjectShell& rDocSh = *rDoc.GetDocumentShell();
    uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
    DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );

    uno::Reference< container::XNameContainer > xLib;
    if( xLibContainer.is() )
    {
        String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
        if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() )
            aLibName = rDocSh.GetBasicManager()->GetName();
        uno::Any aLibAny = xLibContainer->getByName( aLibName );
        aLibAny >>= xLib;
    }
    if( xLib.is() )
    {
        // if the Module with codename exists then find a new name
        sal_Int32 nNum = 0;
        String genModuleName;
        if ( sModuleName.Len() )
            sModuleName = sModuleName;
        else
        {
             genModuleName = String::CreateFromAscii( "Sheet1" );
             nNum = 1;
        }
        while( xLib->hasByName( genModuleName  ) )
            genModuleName = rtl::OUString::createFromAscii( "Sheet" ) + rtl::OUString::valueOf( ++nNum );

        uno::Any aSourceAny;
        rtl::OUString sTmpSource = sSource;
        if ( sTmpSource.getLength() == 0 )
            sTmpSource = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" ));
        aSourceAny <<= sTmpSource;
        uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
        if ( xVBAModuleInfo.is() )
        {
            rDoc.SetCodeName( nTab, genModuleName );
            script::ModuleInfo sModuleInfo = lcl_InitModuleInfo(  rDocSh, genModuleName );
            xVBAModuleInfo->insertModuleInfo( genModuleName, sModuleInfo );
            xLib->insertByName( genModuleName, aSourceAny );
        }

    }
}

void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName )
{
    uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
    DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );

    uno::Reference< container::XNameContainer > xLib;
    if( xLibContainer.is() )
    {
        String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
        if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() )
            aLibName = rDocSh.GetBasicManager()->GetName();
        uno::Any aLibAny = xLibContainer->getByName( aLibName );
        aLibAny >>= xLib;
    }
    if( xLib.is() )
    {
        uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
        if( xLib->hasByName( sModuleName ) )
            xLib->removeByName( sModuleName );
        if ( xVBAModuleInfo.is() )
            xVBAModuleInfo->removeModuleInfo( sModuleName );

    }
}


sal_Bool ScDocFunc::InsertTable( SCTAB nTab, const String& rName, sal_Bool bRecord, sal_Bool bApi )
{
	sal_Bool bSuccess = sal_False;
	WaitObject aWait( rDocShell.GetActiveDialogParent() );

	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();


    // Strange loop, also basic is loaded too early ( InsertTable )
    // is called via the xml import for sheets in described in odf
    sal_Bool bInsertDocModule = false;

    if(  !rDocShell.GetDocument()->IsImportingXML() )
    {
        bInsertDocModule = pDoc ? pDoc->IsInVBAMode() : false;
    }
	if ( bInsertDocModule || ( bRecord && !pDoc->IsUndoEnabled() ) )
		bRecord = sal_False;

	if (bRecord)
		pDoc->BeginDrawUndo();							//	InsertTab erzeugt ein SdrUndoNewPage

	SCTAB nTabCount = pDoc->GetTableCount();
	sal_Bool bAppend = ( nTab >= nTabCount );
	if ( bAppend )
		nTab = nTabCount;		// wichtig fuer Undo

	if (pDoc->InsertTab( nTab, rName ))
	{
		String sCodeName;
		if (bRecord)
			rDocShell.GetUndoManager()->AddUndoAction(
						new ScUndoInsertTab( &rDocShell, nTab, bAppend, rName));
		//	Views updaten:
        // Only insert vba modules if vba mode ( and not currently importing XML )
        if( bInsertDocModule )
        {
            String sSource;
            VBA_InsertModule( *pDoc, nTab, sCodeName, sSource );
        }
		rDocShell.Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab ) );

		rDocShell.PostPaintExtras();
		aModificator.SetDocumentModified();
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
		bSuccess = sal_True;
	}
	else if (!bApi)
		rDocShell.ErrorMessage(STR_TABINSERT_ERROR);

	return bSuccess;
}

sal_Bool ScDocFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord, sal_Bool /* bApi */ )
{
	WaitObject aWait( rDocShell.GetActiveDialogParent() );

	ScDocShellModificator aModificator( rDocShell );

	sal_Bool bSuccess = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
    sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : false;
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
    if ( bVbaEnabled )
        bRecord = sal_False;
	sal_Bool bWasLinked = pDoc->IsLinked(nTab);
	ScDocument* pUndoDoc = NULL;
	ScRefUndoData* pUndoData = NULL;
	if (bRecord)
	{
		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		SCTAB nCount = pDoc->GetTableCount();

		pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );		// nur nTab mit Flags
		pUndoDoc->AddUndoTab( 0, nCount-1 );					// alle Tabs fuer Referenzen

		pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,sal_False, pUndoDoc );
		String aOldName;
		pDoc->GetName( nTab, aOldName );
		pUndoDoc->RenameTab( nTab, aOldName, sal_False );
		if (bWasLinked)
			pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
								pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
								pDoc->GetLinkTab(nTab),
								pDoc->GetLinkRefreshDelay(nTab) );

		if ( pDoc->IsScenario(nTab) )
		{
			pUndoDoc->SetScenario( nTab, sal_True );
			String aComment;
			Color  aColor;
			sal_uInt16 nScenFlags;
			pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
			pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
			sal_Bool bActive = pDoc->IsActiveScenario( nTab );
			pUndoDoc->SetActiveScenario( nTab, bActive );
		}
		pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
        pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
        pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );

		//	Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
		pDoc->BeginDrawUndo();							//	DeleteTab erzeugt ein SdrUndoDelPage

		pUndoData = new ScRefUndoData( pDoc );
	}

    String sCodeName;
    sal_Bool bHasCodeName = pDoc->GetCodeName( nTab, sCodeName );
	if (pDoc->DeleteTab( nTab, pUndoDoc ))
	{
		if (bRecord)
		{
			SvShorts theTabs;
			theTabs.push_back(nTab);
			rDocShell.GetUndoManager()->AddUndoAction(
						new ScUndoDeleteTab( &rDocShell, theTabs, pUndoDoc, pUndoData ));
		}
		//	Views updaten:
        if( bVbaEnabled )
        {
            if( bHasCodeName )
            {
                VBA_DeleteModule( rDocShell, sCodeName );
            }
        }
		rDocShell.Broadcast( ScTablesHint( SC_TAB_DELETED, nTab ) );

		if (bWasLinked)
		{
			rDocShell.UpdateLinks();				// Link-Manager updaten
			SfxBindings* pBindings = rDocShell.GetViewBindings();
			if (pBindings)
				pBindings->Invalidate(SID_LINKS);
		}

		rDocShell.PostPaintExtras();
		aModificator.SetDocumentModified();

        SfxApplication* pSfxApp = SFX_APP();                                // Navigator
        pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
        pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
        pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );

		bSuccess = sal_True;
	}
	else
	{
		delete pUndoDoc;
		delete pUndoData;
	}
	return bSuccess;
}

sal_Bool ScDocFunc::SetTableVisible( SCTAB nTab, sal_Bool bVisible, sal_Bool bApi )
{
	ScDocument* pDoc = rDocShell.GetDocument();
	sal_Bool bUndo(pDoc->IsUndoEnabled());
	if ( pDoc->IsVisible( nTab ) == bVisible )
		return sal_True;								// nichts zu tun - ok

	if ( !pDoc->IsDocEditable() )
	{
		if (!bApi)
			rDocShell.ErrorMessage(STR_PROTECTIONERR);
		return sal_False;
	}

	ScDocShellModificator aModificator( rDocShell );

	if ( !bVisible && !pDoc->IsImportingXML() )     // #i57869# allow hiding in any order for loading
	{
		//	nicht alle Tabellen ausblenden

		sal_uInt16 nVisCount = 0;
		SCTAB nCount = pDoc->GetTableCount();
		for (SCTAB i=0; i<nCount; i++)
			if (pDoc->IsVisible(i))
				++nVisCount;

		if (nVisCount <= 1)
		{
			if (!bApi)
				rDocShell.ErrorMessage(STR_PROTECTIONERR);	//!	eigene Meldung?
			return sal_False;
		}
	}

	pDoc->SetVisible( nTab, bVisible );
	if (bUndo)
		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( &rDocShell, nTab, bVisible ) );

	//	Views updaten:
	if (!bVisible)
		rDocShell.Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );

	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
	rDocShell.PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
	aModificator.SetDocumentModified();

	return sal_True;
}

sal_Bool ScDocFunc::SetLayoutRTL( SCTAB nTab, sal_Bool bRTL, sal_Bool /* bApi */ )
{
	ScDocument* pDoc = rDocShell.GetDocument();
	sal_Bool bUndo(pDoc->IsUndoEnabled());
	if ( pDoc->IsLayoutRTL( nTab ) == bRTL )
		return sal_True;								// nothing to do - ok

	//!	protection (sheet or document?)

	ScDocShellModificator aModificator( rDocShell );

	pDoc->SetLayoutRTL( nTab, bRTL );

	if (bUndo)
	{
		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoLayoutRTL( &rDocShell, nTab, bRTL ) );
	}

	rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
	aModificator.SetDocumentModified();

	SfxBindings* pBindings = rDocShell.GetViewBindings();
	if (pBindings)
	{
		pBindings->Invalidate( FID_TAB_RTL );
		pBindings->Invalidate( SID_ATTR_SIZE );
	}

	return sal_True;
}

//UNUSED2009-05 sal_Bool ScDocFunc::SetGrammar( formula::FormulaGrammar::Grammar eGrammar )
//UNUSED2009-05 {
//UNUSED2009-05     ScDocument* pDoc = rDocShell.GetDocument();
//UNUSED2009-05
//UNUSED2009-05     if ( pDoc->GetGrammar() == eGrammar )
//UNUSED2009-05         return sal_True;
//UNUSED2009-05
//UNUSED2009-05     sal_Bool bUndo(pDoc->IsUndoEnabled());
//UNUSED2009-05     ScDocShellModificator aModificator( rDocShell );
//UNUSED2009-05
//UNUSED2009-05     pDoc->SetGrammar( eGrammar );
//UNUSED2009-05
//UNUSED2009-05     if (bUndo)
//UNUSED2009-05     {
//UNUSED2009-05         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoSetGrammar( &rDocShell, eGrammar ) );
//UNUSED2009-05     }
//UNUSED2009-05
//UNUSED2009-05     rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
//UNUSED2009-05
//UNUSED2009-05     ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
//UNUSED2009-05     if (NULL != pViewSh)
//UNUSED2009-05     {
//UNUSED2009-05         pViewSh->UpdateInputHandler( sal_False, sal_False );
//UNUSED2009-05     }
//UNUSED2009-05
//UNUSED2009-05     aModificator.SetDocumentModified();
//UNUSED2009-05
//UNUSED2009-05     SfxBindings* pBindings = rDocShell.GetViewBindings();
//UNUSED2009-05     if (pBindings)
//UNUSED2009-05     {
//UNUSED2009-05         // erAck: 2006-09-07T22:19+0200  commented out in CWS scr1c1
//UNUSED2009-05         //pBindings->Invalidate( FID_TAB_USE_R1C1 );
//UNUSED2009-05     }
//UNUSED2009-05
//UNUSED2009-05     return sal_True;
//UNUSED2009-05 }

sal_Bool ScDocFunc::RenameTable( SCTAB nTab, const String& rName, sal_Bool bRecord, sal_Bool bApi )
{
	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	if ( !pDoc->IsDocEditable() )
	{
		if (!bApi)
			rDocShell.ErrorMessage(STR_PROTECTIONERR);
		return sal_False;
	}

	ScDocShellModificator aModificator( rDocShell );

	sal_Bool bSuccess = sal_False;
	String sOldName;
	pDoc->GetName(nTab, sOldName);
	if (pDoc->RenameTab( nTab, rName ))
	{
		if (bRecord)
		{
			rDocShell.GetUndoManager()->AddUndoAction(
							new ScUndoRenameTab( &rDocShell, nTab, sOldName, rName));
		}
		rDocShell.PostPaintExtras();
		aModificator.SetDocumentModified();
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );

		bSuccess = sal_True;
	}
	return bSuccess;
}

bool ScDocFunc::SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi )
{

    ScDocument* pDoc = rDocShell.GetDocument();
    if (bRecord && !pDoc->IsUndoEnabled())
        bRecord = false;
    if ( !pDoc->IsDocEditable() || pDoc->IsTabProtected(nTab) )
    {
        if (!bApi)
            rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Check to see what this string is...
        return false;
    }

    Color aOldTabBgColor;
    aOldTabBgColor = pDoc->GetTabBgColor(nTab);

    bool bSuccess = false;
    pDoc->SetTabBgColor(nTab, rColor);
    if ( pDoc->GetTabBgColor(nTab) == rColor)
        bSuccess = true;
    if (bSuccess)
    {
        if (bRecord)
        {
            rDocShell.GetUndoManager()->AddUndoAction(
                new ScUndoTabColor( &rDocShell, nTab, aOldTabBgColor, rColor));
        }
        rDocShell.PostPaintExtras();
        ScDocShellModificator aModificator( rDocShell );
        aModificator.SetDocumentModified();
        SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );

        bSuccess = true;
    }
    return bSuccess;
}

bool ScDocFunc::SetTabBgColor(
    ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi )
{
    ScDocument* pDoc = rDocShell.GetDocument();
    if (bRecord && !pDoc->IsUndoEnabled())
        bRecord = false;

    if ( !pDoc->IsDocEditable() )
    {
        if (!bApi)
            rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
        return false;
    }

    sal_uInt16 nTab;
    Color aNewTabBgColor;
    bool bSuccess = true;
    size_t nTabProtectCount = 0;
    size_t nTabListCount = rUndoTabColorList.size();
    for ( size_t i = 0; i < nTabListCount; ++i )
    {
        ScUndoTabColorInfo& rInfo = rUndoTabColorList[i];
        nTab = rInfo.mnTabId;
        if ( !pDoc->IsTabProtected(nTab) )
        {
            aNewTabBgColor = rInfo.maNewTabBgColor;
            rInfo.maOldTabBgColor = pDoc->GetTabBgColor(nTab);
            pDoc->SetTabBgColor(nTab, aNewTabBgColor);
            if ( pDoc->GetTabBgColor(nTab) != aNewTabBgColor)
            {
                bSuccess = false;
                break;
            }
        }
        else
        {
            nTabProtectCount++;
        }
    }

    if ( nTabProtectCount == nTabListCount )
    {
        if (!bApi)
            rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
        return false;
    }

    if (bSuccess)
    {
        if (bRecord)
        {
            rDocShell.GetUndoManager()->AddUndoAction(
                new ScUndoTabColor( &rDocShell, rUndoTabColorList));
        }
        rDocShell.PostPaintExtras();
        ScDocShellModificator aModificator( rDocShell );
        aModificator.SetDocumentModified();
    }
    return bSuccess;
}

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

//!	SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!!
//!	Probleme:
//!	- Optimale Hoehe fuer Edit-Zellen ist unterschiedlich zwischen Drucker und Bildschirm
//!	- Optimale Breite braucht Selektion, um evtl. nur selektierte Zellen zu beruecksichtigen

sal_uInt16 lcl_GetOptimalColWidth( ScDocShell& rDocShell, SCCOL nCol, SCTAB nTab, sal_Bool bFormula )
{
	sal_uInt16 nTwips = 0;

	ScSizeDeviceProvider aProv(&rDocShell);
	OutputDevice* pDev = aProv.GetDevice();			// has pixel MapMode
	double nPPTX = aProv.GetPPTX();
	double nPPTY = aProv.GetPPTY();

	ScDocument* pDoc = rDocShell.GetDocument();
	Fraction aOne(1,1);
	nTwips = pDoc->GetOptimalColWidth( nCol, nTab, pDev, nPPTX, nPPTY, aOne, aOne,
										bFormula, NULL );

	return nTwips;
}

sal_Bool ScDocFunc::SetWidthOrHeight( sal_Bool bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges, SCTAB nTab,
										ScSizeMode eMode, sal_uInt16 nSizeTwips,
										sal_Bool bRecord, sal_Bool bApi )
{
    ScDocShellModificator aModificator( rDocShell );

	if (!nRangeCnt)
		return sal_True;

	ScDocument* pDoc = rDocShell.GetDocument();
	if ( bRecord && !pDoc->IsUndoEnabled() )
		bRecord = sal_False;

    // import into read-only document is possible
    if ( !pDoc->IsChangeReadOnlyEnabled() && !rDocShell.IsEditable() )
	{
		if (!bApi)
			rDocShell.ErrorMessage(STR_PROTECTIONERR);		//! eigene Meldung?
		return sal_False;
	}

	sal_Bool bSuccess = sal_False;
	SCCOLROW nStart = pRanges[0];
	SCCOLROW nEnd = pRanges[2*nRangeCnt-1];

	sal_Bool bFormula = sal_False;
	if ( eMode == SC_SIZE_OPTIMAL )
	{
		//!	Option "Formeln anzeigen" - woher nehmen?
	}

	ScDocument* 	pUndoDoc = NULL;
	ScOutlineTable* pUndoTab = NULL;
	SCCOLROW*		pUndoRanges = NULL;

	if ( bRecord )
	{
		pDoc->BeginDrawUndo();							// Drawing Updates

		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		if (bWidth)
		{
			pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
			pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab, static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
		}
		else
		{
			pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
			pDoc->CopyToDocument( 0, static_cast<SCROW>(nStart), nTab, MAXCOL, static_cast<SCROW>(nEnd), nTab, IDF_NONE, sal_False, pUndoDoc );
		}

		pUndoRanges = new SCCOLROW[ 2*nRangeCnt ];
		memmove( pUndoRanges, pRanges, 2*nRangeCnt*sizeof(SCCOLROW) );

		ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
		if (pTable)
			pUndoTab = new ScOutlineTable( *pTable );
	}

	sal_Bool bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT;
	sal_Bool bOutline = sal_False;

	pDoc->IncSizeRecalcLevel( nTab );		// nicht fuer jede Spalte einzeln
	for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
	{
		SCCOLROW nStartNo = *(pRanges++);
		SCCOLROW nEndNo = *(pRanges++);

		if ( !bWidth )						// Hoehen immer blockweise
		{
			if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
			{
				sal_Bool bAll = ( eMode==SC_SIZE_OPTIMAL );
				if (!bAll)
				{
					//	fuer alle eingeblendeten CR_MANUALSIZE loeschen,
					//	dann SetOptimalHeight mit bShrink = FALSE
					for (SCROW nRow=nStartNo; nRow<=nEndNo; nRow++)
					{
						sal_uInt8 nOld = pDoc->GetRowFlags(nRow,nTab);
						SCROW nLastRow = -1;
						bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow);
						if ( !bHidden && ( nOld & CR_MANUALSIZE ) )
							pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE );
					}
				}

				ScSizeDeviceProvider aProv( &rDocShell );
				Fraction aOne(1,1);
				pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
										aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, bAll );

				if (bAll)
					pDoc->ShowRows( nStartNo, nEndNo, nTab, sal_True );

				//	Manual-Flag wird bei bAll=sal_True schon in SetOptimalHeight gesetzt
				//	(an bei Extra-Height, sonst aus).
			}
			else if ( eMode==SC_SIZE_DIRECT || eMode==SC_SIZE_ORIGINAL )
			{
				if (nSizeTwips)
				{
					pDoc->SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
					pDoc->SetManualHeight( nStartNo, nEndNo, nTab, sal_True );			// height was set manually
				}
				if ( eMode != SC_SIZE_ORIGINAL )
					pDoc->ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 );
			}
			else if ( eMode==SC_SIZE_SHOW )
			{
				pDoc->ShowRows( nStartNo, nEndNo, nTab, sal_True );
			}
		}
		else								// Spaltenbreiten
		{
			for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++)
			{
                SCCOL nLastCol = -1;
                if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab, nLastCol) )
				{
					sal_uInt16 nThisSize = nSizeTwips;

					if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
						nThisSize = nSizeTwips +
									lcl_GetOptimalColWidth( rDocShell, nCol, nTab, bFormula );
					if ( nThisSize )
						pDoc->SetColWidth( nCol, nTab, nThisSize );

					if ( eMode != SC_SIZE_ORIGINAL )
						pDoc->ShowCol( nCol, nTab, bShow );
				}
			}
		}

							//	adjust outlines

		if ( eMode != SC_SIZE_ORIGINAL )
		{
			if (bWidth)
                bOutline = bOutline || pDoc->UpdateOutlineCol(
                        static_cast<SCCOL>(nStartNo),
                        static_cast<SCCOL>(nEndNo), nTab, bShow );
			else
                bOutline = bOutline || pDoc->UpdateOutlineRow(
                        static_cast<SCROW>(nStartNo),
                        static_cast<SCROW>(nEndNo), nTab, bShow );
		}
	}
	pDoc->DecSizeRecalcLevel( nTab );		// nicht fuer jede Spalte einzeln

	if (!bOutline)
		DELETEZ(pUndoTab);

	if (bRecord)
	{
		ScMarkData aMark;
		aMark.SelectOneTable( nTab );
		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoWidthOrHeight( &rDocShell, aMark,
									 nStart, nTab, nEnd, nTab,
									 pUndoDoc, nRangeCnt, pUndoRanges,
									 pUndoTab, eMode, nSizeTwips, bWidth ) );
	}

	pDoc->UpdatePageBreaks( nTab );

	rDocShell.PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_ALL);
    aModificator.SetDocumentModified();

	return bSuccess;
}


sal_Bool ScDocFunc::InsertPageBreak( sal_Bool bColumn, const ScAddress& rPos,
                                sal_Bool bRecord, sal_Bool bSetModified, sal_Bool /* bApi */ )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	SCTAB nTab = rPos.Tab();
	SfxBindings* pBindings = rDocShell.GetViewBindings();

    SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
        static_cast<SCCOLROW>(rPos.Row());
	if (nPos == 0)
		return sal_False;					// erste Spalte / Zeile

    ScBreakType nBreak = bColumn ?
        pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab) :
        pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
    if (nBreak & BREAK_MANUAL)
        return true;

	if (bRecord)
		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, sal_True ) );

    if (bColumn)
        pDoc->SetColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
    else
        pDoc->SetRowBreak(static_cast<SCROW>(nPos), nTab, false, true);

    pDoc->InvalidatePageBreaks(nTab);
	pDoc->UpdatePageBreaks( nTab );

    if (pDoc->IsStreamValid(nTab))
        pDoc->SetStreamValid(nTab, sal_False);

	if (bColumn)
	{
		rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
		if (pBindings)
		{
			pBindings->Invalidate( FID_INS_COLBRK );
			pBindings->Invalidate( FID_DEL_COLBRK );
		}
	}
	else
	{
		rDocShell.PostPaint( 0, static_cast<SCROW>(nPos)-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
		if (pBindings)
		{
			pBindings->Invalidate( FID_INS_ROWBRK );
			pBindings->Invalidate( FID_DEL_ROWBRK );
		}
	}
	if (pBindings)
		pBindings->Invalidate( FID_DEL_MANUALBREAKS );

	if (bSetModified)
		aModificator.SetDocumentModified();

	return sal_True;
}

sal_Bool ScDocFunc::RemovePageBreak( sal_Bool bColumn, const ScAddress& rPos,
                                sal_Bool bRecord, sal_Bool bSetModified, sal_Bool /* bApi */ )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	SCTAB nTab = rPos.Tab();
	SfxBindings* pBindings = rDocShell.GetViewBindings();

    SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
        static_cast<SCCOLROW>(rPos.Row());

    ScBreakType nBreak;
    if (bColumn)
        nBreak = pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab);
    else
        nBreak = pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
    if ((nBreak & BREAK_MANUAL) == 0)
        // There is no manual break.
        return false;

	if (bRecord)
		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, sal_False ) );

    if (bColumn)
        pDoc->RemoveColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
    else
        pDoc->RemoveRowBreak(static_cast<SCROW>(nPos), nTab, false, true);

	pDoc->UpdatePageBreaks( nTab );

    if (pDoc->IsStreamValid(nTab))
        pDoc->SetStreamValid(nTab, sal_False);

	if (bColumn)
	{
		rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
		if (pBindings)
		{
			pBindings->Invalidate( FID_INS_COLBRK );
			pBindings->Invalidate( FID_DEL_COLBRK );
		}
	}
	else
	{
		rDocShell.PostPaint( 0, nPos-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
		if (pBindings)
		{
			pBindings->Invalidate( FID_INS_ROWBRK );
			pBindings->Invalidate( FID_DEL_ROWBRK );
		}
	}
	if (pBindings)
		pBindings->Invalidate( FID_DEL_MANUALBREAKS );

	if (bSetModified)
		aModificator.SetDocumentModified();

	return sal_True;
}

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

void ScDocFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
{
    ScDocument* pDoc = rDocShell.GetDocument();

    pDoc->SetTabProtection(nTab, &rProtect);
    if (pDoc->IsUndoEnabled())
    {
        ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
        DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
        if (pProtect)
        {
            ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
            p->setProtected(true); // just in case ...
            rDocShell.GetUndoManager()->AddUndoAction(
                new ScUndoTabProtect(&rDocShell, nTab, p) );

            // ownership of auto_ptr now transferred to ScUndoTabProtect.
        }
    }

    rDocShell.PostPaintGridAll();
    ScDocShellModificator aModificator(rDocShell);
    aModificator.SetDocumentModified();
}

sal_Bool ScDocFunc::Protect( SCTAB nTab, const String& rPassword, sal_Bool /*bApi*/ )
{
    ScDocument* pDoc = rDocShell.GetDocument();
    if (nTab == TABLEID_DOC)
    {
        // document protection
        ScDocProtection aProtection;
        aProtection.setProtected(true);
        aProtection.setPassword(rPassword);
        pDoc->SetDocProtection(&aProtection);
        if (pDoc->IsUndoEnabled())
        {
            ScDocProtection* pProtect = pDoc->GetDocProtection();
            DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScDocProtection pointer is NULL!");
            if (pProtect)
            {
                ::std::auto_ptr<ScDocProtection> p(new ScDocProtection(*pProtect));
                p->setProtected(true); // just in case ...
                rDocShell.GetUndoManager()->AddUndoAction(
                    new ScUndoDocProtect(&rDocShell, p) );
                // ownership of auto_ptr is transferred to ScUndoDocProtect.
            }
        }
    }
    else
    {
        // sheet protection

        ScTableProtection aProtection;
        aProtection.setProtected(true);
        aProtection.setPassword(rPassword);
        pDoc->SetTabProtection(nTab, &aProtection);
        if (pDoc->IsUndoEnabled())
        {
            ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
            DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
            if (pProtect)
            {
                ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
                p->setProtected(true); // just in case ...
                rDocShell.GetUndoManager()->AddUndoAction(
                    new ScUndoTabProtect(&rDocShell, nTab, p) );
                // ownership of auto_ptr now transferred to ScUndoTabProtect.
            }
        }
    }

    rDocShell.PostPaintGridAll();
    ScDocShellModificator aModificator( rDocShell );
    aModificator.SetDocumentModified();

    return true;
}

sal_Bool ScDocFunc::Unprotect( SCTAB nTab, const String& rPassword, sal_Bool bApi )
{
    ScDocument* pDoc = rDocShell.GetDocument();

    if (nTab == TABLEID_DOC)
    {
        // document protection

        ScDocProtection* pDocProtect = pDoc->GetDocProtection();
        if (!pDocProtect || !pDocProtect->isProtected())
            // already unprotected (should not happen)!
            return true;

        // save the protection state before unprotect (for undo).
        ::std::auto_ptr<ScDocProtection> pProtectCopy(new ScDocProtection(*pDocProtect));

        if (!pDocProtect->verifyPassword(rPassword))
        {
            if (!bApi)
            {
                InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
                aBox.Execute();
            }
            return false;
        }

        pDoc->SetDocProtection(NULL);
        if (pDoc->IsUndoEnabled())
        {
            pProtectCopy->setProtected(false);
            rDocShell.GetUndoManager()->AddUndoAction(
                new ScUndoDocProtect(&rDocShell, pProtectCopy) );
            // ownership of auto_ptr now transferred to ScUndoDocProtect.
        }
    }
    else
    {
        // sheet protection

        ScTableProtection* pTabProtect = pDoc->GetTabProtection(nTab);
        if (!pTabProtect || !pTabProtect->isProtected())
            // already unprotected (should not happen)!
            return true;

        // save the protection state before unprotect (for undo).
        ::std::auto_ptr<ScTableProtection> pProtectCopy(new ScTableProtection(*pTabProtect));
        if (!pTabProtect->verifyPassword(rPassword))
        {
            if (!bApi)
            {
                InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
                aBox.Execute();
            }
            return false;
        }

        pDoc->SetTabProtection(nTab, NULL);
        if (pDoc->IsUndoEnabled())
        {
            pProtectCopy->setProtected(false);
            rDocShell.GetUndoManager()->AddUndoAction(
                new ScUndoTabProtect(&rDocShell, nTab, pProtectCopy) );
            // ownership of auto_ptr now transferred to ScUndoTabProtect.
        }
    }

    rDocShell.PostPaintGridAll();
    ScDocShellModificator aModificator( rDocShell );
    aModificator.SetDocumentModified();

    return true;
}

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

sal_Bool ScDocFunc::ClearItems( const ScMarkData& rMark, const sal_uInt16* pWhich, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	sal_Bool bUndo (pDoc->IsUndoEnabled());
	ScEditableTester aTester( pDoc, rMark );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	//	#i12940# ClearItems is called (from setPropertyToDefault) directly with uno object's cached
	//	MarkData (GetMarkData), so rMark must be changed to multi selection for ClearSelectionItems
	//	here.

	ScRange aMarkRange;
	ScMarkData aMultiMark = rMark;
	aMultiMark.SetMarking(sal_False);		// for MarkToMulti
	aMultiMark.MarkToMulti();
	aMultiMark.GetMultiMarkArea( aMarkRange );

//	if (bRecord)
	if (bUndo)
	{
		SCTAB nStartTab = aMarkRange.aStart.Tab();
		SCTAB nEndTab = aMarkRange.aEnd.Tab();

		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
		pDoc->CopyToDocument( aMarkRange, IDF_ATTRIB, sal_True, pUndoDoc, (ScMarkData*)&aMultiMark );

		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoClearItems( &rDocShell, aMultiMark, pUndoDoc, pWhich ) );
	}

	pDoc->ClearSelectionItems( pWhich, aMultiMark );

	rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
	aModificator.SetDocumentModified();

	//!	Bindings-Invalidate etc.?

	return sal_True;
}

sal_Bool ScDocFunc::ChangeIndent( const ScMarkData& rMark, sal_Bool bIncrement, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	sal_Bool bUndo(pDoc->IsUndoEnabled());
	ScEditableTester aTester( pDoc, rMark );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	ScRange aMarkRange;
	rMark.GetMultiMarkArea( aMarkRange );

//	if (bRecord)
	if (bUndo)
	{
		SCTAB nStartTab = aMarkRange.aStart.Tab();
		SCTAB nTabCount = pDoc->GetTableCount();

		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
		for (SCTAB i=0; i<nTabCount; i++)
			if (i != nStartTab && rMark.GetTableSelect(i))
				pUndoDoc->AddUndoTab( i, i );

		ScRange aCopyRange = aMarkRange;
		aCopyRange.aStart.SetTab(0);
		aCopyRange.aEnd.SetTab(nTabCount-1);
		pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_True, pUndoDoc, (ScMarkData*)&rMark );

		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoIndent( &rDocShell, rMark, pUndoDoc, bIncrement ) );
	}

	pDoc->ChangeSelectionIndent( bIncrement, rMark );

	rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
	aModificator.SetDocumentModified();

	SfxBindings* pBindings = rDocShell.GetViewBindings();
	if (pBindings)
	{
		pBindings->Invalidate( SID_ALIGNLEFT );			// ChangeIndent setzt auf links
		pBindings->Invalidate( SID_ALIGNRIGHT );
		pBindings->Invalidate( SID_ALIGNBLOCK );
		pBindings->Invalidate( SID_ALIGNCENTERHOR );
		pBindings->Invalidate( SID_ATTR_LRSPACE );
		pBindings->Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
		pBindings->Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
		pBindings->Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
		pBindings->Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
        // pseudo slots for Format menu
        pBindings->Invalidate( SID_ALIGN_ANY_HDEFAULT );
        pBindings->Invalidate( SID_ALIGN_ANY_LEFT );
        pBindings->Invalidate( SID_ALIGN_ANY_HCENTER );
        pBindings->Invalidate( SID_ALIGN_ANY_RIGHT );
        pBindings->Invalidate( SID_ALIGN_ANY_JUSTIFIED );
	}

	return sal_True;
}

sal_Bool ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
							sal_uInt16 nFormatNo, sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	sal_Bool bSuccess = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCTAB nStartTab = rRange.aStart.Tab();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nEndTab = rRange.aEnd.Tab();

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	ScMarkData aMark;
	if (pTabMark)
		aMark = *pTabMark;
	else
	{
		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
			aMark.SelectTable( nTab, sal_True );
	}

	ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat();
	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
	if ( pAutoFormat && nFormatNo < pAutoFormat->GetCount() && aTester.IsEditable() )
	{
		WaitObject aWait( rDocShell.GetActiveDialogParent() );

		sal_Bool bSize = (*pAutoFormat)[nFormatNo]->GetIncludeWidthHeight();

		SCTAB nTabCount = pDoc->GetTableCount();
		ScDocument* pUndoDoc = NULL;
		if ( bRecord )
		{
			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab, bSize, bSize );
			for (SCTAB i=0; i<nTabCount; i++)
				if (i != nStartTab && aMark.GetTableSelect(i))
					pUndoDoc->AddUndoTab( i, i, bSize, bSize );

			ScRange aCopyRange = rRange;
			aCopyRange.aStart.SetTab(0);
			aCopyRange.aStart.SetTab(nTabCount-1);
			pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_False, pUndoDoc, &aMark );
			if (bSize)
			{
				pDoc->CopyToDocument( nStartCol,0,0, nEndCol,MAXROW,nTabCount-1,
															IDF_NONE, sal_False, pUndoDoc, &aMark );
				pDoc->CopyToDocument( 0,nStartRow,0, MAXCOL,nEndRow,nTabCount-1,
															IDF_NONE, sal_False, pUndoDoc, &aMark );
			}
			pDoc->BeginDrawUndo();
		}

		pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, aMark );

		if (bSize)
		{
/*			SCCOL nCols[2];
			nCols[0] = nStartCol;
			nCols[1] = nEndCol;
			SCROW nRows[2];
			nRows[0] = nStartRow;
			nRows[1] = nEndRow;
*/
			SCCOLROW nCols[2] = { nStartCol, nEndCol };
			SCCOLROW nRows[2] = { nStartRow, nEndRow };

			for (SCTAB nTab=0; nTab<nTabCount; nTab++)
				if (aMark.GetTableSelect(nTab))
				{
                    SetWidthOrHeight( sal_True, 1,nCols, nTab, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, sal_False, sal_True);
                    SetWidthOrHeight( sal_False,1,nRows, nTab, SC_SIZE_VISOPT, 0, sal_False, sal_False);
					rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
									PAINT_GRID | PAINT_LEFT | PAINT_TOP );
				}
		}
		else
		{
			for (SCTAB nTab=0; nTab<nTabCount; nTab++)
				if (aMark.GetTableSelect(nTab))
				{
					sal_Bool bAdj = AdjustRowHeight( ScRange(nStartCol, nStartRow, nTab,
														nEndCol, nEndRow, nTab), sal_False );
					if (bAdj)
						rDocShell.PostPaint( 0,nStartRow,nTab, MAXCOL,MAXROW,nTab,
											PAINT_GRID | PAINT_LEFT );
					else
						rDocShell.PostPaint( nStartCol, nStartRow, nTab,
											nEndCol, nEndRow, nTab, PAINT_GRID );
				}
		}

		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
		{
			rDocShell.GetUndoManager()->AddUndoAction(
				new ScUndoAutoFormat( &rDocShell, rRange, pUndoDoc, aMark, bSize, nFormatNo ) );
		}

		aModificator.SetDocumentModified();
	}
	else if (!bApi)
		rDocShell.ErrorMessage(aTester.GetMessageId());

	return bSuccess;
}

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

sal_Bool ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
        const ScTokenArray* pTokenArray, const String& rString, sal_Bool bApi, sal_Bool bEnglish,
        const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
{
	ScDocShellModificator aModificator( rDocShell );

	sal_Bool bSuccess = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCTAB nStartTab = rRange.aStart.Tab();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nEndTab = rRange.aEnd.Tab();

	sal_Bool bUndo(pDoc->IsUndoEnabled());

	ScMarkData aMark;
	if (pTabMark)
		aMark = *pTabMark;
	else
	{
		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
			aMark.SelectTable( nTab, sal_True );
	}

	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
	if ( aTester.IsEditable() )
	{
		WaitObject aWait( rDocShell.GetActiveDialogParent() );

        ScDocument* pUndoDoc = NULL;
//		if (bRecord)	// immer
		if (bUndo)
		{
			//!	auch bei Undo selektierte Tabellen beruecksichtigen
			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
            pDoc->CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, sal_False, pUndoDoc );
		}

        // use TokenArray if given, string (and flags) otherwise
        if ( pTokenArray )
        {
            pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
                    aMark, EMPTY_STRING, pTokenArray, eGrammar);
        }
        else if ( pDoc->IsImportingXML() )
		{
            ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString, rFormulaNmsp, eGrammar );
            pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
                    aMark, EMPTY_STRING, pCode, eGrammar);
			delete pCode;
            pDoc->IncXMLImportedFormulaCount( rString.Len() );
		}
		else if (bEnglish)
        {
			ScCompiler aComp( pDoc, rRange.aStart);
            aComp.SetGrammar(eGrammar);
			ScTokenArray* pCode = aComp.CompileString( rString );
            pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
                    aMark, EMPTY_STRING, pCode, eGrammar);
			delete pCode;
        }
        else
            pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
                    aMark, rString, NULL, eGrammar);

//		if (bRecord)	// immer
		if (bUndo)
		{
			//!	auch bei Undo selektierte Tabellen beruecksichtigen
			rDocShell.GetUndoManager()->AddUndoAction(
				new ScUndoEnterMatrix( &rDocShell, rRange, pUndoDoc, rString ) );
		}

		//	Err522 beim Paint von DDE-Formeln werden jetzt beim Interpretieren abgefangen
		rDocShell.PostPaint( nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab, PAINT_GRID );
		aModificator.SetDocumentModified();

		bSuccess = sal_True;
	}
	else if (!bApi)
		rDocShell.ErrorMessage(aTester.GetMessageId());

	return bSuccess;
}

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

sal_Bool ScDocFunc::TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
							const ScTabOpParam& rParam, sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	sal_Bool bSuccess = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCTAB nStartTab = rRange.aStart.Tab();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nEndTab = rRange.aEnd.Tab();

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScMarkData aMark;
	if (pTabMark)
		aMark = *pTabMark;
	else
	{
		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
			aMark.SelectTable( nTab, sal_True );
	}

	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
	if ( aTester.IsEditable() )
	{
		WaitObject aWait( rDocShell.GetActiveDialogParent() );
		pDoc->SetDirty( rRange );
		if ( bRecord )
		{
			//!	auch bei Undo selektierte Tabellen beruecksichtigen
			ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
            pDoc->CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, sal_False, pUndoDoc );

			rDocShell.GetUndoManager()->AddUndoAction(
					new ScUndoTabOp( &rDocShell,
									 nStartCol, nStartRow, nStartTab,
									 nEndCol, nEndRow, nEndTab, pUndoDoc,
									 rParam.aRefFormulaCell,
									 rParam.aRefFormulaEnd,
									 rParam.aRefRowCell,
									 rParam.aRefColCell,
									 rParam.nMode) );
		}
		pDoc->InsertTableOp(rParam, nStartCol, nStartRow, nEndCol, nEndRow, aMark);
		rDocShell.PostPaintGridAll();
		aModificator.SetDocumentModified();
		bSuccess = sal_True;
	}
	else if (!bApi)
		rDocShell.ErrorMessage(aTester.GetMessageId());

	return bSuccess;
}

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

inline ScDirection DirFromFillDir( FillDir eDir )
{
	if (eDir==FILL_TO_BOTTOM)
		return DIR_BOTTOM;
	else if (eDir==FILL_TO_RIGHT)
		return DIR_RIGHT;
	else if (eDir==FILL_TO_TOP)
		return DIR_TOP;
	else // if (eDir==FILL_TO_LEFT)
		return DIR_LEFT;
}

sal_Bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
							FillDir eDir, sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	sal_Bool bSuccess = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCTAB nStartTab = rRange.aStart.Tab();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nEndTab = rRange.aEnd.Tab();

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScMarkData aMark;
	if (pTabMark)
		aMark = *pTabMark;
	else
	{
		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
			aMark.SelectTable( nTab, sal_True );
	}

	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
	if ( aTester.IsEditable() )
	{
		WaitObject aWait( rDocShell.GetActiveDialogParent() );

		ScRange aSourceArea = rRange;
		ScRange aDestArea   = rRange;

        SCCOLROW nCount = 0;
		switch (eDir)
		{
			case FILL_TO_BOTTOM:
				nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
				aSourceArea.aEnd.SetRow( aSourceArea.aStart.Row() );
				break;
			case FILL_TO_RIGHT:
				nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
				aSourceArea.aEnd.SetCol( aSourceArea.aStart.Col() );
				break;
			case FILL_TO_TOP:
				nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
				aSourceArea.aStart.SetRow( aSourceArea.aEnd.Row() );
				break;
			case FILL_TO_LEFT:
				nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
				aSourceArea.aStart.SetCol( aSourceArea.aEnd.Col() );
				break;
		}

		ScDocument* pUndoDoc = NULL;
		if ( bRecord )
		{
			SCTAB nTabCount = pDoc->GetTableCount();
            SCTAB nDestStartTab = aDestArea.aStart.Tab();

			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
            pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
			for (SCTAB i=0; i<nTabCount; i++)
                if (i != nDestStartTab && aMark.GetTableSelect(i))
					pUndoDoc->AddUndoTab( i, i );

			ScRange aCopyRange = aDestArea;
			aCopyRange.aStart.SetTab(0);
			aCopyRange.aEnd.SetTab(nTabCount-1);
            pDoc->CopyToDocument( aCopyRange, IDF_AUTOFILL, sal_False, pUndoDoc, &aMark );
		}

		pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
					aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
					nCount, eDir, FILL_SIMPLE );
		AdjustRowHeight(rRange);

		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
		{
			rDocShell.GetUndoManager()->AddUndoAction(
				new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
									eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307,
									pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
		}

		rDocShell.PostPaintGridAll();
//		rDocShell.PostPaintDataChanged();
		aModificator.SetDocumentModified();

		bSuccess = sal_True;
	}
	else if (!bApi)
		rDocShell.ErrorMessage(aTester.GetMessageId());

	return bSuccess;
}

sal_Bool ScDocFunc::FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
							FillDir	eDir, FillCmd eCmd, FillDateCmd	eDateCmd,
							double fStart, double fStep, double fMax,
							sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	sal_Bool bSuccess = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCTAB nStartTab = rRange.aStart.Tab();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nEndTab = rRange.aEnd.Tab();

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScMarkData aMark;
	if (pTabMark)
		aMark = *pTabMark;
	else
	{
		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
			aMark.SelectTable( nTab, sal_True );
	}

	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
	if ( aTester.IsEditable() )
	{
		WaitObject aWait( rDocShell.GetActiveDialogParent() );

		ScRange aSourceArea = rRange;
		ScRange aDestArea   = rRange;

		SCSIZE nCount = pDoc->GetEmptyLinesInBlock(
				aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aStart.Tab(),
				aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aSourceArea.aEnd.Tab(),
				DirFromFillDir(eDir) );

		//	#27665# mindestens eine Zeile/Spalte als Quellbereich behalten:
		SCSIZE nTotLines = ( eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP ) ?
            static_cast<SCSIZE>( aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1 ) :
            static_cast<SCSIZE>( aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1 );
		if ( nCount >= nTotLines )
			nCount = nTotLines - 1;

		switch (eDir)
		{
			case FILL_TO_BOTTOM:
                aSourceArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() - nCount ) );
				break;
			case FILL_TO_RIGHT:
                aSourceArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() - nCount ) );
				break;
			case FILL_TO_TOP:
                aSourceArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() + nCount ) );
				break;
			case FILL_TO_LEFT:
                aSourceArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() + nCount ) );
				break;
		}

		ScDocument* pUndoDoc = NULL;
		if ( bRecord )
		{
			SCTAB nTabCount = pDoc->GetTableCount();
            SCTAB nDestStartTab = aDestArea.aStart.Tab();

			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
            pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
			for (SCTAB i=0; i<nTabCount; i++)
                if (i != nDestStartTab && aMark.GetTableSelect(i))
					pUndoDoc->AddUndoTab( i, i );

			pDoc->CopyToDocument(
				aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
				aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
                IDF_AUTOFILL, sal_False, pUndoDoc, &aMark );
		}

		if (aDestArea.aStart.Col() <= aDestArea.aEnd.Col() &&
			aDestArea.aStart.Row() <= aDestArea.aEnd.Row())
		{
			if ( fStart != MAXDOUBLE )
			{
				SCCOL nValX = (eDir == FILL_TO_LEFT) ? aDestArea.aEnd.Col() : aDestArea.aStart.Col();
				SCROW nValY = (eDir == FILL_TO_TOP ) ? aDestArea.aEnd.Row() : aDestArea.aStart.Row();
				SCTAB nTab = aDestArea.aStart.Tab();
				pDoc->SetValue( nValX, nValY, nTab, fStart );
			}
			pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
						aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
						nCount, eDir, eCmd, eDateCmd, fStep, fMax );
			AdjustRowHeight(rRange);

			rDocShell.PostPaintGridAll();
//			rDocShell.PostPaintDataChanged();
			aModificator.SetDocumentModified();
		}

		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
		{
			rDocShell.GetUndoManager()->AddUndoAction(
				new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
									eDir, eCmd, eDateCmd, fStart, fStep, fMax,
									pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
		}

		bSuccess = sal_True;
	}
	else if (!bApi)
		rDocShell.ErrorMessage(aTester.GetMessageId());

	return bSuccess;
}

sal_Bool ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
							FillDir eDir, sal_uLong nCount, sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCTAB nStartTab = rRange.aStart.Tab();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nEndTab = rRange.aEnd.Tab();

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScMarkData aMark;
	if (pTabMark)
		aMark = *pTabMark;
	else
	{
		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
			aMark.SelectTable( nTab, sal_True );
	}

	ScRange aSourceArea = rRange;
	ScRange aDestArea   = rRange;

	FillCmd		eCmd = FILL_AUTO;
	FillDateCmd	eDateCmd = FILL_DAY;
	double		fStep = 1.0;
	double		fMax = MAXDOUBLE;

	switch (eDir)
	{
		case FILL_TO_BOTTOM:
            aDestArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() + nCount ) );
			break;
		case FILL_TO_TOP:
            if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Row() ))
			{
				DBG_ERROR("FillAuto: Row < 0");
				nCount = aSourceArea.aStart.Row();
			}
            aDestArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() - nCount ) );
			break;
		case FILL_TO_RIGHT:
            aDestArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() + nCount ) );
			break;
		case FILL_TO_LEFT:
            if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Col() ))
			{
				DBG_ERROR("FillAuto: Col < 0");
				nCount = aSourceArea.aStart.Col();
			}
            aDestArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() - nCount ) );
			break;
		default:
			DBG_ERROR("Falsche Richtung bei FillAuto");
			break;
	}

	//		Zellschutz testen
	//!		Quellbereich darf geschuetzt sein !!!
	//!		aber kein Matrixfragment enthalten !!!

	ScEditableTester aTester( pDoc, aDestArea );
	if ( !aTester.IsEditable() )
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	if ( pDoc->HasSelectedBlockMatrixFragment( nStartCol, nStartRow,
			nEndCol, nEndRow, aMark ) )
	{
		if (!bApi)
			rDocShell.ErrorMessage(STR_MATRIXFRAGMENTERR);
		return sal_False;
	}

	WaitObject aWait( rDocShell.GetActiveDialogParent() );

	ScDocument* pUndoDoc = NULL;
	if ( bRecord )
	{
		SCTAB nTabCount = pDoc->GetTableCount();
        SCTAB nDestStartTab = aDestArea.aStart.Tab();

		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
        pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
		for (SCTAB i=0; i<nTabCount; i++)
            if (i != nDestStartTab && aMark.GetTableSelect(i))
				pUndoDoc->AddUndoTab( i, i );

        // do not clone note captions in undo document
		pDoc->CopyToDocument(
			aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
			aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
            IDF_AUTOFILL, sal_False, pUndoDoc, &aMark );
	}

	pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
				aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
				nCount, eDir, eCmd, eDateCmd, fStep, fMax );

	AdjustRowHeight(aDestArea);

	if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
	{
		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
								eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax,
								pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
	}

	rDocShell.PostPaintGridAll();
//	rDocShell.PostPaintDataChanged();
	aModificator.SetDocumentModified();

	rRange = aDestArea;			// Zielbereich zurueckgeben (zum Markieren)
	return sal_True;
}

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

sal_Bool ScDocFunc::MergeCells( const ScRange& rRange, sal_Bool bContents, sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nTab = rRange.aStart.Tab();

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScEditableTester aTester( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
	if (!aTester.IsEditable())
	{
		if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	if ( nStartCol == nEndCol && nStartRow == nEndRow )
	{
		// nichts zu tun
		return sal_True;
	}

	if ( pDoc->HasAttrib( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
							HASATTR_MERGED | HASATTR_OVERLAPPED ) )
	{
		// "Zusammenfassen nicht verschachteln !"
		if (!bApi)
			rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0);
		return sal_False;
	}

	sal_Bool bNeedContents = bContents &&
			( !pDoc->IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
			  !pDoc->IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) );

    ScDocument* pUndoDoc = 0;
	if (bRecord)
	{
        // test if the range contains other notes which also implies that we need an undo document
        bool bHasNotes = false;
        for( ScAddress aPos( nStartCol, nStartRow, nTab ); !bHasNotes && (aPos.Col() <= nEndCol); aPos.IncCol() )
            for( aPos.SetRow( nStartRow ); !bHasNotes && (aPos.Row() <= nEndRow); aPos.IncRow() )
                bHasNotes = ((aPos.Col() != nStartCol) || (aPos.Row() != nStartRow)) && (pDoc->GetNote( aPos ) != 0);

		if (bNeedContents || bHasNotes)
		{
			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			pUndoDoc->InitUndo( pDoc, nTab, nTab );
            // note captions are collected by drawing undo
			pDoc->CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
                                    IDF_ALL|IDF_NOCAPTIONS, sal_False, pUndoDoc );
		}
        if( bHasNotes )
            pDoc->BeginDrawUndo();
	}

	if (bNeedContents)
		pDoc->DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
	pDoc->DoMerge( nTab, nStartCol,nStartRow, nEndCol,nEndRow );

    if( bRecord )
    {
        SdrUndoGroup* pDrawUndo = pDoc->GetDrawLayer() ? pDoc->GetDrawLayer()->GetCalcUndo() : 0;
        rDocShell.GetUndoManager()->AddUndoAction(
            new ScUndoMerge( &rDocShell,
                            nStartCol, nStartRow, nTab,
                            nEndCol, nEndRow, nTab, bNeedContents, pUndoDoc, pDrawUndo ) );
    }

	if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab ) ) )
		rDocShell.PostPaint( nStartCol, nStartRow, nTab,
											nEndCol, nEndRow, nTab, PAINT_GRID );
	if (bNeedContents)
		pDoc->SetDirty( rRange );
	aModificator.SetDocumentModified();

	SfxBindings* pBindings = rDocShell.GetViewBindings();
	if (pBindings)
	{
		pBindings->Invalidate( FID_MERGE_ON );
		pBindings->Invalidate( FID_MERGE_OFF );
        pBindings->Invalidate( FID_MERGE_TOGGLE );
	}

	return sal_True;
}

sal_Bool ScDocFunc::UnmergeCells( const ScRange& rRange, sal_Bool bRecord, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );

	ScDocument* pDoc = rDocShell.GetDocument();
	SCTAB nTab = rRange.aStart.Tab();

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	if ( pDoc->HasAttrib( rRange, HASATTR_MERGED ) )
	{
		ScRange aExtended = rRange;
		pDoc->ExtendMerge( aExtended );
		ScRange aRefresh = aExtended;
		pDoc->ExtendOverlapped( aRefresh );

		if (bRecord)
		{
			ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			pUndoDoc->InitUndo( pDoc, nTab, nTab );
			pDoc->CopyToDocument( aExtended, IDF_ATTRIB, sal_False, pUndoDoc );
			rDocShell.GetUndoManager()->AddUndoAction(
				new ScUndoRemoveMerge( &rDocShell, rRange, pUndoDoc ) );
		}

		const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
		ScPatternAttr aPattern( pDoc->GetPool() );
		aPattern.GetItemSet().Put( rDefAttr );
		pDoc->ApplyPatternAreaTab( rRange.aStart.Col(), rRange.aStart.Row(),
									rRange.aEnd.Col(), rRange.aEnd.Row(), nTab,
									aPattern );

		pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
								aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
								SC_MF_HOR | SC_MF_VER );

		pDoc->ExtendMerge( aRefresh, sal_True, sal_False );

		if ( !AdjustRowHeight( aExtended ) )
			rDocShell.PostPaint( aExtended, PAINT_GRID );
		aModificator.SetDocumentModified();
	}
	else if (!bApi)
		Sound::Beep();		//! sal_False zurueck???

	return sal_True;
}

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

sal_Bool ScDocFunc::ModifyRangeNames( const ScRangeName& rNewRanges, sal_Bool bApi )
{
    return SetNewRangeNames( new ScRangeName( rNewRanges ), bApi );
}

sal_Bool ScDocFunc::SetNewRangeNames( ScRangeName* pNewRanges, sal_Bool /* bApi */ )     // takes ownership of pNewRanges
{
	ScDocShellModificator aModificator( rDocShell );

    DBG_ASSERT( pNewRanges, "pNewRanges is 0" );
	ScDocument* pDoc = rDocShell.GetDocument();
	sal_Bool bUndo(pDoc->IsUndoEnabled());

	if (bUndo)
	{
		ScRangeName* pOld = pDoc->GetRangeName();
		ScRangeName* pUndoRanges = new ScRangeName(*pOld);
		ScRangeName* pRedoRanges = new ScRangeName(*pNewRanges);
		rDocShell.GetUndoManager()->AddUndoAction(
			new ScUndoRangeNames( &rDocShell, pUndoRanges, pRedoRanges ) );
	}

    // #i55926# While loading XML, formula cells only have a single string token,
    // so CompileNameFormula would never find any name (index) tokens, and would
    // unnecessarily loop through all cells.
    sal_Bool bCompile = ( !pDoc->IsImportingXML() && pDoc->GetNamedRangesLockCount() == 0 );

    if ( bCompile )
        pDoc->CompileNameFormula( sal_True );	// CreateFormulaString
    pDoc->SetRangeName( pNewRanges );       // takes ownership
    if ( bCompile )
        pDoc->CompileNameFormula( sal_False );	// CompileFormulaString

	aModificator.SetDocumentModified();

    // #i114072# don't broadcast while loading a file
    // (navigator and input line for other open documents would be notified)
    if ( bCompile )
        SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );

	return sal_True;
}

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

void ScDocFunc::CreateOneName( ScRangeName& rList,
								SCCOL nPosX, SCROW nPosY, SCTAB nTab,
								SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
								sal_Bool& rCancel, sal_Bool bApi )
{
	if (rCancel)
		return;

	ScDocument* pDoc = rDocShell.GetDocument();
	if (!pDoc->HasValueData( nPosX, nPosY, nTab ))
	{
		String aName;
		pDoc->GetString( nPosX, nPosY, nTab, aName );
		ScRangeData::MakeValidName(aName);
		if (aName.Len())
		{
			String aContent;
            ScRange( nX1, nY1, nTab, nX2, nY2, nTab ).Format( aContent, SCR_ABS_3D, pDoc );

			sal_Bool bInsert = sal_False;
			sal_uInt16 nOldPos;
			if (rList.SearchName( aName, nOldPos ))			// vorhanden ?
			{
				ScRangeData* pOld = rList[nOldPos];
				String aOldStr;
				pOld->GetSymbol( aOldStr );
				if (aOldStr != aContent)
				{
					if (bApi)
						bInsert = sal_True;		// per API nicht nachfragen
					else
					{
						String aTemplate = ScGlobal::GetRscString( STR_CREATENAME_REPLACE );

						String aMessage = aTemplate.GetToken( 0, '#' );
						aMessage += aName;
						aMessage += aTemplate.GetToken( 1, '#' );

						short nResult = QueryBox( rDocShell.GetActiveDialogParent(),
													WinBits(WB_YES_NO_CANCEL | WB_DEF_YES),
													aMessage ).Execute();
						if ( nResult == RET_YES )
						{
							rList.AtFree(nOldPos);
							bInsert = sal_True;
						}
						else if ( nResult == RET_CANCEL )
							rCancel = sal_True;
					}
				}
			}
			else
				bInsert = sal_True;

			if (bInsert)
			{
                ScRangeData* pData = new ScRangeData( pDoc, aName, aContent,
                        ScAddress( nPosX, nPosY, nTab));
				if (!rList.Insert(pData))
				{
					DBG_ERROR("nanu?");
					delete pData;
				}
			}
		}
	}
}

sal_Bool ScDocFunc::CreateNames( const ScRange& rRange, sal_uInt16 nFlags, sal_Bool bApi )
{
	if (!nFlags)
		return sal_False;		// war nix

	ScDocShellModificator aModificator( rDocShell );

	sal_Bool bDone = sal_False;
	SCCOL nStartCol = rRange.aStart.Col();
	SCROW nStartRow = rRange.aStart.Row();
	SCCOL nEndCol = rRange.aEnd.Col();
	SCROW nEndRow = rRange.aEnd.Row();
	SCTAB nTab = rRange.aStart.Tab();
	DBG_ASSERT(rRange.aEnd.Tab() == nTab, "CreateNames: mehrere Tabellen geht nicht");

	sal_Bool bValid = sal_True;
	if ( nFlags & ( NAME_TOP | NAME_BOTTOM ) )
		if ( nStartRow == nEndRow )
			bValid = sal_False;
	if ( nFlags & ( NAME_LEFT | NAME_RIGHT ) )
		if ( nStartCol == nEndCol )
			bValid = sal_False;

	if (bValid)
	{
		ScDocument* pDoc = rDocShell.GetDocument();
		ScRangeName* pNames = pDoc->GetRangeName();
		if (!pNames)
			return sal_False;	// soll nicht sein
		ScRangeName aNewRanges( *pNames );

		sal_Bool bTop    = ( ( nFlags & NAME_TOP ) != 0 );
		sal_Bool bLeft   = ( ( nFlags & NAME_LEFT ) != 0 );
		sal_Bool bBottom = ( ( nFlags & NAME_BOTTOM ) != 0 );
		sal_Bool bRight  = ( ( nFlags & NAME_RIGHT ) != 0 );

		SCCOL nContX1 = nStartCol;
		SCROW nContY1 = nStartRow;
		SCCOL nContX2 = nEndCol;
		SCROW nContY2 = nEndRow;

		if ( bTop )
			++nContY1;
		if ( bLeft )
			++nContX1;
		if ( bBottom )
			--nContY2;
		if ( bRight )
			--nContX2;

		sal_Bool bCancel = sal_False;
        SCCOL i;
        SCROW j;

		if ( bTop )
			for (i=nContX1; i<=nContX2; i++)
				CreateOneName( aNewRanges, i,nStartRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
		if ( bLeft )
			for (j=nContY1; j<=nContY2; j++)
				CreateOneName( aNewRanges, nStartCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
		if ( bBottom )
			for (i=nContX1; i<=nContX2; i++)
				CreateOneName( aNewRanges, i,nEndRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
		if ( bRight )
			for (j=nContY1; j<=nContY2; j++)
				CreateOneName( aNewRanges, nEndCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );

		if ( bTop && bLeft )
			CreateOneName( aNewRanges, nStartCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
		if ( bTop && bRight )
			CreateOneName( aNewRanges, nEndCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
		if ( bBottom && bLeft )
			CreateOneName( aNewRanges, nStartCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
		if ( bBottom && bRight )
			CreateOneName( aNewRanges, nEndCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );

		bDone = ModifyRangeNames( aNewRanges, bApi );

		aModificator.SetDocumentModified();
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
	}

	return bDone;
}

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

sal_Bool ScDocFunc::InsertNameList( const ScAddress& rStartPos, sal_Bool bApi )
{
	ScDocShellModificator aModificator( rDocShell );


	sal_Bool bDone = sal_False;
	ScDocument* pDoc = rDocShell.GetDocument();
	const sal_Bool bRecord = pDoc->IsUndoEnabled();
	SCTAB nTab = rStartPos.Tab();
	ScDocument* pUndoDoc = NULL;

	ScRangeName* pList = pDoc->GetRangeName();
	sal_uInt16 nCount = pList->GetCount();
	sal_uInt16 nValidCount = 0;
	sal_uInt16 i;
	for (i=0; i<nCount; i++)
	{
		ScRangeData* pData = (*pList)[i];
		if ( !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) )
			++nValidCount;
	}

	if (nValidCount)
	{
		SCCOL nStartCol = rStartPos.Col();
		SCROW nStartRow = rStartPos.Row();
		SCCOL nEndCol = nStartCol + 1;
		SCROW nEndRow = nStartRow + static_cast<SCROW>(nValidCount) - 1;

		ScEditableTester aTester( pDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
		if (aTester.IsEditable())
		{
			if (bRecord)
			{
				pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
				pUndoDoc->InitUndo( pDoc, nTab, nTab );
				pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
										IDF_ALL, sal_False, pUndoDoc );

				pDoc->BeginDrawUndo();		// wegen Hoehenanpassung
			}

			ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ];
			sal_uInt16 j = 0;
			for (i=0; i<nCount; i++)
			{
				ScRangeData* pData = (*pList)[i];
				if ( !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) )
					ppSortArray[j++] = pData;
			}
#ifndef ICC
			qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
				&ScRangeData_QsortNameCompare );
#else
			qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
				ICCQsortNameCompare );
#endif
			String aName;
			rtl::OUStringBuffer aContent;
			String aFormula;
			SCROW nOutRow = nStartRow;
			for (j=0; j<nValidCount; j++)
			{
				ScRangeData* pData = ppSortArray[j];
				pData->GetName(aName);
				// relative Referenzen Excel-konform auf die linke Spalte anpassen:
				pData->UpdateSymbol(aContent, ScAddress( nStartCol, nOutRow, nTab ));
				aFormula = '=';
				aFormula += aContent;
				pDoc->PutCell( nStartCol,nOutRow,nTab, new ScStringCell( aName ) );
				pDoc->PutCell( nEndCol  ,nOutRow,nTab, new ScStringCell( aFormula ) );
				++nOutRow;
			}

			delete [] ppSortArray;

			if (bRecord)
			{
				ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
				pRedoDoc->InitUndo( pDoc, nTab, nTab );
				pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
										IDF_ALL, sal_False, pRedoDoc );

				rDocShell.GetUndoManager()->AddUndoAction(
					new ScUndoListNames( &rDocShell,
								ScRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab ),
								pUndoDoc, pRedoDoc ) );
			}

			if (!AdjustRowHeight(ScRange(0,nStartRow,nTab,MAXCOL,nEndRow,nTab)))
				rDocShell.PostPaint( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, PAINT_GRID );
//!			rDocShell.UpdateOle(GetViewData());
			aModificator.SetDocumentModified();
			bDone = sal_True;
		}
		else if (!bApi)
			rDocShell.ErrorMessage(aTester.GetMessageId());
	}
	return bDone;
}

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

sal_Bool ScDocFunc::ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, sal_Bool bApi )
{
	ScDocument* pDoc = rDocShell.GetDocument();
	SCCOL nStartCol = rOldRange.aStart.Col();
	SCROW nStartRow = rOldRange.aStart.Row();
	SCTAB nTab = rOldRange.aStart.Tab();

	sal_Bool bUndo(pDoc->IsUndoEnabled());

	sal_Bool bRet = sal_False;

	String aFormula;
	pDoc->GetFormula( nStartCol, nStartRow, nTab, aFormula );
	if ( aFormula.GetChar(0) == '{' && aFormula.GetChar(aFormula.Len()-1) == '}' )
	{
		String aUndo = ScGlobal::GetRscString( STR_UNDO_RESIZEMATRIX );
		if (bUndo)
			rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );

		aFormula.Erase(0,1);
		aFormula.Erase(aFormula.Len()-1,1);

		ScMarkData aMark;
		aMark.SetMarkArea( rOldRange );
		aMark.SelectTable( nTab, sal_True );
		ScRange aNewRange( rOldRange.aStart, rNewEnd );

		if ( DeleteContents( aMark, IDF_CONTENTS, sal_True, bApi ) )
		{
            // GRAM_PODF_A1 for API compatibility.
            bRet = EnterMatrix( aNewRange, &aMark, NULL, aFormula, bApi, sal_False, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
			if (!bRet)
			{
				//	versuchen, alten Zustand wiederherzustellen
                EnterMatrix( rOldRange, &aMark, NULL, aFormula, bApi, sal_False, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
			}
		}

		if (bUndo)
			rDocShell.GetUndoManager()->LeaveListAction();
	}

	return bRet;
}

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

sal_Bool ScDocFunc::InsertAreaLink( const String& rFile, const String& rFilter,
								const String& rOptions, const String& rSource,
								const ScRange& rDestRange, sal_uLong nRefresh,
                                sal_Bool bFitBlock, sal_Bool bApi )
{
	//!	auch fuer ScViewFunc::InsertAreaLink benutzen!

	ScDocument* pDoc = rDocShell.GetDocument();
	sal_Bool bUndo (pDoc->IsUndoEnabled());

    sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();

    //  #i52120# if other area links exist at the same start position,
    //  remove them first (file format specifies only one link definition
    //  for a cell)

    sal_uInt16 nLinkCount = pLinkManager->GetLinks().Count();
    sal_uInt16 nRemoved = 0;
    sal_uInt16 nLinkPos = 0;
    while (nLinkPos<nLinkCount)
    {
        ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[nLinkPos];
        if ( pBase->ISA(ScAreaLink) &&
             static_cast<ScAreaLink*>(pBase)->GetDestArea().aStart == rDestRange.aStart )
        {
            if ( bUndo )
            {
                if ( !nRemoved )
                {
                    // group all remove and the insert action
                    String aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK );
                    rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
                }

                ScAreaLink* pOldArea = static_cast<ScAreaLink*>(pBase);
                rDocShell.GetUndoManager()->AddUndoAction(
                    new ScUndoRemoveAreaLink( &rDocShell,
                        pOldArea->GetFile(), pOldArea->GetFilter(), pOldArea->GetOptions(),
                        pOldArea->GetSource(), pOldArea->GetDestArea(), pOldArea->GetRefreshDelay() ) );
            }
            pLinkManager->Remove( pBase );
            nLinkCount = pLinkManager->GetLinks().Count();
            ++nRemoved;
        }
        else
            ++nLinkPos;
    }

	String aFilterName = rFilter;
	String aNewOptions = rOptions;
	if (!aFilterName.Len())
        ScDocumentLoader::GetFilterName( rFile, aFilterName, aNewOptions, sal_True, !bApi );

	//	remove application prefix from filter name here, so the filter options
	//	aren't reset when the filter name is changed in ScAreaLink::DataChanged
	ScDocumentLoader::RemoveAppPrefix( aFilterName );

	ScAreaLink* pLink = new ScAreaLink( &rDocShell, rFile, aFilterName,
										aNewOptions, rSource, rDestRange, nRefresh );
	pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, rFile, &aFilterName, &rSource );

	//	Undo fuer den leeren Link

	if (bUndo)
    {
		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertAreaLink( &rDocShell,
													rFile, aFilterName, aNewOptions,
													rSource, rDestRange, nRefresh ) );
        if ( nRemoved )
            rDocShell.GetUndoManager()->LeaveListAction();  // undo for link update is still separate
    }

	//	Update hat sein eigenes Undo
    if (pDoc->IsExecuteLinkEnabled())
    {
        pLink->SetDoInsert(bFitBlock);	// beim ersten Update ggf. nichts einfuegen
        pLink->Update();				// kein SetInCreate -> Update ausfuehren
    }
	pLink->SetDoInsert(sal_True);		// Default = sal_True

	SfxBindings* pBindings = rDocShell.GetViewBindings();
	if (pBindings)
		pBindings->Invalidate( SID_LINKS );

	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );		// Navigator

	return sal_True;
}

/* vim: set noet sw=4 ts=4: */
