/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

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

#include "scitems.hxx"
#include <editeng/eeitem.hxx>

#include <sfx2/app.hxx>
#include <editeng/acorrcfg.hxx>
#include <svx/algitem.hxx>
#include <editeng/adjitem.hxx>
#include <editeng/brshitem.hxx>
#include <svtools/colorcfg.hxx>
#include <editeng/colritem.hxx>
#include <editeng/editobj.hxx>
#include <editeng/editstat.hxx>
#include <editeng/editview.hxx>
#include <editeng/escpitem.hxx>
#include <editeng/forbiddencharacterstable.hxx>
#include <editeng/langitem.hxx>
#include <editeng/svxacorr.hxx>
#include <editeng/unolingu.hxx>
#include <editeng/wghtitem.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/printer.hxx>
#include <svl/zforlist.hxx>
#include <vcl/sound.hxx>
#include <unotools/localedatawrapper.hxx>
#include <vcl/help.hxx>
#include <vcl/cursor.hxx>
#include <tools/urlobj.hxx>
#include <formula/formulahelper.hxx>

#include "inputwin.hxx"
#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "scmod.hxx"
#include "uiitems.hxx"
#include "global.hxx"
#include "sc.hrc"
#include "globstr.hrc"
#include "patattr.hxx"
#include "viewdata.hxx"
#include "document.hxx"
#include "docpool.hxx"
#include "editutil.hxx"
#include "collect.hxx"
#include "appoptio.hxx"
#include "docoptio.hxx"
#include "validat.hxx"
#include "userlist.hxx"
#include "rfindlst.hxx"
#include "inputopt.hxx"
#include "cell.hxx"				// fuer Formel-Preview
#include "compiler.hxx"			// fuer Formel-Preview
#include "editable.hxx"
#include "funcdesc.hxx"

#define _INPUTHDL_CXX
#include "inputhdl.hxx"

//	max. Ranges im RangeFinder
#define RANGEFIND_MAX	32

using namespace formula;

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

sal_Bool ScInputHandler::bOptLoaded = sal_False;			// App-Optionen ausgewertet
sal_Bool ScInputHandler::bAutoComplete = sal_False;			// wird in KeyInput gesetzt

//	delimiters (in addition to ScEditUtil) needed for range finder:
//	only characters that are allowed in formulas next to references
//	and the quotation mark (so string constants can be skipped)

static const sal_Char __FAR_DATA pMinDelimiters[] = " !\"";

extern sal_uInt16 nEditAdjust;		//! Member an ViewData

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

static sal_Unicode lcl_getSheetSeparator(ScDocument* pDoc)
{
    ScCompiler aComp(pDoc, ScAddress());
    aComp.SetGrammar(pDoc->GetGrammar());
    return aComp.GetNativeAddressSymbol(ScCompiler::Convention::SHEET_SEPARATOR);
}

void ScInputHandler::InitRangeFinder( const String& rFormula )
{
	DeleteRangeFinder();
    ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
    ScDocument* pDoc = pDocSh->GetDocument();
    const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDoc);

	if ( !pActiveViewSh || !SC_MOD()->GetInputOptions().GetRangeFinder() )
		return;

//	String aDelimiters = pEngine->GetWordDelimiters();
	String aDelimiters = ScEditUtil::ModifyDelimiters(
							String::CreateFromAscii( pMinDelimiters ) );

	xub_StrLen nColon = aDelimiters.Search(':');
	if ( nColon != STRING_NOTFOUND )
		aDelimiters.Erase( nColon, 1 );				// Delimiter ohne Doppelpunkt
	xub_StrLen nDot = aDelimiters.Search(cSheetSep);
	if ( nDot != STRING_NOTFOUND )
		aDelimiters.Erase( nDot, 1 );				// Delimiter ohne Punkt

	const sal_Unicode* pChar = rFormula.GetBuffer();
	xub_StrLen nLen = rFormula.Len();
	xub_StrLen nPos = 0;
	xub_StrLen nStart = 0;
	sal_uInt16 nCount = 0;
	ScRange aRange;
	while ( nPos < nLen && nCount < RANGEFIND_MAX )
	{
		//	Trenner ueberlesen
		while ( nPos<nLen && ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) )
		{
			if ( pChar[nPos] == '"' )						// String
			{
				++nPos;
				while (nPos<nLen && pChar[nPos] != '"')		// bis zum Ende ueberlesen
					++nPos;
			}
			++nPos;						// Trennzeichen oder schliessender Quote
		}

		//	Text zwischen Trennern
		nStart = nPos;
handle_r1c1:
		while ( nPos<nLen && !ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) )
			++nPos;

		// for R1C1 '-' in R[-]... or C[-]... are not delimiters
		// Nothing heroic here to ensure that there are '[]' around a negative
		// integer.  we need to clean up this code.
		if( nPos < nLen && nPos > 0 &&
			'-' == pChar[nPos] && '[' == pChar[nPos-1] &&
			NULL != pDoc &&
			formula::FormulaGrammar::CONV_XL_R1C1 == pDoc->GetAddressConvention() )
		{
			nPos++;
			goto handle_r1c1;
		}

		if ( nPos > nStart )
		{
			String aTest = rFormula.Copy( nStart, nPos-nStart );
			const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
			sal_uInt16 nFlags = aRange.ParseAny( aTest, pDoc, aAddrDetails );
			if ( nFlags & SCA_VALID )
			{
				//	Tabelle setzen, wenn nicht angegeben
				if ( (nFlags & SCA_TAB_3D) == 0 )
					aRange.aStart.SetTab( pActiveViewSh->GetViewData()->GetTabNo() );
				if ( (nFlags & SCA_TAB2_3D) == 0 )
					aRange.aEnd.SetTab( aRange.aStart.Tab() );

                if ( ( nFlags & ( SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2 ) ) == 0 )
                {
                    // #i73766# if a single ref was parsed, set the same "abs" flags for ref2,
                    // so Format doesn't output a double ref because of different flags.
                    sal_uInt16 nAbsFlags = nFlags & ( SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE );
                    nFlags |= nAbsFlags << 4;
                }

				if (!nCount)
				{
					pEngine->SetUpdateMode( sal_False );
					pRangeFindList = new ScRangeFindList( pDocSh->GetTitle() );
				}

				ScRangeFindData* pNew = new ScRangeFindData( aRange, nFlags, nStart, nPos );
				pRangeFindList->Insert( pNew );

				ESelection aSel( 0, nStart, 0, nPos );
				SfxItemSet aSet( pEngine->GetEmptyItemSet() );
				aSet.Put( SvxColorItem( Color( ScRangeFindList::GetColorName( nCount ) ),
							EE_CHAR_COLOR ) );
				pEngine->QuickSetAttribs( aSet, aSel );
				++nCount;
			}
		}

		//	letzten Trenner nicht ueberlesen, koennte ja ein Quote sein (?)
	}

	if (nCount)
	{
		pEngine->SetUpdateMode( sal_True );

		pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) );
	}
}

void lcl_Replace( EditView* pView, const String& rNewStr, const ESelection& rOldSel )
{
	if ( pView )
	{
		ESelection aOldSel = pView->GetSelection();
		if (aOldSel.HasRange())
			pView->SetSelection( ESelection( aOldSel.nEndPara, aOldSel.nEndPos,
											 aOldSel.nEndPara, aOldSel.nEndPos ) );

		EditEngine* pEngine = pView->GetEditEngine();
		pEngine->QuickInsertText( rNewStr, rOldSel );

		//	Dummy-InsertText fuer Update und Paint
		//	dafuer muss oben die Selektion aufgehoben werden (vor QuickInsertText)
		pView->InsertText( EMPTY_STRING, sal_False );

		xub_StrLen nLen = pEngine->GetTextLen(0);
		ESelection aSel( 0, nLen, 0, nLen );
		pView->SetSelection( aSel );				// Cursor ans Ende
	}
}

void ScInputHandler::UpdateRange( sal_uInt16 nIndex, const ScRange& rNew )
{
	ScTabViewShell* pDocView = pRefViewSh ? pRefViewSh : pActiveViewSh;
	if ( pDocView && pRangeFindList && nIndex < pRangeFindList->Count() )
	{
		ScRangeFindData* pData = pRangeFindList->GetObject( nIndex );
		xub_StrLen nOldStart = pData->nSelStart;
		xub_StrLen nOldEnd = pData->nSelEnd;

		ScRange aJustified = rNew;
		aJustified.Justify();			// Ref in der Formel immer richtigherum anzeigen
		String aNewStr;
		ScDocument* pDoc = pDocView->GetViewData()->GetDocument();
		const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
		aJustified.Format( aNewStr, pData->nFlags, pDoc, aAddrDetails );
		ESelection aOldSel( 0, nOldStart, 0, nOldEnd );

		DataChanging();

		lcl_Replace( pTopView, aNewStr, aOldSel );
		lcl_Replace( pTableView, aNewStr, aOldSel );

		bInRangeUpdate = sal_True;
		DataChanged();
		bInRangeUpdate = sal_False;

		long nDiff = aNewStr.Len() - (long)(nOldEnd-nOldStart);

		pData->aRef = rNew;
		pData->nSelEnd = (xub_StrLen)(pData->nSelEnd + nDiff);

		sal_uInt16 nCount = (sal_uInt16) pRangeFindList->Count();
		for (sal_uInt16 i=nIndex+1; i<nCount; i++)
		{
			ScRangeFindData* pNext = pRangeFindList->GetObject( i );
			pNext->nSelStart = (xub_StrLen)(pNext->nSelStart + nDiff);
			pNext->nSelEnd   = (xub_StrLen)(pNext->nSelEnd   + nDiff);
		}
	}
	else
	{
		DBG_ERROR("UpdateRange: da fehlt was");
	}
}

void ScInputHandler::DeleteRangeFinder()
{
	ScTabViewShell* pPaintView = pRefViewSh ? pRefViewSh : pActiveViewSh;
	if ( pRangeFindList && pPaintView )
	{
		ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
		pRangeFindList->SetHidden(sal_True);
		pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) );	// wegnehmen
		DELETEZ(pRangeFindList);
	}
}

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

inline String GetEditText(EditEngine* pEng)
{
	return ScEditUtil::GetSpaceDelimitedString(*pEng);
}

void lcl_RemoveTabs(String& rStr)
{
	xub_StrLen nPos;
	while ( (nPos=rStr.Search('\t')) != STRING_NOTFOUND )
		rStr.SetChar( nPos, ' ' );
}

void lcl_RemoveLineEnd(String& rStr)
{
	rStr.ConvertLineEnd(LINEEND_LF);
	xub_StrLen nPos;
	while ( (nPos=rStr.Search('\n')) != STRING_NOTFOUND )
		rStr.SetChar( nPos, ' ' );
}

xub_StrLen lcl_MatchParenthesis( const String& rStr, xub_StrLen nPos )
{
    int nDir;
    sal_Unicode c1, c2 = 0;
    c1 = rStr.GetChar( nPos );
    switch ( c1 )
    {
    case '(' :
        c2 = ')';
        nDir = 1;
        break;
    case ')' :
        c2 = '(';
        nDir = -1;
        break;
    case '<' :
        c2 = '>';
        nDir = 1;
        break;
    case '>' :
        c2 = '<';
        nDir = -1;
        break;
    case '{' :
        c2 = '}';
        nDir = 1;
        break;
    case '}' :
        c2 = '{';
        nDir = -1;
        break;
    case '[' :
        c2 = ']';
        nDir = 1;
        break;
    case ']' :
        c2 = '[';
        nDir = -1;
        break;
    default:
        nDir = 0;
    }
    if ( !nDir )
        return STRING_NOTFOUND;
    xub_StrLen nLen = rStr.Len();
    const sal_Unicode* p0 = rStr.GetBuffer();
    register const sal_Unicode* p;
    const sal_Unicode* p1;
    sal_uInt16 nQuotes = 0;
    if ( nPos < nLen / 2 )
    {
        p = p0;
        p1 = p0 + nPos;
    }
    else
    {
        p = p0 + nPos;
        p1 = p0 + nLen;
    }
    while ( p < p1 )
    {
        if ( *p++ == '\"' )
            nQuotes++;
    }
    // Odd number of quotes that we find ourselves in a string
    sal_Bool bLookInString = ((nQuotes % 2) != 0);
    sal_Bool bInString = bLookInString;
    p = p0 + nPos;
    p1 = (nDir < 0 ? p0 : p0 + nLen) ;
    sal_uInt16 nLevel = 1;
    while ( p != p1 && nLevel )
    {
        p += nDir;
        if ( *p == '\"' )
        {
            bInString = !bInString;
            if ( bLookInString && !bInString )
                p = p1;		//That's it then
        }
        else if ( bInString == bLookInString )
        {
            if ( *p == c1 )
                nLevel++;
            else if ( *p == c2 )
                nLevel--;
        }
    }
    if ( nLevel )
        return STRING_NOTFOUND;
    return (xub_StrLen) (p - p0);
}

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

ScInputHandler::ScInputHandler()
    :   pInputWin( NULL ),
		pEngine( NULL ),
		pTableView( NULL ),
		pTopView( NULL ),
		pColumnData( NULL ),
		pFormulaData( NULL ),
        pFormulaDataPara( NULL ),
        pTipVisibleParent( NULL ),
		nTipVisible( 0 ),
        pTipVisibleSecParent( NULL ),
        nTipVisibleSec( 0 ),
		nAutoPos( SCPOS_INVALID ),
		bUseTab( sal_False ),
		bTextValid( sal_True ),
		nFormSelStart( 0 ),
		nFormSelEnd( 0 ),
		nAutoPar( 0 ),
        eMode( SC_INPUT_NONE ),
		bModified( sal_False ),
		bSelIsRef( sal_False ),
		bFormulaMode( sal_False ),
		bInRangeUpdate( sal_False ),
		bParenthesisShown( sal_False ),
		bCreatingFuncView( sal_False ),
		bInEnterHandler( sal_False ),
		bCommandErrorShown( sal_False ),
		bInOwnChange( sal_False ),
		bProtected( sal_False ),
		bCellHasPercentFormat( sal_False ),
		nValidation( 0 ),
        eAttrAdjust( SVX_HOR_JUSTIFY_STANDARD ),
		aScaleX( 1,1 ),
		aScaleY( 1,1 ),
		pRefViewSh( NULL ),
		pLastPattern( NULL ),
		pEditDefaults( NULL ),
		bLastIsSymbol( sal_False ),
		pLastState( NULL ),
		pDelayTimer( NULL ),
		pRangeFindList( NULL )
{
	//	The InputHandler is constructed with the view, so SfxViewShell::Current
	//	doesn't have the right view yet. pActiveViewSh is updated in NotifyChange.
	pActiveViewSh = NULL;

	//	Bindings (nur noch fuer Invalidate benutzt) werden bei Bedarf aktuell geholt
}

__EXPORT ScInputHandler::~ScInputHandler()
{
	//	Wenn dies der Applikations-InputHandler ist, wird der dtor erst nach SfxApplication::Main
	//	gerufen, darf sich also auf keine Sfx-Funktionen mehr verlassen

	if ( !SFX_APP()->IsDowning() )			// inplace
		EnterHandler();						// Eingabe noch abschliessen

	if (SC_MOD()->GetRefInputHdl()==this)
		SC_MOD()->SetRefInputHdl(NULL);

	if ( pInputWin && pInputWin->GetInputHandler() == this )
		pInputWin->SetInputHandler( NULL );

	delete pRangeFindList;
	delete pEditDefaults;
	delete pEngine;
	delete pLastState;
	delete pDelayTimer;
	delete pColumnData;
	delete pFormulaData;
    delete pFormulaDataPara;
}

void ScInputHandler::SetRefScale( const Fraction& rX, const Fraction& rY )
{
	if ( rX != aScaleX || rY != aScaleY )
	{
		aScaleX = rX;
		aScaleY = rY;
		if (pEngine)
		{
			MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY );
			pEngine->SetRefMapMode( aMode );
		}
	}
}

void ScInputHandler::UpdateRefDevice()
{
	if (!pEngine)
		return;

	sal_Bool bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
    bool bInPlace = pActiveViewSh && pActiveViewSh->GetViewFrame()->GetFrame().IsInPlace();
    sal_uInt32 nCtrl = pEngine->GetControlWord();
    if ( bTextWysiwyg || bInPlace )
        nCtrl |= EE_CNTRL_FORMAT100;    // EditEngine default: always format for 100%
    else
        nCtrl &= ~EE_CNTRL_FORMAT100;   // when formatting for screen, use the actual MapMode
    pEngine->SetControlWord( nCtrl );
	if ( bTextWysiwyg && pActiveViewSh )
		pEngine->SetRefDevice( pActiveViewSh->GetViewData()->GetDocument()->GetPrinter() );
	else
		pEngine->SetRefDevice( NULL );

	MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY );
	pEngine->SetRefMapMode( aMode );

	//	SetRefDevice(NULL) uses VirtualDevice, SetRefMapMode forces creation of a local VDev,
	//	so the DigitLanguage can be safely modified (might use an own VDev instead of NULL).
	if ( !( bTextWysiwyg && pActiveViewSh ) )
	{
		pEngine->GetRefDevice()->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
	}
}

void ScInputHandler::ImplCreateEditEngine()
{
	if ( !pEngine )
	{
		if ( pActiveViewSh )
		{
			const ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
			pEngine = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
		}
		else
			pEngine = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, sal_True );
		pEngine->SetWordDelimiters( ScEditUtil::ModifyDelimiters( pEngine->GetWordDelimiters() ) );
		UpdateRefDevice();		// also sets MapMode
		pEngine->SetPaperSize( Size( 1000000, 1000000 ) );
		pEditDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );

		pEngine->SetControlWord( pEngine->GetControlWord() | EE_CNTRL_AUTOCORRECT );
        pEngine->SetModifyHdl( LINK( this, ScInputHandler, ModifyHdl ) );
	}
}

void ScInputHandler::UpdateAutoCorrFlag()
{
	sal_uLong nCntrl = pEngine->GetControlWord();
	sal_uLong nOld = nCntrl;

	//	don't use pLastPattern here (may be invalid because of AutoStyle)

	sal_Bool bDisable = bLastIsSymbol || bFormulaMode;
	if ( bDisable )
		nCntrl &= ~EE_CNTRL_AUTOCORRECT;
	else
		nCntrl |= EE_CNTRL_AUTOCORRECT;

	if ( nCntrl != nOld )
		pEngine->SetControlWord(nCntrl);
}

void ScInputHandler::UpdateSpellSettings( sal_Bool bFromStartTab )
{
	if ( pActiveViewSh )
	{
		ScViewData* pViewData = pActiveViewSh->GetViewData();
		sal_Bool bOnlineSpell = pViewData->GetDocument()->GetDocOptions().IsAutoSpell();

		//	SetDefaultLanguage is independent of the language attributes,
		//	ScGlobal::GetEditDefaultLanguage is always used.
		//	It must be set every time in case the office language was changed.

		pEngine->SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );

		//	if called for changed options, update flags only if already editing
		//	if called from StartTable, always update flags

		if ( bFromStartTab || eMode != SC_INPUT_NONE )
		{
			sal_uLong nCntrl = pEngine->GetControlWord();
			sal_uLong nOld = nCntrl;
			if( bOnlineSpell )
				nCntrl |= EE_CNTRL_ONLINESPELLING;
			else
				nCntrl &= ~EE_CNTRL_ONLINESPELLING;
			// kein AutoCorrect auf Symbol-Font (EditEngine wertet Default nicht aus)
			if ( pLastPattern && pLastPattern->IsSymbolFont() )
				nCntrl &= ~EE_CNTRL_AUTOCORRECT;
			else
				nCntrl |= EE_CNTRL_AUTOCORRECT;
			if ( nCntrl != nOld )
				pEngine->SetControlWord(nCntrl);

			ScDocument* pDoc = pViewData->GetDocument();
            pDoc->ApplyAsianEditSettings( *pEngine );
			pEngine->SetDefaultHorizontalTextDirection(
				(EEHorizontalTextDirection)pDoc->GetEditTextDirection( pViewData->GetTabNo() ) );
			pEngine->SetFirstWordCapitalization( sal_False );
		}

		//	language is set separately, so the speller is needed only if online
		//	spelling is active

		if ( bOnlineSpell ) {
            com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
			pEngine->SetSpeller( xXSpellChecker1 );
        }

		sal_Bool bHyphen = pLastPattern && ((const SfxBoolItem&)pLastPattern->GetItem(ATTR_HYPHENATE)).GetValue();
		if ( bHyphen ) {
            com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
			pEngine->SetHyphenator( xXHyphenator );
        }
	}
}

//
//		Funktionen/Bereichsnamen etc. als Tip-Hilfe
//

#define SC_STRTYPE_FUNCTIONS	1
//	die anderen Typen sind in ScDocument::GetFormulaEntries festgelegt

void ScInputHandler::GetFormulaData()
{
	if ( pActiveViewSh )
	{
		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();

		if ( pFormulaData )
			pFormulaData->FreeAll();
        else
            pFormulaData = new TypedScStrCollection;

        if( pFormulaDataPara )
            pFormulaDataPara->FreeAll();
        else
            pFormulaDataPara = new TypedScStrCollection;

		//		MRU-Funktionen aus dem Funktions-Autopiloten
		//		wie in ScPosWnd::FillFunctions (inputwin.cxx)

        const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
        sal_uInt16 nMRUCount = rOpt.GetLRUFuncListCount();
        const sal_uInt16* pMRUList = rOpt.GetLRUFuncList();
        const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
        sal_uLong nListCount = pFuncList->GetCount();
        if (pMRUList)
        {
            for (sal_uInt16 i=0; i<nMRUCount; i++)
            {
                sal_uInt16 nId = pMRUList[i];
                for (sal_uLong j=0; j<nListCount; j++)
                {
                    const ScFuncDesc* pDesc = pFuncList->GetFunction( j );
                    if ( pDesc->nFIndex == nId && pDesc->pFuncName )
                    {
                        String aEntry = *pDesc->pFuncName;
                        aEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
                        TypedStrData* pData = new TypedStrData( aEntry, 0.0, SC_STRTYPE_FUNCTIONS );
                        if (!pFormulaData->Insert(pData))
                            delete pData;
                        break;                  // nicht weitersuchen
                    }
                }
            }
        }
        for(sal_uLong i=0;i<nListCount;i++)
        {
            const ScFuncDesc* pDesc = pFuncList->GetFunction( i );
            if ( pDesc->pFuncName )
            {
                pDesc->initArgumentInfo();
                String aEntry = pDesc->GetSignature();
                TypedStrData* pData = new TypedStrData( aEntry, 0.0, SC_STRTYPE_FUNCTIONS );
                if (!pFormulaDataPara->Insert(pData))
                    delete pData;
            }
        }
		pDoc->GetFormulaEntries( *pFormulaData );
        pDoc->GetFormulaEntries( *pFormulaDataPara );
	}
}

IMPL_LINK( ScInputHandler, ShowHideTipVisibleParentListener, VclWindowEvent*, pEvent )
{
    if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
        HideTip();
    return 0;
}

IMPL_LINK( ScInputHandler, ShowHideTipVisibleSecParentListener, VclWindowEvent*, pEvent )
{
    if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
        HideTipBelow();
    return 0;
}

void ScInputHandler::HideTip()
{
	if ( nTipVisible )
	{
        if (pTipVisibleParent)
            pTipVisibleParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) );
		Help::HideTip( nTipVisible );
		nTipVisible = 0;
        pTipVisibleParent = NULL;
	}
	aManualTip.Erase();
}
void ScInputHandler::HideTipBelow()
{
    if ( nTipVisibleSec )
    {
        if (pTipVisibleSecParent)
            pTipVisibleSecParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) );
        Help::HideTip( nTipVisibleSec );
        nTipVisibleSec = 0;
        pTipVisibleSecParent = NULL;
    }
    aManualTip.Erase();
}

void ScInputHandler::ShowTipCursor()
{
    HideTip();
    HideTipBelow();
    EditView* pActiveView = pTopView ? pTopView : pTableView;
    ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
    const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());

    if ( bFormulaMode && pActiveView && pFormulaDataPara && pEngine->GetParagraphCount() == 1 )
    {
        String aFormula = pEngine->GetText( (sal_uInt16) 0 );
        ESelection aSel = pActiveView->GetSelection();
        aSel.Adjust();
        xub_StrLen  nLeftParentPos = 0;
        if( aSel.nEndPos )
        {
            if ( aFormula.Len() < aSel.nEndPos )
                return;
            xub_StrLen nPos = aSel.nEndPos;
            String  aSelText = aFormula.Copy( 0, nPos );
            xub_StrLen  nNextFStart = 0;
            xub_StrLen  nNextFEnd = 0;
            xub_StrLen  nArgPos = 0;
            const IFunctionDescription* ppFDesc;
            ::std::vector< ::rtl::OUString> aArgs;
            sal_uInt16	    nArgs;
            sal_Bool  bFound = sal_False;
            FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr());

            while( !bFound )
            {
                aSelText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
                nLeftParentPos = lcl_MatchParenthesis( aSelText, aSelText.Len()-1 );
                if( nLeftParentPos != STRING_NOTFOUND )
                {
                    sal_Unicode c = ( nLeftParentPos > 0 ) ? aSelText.GetChar( nLeftParentPos-1 ) : 0;
                    if( !((c >= 'A' && c<= 'Z') || (c>= 'a' && c<= 'z' )) )
                        continue;
                    nNextFStart = aHelper.GetFunctionStart( aSelText, nLeftParentPos, sal_True);
                    if( aHelper.GetNextFunc( aSelText, sal_False, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) )
                    {
                        if( ppFDesc->getFunctionName().getLength() )
                        {
                            nArgPos = aHelper.GetArgStart( aSelText, nNextFStart, 0 );
                            nArgs = static_cast<sal_uInt16>(ppFDesc->getParameterCount());

                            sal_uInt16 nActive = 0;
                            sal_uInt16 nCount = 0;
                            sal_uInt16 nCountSemicolon = 0;
                            sal_uInt16 nCountDot = 0;
                            sal_uInt16 nStartPosition = 0;
                            sal_uInt16 nEndPosition = 0;
                            sal_Bool   bFlag = sal_False;
                            String aNew;
                            sal_uInt16 nParAutoPos = SCPOS_INVALID;
                            if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, sal_False ) )
                            {
                                for( sal_uInt16 i=0; i < nArgs; i++ )
                                {
                                    xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength());
                                    if( nArgPos <= aSelText.Len()-1 )
                                    {
                                        nActive = i+1;
                                        bFlag = sal_True;
                                    }
                                    nArgPos+=nLength+1;
                                }
                                if( bFlag )
                                {
                                    nCountSemicolon = aNew.GetTokenCount(cSep)-1;
                                    nCountDot = aNew.GetTokenCount(cSheetSep)-1;

                                    if( !nCountSemicolon )
                                    {
                                        for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
                                        {
                                            sal_Unicode cNext = aNew.GetChar( i );
                                            if( cNext == '(' )
                                            {
                                                nStartPosition = i+1;
                                            }
                                        }
                                    }
                                    else if( !nCountDot )
                                    {
                                        for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
                                        {
                                            sal_Unicode cNext = aNew.GetChar( i );
                                            if( cNext == '(' )
                                            {
                                                nStartPosition = i+1;
                                            }
                                            else if( cNext == cSep )
                                            {
                                                nCount ++;
                                                nEndPosition = i;
                                                if( nCount == nActive )
                                                {
                                                    break;
                                                }
                                                nStartPosition = nEndPosition+1;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
                                        {
                                            sal_Unicode cNext = aNew.GetChar( i );
                                            if( cNext == '(' )
                                            {
                                                nStartPosition = i+1;
                                            }
                                            else if( cNext == cSep )
                                            {
                                                nCount ++;
                                                nEndPosition = i;
                                                if( nCount == nActive )
                                                {
                                                    break;
                                                }
                                                nStartPosition = nEndPosition+1;
                                            }
                                            else if( cNext == cSheetSep )
                                            {
                                                continue;
                                            }
                                        }
                                    }

                                    if( nStartPosition )
                                    {
                                        aNew.Insert( 0x25BA, nStartPosition );
                                        ShowTipBelow( aNew );
                                        bFound = sal_True;
                                    }
                                }
                                else
                                {
                                    ShowTipBelow( aNew );
                                    bFound = sal_True;
                                }
                            }
                        }
                    }
                }
                else
                {
                    sal_uInt16 nPosition = 0;
                    String aText = pEngine->GetWord( 0, aSel.nEndPos-1 );
                    if( aText.GetChar( aSel.nEndPos-1 ) == '=' )
                    {
                        break;
                    }
                    String aNew;
                    sal_uInt16 nParAutoPos = SCPOS_INVALID;
                    nPosition = aText.Len()+1;
                    if( pFormulaDataPara->FindText( aText, aNew, nParAutoPos, sal_False ) )
                    {
                        if( aFormula.GetChar( nPosition ) =='(' )
                        {
                            ShowTipBelow( aNew );
                            bFound = sal_True;
                        }
                        else
                            break;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
    }
}

void ScInputHandler::ShowTip( const String& rText )
{
	//	aManualTip muss hinterher von aussen gesetzt werden
	HideTip();

	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if (pActiveView)
	{
		Point aPos;
		pTipVisibleParent = pActiveView->GetWindow();
		Cursor* pCur = pActiveView->GetCursor();
		if (pCur)
			aPos = pTipVisibleParent->LogicToPixel( pCur->GetPos() );
		aPos = pTipVisibleParent->OutputToScreenPixel( aPos );
		Rectangle aRect( aPos, aPos );

		sal_uInt16 nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
		nTipVisible = Help::ShowTip(pTipVisibleParent, aRect, rText, nAlign);
		pTipVisibleParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) );
	}
}

void ScInputHandler::ShowTipBelow( const String& rText )
{
    HideTipBelow();

    EditView* pActiveView = pTopView ? pTopView : pTableView;
    if ( pActiveView )
    {
        Point aPos;
        pTipVisibleSecParent = pActiveView->GetWindow();
        Cursor* pCur = pActiveView->GetCursor();
        if ( pCur )
        {
            Point aLogicPos = pCur->GetPos();
            aLogicPos.Y() += pCur->GetHeight();
            aPos = pTipVisibleSecParent->LogicToPixel( aLogicPos );
        }
        aPos = pTipVisibleSecParent->OutputToScreenPixel( aPos );
        Rectangle aRect( aPos, aPos );
        sal_uInt16 nAlign = QUICKHELP_LEFT | QUICKHELP_TOP | QUICKHELP_NOEVADEPOINTER;
        nTipVisibleSec = Help::ShowTip(pTipVisibleSecParent, aRect, rText, nAlign);
        pTipVisibleSecParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) );
    }
}

void ScInputHandler::UseFormulaData()
{
	EditView* pActiveView = pTopView ? pTopView : pTableView;
    ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
    const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
    const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());

	//	Formeln duerfen nur 1 Absatz haben
	if ( pActiveView && pFormulaData && pEngine->GetParagraphCount() == 1 )
	{
		String aTotal = pEngine->GetText( (sal_uInt16) 0 );
		ESelection aSel = pActiveView->GetSelection();
		aSel.Adjust();

		//	#59348# Durch Differenzen zwischen Tabelle und Eingabezeile
		//	(z.B. Clipboard mit Zeilenumbruechen) kann es sein, dass die Selektion
		//	nicht mehr zur EditEngine passt. Dann halt kommentarlos abbrechen:

		if ( aSel.nEndPos > aTotal.Len() )
			return;

		//	steht der Cursor am Ende eines Wortes?

		if ( aSel.nEndPos > 0 )
		{
            xub_StrLen nPos = aSel.nEndPos;
            String  aFormula = aTotal.Copy( 0, nPos );
            xub_StrLen  nLeftParentPos = 0;
            xub_StrLen  nNextFStart = 0;
            xub_StrLen  nNextFEnd = 0;
            xub_StrLen  nArgPos = 0;
            const IFunctionDescription* ppFDesc;
            ::std::vector< ::rtl::OUString> aArgs;
            sal_uInt16	    nArgs;
            sal_Bool  bFound = sal_False;

            String aText = pEngine->GetWord( 0, aSel.nEndPos-1 );
            if ( aText.Len() )
            {
                String aNew;
                nAutoPos = SCPOS_INVALID;
                if ( pFormulaData->FindText( aText, aNew, nAutoPos, sal_False ) )
                {
                    ShowTip( aNew );
                    aAutoSearch = aText;
                }
            }
            FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr());

            while( !bFound )
            {
                aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
                nLeftParentPos = lcl_MatchParenthesis( aFormula, aFormula.Len()-1 );
                if( nLeftParentPos == STRING_NOTFOUND )
                    break;

                // #160063# nLeftParentPos can be 0 if a parenthesis is inserted before the formula
                sal_Unicode c = ( nLeftParentPos > 0 ) ? aFormula.GetChar( nLeftParentPos-1 ) : 0;
                if( !((c >= 'A' && c<= 'Z') || (c>= 'a' && c<= 'z') ) )
                    continue;
                nNextFStart = aHelper.GetFunctionStart( aFormula, nLeftParentPos, sal_True);
                if( aHelper.GetNextFunc( aFormula, sal_False, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) )
                {
                    if( ppFDesc->getFunctionName().getLength() )
                    {
                        nArgPos = aHelper.GetArgStart( aFormula, nNextFStart, 0 );
                        nArgs = static_cast<sal_uInt16>(ppFDesc->getParameterCount());

                        sal_uInt16 nActive = 0;
                        sal_uInt16 nCount = 0;
                        sal_uInt16 nCountSemicolon = 0;
                        sal_uInt16 nCountDot = 0;
                        sal_uInt16 nStartPosition = 0;
                        sal_uInt16 nEndPosition = 0;
                        sal_Bool   bFlag = sal_False;
                        String aNew;
                        sal_uInt16 nParAutoPos = SCPOS_INVALID;
                        if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, sal_False ) )
                        {
                            for( sal_uInt16 i=0; i < nArgs; i++ )
                            {
                                xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength());
                                if( nArgPos <= aFormula.Len()-1 )
                                {
                                    nActive = i+1;
                                    bFlag = sal_True;
                                }
                                nArgPos+=nLength+1;
                            }
                            if( bFlag )
                            {
                                nCountSemicolon = aNew.GetTokenCount(cSep)-1;
                                nCountDot = aNew.GetTokenCount(cSheetSep)-1;

                               if( !nCountSemicolon )
                               {
                                    for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
                                    {
                                        sal_Unicode cNext = aNew.GetChar( i );
                                        if( cNext == '(' )
                                        {
                                            nStartPosition = i+1;
                                        }
                                    }
                                }
                                else if( !nCountDot )
                                {
                                    for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
                                    {
                                        sal_Unicode cNext = aNew.GetChar( i );
                                        if( cNext == '(' )
                                        {
                                            nStartPosition = i+1;
                                        }
                                        else if( cNext == cSep )
                                        {
                                            nCount ++;
                                            nEndPosition = i;
                                            if( nCount == nActive )
                                            {
                                                break;
                                            }
                                            nStartPosition = nEndPosition+1;
                                        }
                                    }
                                }
                                else
                                {
                                    for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
                                    {
                                        sal_Unicode cNext = aNew.GetChar( i );
                                        if( cNext == '(' )
                                        {
                                            nStartPosition = i+1;
                                        }
                                        else if( cNext == cSep )
                                        {
                                            nCount ++;
                                            nEndPosition = i;
                                            if( nCount == nActive )
                                            {
                                                break;
                                            }
                                            nStartPosition = nEndPosition+1;
                                        }
                                        else if( cNext == cSheetSep )
                                        {
                                            continue;
                                        }
                                    }
                                }

                                if( nStartPosition )
                                {
                                    aNew.Insert( 0x25BA, nStartPosition );
                                    ShowTipBelow( aNew );
                                    bFound = sal_True;
                                }
                            }
                            else
                            {
                                ShowTipBelow( aNew );
                                bFound = sal_True;
                            }
                        }
                    }
                }
            }
        }
    }
}

void ScInputHandler::NextFormulaEntry( sal_Bool bBack )
{
	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if ( pActiveView && pFormulaData )
	{
		String aNew;
		if ( pFormulaData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) )
			ShowTip( aNew );		//	als QuickHelp anzeigen
	}

	//	bei Tab wird vorher immer HideCursor gerufen

	if (pActiveView)
		pActiveView->ShowCursor();
}

void lcl_CompleteFunction( EditView* pView, const String& rInsert, sal_Bool& rParInserted )
{
	if (pView)
	{
		ESelection aSel = pView->GetSelection();
		--aSel.nStartPos;
		--aSel.nEndPos;
		pView->SetSelection(aSel);
		pView->SelectCurrentWord();

		String aInsStr = rInsert;
		xub_StrLen nInsLen = aInsStr.Len();
		sal_Bool bDoParen = ( nInsLen > 1 && aInsStr.GetChar(nInsLen-2) == '('
									  && aInsStr.GetChar(nInsLen-1) == ')' );
		if ( bDoParen )
		{
			//	Klammern hinter Funktionsnamen nicht einfuegen, wenn direkt dahinter
			//	schon eine Klammer steht (z.B. wenn der Funktionsname geaendert wurde,
			//	#39393#).

			ESelection aWordSel = pView->GetSelection();
			String aOld = pView->GetEditEngine()->GetText((sal_uInt16)0);
			sal_Unicode cNext = aOld.GetChar(aWordSel.nEndPos);
			if ( cNext == '(' )
			{
				bDoParen = sal_False;
				aInsStr.Erase( nInsLen - 2 );	// Klammern weglassen
			}
		}

		pView->InsertText( aInsStr, sal_False );

		if ( bDoParen )							// Cursor zwischen die Klammern setzen
		{
			aSel = pView->GetSelection();
			--aSel.nStartPos;
			--aSel.nEndPos;
			pView->SetSelection(aSel);

			rParInserted = sal_True;
		}
	}
}

void ScInputHandler::PasteFunctionData()
{
	if ( pFormulaData && nAutoPos != SCPOS_INVALID )
	{
		TypedStrData* pData = (*pFormulaData)[nAutoPos];
		if (pData)
		{
			String aInsert = pData->GetString();
			sal_Bool bParInserted = sal_False;

			DataChanging(); 						// kann nicht neu sein
			lcl_CompleteFunction( pTopView, aInsert, bParInserted );
			lcl_CompleteFunction( pTableView, aInsert, bParInserted );
			DataChanged();
            ShowTipCursor();

			if (bParInserted)
				AutoParAdded();
		}
	}

	HideTip();

	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if (pActiveView)
		pActiveView->ShowCursor();
}

//
//		Selektion berechnen und als Tip-Hilfe anzeigen
//

String lcl_Calculate( const String& rFormula, ScDocument* pDoc, const ScAddress &rPos )
{
	//!		mit ScFormulaDlg::CalcValue zusammenfassen und ans Dokument verschieben !!!!
	//!		(Anfuehrungszeichen bei Strings werden nur hier eingefuegt)

	String aValue;

	if (rFormula.Len())
	{
		ScFormulaCell* pCell = new ScFormulaCell( pDoc, rPos, rFormula );

		// #35521# HACK! um bei ColRowNames kein #REF! zu bekommen,
		// wenn ein Name eigentlich als Bereich in die Gesamt-Formel
		// eingefuegt wird, bei der Einzeldarstellung aber als
		// single-Zellbezug interpretiert wird
		sal_Bool bColRowName = pCell->HasColRowName();
		if ( bColRowName )
		{
			// ColRowName im RPN-Code?
			if ( pCell->GetCode()->GetCodeLen() <= 1 )
			{	// ==1: einzelner ist als Parameter immer Bereich
				// ==0: es waere vielleicht einer, wenn..
				String aBraced( '(' );
				aBraced += rFormula;
				aBraced += ')';
				delete pCell;
				pCell = new ScFormulaCell( pDoc, rPos, aBraced );
			}
			else
				bColRowName = sal_False;
		}

		sal_uInt16 nErrCode = pCell->GetErrCode();
		if ( nErrCode == 0 )
		{
			SvNumberFormatter& aFormatter = *(pDoc->GetFormatTable());
			Color* pColor;
			if ( pCell->IsValue() )
			{
				double n = pCell->GetValue();
				sal_uLong nFormat = aFormatter.GetStandardFormat( n, 0,
								pCell->GetFormatType(), ScGlobal::eLnge );
				aFormatter.GetInputLineString( n, nFormat, aValue );
				//!	display OutputString but insert InputLineString
			}
			else
			{
				String aStr;

				pCell->GetString( aStr );
				sal_uLong nFormat = aFormatter.GetStandardFormat(
								pCell->GetFormatType(), ScGlobal::eLnge);
				aFormatter.GetOutputString( aStr, nFormat,
											aValue, &pColor );

				aValue.Insert('"',0);	// in Anfuehrungszeichen
				aValue+='"';
				//!	Anfuehrungszeichen im String escapen ????
			}

			ScRange aTestRange;
			if ( bColRowName || (aTestRange.Parse(rFormula) & SCA_VALID) )
				aValue.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ..." ));		// Bereich
		}
		else
			aValue = ScGlobal::GetErrorString(nErrCode);
		delete pCell;
	}

	return aValue;
}

void ScInputHandler::FormulaPreview()
{
	String aValue;
	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if ( pActiveView && pActiveViewSh )
	{
		String aPart = pActiveView->GetSelected();
		if (!aPart.Len())
			aPart = pEngine->GetText((sal_uInt16)0);
		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
		aValue = lcl_Calculate( aPart, pDoc, aCursorPos );
	}

	if (aValue.Len())
	{
		ShowTip( aValue );			//	als QuickHelp anzeigen
		aManualTip = aValue;		//	nach ShowTip setzen
		nAutoPos = SCPOS_INVALID;	//	Formel-Autocomplete aufheben
	}
}

void ScInputHandler::PasteManualTip()
{
	//	drei Punkte am Ende -> Bereichsreferenz -> nicht einfuegen
	//	(wenn wir mal Matrix-Konstanten haben, kann das geaendert werden)

	xub_StrLen nTipLen = aManualTip.Len();
	if ( nTipLen && ( nTipLen < 3 || !aManualTip.Copy( nTipLen-3 ).EqualsAscii("...") ) )
	{
		DataChanging(); 									// kann nicht neu sein

		String aInsert = aManualTip;
		EditView* pActiveView = pTopView ? pTopView : pTableView;
		if (!pActiveView->HasSelection())
		{
			//	nichts selektiert -> alles selektieren
			xub_StrLen nOldLen = pEngine->GetTextLen(0);
			ESelection aAllSel( 0, 0, 0, nOldLen );
			if ( pTopView )
				pTopView->SetSelection( aAllSel );
			if ( pTableView )
				pTableView->SetSelection( aAllSel );
		}

		ESelection aSel = pActiveView->GetSelection();
		aSel.Adjust();
		DBG_ASSERT( !aSel.nStartPara && !aSel.nEndPara, "Zuviele Absaetze in Formel" );
		if ( !aSel.nStartPos )	// Selektion ab Anfang?
		{
			if ( aSel.nEndPos == pEngine->GetTextLen(0) )
			{
				//	alles selektiert -> Anfuehrungszeichen weglassen
				if ( aInsert.GetChar(0) == '"' )
					aInsert.Erase(0,1);
				xub_StrLen nInsLen = aInsert.Len();
				if ( nInsLen && aInsert.GetChar(nInsLen-1) == '"' )
					aInsert.Erase( nInsLen-1 );
			}
			else if ( aSel.nEndPos )
			{
				//	nicht alles selektiert -> Gleichheitszeichen nicht ueberschreiben
				//!	doppelte Gleichheitszeichen auch ???

				aSel.nStartPos = 1;
				if ( pTopView )
					pTopView->SetSelection( aSel );
				if ( pTableView )
					pTableView->SetSelection( aSel );
			}
		}
		if ( pTopView )
			pTopView->InsertText( aInsert, sal_True );
		if ( pTableView )
			pTableView->InsertText( aInsert, sal_True );

		DataChanged();
	}

	HideTip();
}

void ScInputHandler::ResetAutoPar()
{
	nAutoPar = 0;
}

void ScInputHandler::AutoParAdded()
{
	++nAutoPar;		//	closing parenthesis can be overwritten
}

sal_Bool ScInputHandler::CursorAtClosingPar()
{
	//	test if the cursor is before a closing parenthesis

	//	selection from SetReference has been removed before
	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if ( pActiveView && !pActiveView->HasSelection() && bFormulaMode )
	{
		ESelection aSel = pActiveView->GetSelection();
		xub_StrLen nPos = aSel.nStartPos;
		String aFormula = pEngine->GetText((sal_uInt16)0);
		if ( nPos < aFormula.Len() && aFormula.GetChar(nPos) == ')' )
			return sal_True;
	}
	return sal_False;
}

void ScInputHandler::SkipClosingPar()
{
	//	this is called when a ')' is typed and the cursor is before a ')'
	//	that can be overwritten -> just set the cursor behind the ')'

	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if (pActiveView)
	{
		ESelection aSel = pActiveView->GetSelection();
		++aSel.nStartPos;
		++aSel.nEndPos;

		//	this is in a formula (only one paragraph), so the selection
		//	can be used directly for the TopView

		if ( pTopView )
			pTopView->SetSelection( aSel );
		if ( pTableView )
			pTableView->SetSelection( aSel );
	}

	DBG_ASSERT(nAutoPar, "SkipClosingPar: count is wrong");
	--nAutoPar;
}

//
//		Auto-Eingabe
//

void ScInputHandler::GetColData()
{
	if ( pActiveViewSh )
	{
		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();

		if ( pColumnData )
			pColumnData->FreeAll();
		else
		{
			pColumnData = new TypedScStrCollection;
			pColumnData->SetCaseSensitive( sal_True );		// equal strings are handled in FindText
		}

		pDoc->GetDataEntries( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
								*pColumnData, sal_True );
	}
}

void ScInputHandler::UseColData()			// beim Tippen
{
	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if ( pActiveView && pColumnData )
	{
		//	nur anpassen, wenn Cursor am Ende steht

		ESelection aSel = pActiveView->GetSelection();
		aSel.Adjust();

		sal_uInt32 nParCnt = pEngine->GetParagraphCount();
		if ( aSel.nEndPara+1 == nParCnt )
		{
			xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara );
			if ( aSel.nEndPos == nParLen )
			{
				String aText = GetEditText(pEngine);
				if (aText.Len())
				{
					String aNew;
					nAutoPos = SCPOS_INVALID;	// nix
					if ( pColumnData->FindText( aText, aNew, nAutoPos, sal_False ) )
					{
						//	#45434# durch dBase Import etc. koennen Umbrueche im String sein,
						//	das wuerde hier mehrere Absaetze ergeben -> nicht gut
						//!	GetExactMatch funktioniert dann auch nicht
						lcl_RemoveLineEnd( aNew );

                        //  Absaetze beibehalten, nur den Rest anfuegen
						//!	genaue Ersetzung im EnterHandler !!!

						// ein Space zwischen Absaetzen:
						sal_uLong nEdLen = pEngine->GetTextLen() + nParCnt - 1;
						String aIns = aNew.Copy( (xub_StrLen)nEdLen );

						//	selection must be "backwards", so the cursor stays behind the last
						//	typed character
						ESelection aSelection( aSel.nEndPara, aSel.nEndPos + aIns.Len(),
											   aSel.nEndPara, aSel.nEndPos );

						//	when editing in input line, apply to both edit views
						if ( pTableView )
						{
							pTableView->InsertText( aIns, sal_False );
							pTableView->SetSelection( aSelection );
						}
						if ( pTopView )
						{
							pTopView->InsertText( aIns, sal_False );
							pTopView->SetSelection( aSelection );
						}

						aAutoSearch = aText;	// zum Weitersuchen - nAutoPos ist gesetzt

						if ( aText.Len() == aNew.Len() )
						{
							//	Wenn der eingegebene Text gefunden wurde, TAB nur dann
							//	verschlucken, wenn noch etwas kommt

							String aDummy;
							sal_uInt16 nNextPos = nAutoPos;
							bUseTab = pColumnData->FindText( aText, aDummy, nNextPos, sal_False );
						}
						else
							bUseTab = sal_True;
					}
				}
			}
		}
	}
}

void ScInputHandler::NextAutoEntry( sal_Bool bBack )
{
	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if ( pActiveView && pColumnData )
	{
		if ( nAutoPos != SCPOS_INVALID && aAutoSearch.Len() )
		{
			//	stimmt die Selektion noch? (kann per Maus geaendert sein)

			ESelection aSel = pActiveView->GetSelection();
			aSel.Adjust();
			sal_uInt32 nParCnt = pEngine->GetParagraphCount();
			if ( aSel.nEndPara+1 == nParCnt && aSel.nStartPara == aSel.nEndPara )
			{
				String aText = GetEditText(pEngine);
				xub_StrLen nSelLen = aSel.nEndPos - aSel.nStartPos;
				xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara );
				if ( aSel.nEndPos == nParLen && aText.Len() == aAutoSearch.Len() + nSelLen )
				{
					String aNew;
					if ( pColumnData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) )
					{
						bInOwnChange = sal_True;		// disable ModifyHdl (reset below)

						lcl_RemoveLineEnd( aNew );
						String aIns = aNew.Copy( aAutoSearch.Len() );

						//	when editing in input line, apply to both edit views
						if ( pTableView )
						{
							pTableView->DeleteSelected();
							pTableView->InsertText( aIns, sal_False );
							pTableView->SetSelection( ESelection(
														aSel.nEndPara, aSel.nStartPos + aIns.Len(),
														aSel.nEndPara, aSel.nStartPos ) );
						}
						if ( pTopView )
						{
							pTopView->DeleteSelected();
							pTopView->InsertText( aIns, sal_False );
							pTopView->SetSelection( ESelection(
														aSel.nEndPara, aSel.nStartPos + aIns.Len(),
														aSel.nEndPara, aSel.nStartPos ) );
						}

						bInOwnChange = sal_False;
					}
					else
					{
						// mehr gibts nicht

						Sound::Beep();
					}
				}
			}
		}
	}

	//	bei Tab wird vorher immer HideCursor gerufen

	if (pActiveView)
		pActiveView->ShowCursor();
}

//
//		Klammern hervorheben
//

void ScInputHandler::UpdateParenthesis()
{
	//	Klammern suchen

	//!	Klammer-Hervorhebung einzeln abschaltbar ????

	sal_Bool bFound = sal_False;
	if ( bFormulaMode && eMode != SC_INPUT_TOP )
	{
		if ( pTableView && !pTableView->HasSelection() )		// Selektion ist immer unten
		{
			ESelection aSel = pTableView->GetSelection();
			if (aSel.nStartPos)
			{
				//	Das Zeichen links vom Cursor wird angeschaut

				xub_StrLen nPos = aSel.nStartPos - 1;
				String aFormula = pEngine->GetText((sal_uInt16)0);
				sal_Unicode c = aFormula.GetChar(nPos);
				if ( c == '(' || c == ')' )
				{
					xub_StrLen nOther = lcl_MatchParenthesis( aFormula, nPos );
					if ( nOther != STRING_NOTFOUND )
					{
						SfxItemSet aSet( pEngine->GetEmptyItemSet() );
						aSet.Put( SvxWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT ) );
						//!	Unterscheidung, wenn die Zelle schon fett ist !!!!

						if (bParenthesisShown)
						{
							//	alte Hervorhebung wegnehmen
							sal_uInt32 nCount = pEngine->GetParagraphCount();
							for (sal_uInt32 i=0; i<nCount; i++)
								pEngine->QuickRemoveCharAttribs( i, EE_CHAR_WEIGHT );
						}

						ESelection aSelThis( 0,nPos, 0,nPos+1 );
						pEngine->QuickSetAttribs( aSet, aSelThis );
						ESelection aSelOther( 0,nOther, 0,nOther+1 );
						pEngine->QuickSetAttribs( aSet, aSelOther );

						//	Dummy-InsertText fuer Update und Paint (Selektion ist leer)
						pTableView->InsertText( EMPTY_STRING, sal_False );

						bFound = sal_True;
					}
				}
			}

			//	mark parenthesis right of cursor if it will be overwritten (nAutoPar)
			//	with different color (COL_LIGHTBLUE) ??
		}
	}

	//	alte Hervorhebung wegnehmen, wenn keine neue gesetzt

	if ( bParenthesisShown && !bFound && pTableView )
	{
		sal_uInt32 nCount = pEngine->GetParagraphCount();
		for (sal_uInt32 i=0; i<nCount; i++)
			pTableView->RemoveCharAttribs( i, EE_CHAR_WEIGHT );
	}

	bParenthesisShown = bFound;
}

void ScInputHandler::ViewShellGone(ScTabViewShell* pViewSh) 	// wird synchron aufgerufen!
{
	if ( pViewSh == pActiveViewSh )
	{
		delete pLastState;
		pLastState = NULL;
		pLastPattern = NULL;
	}

	if ( pViewSh == pRefViewSh )
	{
		//! Die Eingabe kommt aus dem EnterHandler nicht mehr an
		//	Trotzdem wird immerhin der Editmodus beendet

		EnterHandler();
		bFormulaMode = sal_False;
		pRefViewSh = NULL;
		SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
		SC_MOD()->SetRefInputHdl(NULL);
		if (pInputWin)
			pInputWin->SetFormulaMode(sal_False);
		UpdateAutoCorrFlag();
	}

	pActiveViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );

	if ( pActiveViewSh && pActiveViewSh == pViewSh )
	{
		DBG_ERROR("pActiveViewSh weg");
		pActiveViewSh = NULL;
	}

	if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
		UpdateRefDevice();		// don't keep old document's printer as RefDevice
}

void ScInputHandler::UpdateActiveView()
{
	ImplCreateEditEngine();

    // #i20588# Don't rely on focus to find the active edit view. Instead, the
    // active pane at the start of editing is now stored (GetEditActivePart).
    // GetActiveWin (the currently active pane) fails for ref input across the
    // panes of a split view.

    Window* pShellWin = pActiveViewSh ?
                pActiveViewSh->GetWindowByPos( pActiveViewSh->GetViewData()->GetEditActivePart() ) :
                NULL;

	sal_uInt16 nCount = pEngine->GetViewCount();
	if (nCount > 0)
	{
		pTableView = pEngine->GetView(0);
		for (sal_uInt16 i=1; i<nCount; i++)
		{
			EditView* pThis = pEngine->GetView(i);
			Window* pWin = pThis->GetWindow();
			if ( pWin==pShellWin )
				pTableView = pThis;
		}
	}
	else
		pTableView = NULL;

	if (pInputWin)
		pTopView = pInputWin->GetEditView();
	else
		pTopView = NULL;
}

void ScInputHandler::StopInputWinEngine( sal_Bool bAll )
{
	if (pInputWin)
		pInputWin->StopEditEngine( bAll );

	pTopView = NULL;		// invalid now
}

EditView* ScInputHandler::GetActiveView()
{
	UpdateActiveView();
	return pTopView ? pTopView : pTableView;
}

void ScInputHandler::ForgetLastPattern()
{
	pLastPattern = NULL;
	if ( !pLastState && pActiveViewSh )
		pActiveViewSh->UpdateInputHandler( sal_True );		// Status neu holen
	else
		NotifyChange( pLastState, sal_True );
}

void ScInputHandler::UpdateAdjust( sal_Unicode cTyped )
{
	SvxAdjust eSvxAdjust;
    switch (eAttrAdjust)
	{
		case SVX_HOR_JUSTIFY_STANDARD:
			{
				sal_Bool bNumber = sal_False;
				if (cTyped)										// neu angefangen
					bNumber = (cTyped>='0' && cTyped<='9');		// nur Ziffern sind Zahlen
				else if ( pActiveViewSh )
				{
					ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
					bNumber = ( pDoc->GetCellType( aCursorPos ) == CELLTYPE_VALUE );
				}
				eSvxAdjust = bNumber ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
			}
			break;
		case SVX_HOR_JUSTIFY_BLOCK:
			eSvxAdjust = SVX_ADJUST_BLOCK;
			break;
		case SVX_HOR_JUSTIFY_CENTER:
			eSvxAdjust = SVX_ADJUST_CENTER;
			break;
		case SVX_HOR_JUSTIFY_RIGHT:
			eSvxAdjust = SVX_ADJUST_RIGHT;
			break;
		default:	// SVX_HOR_JUSTIFY_LEFT
			eSvxAdjust = SVX_ADJUST_LEFT;
			break;
	}

	sal_Bool bAsianVertical = pLastPattern &&
        ((const SfxBoolItem&)pLastPattern->GetItem( ATTR_STACKED )).GetValue() &&
		((const SfxBoolItem&)pLastPattern->GetItem( ATTR_VERTICAL_ASIAN )).GetValue();
	if ( bAsianVertical )
	{
		//	always edit at top of cell -> LEFT when editing vertically
		eSvxAdjust = SVX_ADJUST_LEFT;
	}

	pEditDefaults->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
	pEngine->SetDefaults( *pEditDefaults );

    nEditAdjust = sal::static_int_cast<sal_uInt16>(eSvxAdjust);     //! set at ViewData or with PostEditView

	pEngine->SetVertical( bAsianVertical );
}

void ScInputHandler::RemoveAdjust()
{
	//	harte Ausrichtungs-Attribute loeschen

	sal_Bool bUndo = pEngine->IsUndoEnabled();
	if ( bUndo )
		pEngine->EnableUndo( sal_False );

	//	RemoveParaAttribs removes all paragraph attributes, including EE_PARA_JUST
#if 0
	sal_Bool bChange = sal_False;
	sal_uInt32 nCount = pEngine->GetParagraphCount();
	for (sal_uInt32 i=0; i<nCount; i++)
	{
		const SfxItemSet& rOld = pEngine->GetParaAttribs( i );
		if ( rOld.GetItemState( EE_PARA_JUST ) == SFX_ITEM_SET )
		{
			SfxItemSet aNew( rOld );
			aNew.ClearItem( EE_PARA_JUST );
			pEngine->SetParaAttribs( i, aNew );
			bChange = sal_True;
		}
	}
#endif

	//	#89403# non-default paragraph attributes (e.g. from clipboard)
	//	must be turned into character attributes
	pEngine->RemoveParaAttribs();

	if ( bUndo )
		pEngine->EnableUndo( sal_True );

	// ER 31.08.00  Only called in EnterHandler, don't change view anymore.
#if 0
	if (bChange)
	{
		EditView* pActiveView = pTopView ? pTopView : pTableView;
		pActiveView->ShowCursor( sal_False, sal_True );
	}
#endif
}

void ScInputHandler::RemoveRangeFinder()
{
	//	pRangeFindList und Farben loeschen

	pEngine->SetUpdateMode(sal_False);
	sal_uInt32 nCount = pEngine->GetParagraphCount();	// koennte gerade neu eingefuegt worden sein
	for (sal_uInt32 i=0; i<nCount; i++)
		pEngine->QuickRemoveCharAttribs( i, EE_CHAR_COLOR );
	pEngine->SetUpdateMode(sal_True);

	EditView* pActiveView = pTopView ? pTopView : pTableView;
	pActiveView->ShowCursor( sal_False, sal_True );

	DeleteRangeFinder();		// loescht die Liste und die Markierungen auf der Tabelle
}

sal_Bool ScInputHandler::StartTable( sal_Unicode cTyped, sal_Bool bFromCommand )
{
	// returns sal_True if a new edit mode was started

	sal_Bool bNewTable = sal_False;

	if (!bModified && ValidCol(aCursorPos.Col()))
	{
		if (pActiveViewSh)
		{
			ImplCreateEditEngine();
			UpdateActiveView();
			SyncViews();

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

			const ScMarkData& rMark = pActiveViewSh->GetViewData()->GetMarkData();
			ScEditableTester aTester;
			if ( rMark.IsMarked() || rMark.IsMultiMarked() )
				aTester.TestSelection( pDoc, rMark );
			else
				aTester.TestSelectedBlock( pDoc, aCursorPos.Col(),aCursorPos.Row(),
												 aCursorPos.Col(),aCursorPos.Row(), rMark );
			if ( aTester.IsEditable() )
			{
				// UpdateMode is enabled again in ScViewData::SetEditEngine (and not needed otherwise)
				pEngine->SetUpdateMode( sal_False );

				//	Attribute in EditEngine uebernehmen

				const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(),
																  aCursorPos.Row(),
																  aCursorPos.Tab() );
				if (pPattern != pLastPattern)
				{
					//	Prozent-Format?

					const SfxItemSet& rAttrSet = pPattern->GetItemSet();
					const SfxPoolItem* pItem;

					if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALUE_FORMAT, sal_True, &pItem ) )
					{
						sal_uLong nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
						bCellHasPercentFormat = ( NUMBERFORMAT_PERCENT ==
												  pDoc->GetFormatTable()->GetType( nFormat ) );
					}
					else
						bCellHasPercentFormat = sal_False; // Default: kein Prozent

					//	Gueltigkeit angegeben?

					if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALIDDATA, sal_True, &pItem ) )
						nValidation = ((const SfxUInt32Item*)pItem)->GetValue();
					else
						nValidation = 0;

					// 	EditEngine Defaults

					//	Hier auf keinen Fall SetParaAttribs, weil die EditEngine evtl.
					//	schon gefuellt ist (bei Edit-Zellen).
					//	SetParaAttribs wuerde dann den Inhalt aendern

					//! ER 30.08.00  The SetDefaults is now (since MUST/src602
					//! EditEngine changes) implemented as a SetParaAttribs.
					//! Any problems?

					pPattern->FillEditItemSet( pEditDefaults );
					pEngine->SetDefaults( *pEditDefaults );
					pLastPattern = pPattern;
					bLastIsSymbol = pPattern->IsSymbolFont();

					//	Background color must be known for automatic font color.
					//	For transparent cell background, the document background color must be used.

					Color aBackCol = ((const SvxBrushItem&)
									pPattern->GetItem( ATTR_BACKGROUND )).GetColor();
					ScModule* pScMod = SC_MOD();
					//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
					if ( aBackCol.GetTransparency() > 0 ||
							Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
                        aBackCol.SetColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
					pEngine->SetBackgroundColor( aBackCol );

					//	Ausrichtung

                    eAttrAdjust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
									GetItem(ATTR_HOR_JUSTIFY)).GetValue();
                    if ( eAttrAdjust == SVX_HOR_JUSTIFY_REPEAT &&
                         static_cast<const SfxBoolItem&>(pPattern->GetItem(ATTR_LINEBREAK)).GetValue() )
                    {
                        // #i31843# "repeat" with "line breaks" is treated as default alignment
                        eAttrAdjust = SVX_HOR_JUSTIFY_STANDARD;
                    }
				}

				//	UpdateSpellSettings enables online spelling if needed
				//	-> also call if attributes are unchanged

				UpdateSpellSettings( sal_True );	// uses pLastPattern

				//	Edit-Engine fuellen

				String aStr;
				if (bTextValid)
				{
					pEngine->SetText(aCurrentText);
					aStr = aCurrentText;
					bTextValid = sal_False;
					aCurrentText.Erase();
				}
				else
					aStr = GetEditText(pEngine);

				if (aStr.Len() > 3 && 					// Matrix-Formel ?
					aStr.GetChar(0) == '{' &&
					aStr.GetChar(1) == '=' &&
					aStr.GetChar(aStr.Len()-1) == '}')
				{
					aStr.Erase(0,1);
					aStr.Erase(aStr.Len()-1,1);
					pEngine->SetText(aStr);
					if ( pInputWin )
						pInputWin->SetTextString(aStr);
				}

				UpdateAdjust( cTyped );

				if ( bAutoComplete )
					GetColData();

                if ( ( aStr.GetChar(0) == '=' || aStr.GetChar(0) == '+' || aStr.GetChar(0) == '-' ) &&
                     !cTyped && !bCreatingFuncView )
					InitRangeFinder(aStr);				// Formel wird editiert -> RangeFinder

				bNewTable = sal_True;		//	-> PostEditView-Aufruf
			}
			else
			{
				bProtected = sal_True;
				eMode = SC_INPUT_NONE;
				StopInputWinEngine( sal_True );
				UpdateFormulaMode();
				if ( pActiveViewSh && ( !bFromCommand || !bCommandErrorShown ) )
				{
					//	#97673# Prevent repeated error messages for the same cell from command events
					//	(for keyboard events, multiple messages are wanted).
					//	Set the flag before showing the error message because the command handler
					//	for the next IME command may be called when showing the dialog.
					if ( bFromCommand )
						bCommandErrorShown = sal_True;

					pActiveViewSh->GetActiveWin()->GrabFocus();
					pActiveViewSh->ErrorMessage(aTester.GetMessageId());
				}
			}
		}

		if (!bProtected && pInputWin)
			pInputWin->SetOkCancelMode();
	}

	return bNewTable;
}

void lcl_SetTopSelection( EditView* pEditView, ESelection& rSel )
{
	DBG_ASSERT( rSel.nStartPara==0 && rSel.nEndPara==0, "SetTopSelection: Para != 0" );

	EditEngine* pEngine = pEditView->GetEditEngine();
	sal_uInt32 nCount = pEngine->GetParagraphCount();
	if (nCount > 1)
	{
		xub_StrLen nParLen = pEngine->GetTextLen(rSel.nStartPara);
		while (rSel.nStartPos > nParLen && rSel.nStartPara+1 < nCount)
		{
			rSel.nStartPos -= nParLen + 1;			// incl. Leerzeichen vom Umbruch
			nParLen = pEngine->GetTextLen(++rSel.nStartPara);
		}

		nParLen = pEngine->GetTextLen(rSel.nEndPara);
		while (rSel.nEndPos > nParLen && rSel.nEndPara+1 < nCount)
		{
			rSel.nEndPos -= nParLen + 1;			// incl. Leerzeichen vom Umbruch
			nParLen = pEngine->GetTextLen(++rSel.nEndPara);
		}
	}

	ESelection aSel = pEditView->GetSelection();

	if (   rSel.nStartPara != aSel.nStartPara || rSel.nEndPara != aSel.nEndPara
		|| rSel.nStartPos  != aSel.nStartPos  || rSel.nEndPos  != aSel.nEndPos )
		pEditView->SetSelection( rSel );
}

void ScInputHandler::SyncViews( EditView* pSourceView )
{
	ESelection aSel;

	if (pSourceView)
	{
		aSel = pSourceView->GetSelection();
		if (pTopView && pTopView != pSourceView)
			pTopView->SetSelection( aSel );
		if (pTableView && pTableView != pSourceView)
			lcl_SetTopSelection( pTableView, aSel );
	}
	else if (pTopView && pTableView)
	{
		aSel = pTopView->GetSelection();
		lcl_SetTopSelection( pTableView, aSel );
	}
}

IMPL_LINK( ScInputHandler, ModifyHdl, void *, EMPTYARG )
{
	if ( !bInOwnChange && ( eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE ) &&
		 pEngine && pEngine->GetUpdateMode() && pInputWin )
	{
		//	#102745# update input line from ModifyHdl for changes that are not
		//	wrapped by DataChanging/DataChanged calls (like Drag&Drop)

		String aText = GetEditText(pEngine);
		lcl_RemoveTabs(aText);
		pInputWin->SetTextString(aText);
	}
	return 0;
}

sal_Bool ScInputHandler::DataChanging( sal_Unicode cTyped, sal_Bool bFromCommand )		// return sal_True = new view created
{
	bInOwnChange = sal_True;				// disable ModifyHdl (reset in DataChanged)

	if ( eMode == SC_INPUT_NONE )
		return StartTable( cTyped, bFromCommand );
	else
		return sal_False;
}

void ScInputHandler::DataChanged( sal_Bool bFromTopNotify, sal_Bool bSetModified )
{
	ImplCreateEditEngine();

	if (eMode==SC_INPUT_NONE)
		eMode = SC_INPUT_TYPE;

	if ( eMode == SC_INPUT_TOP && pTopView && !bFromTopNotify )
	{
		//	table EditEngine is formatted below, input line needs formatting after paste
		//	#i20282# not when called from the input line's modify handler
		pTopView->GetEditEngine()->QuickFormatDoc( sal_True );

		//	#i23720# QuickFormatDoc hides the cursor, but can't show it again because it
		//	can't safely access the EditEngine's current view, so the cursor has to be
		//	shown again here.
		pTopView->ShowCursor();
	}

    if (bSetModified)
        bModified = sal_True;
	bSelIsRef = sal_False;

	if ( pRangeFindList && !bInRangeUpdate )
		RemoveRangeFinder();					// Attribute und Markierung loeschen

	UpdateParenthesis();	//	Hervorhebung der Klammern neu

	// ER 31.08.00  New SetDefaults sets ParaAttribs, don't clear them away ...
//	RemoveAdjust();		//	#40255# harte Ausrichtungs-Attribute loeschen

	if (eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE)
	{
		String aText = GetEditText(pEngine);
		lcl_RemoveTabs(aText);

		if ( pInputWin )
			pInputWin->SetTextString(aText);
	}

		//	wenn der Cursor vor dem Absatzende steht, werden Teile rechts rausgeschoben
		//	(unabhaengig von eMode)		-> View anpassen!
		//	wenn der Cursor am Ende steht, reicht der Status-Handler an der ViewData

	//	#93767# first make sure the status handler is called now if the cursor
	//	is outside the visible area
	pEngine->QuickFormatDoc();

	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if (pActiveView && pActiveViewSh)
	{
		ScViewData* pViewData = pActiveViewSh->GetViewData();

		sal_Bool bNeedGrow = ( nEditAdjust != SVX_ADJUST_LEFT );		// rechtsbuendig immer
		if (!bNeedGrow)
		{
				//	Cursor vor dem Ende?
			ESelection aSel = pActiveView->GetSelection();
			aSel.Adjust();
			bNeedGrow = ( aSel.nEndPos != pEngine->GetTextLen(aSel.nEndPara) );
		}
		if (!bNeedGrow)
		{
			bNeedGrow = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
		}
		if (bNeedGrow)
		{
			// adjust inplace view
			pViewData->EditGrowY();
			pViewData->EditGrowX();
		}
	}

	UpdateFormulaMode();
	bTextValid = sal_False;			// Aenderungen sind nur in der Edit-Engine
	bInOwnChange = sal_False;
}

void ScInputHandler::UpdateFormulaMode()
{
	SfxApplication* pSfxApp = SFX_APP();

    if ( pEngine->GetParagraphCount() == 1 &&
         ( pEngine->GetText(0).GetChar(0) == '=' ||
           pEngine->GetText(0).GetChar(0) == '+' ||
           pEngine->GetText(0).GetChar(0) == '-' ) &&
         !bProtected )
	{
		if (!bFormulaMode)
		{
			bFormulaMode = sal_True;
			pRefViewSh = pActiveViewSh;
			pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
			SC_MOD()->SetRefInputHdl(this);
			if (pInputWin)
				pInputWin->SetFormulaMode(sal_True);

			if ( bAutoComplete )
				GetFormulaData();

			UpdateParenthesis();
			UpdateAutoCorrFlag();
		}
	}
	else		// ausschalten
	{
		if (bFormulaMode)
		{
			ShowRefFrame();
			bFormulaMode = sal_False;
			pRefViewSh = NULL;
			pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
			SC_MOD()->SetRefInputHdl(NULL);
			if (pInputWin)
				pInputWin->SetFormulaMode(sal_False);
			UpdateAutoCorrFlag();
		}
	}
}

void ScInputHandler::ShowRefFrame()
{
    // #123169# Modifying pActiveViewSh here would interfere with the bInEnterHandler / bRepeat
    // checks in NotifyChange, and lead to keeping the wrong value in pActiveViewSh.
    // A local variable is used instead.
    ScTabViewShell* pVisibleSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
    if ( pRefViewSh && pRefViewSh != pVisibleSh )
	{
		sal_Bool bFound = sal_False;
		SfxViewFrame* pRefFrame = pRefViewSh->GetViewFrame();
		SfxViewFrame* pOneFrame = SfxViewFrame::GetFirst();
		while ( pOneFrame && !bFound )
		{
			if ( pOneFrame == pRefFrame )
				bFound = sal_True;
			pOneFrame = SfxViewFrame::GetNext( *pOneFrame );
		}

		if (bFound)
		{
			//	Hier wird sich darauf verlassen, dass Activate synchron funktioniert
			//	(dabei wird pActiveViewSh umgesetzt)

			pRefViewSh->SetActive();	// Appear und SetViewFrame

			//	pLastState wird im NotifyChange aus dem Activate richtig gesetzt
		}
		else
		{
			DBG_ERROR("ViewFrame fuer Referenzeingabe ist nicht mehr da");
		}
	}
}

void ScInputHandler::RemoveSelection()
{
	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if (!pActiveView)
		return;

	ESelection aSel = pActiveView->GetSelection();
	aSel.nStartPara = aSel.nEndPara;
	aSel.nStartPos  = aSel.nEndPos;
	if (pTableView)
		pTableView->SetSelection( aSel );
	if (pTopView)
		pTopView->SetSelection( aSel );
}

void ScInputHandler::InvalidateAttribs()
{
	SfxViewFrame* pViewFrm = SfxViewFrame::Current();
	if (pViewFrm)
	{
		SfxBindings& rBindings = pViewFrm->GetBindings();

		rBindings.Invalidate( SID_ATTR_CHAR_FONT );
		rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
		rBindings.Invalidate( SID_ATTR_CHAR_COLOR );

		rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
		rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
		rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
		rBindings.Invalidate( SID_ULINE_VAL_NONE );
		rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
		rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
		rBindings.Invalidate( SID_ULINE_VAL_DOTTED );

		rBindings.Invalidate( SID_HYPERLINK_GETLINK );

		rBindings.Invalidate( SID_ATTR_CHAR_KERNING );
		rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
		rBindings.Invalidate( SID_SET_SUB_SCRIPT );
		rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT );
		rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED );
	}
}


//
//		--------------- public Methoden --------------------------------------------
//

void ScInputHandler::SetMode( ScInputMode eNewMode )
{
	if ( eMode == eNewMode )
		return;

	ImplCreateEditEngine();

	if (bProtected)
	{
		eMode = SC_INPUT_NONE;
		StopInputWinEngine( sal_True );
		if (pActiveViewSh)
			pActiveViewSh->GetActiveWin()->GrabFocus();
		return;
	}

	bInOwnChange = sal_True;				// disable ModifyHdl (reset below)

	ScInputMode eOldMode = eMode;
	eMode = eNewMode;
	if (eOldMode == SC_INPUT_TOP && eNewMode != eOldMode)
		StopInputWinEngine( sal_False );

	if (eMode==SC_INPUT_TOP || eMode==SC_INPUT_TABLE)
	{
		if (eOldMode == SC_INPUT_NONE)		// not when switching between modes
		{
			if (StartTable(0, sal_False))		// 0 = look at existing document content for text or number
			{
				if (pActiveViewSh)
					pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
			}
		}

		sal_uInt32 nPara    = pEngine->GetParagraphCount()-1;
		xub_StrLen nLen = pEngine->GetText(nPara).Len();
		sal_uInt16 nCount   = pEngine->GetViewCount();

		for (sal_uInt32 i=0; i<nCount; i++)
		{
			if ( eMode == SC_INPUT_TABLE && eOldMode == SC_INPUT_TOP )
			{
				//	Selektion bleibt
			}
			else
			{
				pEngine->GetView(i)->
					SetSelection( ESelection( nPara, nLen, nPara, nLen ) );
			}
			pEngine->GetView(i)->ShowCursor(sal_False);
		}
	}

	UpdateActiveView();
	if (eMode==SC_INPUT_TABLE || eMode==SC_INPUT_TYPE)
	{
		if (pTableView)
			pTableView->SetEditEngineUpdateMode(sal_True);
	}
	else
	{
		if (pTopView)
			pTopView->SetEditEngineUpdateMode(sal_True);
	}

	if (eNewMode != eOldMode)
		UpdateFormulaMode();

	bInOwnChange = sal_False;
}

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

//	lcl_IsNumber - sal_True, wenn nur Ziffern (dann keine Autokorrektur)

sal_Bool lcl_IsNumber(const String& rString)
{
	xub_StrLen nLen = rString.Len();
	for (xub_StrLen i=0; i<nLen; i++)
	{
		sal_Unicode c = rString.GetChar(i);
		if ( c < '0' || c > '9' )
			return sal_False;
	}
	return sal_True;
}

void lcl_SelectionToEnd( EditView* pView )
{
    if ( pView )
    {
        EditEngine* pEngine = pView->GetEditEngine();
        sal_uInt32 nParCnt = pEngine->GetParagraphCount();
        if ( nParCnt == 0 )
            nParCnt = 1;
        ESelection aSel( nParCnt-1, pEngine->GetTextLen(nParCnt-1) );   // empty selection, cursor at the end
        pView->SetSelection( aSel );
    }
}

void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode )
{
	//	#62806# Bei Makro-Aufrufen fuer Gueltigkeit kann Tod und Teufel passieren,
	//	darum dafuer sorgen, dass EnterHandler nicht verschachtelt gerufen wird:

	if (bInEnterHandler) return;
	bInEnterHandler = sal_True;
	bInOwnChange = sal_True;				// disable ModifyHdl (reset below)

	ImplCreateEditEngine();

	sal_Bool bMatrix = ( nBlockMode == SC_ENTER_MATRIX );

	SfxApplication*	pSfxApp		= SFX_APP();
	EditTextObject* pObject		= NULL;
	ScPatternAttr*	pCellAttrs	= NULL;
	sal_Bool			bAttrib		= sal_False;	// Formatierung vorhanden ?
	sal_Bool			bForget		= sal_False;	// wegen Gueltigkeit streichen ?

	String aString = GetEditText(pEngine);
	EditView* pActiveView = pTopView ? pTopView : pTableView;
	if (bModified && pActiveView && aString.Len() && !lcl_IsNumber(aString))
	{
        if ( pColumnData && nAutoPos != SCPOS_INVALID )
        {
            // #i47125# If AutoInput appended something, do the final AutoCorrect
            // with the cursor at the end of the input.

            lcl_SelectionToEnd(pTopView);
            lcl_SelectionToEnd(pTableView);
        }

		if (pTopView)
			pTopView->CompleteAutoCorrect();	// #59759# CompleteAutoCorrect fuer beide Views
		if (pTableView)
			pTableView->CompleteAutoCorrect();
		aString = GetEditText(pEngine);
	}
	lcl_RemoveTabs(aString);

	//	Test, ob zulaessig (immer mit einfachem String)

	if ( bModified && nValidation && pActiveViewSh )
	{
		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
		const ScValidationData*	pData = pDoc->GetValidationEntry( nValidation );
		if (pData && pData->HasErrMsg())
		{
            // #i67990# don't use pLastPattern in EnterHandler
            const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
			sal_Bool bOk = pData->IsDataValid( aString, *pPattern, aCursorPos );

			if (!bOk)
			{
				if ( pActiveViewSh )				// falls aus MouseButtonDown gekommen
					pActiveViewSh->StopMarking();	// (die InfoBox verschluckt das MouseButtonUp)

					//!	es gibt noch Probleme, wenn die Eingabe durch Aktivieren einer
					//!	anderen View ausgeloest wurde

				Window* pParent = Application::GetDefDialogParent();
				if ( pData->DoError( pParent, aString, aCursorPos ) )
					bForget = sal_True;					// Eingabe nicht uebernehmen
			}
		}
	}

    // check for input into DataPilot table

	if ( bModified && pActiveViewSh && !bForget )
	{
		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
        ScDPObject* pDPObj = pDoc->GetDPAtCursor( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
        if ( pDPObj )
        {
            // any input within the DataPilot table is either a valid renaming
            // or an invalid action - normal cell input is always aborted

            pActiveViewSh->DataPilotInput( aCursorPos, aString );
            bForget = sal_True;
        }
	}

	pEngine->CompleteOnlineSpelling();
	sal_Bool bSpellErrors = !bFormulaMode && pEngine->HasOnlineSpellErrors();
	if ( bSpellErrors )
	{
		//	#i3820# If the spell checker flags numerical input as error,
		//	it still has to be treated as number, not EditEngine object.

        if ( pActiveViewSh )
		{
			ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
            // #i67990# don't use pLastPattern in EnterHandler
            const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
			SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
			// without conditional format, as in ScColumn::SetString
            sal_uInt32 nFormat = pPattern->GetNumberFormat( pFormatter );
			double nVal;
			if ( pFormatter->IsNumberFormat( aString, nFormat, nVal ) )
			{
				bSpellErrors = sal_False;		// ignore the spelling errors
			}
		}
	}

	//	After RemoveAdjust, the EditView must not be repainted (has wrong font size etc).
	//	SetUpdateMode must come after CompleteOnlineSpelling.
	//	The view is hidden in any case below (Broadcast).
	pEngine->SetUpdateMode( sal_False );

	if ( bModified && !bForget )			// was wird eingeben (Text/Objekt) ?
	{
		sal_uInt32 nParCnt = pEngine->GetParagraphCount();
		if ( nParCnt == 0 )
			nParCnt = 1;
		ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) );
		SfxItemSet aOldAttribs = pEngine->GetAttribs( aSel );
		const SfxPoolItem* pItem = NULL;

		//	find common (cell) attributes before RemoveAdjust

		if ( pActiveViewSh )
		{
			SfxItemSet* pCommonAttrs = NULL;
			for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END; nId++)
			{
				SfxItemState eState = aOldAttribs.GetItemState( nId, sal_False, &pItem );
				if ( eState == SFX_ITEM_SET &&
						nId != EE_CHAR_ESCAPEMENT && nId != EE_CHAR_PAIRKERNING &&
						nId != EE_CHAR_KERNING && nId != EE_CHAR_XMLATTRIBS &&
							*pItem != pEditDefaults->Get(nId) )
				{
					if ( !pCommonAttrs )
						pCommonAttrs = new SfxItemSet( pEngine->GetEmptyItemSet() );
					pCommonAttrs->Put( *pItem );
				}
			}

			if ( pCommonAttrs )
			{
				ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
				pCellAttrs = new ScPatternAttr( pDoc->GetPool() );
				pCellAttrs->GetFromEditItemSet( pCommonAttrs );
				delete pCommonAttrs;
			}
		}

		//	clear ParaAttribs (including adjustment)

		RemoveAdjust();

		//	check if EditObject is needed

		if ( bSpellErrors || nParCnt > 1 )
			bAttrib = sal_True;
		else
		{
			for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && !bAttrib; nId++)
			{
				SfxItemState eState = aOldAttribs.GetItemState( nId, sal_False, &pItem );
				if (eState == SFX_ITEM_DONTCARE)
					bAttrib = sal_True;
				else if (eState == SFX_ITEM_SET)
				{
					//	keep same items in EditEngine as in ScEditAttrTester
					if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
						 nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS )
					{
						if ( *pItem != pEditDefaults->Get(nId) )
							bAttrib = sal_True;
					}
				}
			}

			//	Feldbefehle enthalten?

			SfxItemState eFieldState = aOldAttribs.GetItemState( EE_FEATURE_FIELD, sal_False );
			if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
				bAttrib = sal_True;

			//	not converted characters?

			SfxItemState eConvState = aOldAttribs.GetItemState( EE_FEATURE_NOTCONV, sal_False );
			if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET )
				bAttrib = sal_True;

			//	Formeln immer als Formeln erkennen (#38309#)
			//	(der Test vorher ist trotzdem noetig wegen Zell-Attributen)
		}

		if (bMatrix)
			bAttrib = sal_False;

		if (bAttrib)
		{
			sal_uLong nCtrl = pEngine->GetControlWord();
			sal_uLong nWantBig = bSpellErrors ? EE_CNTRL_ALLOWBIGOBJS : 0;
			if ( ( nCtrl & EE_CNTRL_ALLOWBIGOBJS ) != nWantBig )
				pEngine->SetControlWord( (nCtrl & ~EE_CNTRL_ALLOWBIGOBJS) | nWantBig );
			pObject = pEngine->CreateTextObject();
		}
		else if (bAutoComplete)			// Gross-/Kleinschreibung anpassen
		{
			if (pColumnData)
				pColumnData->GetExactMatch( aString );

			//!	effizienter in der Liste suchen (ScUserList, nur einmal ToUpper)

			sal_uInt16 nIndex;
			ScUserListData* pData = ScGlobal::GetUserList()->GetData(aString);
			if ( pData && pData->GetSubIndex( aString, nIndex ) )
				aString = pData->GetSubStr( nIndex );
		}
	}

	//	don't rely on ShowRefFrame switching the active view synchronously
	//	execute the function directly on the correct view's bindings instead
	//	pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call
	ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh;

	if (bFormulaMode)
	{
		ShowRefFrame();

		if (pExecuteSh)
        {
			pExecuteSh->SetTabNo(aCursorPos.Tab());
            pExecuteSh->ActiveGrabFocus();
        }

		bFormulaMode = sal_False;
		pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
		SC_MOD()->SetRefInputHdl(NULL);
		if (pInputWin)
			pInputWin->SetFormulaMode(sal_False);
		UpdateAutoCorrFlag();
	}
	pRefViewSh = NULL;			// auch ohne FormulaMode wegen Funktions-AP
	DeleteRangeFinder();
	ResetAutoPar();

	sal_Bool bOldMod = bModified;

	bModified = sal_False;
	bSelIsRef = sal_False;
	eMode 	  = SC_INPUT_NONE;
	StopInputWinEngine( sal_True );

    // #123344# Text input (through number formats) or ApplySelectionPattern modify
    // the cell's attributes, so pLastPattern is no longer valid
    pLastPattern = NULL;

	if (bOldMod && !bProtected && !bForget)
	{
		//	keine typographische Anfuehrungszeichen in Formeln

		if ( aString.GetChar(0) == '=' )
		{
			SvxAutoCorrect* pAuto = SvxAutoCorrCfg::Get()->GetAutoCorrect();
			if ( pAuto )
			{
				sal_Unicode cReplace = pAuto->GetStartDoubleQuote();
				if( !cReplace )
                    cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkStart().GetChar(0);
				if ( cReplace != '"' )
					aString.SearchAndReplaceAll( cReplace, '"' );

				cReplace = pAuto->GetEndDoubleQuote();
				if( !cReplace )
                    cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkEnd().GetChar(0);
				if ( cReplace != '"' )
					aString.SearchAndReplaceAll( cReplace, '"' );

				cReplace = pAuto->GetStartSingleQuote();
				if( !cReplace )
                    cReplace = ScGlobal::pLocaleData->getQuotationMarkStart().GetChar(0);
				if ( cReplace != '\'' )
					aString.SearchAndReplaceAll( cReplace, '\'' );

				cReplace = pAuto->GetEndSingleQuote();
				if( !cReplace )
                    cReplace = ScGlobal::pLocaleData->getQuotationMarkEnd().GetChar(0);
				if ( cReplace != '\'' )
					aString.SearchAndReplaceAll( cReplace, '\'' );
			}
		}

		pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW_NOPAINT ) );

		if ( pExecuteSh )
		{
			SfxBindings& rBindings = pExecuteSh->GetViewFrame()->GetBindings();

			sal_uInt16 nId = FID_INPUTLINE_ENTER;
			if ( nBlockMode == SC_ENTER_BLOCK )
				nId = FID_INPUTLINE_BLOCK;
			else if ( nBlockMode == SC_ENTER_MATRIX )
				nId = FID_INPUTLINE_MATRIX;

			ScInputStatusItem aItem( FID_INPUTLINE_STATUS,
									 aCursorPos, aCursorPos, aCursorPos,
									 aString, pObject );
			const SfxPoolItem* aArgs[2];
			aArgs[0] = &aItem;
			aArgs[1] = NULL;
			rBindings.Execute( nId, aArgs );
		}

		delete pLastState;		// pLastState enthaelt noch den alten Text
		pLastState = NULL;
	}
	else
		pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );

	if ( bOldMod && pExecuteSh && pCellAttrs && !bForget )
	{
		//	mit Eingabe zusammenfassen ?
		pExecuteSh->ApplySelectionPattern( *pCellAttrs, sal_True, sal_True );
		pExecuteSh->AdjustBlockHeight();
	}

	delete pCellAttrs;
	delete pObject;

	HideTip();
    HideTipBelow();

	nFormSelStart = nFormSelEnd = 0;
	aFormText.Erase();

	bInOwnChange = sal_False;
	bInEnterHandler = sal_False;
}

void ScInputHandler::CancelHandler()
{
	bInOwnChange = sal_True;				// disable ModifyHdl (reset below)

	ImplCreateEditEngine();

	bModified = sal_False;

	//	don't rely on ShowRefFrame switching the active view synchronously
	//	execute the function directly on the correct view's bindings instead
	//	pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call
	ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh;

	if (bFormulaMode)
	{
		ShowRefFrame();
		if (pExecuteSh)
        {
			pExecuteSh->SetTabNo(aCursorPos.Tab());
            pExecuteSh->ActiveGrabFocus();
        }
		bFormulaMode = sal_False;
		SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
		SC_MOD()->SetRefInputHdl(NULL);
		if (pInputWin)
			pInputWin->SetFormulaMode(sal_False);
		UpdateAutoCorrFlag();
	}
	pRefViewSh = NULL;			// auch ohne FormulaMode wegen Funktions-AP
	DeleteRangeFinder();
	ResetAutoPar();

	eMode = SC_INPUT_NONE;
	StopInputWinEngine( sal_True );
	if (pExecuteSh)
		pExecuteSh->StopEditShell();

	aCursorPos.Set(MAXCOL+1,0,0);		// Flag, dass ungueltig
	pEngine->SetText(String());

	if ( !pLastState && pExecuteSh )
		pExecuteSh->UpdateInputHandler( sal_True );		// Status neu holen
	else
		NotifyChange( pLastState, sal_True );

	nFormSelStart = nFormSelEnd = 0;
	aFormText.Erase();

	bInOwnChange = sal_False;
}

sal_Bool ScInputHandler::IsModalMode( SfxObjectShell* pDocSh )
{
	//	Referenzen auf unbenanntes Dokument gehen nicht

	return bFormulaMode && pRefViewSh
			&& pRefViewSh->GetViewData()->GetDocument()->GetDocumentShell() != pDocSh
			&& !pDocSh->HasName();
}

void ScInputHandler::AddRefEntry()
{
    const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
	UpdateActiveView();
	if (!pTableView && !pTopView)
		return; 							// z.B. FillMode

	DataChanging(); 						// kann nicht neu sein

	RemoveSelection();
	if (pTableView)
        pTableView->InsertText( cSep, sal_False );
	if (pTopView)
        pTopView->InsertText( cSep, sal_False );

	DataChanged();
}

void ScInputHandler::SetReference( const ScRange& rRef, ScDocument* pDoc )
{
	HideTip();

	sal_Bool bOtherDoc = ( pRefViewSh &&
						pRefViewSh->GetViewData()->GetDocument() != pDoc );
	if (bOtherDoc)
		if (!pDoc->GetDocumentShell()->HasName())
		{
			//	Referenzen auf unbenanntes Dokument gehen nicht
			//	(SetReference sollte dann auch nicht gerufen werden)

			return;
		}

	UpdateActiveView();
	if (!pTableView && !pTopView)
		return; 							// z.B. FillMode

	//	nie das "=" ueberschreiben!
	EditView* pActiveView = pTopView ? pTopView : pTableView;
	ESelection aSel = pActiveView->GetSelection();
	aSel.Adjust();
	if ( aSel.nStartPara == 0 && aSel.nStartPos == 0 )
		return;

	DataChanging(); 						// kann nicht neu sein

			//	Selektion umdrehen, falls rueckwaerts (noetig ???)

	if (pTableView)
	{
        ESelection aTabSel = pTableView->GetSelection();
        if (aTabSel.nStartPos > aTabSel.nEndPos && aTabSel.nStartPara == aTabSel.nEndPara)
		{
            aTabSel.Adjust();
            pTableView->SetSelection(aTabSel);
		}
	}
	if (pTopView)
	{
        ESelection aTopSel = pTopView->GetSelection();
        if (aTopSel.nStartPos > aTopSel.nEndPos && aTopSel.nStartPara == aTopSel.nEndPara)
		{
            aTopSel.Adjust();
            pTopView->SetSelection(aTopSel);
		}
	}

	//	String aus Referenz erzeugen

	String aRefStr;
	const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
	if (bOtherDoc)
	{
		//	Referenz auf anderes Dokument

		DBG_ASSERT(rRef.aStart.Tab()==rRef.aEnd.Tab(), "nStartTab!=nEndTab");

		String aTmp;
		rRef.Format( aTmp, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails );		// immer 3d

		SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
        // #i75893# convert escaped URL of the document to something user friendly
//       String aFileName = pObjSh->GetMedium()->GetName();
        String aFileName = pObjSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );

		aRefStr = '\'';
		aRefStr += aFileName;
		aRefStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "'#" ));
		aRefStr += aTmp;
	}
	else
	{
		if ( ( rRef.aStart.Tab() != aCursorPos.Tab() ||
				rRef.aStart.Tab() != rRef.aEnd.Tab() ) && pDoc )
			rRef.Format( aRefStr, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails );
		else
			rRef.Format( aRefStr, SCA_VALID, pDoc, aAddrDetails );
	}

	if (pTableView || pTopView)
	{
		if (pTableView)
			pTableView->InsertText( aRefStr, sal_True );
		if (pTopView)
			pTopView->InsertText( aRefStr, sal_True );

		DataChanged();
	}

	bSelIsRef = sal_True;
}

void ScInputHandler::InsertFunction( const String& rFuncName, sal_Bool bAddPar )
{
	if ( eMode == SC_INPUT_NONE )
	{
		DBG_ERROR("InsertFunction, nicht im Eingabemodus");
		return;
	}

	UpdateActiveView();
	if (!pTableView && !pTopView)
		return; 							// z.B. FillMode

	DataChanging(); 						// kann nicht neu sein

	String aText = rFuncName;
	if (bAddPar)
		aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));

	if (pTableView)
	{
		pTableView->InsertText( aText, sal_False );
		if (bAddPar)
		{
			ESelection aSel = pTableView->GetSelection();
			--aSel.nStartPos;
			--aSel.nEndPos;
			pTableView->SetSelection(aSel);
		}
	}
	if (pTopView)
	{
		pTopView->InsertText( aText, sal_False );
		if (bAddPar)
		{
			ESelection aSel = pTopView->GetSelection();
			--aSel.nStartPos;
			--aSel.nEndPos;
			pTopView->SetSelection(aSel);
		}
	}

	DataChanged();

	if (bAddPar)
		AutoParAdded();
}

void ScInputHandler::ClearText()
{
	if ( eMode == SC_INPUT_NONE )
	{
		DBG_ERROR("ClearText, nicht im Eingabemodus");
		return;
	}

	UpdateActiveView();
	if (!pTableView && !pTopView)
		return; 							// z.B. FillMode

	DataChanging(); 						// darf nicht neu sein

	String aEmpty;
	if (pTableView)
	{
		pTableView->GetEditEngine()->SetText( aEmpty );
		pTableView->SetSelection( ESelection(0,0, 0,0) );
	}
	if (pTopView)
	{
		pTopView->GetEditEngine()->SetText( aEmpty );
		pTopView->SetSelection( ESelection(0,0, 0,0) );
	}

	DataChanged();
}

sal_Bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, sal_Bool bStartEdit /* = sal_False */ )
{
	if (!bOptLoaded)
	{
		bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete();
		bOptLoaded = sal_True;
	}

	KeyCode aCode = rKEvt.GetKeyCode();
	sal_uInt16 nModi  = aCode.GetModifier();
	sal_Bool bShift   = aCode.IsShift();
	sal_Bool bControl = aCode.IsMod1();
	sal_Bool bAlt	  = aCode.IsMod2();
	sal_uInt16 nCode  = aCode.GetCode();
	sal_Unicode nChar = rKEvt.GetCharCode();

	//	Alt-Return is accepted, everything else with ALT, or CTRL-TAB are not:
	if (( bAlt && !bControl && nCode != KEY_RETURN ) ||
			( bControl && aCode.GetCode() == KEY_TAB ))
		return sal_False;

	sal_Bool bInputLine = ( eMode==SC_INPUT_TOP );

	sal_Bool bUsed = sal_False;
	sal_Bool bSkip = sal_False;
	sal_Bool bDoEnter = sal_False;

	switch ( nCode )
	{
		case KEY_RETURN:
			if (bControl && !bShift && !bInputLine)
				bDoEnter = sal_True;
			else if ( nModi == 0 && nTipVisible && pFormulaData && nAutoPos != SCPOS_INVALID )
			{
				PasteFunctionData();
				bUsed = sal_True;
			}
			else if ( nModi == 0 && nTipVisible && aManualTip.Len() )
			{
				PasteManualTip();
				bUsed = sal_True;
			}
			else
			{
				sal_uInt8 nMode = SC_ENTER_NORMAL;
				if ( bShift && bControl )
					nMode = SC_ENTER_MATRIX;
				else if ( bAlt )
					nMode = SC_ENTER_BLOCK;
				EnterHandler( nMode );

				if (pActiveViewSh)
					pActiveViewSh->MoveCursorEnter( bShift && !bControl );

				bUsed = sal_True;
			}
			break;
		case KEY_TAB:
			if (!bControl && !bAlt)
			{
				if ( pFormulaData && nTipVisible && nAutoPos != SCPOS_INVALID )
				{
					//	blaettern

					NextFormulaEntry( bShift );
				}
				else if ( pColumnData && bUseTab && nAutoPos != SCPOS_INVALID )
				{
					//	in den Eintraegen der AutoEingabe blaettern

					NextAutoEntry( bShift );
				}
				else
				{
					EnterHandler();

					//	TabKeyInput gibt auf manchen Rechnern unter W95 Stackueberlaeufe,
					//	darum direkter Aufruf:
					if (pActiveViewSh)
						pActiveViewSh->FindNextUnprot( bShift );
				}
				bUsed = sal_True;
			}
			break;
		case KEY_ESCAPE:
			if ( nTipVisible )
			{
				HideTip();
				bUsed = sal_True;
			}
            else if( nTipVisibleSec )
            {
                HideTipBelow();
                bUsed = sal_True;
            }
			else if (eMode != SC_INPUT_NONE)
			{
				CancelHandler();
				bUsed = sal_True;
			}
			else
				bSkip = sal_True;
			break;
		case KEY_F2:
			if ( !bShift && !bControl && !bAlt && eMode == SC_INPUT_TABLE )
			{
				eMode = SC_INPUT_TYPE;
				bUsed = sal_True;
			}
			break;
	}

	//	Cursortasten nur ausfuehren, wenn schon im Edit-Modus
	//	z.B. wegen Shift-Ctrl-PageDn (ist nicht als Accelerator definiert)

	sal_Bool bCursorKey = EditEngine::DoesKeyMoveCursor(rKEvt);
	sal_Bool bInsKey = ( nCode == KEY_INSERT && !nModi );	// Insert wie Cursortasten behandeln
	if ( !bUsed && !bSkip && ( bDoEnter || EditEngine::DoesKeyChangeText(rKEvt) ||
					( eMode != SC_INPUT_NONE && ( bCursorKey || bInsKey ) ) ) )
	{
		HideTip();
        HideTipBelow();

		if (bSelIsRef)
		{
			RemoveSelection();
			bSelIsRef = sal_False;
		}

		UpdateActiveView();
		sal_Bool bNewView = DataChanging( nChar );

		if (bProtected)								// Zelle geschuetzt?
			bUsed = sal_True;							// Key-Event nicht weiterleiten
		else										// Aenderungen erlaubt
		{
			if (bNewView )							// neu anlegen
			{
				if (pActiveViewSh)
					pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
				UpdateActiveView();
				if (eMode==SC_INPUT_NONE)
					if (pTableView || pTopView)
					{
						String aStrLoP;

						if ( bStartEdit && bCellHasPercentFormat && ((nChar >= '0' && nChar <= '9') || nChar == '-') )
							aStrLoP = '%';

						if (pTableView)
						{
							pTableView->GetEditEngine()->SetText( aStrLoP );
							if ( aStrLoP.Len() )
								pTableView->SetSelection( ESelection(0,0, 0,0) );	// before the '%'

							// don't call SetSelection if the string is empty anyway,
							// to avoid breaking the bInitial handling in ScViewData::EditGrowY
						}
						if (pTopView)
						{
							pTopView->GetEditEngine()->SetText( aStrLoP );
							if ( aStrLoP.Len() )
								pTopView->SetSelection( ESelection(0,0, 0,0) );		// before the '%'
						}
					}
				SyncViews();
			}

			if (pTableView || pTopView)
			{
//				pActiveView->SetEditEngineUpdateMode(sal_True); 		//! gibt Muell !!!!

				if (bDoEnter)
				{
					if (pTableView)
						if( pTableView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) )
							bUsed = sal_True;
					if (pTopView)
						if( pTopView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) )
							bUsed = sal_True;
				}
				else if ( nAutoPar && nChar == ')' && CursorAtClosingPar() )
				{
					SkipClosingPar();
					bUsed = sal_True;
				}
				else
				{
					if (pTableView)
						if ( pTableView->PostKeyEvent( rKEvt ) )
							bUsed = sal_True;
					if (pTopView)
						if ( pTopView->PostKeyEvent( rKEvt ) )
							bUsed = sal_True;
				}

				//	Auto-Eingabe:

				if ( bUsed && bAutoComplete )
				{
					bUseTab = sal_False;
					nAutoPos = SCPOS_INVALID;						// do not search further

					KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
					if ( nChar && nChar != 8 && nChar != 127 &&		// no 'backspace', no 'delete'
						 KEYFUNC_CUT != eFunc)						// and no 'CTRL-X'
					{
						if (bFormulaMode)
							UseFormulaData();
						else
							UseColData();
					}
				}

				//	when the selection is changed manually or an opening parenthesis
				//	is typed, stop overwriting parentheses
				if ( bUsed && nChar == '(' )
					ResetAutoPar();

				if ( KEY_INSERT == nCode )
				{
					SfxViewFrame* pViewFrm = SfxViewFrame::Current();
					if (pViewFrm)
						pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
				}
                if( bUsed && bFormulaMode && ( bCursorKey || bInsKey || nCode == KEY_DELETE || nCode == KEY_BACKSPACE ) )
                {
                    ShowTipCursor();
                }
			}

            // #i114511# don't count cursor keys as modification
            sal_Bool bSetModified = !bCursorKey;
            DataChanged(sal_False, bSetModified);  // also calls UpdateParenthesis()
			InvalidateAttribs();		//! in DataChanged ?
		}
	}

	if (pTopView && eMode != SC_INPUT_NONE)
		SyncViews();

	return bUsed;
}

sal_Bool ScInputHandler::InputCommand( const CommandEvent& rCEvt, sal_Bool bForce )
{
	sal_Bool bUsed = sal_False;

	if ( rCEvt.GetCommand() == COMMAND_CURSORPOS )
	{
		//	#90346# for COMMAND_CURSORPOS, do as little as possible, because
		//	with remote VCL, even a ShowCursor will generate another event.
		if ( eMode != SC_INPUT_NONE )
		{
			UpdateActiveView();
			if (pTableView || pTopView)
			{
				if (pTableView)
					pTableView->Command( rCEvt );
				else if (pTopView)						// call only once
					pTopView->Command( rCEvt );
				bUsed = sal_True;
			}
		}
	}
	else
	{
		if ( bForce || eMode != SC_INPUT_NONE )
		{
			if (!bOptLoaded)
			{
				bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete();
				bOptLoaded = sal_True;
			}

			HideTip();
            HideTipBelow();

			if ( bSelIsRef )
			{
				RemoveSelection();
				bSelIsRef = sal_False;
			}

			UpdateActiveView();
			sal_Bool bNewView = DataChanging( 0, sal_True );

			if (bProtected)								// cell protected
				bUsed = sal_True;							// event is used
			else										// changes allowed
			{
				if (bNewView)							// create new edit view
				{
					if (pActiveViewSh)
						pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
					UpdateActiveView();
					if (eMode==SC_INPUT_NONE)
						if (pTableView || pTopView)
						{
							String aStrLoP;
							if (pTableView)
							{
								pTableView->GetEditEngine()->SetText( aStrLoP );
								pTableView->SetSelection( ESelection(0,0, 0,0) );
							}
							if (pTopView)
							{
								pTopView->GetEditEngine()->SetText( aStrLoP );
								pTopView->SetSelection( ESelection(0,0, 0,0) );
							}
						}
					SyncViews();
				}

				if (pTableView || pTopView)
				{
					if (pTableView)
						pTableView->Command( rCEvt );
					if (pTopView)
						pTopView->Command( rCEvt );

					bUsed = sal_True;

					if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT )
					{
						//	AutoInput after ext text input

						nAutoPos = SCPOS_INVALID;
						if (bFormulaMode)
							UseFormulaData();
						else
							UseColData();
					}
				}

				DataChanged();				//	calls UpdateParenthesis()
				InvalidateAttribs();		//! in DataChanged ?
			}
		}

		if (pTopView && eMode != SC_INPUT_NONE)
			SyncViews();
	}

	return bUsed;
}

void ScInputHandler::NotifyChange( const ScInputHdlState* pState,
								   sal_Bool bForce, ScTabViewShell* pSourceSh,
                                   sal_Bool bStopEditing)
{
	//	#62806# Wenn der Aufruf aus einem Makro-Aufruf im EnterHandler kommt,
	//	gleich abbrechen und nicht den Status durcheinander bringen
	if (bInEnterHandler)
		return;

	sal_Bool bRepeat = (pState == pLastState);
	if (!bRepeat && pState && pLastState)
        bRepeat = sal::static_int_cast<sal_Bool>(*pState == *pLastState);
	if (bRepeat && !bForce)
		return;

	bInOwnChange = sal_True;				// disable ModifyHdl (reset below)

	if ( pState && !pLastState )		// wieder enablen
		bForce = sal_True;

	sal_Bool bHadObject = pLastState && pLastState->GetEditData();

	//! Before EditEngine gets eventually created (so it gets the right pools)
	if ( pSourceSh )
		pActiveViewSh = pSourceSh;
	else
		pActiveViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());

	ImplCreateEditEngine();

	if ( pState != pLastState )
	{
		delete pLastState;
		pLastState = pState ? new ScInputHdlState( *pState ) : NULL;
	}

	if ( pState && pActiveViewSh )
	{
		ScModule* pScMod = SC_MOD();

		if ( pState )
		{
			sal_Bool bIgnore = sal_False;

			//	hier auch fremde Referenzeingabe beruecksichtigen (z.B. Funktions-AP),
			//	FormEditData falls gerade von der Hilfe auf Calc umgeschaltet wird:

			if ( !bFormulaMode && !pScMod->IsFormulaMode() && !pScMod->GetFormEditData() )
			{
				if ( bModified )
				{
					if (pState->GetPos() != aCursorPos)
					{
						if (!bProtected)
							EnterHandler();
					}
					else
						bIgnore = sal_True;
				}

				if ( !bIgnore /* || bRepeat */ )
				{
					const ScAddress& 		rSPos	= pState->GetStartPos();
					const ScAddress& 		rEPos	= pState->GetEndPos();
					const EditTextObject*	pData	= pState->GetEditData();
					String					aString = pState->GetString();
					sal_Bool					bTxtMod = sal_False;
					ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
					ScDocument* pDoc = pDocSh->GetDocument();

					aCursorPos	= pState->GetPos();

					if ( pData /* || bRepeat */ )
						bTxtMod = sal_True;
					else if ( bHadObject )
						bTxtMod = sal_True;
					else if ( bTextValid )
						bTxtMod = ( aString != aCurrentText );
					else
						bTxtMod = ( aString != GetEditText(pEngine) );

					if ( bTxtMod || bForce )
					{
						if (pData)
						{
							pEngine->SetText( *pData );
							aString = GetEditText(pEngine);
							lcl_RemoveTabs(aString);
							bTextValid = sal_False;
							aCurrentText.Erase();
						}
						else
						{
							aCurrentText = aString;
							bTextValid = sal_True;				//! erst nur als String merken
						}

						if ( pInputWin )
							pInputWin->SetTextString(aString);
					}

					if ( pInputWin )						// Bereichsanzeige
					{
						String aPosStr;
						const ScAddress::Details aAddrDetails( pDoc, aCursorPos );

						//	Ist der Bereich ein Name?
						//!	per Timer suchen ???

						if ( pActiveViewSh )
							pActiveViewSh->GetViewData()->GetDocument()->
								GetRangeAtBlock( ScRange( rSPos, rEPos ), &aPosStr );

						if ( !aPosStr.Len() )			// kein Name -> formatieren
						{
							sal_uInt16 nFlags = 0;
							if( aAddrDetails.eConv == formula::FormulaGrammar::CONV_XL_R1C1 )
								nFlags |= SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE;
							if ( rSPos != rEPos )
							{
								ScRange r(rSPos, rEPos);
								nFlags |= (nFlags << 4);
								r.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
							}
							else
								aCursorPos.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
						}
						// Disable the accessible VALUE_CHANGE event
						sal_Bool bIsSuppressed = pInputWin->IsAccessibilityEventsSuppressed(sal_False);
						pInputWin->SetAccessibilityEventsSuppressed(sal_True);
						pInputWin->SetPosString(aPosStr);
						pInputWin->SetAccessibilityEventsSuppressed(bIsSuppressed);
						pInputWin->SetSumAssignMode();
					}

                    if (bStopEditing)
					    SFX_APP()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );

					//	As long as the content is not edited, turn off online spelling.
					//	Online spelling is turned back on in StartTable, after setting
					//	the right language from cell attributes.

					sal_uLong nCntrl = pEngine->GetControlWord();
					if ( nCntrl & EE_CNTRL_ONLINESPELLING )
						pEngine->SetControlWord( nCntrl & ~EE_CNTRL_ONLINESPELLING );

					bModified = sal_False;
					bSelIsRef = sal_False;
					bProtected = sal_False;
					bCommandErrorShown = sal_False;
				}
			}
		}

//		bProtected = sal_False;

		if ( pInputWin)
		{
			if(!pScMod->IsFormulaMode()&& !pScMod->IsRefDialogOpen())	//BugID 54702
			{															//Wenn RefDialog offen, dann nicht enablen
				if ( !pInputWin->IsEnabled())
				{
					pInputWin->Enable();
					if(pDelayTimer )
					{
						DELETEZ( pDelayTimer );
					}
				}
			}
			else if(pScMod->IsRefDialogOpen())
			{									// Da jedes Dokument eigenes InputWin hat, sollte
				if ( !pDelayTimer )				// nochmals Timer gestartet werden, da sonst Ein-
				{								// gabezeile evt. noch aktiv ist.
					pDelayTimer = new Timer;
					pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung
					pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) );
					pDelayTimer->Start();
				}
			}
		}
	}
	else // !pState || !pActiveViewSh
	{
		if ( !pDelayTimer )
		{
			pDelayTimer = new Timer;
			pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung
			pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) );
			pDelayTimer->Start();
		}
	}

	HideTip();
    HideTipBelow();
	bInOwnChange = sal_False;
}

void ScInputHandler::UpdateCellAdjust( SvxCellHorJustify eJust )
{
    eAttrAdjust = eJust;
    UpdateAdjust( 0 );
}

void ScInputHandler::ResetDelayTimer()
{
	if(pDelayTimer!=NULL)
	{
		DELETEZ( pDelayTimer );

		if ( pInputWin)
		{
			pInputWin->Enable();
		}
	}
}

IMPL_LINK( ScInputHandler, DelayTimer, Timer*, pTimer )
{
	if ( pTimer == pDelayTimer )
	{
		DELETEZ( pDelayTimer );

		if ( NULL == pLastState || SC_MOD()->IsFormulaMode() || SC_MOD()->IsRefDialogOpen())
		{
			//!	new method at ScModule to query if function autopilot is open

			SfxViewFrame* pViewFrm = SfxViewFrame::Current();
			if ( pViewFrm && pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
			{
				if ( pInputWin)
				{
					pInputWin->EnableButtons( sal_False );
					pInputWin->Disable();
				}
			}
			else if ( !bFormulaMode )	// #39210# Formel auch z.B. bei Hilfe behalten
			{
				bInOwnChange = sal_True;	// disable ModifyHdl (reset below)

				pActiveViewSh = NULL;
				pEngine->SetText( EMPTY_STRING );
				if ( pInputWin )
				{
					pInputWin->SetPosString( EMPTY_STRING );
					pInputWin->SetTextString( EMPTY_STRING );
					pInputWin->Disable();
				}

				bInOwnChange = sal_False;
			}
		}
	}
	return 0;
}

void ScInputHandler::InputSelection( EditView* pView )
{
	SyncViews( pView );
    ShowTipCursor();
	UpdateParenthesis();	//	Selektion geaendert -> Klammer-Hervorhebung neu

	//	when the selection is changed manually, stop overwriting parentheses
	ResetAutoPar();
}

void ScInputHandler::InputChanged( EditView* pView, sal_Bool bFromNotify )
{
	ESelection aSelection = pView->GetSelection();

	UpdateActiveView();

	// #i20282# DataChanged needs to know if this is from the input line's modify handler
	sal_Bool bFromTopNotify = ( bFromNotify && pView == pTopView );

	sal_Bool bNewView = DataChanging();						//!	kann das hier ueberhaupt sein?
	aCurrentText = pView->GetEditEngine()->GetText();	// auch den String merken
	pEngine->SetText( aCurrentText );
	DataChanged( bFromTopNotify );
	bTextValid = sal_True;		// wird in DataChanged auf sal_False gesetzt

	if ( pActiveViewSh )
	{
		ScViewData* pViewData = pActiveViewSh->GetViewData();
		if ( bNewView )
			pViewData->GetDocShell()->PostEditView( pEngine, aCursorPos );

		pViewData->EditGrowY();
		pViewData->EditGrowX();
	}

	SyncViews( pView );
}

const String& ScInputHandler::GetEditString()
{
	if (pEngine)
	{
		aCurrentText = pEngine->GetText();		// immer neu aus Engine
		bTextValid = sal_True;
	}

	return aCurrentText;
}

Size ScInputHandler::GetTextSize()
{
	Size aSize;
	if ( pEngine )
		aSize = Size( pEngine->CalcTextWidth(), pEngine->GetTextHeight() );

	return aSize;
}

sal_Bool ScInputHandler::GetTextAndFields( ScEditEngineDefaulter& rDestEngine )
{
	sal_Bool bRet = sal_False;
	if (pEngine)
	{
		//	Feldbefehle enthalten?

		sal_uInt32 nParCnt = pEngine->GetParagraphCount();
		SfxItemSet aSet = pEngine->GetAttribs( ESelection(0,0,nParCnt,0) );
		SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, sal_False );
		if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
		{
			//	Inhalt kopieren

			EditTextObject* pObj = pEngine->CreateTextObject();
			rDestEngine.SetText(*pObj);
			delete pObj;

			//	Attribute loeschen

			for (sal_uInt32 i=0; i<nParCnt; i++)
				rDestEngine.QuickRemoveCharAttribs( i );

			//	Absaetze zusammenfassen

			while ( nParCnt > 1 )
			{
				xub_StrLen nLen = rDestEngine.GetTextLen( 0 );
				ESelection aSel( 0,nLen, 1,0 );
				rDestEngine.QuickInsertText( ' ', aSel );		// Umbruch durch Space ersetzen
				--nParCnt;
			}

			bRet = sal_True;
		}
	}
	return bRet;
}


//------------------------------------------------------------------------
// Methoden fuer FunktionsAutopiloten:
// InputGetSelection, InputSetSelection, InputReplaceSelection, InputGetFormulaStr
//------------------------------------------------------------------------

void ScInputHandler::InputGetSelection( xub_StrLen& rStart, xub_StrLen& rEnd )
{
	rStart = nFormSelStart;
	rEnd = nFormSelEnd;
}

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

EditView* ScInputHandler::GetFuncEditView()
{
	UpdateActiveView();		// wegen pTableView

	EditView* pView = NULL;
	if ( pInputWin )
	{
		pInputWin->MakeDialogEditView();
		pView = pInputWin->GetEditView();
	}
	else
	{
		if ( eMode != SC_INPUT_TABLE )
		{
			bCreatingFuncView = sal_True;		// RangeFinder nicht anzeigen
			SetMode( SC_INPUT_TABLE );
			bCreatingFuncView = sal_False;
			if ( pTableView )
				pTableView->GetEditEngine()->SetText( EMPTY_STRING );
		}
		pView = pTableView;
	}

	return pView;
}

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

void ScInputHandler::InputSetSelection( xub_StrLen nStart, xub_StrLen nEnd )
{
	if ( nStart <= nEnd )
	{
		nFormSelStart = nStart;
		nFormSelEnd = nEnd;
	}
	else
	{
		nFormSelEnd = nStart;
		nFormSelStart = nEnd;
	}

	EditView* pView = GetFuncEditView();
	if (pView)
		pView->SetSelection( ESelection(0,nStart, 0,nEnd) );

	bModified = sal_True;
}

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

void ScInputHandler::InputReplaceSelection( const String& rStr )
{
	if (!pRefViewSh)
		pRefViewSh = pActiveViewSh;

	DBG_ASSERT(nFormSelEnd>=nFormSelStart,"Selektion kaputt...");

	xub_StrLen nOldLen = nFormSelEnd-nFormSelStart;
	xub_StrLen nNewLen = rStr.Len();
	if (nOldLen)
		aFormText.Erase( nFormSelStart, nOldLen );
	if (nNewLen)
		aFormText.Insert( rStr, nFormSelStart );
	nFormSelEnd = nFormSelStart + nNewLen;

	EditView* pView = GetFuncEditView();
	if (pView)
	{
		pView->SetEditEngineUpdateMode( sal_False );
//		pView->InsertText( rStr, sal_True );
		pView->GetEditEngine()->SetText( aFormText );
		pView->SetSelection( ESelection(0,nFormSelStart, 0,nFormSelEnd) );
		pView->SetEditEngineUpdateMode( sal_True );
	}
	bModified = sal_True;
}

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

String ScInputHandler::InputGetFormulaStr()
{
	return aFormText;	//!	eigene Membervariable?
}

//========================================================================
//	ScInputHdlState
//========================================================================

ScInputHdlState::ScInputHdlState( const ScAddress& rCurPos,
								  const ScAddress& rStartPos,
								  const ScAddress& rEndPos,
								  const String& rString,
								  const EditTextObject* pData )
	:   aCursorPos	( rCurPos ),
		aStartPos	( rStartPos ),
		aEndPos		( rEndPos ),
		aString		( rString ),
		pEditData	( pData ? pData->Clone() : NULL )
{
}

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

ScInputHdlState::ScInputHdlState( const ScInputHdlState& rCpy )
	:	pEditData	( NULL )
{
	*this = rCpy;
}

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

ScInputHdlState::~ScInputHdlState()
{
	delete pEditData;
}

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

int ScInputHdlState::operator==( const ScInputHdlState& r ) const
{
	return (    (aStartPos 	== r.aStartPos)
			 &&	(aEndPos   	== r.aEndPos)
			 &&	(aCursorPos == r.aCursorPos)
			 && (aString   	== r.aString)
			 && ScGlobal::EETextObjEqual( pEditData, r.pEditData ) );
}

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

ScInputHdlState& ScInputHdlState::operator=( const ScInputHdlState& r )
{
	delete pEditData;

	aCursorPos	= r.aCursorPos;
	aStartPos	= r.aStartPos;
	aEndPos		= r.aEndPos;
	aString		= r.aString;
	pEditData	= r.pEditData ? r.pEditData->Clone() : NULL;

	return *this;
}
