/**************************************************************
 *
 * 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 <svx/algitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/editobj.hxx>
#include <editeng/editview.hxx>
#include <editeng/langitem.hxx>
#include <editeng/scripttypeitem.hxx>
#include <sfx2/bindings.hxx>
#include <svl/zforlist.hxx>
#include <svl/zformat.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/sound.hxx>
#include <vcl/virdev.hxx>
#include <vcl/waitobj.hxx>
#include <vcl/wrkwin.hxx>
#include <stdlib.h>				// qsort

#include "viewfunc.hxx"
#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "attrib.hxx"
#include "patattr.hxx"
#include "docpool.hxx"
#include "uiitems.hxx"
#include "sc.hrc"
#include "undocell.hxx"
#include "undoblk.hxx"
#include "undotab.hxx"
#include "refundo.hxx"
#include "dbcolect.hxx"
#include "olinetab.hxx"
#include "rangeutl.hxx"
#include "rangenam.hxx"
#include "globstr.hrc"
#include "global.hxx"
#include "stlsheet.hxx"
#include "editutil.hxx"
//CHINA001 #include "namecrea.hxx"			// wegen Flags
#include "cell.hxx"
#include "scresid.hxx"
#include "inputhdl.hxx"
#include "scmod.hxx"
#include "inputopt.hxx"
#include "compiler.hxx"
#include "docfunc.hxx"
#include "appoptio.hxx"
#include "dociter.hxx"
#include "sizedev.hxx"
#include "editable.hxx"
#include "scui_def.hxx" //CHINA001
#include "funcdesc.hxx"
#include "docuno.hxx"
#include "cellsuno.hxx"
//==================================================================

ScViewFunc::ScViewFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
	ScTabView( pParent, rDocSh, pViewShell ),
	bFormatValid( sal_False )
{
}

//UNUSED2008-05  ScViewFunc::ScViewFunc( Window* pParent, const ScViewFunc& rViewFunc, ScTabViewShell* pViewShell ) :
//UNUSED2008-05      ScTabView( pParent, rViewFunc, pViewShell ),
//UNUSED2008-05      bFormatValid( sal_False )
//UNUSED2008-05  {
//UNUSED2008-05  }

ScViewFunc::~ScViewFunc()
{
}

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

void ScViewFunc::StartFormatArea()
{
	//	ueberhaupt aktiviert?
	if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
		return;

	//	start only with single cell (marked or cursor position)
	ScRange aMarkRange;
	sal_Bool bOk = (GetViewData()->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
	if ( bOk && aMarkRange.aStart != aMarkRange.aEnd )
		bOk = sal_False;

	if (bOk)
	{
		bFormatValid = sal_True;
		aFormatSource = aMarkRange.aStart;
		aFormatArea = ScRange( aFormatSource );
	}
	else
		bFormatValid = sal_False;		// keinen alten Bereich behalten
}

sal_Bool ScViewFunc::TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bAttrChanged )
{
	//	ueberhaupt aktiviert?
	if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
		return sal_False;

	//	Test: Eingabe mit Zahlformat (bAttrChanged) immer als neue Attributierung behandeln
	//	(alte Area verwerfen). Wenn das nicht gewollt ist, den if-Teil weglassen:
	if ( bAttrChanged )
	{
		StartFormatArea();
		return sal_False;
	}

	//!	Abfrage, ob Zelle leer war ???

	sal_Bool bFound = sal_False;
	ScRange aNewRange = aFormatArea;
	if ( bFormatValid && nTab == aFormatSource.Tab() )
	{
		if ( nRow >= aFormatArea.aStart.Row() && nRow <= aFormatArea.aEnd.Row() )
		{
			//	innerhalb ?
			if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
			{
				bFound = sal_True;			// Bereich nicht aendern
			}
			//	links ?
			if ( nCol+1 == aFormatArea.aStart.Col() )
			{
				bFound = sal_True;
				aNewRange.aStart.SetCol( nCol );
			}
			//	rechts ?
			if ( nCol == aFormatArea.aEnd.Col()+1 )
			{
				bFound = sal_True;
				aNewRange.aEnd.SetCol( nCol );
			}
		}
		if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
		{
			//	oben ?
			if ( nRow+1 == aFormatArea.aStart.Row() )
			{
				bFound = sal_True;
				aNewRange.aStart.SetRow( nRow );
			}
			//	unten ?
			if ( nRow == aFormatArea.aEnd.Row()+1 )
			{
				bFound = sal_True;
				aNewRange.aEnd.SetRow( nRow );
			}
		}
	}

	if (bFound)
		aFormatArea = aNewRange;	// erweitern
	else
	{
		bFormatValid = sal_False;		// ausserhalb -> abbrechen
		if ( bAttrChanged )			// Wert mit Zahlformat eingegeben?
			StartFormatArea();		// dann ggf. neu starten
	}

	return bFound;
}

void ScViewFunc::DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab,
									sal_Bool bAttrChanged, sal_Bool bAddUndo )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	if (bAddUndo && !pDoc->IsUndoEnabled())
		bAddUndo = sal_False;

	const ScPatternAttr* pSource = pDoc->GetPattern(
							aFormatSource.Col(), aFormatSource.Row(), nTab );
	if ( !((const ScMergeAttr&)pSource->GetItem(ATTR_MERGE)).IsMerged() )
	{
		const ScPatternAttr* pDocOld = pDoc->GetPattern( nCol, nRow, nTab );
		//	pDocOld ist nur bis zum Apply... gueltig!

		ScPatternAttr* pOldPattern = NULL;
		if ( bAddUndo )
			pOldPattern = new ScPatternAttr( *pDocOld );

		const ScStyleSheet* pSrcStyle = pSource->GetStyleSheet();
		if ( pSrcStyle && pSrcStyle != pDocOld->GetStyleSheet() )
			pDoc->ApplyStyle( nCol, nRow, nTab, *pSrcStyle );
		pDoc->ApplyPattern( nCol, nRow, nTab, *pSource );
		AdjustRowHeight( nRow, nRow, sal_True );				//! nicht doppelt ?

		if ( bAddUndo )
		{
			const ScPatternAttr* pNewPattern = pDoc->GetPattern( nCol, nRow, nTab );

			pDocSh->GetUndoManager()->AddUndoAction(
						new ScUndoCursorAttr( pDocSh, nCol, nRow, nTab,
											  pOldPattern, pNewPattern, pSource,
											  sal_True ) );

			delete pOldPattern;		// wird im Undo kopiert (Pool)
		}
	}

	if ( bAttrChanged )								// Wert mit Zahlformat eingegeben?
		aFormatSource.Set( nCol, nRow, nTab );		// dann als neue Quelle
}

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

//		Hilfsroutinen

sal_uInt16 ScViewFunc::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, sal_Bool bFormula )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	ScMarkData& rMark = GetViewData()->GetMarkData();

	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_uInt16 nTwips = pDoc->GetOptimalColWidth( nCol, nTab, aProv.GetDevice(),
								nPPTX, nPPTY, aZoomX, aZoomY, bFormula, &rMark );
	return nTwips;
}

sal_Bool ScViewFunc::SelectionEditable( sal_Bool* pOnlyNotBecauseOfMatrix /* = NULL */ )
{
	sal_Bool bRet;
	ScDocument* pDoc = GetViewData()->GetDocument();
	ScMarkData& rMark = GetViewData()->GetMarkData();
	if (rMark.IsMarked() || rMark.IsMultiMarked())
		bRet = pDoc->IsSelectionEditable( rMark, pOnlyNotBecauseOfMatrix );
	else
	{
		SCCOL nCol = GetViewData()->GetCurX();
		SCROW nRow = GetViewData()->GetCurY();
		SCTAB nTab = GetViewData()->GetTabNo();
		bRet = pDoc->IsBlockEditable( nTab, nCol, nRow, nCol, nRow,
			pOnlyNotBecauseOfMatrix );
	}
	return bRet;
}

#ifndef	LRU_MAX
#define LRU_MAX 10
#endif

sal_Bool lcl_FunctionKnown( sal_uInt16 nOpCode )
{
	const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
	if ( pFuncList )
	{
		sal_uLong nCount = pFuncList->GetCount();
		for (sal_uLong i=0; i<nCount; i++)
			if ( pFuncList->GetFunction(i)->nFIndex == nOpCode )
				return sal_True;
	}
	return sal_False;
}

sal_Bool lcl_AddFunction( ScAppOptions& rAppOpt, sal_uInt16 nOpCode )
{
	sal_uInt16 nOldCount = rAppOpt.GetLRUFuncListCount();
	sal_uInt16* pOldList = rAppOpt.GetLRUFuncList();
	sal_uInt16 nPos;
	for (nPos=0; nPos<nOldCount; nPos++)
		if (pOldList[nPos] == nOpCode)			// is the function already in the list?
		{
			if ( nPos == 0 )
				return sal_False;					// already at the top -> no change

			//	count doesn't change, so the original array is modified

			for (sal_uInt16 nCopy=nPos; nCopy>0; nCopy--)
				pOldList[nCopy] = pOldList[nCopy-1];
			pOldList[0] = nOpCode;

			return sal_True;						// list has changed
		}

	if ( !lcl_FunctionKnown( nOpCode ) )
		return sal_False;							// not in function list -> no change

	sal_uInt16 nNewCount = Min( (sal_uInt16)(nOldCount + 1), (sal_uInt16)LRU_MAX );
	sal_uInt16 nNewList[LRU_MAX];
	nNewList[0] = nOpCode;
	for (nPos=1; nPos<nNewCount; nPos++)
		nNewList[nPos] = pOldList[nPos-1];
	rAppOpt.SetLRUFuncList( nNewList, nNewCount );

	return sal_True;								// list has changed
}

//		eigentliche Funktionen

//	Eingabe - Undo OK

void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString,
                            sal_Bool bRecord, const EditTextObject* pData )
{
	ScDocument* pDoc = GetViewData()->GetDocument();
	ScMarkData& rMark = GetViewData()->GetMarkData();
	SCTAB nTabCount = pDoc->GetTableCount();
	SCTAB nSelCount = rMark.GetSelectCount();
	SCTAB i;
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocShellModificator aModificator( *pDocSh );

	ScEditableTester aTester( pDoc, nCol,nRow, nCol,nRow, rMark );
	if (aTester.IsEditable())
	{
		sal_Bool bEditDeleted = sal_False;
		sal_uInt8 nOldScript = 0;

		ScBaseCell** ppOldCells	= NULL;
		sal_Bool* pHasFormat		= NULL;
		sal_uLong* pOldFormats		= NULL;
		SCTAB* pTabs			= NULL;
		SCTAB nUndoPos = 0;
        EditTextObject* pUndoData = NULL;
		if ( bRecord )
		{
			ppOldCells		= new ScBaseCell*[nSelCount];
			pHasFormat		= new sal_Bool[nSelCount];
			pOldFormats		= new sal_uLong[nSelCount];
			pTabs			= new SCTAB[nSelCount];
			nUndoPos = 0;

			for (i=0; i<nTabCount; i++)
				if (rMark.GetTableSelect(i))
				{
					pTabs[nUndoPos] = i;
					ScBaseCell* pDocCell;
					pDoc->GetCell( nCol, nRow, i, pDocCell );
					if ( pDocCell )
					{
                        ppOldCells[nUndoPos] = pDocCell->CloneWithoutNote( *pDoc );
						if ( pDocCell->GetCellType() == CELLTYPE_EDIT )
							bEditDeleted = sal_True;

						sal_uInt8 nDocScript = pDoc->GetScriptType( nCol, nRow, i, pDocCell );
						if ( nOldScript == 0 )
							nOldScript = nDocScript;
						else if ( nDocScript != nOldScript )
							bEditDeleted = sal_True;
					}
					else
					{
						ppOldCells[nUndoPos] = NULL;
					}

					const SfxPoolItem* pItem;
					const ScPatternAttr* pPattern = pDoc->GetPattern(nCol, nRow, i);
					if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState(
											ATTR_VALUE_FORMAT,sal_False,&pItem) )
					{
						pHasFormat[nUndoPos] = sal_True;
						pOldFormats[nUndoPos] = ((const SfxUInt32Item*)pItem)->GetValue();
					}
					else
						pHasFormat[nUndoPos] = sal_False;

					++nUndoPos;
				}

			DBG_ASSERT( nUndoPos==nSelCount, "nUndoPos!=nSelCount" );

            pUndoData = ( pData ? pData->Clone() : NULL );
		}

        bool bFormula = false;

        // a single '=' character is handled as string (needed for special filters)
        if ( rString.Len() > 1 )
        {
            if ( rString.GetChar(0) == '=' )
            {
                // handle as formula
                bFormula = true;
            }
            else if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
            {
                // if there is more than one leading '+' or '-' character, remove the additional ones
                String aString( rString );
                xub_StrLen nIndex = 1;
                xub_StrLen nLen = aString.Len();
                while ( nIndex < nLen && ( aString.GetChar( nIndex ) == '+' || aString.GetChar( nIndex ) == '-' ) )
                {
                    ++nIndex;
                }
	            aString.Erase( 1, nIndex - 1 );

                // if the remaining part without the leading '+' or '-' character
                // is non-empty and not a number, handle as formula
                if ( aString.Len() > 1 )
                {
                    sal_uInt32 nFormat = 0;
                    pDoc->GetNumberFormat( nCol, nRow, nTab, nFormat );
                    SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
                    double fNumber = 0;
                    if ( !pFormatter->IsNumberFormat( aString, nFormat, fNumber ) )
                    {
                        bFormula = true;
                    }
                }
            }
        }

		sal_Bool bNumFmtChanged = sal_False;
        if ( bFormula )
		{	// Formel, compile mit AutoCorrection
			for (i=0; i<nTabCount; i++)
				if (rMark.GetTableSelect(i))
					break;
			ScAddress aPos( nCol, nRow, i );
			ScCompiler aComp( pDoc, aPos);
            aComp.SetGrammar(pDoc->GetGrammar());
// TODO: AutoCorrection via CalcOptions abschaltbar machen
			aComp.SetAutoCorrection( sal_True );
            if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
            {
                aComp.SetExtendedErrorDetection( true );
            }
			String aFormula( rString );
			ScTokenArray* pArr;
			sal_Bool bAgain;
			do
			{
				bAgain = sal_False;
				sal_Bool bAddEqual = sal_False;
				ScTokenArray* pArrFirst = pArr = aComp.CompileString( aFormula );
				sal_Bool bCorrected = aComp.IsCorrected();
				if ( bCorrected )
				{	// probieren, mit erster Parser-Korrektur neu zu parsen
					pArr = aComp.CompileString( aComp.GetCorrectedFormula() );
				}
				if ( !pArr->GetCodeError() )
				{
					bAddEqual = sal_True;
					aComp.CompileTokenArray();
					bCorrected |= aComp.IsCorrected();
				}
				if ( bCorrected )
				{
					String aCorrectedFormula;
					if ( bAddEqual )
					{
						aCorrectedFormula = '=';
						aCorrectedFormula += aComp.GetCorrectedFormula();
					}
					else
						aCorrectedFormula = aComp.GetCorrectedFormula();
					short nResult;
					if ( aCorrectedFormula.Len() == 1 )
						nResult = RET_NO;	// leere Formel, nur '='
					else
					{
						String aMessage( ScResId( SCSTR_FORMULA_AUTOCORRECTION ) );
						aMessage += aCorrectedFormula;
						nResult = QueryBox( GetViewData()->GetDialogParent(),
												WinBits(WB_YES_NO | WB_DEF_YES),
												aMessage ).Execute();
					}
					if ( nResult == RET_YES )
					{
						aFormula = aCorrectedFormula;
						if ( pArr != pArrFirst )
							delete pArrFirst;
						bAgain = sal_True;
					}
					else
					{
						if ( pArr != pArrFirst )
						{
							delete pArr;
							pArr = pArrFirst;
						}
					}
				}
			} while ( bAgain );
			// um in mehreren Tabellen eingesetzt zu werden, muss die Formel
			// via ScFormulaCell copy-ctor evtl. wegen RangeNames neu kompiliert
			// werden, gleiches Code-Array fuer alle Zellen geht nicht.
			// Wenn das Array einen Fehler enthaelt, muss in den neu erzeugten
			// Zellen RPN geloescht und der Fehler explizit gesetzt werden, da
			// via FormulaCell copy-ctor und Interpreter das, wenn moeglich,
			// wieder glattgebuegelt wird, zu intelligent.. z.B.: =1))
			sal_uInt16 nError = pArr->GetCodeError();
			if ( !nError )
			{
				//	#68693# update list of recent functions with all functions that
				//	are not within parentheses

				ScModule* pScMod = SC_MOD();
				ScAppOptions aAppOpt = pScMod->GetAppOptions();
				sal_Bool bOptChanged = sal_False;

                formula::FormulaToken** ppToken = pArr->GetArray();
				sal_uInt16 nTokens = pArr->GetLen();
				sal_uInt16 nLevel = 0;
				for (sal_uInt16 nTP=0; nTP<nTokens; nTP++)
				{
					formula::FormulaToken* pTok = ppToken[nTP];
					OpCode eOp = pTok->GetOpCode();
					if ( eOp == ocOpen )
						++nLevel;
					else if ( eOp == ocClose && nLevel )
						--nLevel;
                    if ( nLevel == 0 && pTok->IsFunction() &&
                            lcl_AddFunction( aAppOpt, sal::static_int_cast<sal_uInt16>( eOp ) ) )
						bOptChanged = sal_True;
				}

				if ( bOptChanged )
				{
					pScMod->SetAppOptions(aAppOpt);
					pScMod->RecentFunctionsChanged();
				}
			}

			ScFormulaCell aCell( pDoc, aPos, pArr,formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE );
			delete pArr;
			sal_Bool bAutoCalc = pDoc->GetAutoCalc();
			SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
			for ( ; i<nTabCount; i++)
			{
				if (rMark.GetTableSelect(i))
				{
					aPos.SetTab( i );
					sal_uLong nIndex = (sal_uLong) ((SfxUInt32Item*) pDoc->GetAttr(
						nCol, nRow, i, ATTR_VALUE_FORMAT ))->GetValue();
                    if ( pFormatter->GetType( nIndex ) == NUMBERFORMAT_TEXT ||
                         ( ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' ) && nError && rString.Equals( aFormula ) ) )
					{
                        if ( pData )
                        {
                            ScEditCell* pCell = new ScEditCell( pData, pDoc, NULL );
                            pDoc->PutCell( aPos, pCell );
                        }
                        else
                        {
                            ScStringCell* pCell = new ScStringCell( aFormula );
                            pDoc->PutCell( aPos, pCell );
                        }
					}
					else
					{
                        DELETEZ(pUndoData);
                        ScFormulaCell* pCell = new ScFormulaCell( aCell, *pDoc, aPos );
						if ( nError )
						{
							pCell->GetCode()->DelRPN();
							pCell->SetErrCode( nError );
                            if(pCell->GetCode()->IsHyperLink())
                                pCell->GetCode()->SetHyperLink(sal_False);
						}
						pDoc->PutCell( aPos, pCell );
						if ( !bAutoCalc )
						{	// einmal nur die Zelle berechnen und wieder dirty setzen
							pCell->Interpret();
							pCell->SetDirtyVar();
							pDoc->PutInFormulaTree( pCell );
						}
					}

				}
			}
		}
		else
		{
			for (i=0; i<nTabCount; i++)
				if (rMark.GetTableSelect(i))
					if (pDoc->SetString( nCol, nRow, i, rString ))
						bNumFmtChanged = sal_True;
		}

		//	row height must be changed if new text has a different script type
		for (i=0; i<nTabCount && !bEditDeleted; i++)
			if (rMark.GetTableSelect(i))
				if ( pDoc->GetScriptType( nCol, nRow, i ) != nOldScript )
					bEditDeleted = sal_True;

		HideAllCursors();

		if (bEditDeleted || pDoc->HasAttrib( nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_NEEDHEIGHT ))
			AdjustRowHeight(nRow,nRow);

		sal_Bool bAutoFormat = TestFormatArea(nCol, nRow, nTab, bNumFmtChanged);
		if (bAutoFormat)
			DoAutoAttributes(nCol, nRow, nTab, bNumFmtChanged, bRecord);

		if ( bRecord )
		{	// wg. ChangeTrack erst jetzt
 			pDocSh->GetUndoManager()->AddUndoAction(
				new ScUndoEnterData( pDocSh, nCol, nRow, nTab, nUndoPos, pTabs,
									 ppOldCells, pHasFormat, pOldFormats,
                                     rString, pUndoData ) );
		}

		for (i=0; i<nTabCount; i++)
			if (rMark.GetTableSelect(i))
				pDocSh->PostPaintCell( nCol, nRow, i );

		ShowAllCursors();

		pDocSh->UpdateOle(GetViewData());

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

		aModificator.SetDocumentModified();
	}
	else
	{
		ErrorMessage(aTester.GetMessageId());
		PaintArea( nCol, nRow, nCol, nRow );		// da steht evtl. noch die Edit-Engine
	}
}

//	Wert in einzele Zelle eintragen (nur auf nTab)

void ScViewFunc::EnterValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rValue )
{
	ScDocument* pDoc = GetViewData()->GetDocument();
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	sal_Bool bUndo (pDoc->IsUndoEnabled());

	if ( pDoc && pDocSh )
	{
		ScDocShellModificator aModificator( *pDocSh );

		ScEditableTester aTester( pDoc, nTab, nCol,nRow, nCol,nRow );
		if (aTester.IsEditable())
		{
            ScAddress aPos( nCol, nRow, nTab );
			ScBaseCell* pOldCell = pDoc->GetCell( aPos );
			sal_Bool bNeedHeight = ( pOldCell && pOldCell->GetCellType() == CELLTYPE_EDIT )
								|| pDoc->HasAttrib(
									nCol,nRow,nTab, nCol,nRow,nTab, HASATTR_NEEDHEIGHT );

			//	Undo
            ScBaseCell* pUndoCell = (bUndo && pOldCell) ? pOldCell->CloneWithoutNote( *pDoc ) : 0;

			pDoc->SetValue( nCol, nRow, nTab, rValue );

			// wg. ChangeTrack nach Aenderung im Dokument
			if (bUndo)
			{
				pDocSh->GetUndoManager()->AddUndoAction(
					new ScUndoEnterValue( pDocSh, aPos, pUndoCell, rValue, bNeedHeight ) );
			}

/*!				Zeilenhoehe anpassen? Dann auch bei Undo...
			if (bNeedHeight)
				AdjustRowHeight(nRow,nRow);
*/

			pDocSh->PostPaintCell( aPos );
			pDocSh->UpdateOle(GetViewData());
			aModificator.SetDocumentModified();
		}
		else
			ErrorMessage(aTester.GetMessageId());
	}
}

void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const EditTextObject* pData,
							sal_Bool bRecord, sal_Bool bTestSimple )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScMarkData& rMark = GetViewData()->GetMarkData();
	ScDocument* pDoc = pDocSh->GetDocument();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScDocShellModificator aModificator( *pDocSh );

	ScEditableTester aTester( pDoc, nTab, nCol,nRow, nCol,nRow );
	if (aTester.IsEditable())
	{
		//
		// 		Test auf Attribute
		//
		sal_Bool bSimple = sal_False;
		sal_Bool bCommon = sal_False;
		ScPatternAttr* pCellAttrs = NULL;
		EditTextObject* pNewData = NULL;
		String aString;

		const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
		ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
		aEngine.SetText(*pData);

		if (bTestSimple)					// Testen, ob einfacher String ohne Attribute
		{
			ScEditAttrTester aAttrTester( &aEngine );
			bSimple = !aAttrTester.NeedsObject();
			bCommon = aAttrTester.NeedsCellAttr();

			// formulas have to be recognized even if they're formatted
			// (but common attributes are still collected)

			if ( !bSimple && aEngine.GetParagraphCount() == 1 )
			{
				String aParStr = aEngine.GetText( 0 );
				if ( aParStr.GetChar(0) == '=' )
					bSimple = sal_True;
			}

			if (bCommon)				// Attribute fuer Tabelle
			{
				pCellAttrs = new ScPatternAttr( *pOldPattern );
				pCellAttrs->GetFromEditItemSet( &aAttrTester.GetAttribs() );
				//!	remove common attributes from EditEngine?
			}
		}

        // #i97726# always get text for "repeat" of undo action
        aString = ScEditUtil::GetSpaceDelimitedString(aEngine);

		//
		// 		Undo
		//

		SCTAB nTabCount = pDoc->GetTableCount();
		SCTAB nSelCount = rMark.GetSelectCount();
		SCTAB i;
		ScBaseCell** ppOldCells	= NULL;
		SCTAB* pTabs			= NULL;
		SCTAB nPos = 0;
		EditTextObject* pUndoData = NULL;
		if (bRecord && !bSimple)
		{
			ppOldCells	= new ScBaseCell*[nSelCount];
			pTabs  		= new SCTAB[nSelCount];
			nPos = 0;

			for (i=0; i<nTabCount; i++)
				if (rMark.GetTableSelect(i))
				{
					pTabs[nPos] = i;
					ScBaseCell* pDocCell;
					pDoc->GetCell( nCol, nRow, i, pDocCell );
                    ppOldCells[nPos] = pDocCell ? pDocCell->CloneWithoutNote( *pDoc ) : 0;
					++nPos;
				}

			DBG_ASSERT( nPos==nSelCount, "nPos!=nSelCount" );

			pUndoData = pData->Clone();
		}

		//
		//		Daten eintragen
		//

		if (bCommon)
			pDoc->ApplyPattern(nCol,nRow,nTab,*pCellAttrs);			//! Undo

		if (bSimple)
		{
			if (bCommon)
				AdjustRowHeight(nRow,nRow);

			EnterData(nCol,nRow,nTab,aString,bRecord);
		}
		else
		{
			for (i=0; i<nTabCount; i++)
				if (rMark.GetTableSelect(i))
					pDoc->PutCell( nCol, nRow, i, new ScEditCell( pData, pDoc, NULL ) );

			if ( bRecord )
			{	// wg. ChangeTrack erst jetzt
				pDocSh->GetUndoManager()->AddUndoAction(
					new ScUndoEnterData( pDocSh, nCol, nRow, nTab, nPos, pTabs,
										ppOldCells, NULL, NULL, aString,
										pUndoData ) );
			}

			HideAllCursors();

			AdjustRowHeight(nRow,nRow);

			for (i=0; i<nTabCount; i++)
				if (rMark.GetTableSelect(i))
					pDocSh->PostPaintCell( nCol, nRow, i );

			ShowAllCursors();

			pDocSh->UpdateOle(GetViewData());

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

			aModificator.SetDocumentModified();
		}

		delete pCellAttrs;
		delete pNewData;
	}
	else
	{
		ErrorMessage(aTester.GetMessageId());
		PaintArea( nCol, nRow, nCol, nRow );		// da steht evtl. noch die Edit-Engine
	}
}

void ScViewFunc::EnterDataAtCursor( const String& rString )
{
	SCCOL nPosX = GetViewData()->GetCurX();
	SCROW nPosY = GetViewData()->GetCurY();
	SCTAB nTab = GetViewData()->GetTabNo();

	EnterData( nPosX, nPosY, nTab, rString );
}

void ScViewFunc::EnterMatrix( const String& rString )
{
	ScViewData* pData = GetViewData();
	const ScMarkData& rMark = pData->GetMarkData();
	if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
	{
		//	nichts markiert -> automatisch Block mit Groesse des Ergebnisses
		//	Formel temporaer berechnen, um an die Groesse heranzukommen

		ScDocument* pDoc = pData->GetDocument();
		SCCOL nCol = pData->GetCurX();
		SCROW nRow = pData->GetCurY();
		SCTAB nTab = pData->GetTabNo();
		ScFormulaCell aFormCell( pDoc, ScAddress(nCol,nRow,nTab), rString,formula::FormulaGrammar::GRAM_DEFAULT, MM_FORMULA );

        SCSIZE nSizeX;
        SCSIZE nSizeY;
        aFormCell.GetResultDimensions( nSizeX, nSizeY );
        if ( nSizeX != 0 && nSizeY != 0 &&
             nCol+nSizeX-1 <= sal::static_int_cast<SCSIZE>(MAXCOL) &&
             nRow+nSizeY-1 <= sal::static_int_cast<SCSIZE>(MAXROW) )
		{
            ScRange aResult( nCol, nRow, nTab,
                             sal::static_int_cast<SCCOL>(nCol+nSizeX-1),
                             sal::static_int_cast<SCROW>(nRow+nSizeY-1), nTab );
			MarkRange( aResult, sal_False );
		}
	}

	ScRange aRange;
	if (pData->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
	{
		ScDocShell* pDocSh = pData->GetDocShell();
        sal_Bool bSuccess = pDocSh->GetDocFunc().EnterMatrix( aRange, &rMark, NULL, rString, sal_False, sal_False, EMPTY_STRING, formula::FormulaGrammar::GRAM_DEFAULT );
		if (bSuccess)
			pDocSh->UpdateOle(GetViewData());
	}
	else
		ErrorMessage(STR_NOMULTISELECT);
}

sal_uInt8 ScViewFunc::GetSelectionScriptType()
{
	sal_uInt8 nScript = 0;

	ScDocument* pDoc = GetViewData()->GetDocument();
	const ScMarkData& rMark = GetViewData()->GetMarkData();
	if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
	{
		// no selection -> cursor

		nScript = pDoc->GetScriptType( GetViewData()->GetCurX(),
							GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
	}
	else
	{
		ScRangeList aRanges;
		rMark.FillRangeListWithMarks( &aRanges, sal_False );
		sal_uLong nCount = aRanges.Count();
		for (sal_uLong i=0; i<nCount; i++)
		{
			ScRange aRange = *aRanges.GetObject(i);
			ScCellIterator aIter( pDoc, aRange );
			ScBaseCell* pCell = aIter.GetFirst();
			while ( pCell )
			{
				nScript |= pDoc->GetScriptType( aIter.GetCol(), aIter.GetRow(), aIter.GetTab(), pCell );
				pCell = aIter.GetNext();
			}
		}
	}

	if (nScript == 0)
		nScript = ScGlobal::GetDefaultScriptType();

	return nScript;
}

const ScPatternAttr* ScViewFunc::GetSelectionPattern()
{
    // Don't use UnmarkFiltered in slot state functions, for performance reasons.
    // The displayed state is always that of the whole selection including filtered rows.

	const ScMarkData& rMark = GetViewData()->GetMarkData();
	ScDocument* pDoc = GetViewData()->GetDocument();
	if ( rMark.IsMarked() || rMark.IsMultiMarked() )
	{
		//	MarkToMulti is no longer necessary for pDoc->GetSelectionPattern
		const ScPatternAttr* pAttr = pDoc->GetSelectionPattern( rMark );
		return pAttr;
	}
	else
	{
		SCCOL  nCol = GetViewData()->GetCurX();
		SCROW  nRow = GetViewData()->GetCurY();
		SCTAB  nTab = GetViewData()->GetTabNo();

		ScMarkData aTempMark( rMark );		// copy sheet selection
		aTempMark.SetMarkArea( ScRange( nCol, nRow, nTab ) );
		const ScPatternAttr* pAttr = pDoc->GetSelectionPattern( aTempMark );
		return pAttr;
	}
}

void ScViewFunc::GetSelectionFrame( SvxBoxItem&		rLineOuter,
									SvxBoxInfoItem&	rLineInner )
{
	ScDocument* pDoc = GetViewData()->GetDocument();
	const ScMarkData& rMark = GetViewData()->GetMarkData();

	if ( rMark.IsMarked() || rMark.IsMultiMarked() )
	{
		if ( rMark.IsMultiMarked() )
		{
			ScMarkData aNewMark( rMark );	// use local copy for MarkToSimple
			aNewMark.MarkToSimple();		// simple block is needed for GetSelectionFrame
			pDoc->GetSelectionFrame( aNewMark, rLineOuter, rLineInner );
		}
		else
			pDoc->GetSelectionFrame( rMark, rLineOuter, rLineInner );
	}
	else
	{
		const ScPatternAttr* pAttrs =
					pDoc->GetPattern( GetViewData()->GetCurX(),
									  GetViewData()->GetCurY(),
									  GetViewData()->GetTabNo() );

		rLineOuter = (const SvxBoxItem&)	(pAttrs->GetItem( ATTR_BORDER ));
		rLineInner = (const SvxBoxInfoItem&)(pAttrs->GetItem( ATTR_BORDER_INNER ));
		rLineInner.SetTable(sal_False);
        rLineInner.SetDist(sal_True);
		rLineInner.SetMinDist(sal_False);
	}
}

//
//	Attribute anwenden - Undo OK
//
//	kompletter Set ( ATTR_STARTINDEX, ATTR_ENDINDEX )
//

void ScViewFunc::ApplyAttributes( const SfxItemSet* pDialogSet,
								  const SfxItemSet* pOldSet,
								  sal_Bool				bRecord )
{
	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
	sal_Bool bOnlyNotBecauseOfMatrix;
	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

	ScPatternAttr aOldAttrs( new SfxItemSet(*pOldSet) );
	ScPatternAttr aNewAttrs( new SfxItemSet(*pDialogSet) );
	aNewAttrs.DeleteUnchanged( &aOldAttrs );

	if ( pDialogSet->GetItemState( ATTR_VALUE_FORMAT ) == SFX_ITEM_SET )
	{	// #82521# don't reset to default SYSTEM GENERAL if not intended
		sal_uInt32 nOldFormat =
			((const SfxUInt32Item&)pOldSet->Get( ATTR_VALUE_FORMAT )).GetValue();
		sal_uInt32 nNewFormat =
			((const SfxUInt32Item&)pDialogSet->Get( ATTR_VALUE_FORMAT )).GetValue();
		if ( nNewFormat != nOldFormat )
		{
			SvNumberFormatter* pFormatter =
				GetViewData()->GetDocument()->GetFormatTable();
			const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
			LanguageType eOldLang =
				pOldEntry ? pOldEntry->GetLanguage() : LANGUAGE_DONTKNOW;
			const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
			LanguageType eNewLang =
				pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
			if ( eNewLang != eOldLang )
			{
				aNewAttrs.GetItemSet().Put(
					SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );

				//	#40606# nur die Sprache geaendert -> Zahlformat-Attribut nicht anfassen
				sal_uInt32 nNewMod = nNewFormat % SV_COUNTRY_LANGUAGE_OFFSET;
				if ( nNewMod == ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) &&
				 	nNewMod <= SV_MAX_ANZ_STANDARD_FORMATE )
					aNewAttrs.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
			}
		}
	}

	const SvxBoxItem*	  pOldOuter = (const SvxBoxItem*) 	  &pOldSet->Get( ATTR_BORDER );
	const SvxBoxItem* 	  pNewOuter = (const SvxBoxItem*)	  &pDialogSet->Get( ATTR_BORDER );
	const SvxBoxInfoItem* pOldInner = (const SvxBoxInfoItem*) &pOldSet->Get( ATTR_BORDER_INNER );
	const SvxBoxInfoItem* pNewInner = (const SvxBoxInfoItem*) &pDialogSet->Get( ATTR_BORDER_INNER );
	SfxItemSet&			  rNewSet   = aNewAttrs.GetItemSet();
	SfxItemPool*		  pNewPool  = rNewSet.GetPool();

	pNewPool->Put( *pNewOuter );		// noch nicht loeschen
	pNewPool->Put( *pNewInner );
	rNewSet.ClearItem( ATTR_BORDER );
	rNewSet.ClearItem( ATTR_BORDER_INNER );

	/*
	 * Feststellen, ob Rahmenattribute zu setzen sind:
	 * 1. Neu != Alt
	 * 2. Ist eine der Linien nicht-DontCare (seit 238.f: IsxxValid())
	 *
	 */

	sal_Bool bFrame =    (pDialogSet->GetItemState( ATTR_BORDER ) != SFX_ITEM_DEFAULT)
				  || (pDialogSet->GetItemState( ATTR_BORDER_INNER ) != SFX_ITEM_DEFAULT);

	if ( pNewOuter==pOldOuter && pNewInner==pOldInner )
		bFrame = sal_False;

	//	das sollte doch der Pool abfangen: ?!??!??

	if ( bFrame && pNewOuter && pNewInner )
		if ( *pNewOuter == *pOldOuter && *pNewInner == *pOldInner )
			bFrame = sal_False;

	if ( pNewInner )
	{
		bFrame =   bFrame
				&& (   pNewInner->IsValid(VALID_LEFT)
					|| pNewInner->IsValid(VALID_RIGHT)
					|| pNewInner->IsValid(VALID_TOP)
					|| pNewInner->IsValid(VALID_BOTTOM)
					|| pNewInner->IsValid(VALID_HORI)
					|| pNewInner->IsValid(VALID_VERT) );
	}
	else
		bFrame = sal_False;

	if (!bFrame)
		ApplySelectionPattern( aNewAttrs, bRecord );				// nur normale
	else
	{
		// wenn neue Items Default-Items sind, so muessen die
		// alten Items geputtet werden:

		sal_Bool bDefNewOuter = ( SFX_ITEMS_STATICDEFAULT == pNewOuter->GetKind() );
		sal_Bool bDefNewInner = ( SFX_ITEMS_STATICDEFAULT == pNewInner->GetKind() );

		ApplyPatternLines( aNewAttrs,
						   bDefNewOuter ? pOldOuter : pNewOuter,
						   bDefNewInner ? pOldInner : pNewInner,
						   bRecord );
	}

	pNewPool->Remove( *pNewOuter );			// freigeben
	pNewPool->Remove( *pNewInner );

	//	Hoehen anpassen
	AdjustBlockHeight();

	// CellContentChanged wird von ApplySelectionPattern / ApplyPatternLines gerufen
}

void ScViewFunc::ApplyAttr( const SfxPoolItem& rAttrItem )
{
	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
	sal_Bool bOnlyNotBecauseOfMatrix;
	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

	ScPatternAttr aNewAttrs( new SfxItemSet( *GetViewData()->GetDocument()->GetPool(),
											ATTR_PATTERN_START, ATTR_PATTERN_END ) );

	aNewAttrs.GetItemSet().Put( rAttrItem );
	//	Wenn Ausrichtung eingestellt wird (ueber Buttons), immer Einzug 0
	if ( rAttrItem.Which() == ATTR_HOR_JUSTIFY )
		aNewAttrs.GetItemSet().Put( SfxUInt16Item( ATTR_INDENT, 0 ) );
	ApplySelectionPattern( aNewAttrs );

	AdjustBlockHeight();

	// CellContentChanged wird von ApplySelectionPattern gerufen
}


//	Pattern und Rahmen

void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem* pNewOuter,
									const SvxBoxInfoItem* pNewInner, sal_Bool bRecord )
{
	ScDocument* pDoc = GetViewData()->GetDocument();
    ScMarkData aFuncMark( GetViewData()->GetMarkData() );       // local copy for UnmarkFiltered
    ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScRange aMarkRange;
	aFuncMark.MarkToSimple();
	sal_Bool bMulti = aFuncMark.IsMultiMarked();
	if (bMulti)
		aFuncMark.GetMultiMarkArea( aMarkRange );
	else if (aFuncMark.IsMarked())
		aFuncMark.GetMarkArea( aMarkRange );
	else
	{
		aMarkRange = ScRange( GetViewData()->GetCurX(),
							GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
		DoneBlockMode();
		InitOwnBlockMode();
		aFuncMark.SetMarkArea(aMarkRange);
		MarkDataChanged();
	}

	ScDocShell* pDocSh = GetViewData()->GetDocShell();

	ScDocShellModificator aModificator( *pDocSh );

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

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

		pDocSh->GetUndoManager()->AddUndoAction(
			new ScUndoSelectionAttr(
			pDocSh, aFuncMark,
			aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), aMarkRange.aStart.Tab(),
			aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), aMarkRange.aEnd.Tab(),
			pUndoDoc, bMulti, &rAttr, pNewOuter, pNewInner ) );
	}

	sal_uInt16 nExt = SC_PF_TESTMERGE;
	pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content before the change

	pDoc->ApplySelectionFrame( aFuncMark, pNewOuter, pNewInner );

	pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content after the change

	aFuncMark.MarkToMulti();
	pDoc->ApplySelectionPattern( rAttr, aFuncMark );

	pDocSh->PostPaint( aMarkRange, PAINT_GRID, nExt );
	pDocSh->UpdateOle(GetViewData());
	aModificator.SetDocumentModified();
	CellContentChanged();

	StartFormatArea();
}

//	nur Pattern

void ScViewFunc::ApplySelectionPattern( const ScPatternAttr& rAttr,
											sal_Bool bRecord, sal_Bool bCursorOnly )
{
	ScViewData* pViewData	= GetViewData();
	ScDocShell* pDocSh		= pViewData->GetDocShell();
	ScDocument* pDoc		= pDocSh->GetDocument();
    ScMarkData aFuncMark( pViewData->GetMarkData() );       // local copy for UnmarkFiltered
    ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );

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

	//	State from old ItemSet doesn't matter for paint flags, as any change will be
	//	from SFX_ITEM_SET in the new ItemSet (default is ignored in ApplyPattern).
	//	New alignment is checked (check in PostPaint isn't enough) in case a right
	//	alignment is changed to left.
	const SfxItemSet& rNewSet = rAttr.GetItemSet();
	sal_Bool bSetLines = rNewSet.GetItemState( ATTR_BORDER, sal_True ) == SFX_ITEM_SET ||
					 rNewSet.GetItemState( ATTR_SHADOW, sal_True ) == SFX_ITEM_SET;
	sal_Bool bSetAlign = rNewSet.GetItemState( ATTR_HOR_JUSTIFY, sal_True ) == SFX_ITEM_SET;

	sal_uInt16 nExtFlags = 0;
	if ( bSetLines )
		nExtFlags |= SC_PF_LINES;
	if ( bSetAlign )
		nExtFlags |= SC_PF_WHOLEROWS;

	ScDocShellModificator aModificator( *pDocSh );

	sal_Bool bMulti = aFuncMark.IsMultiMarked();
	aFuncMark.MarkToMulti();
	sal_Bool bOnlyTab = (!aFuncMark.IsMultiMarked() && !bCursorOnly && aFuncMark.GetSelectCount() > 1);
	if (bOnlyTab)
	{
		SCCOL nCol = pViewData->GetCurX();
		SCROW nRow = pViewData->GetCurY();
		SCTAB nTab = pViewData->GetTabNo();
		aFuncMark.SetMarkArea(ScRange(nCol,nRow,nTab));
		aFuncMark.MarkToMulti();
	}

    ScRangeList aChangeRanges;

	if (aFuncMark.IsMultiMarked() && !bCursorOnly)
	{
		ScRange aMarkRange;
		aFuncMark.GetMultiMarkArea( aMarkRange );
        SCTAB nTabCount = pDoc->GetTableCount();
        for ( SCTAB i = 0; i < nTabCount; ++i )
        {
            if ( aFuncMark.GetTableSelect( i ) )
            {
                ScRange aChangeRange( aMarkRange );
                aChangeRange.aStart.SetTab( i );
                aChangeRange.aEnd.SetTab( i );
                aChangeRanges.Append( aChangeRange );
            }
        }

        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 (bRecord)
		{
			ScRange aCopyRange = aMarkRange;
			aCopyRange.aStart.SetTab(0);
			aCopyRange.aEnd.SetTab(nTabCount-1);

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

			aFuncMark.MarkToMulti();

			pDocSh->GetUndoManager()->AddUndoAction(
				new ScUndoSelectionAttr(
							pDocSh, aFuncMark,
							nStartCol, nStartRow, nStartTab,
							nEndCol, nEndRow, nEndTab,
							pUndoDoc, bMulti, &rAttr ) );
		}

		pDoc->ApplySelectionPattern( rAttr, aFuncMark );

		pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
						   nEndCol,   nEndRow,   nEndTab,
						   PAINT_GRID, nExtFlags | SC_PF_TESTMERGE );
		pDocSh->UpdateOle(GetViewData());
		aModificator.SetDocumentModified();
		CellContentChanged();
	}
	else							// einzelne Zelle - Undo einfacher
	{
		SCCOL nCol = pViewData->GetCurX();
		SCROW nRow = pViewData->GetCurY();
		SCTAB nTab = pViewData->GetTabNo();
        aChangeRanges.Append( ScRange( nCol, nRow, nTab ) );
		ScPatternAttr* pOldPat = new ScPatternAttr(*pDoc->GetPattern( nCol, nRow, nTab ));

		pDoc->ApplyPattern( nCol, nRow, nTab, rAttr );

		const ScPatternAttr* pNewPat = pDoc->GetPattern( nCol, nRow, nTab );

		if (bRecord)
		{
			pDocSh->GetUndoManager()->AddUndoAction(
						new ScUndoCursorAttr( pDocSh,
											  nCol, nRow, nTab,
											  pOldPat, pNewPat, &rAttr,
											  sal_False ) );	// sal_False = nicht automatisch
		}
		delete pOldPat;		// wird im Undo kopiert (Pool)

		pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, nExtFlags | SC_PF_TESTMERGE );
		pDocSh->UpdateOle(GetViewData());
		aModificator.SetDocumentModified();
		CellContentChanged();
	}

    // #i97876# Spreadsheet data changes are not notified
    ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
    if ( pModelObj && pModelObj->HasChangesListeners() )
    {
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aProperties;
        sal_Int32 nCount = 0;
        const SfxItemPropertyMap* pMap = ScCellObj::GetCellPropertyMap();
        PropertyEntryVector_t aPropVector = pMap->getPropertyEntries();
        for ( sal_uInt16 nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; ++nWhich )
        {
            const SfxPoolItem* pItem = 0;
		    if ( rNewSet.GetItemState( nWhich, sal_True, &pItem ) == SFX_ITEM_SET && pItem )
            {
                PropertyEntryVector_t::const_iterator aIt = aPropVector.begin();
                while ( aIt != aPropVector.end())
                {
                    if ( aIt->nWID == nWhich )
                    {
                        ::com::sun::star::uno::Any aVal;
                        pItem->QueryValue( aVal, aIt->nMemberId );
                        aProperties.realloc( nCount + 1 );
                        aProperties[ nCount ].Name = aIt->sName;
                        aProperties[ nCount ].Value <<= aVal;
                        ++nCount;
                    }
                    ++aIt;
                }
            }
        }
        pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute" ) ), aChangeRanges, aProperties );
    }

	StartFormatArea();
}

void ScViewFunc::ApplyUserItemSet( const SfxItemSet& rItemSet )
{
	//	ItemSet from UI, may have different pool

	sal_Bool bOnlyNotBecauseOfMatrix;
	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

	ScPatternAttr aNewAttrs( GetViewData()->GetDocument()->GetPool() );
	SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
	rNewSet.Put( rItemSet, sal_False );
	ApplySelectionPattern( aNewAttrs );

	AdjustBlockHeight();
}

const SfxStyleSheet* ScViewFunc::GetStyleSheetFromMarked()
{
    // Don't use UnmarkFiltered in slot state functions, for performance reasons.
    // The displayed state is always that of the whole selection including filtered rows.

	const ScStyleSheet*	pSheet		= NULL;
	ScViewData*			pViewData	= GetViewData();
	ScDocument*			pDoc		= pViewData->GetDocument();
	ScMarkData&			rMark		= pViewData->GetMarkData();

	if ( rMark.IsMarked() || rMark.IsMultiMarked() )
		pSheet = pDoc->GetSelectionStyle( rMark );					// MarkToMulti isn't necessary
	else
		pSheet = pDoc->GetStyle( pViewData->GetCurX(),
								 pViewData->GetCurY(),
								 pViewData->GetTabNo() );

	return pSheet;
}

void ScViewFunc::SetStyleSheetToMarked( SfxStyleSheet* pStyleSheet, sal_Bool bRecord )
{
	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
	sal_Bool bOnlyNotBecauseOfMatrix;
	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

	if ( !pStyleSheet) return;
	// -------------------------------------------------------------------

	ScViewData* pViewData	= GetViewData();
	ScDocShell* pDocSh		= pViewData->GetDocShell();
	ScDocument* pDoc		= pDocSh->GetDocument();
    ScMarkData aFuncMark( pViewData->GetMarkData() );       // local copy for UnmarkFiltered
    ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
	SCTAB nTabCount		= pDoc->GetTableCount();
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScDocShellModificator aModificator( *pDocSh );

	if ( aFuncMark.IsMarked() || aFuncMark.IsMultiMarked() )
	{
		ScRange aMarkRange;
		aFuncMark.MarkToMulti();
		aFuncMark.GetMultiMarkArea( aMarkRange );

		if ( bRecord )
		{
			SCTAB nTab = pViewData->GetTabNo();
			ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
			pUndoDoc->InitUndo( pDoc, nTab, nTab );
			for (SCTAB i=0; i<nTabCount; i++)
				if (i != nTab && aFuncMark.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, &aFuncMark );
			aFuncMark.MarkToMulti();

			String aName = pStyleSheet->GetName();
			pDocSh->GetUndoManager()->AddUndoAction(
				new ScUndoSelectionStyle( pDocSh, aFuncMark, aMarkRange, aName, pUndoDoc ) );
		}

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

		if (!AdjustBlockHeight())
			pViewData->GetDocShell()->PostPaint( aMarkRange, PAINT_GRID );

		aFuncMark.MarkToSimple();
	}
	else
	{
		SCCOL nCol = pViewData->GetCurX();
		SCROW nRow = pViewData->GetCurY();
		SCTAB nTab = pViewData->GetTabNo();

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

			ScRange aCopyRange( nCol, nRow, 0, nCol, nRow, nTabCount-1 );
			pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_False, pUndoDoc );

			ScRange aMarkRange ( nCol, nRow, nTab );
			ScMarkData aUndoMark = aFuncMark;
			aUndoMark.SetMultiMarkArea( aMarkRange );

			String aName = pStyleSheet->GetName();
			pDocSh->GetUndoManager()->AddUndoAction(
				new ScUndoSelectionStyle( pDocSh, aUndoMark, aMarkRange, aName, pUndoDoc ) );
		}

		for (SCTAB i=0; i<nTabCount; i++)
			if (aFuncMark.GetTableSelect(i))
				pDoc->ApplyStyle( nCol, nRow, i, (ScStyleSheet&)*pStyleSheet );

		if (!AdjustBlockHeight())
			pViewData->GetDocShell()->PostPaintCell( nCol, nRow, nTab );

	}

	aModificator.SetDocumentModified();

	StartFormatArea();
}


void ScViewFunc::RemoveStyleSheetInUse( const SfxStyleSheetBase* pStyleSheet )
{
	if ( !pStyleSheet) return;
	// -------------------------------------------------------------------

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

	ScDocShellModificator aModificator( *pDocSh );

	VirtualDevice aVirtDev;
	aVirtDev.SetMapMode(MAP_PIXEL);
	pDoc->StyleSheetChanged( pStyleSheet, sal_True, &aVirtDev,
								pViewData->GetPPTX(),
								pViewData->GetPPTY(),
								pViewData->GetZoomX(),
								pViewData->GetZoomY() );

	pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
	aModificator.SetDocumentModified();

	ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
	if (pHdl)
		pHdl->ForgetLastPattern();
}

void ScViewFunc::UpdateStyleSheetInUse( const SfxStyleSheetBase* pStyleSheet )
{
	if ( !pStyleSheet) return;
	// -------------------------------------------------------------------

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

	ScDocShellModificator aModificator( *pDocSh );

	VirtualDevice aVirtDev;
	aVirtDev.SetMapMode(MAP_PIXEL);
	pDoc->StyleSheetChanged( pStyleSheet, sal_False, &aVirtDev,
								pViewData->GetPPTX(),
								pViewData->GetPPTY(),
								pViewData->GetZoomX(),
								pViewData->GetZoomY() );

	pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
	aModificator.SetDocumentModified();

	ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
	if (pHdl)
		pHdl->ForgetLastPattern();
}

//	Zellen einfuegen - Undo OK

sal_Bool ScViewFunc::InsertCells( InsCellCmd eCmd, sal_Bool bRecord, sal_Bool bPartOfPaste )
{
	ScRange aRange;
	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
	{
		ScDocShell* pDocSh = GetViewData()->GetDocShell();
        const ScMarkData& rMark = GetViewData()->GetMarkData();
		sal_Bool bSuccess = pDocSh->GetDocFunc().InsertCells( aRange, &rMark, eCmd, bRecord, sal_False, bPartOfPaste );
		if (bSuccess)
		{
			pDocSh->UpdateOle(GetViewData());
			CellContentChanged();

            // #i97876# Spreadsheet data changes are not notified
            ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
            if ( pModelObj && pModelObj->HasChangesListeners() )
            {
                if ( eCmd == INS_INSROWS || eCmd == INS_INSCOLS )
                {
                    ScRangeList aChangeRanges;
                    aChangeRanges.Append( aRange );
                    ::rtl::OUString aOperation = ( eCmd == INS_INSROWS ?
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert-rows" ) ) :
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert-columns" ) ) );
                    pModelObj->NotifyChanges( aOperation, aChangeRanges );
                }
            }
		}
		return bSuccess;
	}
	else
	{
		ErrorMessage(STR_NOMULTISELECT);
		return sal_False;
	}
}

//	Zellen loeschen - Undo OK

void ScViewFunc::DeleteCells( DelCellCmd eCmd, sal_Bool bRecord )
{
	ScRange aRange;
    if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
	{
		ScDocShell* pDocSh = GetViewData()->GetDocShell();
        const ScMarkData& rMark = GetViewData()->GetMarkData();

        // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
        if ( pDocSh->IsDocShared() && ( eCmd == DEL_DELROWS || eCmd == DEL_DELCOLS ) )
        {
            ScRange aDelRange( aRange.aStart );
            SCCOLROW nCount = 0;
            if ( eCmd == DEL_DELROWS )
            {
                nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Row() - aRange.aStart.Row() + 1 );
            }
            else
            {
                nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Col() - aRange.aStart.Col() + 1 );
            }
            while ( nCount > 0 )
            {
                pDocSh->GetDocFunc().DeleteCells( aDelRange, &rMark, eCmd, bRecord, sal_False );
                --nCount;
            }
        }
        else
        {
            pDocSh->GetDocFunc().DeleteCells( aRange, &rMark, eCmd, bRecord, sal_False );
        }

		pDocSh->UpdateOle(GetViewData());
		CellContentChanged();

        // #i97876# Spreadsheet data changes are not notified
        ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
        if ( pModelObj && pModelObj->HasChangesListeners() )
        {
            if ( eCmd == DEL_DELROWS || eCmd == DEL_DELCOLS )
            {
                ScRangeList aChangeRanges;
                aChangeRanges.Append( aRange );
                ::rtl::OUString aOperation = ( eCmd == DEL_DELROWS ?
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete-rows" ) ) :
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete-columns" ) ) );
                pModelObj->NotifyChanges( aOperation, aChangeRanges );
            }
        }

		//	#58106# Cursor direkt hinter den geloeschten Bereich setzen
		SCCOL nCurX = GetViewData()->GetCurX();
		SCROW nCurY = GetViewData()->GetCurY();
		if ( eCmd==DEL_CELLSLEFT || eCmd==DEL_DELCOLS )
			nCurX = aRange.aStart.Col();
		else
			nCurY = aRange.aStart.Row();
		SetCursor( nCurX, nCurY );
	}
	else
	{
		if (eCmd == DEL_DELCOLS)
			DeleteMulti( sal_False, bRecord );
		else if (eCmd == DEL_DELROWS)
			DeleteMulti( sal_True, bRecord );
		else
			ErrorMessage(STR_NOMULTISELECT);
	}

	Unmark();
}

void ScViewFunc::DeleteMulti( sal_Bool bRows, sal_Bool bRecord )
{
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocShellModificator aModificator( *pDocSh );
	SCTAB nTab = GetViewData()->GetTabNo();
	ScDocument* pDoc = pDocSh->GetDocument();
    ScMarkData aFuncMark( GetViewData()->GetMarkData() );       // local copy for UnmarkFiltered
    ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );

	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;
	SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
	SCCOLROW nRangeCnt = bRows ? aFuncMark.GetMarkRowRanges( pRanges ) :
								aFuncMark.GetMarkColumnRanges( pRanges );
	if (nRangeCnt == 0)
	{
		pRanges[0] = pRanges[1] = bRows ? static_cast<SCCOLROW>(GetViewData()->GetCurY()) : static_cast<SCCOLROW>(GetViewData()->GetCurX());
		nRangeCnt = 1;
	}

	//	Test ob erlaubt

	SCCOLROW* pOneRange = pRanges;
    sal_uInt16 nErrorId = 0;
    sal_Bool bNeedRefresh = sal_False;
	SCCOLROW nRangeNo;
    for (nRangeNo=0; nRangeNo<nRangeCnt && !nErrorId; nRangeNo++)
	{
		SCCOLROW nStart = *(pOneRange++);
		SCCOLROW nEnd = *(pOneRange++);

        SCCOL nStartCol, nEndCol;
        SCROW nStartRow, nEndRow;
        if ( bRows )
        {
            nStartCol = 0;
            nEndCol   = MAXCOL;
            nStartRow = static_cast<SCROW>(nStart);
            nEndRow   = static_cast<SCROW>(nEnd);
        }
        else
        {
            nStartCol = static_cast<SCCOL>(nStart);
            nEndCol   = static_cast<SCCOL>(nEnd);
            nStartRow = 0;
            nEndRow   = MAXROW;
        }

        // cell protection (only needed for first range, as all following cells are moved)
        if ( nRangeNo == 0 )
        {
            // test to the end of the sheet
            ScEditableTester aTester( pDoc, nTab, nStartCol, nStartRow, MAXCOL, MAXROW );
            if (!aTester.IsEditable())
                nErrorId = aTester.GetMessageId();
        }

        // merged cells
        SCCOL nMergeStartX = nStartCol;
        SCROW nMergeStartY = nStartRow;
        SCCOL nMergeEndX   = nEndCol;
        SCROW nMergeEndY   = nEndRow;
        pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );
        pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );

        if ( nMergeStartX != nStartCol || nMergeStartY != nStartRow )
        {
            // Disallow deleting parts of a merged cell.
            // Deleting the start is allowed (merge is removed), so the end doesn't have to be checked.

            nErrorId = STR_MSSG_DELETECELLS_0;
        }
        if ( nMergeEndX != nEndCol || nMergeEndY != nEndRow )
        {
            // detect if the start of a merged cell is deleted, so the merge flags can be refreshed

            bNeedRefresh = sal_True;
        }
	}

    if ( nErrorId )
    {
        ErrorMessage( nErrorId );
        delete[] pRanges;
		return;
    }

	//	ausfuehren

	WaitObject aWait( GetFrameWin() );		// wichtig wegen TrackFormulas bei UpdateReference

	ScDocument* pUndoDoc = NULL;
	ScRefUndoData* pUndoData = NULL;
	if (bRecord)
	{
		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, nTab, nTab, !bRows, bRows );		// Zeilenhoehen

		pOneRange = pRanges;
		for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
		{
			SCCOLROW nStart = *(pOneRange++);
			SCCOLROW nEnd = *(pOneRange++);
			if (bRows)
				pDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,sal_False,pUndoDoc );
			else
                pDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
                        static_cast<SCCOL>(nEnd),MAXROW,nTab,
                        IDF_ALL,sal_False,pUndoDoc );
		}

				//	alle Formeln wegen Referenzen
		SCTAB nTabCount = pDoc->GetTableCount();
		pUndoDoc->AddUndoTab( 0, nTabCount-1, sal_False, sal_False );
		pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,MAXTAB, IDF_FORMULA,sal_False,pUndoDoc );

		pUndoData = new ScRefUndoData( pDoc );

		pDoc->BeginDrawUndo();
	}

	pOneRange = &pRanges[2*nRangeCnt];		// rueckwaerts
    for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
	{
		SCCOLROW nEnd = *(--pOneRange);
		SCCOLROW nStart = *(--pOneRange);

		if (bRows)
			pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, nStart, static_cast<SCSIZE>(nEnd-nStart+1) );
		else
            pDoc->DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
	}

    if (bNeedRefresh)
    {
        SCCOLROW nFirstStart = pRanges[0];
        SCCOL nStartCol = bRows ? 0 : static_cast<SCCOL>(nFirstStart);
        SCROW nStartRow = bRows ? static_cast<SCROW>(nFirstStart) : 0;
        SCCOL nEndCol = MAXCOL;
        SCROW nEndRow = MAXROW;

        pDoc->RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
        pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, sal_True );
    }

	if (bRecord)
	{
		pDocSh->GetUndoManager()->AddUndoAction(
			new ScUndoDeleteMulti( pDocSh, bRows, bNeedRefresh, nTab, pRanges, nRangeCnt,
									pUndoDoc, pUndoData ) );
	}

	if (!AdjustRowHeight(0, MAXROW))
	{
		if (bRows)
			pDocSh->PostPaint( 0,pRanges[0],nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT );
		else
            pDocSh->PostPaint( static_cast<SCCOL>(pRanges[0]),0,nTab,
                    MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_TOP );
	}
	aModificator.SetDocumentModified();

	CellContentChanged();

	//	#58106# Cursor direkt hinter den ersten geloeschten Bereich setzen
	SCCOL nCurX = GetViewData()->GetCurX();
	SCROW nCurY = GetViewData()->GetCurY();
	if ( bRows )
		nCurY = pRanges[0];
	else
		nCurX = static_cast<SCCOL>(pRanges[0]);
	SetCursor( nCurX, nCurY );

	delete[] pRanges;

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

//	Inhalte loeschen

void ScViewFunc::DeleteContents( sal_uInt16 nFlags, sal_Bool bRecord )
{
	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
	sal_Bool bOnlyNotBecauseOfMatrix;
	sal_Bool bEditable = SelectionEditable( &bOnlyNotBecauseOfMatrix );
	if ( !bEditable )
	{
		if ( !(bOnlyNotBecauseOfMatrix &&
				((nFlags & (IDF_ATTRIB | IDF_EDITATTR)) == nFlags)) )
		{
			ErrorMessage(bOnlyNotBecauseOfMatrix ? STR_MATRIXFRAGMENTERR : STR_PROTECTIONERR);
			return;
		}
	}

	ScRange aMarkRange;
	sal_Bool bSimple = sal_False;

	ScDocument* pDoc = GetViewData()->GetDocument();
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
    ScMarkData aFuncMark( GetViewData()->GetMarkData() );       // local copy for UnmarkFiltered
    ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );

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

	ScDocShellModificator aModificator( *pDocSh );

	if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
	{
		aMarkRange.aStart.SetCol(GetViewData()->GetCurX());
		aMarkRange.aStart.SetRow(GetViewData()->GetCurY());
		aMarkRange.aStart.SetTab(GetViewData()->GetTabNo());
		aMarkRange.aEnd = aMarkRange.aStart;
		if ( pDoc->HasAttrib( aMarkRange, HASATTR_MERGED ) )
		{
//			InitOwnBlockMode();
			aFuncMark.SetMarkArea( aMarkRange );
		}
		else
			bSimple = sal_True;
	}

	aFuncMark.SetMarking(sal_False);		// for MarkToMulti
	aFuncMark.MarkToSimple();			// before bMulti test below

	DBG_ASSERT( aFuncMark.IsMarked() || aFuncMark.IsMultiMarked() || bSimple, "delete what?" );

	ScDocument* pUndoDoc = NULL;
	sal_Bool bMulti = !bSimple && aFuncMark.IsMultiMarked();
	if (!bSimple)
	{
		aFuncMark.MarkToMulti();
		aFuncMark.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 (aFuncMark.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 )
		pDocSh->UpdatePaintExt( nExtFlags, aMarkRange );

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

    sal_Bool bDrawUndo = bObjects || ( nFlags & IDF_NOTE );     // needed for shown notes
    if ( bDrawUndo && bRecord )
        pDoc->BeginDrawUndo();

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

	if ( bRecord )
	{
		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		SCTAB nTab = aMarkRange.aStart.Tab();
		pUndoDoc->InitUndo( pDoc, nTab, nTab );
		SCTAB nTabCount = pDoc->GetTableCount();
		for (SCTAB i=0; i<nTabCount; i++)
			if (i != nTab && aFuncMark.GetTableSelect(i))
				pUndoDoc->AddUndoTab( i, i );
		ScRange aCopyRange = aExtendedRange;
		aCopyRange.aStart.SetTab(0);
		aCopyRange.aEnd.SetTab(nTabCount-1);

		//	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
        // do not copy note captions to undo document
        nUndoDocFlags |= IDF_NOCAPTIONS;
		pDoc->CopyToDocument( aCopyRange, nUndoDocFlags, bMulti, pUndoDoc, &aFuncMark );
	}

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

	if ( bRecord )
	{
		pDocSh->GetUndoManager()->AddUndoAction(
			new ScUndoDeleteContents( pDocSh, aFuncMark, aExtendedRange,
									  pUndoDoc, bMulti, nFlags, bDrawUndo ) );
	}

	if (!AdjustRowHeight( aExtendedRange.aStart.Row(), aExtendedRange.aEnd.Row() ))
		pDocSh->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );

	pDocSh->UpdateOle(GetViewData());

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

	aModificator.SetDocumentModified();
	CellContentChanged();
	ShowAllCursors();

	if ( nFlags & IDF_ATTRIB )
	{
		if ( nFlags & IDF_CONTENTS )
			ForgetFormatArea();
		else
			StartFormatArea();				// Attribute loeschen ist auch Attributierung
	}
}

//	Spaltenbreiten/Zeilenhoehen (ueber Header) - Undo OK

void ScViewFunc::SetWidthOrHeight( sal_Bool bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges,
									ScSizeMode eMode, sal_uInt16 nSizeTwips,
									sal_Bool bRecord, sal_Bool bPaint, ScMarkData* pMarkData )
{
	if (nRangeCnt == 0)
		return;

	// use view's mark if none specified
	if ( !pMarkData )
		pMarkData = &GetViewData()->GetMarkData();

	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	SCTAB nTabCount = pDoc->GetTableCount();
	SCTAB nFirstTab = pMarkData->GetFirstSelected();
	SCTAB nCurTab = GetViewData()->GetTabNo();
	SCTAB nTab;
	if (bRecord && !pDoc->IsUndoEnabled())
		bRecord = sal_False;

	ScDocShellModificator aModificator( *pDocSh );

	sal_Bool bAllowed = sal_True;
	for (nTab=0; nTab<nTabCount && bAllowed; nTab++)
		if (pMarkData->GetTableSelect(nTab))
		{
			for ( SCCOLROW i=0; i<nRangeCnt && bAllowed; i++ )
			{
				sal_Bool bOnlyMatrix;
				if (bWidth)
                    bAllowed = pDoc->IsBlockEditable( nTab,
                            static_cast<SCCOL>(pRanges[2*i]),0,
                            static_cast<SCCOL>(pRanges[2*i+1]),MAXROW,
                            &bOnlyMatrix ) || bOnlyMatrix;
				else
                    bAllowed = pDoc->IsBlockEditable( nTab, 0,pRanges[2*i],
                            MAXCOL,pRanges[2*i+1], &bOnlyMatrix ) ||
                        bOnlyMatrix;
			}
		}
	if ( !bAllowed )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

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

	sal_Bool bFormula = sal_False;
	if ( eMode == SC_SIZE_OPTIMAL )
	{
		const ScViewOptions& rOpts = GetViewData()->GetOptions();
		bFormula = rOpts.GetOption( VOPT_FORMULAS );
	}

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

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

		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		for (nTab=0; nTab<nTabCount; nTab++)
			if (pMarkData->GetTableSelect(nTab))
			{
				if (bWidth)
				{
					if ( nTab == nFirstTab )
						pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
					else
						pUndoDoc->AddUndoTab( 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
				{
					if ( nTab == nFirstTab )
						pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
					else
						pUndoDoc->AddUndoTab( nTab, nTab, sal_False, sal_True );
					pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pUndoDoc );
				}
			}

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

		//!	outlines from all tables?
		ScOutlineTable* pTable = pDoc->GetOutlineTable( nCurTab );
		if (pTable)
			pUndoTab = new ScOutlineTable( *pTable );
	}

	if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
		pMarkData->MarkToMulti();

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

	for (nTab=0; nTab<nTabCount; nTab++)
		if (pMarkData->GetTableSelect(nTab))
		{
			const SCCOLROW* pTabRanges = pRanges;

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

				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)
                            {
                                SCROW nLastRow = nRow;
                                if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow))
                                {
                                    nRow = nLastRow;
                                    continue;
                                }

                                sal_uInt8 nOld = pDoc->GetRowFlags(nRow, nTab);
                                if (nOld & CR_MANUALSIZE)
                                    pDoc->SetRowFlags(nRow, nTab, nOld & ~CR_MANUALSIZE);
                            }
						}

						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 );
						}

						pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, nSizeTwips, aProv.GetDevice(),
													nPPTX, nPPTY, aZoomX, aZoomY, 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 )
					{
						if (nSizeTwips)
						{
							pDoc->SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
							pDoc->SetManualHeight( nStartNo, nEndNo, nTab, sal_True );			// height was set manually
						}
						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++)
					{
						if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab) )
						{
							sal_uInt16 nThisSize = nSizeTwips;

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

							pDoc->ShowCol( nCol, nTab, bShow );
						}
					}
				}

									//	Outline anpassen

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


	if (!bOutline)
		DELETEZ(pUndoTab);

	if (bRecord)
	{
		pDocSh->GetUndoManager()->AddUndoAction(
			new ScUndoWidthOrHeight( pDocSh, *pMarkData,
									 nStart, nCurTab, nEnd, nCurTab,
									 pUndoDoc, nRangeCnt, pUndoRanges,
									 pUndoTab, eMode, nSizeTwips, bWidth ) );
	}

	for (nTab=0; nTab<nTabCount; nTab++)
		if (pMarkData->GetTableSelect(nTab))
			pDoc->UpdatePageBreaks( nTab );

	GetViewData()->GetView()->UpdateScrollBars();

	if (bPaint)
	{
		HideCursor();

		for (nTab=0; nTab<nTabCount; nTab++)
			if (pMarkData->GetTableSelect(nTab))
			{
				if (bWidth)
				{
                    if (pDoc->HasAttrib( static_cast<SCCOL>(nStart),0,nTab,
                                static_cast<SCCOL>(nEnd),MAXROW,nTab,
                                HASATTR_MERGED | HASATTR_OVERLAPPED ))
						nStart = 0;
					if (nStart > 0)				// weiter oben anfangen wegen Linien und Cursor
						--nStart;
                    pDocSh->PostPaint( static_cast<SCCOL>(nStart), 0, nTab,
                            MAXCOL, MAXROW, nTab, PAINT_GRID | PAINT_TOP );
				}
				else
				{
					if (pDoc->HasAttrib( 0,nStart,nTab, MAXCOL,nEnd,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ))
						nStart = 0;
					if (nStart != 0)
						--nStart;
					pDocSh->PostPaint( 0, nStart, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID | PAINT_LEFT );
				}
			}

		pDocSh->UpdateOle(GetViewData());
		aModificator.SetDocumentModified();

		ShowCursor();
	}

    // #i97876# Spreadsheet data changes are not notified
    if ( bWidth )
    {
        ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
        if ( pModelObj && pModelObj->HasChangesListeners() )
        {
            ScRangeList aChangeRanges;
            for ( nTab = 0; nTab < nTabCount; ++nTab )
            {
                if ( pMarkData->GetTableSelect( nTab ) )
                {
                    const SCCOLROW* pTabRanges = pRanges;
                    for ( SCCOLROW nRange = 0; nRange < nRangeCnt; ++nRange )
                    {
                        SCCOL nStartCol = static_cast< SCCOL >( *(pTabRanges++) );
                        SCCOL nEndCol = static_cast< SCCOL >( *(pTabRanges++) );
                        for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
                        {
                            aChangeRanges.Append( ScRange( nCol, 0, nTab ) );
                        }
                    }
                }
            }
            pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "column-resize" ) ), aChangeRanges );
        }
    }
}

//	Spaltenbreiten/Zeilenhoehen (ueber Blockmarken)

void ScViewFunc::SetMarkedWidthOrHeight( sal_Bool bWidth, ScSizeMode eMode, sal_uInt16 nSizeTwips,
										sal_Bool bRecord, sal_Bool bPaint )
{
	ScMarkData& rMark = GetViewData()->GetMarkData();

	rMark.MarkToMulti();
	if (!rMark.IsMultiMarked())
	{
		SCCOL nCol = GetViewData()->GetCurX();
		SCROW nRow = GetViewData()->GetCurY();
		SCTAB nTab = GetViewData()->GetTabNo();
		DoneBlockMode();
		InitOwnBlockMode();
		rMark.SetMultiMarkArea( ScRange( nCol,nRow,nTab ), sal_True );
        MarkDataChanged();
	}

	SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
	SCCOLROW nRangeCnt = 0;

	if ( bWidth )
		nRangeCnt = rMark.GetMarkColumnRanges( pRanges );
	else
		nRangeCnt = rMark.GetMarkRowRanges( pRanges );

	SetWidthOrHeight( bWidth, nRangeCnt, pRanges, eMode, nSizeTwips, bRecord, bPaint );

	delete[] pRanges;
	rMark.MarkToSimple();
}

void ScViewFunc::ModifyCellSize( ScDirection eDir, sal_Bool bOptimal )
{
	//!	Schrittweiten einstellbar
	//	Schrittweite ist auch Minimum
	sal_uInt16 nStepX = STD_COL_WIDTH / 5;
	sal_uInt16 nStepY = ScGlobal::nStdRowHeight;

	ScModule* pScMod = SC_MOD();
	sal_Bool bAnyEdit = pScMod->IsInputMode();
	SCCOL nCol = GetViewData()->GetCurX();
	SCROW nRow = GetViewData()->GetCurY();
	SCTAB nTab = GetViewData()->GetTabNo();
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();

	sal_Bool bAllowed, bOnlyMatrix;
	if ( eDir == DIR_LEFT || eDir == DIR_RIGHT )
		bAllowed = pDoc->IsBlockEditable( nTab, nCol,0, nCol,MAXROW, &bOnlyMatrix );
	else
		bAllowed = pDoc->IsBlockEditable( nTab, 0,nRow, MAXCOL,nRow, &bOnlyMatrix );
	if ( !bAllowed && !bOnlyMatrix )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

	HideAllCursors();

	sal_uInt16 nWidth = pDoc->GetColWidth( nCol, nTab );
	sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTab );
	SCCOLROW nRange[2];
	if ( eDir == DIR_LEFT || eDir == DIR_RIGHT )
	{
		if (bOptimal)				// Breite dieser einen Zelle
		{
			if ( bAnyEdit )
			{
				//	beim Editieren die aktuelle Breite der Eingabe
				ScInputHandler* pHdl = pScMod->GetInputHdl( GetViewData()->GetViewShell() );
				if (pHdl)
				{
					long nEdit = pHdl->GetTextSize().Width();		// in 1/100mm

					const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
					const SvxMarginItem& rMItem =
							(const SvxMarginItem&)pPattern->GetItem(ATTR_MARGIN);
					sal_uInt16 nMargin = rMItem.GetLeftMargin() + rMItem.GetRightMargin();
					if ( ((const SvxHorJustifyItem&) pPattern->
							GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_LEFT )
                        nMargin = sal::static_int_cast<sal_uInt16>(
                            nMargin + ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue() );

					nWidth = (sal_uInt16)(nEdit * pDocSh->GetOutputFactor() / HMM_PER_TWIPS)
								+ nMargin + STD_EXTRA_WIDTH;
				}
			}
			else
			{
				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 );
				}

				long nPixel = pDoc->GetNeededSize( nCol, nRow, nTab, aProv.GetDevice(),
											nPPTX, nPPTY, aZoomX, aZoomY, sal_True );
				sal_uInt16 nTwips = (sal_uInt16)( nPixel / nPPTX );
				if (nTwips != 0)
					nWidth = nTwips + STD_EXTRA_WIDTH;
				else
					nWidth = STD_COL_WIDTH;
			}
		}
		else						// vergroessern / verkleinern
		{
			if ( eDir == DIR_RIGHT )
                nWidth = sal::static_int_cast<sal_uInt16>( nWidth + nStepX );
			else if ( nWidth > nStepX )
                nWidth = sal::static_int_cast<sal_uInt16>( nWidth - nStepX );
			if ( nWidth < nStepX ) nWidth = nStepX;
			if ( nWidth > MAX_COL_WIDTH ) nWidth = MAX_COL_WIDTH;
		}
		nRange[0] = nRange[1] = nCol;
		SetWidthOrHeight( sal_True, 1, nRange, SC_SIZE_DIRECT, nWidth );

		//	hier bei Breite auch Hoehe anpassen (nur die eine Zeile)

		if (!bAnyEdit)
		{
			const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
			sal_Bool bNeedHeight =
					((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK )).GetValue() ||
					((const SvxHorJustifyItem&)pPattern->
						GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK;
			if (bNeedHeight)
				AdjustRowHeight( nRow, nRow );
		}
	}
	else
	{
		ScSizeMode eMode;
		if (bOptimal)
		{
			eMode = SC_SIZE_OPTIMAL;
			nHeight = 0;
		}
		else
		{
			eMode = SC_SIZE_DIRECT;
			if ( eDir == DIR_BOTTOM )
                nHeight = sal::static_int_cast<sal_uInt16>( nHeight + nStepY );
			else if ( nHeight > nStepY )
                nHeight = sal::static_int_cast<sal_uInt16>( nHeight - nStepY );
			if ( nHeight < nStepY ) nHeight = nStepY;
			if ( nHeight > MAX_COL_HEIGHT ) nHeight = MAX_COL_HEIGHT;
			//!	MAX_COL_HEIGHT umbenennen in MAX_ROW_HEIGHT in global.hxx !!!!!!
		}
		nRange[0] = nRange[1] = nRow;
		SetWidthOrHeight( sal_False, 1, nRange, eMode, nHeight );
	}

	if ( bAnyEdit )
	{
		UpdateEditView();
		if ( pDoc->HasAttrib( nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_NEEDHEIGHT ) )
		{
			ScInputHandler* pHdl = pScMod->GetInputHdl( GetViewData()->GetViewShell() );
			if (pHdl)
				pHdl->SetModified();	// damit bei Enter die Hoehe angepasst wird
		}
	}

	ShowAllCursors();
}

void ScViewFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
{
    if (nTab == TABLEID_DOC)
        return;

	ScMarkData& rMark = GetViewData()->GetMarkData();
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	ScDocFunc aFunc(*pDocSh);
	bool bUndo(pDoc->IsUndoEnabled());

    //	modifying several tables is handled here

    if (bUndo)
    {
        String aUndo = ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB );
        pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
    }

    SCTAB nCount = pDocSh->GetDocument()->GetTableCount();
    for ( SCTAB i=0; i<nCount; i++ )
        if ( rMark.GetTableSelect(i) )
            aFunc.ProtectSheet(i, rProtect);

    if (bUndo)
        pDocSh->GetUndoManager()->LeaveListAction();

	UpdateLayerLocks();			//!	broadcast to all views
}

void ScViewFunc::Protect( SCTAB nTab, const String& rPassword )
{
	ScMarkData& rMark = GetViewData()->GetMarkData();
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	ScDocFunc aFunc(*pDocSh);
	sal_Bool bUndo(pDoc->IsUndoEnabled());

	if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
		aFunc.Protect( nTab, rPassword, sal_False );
	else
	{
		//	modifying several tables is handled here

		if (bUndo)
		{
			String aUndo = ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB );
			pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
		}

		SCTAB nCount = pDocSh->GetDocument()->GetTableCount();
		for ( SCTAB i=0; i<nCount; i++ )
			if ( rMark.GetTableSelect(i) )
				aFunc.Protect( i, rPassword, sal_False );

		if (bUndo)
			pDocSh->GetUndoManager()->LeaveListAction();
	}

	UpdateLayerLocks();			//!	broadcast to all views
}

sal_Bool ScViewFunc::Unprotect( SCTAB nTab, const String& rPassword )
{
	ScMarkData& rMark = GetViewData()->GetMarkData();
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	ScDocFunc aFunc(*pDocSh);
	sal_Bool bChanged = sal_False;
	sal_Bool bUndo (pDoc->IsUndoEnabled());

	if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
		bChanged = aFunc.Unprotect( nTab, rPassword, sal_False );
	else
	{
		//	modifying several tables is handled here

		if (bUndo)
		{
			String aUndo = ScGlobal::GetRscString( STR_UNDO_UNPROTECT_TAB );
			pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
		}

		SCTAB nCount = pDocSh->GetDocument()->GetTableCount();
		for ( SCTAB i=0; i<nCount; i++ )
			if ( rMark.GetTableSelect(i) )
				if ( aFunc.Unprotect( i, rPassword, sal_False ) )
					bChanged = sal_True;

		if (bUndo)
			pDocSh->GetUndoManager()->LeaveListAction();
	}

	if (bChanged)
		UpdateLayerLocks();		//!	broadcast to all views

	return bChanged;
}

void ScViewFunc::SetNoteText( const ScAddress& rPos, const String& rNoteText )
{
    GetViewData()->GetDocShell()->GetDocFunc().SetNoteText( rPos, rNoteText, sal_False );
}

void ScViewFunc::ReplaceNote( const ScAddress& rPos, const String& rNoteText, const String* pAuthor, const String* pDate )
{
    GetViewData()->GetDocShell()->GetDocFunc().ReplaceNote( rPos, rNoteText, pAuthor, pDate, sal_False );
}

void ScViewFunc::SetNumberFormat( short nFormatType, sal_uLong nAdd )
{
	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
	sal_Bool bOnlyNotBecauseOfMatrix;
	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

	sal_uInt32			nNumberFormat = 0;
	ScViewData*			pViewData = GetViewData();
	ScDocument*			pDoc = pViewData->GetDocument();
	SvNumberFormatter*	pNumberFormatter = pDoc->GetFormatTable();
	LanguageType		eLanguage = ScGlobal::eLnge;
	ScPatternAttr		aNewAttrs( pDoc->GetPool() );

	//	#67936# always take language from cursor position, even if there is a selection

	sal_uInt32 nCurrentNumberFormat;
	pDoc->GetNumberFormat( pViewData->GetCurX(),
						   pViewData->GetCurY(),
						   pViewData->GetTabNo(),
						   nCurrentNumberFormat );
	const SvNumberformat* pEntry = pNumberFormatter->GetEntry( nCurrentNumberFormat );
	if (pEntry)
		eLanguage = pEntry->GetLanguage();		// sonst ScGlobal::eLnge behalten

	nNumberFormat =	pNumberFormatter->GetStandardFormat( nFormatType, eLanguage ) + nAdd;

	SfxItemSet& rSet = aNewAttrs.GetItemSet();
	rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
	//	ATTR_LANGUAGE_FORMAT nicht
	ApplySelectionPattern( aNewAttrs, sal_True );
}

void ScViewFunc::SetNumFmtByStr( const String& rCode )
{
	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
	sal_Bool bOnlyNotBecauseOfMatrix;
	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
	{
		ErrorMessage(STR_PROTECTIONERR);
		return;
	}

	ScViewData*			pViewData = GetViewData();
	ScDocument*			pDoc = pViewData->GetDocument();
	SvNumberFormatter*	pFormatter = pDoc->GetFormatTable();

	//	Sprache immer von Cursorposition

	sal_uInt32 nCurrentNumberFormat;
	pDoc->GetNumberFormat( pViewData->GetCurX(), pViewData->GetCurY(),
						   pViewData->GetTabNo(), nCurrentNumberFormat );
	const SvNumberformat* pEntry = pFormatter->GetEntry( nCurrentNumberFormat );
	LanguageType eLanguage = pEntry ? pEntry->GetLanguage() : ScGlobal::eLnge;

	//	Index fuer String bestimmen

	sal_Bool bOk = sal_True;
	sal_uInt32 nNumberFormat = pFormatter->GetEntryKey( rCode, eLanguage );
	if ( nNumberFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
	{
		//	neu eintragen

		String		aFormat	= rCode;	// wird veraendert
		xub_StrLen	nErrPos	= 0;
		short		nType	= 0;		//! ???
		bOk = pFormatter->PutEntry( aFormat, nErrPos, nType, nNumberFormat, eLanguage );
	}

	if ( bOk )			// gueltiges Format?
	{
		ScPatternAttr aNewAttrs( pDoc->GetPool() );
		SfxItemSet& rSet = aNewAttrs.GetItemSet();
		rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
		rSet.Put( SvxLanguageItem( eLanguage, ATTR_LANGUAGE_FORMAT ) );
		ApplySelectionPattern( aNewAttrs, sal_True );
	}

	//!	sonst Fehler zuerueckgeben / Meldung ausgeben ???
}

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

	ScDocument*			pDoc = GetViewData()->GetDocument();
	SvNumberFormatter*	pFormatter = pDoc->GetFormatTable();

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

	sal_uInt32 nOldFormat;
	pDoc->GetNumberFormat( nCol, nRow, nTab, nOldFormat );
	const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
	if (!pOldEntry)
	{
		DBG_ERROR("Zahlformat nicht gefunden !!!");
		return;
	}

	//	was haben wir denn da?

	sal_uInt32 nNewFormat = nOldFormat;
	sal_Bool bError = sal_False;

	LanguageType eLanguage = pOldEntry->GetLanguage();
	sal_Bool bThousand, bNegRed;
	sal_uInt16 nPrecision, nLeading;
	pOldEntry->GetFormatSpecialInfo( bThousand, bNegRed, nPrecision, nLeading );

	short nOldType = pOldEntry->GetType();
	if ( 0 == ( nOldType & (
				NUMBERFORMAT_NUMBER |  NUMBERFORMAT_CURRENCY | NUMBERFORMAT_PERCENT ) ) )
	{
		//	Datum, Zeit, Bruch, logisch, Text kann nicht angepasst werden
		//!	bei Wisssenschaftlich kann es der Numberformatter auch nicht
		bError = sal_True;
	}

	//!	Das SvNumberformat hat einen Member bStandard, verraet ihn aber nicht
	sal_Bool bWasStandard = ( nOldFormat == pFormatter->GetStandardIndex( eLanguage ) );
	if (bWasStandard)
	{
		//	bei "Standard" die Nachkommastellen abhaengig vom Zellinhalt
		//	0 bei leer oder Text -> keine Nachkommastellen
		double nVal = pDoc->GetValue( ScAddress( nCol, nRow, nTab ) );

		//	Die Wege des Numberformatters sind unergruendlich, darum ausprobieren:
		String aOut;
		Color* pCol;
		((SvNumberformat*)pOldEntry)->GetOutputString( nVal, aOut, &pCol );

		nPrecision = 0;
		// 'E' fuer Exponential ist fest im Numberformatter
		if ( aOut.Search('E') != STRING_NOTFOUND )
			bError = sal_True;								// Exponential nicht veraendern
		else
		{
			String aDecSep( pFormatter->GetFormatDecimalSep( nOldFormat ) );
			xub_StrLen nPos = aOut.Search( aDecSep );
			if ( nPos != STRING_NOTFOUND )
				nPrecision = aOut.Len() - nPos - aDecSep.Len();
			// sonst 0 behalten
		}
	}

	if (!bError)
	{
		if (bIncrement)
		{
			if (nPrecision<20)
				++nPrecision;			// erhoehen
			else
				bError = sal_True;			// 20 ist Maximum
		}
		else
		{
			if (nPrecision)
				--nPrecision;			// vermindern
			else
				bError = sal_True;			// weniger als 0 geht nicht
		}
	}

	if (!bError)
	{
		String aNewPicture;
		pFormatter->GenerateFormat( aNewPicture, nOldFormat, eLanguage,
									bThousand, bNegRed, nPrecision, nLeading );

		nNewFormat = pFormatter->GetEntryKey( aNewPicture, eLanguage );
		if ( nNewFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
		{
			xub_StrLen nErrPos = 0;
			short nNewType = 0;
			sal_Bool bOk = pFormatter->PutEntry( aNewPicture, nErrPos,
												nNewType, nNewFormat, eLanguage );
			DBG_ASSERT( bOk, "falsches Zahlformat generiert" );
			if (!bOk)
				bError = sal_True;
		}
	}

	if (!bError)
	{
		ScPatternAttr aNewAttrs( pDoc->GetPool() );
		SfxItemSet& rSet = aNewAttrs.GetItemSet();
		rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
		//	ATTR_LANGUAGE_FORMAT nicht
		ApplySelectionPattern( aNewAttrs, sal_True );
	}
	else
		Sound::Beep();				// war nix
}

void ScViewFunc::ChangeIndent( sal_Bool bIncrement )
{
	ScViewData* pViewData = GetViewData();
	ScDocShell* pDocSh	= pViewData->GetDocShell();
	ScMarkData& rMark	= pViewData->GetMarkData();

	ScMarkData aWorkMark = rMark;
    ScViewUtil::UnmarkFiltered( aWorkMark, pDocSh->GetDocument() );
	aWorkMark.MarkToMulti();
	if (!aWorkMark.IsMultiMarked())
	{
		SCCOL nCol = pViewData->GetCurX();
		SCROW nRow = pViewData->GetCurY();
		SCTAB nTab = pViewData->GetTabNo();
		aWorkMark.SetMultiMarkArea( ScRange(nCol,nRow,nTab) );
	}

	sal_Bool bSuccess = pDocSh->GetDocFunc().ChangeIndent( aWorkMark, bIncrement, sal_False );
	if (bSuccess)
	{
		pDocSh->UpdateOle(pViewData);
		StartFormatArea();

        // stuff for sidebar panels
		SfxBindings& rBindings = GetViewData()->GetBindings();
		rBindings.Invalidate( SID_H_ALIGNCELL );
		rBindings.Invalidate( SID_ATTR_ALIGN_INDENT );
	}
}

sal_Bool ScViewFunc::InsertName( const String& rName, const String& rSymbol,
								const String& rType )
{
	//	Type = P,R,C,F (und Kombinationen)
	//!	Undo...

	sal_Bool bOk = sal_False;
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	SCTAB nTab = GetViewData()->GetTabNo();
	ScRangeName* pList = pDoc->GetRangeName();

	RangeType nType = RT_NAME;
    ScRangeData* pNewEntry = new ScRangeData( pDoc, rName, rSymbol,
            ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
                nTab), nType );
	String aUpType = rType;
	aUpType.ToUpperAscii();
	if ( aUpType.Search( 'P' ) != STRING_NOTFOUND )
		nType |= RT_PRINTAREA;
	if ( aUpType.Search( 'R' ) != STRING_NOTFOUND )
		nType |= RT_ROWHEADER;
	if ( aUpType.Search( 'C' ) != STRING_NOTFOUND )
		nType |= RT_COLHEADER;
	if ( aUpType.Search( 'F' ) != STRING_NOTFOUND )
		nType |= RT_CRITERIA;
	pNewEntry->AddType(nType);

	if ( !pNewEntry->GetErrCode() )		//	Text gueltig?
	{
		ScDocShellModificator aModificator( *pDocSh );

		pDoc->CompileNameFormula( sal_True );	// CreateFormulaString

		// Eintrag bereits vorhanden? Dann vorher entfernen (=Aendern)
		sal_uInt16 nFoundAt;
		if ( pList->SearchName( rName, nFoundAt ) )
		{									// alten Index uebernehmen
			pNewEntry->SetIndex( ((ScRangeData*)pList->At(nFoundAt))->GetIndex() );
			pList->AtFree( nFoundAt );
		}

		if ( pList->Insert( pNewEntry ) )
		{
			pNewEntry = NULL;	// nicht loeschen
			bOk = sal_True;
		}

		pDoc->CompileNameFormula( sal_False );	// CompileFormulaString
		aModificator.SetDocumentModified();
		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
	}

	delete pNewEntry;		// wenn er nicht eingefuegt wurde
	return bOk;
}

void ScViewFunc::CreateNames( sal_uInt16 nFlags )
{
	sal_Bool bDone = sal_False;
	ScRange aRange;
	if ( GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE )
		bDone = GetViewData()->GetDocShell()->GetDocFunc().CreateNames( aRange, nFlags, sal_False );

	if (!bDone)
		ErrorMessage(STR_CREATENAME_MARKERR);
}

sal_uInt16 ScViewFunc::GetCreateNameFlags()
{
	sal_uInt16 nFlags = 0;

	SCCOL nStartCol, nEndCol;
	SCROW nStartRow, nEndRow;
	SCTAB nDummy;
	if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nDummy,nEndCol,nEndRow,nDummy) == SC_MARK_SIMPLE)
	{
		ScDocument* pDoc = GetViewData()->GetDocument();
		SCTAB nTab = GetViewData()->GetTabNo();
		sal_Bool bOk;
        SCCOL i;
        SCROW j;

		bOk = sal_True;
		SCCOL nFirstCol = nStartCol;
		SCCOL nLastCol  = nEndCol;
		if (nStartCol+1 < nEndCol) { ++nFirstCol; --nLastCol; }
		for (i=nFirstCol; i<=nLastCol && bOk; i++)
			if (!pDoc->HasStringData( i,nStartRow,nTab ))
				bOk = sal_False;
		if (bOk)
			nFlags |= NAME_TOP;
		else							// Bottom nur wenn nicht Top
		{
			bOk = sal_True;
			for (i=nFirstCol; i<=nLastCol && bOk; i++)
				if (!pDoc->HasStringData( i,nEndRow,nTab ))
					bOk = sal_False;
			if (bOk)
				nFlags |= NAME_BOTTOM;
		}

		bOk = sal_True;
		SCROW nFirstRow = nStartRow;
		SCROW nLastRow  = nEndRow;
		if (nStartRow+1 < nEndRow) { ++nFirstRow; --nLastRow; }
		for (j=nFirstRow; j<=nLastRow && bOk; j++)
			if (!pDoc->HasStringData( nStartCol,j,nTab ))
				bOk = sal_False;
		if (bOk)
			nFlags |= NAME_LEFT;
		else							// Right nur wenn nicht Left
		{
			bOk = sal_True;
			for (j=nFirstRow; j<=nLastRow && bOk; j++)
				if (!pDoc->HasStringData( nEndCol,j,nTab ))
					bOk = sal_False;
			if (bOk)
				nFlags |= NAME_RIGHT;
		}
	}

	if (nStartCol == nEndCol)
		nFlags &= ~( NAME_LEFT | NAME_RIGHT );
	if (nStartRow == nEndRow)
		nFlags &= ~( NAME_TOP | NAME_BOTTOM );

	return nFlags;
}

void ScViewFunc::InsertNameList()
{
	ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
	if ( pDocSh->GetDocFunc().InsertNameList( aPos, sal_False ) )
		pDocSh->UpdateOle(GetViewData());
}
