/**************************************************************
 * 
 * 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>
#define _SVSTDARR_STRINGS
#include <editeng/boxitem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/scripttypeitem.hxx>
#include <svl/srchitem.hxx>
#include <sfx2/linkmgr.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/objitem.hxx>
#include <sfx2/viewfrm.hxx>
#include <svl/stritem.hxx>
#include <svl/zforlist.hxx>
#include <svl/svstdarr.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/sound.hxx>
#include <vcl/waitobj.hxx>

#include "viewfunc.hxx"

#include "sc.hrc"
#include "globstr.hrc"

#include "attrib.hxx"
#include "autoform.hxx"
#include "cell.hxx"					// EnterAutoSum
#include "compiler.hxx"
#include "docfunc.hxx"
#include "docpool.hxx"
#include "docsh.hxx"
#include "global.hxx"
#include "patattr.hxx"
#include "printfun.hxx"
#include "rangenam.hxx"
#include "rangeutl.hxx"
#include "refundo.hxx"
#include "tablink.hxx"
#include "tabvwsh.hxx"
#include "uiitems.hxx"
#include "undoblk.hxx"
#include "undocell.hxx"
#include "undotab.hxx"
#include "sizedev.hxx"
#include "editable.hxx"
#include "scmod.hxx"
#include "inputhdl.hxx"
#include "inputwin.hxx"
#include "funcdesc.hxx"
#include "docuno.hxx"
#include "charthelper.hxx"
#include "tabbgcolor.hxx"

#include <basic/sbstar.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
using namespace com::sun::star;

// helper func defined in docfunc.cxx
void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName );

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


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

sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	if (!pMarkData)
		pMarkData = &GetViewData()->GetMarkData();

	ScDocument* pDoc = pDocSh->GetDocument();
	SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
	SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
	if (nRangeCnt == 0)
	{
		pRanges[0] = pRanges[1] = GetViewData()->GetCurY();
		nRangeCnt = 1;
	}

	double nPPTX = GetViewData()->GetPPTX();
	double nPPTY = GetViewData()->GetPPTY();
	Fraction aZoomX = GetViewData()->GetZoomX();
	Fraction aZoomY = GetViewData()->GetZoomY();

	ScSizeDeviceProvider aProv(pDocSh);
	if (aProv.IsPrinter())
	{
		nPPTX = aProv.GetPPTX();
		nPPTY = aProv.GetPPTY();
		aZoomX = aZoomY = Fraction( 1, 1 );
	}

	sal_Bool bAnyChanged = sal_False;
	SCTAB nTabCount = pDoc->GetTableCount();
	for (SCTAB nTab=0; nTab<nTabCount; nTab++)
	{
		if (pMarkData->GetTableSelect(nTab))
		{
			SCCOLROW* pOneRange = pRanges;
			sal_Bool bChanged = sal_False;
            SCROW nPaintY = 0;
			for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
			{
				SCROW nStartNo = *(pOneRange++);
				SCROW nEndNo = *(pOneRange++);
				if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
											nPPTX, nPPTY, aZoomX, aZoomY, sal_False ))
				{
					if (!bChanged)
						nPaintY = nStartNo;
					bAnyChanged = bChanged = sal_True;
				}
			}
			if ( bPaint && bChanged )
				pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
													PAINT_GRID | PAINT_LEFT );
		}
	}
	delete[] pRanges;

	if ( bPaint && bAnyChanged )
		pDocSh->UpdateOle(GetViewData());

	return bAnyChanged;
}


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

sal_Bool ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, sal_Bool bPaint )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	SCTAB nTab = GetViewData()->GetTabNo();
	double nPPTX = GetViewData()->GetPPTX();
	double nPPTY = GetViewData()->GetPPTY();
	Fraction aZoomX = GetViewData()->GetZoomX();
	Fraction aZoomY = GetViewData()->GetZoomY();
    sal_uInt16 nOldPixel = 0;
	if (nStartRow == nEndRow)
		nOldPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);

	ScSizeDeviceProvider aProv(pDocSh);
	if (aProv.IsPrinter())
	{
		nPPTX = aProv.GetPPTX();
		nPPTY = aProv.GetPPTY();
		aZoomX = aZoomY = Fraction( 1, 1 );
	}
	sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
											nPPTX, nPPTY, aZoomX, aZoomY, sal_False );

	if (bChanged && ( nStartRow == nEndRow ))
	{
		sal_uInt16 nNewPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
		if ( nNewPixel == nOldPixel )
			bChanged = sal_False;
	}

	if ( bPaint && bChanged )
		pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
											PAINT_GRID | PAINT_LEFT );

	return bChanged;
}


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

enum ScAutoSum
{
	ScAutoSumNone = 0,
	ScAutoSumData,
	ScAutoSumSum
};


ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
		SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
{
	ScBaseCell* pCell;
	pDoc->GetCell( nCol, nRow, nTab, pCell );
	if ( pCell && pCell->HasValueData() )
	{
		if ( pCell->GetCellType() == CELLTYPE_FORMULA )
		{
			ScTokenArray* pCode = ((ScFormulaCell*)pCell)->GetCode();
			if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
			{
				if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
						ScAddress( nCol, nRow, nTab ), eDir ) )
					return ScAutoSumSum;
			}
		}
		return ScAutoSumData;
	}
	return ScAutoSumNone;
}


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

#define SC_AUTOSUM_MAXCOUNT		20

ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow,
		SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
{
	sal_uInt16 nCount = 0;
	while (nCount < SC_AUTOSUM_MAXCOUNT)
	{
		if ( eDir == DIR_TOP )
		{
			if (nRow > 0)
				--nRow;
			else
				return ScAutoSumNone;
		}
		else
		{
			if (nCol > 0)
				--nCol;
			else
				return ScAutoSumNone;
		}
		ScAutoSum eSum;
		if ( (eSum = lcl_IsAutoSumData(
				pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone )
			return eSum;
		++nCount;
	}
	return ScAutoSumNone;
}

#undef SC_AUTOSUM_MAXCOUNT

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

bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& nRow,
                                   SCTAB nTab, SCCOLROW& nExtend, SCROW nMinRow )
{
    const SCROW nTmp = nRow;
    ScAutoSum eSkip = ScAutoSumNone;
    while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) ) == ScAutoSumData &&
            nRow > nMinRow )
    {
        --nRow;
    }
    if ( eSkip == ScAutoSumSum && nRow < nTmp )
    {
        return true;
    }
    return false;
}

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

bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow,
                                SCTAB nTab, SCCOLROW& nExtend, SCROW nMinCol )
{
    const SCCOL nTmp = nCol;
    ScAutoSum eSkip = ScAutoSumNone;
    while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) ) == ScAutoSumData &&
            nCol > nMinCol )
    {
        --nCol;
    }
    if ( eSkip == ScAutoSumSum && nCol < nTmp )
    {
        return true;
    }
    return false;
}

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

bool lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
{
    const ScAddress aStart = rRange.aStart;
    const ScAddress aEnd = rRange.aEnd;
    if ( aStart.Col() != aEnd.Col() )
    {
        return false;
    }

    const SCTAB nTab = aEnd.Tab();
    const SCCOL nCol = aEnd.Col();
    SCROW nEndRow = aEnd.Row();
    SCROW nStartRow = nEndRow;
    SCCOLROW nExtend = 0;
    const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ );

    if ( eSum == ScAutoSumSum )
    {
        bool bContinue = false;
        do
        {
            rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
            nEndRow = static_cast< SCROW >( nExtend );
            if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, aStart.Row() ) ) == true )
            {
                nStartRow = nEndRow;
            }
        } while ( bContinue );
    }
    else
    {
        while ( nStartRow > aStart.Row() &&
                lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) != ScAutoSumSum )
        {
            --nStartRow;
        }
        rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
    }

    return true;
}

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

bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
{
    const ScAddress aStart = rRange.aStart;
    const ScAddress aEnd = rRange.aEnd;
    if ( aStart.Row() != aEnd.Row() )
    {
        return false;
    }

    const SCTAB nTab = aEnd.Tab();
    const SCROW nRow = aEnd.Row();
    SCCOL nEndCol = aEnd.Col();
    SCCOL nStartCol = nEndCol;
    SCCOLROW nExtend = 0;
    const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );

    if ( eSum == ScAutoSumSum )
    {
        bool bContinue = false;
        do
        {
            rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
            nEndCol = static_cast< SCCOL >( nExtend );
            if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true )
            {
                nStartCol = nEndCol;
            }
        } while ( bContinue );
    }
    else
    {
        while ( nStartCol > aStart.Col() &&
                lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum )
        {
            --nStartCol;
        }
        rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
    }

    return true;
}

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

sal_Bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
{
	ScDocument* pDoc = GetViewData()->GetDocument();
	SCTAB nTab = GetViewData()->GetTabNo();

	SCCOL nCol = GetViewData()->GetCurX();
	SCROW nRow = GetViewData()->GetCurY();

	SCCOL nStartCol = nCol;
	SCROW nStartRow = nRow;
	SCCOL nEndCol	 = nCol;
	SCROW nEndRow	 = nRow;
	SCCOL nSeekCol	 = nCol;
	SCROW nSeekRow	 = nRow;
	SCCOLROW nExtend;		// wird per Reference gueltig bei ScAutoSumSum

	sal_Bool bCol = sal_False;
	sal_Bool bRow = sal_False;

	ScAutoSum eSum;
	if ( nRow != 0
			&& ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
				DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
			&& ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
				DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
		)
	{
		bRow = sal_True;
		nSeekRow = nRow - 1;
	}
	else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
			DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
	{
		bCol = sal_True;
		nSeekCol = nCol - 1;
	}
    else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
		bRow = sal_True;
    else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
		bCol = sal_True;

	if ( bCol || bRow )
	{
		if ( bRow )
		{
			nStartRow = nSeekRow;		// nSeekRow evtl. per Reference angepasst
			if ( eSum == ScAutoSumSum )
				nEndRow = nStartRow;		// nur Summen summieren
			else
				nEndRow = nRow - 1;		// Datenbereich evtl. nach unten erweitern
		}
		else
		{
			nStartCol = nSeekCol;		// nSeekCol evtl. per Reference angepasst
			if ( eSum == ScAutoSumSum )
				nEndCol = nStartCol;		// nur Summen summieren
			else
				nEndCol = nCol - 1;		// Datenbereich evtl. nach rechts erweitern
		}
		sal_Bool bContinue = sal_False;
		do
		{
			if ( eSum == ScAutoSumData )
			{
				if ( bRow )
				{
					while ( nStartRow != 0 && lcl_IsAutoSumData(	pDoc, nCol,
							nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
						--nStartRow;
				}
				else
				{
					while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
							nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
						--nStartCol;
				}
			}
			rRangeList.Append(
				ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
			if ( eSum == ScAutoSumSum )
			{
				if ( bRow )
				{
                    nEndRow = static_cast< SCROW >( nExtend );
                    if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true )
                    {
                        nStartRow = nEndRow;
                    }
				}
				else
				{
                    nEndCol = static_cast< SCCOL >( nExtend );
                    if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
                    {
                        nStartCol = nEndCol;
                    }
				}
			}
		} while ( bContinue );
		return sal_True;
	}
	return sal_False;
}

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

void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, sal_Bool bSubTotal)		// Block mit Summen fuellen
{
    String aFormula = GetAutoSumFormula( rRangeList, bSubTotal );
	EnterBlock( aFormula, NULL );
}

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

bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
{
	ScDocument* pDoc = GetViewData()->GetDocument();
    const SCTAB nTab = rRange.aStart.Tab();
    SCCOL nStartCol = rRange.aStart.Col();
    SCROW nStartRow = rRange.aStart.Row();
    const SCCOL nEndCol = rRange.aEnd.Col();
    const SCROW nEndRow = rRange.aEnd.Row();
    SCCOLROW nExtend = 0; // out parameter for lcl_IsAutoSumData

    // ignore rows at the top of the given range which don't contain autosum data
    bool bRowData = false;
    for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
    {
        for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
        {
            if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) != ScAutoSumNone )
            {
                bRowData = true;
                break;
            }
        }
        if ( bRowData )
        {
            nStartRow = nRow;
            break;
        }
    }
    if ( !bRowData )
    {
        return false;
    }

    // ignore columns at the left of the given range which don't contain autosum data
    bool bColData = false;
    for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
    {
        for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
        {
            if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) != ScAutoSumNone )
            {
                bColData = true;
                break;
            }
        }
        if ( bColData )
        {
            nStartCol = nCol;
            break;
        }
    }
    if ( !bColData )
    {
        return false;
    }

    const bool bEndRowEmpty = pDoc->IsBlockEmpty( nTab, nStartCol, nEndRow, nEndCol, nEndRow );
    const bool bEndColEmpty = pDoc->IsBlockEmpty( nTab, nEndCol, nStartRow, nEndCol, nEndRow );
    bool bRow = ( ( nStartRow != nEndRow ) && ( bEndRowEmpty || ( !bEndRowEmpty && !bEndColEmpty ) ) );
    bool bCol = ( ( nStartCol != nEndCol ) && ( bEndColEmpty || nStartRow == nEndRow ) );

    // find an empty row for entering the result
    SCROW nInsRow = nEndRow;
    if ( bRow && !bEndRowEmpty )
    {
        if ( nInsRow < MAXROW )
        {
            ++nInsRow;
            while ( !pDoc->IsBlockEmpty( nTab, nStartCol, nInsRow, nEndCol, nInsRow ) )
            {
                if ( nInsRow < MAXROW )
                {
                    ++nInsRow;
                }
                else
                {
                    bRow = false;
                    break;
                }
            }
        }
        else
        {
            bRow = false;
        }
    }

    // find an empty column for entering the result
    SCCOL nInsCol = nEndCol;
    if ( bCol && !bEndColEmpty )
    {
        if ( nInsCol < MAXCOL )
        {
            ++nInsCol;
            while ( !pDoc->IsBlockEmpty( nTab, nInsCol, nStartRow, nInsCol, nEndRow ) )
            {
                if ( nInsCol < MAXCOL )
                {
                    ++nInsCol;
                }
                else
                {
                    bCol = false;
                    break;
                }
            }
        }
        else
        {
            bCol = false;
        }
    }

    if ( !bRow && !bCol )
    {
        return false;
    }

    SCCOL nMarkEndCol = nEndCol;
    SCROW nMarkEndRow = nEndRow;

    if ( bRow )
    {
        // calculate the row sums for all columns of the given range

        SCROW nSumEndRow = nEndRow;

        if ( bEndRowEmpty )
        {
            // the last row of the given range is empty;
            // don't take into account for calculating the autosum
            --nSumEndRow;
        }
        else
        {
            // increase mark range
            ++nMarkEndRow;
        }

        for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
        {
            if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) )
            {
                ScRangeList aRangeList;
                const ScRange aRange( nCol, nStartRow, nTab, nCol, nSumEndRow, nTab );
                if ( lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange ) )
                {
                    const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
                    EnterData( nCol, nInsRow, nTab, aFormula );
                }
            }
        }
    }

    if ( bCol )
    {
        // calculate the column sums for all rows of the given range

        SCCOL nSumEndCol = nEndCol;

        if ( bEndColEmpty )
        {
            // the last column of the given range is empty;
            // don't take into account for calculating the autosum
            --nSumEndCol;
        }
        else
        {
            // increase mark range
            ++nMarkEndCol;
        }

        for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
        {
            if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) )
            {
                ScRangeList aRangeList;
                const ScRange aRange( nStartCol, nRow, nTab, nSumEndCol, nRow, nTab );
                if ( lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange ) )
                {
                    const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
                    EnterData( nInsCol, nRow, nTab, aFormula );
                }
            }
        }
    }

    // set new mark range and cursor position
    const ScRange aMarkRange( nStartCol, nStartRow, nTab, nMarkEndCol, nMarkEndRow, nTab );
    MarkRange( aMarkRange, sal_False, bContinue );
    if ( bSetCursor )
    {
        SetCursor( nMarkEndCol, nMarkEndRow );
    }

    return true;
}

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

String ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal )
{
    String aFormula = '=';
    ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
    const ScFuncDesc* pDesc = NULL;
    if ( bSubTotal )
    {
        pDesc = pFuncMgr->Get( SC_OPCODE_SUB_TOTAL );
    }
    else
    {
        pDesc = pFuncMgr->Get( SC_OPCODE_SUM );
    }
    if ( pDesc && pDesc->pFuncName )
    {
        aFormula += *pDesc->pFuncName;
        if ( bSubTotal )
        {
            aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "(9;" ) );
        }
        else
        {
            aFormula += '(';
        }
        ScDocument* pDoc = GetViewData()->GetDocument();
        String aRef;
        rRangeList.Format( aRef, SCA_VALID, pDoc );
        aFormula += aRef;
        aFormula += ')';
    }
    return aFormula;
}

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

void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData )
{
	//	Mehrfachselektion vorher abfragen...

	SCCOL nCol = GetViewData()->GetCurX();
	SCROW nRow = GetViewData()->GetCurY();
	SCTAB nTab = GetViewData()->GetTabNo();
	ScMarkData& rMark = GetViewData()->GetMarkData();
	if ( rMark.IsMultiMarked() )
	{
		rMark.MarkToSimple();
		if ( rMark.IsMultiMarked() )
		{		// "Einfuegen auf Mehrfachselektion nicht moeglich"
			ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);

			//	insert into single cell
			if ( pData )
				EnterData( nCol, nRow, nTab, pData );
			else
				EnterData( nCol, nRow, nTab, rString );
			return;
		}
	}

	ScDocument* pDoc = GetViewData()->GetDocument();
	String aNewStr = rString;
	if ( pData )
	{
		const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
		ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
		aEngine.SetText(*pData);

		ScEditAttrTester aTester( &aEngine );
		if (!aTester.NeedsObject())
		{
			aNewStr = aEngine.GetText();
			pData = NULL;
		}
	}

	//	Einfuegen per PasteFromClip

	WaitObject aWait( GetFrameWin() );

	ScAddress aPos( nCol, nRow, nTab );

	ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
	pInsDoc->ResetClip( pDoc, nTab );

	if (aNewStr.GetChar(0) == '=')						// Formel ?
	{
		//	SetString geht nicht, weil in Clipboard-Dokumenten nicht kompiliert wird!
		ScFormulaCell* pFCell = new ScFormulaCell( pDoc, aPos, aNewStr );
		pInsDoc->PutCell( nCol, nRow, nTab, pFCell );
	}
	else if ( pData )
		pInsDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pData, pDoc, NULL ) );
	else
		pInsDoc->SetString( nCol, nRow, nTab, aNewStr );

	pInsDoc->SetClipArea( ScRange(aPos) );
	// auf Block einfuegen, mit Undo etc.
	if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, sal_False, sal_False,
			sal_False, INS_NONE, IDF_ATTRIB ) )
	{
		const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
			nCol, nRow, nTab, ATTR_VALUE_FORMAT );
		if ( pItem )
		{	// Numberformat setzen wenn inkompatibel
			// MarkData wurde bereits in PasteFromClip MarkToSimple'ed
			ScRange aRange;
			rMark.GetMarkArea( aRange );
			ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
			pPattern->GetItemSet().Put( *pItem );
			short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
			pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
				*pPattern, nNewType );
			delete pPattern;
		}
	}

	delete pInsDoc;
}


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

//UNUSED2008-05  void ScViewFunc::PaintWidthHeight( sal_Bool bColumns, SCCOLROW nStart, SCCOLROW nEnd )
//UNUSED2008-05  {
//UNUSED2008-05      SCTAB nTab = GetViewData()->GetTabNo();
//UNUSED2008-05      ScDocument* pDoc = GetViewData()->GetDocument();
//UNUSED2008-05
//UNUSED2008-05      sal_uInt16 nParts = PAINT_GRID;
//UNUSED2008-05      SCCOL nStartCol = 0;
//UNUSED2008-05      SCROW nStartRow = 0;
//UNUSED2008-05      SCCOL nEndCol = MAXCOL;         // fuer Test auf Merge
//UNUSED2008-05      SCROW nEndRow = MAXROW;
//UNUSED2008-05      if ( bColumns )
//UNUSED2008-05      {
//UNUSED2008-05          nParts |= PAINT_TOP;
//UNUSED2008-05          nStartCol = static_cast<SCCOL>(nStart);
//UNUSED2008-05          nEndCol = static_cast<SCCOL>(nEnd);
//UNUSED2008-05      }
//UNUSED2008-05      else
//UNUSED2008-05      {
//UNUSED2008-05          nParts |= PAINT_LEFT;
//UNUSED2008-05          nStartRow = nStart;
//UNUSED2008-05          nEndRow = nEnd;
//UNUSED2008-05      }
//UNUSED2008-05      if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
//UNUSED2008-05                           HASATTR_MERGED | HASATTR_OVERLAPPED ))
//UNUSED2008-05      {
//UNUSED2008-05          nStartCol = 0;
//UNUSED2008-05          nStartRow = 0;
//UNUSED2008-05      }
//UNUSED2008-05      GetViewData()->GetDocShell()->PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts );
//UNUSED2008-05  }


//----------------------------------------------------------------------------
//	manueller Seitenumbruch

void ScViewFunc::InsertPageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
									sal_Bool bSetModified )
{
	SCTAB nTab = GetViewData()->GetTabNo();
	ScAddress aCursor;
	if (pPos)
		aCursor = *pPos;
	else
		aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );

	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
						InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, sal_False );

	if ( bSuccess && bSetModified )
		UpdatePageBreakData( sal_True );	// fuer PageBreak-Modus
}


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

void ScViewFunc::DeletePageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
									sal_Bool bSetModified )
{
	SCTAB nTab = GetViewData()->GetTabNo();
	ScAddress aCursor;
	if (pPos)
		aCursor = *pPos;
	else
		aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );

	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
						RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, sal_False );

	if ( bSuccess && bSetModified )
		UpdatePageBreakData( sal_True );	// fuer PageBreak-Modus
}

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

void ScViewFunc::RemoveManualBreaks()
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	SCTAB nTab = GetViewData()->GetTabNo();
	sal_Bool bUndo(pDoc->IsUndoEnabled());

	if (bUndo)
	{
		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
		pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, sal_False, pUndoDoc );
		pDocSh->GetUndoManager()->AddUndoAction(
								new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
	}

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

	UpdatePageBreakData( sal_True );
	pDocSh->SetDocumentModified();
	pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
}

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

void ScViewFunc::SetPrintZoom(sal_uInt16 nScale, sal_uInt16 nPages)
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	SCTAB nTab = GetViewData()->GetTabNo();
	pDocSh->SetPrintZoom( nTab, nScale, nPages );
}

void ScViewFunc::AdjustPrintZoom()
{
	ScRange aRange;
	if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
		GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
	GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
}

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

void ScViewFunc::SetPrintRanges( sal_Bool bEntireSheet, const String* pPrint,
								const String* pRepCol, const String* pRepRow,
								sal_Bool bAddPrint )
{
	//	on all selected tables

	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
	ScDocument* pDoc	= pDocSh->GetDocument();
	SCTAB nTabCount	= pDoc->GetTableCount();
	ScMarkData& rMark	= GetViewData()->GetMarkData();
	SCTAB nTab;
	sal_Bool bUndo (pDoc->IsUndoEnabled());

	ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();

    ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);

	for (nTab=0; nTab<nTabCount; nTab++)
		if (rMark.GetTableSelect(nTab))
		{
			ScRange aRange( 0,0,nTab );

			//	print ranges

            if( !bAddPrint )
                pDoc->ClearPrintRanges( nTab );

            if( bEntireSheet )
            {
                pDoc->SetPrintEntireSheet( nTab );
            }
            else if ( pPrint )
			{
                if ( pPrint->Len() )
				{
                    const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
                    sal_uInt16 nTCount = pPrint->GetTokenCount(sep);
					for (sal_uInt16 i=0; i<nTCount; i++)
					{
						String aToken = pPrint->GetToken(i, sep);
						if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
                            pDoc->AddPrintRange( nTab, aRange );
					}
				}
			}
            else    // NULL = use selection (print range is always set), use empty string to delete all ranges
			{
				if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
				{
                    pDoc->AddPrintRange( nTab, aRange );
				}
				else if ( rMark.IsMultiMarked() )
				{
					rMark.MarkToMulti();
					ScRangeListRef aList( new ScRangeList );
					rMark.FillRangeListWithMarks( aList, sal_False );
					sal_uInt16 nCnt = (sal_uInt16) aList->Count();
					if ( nCnt )
					{
						ScRangePtr pR;
						sal_uInt16 i;
						for ( pR = aList->First(), i=0; i < nCnt;
							  pR = aList->Next(), i++ )
						{
                            pDoc->AddPrintRange( nTab, *pR );
						}
					}
				}
			}

			//	repeat columns

			if ( pRepCol )
			{
				if ( !pRepCol->Len() )
					pDoc->SetRepeatColRange( nTab, NULL );
				else
					if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID )
						pDoc->SetRepeatColRange( nTab, &aRange );
			}

			//	repeat rows

			if ( pRepRow )
			{
				if ( !pRepRow->Len() )
					pDoc->SetRepeatRowRange( nTab, NULL );
				else
					if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID )
						pDoc->SetRepeatRowRange( nTab, &aRange );
			}
		}

	//	undo (for all tables)
	if (bUndo)
	{
		SCTAB nCurTab = GetViewData()->GetTabNo();
		ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
		pDocSh->GetUndoManager()->AddUndoAction(
					new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) );
	}

	//	update page breaks

	for (nTab=0; nTab<nTabCount; nTab++)
		if (rMark.GetTableSelect(nTab))
			ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();

	SfxBindings& rBindings = GetViewData()->GetBindings();
	rBindings.Invalidate( SID_DELETE_PRINTAREA );

	pDocSh->SetDocumentModified();
}

//----------------------------------------------------------------------------
//	Zellen zusammenfassen

sal_Bool ScViewFunc::TestMergeCells()			// Vorab-Test (fuer Menue)
{
	//	simple test: sal_True if there's a selection but no multi selection and not filtered

	const ScMarkData& rMark = GetViewData()->GetMarkData();
	if ( rMark.IsMarked() || rMark.IsMultiMarked() )
	{
        ScRange aDummy;
        return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
	}
	else
		return sal_False;
}


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

sal_Bool ScViewFunc::MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord )
{
	//	Editable- und Verschachtelungs-Abfrage muss vorneweg sein (auch in DocFunc),
	//	damit dann nicht die Inhalte-QueryBox kommt
	ScEditableTester aTester( this );
	if (!aTester.IsEditable())
	{
		ErrorMessage(aTester.GetMessageId());
		return sal_False;
	}

	ScMarkData& rMark = GetViewData()->GetMarkData();
	rMark.MarkToSimple();
	if (!rMark.IsMarked())
	{
		ErrorMessage(STR_NOMULTISELECT);
		return sal_False;
	}

	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();

	ScRange aMarkRange;
	rMark.GetMarkArea( aMarkRange );
	SCCOL nStartCol = aMarkRange.aStart.Col();
	SCROW nStartRow = aMarkRange.aStart.Row();
	SCTAB nStartTab = aMarkRange.aStart.Tab();
	SCCOL nEndCol = aMarkRange.aEnd.Col();
	SCROW nEndRow = aMarkRange.aEnd.Row();
	SCTAB nEndTab = aMarkRange.aEnd.Tab();
	if ( nStartCol == nEndCol && nStartRow == nEndRow )
	{
		// nichts zu tun
		return sal_True;
	}

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

	sal_Bool bOk = sal_True;

	if ( !pDoc->IsBlockEmpty( nStartTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
		 !pDoc->IsBlockEmpty( nStartTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) )
	{
		if (!bApi)
		{
			MessBox aBox( GetViewData()->GetDialogParent(),
							WinBits(WB_YES_NO_CANCEL | WB_DEF_NO),
							ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
							ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) );
			sal_uInt16 nRetVal = aBox.Execute();

			if ( nRetVal == RET_YES )
				rDoContents = sal_True;
			else if ( nRetVal == RET_CANCEL )
				bOk = sal_False;
		}
	}

	if (bOk)
	{
		HideCursor();
		bOk = pDocSh->GetDocFunc().MergeCells( aMarkRange, rDoContents, bRecord, bApi );
		ShowCursor();

		if (bOk)
		{
			SetCursor( nStartCol, nStartRow );
			//DoneBlockMode( sal_False);
			Unmark();

			pDocSh->UpdateOle(GetViewData());
			UpdateInputLine();
		}
	}

	return bOk;
}


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

sal_Bool ScViewFunc::TestRemoveMerge()
{
	sal_Bool bMerged = sal_False;
	ScRange aRange;
	if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
	{
		ScDocument* pDoc = GetViewData()->GetDocument();
		if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
			bMerged = sal_True;
	}
	return bMerged;
}


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

sal_Bool ScViewFunc::RemoveMerge( sal_Bool bRecord )
{
	ScRange aRange;
    ScEditableTester aTester( this );
    if (!aTester.IsEditable())
    {
        ErrorMessage(aTester.GetMessageId());
        return sal_False;
    }
	else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
	{
        ScRange aExtended( aRange );
        GetViewData()->GetDocument()->ExtendMerge( aExtended );
		ScDocShell* pDocSh = GetViewData()->GetDocShell();

		HideCursor();
		sal_Bool bOk = pDocSh->GetDocFunc().UnmergeCells( aRange, bRecord, sal_False );
        MarkRange( aExtended );
		ShowCursor();

		if (bOk)
			pDocSh->UpdateOle(GetViewData());
	}
	return sal_True;		//! bOk ??
}

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

void ScViewFunc::FillSimple( FillDir eDir, sal_Bool bRecord )
{
	ScRange aRange;
	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
	{
		ScDocShell* pDocSh = GetViewData()->GetDocShell();
		const ScMarkData& rMark = GetViewData()->GetMarkData();
		sal_Bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, sal_False );
		if (bSuccess)
		{
			pDocSh->UpdateOle(GetViewData());
			UpdateScrollBars();
		}
	}
	else
		ErrorMessage(STR_NOMULTISELECT);
}

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

void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
							 double fStart, double fStep, double fMax, sal_Bool bRecord )
{
	ScRange aRange;
	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
	{
		ScDocShell* pDocSh = GetViewData()->GetDocShell();
		const ScMarkData& rMark = GetViewData()->GetMarkData();
		sal_Bool bSuccess = pDocSh->GetDocFunc().
						FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
									fStart, fStep, fMax, bRecord, sal_False );
		if (bSuccess)
		{
			pDocSh->UpdateOle(GetViewData());
			UpdateScrollBars();

            // #i97876# Spreadsheet data changes are not notified
            ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
            if ( pModelObj && pModelObj->HasChangesListeners() )
            {
                ScRangeList aChangeRanges;
                aChangeRanges.Append( aRange );
                pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
            }
		}
	}
	else
		ErrorMessage(STR_NOMULTISELECT);
}

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

void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
							SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount, sal_Bool bRecord )
{
	SCTAB nTab = GetViewData()->GetTabNo();
	ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
    ScRange aSourceRange( aRange );
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	const ScMarkData& rMark = GetViewData()->GetMarkData();
	sal_Bool bSuccess = pDocSh->GetDocFunc().
					FillAuto( aRange, &rMark, eDir, nCount, bRecord, sal_False );
	if (bSuccess)
	{
		MarkRange( aRange, sal_False );			// aRange ist in FillAuto veraendert worden
		pDocSh->UpdateOle(GetViewData());
		UpdateScrollBars();

        // #i97876# Spreadsheet data changes are not notified
        ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
        if ( pModelObj && pModelObj->HasChangesListeners() )
        {
            ScRangeList aChangeRanges;
            ScRange aChangeRange( aRange );
            switch ( eDir )
            {
                case FILL_TO_BOTTOM:
                    {
                        aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
                    }
                    break;
                case FILL_TO_TOP:
                    {
                        aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
                    }
                    break;
                case FILL_TO_RIGHT:
                    {
                        aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
                    }
                    break;
                case FILL_TO_LEFT:
                    {
                        aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
                    }
                    break;
                default:
                    {

                    }
                    break;
            }
            aChangeRanges.Append( aChangeRange );
            pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
        }
	}
}

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

void ScViewFunc::FillTab( sal_uInt16 nFlags, sal_uInt16 nFunction, sal_Bool bSkipEmpty, sal_Bool bAsLink )
{
	//! allow source sheet to be protected
	ScEditableTester aTester( this );
	if (!aTester.IsEditable())
	{
		ErrorMessage(aTester.GetMessageId());
		return;
	}

	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	ScMarkData& rMark = GetViewData()->GetMarkData();
	SCTAB nTab = GetViewData()->GetTabNo();
	sal_Bool bUndo(pDoc->IsUndoEnabled());

	ScRange aMarkRange;
	rMark.MarkToSimple();
	sal_Bool bMulti = rMark.IsMultiMarked();
	if (bMulti)
		rMark.GetMultiMarkArea( aMarkRange );
	else if (rMark.IsMarked())
		rMark.GetMarkArea( aMarkRange );
	else
		aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );

	ScDocument* pUndoDoc = NULL;
//	if ( bRecord )
	if (bUndo)
	{
		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, nTab, nTab );
//		pUndoDoc->SelectTable( nTab, sal_True );		// nur fuer Markierung

		SCTAB nTabCount = pDoc->GetTableCount();
		for (SCTAB i=0; i<nTabCount; i++)
			if (i != nTab && rMark.GetTableSelect(i))
			{
				pUndoDoc->AddUndoTab( i, i );
				aMarkRange.aStart.SetTab( i );
				aMarkRange.aEnd.SetTab( i );
				pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
//				pUndoDoc->SelectTable( i, sal_True );
			}
	}

	if (bMulti)
		pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
	else
	{
		aMarkRange.aStart.SetTab( nTab );
		aMarkRange.aEnd.SetTab( nTab );
		pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
	}

//	if ( bRecord )
	if (bUndo)
	{	//! fuer ChangeTrack erst zum Schluss
		pDocSh->GetUndoManager()->AddUndoAction(
			new ScUndoFillTable( pDocSh, rMark,
								aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
								aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
								pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
	}

	pDocSh->PostPaintGridAll();
	pDocSh->PostDataChanged();
}

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

/** Downward fill of selected cell(s) by double-clicking cross-hair cursor

	Extends a current selection down to the last non-empty cell of an adjacent
	column when the lower-right corner of the selection is double-clicked.  It
	uses a left-adjoining non-empty column as a guide if such is available,
	otherwise a right-adjoining non-empty column is used.

	@author Kohei Yoshida (kohei@openoffice.org)

	@return No return value

	@see #i12313#
*/
void ScViewFunc::FillCrossDblClick()
{
	ScRange aRange;
	GetViewData()->GetSimpleArea( aRange );
	aRange.Justify();

	SCTAB nTab = GetViewData()->GetCurPos().Tab();
	SCCOL nStartX = aRange.aStart.Col();
	SCROW nStartY = aRange.aStart.Row();
	SCCOL nEndX   = aRange.aEnd.Col();
	SCROW nEndY   = aRange.aEnd.Row();

	ScDocument* pDoc = GetViewData()->GetDocument();

	// Make sure the selection is not empty
	if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) )
		return;

	if ( nEndY < MAXROW )
	{
		if ( nStartX > 0 )
		{
			SCCOL nMovX = nStartX - 1;
			SCROW nMovY = nStartY;

			if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
				 pDoc->HasData( nMovX, nStartY + 1, nTab ) )
			{
				pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );

				if ( nMovY > nEndY )
				{
					FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
							  nMovY - nEndY );
					return;
				}
			}
		}

		if ( nEndX < MAXCOL )
		{
			SCCOL nMovX = nEndX + 1;
			SCROW nMovY = nStartY;

			if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
				 pDoc->HasData( nMovX, nStartY + 1, nTab ) )
			{
				pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );

				if ( nMovY > nEndY )
				{
					FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
							  nMovY - nEndY );
					return;
				}
			}
		}
	}
}

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

void ScViewFunc::TransliterateText( sal_Int32 nType )
{
	ScMarkData aFuncMark = GetViewData()->GetMarkData();
	if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
	{
		//	no selection -> use cursor position

		ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
		aFuncMark.SetMarkArea( ScRange( aCursor ) );
	}

	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
						TransliterateText( aFuncMark, nType, sal_True, sal_False );
	if (bSuccess)
	{
		GetViewData()->GetViewShell()->UpdateInputHandler();
	}
}

//----------------------------------------------------------------------------
//	AutoFormat

ScAutoFormatData* ScViewFunc::CreateAutoFormatData()
{
	ScAutoFormatData* pData = NULL;
	SCCOL nStartCol;
	SCROW nStartRow;
	SCTAB nStartTab;
	SCCOL nEndCol;
	SCROW nEndRow;
	SCTAB nEndTab;
	if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
	{
		if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 )
		{
			ScDocument* pDoc = GetViewData()->GetDocument();
			pData = new ScAutoFormatData;
			pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData );
		}
	}
	return pData;
}


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

void ScViewFunc::AutoFormat( sal_uInt16 nFormatNo, sal_Bool bRecord )
{
#if 1

	ScRange aRange;
	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
	{
		ScDocShell* pDocSh = GetViewData()->GetDocShell();
		ScMarkData& rMark = GetViewData()->GetMarkData();

		sal_Bool bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, sal_False );
		if (bSuccess)
			pDocSh->UpdateOle(GetViewData());
	}
	else
		ErrorMessage(STR_NOMULTISELECT);

#else

	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
	sal_Bool bOnlyNotBecauseOfMatrix;
	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

	SCCOL nStartCol;
	SCROW nStartRow;
	SCTAB nStartTab;
	SCCOL nEndCol;
	SCROW nEndRow;
	SCTAB nEndTab;

	if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
	{
		ScDocShell* pDocSh = GetViewData()->GetDocShell();
		ScDocument* pDoc = pDocSh->GetDocument();
		ScMarkData& rMark = GetViewData()->GetMarkData();
		sal_Bool bSize = (*ScGlobal::GetAutoFormat())[nFormatNo]->GetIncludeWidthHeight();
		if (bRecord && !pDoc->IsUndoEnabled())
			bRecord = sal_False;

		ScDocument* pUndoDoc = NULL;
		if ( bRecord )
		{
			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bSize, bSize );
			pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
									IDF_ATTRIB, sal_False, pUndoDoc );
			if (bSize)
			{
				pDoc->CopyToDocument( nStartCol,0,nStartTab, nEndCol,MAXROW,nEndTab,
															IDF_NONE, sal_False, pUndoDoc );
				pDoc->CopyToDocument( 0,nStartRow,nStartTab, MAXCOL,nEndRow,nEndTab,
															IDF_NONE, sal_False, pUndoDoc );
			}
			pDoc->BeginDrawUndo();
		}

		GetFrameWin()->EnterWait();
		pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, rMark );
		GetFrameWin()->LeaveWait();

		if (bSize)
		{
			SetMarkedWidthOrHeight( sal_True, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, sal_False, sal_False );
			SetMarkedWidthOrHeight( sal_False, SC_SIZE_VISOPT, 0, sal_False, sal_False );
			pDocSh->PostPaint( 0,0,nStartTab, MAXCOL,MAXROW,nStartTab,
									PAINT_GRID | PAINT_LEFT | PAINT_TOP );
		}
		else
		{
			sal_Bool bAdj = AdjustBlockHeight( sal_False );
			if (bAdj)
				pDocSh->PostPaint( 0,nStartRow,nStartTab, MAXCOL,MAXROW,nStartTab,
									PAINT_GRID | PAINT_LEFT );
			else
				pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
									nEndCol, nEndRow, nEndTab, PAINT_GRID );
		}

		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
		{
			pDocSh->GetUndoManager()->AddUndoAction(
				new ScUndoAutoFormat( pDocSh,
						ScRange(nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab),
						pUndoDoc, rMark, bSize, nFormatNo ) );
		}

		pDocSh->UpdateOle(GetViewData());
		pDocSh->SetDocumentModified();
	}
	else
		ErrorMessage(STR_NOMULTISELECT);

#endif
}


//----------------------------------------------------------------------------
//	Suchen & Ersetzen

sal_Bool ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
										sal_Bool bAddUndo, sal_Bool bIsApi )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	ScMarkData& rMark = GetViewData()->GetMarkData();
	if (bAddUndo && !pDoc->IsUndoEnabled())
		bAddUndo = sal_False;

	SCCOL nCol = GetViewData()->GetCurX();
	SCROW nRow = GetViewData()->GetCurY();
	SCTAB nTab = GetViewData()->GetTabNo();
//    sal_Bool bAttrib = pSearchItem->GetPattern();
	sal_uInt16 nCommand = pSearchItem->GetCommand();
	sal_Bool bAllTables = pSearchItem->IsAllTables();
	sal_Bool* pOldSelectedTables = NULL;
	sal_uInt16 nOldSelectedCount = 0;
	SCTAB nOldTab = nTab;
	SCTAB nLastTab = pDoc->GetTableCount() - 1;
	SCTAB nStartTab, nEndTab;
	if ( bAllTables )
	{
		nStartTab = 0;
		nEndTab = nLastTab;
		pOldSelectedTables = new sal_Bool [ nEndTab + 1 ];
		for ( SCTAB j = 0; j <= nEndTab; j++ )
		{
			pOldSelectedTables[j] = rMark.GetTableSelect( j );
			if ( pOldSelectedTables[j] )
				++nOldSelectedCount;
		}
	}
	else
	{	//! mindestens eine ist immer selektiert
		nStartTab = nEndTab = rMark.GetFirstSelected();
		for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ )
		{
			if ( rMark.GetTableSelect( j ) )
				nEndTab = j;
		}
	}

	if (   nCommand == SVX_SEARCHCMD_REPLACE
		|| nCommand == SVX_SEARCHCMD_REPLACE_ALL )
	{
		for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
		{
			if ( (bAllTables || rMark.GetTableSelect( j )) &&
					pDoc->IsTabProtected( j ) )
			{
				if ( pOldSelectedTables )
					delete [] pOldSelectedTables;
				ErrorMessage(STR_PROTECTIONERR);
				return sal_False;
			}
		}
	}

	if (   nCommand == SVX_SEARCHCMD_FIND
		|| nCommand == SVX_SEARCHCMD_FIND_ALL)
		bAddUndo = sal_False;

	//!		bAttrib bei Undo beruecksichtigen !!!

	ScDocument* pUndoDoc = NULL;
	ScMarkData* pUndoMark = NULL;
	String aUndoStr;
	if (bAddUndo)
	{
		pUndoMark = new ScMarkData( rMark );				// Markierung wird veraendert
		if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
		{
			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
		}
	}

	if ( bAllTables )
	{	//! alles selektieren, erst nachdem pUndoMark erzeugt wurde
		for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
		{
			rMark.SelectTable( j, sal_True );
		}
	}

	DoneBlockMode(sal_True);				// Markierung nicht loeschen!
	InitOwnBlockMode();

	//	wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll
	sal_Bool bFirst = sal_True;
	if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward()  )
		bFirst = sal_False;

	sal_Bool bFound = sal_False;
	while (sal_True)
	{
		GetFrameWin()->EnterWait();
		if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) )
		{
			bFound = sal_True;
			bFirst = sal_True;
			if (bAddUndo)
			{
				GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
					new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
										nCol, nRow, nTab,
										aUndoStr, pUndoDoc, pSearchItem ) );
				pUndoDoc = NULL;
			}

			break;					// Abbruch while True
		}
		else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
				nCommand == SVX_SEARCHCMD_REPLACE) )
		{
			bFirst = sal_False;
			sal_uInt16 nRetVal;
			GetFrameWin()->LeaveWait();
			if ( bIsApi )
				nRetVal = RET_NO;
			else
			{
				//	Suchen-Dialog als Parent, wenn vorhanden
				Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
				sal_uInt16 nStrId;
				if ( pSearchItem->GetBackward() )
				{
					if ( nStartTab == nEndTab )
						nStrId = STR_MSSG_SEARCHANDREPLACE_1;
					else
						nStrId = STR_MSSG_SEARCHANDREPLACE_4;
				}
				else
				{
					if ( nStartTab == nEndTab )
						nStrId = STR_MSSG_SEARCHANDREPLACE_2;
					else
						nStrId = STR_MSSG_SEARCHANDREPLACE_5;
				}
				MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
								ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
								ScGlobal::GetRscString( nStrId ) );
				nRetVal = aBox.Execute();
			}

			if ( nRetVal == RET_YES )
			{
				ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
				if (pSearchItem->GetBackward())
					nTab = nEndTab;
				else
					nTab = nStartTab;
			}
			else
			{
				break;					// Abbruch while True
			}
		}
		else							// nichts gefunden
		{
			if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
			{
				pDocSh->PostPaintGridAll();								// Markierung
			}

			GetFrameWin()->LeaveWait();
			if (!bIsApi)
			{
				//	Suchen-Dialog als Parent, wenn vorhanden
				Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
				// "nichts gefunden"
				InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
				aBox.Execute();
			}

			break;						// Abbruch while True
		}
	}								// of while sal_True

	if ( pOldSelectedTables )
	{	// urspruenglich selektierte Tabellen wiederherstellen
		for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
		{
			rMark.SelectTable( j, pOldSelectedTables[j] );
		}
		if ( bFound )
		{	// durch Fundstelle neu selektierte Tabelle bleibt
			rMark.SelectTable( nTab, sal_True );
			// wenn vorher nur eine selektiert war, ist es ein Tausch
			//! wenn nicht, ist jetzt evtl. eine mehr selektiert
			if ( nOldSelectedCount == 1 && nTab != nOldTab )
				rMark.SelectTable( nOldTab, sal_False );
		}
		delete [] pOldSelectedTables;
	}

    MarkDataChanged();

	if ( bFound )
	{
		if ( nTab != GetViewData()->GetTabNo() )
			SetTabNo( nTab );

		//	wenn nichts markiert ist, DoneBlockMode, damit von hier aus
		//	direkt per Shift-Cursor markiert werden kann:
		if (!rMark.IsMarked() && !rMark.IsMultiMarked())
			DoneBlockMode(sal_True);

		AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
		SetCursor( nCol, nRow, sal_True );

		if (   nCommand == SVX_SEARCHCMD_REPLACE
			|| nCommand == SVX_SEARCHCMD_REPLACE_ALL )
		{
			if ( nCommand == SVX_SEARCHCMD_REPLACE )
				pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
			else
				pDocSh->PostPaintGridAll();
			pDocSh->SetDocumentModified();
		}
		else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
			pDocSh->PostPaintGridAll();								// Markierung
		GetFrameWin()->LeaveWait();
	}

	delete pUndoDoc;			// loeschen wenn nicht benutzt
	delete pUndoMark;			// kann immer geloescht werden
	return bFound;
}


//----------------------------------------------------------------------------
//	Zielwertsuche

void ScViewFunc::Solve( const ScSolveParam& rParam )
{
	ScDocument* pDoc = GetViewData()->GetDocument();

	SCCOL nDestCol = rParam.aRefVariableCell.Col();
	SCROW nDestRow = rParam.aRefVariableCell.Row();
	SCTAB nDestTab = rParam.aRefVariableCell.Tab();

	ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
	if (!aTester.IsEditable())
	{
		ErrorMessage(aTester.GetMessageId());
		return;
	}

	if ( pDoc )
	{
		String  aTargetValStr;
		if ( rParam.pStrTargetVal != NULL )
			aTargetValStr = *(rParam.pStrTargetVal);

		String  aMsgStr;
		String	aResStr;
		double	nSolveResult;

		GetFrameWin()->EnterWait();

		sal_Bool  	bExact =
					pDoc->Solver(
						rParam.aRefFormulaCell.Col(),
						rParam.aRefFormulaCell.Row(),
						rParam.aRefFormulaCell.Tab(),
						nDestCol, nDestRow, nDestTab,
						aTargetValStr,
						nSolveResult );

		GetFrameWin()->LeaveWait();

		SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
		sal_uLong nFormat = 0;
		const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
		if ( pPattern )
			nFormat = pPattern->GetNumberFormat( pFormatter );
		Color* p;
		pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );

		if ( bExact )
		{
			aMsgStr  = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
			aMsgStr += String( aResStr );
			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
		}
		else
		{
			aMsgStr  = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 );
			aMsgStr += String( aResStr );
			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 );
		}

		MessBox aBox( GetViewData()->GetDialogParent(),
						WinBits(WB_YES_NO | WB_DEF_NO),
						ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
		sal_uInt16 nRetVal = aBox.Execute();

		if ( RET_YES == nRetVal )
			EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );

		GetViewData()->GetViewShell()->UpdateInputHandler( sal_True );
	}
}


//----------------------------------------------------------------------------
//	Mehrfachoperation

void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord )
{
	ScRange aRange;
	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
	{
		ScDocShell* pDocSh = GetViewData()->GetDocShell();
		ScMarkData& rMark = GetViewData()->GetMarkData();
		pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, sal_False );
	}
	else
		ErrorMessage(STR_NOMULTISELECT);
}


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

void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
									const Color& rColor, sal_uInt16 nFlags )
{
	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
	ScMarkData&	rMark	= GetViewData()->GetMarkData();
	SCTAB		nTab	= GetViewData()->GetTabNo();

	SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
	if (nFlags & SC_SCENARIO_COPYALL)
		SetTabNo( nNewTab, sal_True );			// SC_SCENARIO_COPYALL -> sichtbar
	else
	{
		SfxBindings& rBindings = GetViewData()->GetBindings();
		rBindings.Invalidate( SID_STATUS_DOCPOS );		// Statusbar
		rBindings.Invalidate( SID_TABLES_COUNT );
		rBindings.Invalidate( SID_SELECT_SCENARIO );
		rBindings.Invalidate( FID_TABLE_SHOW );
	}
}


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

void ScViewFunc::ExtendScenario()
{
	ScEditableTester aTester( this );
	if (!aTester.IsEditable())
	{
		ErrorMessage(aTester.GetMessageId());
		return;
	}

		//	Undo: Attribute anwenden

	ScDocument* pDoc = GetViewData()->GetDocument();
	ScPatternAttr aPattern( pDoc->GetPool() );
	aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
	aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
	ApplySelectionPattern(aPattern);
}


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

void ScViewFunc::UseScenario( const String& rName )
{
	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
	SCTAB		nTab	= GetViewData()->GetTabNo();

	DoneBlockMode();
	InitOwnBlockMode();
	pDocSh->UseScenario( nTab, rName );
}


//----------------------------------------------------------------------------
//	Tabelle einfuegen

sal_Bool ScViewFunc::InsertTable( const String& rName, SCTAB nTab, sal_Bool bRecord )
{
	//	Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
						InsertTable( nTab, rName, bRecord, sal_False );
	if (bSuccess)
		SetTabNo( nTab, sal_True );

	return bSuccess;
}

//----------------------------------------------------------------------------
//	Tabellen einfuegen

sal_Bool ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab,
											SCTAB nCount, sal_Bool bRecord )
{
	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
	ScDocument* pDoc 	= pDocSh->GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	SvStrings *pNameList= NULL;

	WaitObject aWait( GetFrameWin() );

	if (bRecord)
	{
		pNameList= new SvStrings;
		pDoc->BeginDrawUndo();							//	InsertTab erzeugt ein SdrUndoNewPage
	}

	sal_Bool bFlag=sal_False;

	String aValTabName;
	String *pStr;

	for(SCTAB i=0;i<nCount;i++)
	{
		if(pNames!=NULL)
		{
			pStr=pNames->GetObject(static_cast<sal_uInt16>(i));
		}
		else
		{
			aValTabName.Erase();
			pDoc->CreateValidTabName( aValTabName);
			pStr=&aValTabName;
		}

		if(pDoc->InsertTab( nTab+i,*pStr))
		{
			bFlag=sal_True;
			pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) );
		}
		else
		{
			break;
		}

		if(pNameList!=NULL)
			pNameList->Insert(new String(*pStr),pNameList->Count());

	}

	if (bFlag)
	{
		if (bRecord)
			pDocSh->GetUndoManager()->AddUndoAction(
						new ScUndoInsertTables( pDocSh, nTab, sal_False, pNameList));

		//	Views updaten:

		SetTabNo( nTab, sal_True );
		pDocSh->PostPaintExtras();
		pDocSh->SetDocumentModified();
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
		return sal_True;
	}
	else
	{
		return sal_False;
	}
}


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

sal_Bool ScViewFunc::AppendTable( const String& rName, sal_Bool bRecord )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc   = pDocSh->GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	WaitObject aWait( GetFrameWin() );

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

	if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
	{
		SCTAB nTab = pDoc->GetTableCount()-1;
		if (bRecord)
			pDocSh->GetUndoManager()->AddUndoAction(
						new ScUndoInsertTab( pDocSh, nTab, sal_True, rName));
		GetViewData()->InsertTab( nTab );
		SetTabNo( nTab, sal_True );
		pDocSh->PostPaintExtras();
		pDocSh->SetDocumentModified();
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
		return sal_True;
	}
	else
	{
		return sal_False;
	}
}


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

sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord )
{
	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
	ScDocument* pDoc 	= pDocSh->GetDocument();

	sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, sal_False );
	if (bSuccess)
	{
		SCTAB nNewTab = nTab;
		if ( nNewTab >= pDoc->GetTableCount() )
			--nNewTab;
		SetTabNo( nNewTab, sal_True );
	}
	return bSuccess;
}

sal_Bool ScViewFunc::DeleteTables(const SvShorts &TheTabs, sal_Bool bRecord )
{
	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
	ScDocument* pDoc 	= pDocSh->GetDocument();
    sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : sal_False;
	SCTAB		nNewTab = TheTabs.front();
	WaitObject aWait( GetFrameWin() );
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
		--nNewTab;

	sal_Bool bWasLinked = sal_False;
	ScDocument* pUndoDoc = NULL;
	ScRefUndoData* pUndoData = NULL;
	if (bRecord)
	{
		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
//		pUndoDoc->InitDrawLayer( pDocSh );
		SCTAB nCount = pDoc->GetTableCount();

//		pUndoDoc->InitUndo( pDoc, 0, nCount-1 );		// incl. Ref.

		String aOldName;
        for (size_t i = 0; i < TheTabs.size(); i++)
        {
            SCTAB nTab = TheTabs[i];
			if (i==0)
				pUndoDoc->InitUndo( pDoc, nTab,nTab, sal_True,sal_True );	// incl. Spalten/Zeilenflags
			else
				pUndoDoc->AddUndoTab( nTab,nTab, sal_True,sal_True );		// incl. Spalten/Zeilenflags

			pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,sal_False, pUndoDoc );
			pDoc->GetName( nTab, aOldName );
			pUndoDoc->RenameTab( nTab, aOldName, sal_False );
			if (pDoc->IsLinked(nTab))
			{
				bWasLinked = sal_True;
				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 ) );

			if ( pDoc->IsTabProtected( nTab ) )
                pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));

			//	Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
			//		pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
		}

		pUndoDoc->AddUndoTab( 0, nCount-1 );			//	alle Tabs fuer Referenzen

		pDoc->BeginDrawUndo();							//	DeleteTab erzeugt ein SdrUndoDelPage

		pUndoData = new ScRefUndoData( pDoc );
	}

	sal_Bool bDelDone = sal_False;

    for (size_t i = TheTabs.size(); i > 0; i--)
    {
        String sCodeName;
        sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i-1], sCodeName );
        if (pDoc->DeleteTab( TheTabs[i-1], pUndoDoc ))
		{
			bDelDone = sal_True;
            if( bVbaEnabled )
            {
                if( bHasCodeName )
                {
                    VBA_DeleteModule( *pDocSh, sCodeName );
                }
            }
            pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i-1] ) );
		}
	}
	if (bRecord)
	{
		pDocSh->GetUndoManager()->AddUndoAction(
					new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
											pUndoDoc, pUndoData ));
	}


	if (bDelDone)
	{
		if ( nNewTab >= pDoc->GetTableCount() )
			nNewTab = pDoc->GetTableCount() - 1;

		SetTabNo( nNewTab, sal_True );

		if (bWasLinked)
		{
			pDocSh->UpdateLinks();				// Link-Manager updaten
			GetViewData()->GetBindings().Invalidate(SID_LINKS);
		}

		pDocSh->PostPaintExtras();
		pDocSh->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 ) );
	}
	else
	{
		delete pUndoDoc;
		delete pUndoData;
	}
	return bDelDone;
}


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

sal_Bool ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
{
	//	Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
						RenameTable( nTab, rName, sal_True, sal_False );
	if (bSuccess)
	{
		//	Der Tabellenname koennte in einer Formel vorkommen...
		GetViewData()->GetViewShell()->UpdateInputHandler();
	}
	return bSuccess;
}


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

bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
{
    bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, sal_False );
    if (bSuccess)
    {
        GetViewData()->GetViewShell()->UpdateInputHandler();
    }
    return bSuccess;
}

bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
{
    bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, sal_False );
    if (bSuccess)
    {
        GetViewData()->GetViewShell()->UpdateInputHandler();
    }
    return bSuccess;
}

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

void ScViewFunc::InsertAreaLink( const String& rFile,
									const String& rFilter, const String& rOptions,
									const String& rSource, sal_uLong nRefresh )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	SCCOL nPosX = GetViewData()->GetCurX();
	SCROW nPosY = GetViewData()->GetCurY();
	SCTAB nTab = GetViewData()->GetTabNo();
	ScAddress aPos( nPosX, nPosY, nTab );

    pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, sal_False, sal_False );
}


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

void ScViewFunc::InsertTableLink( const String& rFile,
									const String& rFilter, const String& rOptions,
									const String& rTabName )
{
	String aFilterName = rFilter;
	String aOpt = rOptions;
	ScDocumentLoader aLoader( rFile, aFilterName, aOpt );
	if (!aLoader.IsError())
	{
		ScDocShell* pSrcSh = aLoader.GetDocShell();
		ScDocument* pSrcDoc = pSrcSh->GetDocument();
		SCTAB nTab = MAXTAB+1;
		if (!rTabName.Len())				// kein Name angegeben -> erste Tabelle
			nTab = 0;
		else
		{
			String aTemp;
			SCTAB nCount = pSrcDoc->GetTableCount();
			for (SCTAB i=0; i<nCount; i++)
			{
				pSrcDoc->GetName( i, aTemp );
				if ( aTemp == rTabName )
					nTab = i;
			}
		}

		if ( nTab <= MAXTAB )
			ImportTables( pSrcSh, 1, &nTab, sal_True,
						GetViewData()->GetTabNo() );
	}
}


//----------------------------------------------------------------------------
//	Tabellen aus anderem Dokument kopieren / linken

void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
								SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab )
{
	ScDocument* pSrcDoc = pSrcShell->GetDocument();

	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	sal_Bool bUndo(pDoc->IsUndoEnabled());
	//SCTAB nTab = GetViewData()->GetTabNo();

	sal_Bool bError = sal_False;
	sal_Bool bRefs = sal_False;
	sal_Bool bName = sal_False;

	if (pSrcDoc->GetDrawLayer())
		pDocSh->MakeDrawLayer();

	if (bUndo)
		pDoc->BeginDrawUndo();			// drawing layer must do its own undo actions

	SCTAB nInsCount = 0;
	SCTAB i;
	for( i=0; i<nCount; i++ )
	{	// #63304# insert sheets first and update all references
		String aName;
		pSrcDoc->GetName( pSrcTabs[i], aName );
		pDoc->CreateValidTabName( aName );
		if ( !pDoc->InsertTab( nTab+i, aName ) )
		{
			bError = sal_True;		// total error
			break;	// for
		}
		++nInsCount;
	}
	for (i=0; i<nCount && !bError; i++)
	{
		SCTAB nSrcTab = pSrcTabs[i];
		SCTAB nDestTab1=nTab+i;
		sal_uLong nErrVal = pDoc->TransferTab( pSrcDoc, nSrcTab, nDestTab1,
			sal_False );		// no insert

		switch (nErrVal)
		{
			case 0:						// interner Fehler oder voll Fehler
				bError = sal_True;
				break;
			case 2:
				bRefs = sal_True;
				break;
			case 3:
				bName = sal_True;
				break;
			case 4:
				bRefs = bName = sal_True;
				break;
		}

		// TransferTab doesn't copy drawing objects with bInsertNew=FALSE
		if ( !bError )
			pDoc->TransferDrawPage( pSrcDoc, nSrcTab, nDestTab1 );

		if(!bError &&pSrcDoc->IsScenario(nSrcTab))
		{
			String aComment;
			Color  aColor;
			sal_uInt16 nFlags;

			pSrcDoc->GetScenarioData(nSrcTab, aComment,aColor, nFlags);
			pDoc->SetScenario( nDestTab1,sal_True);
			pDoc->SetScenarioData( nTab+i,aComment,aColor,nFlags);
			sal_Bool bActive = pSrcDoc->IsActiveScenario(nSrcTab );
			pDoc->SetActiveScenario( nDestTab1, bActive );
			sal_Bool bVisible=pSrcDoc->IsVisible(nSrcTab);
			pDoc->SetVisible(nDestTab1,bVisible );

		}
	}

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

		SfxMedium* pMed = pSrcShell->GetMedium();
		String aFileName = pMed->GetName();
		String aFilterName;
		if (pMed->GetFilter())
			aFilterName = pMed->GetFilter()->GetFilterName();
		String aOptions = ScDocumentLoader::GetOptions(*pMed);

		sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );

		sal_uLong nRefresh = 0;
		String aTabStr;
		for (i=0; i<nInsCount; i++)
		{
			pSrcDoc->GetName( pSrcTabs[i], aTabStr );
			pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
						aFileName, aFilterName, aOptions, aTabStr, nRefresh );
		}

		if (!bWasThere)			// Link pro Quelldokument nur einmal eintragen
		{
			ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
			pLink->SetInCreate( sal_True );
			pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
			pLink->Update();
			pLink->SetInCreate( sal_False );

			SfxBindings& rBindings = GetViewData()->GetBindings();
			rBindings.Invalidate( SID_LINKS );
		}
	}


	if (bUndo)
	{
		pDocSh->GetUndoManager()->AddUndoAction(
				new ScUndoImportTab( pDocSh, nTab, nCount, bLink ) );
	}

	for (i=0; i<nInsCount; i++)
		GetViewData()->InsertTab(nTab);
	SetTabNo(nTab,sal_True);
	pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
								PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );

	SfxApplication* pSfxApp = SFX_APP();
	pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
	pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );

	pDocSh->PostPaintExtras();
	pDocSh->PostPaintGridAll();
	pDocSh->SetDocumentModified();

	if (bRefs)
		ErrorMessage(STR_ABSREFLOST);
	if (bName)
		ErrorMessage(STR_NAMECONFLICT);
}


//----------------------------------------------------------------------------
//	Tabelle in anderes Dokument verschieben / kopieren

void ScViewFunc::MoveTable( sal_uInt16 nDestDocNo, SCTAB nDestTab, sal_Bool bCopy )
{
	ScDocument* pDoc	   = GetViewData()->GetDocument();
	ScDocShell* pDocShell  = GetViewData()->GetDocShell();
	ScDocument*	pDestDoc   = NULL;
	ScDocShell* pDestShell = NULL;
	ScTabViewShell* pDestViewSh = NULL;
	sal_Bool bUndo (pDoc->IsUndoEnabled());

	sal_Bool bNewDoc = ( nDestDocNo == SC_DOC_NEW );
	if ( bNewDoc )
	{
        nDestTab = 0;           // als erstes einfuegen

		//	ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten:

		String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/"));
		aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP ));				// "scalc"
		SfxStringItem aItem( SID_FILE_NAME, aUrl );
		SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );

		const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
					SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
		if ( pRetItem )
		{
			if ( dynamic_cast< const SfxObjectItem* >(pRetItem) )
			{
				pDestShell = dynamic_cast< ScDocShell* >( ((const SfxObjectItem*)pRetItem)->GetShell() );
			}
			else if ( dynamic_cast< const SfxViewFrameItem* >(pRetItem) )
			{
				SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
				if (pFrm)
					pDestShell = dynamic_cast< ScDocShell* >( pFrm->GetObjectShell() );
			}
			if (pDestShell)
				pDestViewSh = pDestShell->GetBestViewShell();
		}
	}
	else
		pDestShell = ScDocShell::GetShellByNum( nDestDocNo );

	if (!pDestShell)
	{
		DBG_ERROR("Dest-Doc nicht gefunden !!!");
		return;
	}

	pDestDoc = pDestShell->GetDocument();

	SCTAB nTab = GetViewData()->GetTabNo();

	if (pDestDoc != pDoc)
	{
		if (bNewDoc)
		{
			while (pDestDoc->GetTableCount() > 1)
				pDestDoc->DeleteTab(0);
			pDestDoc->RenameTab( 0,
						String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")),
						sal_False );
		}

		ScMarkData& rMark		= GetViewData()->GetMarkData();
		SCTAB		nTabCount	= pDoc->GetTableCount();
		SCTAB		nTabSelCount = rMark.GetSelectCount();

		SvShorts	TheTabs;

		for(SCTAB i=0;i<nTabCount;i++)
		{
			if(rMark.GetTableSelect(i))
			{
				String aTabName;
				pDoc->GetName( i, aTabName);
				TheTabs.push_back(i);
				for(SCTAB j=i+1;j<nTabCount;j++)
				{
					if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
					{
						pDoc->GetName( j, aTabName);
						TheTabs.push_back(j);
						i=j;
					}
					else break;
				}
			}
		}

		GetFrameWin()->EnterWait();

		if (pDoc->GetDrawLayer())
			pDestShell->MakeDrawLayer();

		if (!bNewDoc && bUndo)
			pDestDoc->BeginDrawUndo();		// drawing layer must do its own undo actions

		sal_uLong nErrVal =1;
		if(nDestTab==SC_TAB_APPEND)
            nDestTab=pDestDoc->GetTableCount();
		SCTAB nDestTab1=nDestTab;
		for( size_t j=0; j<TheTabs.size(); j++, nDestTab1++ )
		{	// #63304# insert sheets first and update all references
			String aName;
			pDoc->GetName( TheTabs[j], aName );
			pDestDoc->CreateValidTabName( aName );
			if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
			{
				nErrVal = 0;		// total error
				break;	// for
			}
		}
		if ( nErrVal > 0 )
		{
			nDestTab1 = nDestTab;
			for(size_t i=0;i<TheTabs.size();i++)
			{
				nErrVal = pDestDoc->TransferTab( pDoc, TheTabs[i], nDestTab1,
					sal_False );		// no insert

				// TransferTab doesn't copy drawing objects with bInsertNew=FALSE
				if ( nErrVal > 0 )
					pDestDoc->TransferDrawPage( pDoc, TheTabs[i], nDestTab1 );

				if(nErrVal>0 && pDoc->IsScenario(TheTabs[i]))
				{
					String aComment;
					Color  aColor;
					sal_uInt16 nFlags;

					pDoc->GetScenarioData(TheTabs[i], aComment,aColor, nFlags);
					pDestDoc->SetScenario(nDestTab1,sal_True);
					pDestDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
					sal_Bool bActive = pDoc->IsActiveScenario(TheTabs[i]);
					pDestDoc->SetActiveScenario(nDestTab1, bActive );

					sal_Bool bVisible=pDoc->IsVisible(TheTabs[i]);
					pDestDoc->SetVisible(nDestTab1,bVisible );

				}

				if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
                    pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));

				nDestTab1++;
			}
		}
		String sName;
		if (!bNewDoc && bUndo)
		{
			pDestDoc->GetName(nDestTab, sName);
			pDestShell->GetUndoManager()->AddUndoAction(
                            new ScUndoImportTab( pDestShell, nDestTab,
                                static_cast<SCTAB>(TheTabs.size()), sal_False));

		}
		else
		{
			pDestShell->GetUndoManager()->Clear();
		}

		GetFrameWin()->LeaveWait();
		switch (nErrVal)
		{
			case 0:						// interner Fehler oder voll Fehler
			{
				ErrorMessage(STR_TABINSERT_ERROR);
				return;
			}
            //break;
			case 2:
				ErrorMessage(STR_ABSREFLOST);
			break;
			case 3:
				ErrorMessage(STR_NAMECONFLICT);
			break;
			case 4:
			{
				ErrorMessage(STR_ABSREFLOST);
				ErrorMessage(STR_NAMECONFLICT);
			}
			break;
			default:
			break;
		}
		//pDestShell->GetUndoManager()->Clear();		//! Undo implementieren !!!
/*
		String sName;
		pDestDoc->GetName(nDestTab, sName);
		pDestShell->GetUndoManager()->AddUndoAction(
						new ScUndoInsertTab( pDestShell, nDestTab, sal_True, sName ) );
*/
		if (!bCopy)
		{
			if(nTabCount!=nTabSelCount)
				DeleteTables(TheTabs);// incl. Paint & Undo
			else
				ErrorMessage(STR_TABREMOVE_ERROR);
		}

		if (bNewDoc)
		{
			//	ChartListenerCollection must be updated before DeleteTab
			if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
				pDestDoc->UpdateChartListenerCollection();

			pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.size()));   // first old table
//?			pDestDoc->SelectTable(0, sal_True);		// neue erste Tabelle selektieren
			if (pDestViewSh)
				pDestViewSh->TabChanged();		// Pages auf dem Drawing-Layer
			pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
									PAINT_GRID | PAINT_TOP | PAINT_LEFT |
									PAINT_EXTRAS | PAINT_SIZE );
			//	PAINT_SIZE fuer Gliederung
		}
		else
		{
			pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
			pDestShell->PostPaintExtras();
			pDestShell->PostPaintGridAll();
		}

		TheTabs.clear();

		pDestShell->SetDocumentModified();
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
	}
	else					// within the documents
	{

		ScMarkData& rMark		= GetViewData()->GetMarkData();
		SCTAB		nTabCount	= pDoc->GetTableCount();

		SvShorts	TheTabs;
		SvShorts	TheDestTabs;
		SvStrings	TheTabNames;
		String		aDestName;
		String		*pString;

		for(SCTAB i=0;i<nTabCount;i++)
		{
			if(rMark.GetTableSelect(i))
			{
				String aTabName;
				pDoc->GetName( i, aTabName);
				TheTabNames.Insert(new String(aTabName),TheTabNames.Count());

				for(SCTAB j=i+1;j<nTabCount;j++)
				{
					if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
					{
						pDoc->GetName( j, aTabName);
						TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
						i=j;
					}
					else break;
				}

			}
		}

		if (bCopy && bUndo)
			pDoc->BeginDrawUndo();			// drawing layer must do its own undo actions

		pDoc->GetName( nDestTab, aDestName);
		SCTAB nDestTab1=nDestTab;
		SCTAB nMovTab=0;
		for(int j=0;j<TheTabNames.Count();j++)
		{
			nTabCount	= pDoc->GetTableCount();
            pString=TheTabNames[sal::static_int_cast<sal_uInt16>(j)];
			if(!pDoc->GetTable(*pString,nMovTab))
			{
				nMovTab=nTabCount;
			}
			if(!pDoc->GetTable(aDestName,nDestTab1))
			{
				nDestTab1=nTabCount;
			}
			pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, sal_False );	// Undo ist hier

			if(bCopy && pDoc->IsScenario(nMovTab))
			{
				String aComment;
				Color  aColor;
				sal_uInt16 nFlags;

				pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
				pDoc->SetScenario(nDestTab1,sal_True);
				pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
				sal_Bool bActive = pDoc->IsActiveScenario(nMovTab );
				pDoc->SetActiveScenario( nDestTab1, bActive );
				sal_Bool bVisible=pDoc->IsVisible(nMovTab);
				pDoc->SetVisible(nDestTab1,bVisible );
			}

			TheTabs.push_back(nMovTab);

			if(!bCopy)
			{
				if(!pDoc->GetTable(*pString,nDestTab1))
				{
					nDestTab1=nTabCount;
				}
			}

			TheDestTabs.push_back(nDestTab1);
			delete pString;
		}

		nTab = GetViewData()->GetTabNo();

		if (bUndo)
		{
			if (bCopy)
			{
				pDocShell->GetUndoManager()->AddUndoAction(
						new ScUndoCopyTab( pDocShell, TheTabs, TheDestTabs));
			}
			else
			{
				pDocShell->GetUndoManager()->AddUndoAction(
						new ScUndoMoveTab( pDocShell, TheTabs, TheDestTabs));
			}
		}

		SCTAB nNewTab = nDestTab;
		if (nNewTab == SC_TAB_APPEND)
			nNewTab = pDoc->GetTableCount()-1;
		else if (!bCopy && nTab<nDestTab)
			nNewTab--;

		SetTabNo( nNewTab, sal_True );

        //#i29848# adjust references to data on the copied sheet
        if( bCopy )
            ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab );
	}
}


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

void ScViewFunc::ShowTable( const String& rName )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	sal_Bool bUndo(pDoc->IsUndoEnabled());
	sal_Bool bFound = sal_False;
	SCTAB nPos = 0;
	String aTabName;
	SCTAB nCount = pDoc->GetTableCount();
	for (SCTAB i=0; i<nCount; i++)
	{
		pDoc->GetName( i, aTabName );
		if ( aTabName == rName )
		{
			nPos = i;
			bFound = sal_True;
		}
	}

	if (bFound)
	{
		pDoc->SetVisible( nPos, sal_True );
		if (bUndo)
		{
			pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, sal_True ) );
		}
		SetTabNo( nPos, sal_True );
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
		pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
		pDocSh->SetDocumentModified();
	}
	else
		Sound::Beep();
}


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

void ScViewFunc::HideTable( SCTAB nTab )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	sal_Bool bUndo(pDoc->IsUndoEnabled());
	SCTAB nVisible = 0;
	SCTAB nCount = pDoc->GetTableCount();
	for (SCTAB i=0; i<nCount; i++)
	{
		if (pDoc->IsVisible(i))
			++nVisible;
	}

	if (nVisible > 1)
	{
		pDoc->SetVisible( nTab, sal_False );
		if (bUndo)
		{
			pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, sal_False ) );
		}

		//	Views updaten:
		pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );

		SetTabNo( nTab, sal_True );
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
		pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
		pDocSh->SetDocumentModified();
	}
	else
		Sound::Beep();
}


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

void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
{
	ScEditableTester aTester( this );
	if (!aTester.IsEditable())
	{
		ErrorMessage(aTester.GetMessageId());
		return;
	}

	const sal_Unicode* pChar	= rStr.GetBuffer();
	ScTabViewShell* pViewShell	= GetViewData()->GetViewShell();
	SvxFontItem		aFontItem( rFont.GetFamily(),
							   rFont.GetName(),
							   rFont.GetStyleName(),
							   rFont.GetPitch(),
							   rFont.GetCharSet(),
							   ATTR_FONT );

	//	if string contains WEAK characters, set all fonts
	sal_uInt8 nScript;
	ScDocument* pDoc = GetViewData()->GetDocument();
	if ( pDoc->HasStringWeakCharacters( rStr ) )
		nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
	else
		nScript = pDoc->GetStringScriptType( rStr );

	SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
	aSetItem.PutItemForScriptType( nScript, aFontItem );
	ApplyUserItemSet( aSetItem.GetItemSet() );

	while ( *pChar )
		pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
}


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

void ScViewFunc::UpdateLineAttrs( SvxBorderLine&	   rLine,
								  const SvxBorderLine* pDestLine,
								  const SvxBorderLine* pSrcLine,
								  sal_Bool 				   bColor )
{
	if ( pSrcLine && pDestLine )
	{
		if ( bColor )
		{
			rLine.SetColor		( pSrcLine->GetColor() );
			rLine.SetOutWidth	( pDestLine->GetOutWidth() );
			rLine.SetInWidth	( pDestLine->GetInWidth() );
			rLine.SetDistance	( pDestLine->GetDistance() );
		}
		else
		{
			rLine.SetColor		( pDestLine->GetColor() );
			rLine.SetOutWidth	( pSrcLine->GetOutWidth() );
			rLine.SetInWidth	( pSrcLine->GetInWidth() );
			rLine.SetDistance	( pSrcLine->GetDistance() );
		}
	}
}


#define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
	pBoxLine = aBoxItem.Get##LINE();								\
	if ( pBoxLine )													\
	{																\
		if ( pLine )												\
		{															\
			UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly );	\
			aBoxItem.SetLine( &aLine, BOXLINE );					\
		}															\
		else														\
			aBoxItem.SetLine( NULL, BOXLINE );						\
	}


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

void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
										 sal_Bool bColorOnly )
{
	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
	sal_Bool bOnlyNotBecauseOfMatrix;
	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

	ScDocument*				pDoc = GetViewData()->GetDocument();
    ScMarkData aFuncMark( GetViewData()->GetMarkData() );       // local copy for UnmarkFiltered
    ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
	ScDocShell*				pDocSh = GetViewData()->GetDocShell();
	const ScPatternAttr*	pSelAttrs = GetSelectionPattern();
    const SfxItemSet&       rSelItemSet = pSelAttrs->GetItemSet();

	const SfxPoolItem*		pBorderAttr	= NULL;
    SfxItemState            eItemState = rSelItemSet.GetItemState( ATTR_BORDER, sal_True, &pBorderAttr );

    const SfxPoolItem*      pTLBRItem = 0;
    SfxItemState            eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem );

    const SfxPoolItem*      pBLTRItem = 0;
    SfxItemState            eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem );

    // any of the lines visible?
    if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
	{
        // none of the lines don't care?
        if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
		{
			SfxItemSet*		pOldSet	= new SfxItemSet(
											*(pDoc->GetPool()),
											ATTR_PATTERN_START,
											ATTR_PATTERN_END );
			SfxItemSet*		pNewSet	= new SfxItemSet(
											*(pDoc->GetPool()),
											ATTR_PATTERN_START,
											ATTR_PATTERN_END );

			//------------------------------------------------------------
			const SvxBorderLine*	pBoxLine = NULL;
			SvxBorderLine			aLine;

			// hier wird die pBoxLine benutzt:

            if( pBorderAttr )
            {
                SvxBoxItem      aBoxItem( *(const SvxBoxItem*)pBorderAttr );
                SvxBoxInfoItem  aBoxInfoItem( ATTR_BORDER_INNER );

                SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
                SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
                SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
                SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)

                aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
                aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
                aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen

                pOldSet->Put( *pBorderAttr );
                pNewSet->Put( aBoxItem );
                pNewSet->Put( aBoxInfoItem );
            }

            if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
            {
                SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
                UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
                aTLBRItem.SetLine( &aLine );
                pOldSet->Put( *pTLBRItem );
                pNewSet->Put( aTLBRItem );
            }

            if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
            {
                SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
                UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
                aBLTRItem.SetLine( &aLine );
                pOldSet->Put( *pBLTRItem );
                pNewSet->Put( aBLTRItem );
            }

			ApplyAttributes( pNewSet, pOldSet );

			delete pOldSet;
			delete pNewSet;
		}
		else // if ( eItemState == SFX_ITEM_DONTCARE )
		{
			aFuncMark.MarkToMulti();
			pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
		}

		ScRange aMarkRange;
		aFuncMark.GetMultiMarkArea( aMarkRange );
		SCCOL nStartCol = aMarkRange.aStart.Col();
		SCROW nStartRow = aMarkRange.aStart.Row();
		SCTAB nStartTab = aMarkRange.aStart.Tab();
		SCCOL nEndCol = aMarkRange.aEnd.Col();
		SCROW nEndRow = aMarkRange.aEnd.Row();
		SCTAB nEndTab = aMarkRange.aEnd.Tab();
		pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
						   nEndCol, nEndRow, nEndTab,
						   PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );

		pDocSh->UpdateOle( GetViewData() );
		pDocSh->SetDocumentModified();
	}
}

#undef SET_LINE_ATTRIBUTES


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

void ScViewFunc::SetConditionalFormat( const ScConditionalFormat& rNew )
{
	ScDocument* pDoc = GetViewData()->GetDocument();
	sal_uLong nIndex = pDoc->AddCondFormat(rNew);			// dafuer gibt's kein Undo
	SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex );

	ApplyAttr( aItem );			// mit Paint und Undo...
}


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

void ScViewFunc::SetValidation( const ScValidationData& rNew )
{
	ScDocument* pDoc = GetViewData()->GetDocument();
	sal_uLong nIndex = pDoc->AddValidationEntry(rNew);		// dafuer gibt's kein Undo
	SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );

	ApplyAttr( aItem );			// mit Paint und Undo...
}


