xref: /aoo41x/main/sc/source/ui/app/inputhdl.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 //------------------------------------------------------------------
32 
33 #include "scitems.hxx"
34 #include <editeng/eeitem.hxx>
35 
36 #include <sfx2/app.hxx>
37 #include <editeng/acorrcfg.hxx>
38 #include <svx/algitem.hxx>
39 #include <editeng/adjitem.hxx>
40 #include <editeng/brshitem.hxx>
41 #include <svtools/colorcfg.hxx>
42 #include <editeng/colritem.hxx>
43 #include <editeng/editobj.hxx>
44 #include <editeng/editstat.hxx>
45 #include <editeng/editview.hxx>
46 #include <editeng/escpitem.hxx>
47 #include <editeng/forbiddencharacterstable.hxx>
48 #include <editeng/langitem.hxx>
49 #include <editeng/svxacorr.hxx>
50 #include <editeng/unolingu.hxx>
51 #include <editeng/wghtitem.hxx>
52 #include <sfx2/bindings.hxx>
53 #include <sfx2/viewfrm.hxx>
54 #include <sfx2/dispatch.hxx>
55 #include <sfx2/docfile.hxx>
56 #include <sfx2/printer.hxx>
57 #include <svl/zforlist.hxx>
58 #include <vcl/sound.hxx>
59 #include <unotools/localedatawrapper.hxx>
60 #include <vcl/help.hxx>
61 #include <vcl/cursor.hxx>
62 #include <tools/urlobj.hxx>
63 #include <formula/formulahelper.hxx>
64 
65 #include "inputwin.hxx"
66 #include "tabvwsh.hxx"
67 #include "docsh.hxx"
68 #include "scmod.hxx"
69 #include "uiitems.hxx"
70 #include "global.hxx"
71 #include "sc.hrc"
72 #include "globstr.hrc"
73 #include "patattr.hxx"
74 #include "viewdata.hxx"
75 #include "document.hxx"
76 #include "docpool.hxx"
77 #include "editutil.hxx"
78 #include "collect.hxx"
79 #include "appoptio.hxx"
80 #include "docoptio.hxx"
81 #include "validat.hxx"
82 #include "userlist.hxx"
83 #include "rfindlst.hxx"
84 #include "inputopt.hxx"
85 #include "cell.hxx"				// fuer Formel-Preview
86 #include "compiler.hxx"			// fuer Formel-Preview
87 #include "editable.hxx"
88 #include "funcdesc.hxx"
89 
90 #define _INPUTHDL_CXX
91 #include "inputhdl.hxx"
92 
93 //	max. Ranges im RangeFinder
94 #define RANGEFIND_MAX	32
95 
96 using namespace formula;
97 
98 // STATIC DATA -----------------------------------------------------------
99 
100 sal_Bool ScInputHandler::bOptLoaded = sal_False;			// App-Optionen ausgewertet
101 sal_Bool ScInputHandler::bAutoComplete = sal_False;			// wird in KeyInput gesetzt
102 
103 //	delimiters (in addition to ScEditUtil) needed for range finder:
104 //	only characters that are allowed in formulas next to references
105 //	and the quotation mark (so string constants can be skipped)
106 
107 static const sal_Char __FAR_DATA pMinDelimiters[] = " !\"";
108 
109 extern sal_uInt16 nEditAdjust;		//! Member an ViewData
110 
111 //==================================================================
112 
113 static sal_Unicode lcl_getSheetSeparator(ScDocument* pDoc)
114 {
115     ScCompiler aComp(pDoc, ScAddress());
116     aComp.SetGrammar(pDoc->GetGrammar());
117     return aComp.GetNativeAddressSymbol(ScCompiler::Convention::SHEET_SEPARATOR);
118 }
119 
120 void ScInputHandler::InitRangeFinder( const String& rFormula )
121 {
122 	DeleteRangeFinder();
123     ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
124     ScDocument* pDoc = pDocSh->GetDocument();
125     const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDoc);
126 
127 	if ( !pActiveViewSh || !SC_MOD()->GetInputOptions().GetRangeFinder() )
128 		return;
129 
130 //	String aDelimiters = pEngine->GetWordDelimiters();
131 	String aDelimiters = ScEditUtil::ModifyDelimiters(
132 							String::CreateFromAscii( pMinDelimiters ) );
133 
134 	xub_StrLen nColon = aDelimiters.Search(':');
135 	if ( nColon != STRING_NOTFOUND )
136 		aDelimiters.Erase( nColon, 1 );				// Delimiter ohne Doppelpunkt
137 	xub_StrLen nDot = aDelimiters.Search(cSheetSep);
138 	if ( nDot != STRING_NOTFOUND )
139 		aDelimiters.Erase( nDot, 1 );				// Delimiter ohne Punkt
140 
141 	const sal_Unicode* pChar = rFormula.GetBuffer();
142 	xub_StrLen nLen = rFormula.Len();
143 	xub_StrLen nPos = 0;
144 	xub_StrLen nStart = 0;
145 	sal_uInt16 nCount = 0;
146 	ScRange aRange;
147 	while ( nPos < nLen && nCount < RANGEFIND_MAX )
148 	{
149 		//	Trenner ueberlesen
150 		while ( nPos<nLen && ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) )
151 		{
152 			if ( pChar[nPos] == '"' )						// String
153 			{
154 				++nPos;
155 				while (nPos<nLen && pChar[nPos] != '"')		// bis zum Ende ueberlesen
156 					++nPos;
157 			}
158 			++nPos;						// Trennzeichen oder schliessender Quote
159 		}
160 
161 		//	Text zwischen Trennern
162 		nStart = nPos;
163 handle_r1c1:
164 		while ( nPos<nLen && !ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) )
165 			++nPos;
166 
167 		// for R1C1 '-' in R[-]... or C[-]... are not delimiters
168 		// Nothing heroic here to ensure that there are '[]' around a negative
169 		// integer.  we need to clean up this code.
170 		if( nPos < nLen && nPos > 0 &&
171 			'-' == pChar[nPos] && '[' == pChar[nPos-1] &&
172 			NULL != pDoc &&
173 			formula::FormulaGrammar::CONV_XL_R1C1 == pDoc->GetAddressConvention() )
174 		{
175 			nPos++;
176 			goto handle_r1c1;
177 		}
178 
179 		if ( nPos > nStart )
180 		{
181 			String aTest = rFormula.Copy( nStart, nPos-nStart );
182 			const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
183 			sal_uInt16 nFlags = aRange.ParseAny( aTest, pDoc, aAddrDetails );
184 			if ( nFlags & SCA_VALID )
185 			{
186 				//	Tabelle setzen, wenn nicht angegeben
187 				if ( (nFlags & SCA_TAB_3D) == 0 )
188 					aRange.aStart.SetTab( pActiveViewSh->GetViewData()->GetTabNo() );
189 				if ( (nFlags & SCA_TAB2_3D) == 0 )
190 					aRange.aEnd.SetTab( aRange.aStart.Tab() );
191 
192                 if ( ( nFlags & ( SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2 ) ) == 0 )
193                 {
194                     // #i73766# if a single ref was parsed, set the same "abs" flags for ref2,
195                     // so Format doesn't output a double ref because of different flags.
196                     sal_uInt16 nAbsFlags = nFlags & ( SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE );
197                     nFlags |= nAbsFlags << 4;
198                 }
199 
200 				if (!nCount)
201 				{
202 					pEngine->SetUpdateMode( sal_False );
203 					pRangeFindList = new ScRangeFindList( pDocSh->GetTitle() );
204 				}
205 
206 				ScRangeFindData* pNew = new ScRangeFindData( aRange, nFlags, nStart, nPos );
207 				pRangeFindList->Insert( pNew );
208 
209 				ESelection aSel( 0, nStart, 0, nPos );
210 				SfxItemSet aSet( pEngine->GetEmptyItemSet() );
211 				aSet.Put( SvxColorItem( Color( ScRangeFindList::GetColorName( nCount ) ),
212 							EE_CHAR_COLOR ) );
213 				pEngine->QuickSetAttribs( aSet, aSel );
214 				++nCount;
215 			}
216 		}
217 
218 		//	letzten Trenner nicht ueberlesen, koennte ja ein Quote sein (?)
219 	}
220 
221 	if (nCount)
222 	{
223 		pEngine->SetUpdateMode( sal_True );
224 
225 		pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) );
226 	}
227 }
228 
229 void lcl_Replace( EditView* pView, const String& rNewStr, const ESelection& rOldSel )
230 {
231 	if ( pView )
232 	{
233 		ESelection aOldSel = pView->GetSelection();
234 		if (aOldSel.HasRange())
235 			pView->SetSelection( ESelection( aOldSel.nEndPara, aOldSel.nEndPos,
236 											 aOldSel.nEndPara, aOldSel.nEndPos ) );
237 
238 		EditEngine* pEngine = pView->GetEditEngine();
239 		pEngine->QuickInsertText( rNewStr, rOldSel );
240 
241 		//	Dummy-InsertText fuer Update und Paint
242 		//	dafuer muss oben die Selektion aufgehoben werden (vor QuickInsertText)
243 		pView->InsertText( EMPTY_STRING, sal_False );
244 
245 		xub_StrLen nLen = pEngine->GetTextLen(0);
246 		ESelection aSel( 0, nLen, 0, nLen );
247 		pView->SetSelection( aSel );				// Cursor ans Ende
248 	}
249 }
250 
251 void ScInputHandler::UpdateRange( sal_uInt16 nIndex, const ScRange& rNew )
252 {
253 	ScTabViewShell* pDocView = pRefViewSh ? pRefViewSh : pActiveViewSh;
254 	if ( pDocView && pRangeFindList && nIndex < pRangeFindList->Count() )
255 	{
256 		ScRangeFindData* pData = pRangeFindList->GetObject( nIndex );
257 		xub_StrLen nOldStart = pData->nSelStart;
258 		xub_StrLen nOldEnd = pData->nSelEnd;
259 
260 		ScRange aJustified = rNew;
261 		aJustified.Justify();			// Ref in der Formel immer richtigherum anzeigen
262 		String aNewStr;
263 		ScDocument* pDoc = pDocView->GetViewData()->GetDocument();
264 		const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
265 		aJustified.Format( aNewStr, pData->nFlags, pDoc, aAddrDetails );
266 		ESelection aOldSel( 0, nOldStart, 0, nOldEnd );
267 
268 		DataChanging();
269 
270 		lcl_Replace( pTopView, aNewStr, aOldSel );
271 		lcl_Replace( pTableView, aNewStr, aOldSel );
272 
273 		bInRangeUpdate = sal_True;
274 		DataChanged();
275 		bInRangeUpdate = sal_False;
276 
277 		long nDiff = aNewStr.Len() - (long)(nOldEnd-nOldStart);
278 
279 		pData->aRef = rNew;
280 		pData->nSelEnd = (xub_StrLen)(pData->nSelEnd + nDiff);
281 
282 		sal_uInt16 nCount = (sal_uInt16) pRangeFindList->Count();
283 		for (sal_uInt16 i=nIndex+1; i<nCount; i++)
284 		{
285 			ScRangeFindData* pNext = pRangeFindList->GetObject( i );
286 			pNext->nSelStart = (xub_StrLen)(pNext->nSelStart + nDiff);
287 			pNext->nSelEnd   = (xub_StrLen)(pNext->nSelEnd   + nDiff);
288 		}
289 	}
290 	else
291 	{
292 		DBG_ERROR("UpdateRange: da fehlt was");
293 	}
294 }
295 
296 void ScInputHandler::DeleteRangeFinder()
297 {
298 	ScTabViewShell* pPaintView = pRefViewSh ? pRefViewSh : pActiveViewSh;
299 	if ( pRangeFindList && pPaintView )
300 	{
301 		ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
302 		pRangeFindList->SetHidden(sal_True);
303 		pDocSh->Broadcast( SfxSimpleHint( SC_HINT_SHOWRANGEFINDER ) );	// wegnehmen
304 		DELETEZ(pRangeFindList);
305 	}
306 }
307 
308 //==================================================================
309 
310 inline String GetEditText(EditEngine* pEng)
311 {
312 	return ScEditUtil::GetSpaceDelimitedString(*pEng);
313 }
314 
315 void lcl_RemoveTabs(String& rStr)
316 {
317 	xub_StrLen nPos;
318 	while ( (nPos=rStr.Search('\t')) != STRING_NOTFOUND )
319 		rStr.SetChar( nPos, ' ' );
320 }
321 
322 void lcl_RemoveLineEnd(String& rStr)
323 {
324 	rStr.ConvertLineEnd(LINEEND_LF);
325 	xub_StrLen nPos;
326 	while ( (nPos=rStr.Search('\n')) != STRING_NOTFOUND )
327 		rStr.SetChar( nPos, ' ' );
328 }
329 
330 xub_StrLen lcl_MatchParenthesis( const String& rStr, xub_StrLen nPos )
331 {
332     int nDir;
333     sal_Unicode c1, c2 = 0;
334     c1 = rStr.GetChar( nPos );
335     switch ( c1 )
336     {
337     case '(' :
338         c2 = ')';
339         nDir = 1;
340         break;
341     case ')' :
342         c2 = '(';
343         nDir = -1;
344         break;
345     case '<' :
346         c2 = '>';
347         nDir = 1;
348         break;
349     case '>' :
350         c2 = '<';
351         nDir = -1;
352         break;
353     case '{' :
354         c2 = '}';
355         nDir = 1;
356         break;
357     case '}' :
358         c2 = '{';
359         nDir = -1;
360         break;
361     case '[' :
362         c2 = ']';
363         nDir = 1;
364         break;
365     case ']' :
366         c2 = '[';
367         nDir = -1;
368         break;
369     default:
370         nDir = 0;
371     }
372     if ( !nDir )
373         return STRING_NOTFOUND;
374     xub_StrLen nLen = rStr.Len();
375     const sal_Unicode* p0 = rStr.GetBuffer();
376     register const sal_Unicode* p;
377     const sal_Unicode* p1;
378     sal_uInt16 nQuotes = 0;
379     if ( nPos < nLen / 2 )
380     {
381         p = p0;
382         p1 = p0 + nPos;
383     }
384     else
385     {
386         p = p0 + nPos;
387         p1 = p0 + nLen;
388     }
389     while ( p < p1 )
390     {
391         if ( *p++ == '\"' )
392             nQuotes++;
393     }
394     // Odd number of quotes that we find ourselves in a string
395     sal_Bool bLookInString = ((nQuotes % 2) != 0);
396     sal_Bool bInString = bLookInString;
397     p = p0 + nPos;
398     p1 = (nDir < 0 ? p0 : p0 + nLen) ;
399     sal_uInt16 nLevel = 1;
400     while ( p != p1 && nLevel )
401     {
402         p += nDir;
403         if ( *p == '\"' )
404         {
405             bInString = !bInString;
406             if ( bLookInString && !bInString )
407                 p = p1;		//That's it then
408         }
409         else if ( bInString == bLookInString )
410         {
411             if ( *p == c1 )
412                 nLevel++;
413             else if ( *p == c2 )
414                 nLevel--;
415         }
416     }
417     if ( nLevel )
418         return STRING_NOTFOUND;
419     return (xub_StrLen) (p - p0);
420 }
421 
422 //==================================================================
423 
424 ScInputHandler::ScInputHandler()
425     :   pInputWin( NULL ),
426 		pEngine( NULL ),
427 		pTableView( NULL ),
428 		pTopView( NULL ),
429 		pColumnData( NULL ),
430 		pFormulaData( NULL ),
431         pFormulaDataPara( NULL ),
432         pTipVisibleParent( NULL ),
433 		nTipVisible( 0 ),
434         pTipVisibleSecParent( NULL ),
435         nTipVisibleSec( 0 ),
436 		nAutoPos( SCPOS_INVALID ),
437 		bUseTab( sal_False ),
438 		bTextValid( sal_True ),
439 		nFormSelStart( 0 ),
440 		nFormSelEnd( 0 ),
441 		nAutoPar( 0 ),
442         eMode( SC_INPUT_NONE ),
443 		bModified( sal_False ),
444 		bSelIsRef( sal_False ),
445 		bFormulaMode( sal_False ),
446 		bInRangeUpdate( sal_False ),
447 		bParenthesisShown( sal_False ),
448 		bCreatingFuncView( sal_False ),
449 		bInEnterHandler( sal_False ),
450 		bCommandErrorShown( sal_False ),
451 		bInOwnChange( sal_False ),
452 		bProtected( sal_False ),
453 		bCellHasPercentFormat( sal_False ),
454 		nValidation( 0 ),
455         eAttrAdjust( SVX_HOR_JUSTIFY_STANDARD ),
456 		aScaleX( 1,1 ),
457 		aScaleY( 1,1 ),
458 		pRefViewSh( NULL ),
459 		pLastPattern( NULL ),
460 		pEditDefaults( NULL ),
461 		bLastIsSymbol( sal_False ),
462 		pLastState( NULL ),
463 		pDelayTimer( NULL ),
464 		pRangeFindList( NULL )
465 {
466 	//	The InputHandler is constructed with the view, so SfxViewShell::Current
467 	//	doesn't have the right view yet. pActiveViewSh is updated in NotifyChange.
468 	pActiveViewSh = NULL;
469 
470 	//	Bindings (nur noch fuer Invalidate benutzt) werden bei Bedarf aktuell geholt
471 }
472 
473 __EXPORT ScInputHandler::~ScInputHandler()
474 {
475 	//	Wenn dies der Applikations-InputHandler ist, wird der dtor erst nach SfxApplication::Main
476 	//	gerufen, darf sich also auf keine Sfx-Funktionen mehr verlassen
477 
478 	if ( !SFX_APP()->IsDowning() )			// inplace
479 		EnterHandler();						// Eingabe noch abschliessen
480 
481 	if (SC_MOD()->GetRefInputHdl()==this)
482 		SC_MOD()->SetRefInputHdl(NULL);
483 
484 	if ( pInputWin && pInputWin->GetInputHandler() == this )
485 		pInputWin->SetInputHandler( NULL );
486 
487 	delete pRangeFindList;
488 	delete pEditDefaults;
489 	delete pEngine;
490 	delete pLastState;
491 	delete pDelayTimer;
492 	delete pColumnData;
493 	delete pFormulaData;
494     delete pFormulaDataPara;
495 }
496 
497 void ScInputHandler::SetRefScale( const Fraction& rX, const Fraction& rY )
498 {
499 	if ( rX != aScaleX || rY != aScaleY )
500 	{
501 		aScaleX = rX;
502 		aScaleY = rY;
503 		if (pEngine)
504 		{
505 			MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY );
506 			pEngine->SetRefMapMode( aMode );
507 		}
508 	}
509 }
510 
511 void ScInputHandler::UpdateRefDevice()
512 {
513 	if (!pEngine)
514 		return;
515 
516 	sal_Bool bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg();
517     bool bInPlace = pActiveViewSh && pActiveViewSh->GetViewFrame()->GetFrame().IsInPlace();
518     sal_uInt32 nCtrl = pEngine->GetControlWord();
519     if ( bTextWysiwyg || bInPlace )
520         nCtrl |= EE_CNTRL_FORMAT100;    // EditEngine default: always format for 100%
521     else
522         nCtrl &= ~EE_CNTRL_FORMAT100;   // when formatting for screen, use the actual MapMode
523     pEngine->SetControlWord( nCtrl );
524 	if ( bTextWysiwyg && pActiveViewSh )
525 		pEngine->SetRefDevice( pActiveViewSh->GetViewData()->GetDocument()->GetPrinter() );
526 	else
527 		pEngine->SetRefDevice( NULL );
528 
529 	MapMode aMode( MAP_100TH_MM, Point(), aScaleX, aScaleY );
530 	pEngine->SetRefMapMode( aMode );
531 
532 	//	SetRefDevice(NULL) uses VirtualDevice, SetRefMapMode forces creation of a local VDev,
533 	//	so the DigitLanguage can be safely modified (might use an own VDev instead of NULL).
534 	if ( !( bTextWysiwyg && pActiveViewSh ) )
535 	{
536 		pEngine->GetRefDevice()->SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
537 	}
538 }
539 
540 void ScInputHandler::ImplCreateEditEngine()
541 {
542 	if ( !pEngine )
543 	{
544 		if ( pActiveViewSh )
545 		{
546 			const ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
547 			pEngine = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
548 		}
549 		else
550 			pEngine = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, sal_True );
551 		pEngine->SetWordDelimiters( ScEditUtil::ModifyDelimiters( pEngine->GetWordDelimiters() ) );
552 		UpdateRefDevice();		// also sets MapMode
553 		pEngine->SetPaperSize( Size( 1000000, 1000000 ) );
554 		pEditDefaults = new SfxItemSet( pEngine->GetEmptyItemSet() );
555 
556 		pEngine->SetControlWord( pEngine->GetControlWord() | EE_CNTRL_AUTOCORRECT );
557         pEngine->SetModifyHdl( LINK( this, ScInputHandler, ModifyHdl ) );
558 	}
559 }
560 
561 void ScInputHandler::UpdateAutoCorrFlag()
562 {
563 	sal_uLong nCntrl = pEngine->GetControlWord();
564 	sal_uLong nOld = nCntrl;
565 
566 	//	don't use pLastPattern here (may be invalid because of AutoStyle)
567 
568 	sal_Bool bDisable = bLastIsSymbol || bFormulaMode;
569 	if ( bDisable )
570 		nCntrl &= ~EE_CNTRL_AUTOCORRECT;
571 	else
572 		nCntrl |= EE_CNTRL_AUTOCORRECT;
573 
574 	if ( nCntrl != nOld )
575 		pEngine->SetControlWord(nCntrl);
576 }
577 
578 void ScInputHandler::UpdateSpellSettings( sal_Bool bFromStartTab )
579 {
580 	if ( pActiveViewSh )
581 	{
582 		ScViewData* pViewData = pActiveViewSh->GetViewData();
583 		sal_Bool bOnlineSpell = pViewData->GetDocument()->GetDocOptions().IsAutoSpell();
584 
585 		//	SetDefaultLanguage is independent of the language attributes,
586 		//	ScGlobal::GetEditDefaultLanguage is always used.
587 		//	It must be set every time in case the office language was changed.
588 
589 		pEngine->SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
590 
591 		//	if called for changed options, update flags only if already editing
592 		//	if called from StartTable, always update flags
593 
594 		if ( bFromStartTab || eMode != SC_INPUT_NONE )
595 		{
596 			sal_uLong nCntrl = pEngine->GetControlWord();
597 			sal_uLong nOld = nCntrl;
598 			if( bOnlineSpell )
599 				nCntrl |= EE_CNTRL_ONLINESPELLING;
600 			else
601 				nCntrl &= ~EE_CNTRL_ONLINESPELLING;
602 			// kein AutoCorrect auf Symbol-Font (EditEngine wertet Default nicht aus)
603 			if ( pLastPattern && pLastPattern->IsSymbolFont() )
604 				nCntrl &= ~EE_CNTRL_AUTOCORRECT;
605 			else
606 				nCntrl |= EE_CNTRL_AUTOCORRECT;
607 			if ( nCntrl != nOld )
608 				pEngine->SetControlWord(nCntrl);
609 
610 			ScDocument* pDoc = pViewData->GetDocument();
611             pDoc->ApplyAsianEditSettings( *pEngine );
612 			pEngine->SetDefaultHorizontalTextDirection(
613 				(EEHorizontalTextDirection)pDoc->GetEditTextDirection( pViewData->GetTabNo() ) );
614 			pEngine->SetFirstWordCapitalization( sal_False );
615 		}
616 
617 		//	language is set separately, so the speller is needed only if online
618 		//	spelling is active
619 
620 		if ( bOnlineSpell ) {
621             com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
622 			pEngine->SetSpeller( xXSpellChecker1 );
623         }
624 
625 		sal_Bool bHyphen = pLastPattern && ((const SfxBoolItem&)pLastPattern->GetItem(ATTR_HYPHENATE)).GetValue();
626 		if ( bHyphen ) {
627             com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
628 			pEngine->SetHyphenator( xXHyphenator );
629         }
630 	}
631 }
632 
633 //
634 //		Funktionen/Bereichsnamen etc. als Tip-Hilfe
635 //
636 
637 #define SC_STRTYPE_FUNCTIONS	1
638 //	die anderen Typen sind in ScDocument::GetFormulaEntries festgelegt
639 
640 void ScInputHandler::GetFormulaData()
641 {
642 	if ( pActiveViewSh )
643 	{
644 		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
645 
646 		if ( pFormulaData )
647 			pFormulaData->FreeAll();
648         else
649             pFormulaData = new TypedScStrCollection;
650 
651         if( pFormulaDataPara )
652             pFormulaDataPara->FreeAll();
653         else
654             pFormulaDataPara = new TypedScStrCollection;
655 
656 		//		MRU-Funktionen aus dem Funktions-Autopiloten
657 		//		wie in ScPosWnd::FillFunctions (inputwin.cxx)
658 
659         const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
660         sal_uInt16 nMRUCount = rOpt.GetLRUFuncListCount();
661         const sal_uInt16* pMRUList = rOpt.GetLRUFuncList();
662         const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
663         sal_uLong nListCount = pFuncList->GetCount();
664         if (pMRUList)
665         {
666             for (sal_uInt16 i=0; i<nMRUCount; i++)
667             {
668                 sal_uInt16 nId = pMRUList[i];
669                 for (sal_uLong j=0; j<nListCount; j++)
670                 {
671                     const ScFuncDesc* pDesc = pFuncList->GetFunction( j );
672                     if ( pDesc->nFIndex == nId && pDesc->pFuncName )
673                     {
674                         String aEntry = *pDesc->pFuncName;
675                         aEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
676                         TypedStrData* pData = new TypedStrData( aEntry, 0.0, SC_STRTYPE_FUNCTIONS );
677                         if (!pFormulaData->Insert(pData))
678                             delete pData;
679                         break;                  // nicht weitersuchen
680                     }
681                 }
682             }
683         }
684         for(sal_uLong i=0;i<nListCount;i++)
685         {
686             const ScFuncDesc* pDesc = pFuncList->GetFunction( i );
687             if ( pDesc->pFuncName )
688             {
689                 pDesc->initArgumentInfo();
690                 String aEntry = pDesc->GetSignature();
691                 TypedStrData* pData = new TypedStrData( aEntry, 0.0, SC_STRTYPE_FUNCTIONS );
692                 if (!pFormulaDataPara->Insert(pData))
693                     delete pData;
694             }
695         }
696 		pDoc->GetFormulaEntries( *pFormulaData );
697         pDoc->GetFormulaEntries( *pFormulaDataPara );
698 	}
699 }
700 
701 IMPL_LINK( ScInputHandler, ShowHideTipVisibleParentListener, VclWindowEvent*, pEvent )
702 {
703     if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
704         HideTip();
705     return 0;
706 }
707 
708 IMPL_LINK( ScInputHandler, ShowHideTipVisibleSecParentListener, VclWindowEvent*, pEvent )
709 {
710     if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
711         HideTipBelow();
712     return 0;
713 }
714 
715 void ScInputHandler::HideTip()
716 {
717 	if ( nTipVisible )
718 	{
719         if (pTipVisibleParent)
720             pTipVisibleParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) );
721 		Help::HideTip( nTipVisible );
722 		nTipVisible = 0;
723         pTipVisibleParent = NULL;
724 	}
725 	aManualTip.Erase();
726 }
727 void ScInputHandler::HideTipBelow()
728 {
729     if ( nTipVisibleSec )
730     {
731         if (pTipVisibleSecParent)
732             pTipVisibleSecParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) );
733         Help::HideTip( nTipVisibleSec );
734         nTipVisibleSec = 0;
735         pTipVisibleSecParent = NULL;
736     }
737     aManualTip.Erase();
738 }
739 
740 void ScInputHandler::ShowTipCursor()
741 {
742     HideTip();
743     HideTipBelow();
744     EditView* pActiveView = pTopView ? pTopView : pTableView;
745     ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
746     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
747     const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());
748 
749     if ( bFormulaMode && pActiveView && pFormulaDataPara && pEngine->GetParagraphCount() == 1 )
750     {
751         String aFormula = pEngine->GetText( (sal_uInt16) 0 );
752         ESelection aSel = pActiveView->GetSelection();
753         aSel.Adjust();
754         xub_StrLen  nLeftParentPos = 0;
755         if( aSel.nEndPos )
756         {
757             if ( aFormula.Len() < aSel.nEndPos )
758                 return;
759             xub_StrLen nPos = aSel.nEndPos;
760             String  aSelText = aFormula.Copy( 0, nPos );
761             xub_StrLen  nNextFStart = 0;
762             xub_StrLen  nNextFEnd = 0;
763             xub_StrLen  nArgPos = 0;
764             const IFunctionDescription* ppFDesc;
765             ::std::vector< ::rtl::OUString> aArgs;
766             sal_uInt16	    nArgs;
767             sal_Bool  bFound = sal_False;
768             FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr());
769 
770             while( !bFound )
771             {
772                 aSelText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
773                 nLeftParentPos = lcl_MatchParenthesis( aSelText, aSelText.Len()-1 );
774                 if( nLeftParentPos != STRING_NOTFOUND )
775                 {
776                     sal_Unicode c = ( nLeftParentPos > 0 ) ? aSelText.GetChar( nLeftParentPos-1 ) : 0;
777                     if( !((c >= 'A' && c<= 'Z') || (c>= 'a' && c<= 'z' )) )
778                         continue;
779                     nNextFStart = aHelper.GetFunctionStart( aSelText, nLeftParentPos, sal_True);
780                     if( aHelper.GetNextFunc( aSelText, sal_False, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) )
781                     {
782                         if( ppFDesc->getFunctionName().getLength() )
783                         {
784                             nArgPos = aHelper.GetArgStart( aSelText, nNextFStart, 0 );
785                             nArgs = static_cast<sal_uInt16>(ppFDesc->getParameterCount());
786 
787                             sal_uInt16 nActive = 0;
788                             sal_uInt16 nCount = 0;
789                             sal_uInt16 nCountSemicolon = 0;
790                             sal_uInt16 nCountDot = 0;
791                             sal_uInt16 nStartPosition = 0;
792                             sal_uInt16 nEndPosition = 0;
793                             sal_Bool   bFlag = sal_False;
794                             String aNew;
795                             sal_uInt16 nParAutoPos = SCPOS_INVALID;
796                             if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, sal_False ) )
797                             {
798                                 for( sal_uInt16 i=0; i < nArgs; i++ )
799                                 {
800                                     xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength());
801                                     if( nArgPos <= aSelText.Len()-1 )
802                                     {
803                                         nActive = i+1;
804                                         bFlag = sal_True;
805                                     }
806                                     nArgPos+=nLength+1;
807                                 }
808                                 if( bFlag )
809                                 {
810                                     nCountSemicolon = aNew.GetTokenCount(cSep)-1;
811                                     nCountDot = aNew.GetTokenCount(cSheetSep)-1;
812 
813                                     if( !nCountSemicolon )
814                                     {
815                                         for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
816                                         {
817                                             sal_Unicode cNext = aNew.GetChar( i );
818                                             if( cNext == '(' )
819                                             {
820                                                 nStartPosition = i+1;
821                                             }
822                                         }
823                                     }
824                                     else if( !nCountDot )
825                                     {
826                                         for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
827                                         {
828                                             sal_Unicode cNext = aNew.GetChar( i );
829                                             if( cNext == '(' )
830                                             {
831                                                 nStartPosition = i+1;
832                                             }
833                                             else if( cNext == cSep )
834                                             {
835                                                 nCount ++;
836                                                 nEndPosition = i;
837                                                 if( nCount == nActive )
838                                                 {
839                                                     break;
840                                                 }
841                                                 nStartPosition = nEndPosition+1;
842                                             }
843                                         }
844                                     }
845                                     else
846                                     {
847                                         for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
848                                         {
849                                             sal_Unicode cNext = aNew.GetChar( i );
850                                             if( cNext == '(' )
851                                             {
852                                                 nStartPosition = i+1;
853                                             }
854                                             else if( cNext == cSep )
855                                             {
856                                                 nCount ++;
857                                                 nEndPosition = i;
858                                                 if( nCount == nActive )
859                                                 {
860                                                     break;
861                                                 }
862                                                 nStartPosition = nEndPosition+1;
863                                             }
864                                             else if( cNext == cSheetSep )
865                                             {
866                                                 continue;
867                                             }
868                                         }
869                                     }
870 
871                                     if( nStartPosition )
872                                     {
873                                         aNew.Insert( 0x25BA, nStartPosition );
874                                         ShowTipBelow( aNew );
875                                         bFound = sal_True;
876                                     }
877                                 }
878                                 else
879                                 {
880                                     ShowTipBelow( aNew );
881                                     bFound = sal_True;
882                                 }
883                             }
884                         }
885                     }
886                 }
887                 else
888                 {
889                     sal_uInt16 nPosition = 0;
890                     String aText = pEngine->GetWord( 0, aSel.nEndPos-1 );
891                     if( aText.GetChar( aSel.nEndPos-1 ) == '=' )
892                     {
893                         break;
894                     }
895                     String aNew;
896                     sal_uInt16 nParAutoPos = SCPOS_INVALID;
897                     nPosition = aText.Len()+1;
898                     if( pFormulaDataPara->FindText( aText, aNew, nParAutoPos, sal_False ) )
899                     {
900                         if( aFormula.GetChar( nPosition ) =='(' )
901                         {
902                             ShowTipBelow( aNew );
903                             bFound = sal_True;
904                         }
905                         else
906                             break;
907                     }
908                     else
909                     {
910                         break;
911                     }
912                 }
913             }
914         }
915     }
916 }
917 
918 void ScInputHandler::ShowTip( const String& rText )
919 {
920 	//	aManualTip muss hinterher von aussen gesetzt werden
921 	HideTip();
922 
923 	EditView* pActiveView = pTopView ? pTopView : pTableView;
924 	if (pActiveView)
925 	{
926 		Point aPos;
927 		pTipVisibleParent = pActiveView->GetWindow();
928 		Cursor* pCur = pActiveView->GetCursor();
929 		if (pCur)
930 			aPos = pTipVisibleParent->LogicToPixel( pCur->GetPos() );
931 		aPos = pTipVisibleParent->OutputToScreenPixel( aPos );
932 		Rectangle aRect( aPos, aPos );
933 
934 		sal_uInt16 nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
935 		nTipVisible = Help::ShowTip(pTipVisibleParent, aRect, rText, nAlign);
936 		pTipVisibleParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) );
937 	}
938 }
939 
940 void ScInputHandler::ShowTipBelow( const String& rText )
941 {
942     HideTipBelow();
943 
944     EditView* pActiveView = pTopView ? pTopView : pTableView;
945     if ( pActiveView )
946     {
947         Point aPos;
948         pTipVisibleSecParent = pActiveView->GetWindow();
949         Cursor* pCur = pActiveView->GetCursor();
950         if ( pCur )
951         {
952             Point aLogicPos = pCur->GetPos();
953             aLogicPos.Y() += pCur->GetHeight();
954             aPos = pTipVisibleSecParent->LogicToPixel( aLogicPos );
955         }
956         aPos = pTipVisibleSecParent->OutputToScreenPixel( aPos );
957         Rectangle aRect( aPos, aPos );
958         sal_uInt16 nAlign = QUICKHELP_LEFT | QUICKHELP_TOP | QUICKHELP_NOEVADEPOINTER;
959         nTipVisibleSec = Help::ShowTip(pTipVisibleSecParent, aRect, rText, nAlign);
960         pTipVisibleSecParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) );
961     }
962 }
963 
964 void ScInputHandler::UseFormulaData()
965 {
966 	EditView* pActiveView = pTopView ? pTopView : pTableView;
967     ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
968     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
969     const sal_Unicode cSheetSep = lcl_getSheetSeparator(pDocSh->GetDocument());
970 
971 	//	Formeln duerfen nur 1 Absatz haben
972 	if ( pActiveView && pFormulaData && pEngine->GetParagraphCount() == 1 )
973 	{
974 		String aTotal = pEngine->GetText( (sal_uInt16) 0 );
975 		ESelection aSel = pActiveView->GetSelection();
976 		aSel.Adjust();
977 
978 		//	#59348# Durch Differenzen zwischen Tabelle und Eingabezeile
979 		//	(z.B. Clipboard mit Zeilenumbruechen) kann es sein, dass die Selektion
980 		//	nicht mehr zur EditEngine passt. Dann halt kommentarlos abbrechen:
981 
982 		if ( aSel.nEndPos > aTotal.Len() )
983 			return;
984 
985 		//	steht der Cursor am Ende eines Wortes?
986 
987 		if ( aSel.nEndPos > 0 )
988 		{
989             xub_StrLen nPos = aSel.nEndPos;
990             String  aFormula = aTotal.Copy( 0, nPos );;
991             xub_StrLen  nLeftParentPos = 0;
992             xub_StrLen  nNextFStart = 0;
993             xub_StrLen  nNextFEnd = 0;
994             xub_StrLen  nArgPos = 0;
995             const IFunctionDescription* ppFDesc;
996             ::std::vector< ::rtl::OUString> aArgs;
997             sal_uInt16	    nArgs;
998             sal_Bool  bFound = sal_False;
999 
1000             String aText = pEngine->GetWord( 0, aSel.nEndPos-1 );
1001             if ( aText.Len() )
1002             {
1003                 String aNew;
1004                 nAutoPos = SCPOS_INVALID;
1005                 if ( pFormulaData->FindText( aText, aNew, nAutoPos, sal_False ) )
1006                 {
1007                     ShowTip( aNew );
1008                     aAutoSearch = aText;
1009                 }
1010             }
1011             FormulaHelper aHelper(ScGlobal::GetStarCalcFunctionMgr());
1012 
1013             while( !bFound )
1014             {
1015                 aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
1016                 nLeftParentPos = lcl_MatchParenthesis( aFormula, aFormula.Len()-1 );
1017                 if( nLeftParentPos == STRING_NOTFOUND )
1018                     break;
1019 
1020                 // #160063# nLeftParentPos can be 0 if a parenthesis is inserted before the formula
1021                 sal_Unicode c = ( nLeftParentPos > 0 ) ? aFormula.GetChar( nLeftParentPos-1 ) : 0;
1022                 if( !((c >= 'A' && c<= 'Z') || (c>= 'a' && c<= 'z') ) )
1023                     continue;
1024                 nNextFStart = aHelper.GetFunctionStart( aFormula, nLeftParentPos, sal_True);
1025                 if( aHelper.GetNextFunc( aFormula, sal_False, nNextFStart, &nNextFEnd, &ppFDesc, &aArgs ) )
1026                 {
1027                     if( ppFDesc->getFunctionName().getLength() )
1028                     {
1029                         nArgPos = aHelper.GetArgStart( aFormula, nNextFStart, 0 );
1030                         nArgs = static_cast<sal_uInt16>(ppFDesc->getParameterCount());
1031 
1032                         sal_uInt16 nActive = 0;
1033                         sal_uInt16 nCount = 0;
1034                         sal_uInt16 nCountSemicolon = 0;
1035                         sal_uInt16 nCountDot = 0;
1036                         sal_uInt16 nStartPosition = 0;
1037                         sal_uInt16 nEndPosition = 0;
1038                         sal_Bool   bFlag = sal_False;
1039                         String aNew;
1040                         sal_uInt16 nParAutoPos = SCPOS_INVALID;
1041                         if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, sal_False ) )
1042                         {
1043                             for( sal_uInt16 i=0; i < nArgs; i++ )
1044                             {
1045                                 xub_StrLen nLength = static_cast<xub_StrLen>(aArgs[i].getLength());
1046                                 if( nArgPos <= aFormula.Len()-1 )
1047                                 {
1048                                     nActive = i+1;
1049                                     bFlag = sal_True;
1050                                 }
1051                                 nArgPos+=nLength+1;
1052                             }
1053                             if( bFlag )
1054                             {
1055                                 nCountSemicolon = aNew.GetTokenCount(cSep)-1;
1056                                 nCountDot = aNew.GetTokenCount(cSheetSep)-1;
1057 
1058                                if( !nCountSemicolon )
1059                                {
1060                                     for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
1061                                     {
1062                                         sal_Unicode cNext = aNew.GetChar( i );
1063                                         if( cNext == '(' )
1064                                         {
1065                                             nStartPosition = i+1;
1066                                         }
1067                                     }
1068                                 }
1069                                 else if( !nCountDot )
1070                                 {
1071                                     for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
1072                                     {
1073                                         sal_Unicode cNext = aNew.GetChar( i );
1074                                         if( cNext == '(' )
1075                                         {
1076                                             nStartPosition = i+1;
1077                                         }
1078                                         else if( cNext == cSep )
1079                                         {
1080                                             nCount ++;
1081                                             nEndPosition = i;
1082                                             if( nCount == nActive )
1083                                             {
1084                                                 break;
1085                                             }
1086                                             nStartPosition = nEndPosition+1;
1087                                         }
1088                                     }
1089                                 }
1090                                 else
1091                                 {
1092                                     for( sal_uInt16 i = 0; i < aNew.Len(); i++ )
1093                                     {
1094                                         sal_Unicode cNext = aNew.GetChar( i );
1095                                         if( cNext == '(' )
1096                                         {
1097                                             nStartPosition = i+1;
1098                                         }
1099                                         else if( cNext == cSep )
1100                                         {
1101                                             nCount ++;
1102                                             nEndPosition = i;
1103                                             if( nCount == nActive )
1104                                             {
1105                                                 break;
1106                                             }
1107                                             nStartPosition = nEndPosition+1;
1108                                         }
1109                                         else if( cNext == cSheetSep )
1110                                         {
1111                                             continue;
1112                                         }
1113                                     }
1114                                 }
1115 
1116                                 if( nStartPosition )
1117                                 {
1118                                     aNew.Insert( 0x25BA, nStartPosition );
1119                                     ShowTipBelow( aNew );
1120                                     bFound = sal_True;
1121                                 }
1122                             }
1123                             else
1124                             {
1125                                 ShowTipBelow( aNew );
1126                                 bFound = sal_True;
1127                             }
1128                         }
1129                     }
1130                 }
1131             }
1132         }
1133     }
1134 }
1135 
1136 void ScInputHandler::NextFormulaEntry( sal_Bool bBack )
1137 {
1138 	EditView* pActiveView = pTopView ? pTopView : pTableView;
1139 	if ( pActiveView && pFormulaData )
1140 	{
1141 		String aNew;
1142 		if ( pFormulaData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) )
1143 			ShowTip( aNew );		//	als QuickHelp anzeigen
1144 	}
1145 
1146 	//	bei Tab wird vorher immer HideCursor gerufen
1147 
1148 	if (pActiveView)
1149 		pActiveView->ShowCursor();
1150 }
1151 
1152 void lcl_CompleteFunction( EditView* pView, const String& rInsert, sal_Bool& rParInserted )
1153 {
1154 	if (pView)
1155 	{
1156 		ESelection aSel = pView->GetSelection();
1157 		--aSel.nStartPos;
1158 		--aSel.nEndPos;
1159 		pView->SetSelection(aSel);
1160 		pView->SelectCurrentWord();
1161 
1162 		String aInsStr = rInsert;
1163 		xub_StrLen nInsLen = aInsStr.Len();
1164 		sal_Bool bDoParen = ( nInsLen > 1 && aInsStr.GetChar(nInsLen-2) == '('
1165 									  && aInsStr.GetChar(nInsLen-1) == ')' );
1166 		if ( bDoParen )
1167 		{
1168 			//	Klammern hinter Funktionsnamen nicht einfuegen, wenn direkt dahinter
1169 			//	schon eine Klammer steht (z.B. wenn der Funktionsname geaendert wurde,
1170 			//	#39393#).
1171 
1172 			ESelection aWordSel = pView->GetSelection();
1173 			String aOld = pView->GetEditEngine()->GetText((sal_uInt16)0);
1174 			sal_Unicode cNext = aOld.GetChar(aWordSel.nEndPos);
1175 			if ( cNext == '(' )
1176 			{
1177 				bDoParen = sal_False;
1178 				aInsStr.Erase( nInsLen - 2 );	// Klammern weglassen
1179 			}
1180 		}
1181 
1182 		pView->InsertText( aInsStr, sal_False );
1183 
1184 		if ( bDoParen )							// Cursor zwischen die Klammern setzen
1185 		{
1186 			aSel = pView->GetSelection();
1187 			--aSel.nStartPos;
1188 			--aSel.nEndPos;
1189 			pView->SetSelection(aSel);
1190 
1191 			rParInserted = sal_True;
1192 		}
1193 	}
1194 }
1195 
1196 void ScInputHandler::PasteFunctionData()
1197 {
1198 	if ( pFormulaData && nAutoPos != SCPOS_INVALID )
1199 	{
1200 		TypedStrData* pData = (*pFormulaData)[nAutoPos];
1201 		if (pData)
1202 		{
1203 			String aInsert = pData->GetString();
1204 			sal_Bool bParInserted = sal_False;
1205 
1206 			DataChanging(); 						// kann nicht neu sein
1207 			lcl_CompleteFunction( pTopView, aInsert, bParInserted );
1208 			lcl_CompleteFunction( pTableView, aInsert, bParInserted );
1209 			DataChanged();
1210             ShowTipCursor();
1211 
1212 			if (bParInserted)
1213 				AutoParAdded();
1214 		}
1215 	}
1216 
1217 	HideTip();
1218 
1219 	EditView* pActiveView = pTopView ? pTopView : pTableView;
1220 	if (pActiveView)
1221 		pActiveView->ShowCursor();
1222 }
1223 
1224 //
1225 //		Selektion berechnen und als Tip-Hilfe anzeigen
1226 //
1227 
1228 String lcl_Calculate( const String& rFormula, ScDocument* pDoc, const ScAddress &rPos )
1229 {
1230 	//!		mit ScFormulaDlg::CalcValue zusammenfassen und ans Dokument verschieben !!!!
1231 	//!		(Anfuehrungszeichen bei Strings werden nur hier eingefuegt)
1232 
1233 	String aValue;
1234 
1235 	if (rFormula.Len())
1236 	{
1237 		ScFormulaCell* pCell = new ScFormulaCell( pDoc, rPos, rFormula );
1238 
1239 		// #35521# HACK! um bei ColRowNames kein #REF! zu bekommen,
1240 		// wenn ein Name eigentlich als Bereich in die Gesamt-Formel
1241 		// eingefuegt wird, bei der Einzeldarstellung aber als
1242 		// single-Zellbezug interpretiert wird
1243 		sal_Bool bColRowName = pCell->HasColRowName();
1244 		if ( bColRowName )
1245 		{
1246 			// ColRowName im RPN-Code?
1247 			if ( pCell->GetCode()->GetCodeLen() <= 1 )
1248 			{	// ==1: einzelner ist als Parameter immer Bereich
1249 				// ==0: es waere vielleicht einer, wenn..
1250 				String aBraced( '(' );
1251 				aBraced += rFormula;
1252 				aBraced += ')';
1253 				delete pCell;
1254 				pCell = new ScFormulaCell( pDoc, rPos, aBraced );
1255 			}
1256 			else
1257 				bColRowName = sal_False;
1258 		}
1259 
1260 		sal_uInt16 nErrCode = pCell->GetErrCode();
1261 		if ( nErrCode == 0 )
1262 		{
1263 			SvNumberFormatter& aFormatter = *(pDoc->GetFormatTable());
1264 			Color* pColor;
1265 			if ( pCell->IsValue() )
1266 			{
1267 				double n = pCell->GetValue();
1268 				sal_uLong nFormat = aFormatter.GetStandardFormat( n, 0,
1269 								pCell->GetFormatType(), ScGlobal::eLnge );
1270 				aFormatter.GetInputLineString( n, nFormat, aValue );
1271 				//!	display OutputString but insert InputLineString
1272 			}
1273 			else
1274 			{
1275 				String aStr;
1276 
1277 				pCell->GetString( aStr );
1278 				sal_uLong nFormat = aFormatter.GetStandardFormat(
1279 								pCell->GetFormatType(), ScGlobal::eLnge);
1280 				aFormatter.GetOutputString( aStr, nFormat,
1281 											aValue, &pColor );
1282 
1283 				aValue.Insert('"',0);	// in Anfuehrungszeichen
1284 				aValue+='"';
1285 				//!	Anfuehrungszeichen im String escapen ????
1286 			}
1287 
1288 			ScRange aTestRange;
1289 			if ( bColRowName || (aTestRange.Parse(rFormula) & SCA_VALID) )
1290 				aValue.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ..." ));		// Bereich
1291 		}
1292 		else
1293 			aValue = ScGlobal::GetErrorString(nErrCode);
1294 		delete pCell;
1295 	}
1296 
1297 	return aValue;
1298 }
1299 
1300 void ScInputHandler::FormulaPreview()
1301 {
1302 	String aValue;
1303 	EditView* pActiveView = pTopView ? pTopView : pTableView;
1304 	if ( pActiveView && pActiveViewSh )
1305 	{
1306 		String aPart = pActiveView->GetSelected();
1307 		if (!aPart.Len())
1308 			aPart = pEngine->GetText((sal_uInt16)0);
1309 		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
1310 		aValue = lcl_Calculate( aPart, pDoc, aCursorPos );
1311 	}
1312 
1313 	if (aValue.Len())
1314 	{
1315 		ShowTip( aValue );			//	als QuickHelp anzeigen
1316 		aManualTip = aValue;		//	nach ShowTip setzen
1317 		nAutoPos = SCPOS_INVALID;	//	Formel-Autocomplete aufheben
1318 	}
1319 }
1320 
1321 void ScInputHandler::PasteManualTip()
1322 {
1323 	//	drei Punkte am Ende -> Bereichsreferenz -> nicht einfuegen
1324 	//	(wenn wir mal Matrix-Konstanten haben, kann das geaendert werden)
1325 
1326 	xub_StrLen nTipLen = aManualTip.Len();
1327 	if ( nTipLen && ( nTipLen < 3 || !aManualTip.Copy( nTipLen-3 ).EqualsAscii("...") ) )
1328 	{
1329 		DataChanging(); 									// kann nicht neu sein
1330 
1331 		String aInsert = aManualTip;
1332 		EditView* pActiveView = pTopView ? pTopView : pTableView;
1333 		if (!pActiveView->HasSelection())
1334 		{
1335 			//	nichts selektiert -> alles selektieren
1336 			xub_StrLen nOldLen = pEngine->GetTextLen(0);
1337 			ESelection aAllSel( 0, 0, 0, nOldLen );
1338 			if ( pTopView )
1339 				pTopView->SetSelection( aAllSel );
1340 			if ( pTableView )
1341 				pTableView->SetSelection( aAllSel );
1342 		}
1343 
1344 		ESelection aSel = pActiveView->GetSelection();
1345 		aSel.Adjust();
1346 		DBG_ASSERT( !aSel.nStartPara && !aSel.nEndPara, "Zuviele Absaetze in Formel" );
1347 		if ( !aSel.nStartPos )	// Selektion ab Anfang?
1348 		{
1349 			if ( aSel.nEndPos == pEngine->GetTextLen(0) )
1350 			{
1351 				//	alles selektiert -> Anfuehrungszeichen weglassen
1352 				if ( aInsert.GetChar(0) == '"' )
1353 					aInsert.Erase(0,1);
1354 				xub_StrLen nInsLen = aInsert.Len();
1355 				if ( nInsLen && aInsert.GetChar(nInsLen-1) == '"' )
1356 					aInsert.Erase( nInsLen-1 );
1357 			}
1358 			else if ( aSel.nEndPos )
1359 			{
1360 				//	nicht alles selektiert -> Gleichheitszeichen nicht ueberschreiben
1361 				//!	doppelte Gleichheitszeichen auch ???
1362 
1363 				aSel.nStartPos = 1;
1364 				if ( pTopView )
1365 					pTopView->SetSelection( aSel );
1366 				if ( pTableView )
1367 					pTableView->SetSelection( aSel );
1368 			}
1369 		}
1370 		if ( pTopView )
1371 			pTopView->InsertText( aInsert, sal_True );
1372 		if ( pTableView )
1373 			pTableView->InsertText( aInsert, sal_True );
1374 
1375 		DataChanged();
1376 	}
1377 
1378 	HideTip();
1379 }
1380 
1381 void ScInputHandler::ResetAutoPar()
1382 {
1383 	nAutoPar = 0;
1384 }
1385 
1386 void ScInputHandler::AutoParAdded()
1387 {
1388 	++nAutoPar;		//	closing parenthesis can be overwritten
1389 }
1390 
1391 sal_Bool ScInputHandler::CursorAtClosingPar()
1392 {
1393 	//	test if the cursor is before a closing parenthesis
1394 
1395 	//	selection from SetReference has been removed before
1396 	EditView* pActiveView = pTopView ? pTopView : pTableView;
1397 	if ( pActiveView && !pActiveView->HasSelection() && bFormulaMode )
1398 	{
1399 		ESelection aSel = pActiveView->GetSelection();
1400 		xub_StrLen nPos = aSel.nStartPos;
1401 		String aFormula = pEngine->GetText((sal_uInt16)0);
1402 		if ( nPos < aFormula.Len() && aFormula.GetChar(nPos) == ')' )
1403 			return sal_True;
1404 	}
1405 	return sal_False;
1406 }
1407 
1408 void ScInputHandler::SkipClosingPar()
1409 {
1410 	//	this is called when a ')' is typed and the cursor is before a ')'
1411 	//	that can be overwritten -> just set the cursor behind the ')'
1412 
1413 	EditView* pActiveView = pTopView ? pTopView : pTableView;
1414 	if (pActiveView)
1415 	{
1416 		ESelection aSel = pActiveView->GetSelection();
1417 		++aSel.nStartPos;
1418 		++aSel.nEndPos;
1419 
1420 		//	this is in a formula (only one paragraph), so the selection
1421 		//	can be used directly for the TopView
1422 
1423 		if ( pTopView )
1424 			pTopView->SetSelection( aSel );
1425 		if ( pTableView )
1426 			pTableView->SetSelection( aSel );
1427 	}
1428 
1429 	DBG_ASSERT(nAutoPar, "SkipClosingPar: count is wrong");
1430 	--nAutoPar;
1431 }
1432 
1433 //
1434 //		Auto-Eingabe
1435 //
1436 
1437 void ScInputHandler::GetColData()
1438 {
1439 	if ( pActiveViewSh )
1440 	{
1441 		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
1442 
1443 		if ( pColumnData )
1444 			pColumnData->FreeAll();
1445 		else
1446 		{
1447 			pColumnData = new TypedScStrCollection;
1448 			pColumnData->SetCaseSensitive( sal_True );		// equal strings are handled in FindText
1449 		}
1450 
1451 		pDoc->GetDataEntries( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(),
1452 								*pColumnData, sal_True );
1453 	}
1454 }
1455 
1456 void ScInputHandler::UseColData()			// beim Tippen
1457 {
1458 	EditView* pActiveView = pTopView ? pTopView : pTableView;
1459 	if ( pActiveView && pColumnData )
1460 	{
1461 		//	nur anpassen, wenn Cursor am Ende steht
1462 
1463 		ESelection aSel = pActiveView->GetSelection();
1464 		aSel.Adjust();
1465 
1466 		sal_uInt16 nParCnt = pEngine->GetParagraphCount();
1467 		if ( aSel.nEndPara+1 == nParCnt )
1468 		{
1469 			xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara );
1470 			if ( aSel.nEndPos == nParLen )
1471 			{
1472 				String aText = GetEditText(pEngine);
1473 				if (aText.Len())
1474 				{
1475 					String aNew;
1476 					nAutoPos = SCPOS_INVALID;	// nix
1477 					if ( pColumnData->FindText( aText, aNew, nAutoPos, sal_False ) )
1478 					{
1479 						//	#45434# durch dBase Import etc. koennen Umbrueche im String sein,
1480 						//	das wuerde hier mehrere Absaetze ergeben -> nicht gut
1481 						//!	GetExactMatch funktioniert dann auch nicht
1482 						lcl_RemoveLineEnd( aNew );
1483 
1484                         //  Absaetze beibehalten, nur den Rest anfuegen
1485 						//!	genaue Ersetzung im EnterHandler !!!
1486 
1487 						// ein Space zwischen Absaetzen:
1488 						sal_uLong nEdLen = pEngine->GetTextLen() + nParCnt - 1;
1489 						String aIns = aNew.Copy( (xub_StrLen)nEdLen );
1490 
1491 						//	selection must be "backwards", so the cursor stays behind the last
1492 						//	typed character
1493 						ESelection aSelection( aSel.nEndPara, aSel.nEndPos + aIns.Len(),
1494 											   aSel.nEndPara, aSel.nEndPos );
1495 
1496 						//	when editing in input line, apply to both edit views
1497 						if ( pTableView )
1498 						{
1499 							pTableView->InsertText( aIns, sal_False );
1500 							pTableView->SetSelection( aSelection );
1501 						}
1502 						if ( pTopView )
1503 						{
1504 							pTopView->InsertText( aIns, sal_False );
1505 							pTopView->SetSelection( aSelection );
1506 						}
1507 
1508 						aAutoSearch = aText;	// zum Weitersuchen - nAutoPos ist gesetzt
1509 
1510 						if ( aText.Len() == aNew.Len() )
1511 						{
1512 							//	Wenn der eingegebene Text gefunden wurde, TAB nur dann
1513 							//	verschlucken, wenn noch etwas kommt
1514 
1515 							String aDummy;
1516 							sal_uInt16 nNextPos = nAutoPos;
1517 							bUseTab = pColumnData->FindText( aText, aDummy, nNextPos, sal_False );
1518 						}
1519 						else
1520 							bUseTab = sal_True;
1521 					}
1522 				}
1523 			}
1524 		}
1525 	}
1526 }
1527 
1528 void ScInputHandler::NextAutoEntry( sal_Bool bBack )
1529 {
1530 	EditView* pActiveView = pTopView ? pTopView : pTableView;
1531 	if ( pActiveView && pColumnData )
1532 	{
1533 		if ( nAutoPos != SCPOS_INVALID && aAutoSearch.Len() )
1534 		{
1535 			//	stimmt die Selektion noch? (kann per Maus geaendert sein)
1536 
1537 			ESelection aSel = pActiveView->GetSelection();
1538 			aSel.Adjust();
1539 			sal_uInt16 nParCnt = pEngine->GetParagraphCount();
1540 			if ( aSel.nEndPara+1 == nParCnt && aSel.nStartPara == aSel.nEndPara )
1541 			{
1542 				String aText = GetEditText(pEngine);
1543 				xub_StrLen nSelLen = aSel.nEndPos - aSel.nStartPos;
1544 				xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara );
1545 				if ( aSel.nEndPos == nParLen && aText.Len() == aAutoSearch.Len() + nSelLen )
1546 				{
1547 					String aNew;
1548 					if ( pColumnData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) )
1549 					{
1550 						bInOwnChange = sal_True;		// disable ModifyHdl (reset below)
1551 
1552 						lcl_RemoveLineEnd( aNew );
1553 						String aIns = aNew.Copy( aAutoSearch.Len() );
1554 
1555 						//	when editing in input line, apply to both edit views
1556 						if ( pTableView )
1557 						{
1558 							pTableView->DeleteSelected();
1559 							pTableView->InsertText( aIns, sal_False );
1560 							pTableView->SetSelection( ESelection(
1561 														aSel.nEndPara, aSel.nStartPos + aIns.Len(),
1562 														aSel.nEndPara, aSel.nStartPos ) );
1563 						}
1564 						if ( pTopView )
1565 						{
1566 							pTopView->DeleteSelected();
1567 							pTopView->InsertText( aIns, sal_False );
1568 							pTopView->SetSelection( ESelection(
1569 														aSel.nEndPara, aSel.nStartPos + aIns.Len(),
1570 														aSel.nEndPara, aSel.nStartPos ) );
1571 						}
1572 
1573 						bInOwnChange = sal_False;
1574 					}
1575 					else
1576 					{
1577 						// mehr gibts nicht
1578 
1579 						Sound::Beep();
1580 					}
1581 				}
1582 			}
1583 		}
1584 	}
1585 
1586 	//	bei Tab wird vorher immer HideCursor gerufen
1587 
1588 	if (pActiveView)
1589 		pActiveView->ShowCursor();
1590 }
1591 
1592 //
1593 //		Klammern hervorheben
1594 //
1595 
1596 void ScInputHandler::UpdateParenthesis()
1597 {
1598 	//	Klammern suchen
1599 
1600 	//!	Klammer-Hervorhebung einzeln abschaltbar ????
1601 
1602 	sal_Bool bFound = sal_False;
1603 	if ( bFormulaMode && eMode != SC_INPUT_TOP )
1604 	{
1605 		if ( pTableView && !pTableView->HasSelection() )		// Selektion ist immer unten
1606 		{
1607 			ESelection aSel = pTableView->GetSelection();
1608 			if (aSel.nStartPos)
1609 			{
1610 				//	Das Zeichen links vom Cursor wird angeschaut
1611 
1612 				xub_StrLen nPos = aSel.nStartPos - 1;
1613 				String aFormula = pEngine->GetText((sal_uInt16)0);
1614 				sal_Unicode c = aFormula.GetChar(nPos);
1615 				if ( c == '(' || c == ')' )
1616 				{
1617 					xub_StrLen nOther = lcl_MatchParenthesis( aFormula, nPos );
1618 					if ( nOther != STRING_NOTFOUND )
1619 					{
1620 						SfxItemSet aSet( pEngine->GetEmptyItemSet() );
1621 						aSet.Put( SvxWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT ) );
1622 						//!	Unterscheidung, wenn die Zelle schon fett ist !!!!
1623 
1624 						if (bParenthesisShown)
1625 						{
1626 							//	alte Hervorhebung wegnehmen
1627 							sal_uInt16 nCount = pEngine->GetParagraphCount();
1628 							for (sal_uInt16 i=0; i<nCount; i++)
1629 								pEngine->QuickRemoveCharAttribs( i, EE_CHAR_WEIGHT );
1630 						}
1631 
1632 						ESelection aSelThis( 0,nPos, 0,nPos+1 );
1633 						pEngine->QuickSetAttribs( aSet, aSelThis );
1634 						ESelection aSelOther( 0,nOther, 0,nOther+1 );
1635 						pEngine->QuickSetAttribs( aSet, aSelOther );
1636 
1637 						//	Dummy-InsertText fuer Update und Paint (Selektion ist leer)
1638 						pTableView->InsertText( EMPTY_STRING, sal_False );
1639 
1640 						bFound = sal_True;
1641 					}
1642 				}
1643 			}
1644 
1645 			//	mark parenthesis right of cursor if it will be overwritten (nAutoPar)
1646 			//	with different color (COL_LIGHTBLUE) ??
1647 		}
1648 	}
1649 
1650 	//	alte Hervorhebung wegnehmen, wenn keine neue gesetzt
1651 
1652 	if ( bParenthesisShown && !bFound && pTableView )
1653 	{
1654 		sal_uInt16 nCount = pEngine->GetParagraphCount();
1655 		for (sal_uInt16 i=0; i<nCount; i++)
1656 			pTableView->RemoveCharAttribs( i, EE_CHAR_WEIGHT );
1657 	}
1658 
1659 	bParenthesisShown = bFound;
1660 }
1661 
1662 void ScInputHandler::ViewShellGone(ScTabViewShell* pViewSh) 	// wird synchron aufgerufen!
1663 {
1664 	if ( pViewSh == pActiveViewSh )
1665 	{
1666 		delete pLastState;
1667 		pLastState = NULL;
1668 		pLastPattern = NULL;
1669 	}
1670 
1671 	if ( pViewSh == pRefViewSh )
1672 	{
1673 		//! Die Eingabe kommt aus dem EnterHandler nicht mehr an
1674 		//	Trotzdem wird immerhin der Editmodus beendet
1675 
1676 		EnterHandler();
1677 		bFormulaMode = sal_False;
1678 		pRefViewSh = NULL;
1679 		SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
1680 		SC_MOD()->SetRefInputHdl(NULL);
1681 		if (pInputWin)
1682 			pInputWin->SetFormulaMode(sal_False);
1683 		UpdateAutoCorrFlag();
1684 	}
1685 
1686 	pActiveViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
1687 
1688 	if ( pActiveViewSh && pActiveViewSh == pViewSh )
1689 	{
1690 		DBG_ERROR("pActiveViewSh weg");
1691 		pActiveViewSh = NULL;
1692 	}
1693 
1694 	if ( SC_MOD()->GetInputOptions().GetTextWysiwyg() )
1695 		UpdateRefDevice();		// don't keep old document's printer as RefDevice
1696 }
1697 
1698 void ScInputHandler::UpdateActiveView()
1699 {
1700 	ImplCreateEditEngine();
1701 
1702     // #i20588# Don't rely on focus to find the active edit view. Instead, the
1703     // active pane at the start of editing is now stored (GetEditActivePart).
1704     // GetActiveWin (the currently active pane) fails for ref input across the
1705     // panes of a split view.
1706 
1707     Window* pShellWin = pActiveViewSh ?
1708                 pActiveViewSh->GetWindowByPos( pActiveViewSh->GetViewData()->GetEditActivePart() ) :
1709                 NULL;
1710 
1711 	sal_uInt16 nCount = pEngine->GetViewCount();
1712 	if (nCount > 0)
1713 	{
1714 		pTableView = pEngine->GetView(0);
1715 		for (sal_uInt16 i=1; i<nCount; i++)
1716 		{
1717 			EditView* pThis = pEngine->GetView(i);
1718 			Window* pWin = pThis->GetWindow();
1719 			if ( pWin==pShellWin )
1720 				pTableView = pThis;
1721 		}
1722 	}
1723 	else
1724 		pTableView = NULL;
1725 
1726 	if (pInputWin)
1727 		pTopView = pInputWin->GetEditView();
1728 	else
1729 		pTopView = NULL;
1730 }
1731 
1732 void ScInputHandler::StopInputWinEngine( sal_Bool bAll )
1733 {
1734 	if (pInputWin)
1735 		pInputWin->StopEditEngine( bAll );
1736 
1737 	pTopView = NULL;		// invalid now
1738 }
1739 
1740 EditView* ScInputHandler::GetActiveView()
1741 {
1742 	UpdateActiveView();
1743 	return pTopView ? pTopView : pTableView;
1744 }
1745 
1746 void ScInputHandler::ForgetLastPattern()
1747 {
1748 	pLastPattern = NULL;
1749 	if ( !pLastState && pActiveViewSh )
1750 		pActiveViewSh->UpdateInputHandler( sal_True );		// Status neu holen
1751 	else
1752 		NotifyChange( pLastState, sal_True );
1753 }
1754 
1755 void ScInputHandler::UpdateAdjust( sal_Unicode cTyped )
1756 {
1757 	SvxAdjust eSvxAdjust;
1758     switch (eAttrAdjust)
1759 	{
1760 		case SVX_HOR_JUSTIFY_STANDARD:
1761 			{
1762 				sal_Bool bNumber = sal_False;
1763 				if (cTyped)										// neu angefangen
1764 					bNumber = (cTyped>='0' && cTyped<='9');		// nur Ziffern sind Zahlen
1765 				else if ( pActiveViewSh )
1766 				{
1767 					ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
1768 					bNumber = ( pDoc->GetCellType( aCursorPos ) == CELLTYPE_VALUE );
1769 				}
1770 				eSvxAdjust = bNumber ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
1771 			}
1772 			break;
1773 		case SVX_HOR_JUSTIFY_BLOCK:
1774 			eSvxAdjust = SVX_ADJUST_BLOCK;
1775 			break;
1776 		case SVX_HOR_JUSTIFY_CENTER:
1777 			eSvxAdjust = SVX_ADJUST_CENTER;
1778 			break;
1779 		case SVX_HOR_JUSTIFY_RIGHT:
1780 			eSvxAdjust = SVX_ADJUST_RIGHT;
1781 			break;
1782 		default:	// SVX_HOR_JUSTIFY_LEFT
1783 			eSvxAdjust = SVX_ADJUST_LEFT;
1784 			break;
1785 	}
1786 
1787 	sal_Bool bAsianVertical = pLastPattern &&
1788         ((const SfxBoolItem&)pLastPattern->GetItem( ATTR_STACKED )).GetValue() &&
1789 		((const SfxBoolItem&)pLastPattern->GetItem( ATTR_VERTICAL_ASIAN )).GetValue();
1790 	if ( bAsianVertical )
1791 	{
1792 		//	always edit at top of cell -> LEFT when editing vertically
1793 		eSvxAdjust = SVX_ADJUST_LEFT;
1794 	}
1795 
1796 	pEditDefaults->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
1797 	pEngine->SetDefaults( *pEditDefaults );
1798 
1799     nEditAdjust = sal::static_int_cast<sal_uInt16>(eSvxAdjust);     //! set at ViewData or with PostEditView
1800 
1801 	pEngine->SetVertical( bAsianVertical );
1802 }
1803 
1804 void ScInputHandler::RemoveAdjust()
1805 {
1806 	//	harte Ausrichtungs-Attribute loeschen
1807 
1808 	sal_Bool bUndo = pEngine->IsUndoEnabled();
1809 	if ( bUndo )
1810 		pEngine->EnableUndo( sal_False );
1811 
1812 	//	RemoveParaAttribs removes all paragraph attributes, including EE_PARA_JUST
1813 #if 0
1814 	sal_Bool bChange = sal_False;
1815 	sal_uInt16 nCount = pEngine->GetParagraphCount();
1816 	for (sal_uInt16 i=0; i<nCount; i++)
1817 	{
1818 		const SfxItemSet& rOld = pEngine->GetParaAttribs( i );
1819 		if ( rOld.GetItemState( EE_PARA_JUST ) == SFX_ITEM_SET )
1820 		{
1821 			SfxItemSet aNew( rOld );
1822 			aNew.ClearItem( EE_PARA_JUST );
1823 			pEngine->SetParaAttribs( i, aNew );
1824 			bChange = sal_True;
1825 		}
1826 	}
1827 #endif
1828 
1829 	//	#89403# non-default paragraph attributes (e.g. from clipboard)
1830 	//	must be turned into character attributes
1831 	pEngine->RemoveParaAttribs();
1832 
1833 	if ( bUndo )
1834 		pEngine->EnableUndo( sal_True );
1835 
1836 	// ER 31.08.00  Only called in EnterHandler, don't change view anymore.
1837 #if 0
1838 	if (bChange)
1839 	{
1840 		EditView* pActiveView = pTopView ? pTopView : pTableView;
1841 		pActiveView->ShowCursor( sal_False, sal_True );
1842 	}
1843 #endif
1844 }
1845 
1846 void ScInputHandler::RemoveRangeFinder()
1847 {
1848 	//	pRangeFindList und Farben loeschen
1849 
1850 	pEngine->SetUpdateMode(sal_False);
1851 	sal_uInt16 nCount = pEngine->GetParagraphCount();	// koennte gerade neu eingefuegt worden sein
1852 	for (sal_uInt16 i=0; i<nCount; i++)
1853 		pEngine->QuickRemoveCharAttribs( i, EE_CHAR_COLOR );
1854 	pEngine->SetUpdateMode(sal_True);
1855 
1856 	EditView* pActiveView = pTopView ? pTopView : pTableView;
1857 	pActiveView->ShowCursor( sal_False, sal_True );
1858 
1859 	DeleteRangeFinder();		// loescht die Liste und die Markierungen auf der Tabelle
1860 }
1861 
1862 sal_Bool ScInputHandler::StartTable( sal_Unicode cTyped, sal_Bool bFromCommand )
1863 {
1864 	// returns sal_True if a new edit mode was started
1865 
1866 	sal_Bool bNewTable = sal_False;
1867 
1868 	if (!bModified && ValidCol(aCursorPos.Col()))
1869 	{
1870 		if (pActiveViewSh)
1871 		{
1872 			ImplCreateEditEngine();
1873 			UpdateActiveView();
1874 			SyncViews();
1875 
1876 			ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument();
1877 
1878 			const ScMarkData& rMark = pActiveViewSh->GetViewData()->GetMarkData();
1879 			ScEditableTester aTester;
1880 			if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1881 				aTester.TestSelection( pDoc, rMark );
1882 			else
1883 				aTester.TestSelectedBlock( pDoc, aCursorPos.Col(),aCursorPos.Row(),
1884 												 aCursorPos.Col(),aCursorPos.Row(), rMark );
1885 			if ( aTester.IsEditable() )
1886 			{
1887 				// UpdateMode is enabled again in ScViewData::SetEditEngine (and not needed otherwise)
1888 				pEngine->SetUpdateMode( sal_False );
1889 
1890 				//	Attribute in EditEngine uebernehmen
1891 
1892 				const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(),
1893 																  aCursorPos.Row(),
1894 																  aCursorPos.Tab() );
1895 				if (pPattern != pLastPattern)
1896 				{
1897 					//	Prozent-Format?
1898 
1899 					const SfxItemSet& rAttrSet = pPattern->GetItemSet();
1900 					const SfxPoolItem* pItem;
1901 
1902 					if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALUE_FORMAT, sal_True, &pItem ) )
1903 					{
1904 						sal_uLong nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
1905 						bCellHasPercentFormat = ( NUMBERFORMAT_PERCENT ==
1906 												  pDoc->GetFormatTable()->GetType( nFormat ) );
1907 					}
1908 					else
1909 						bCellHasPercentFormat = sal_False; // Default: kein Prozent
1910 
1911 					//	Gueltigkeit angegeben?
1912 
1913 					if ( SFX_ITEM_SET == rAttrSet.GetItemState( ATTR_VALIDDATA, sal_True, &pItem ) )
1914 						nValidation = ((const SfxUInt32Item*)pItem)->GetValue();
1915 					else
1916 						nValidation = 0;
1917 
1918 					// 	EditEngine Defaults
1919 
1920 					//	Hier auf keinen Fall SetParaAttribs, weil die EditEngine evtl.
1921 					//	schon gefuellt ist (bei Edit-Zellen).
1922 					//	SetParaAttribs wuerde dann den Inhalt aendern
1923 
1924 					//! ER 30.08.00  The SetDefaults is now (since MUST/src602
1925 					//! EditEngine changes) implemented as a SetParaAttribs.
1926 					//! Any problems?
1927 
1928 					pPattern->FillEditItemSet( pEditDefaults );
1929 					pEngine->SetDefaults( *pEditDefaults );
1930 					pLastPattern = pPattern;
1931 					bLastIsSymbol = pPattern->IsSymbolFont();
1932 
1933 					//	Background color must be known for automatic font color.
1934 					//	For transparent cell background, the document background color must be used.
1935 
1936 					Color aBackCol = ((const SvxBrushItem&)
1937 									pPattern->GetItem( ATTR_BACKGROUND )).GetColor();
1938 					ScModule* pScMod = SC_MOD();
1939 					//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
1940 					if ( aBackCol.GetTransparency() > 0 ||
1941 							Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1942                         aBackCol.SetColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1943 					pEngine->SetBackgroundColor( aBackCol );
1944 
1945 					//	Ausrichtung
1946 
1947                     eAttrAdjust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
1948 									GetItem(ATTR_HOR_JUSTIFY)).GetValue();
1949                     if ( eAttrAdjust == SVX_HOR_JUSTIFY_REPEAT &&
1950                          static_cast<const SfxBoolItem&>(pPattern->GetItem(ATTR_LINEBREAK)).GetValue() )
1951                     {
1952                         // #i31843# "repeat" with "line breaks" is treated as default alignment
1953                         eAttrAdjust = SVX_HOR_JUSTIFY_STANDARD;
1954                     }
1955 				}
1956 
1957 				//	UpdateSpellSettings enables online spelling if needed
1958 				//	-> also call if attributes are unchanged
1959 
1960 				UpdateSpellSettings( sal_True );	// uses pLastPattern
1961 
1962 				//	Edit-Engine fuellen
1963 
1964 				String aStr;
1965 				if (bTextValid)
1966 				{
1967 					pEngine->SetText(aCurrentText);
1968 					aStr = aCurrentText;
1969 					bTextValid = sal_False;
1970 					aCurrentText.Erase();
1971 				}
1972 				else
1973 					aStr = GetEditText(pEngine);
1974 
1975 				if (aStr.Len() > 3 && 					// Matrix-Formel ?
1976 					aStr.GetChar(0) == '{' &&
1977 					aStr.GetChar(1) == '=' &&
1978 					aStr.GetChar(aStr.Len()-1) == '}')
1979 				{
1980 					aStr.Erase(0,1);
1981 					aStr.Erase(aStr.Len()-1,1);
1982 					pEngine->SetText(aStr);
1983 					if ( pInputWin )
1984 						pInputWin->SetTextString(aStr);
1985 				}
1986 
1987 				UpdateAdjust( cTyped );
1988 
1989 				if ( bAutoComplete )
1990 					GetColData();
1991 
1992                 if ( ( aStr.GetChar(0) == '=' || aStr.GetChar(0) == '+' || aStr.GetChar(0) == '-' ) &&
1993                      !cTyped && !bCreatingFuncView )
1994 					InitRangeFinder(aStr);				// Formel wird editiert -> RangeFinder
1995 
1996 				bNewTable = sal_True;		//	-> PostEditView-Aufruf
1997 			}
1998 			else
1999 			{
2000 				bProtected = sal_True;
2001 				eMode = SC_INPUT_NONE;
2002 				StopInputWinEngine( sal_True );
2003 				UpdateFormulaMode();
2004 				if ( pActiveViewSh && ( !bFromCommand || !bCommandErrorShown ) )
2005 				{
2006 					//	#97673# Prevent repeated error messages for the same cell from command events
2007 					//	(for keyboard events, multiple messages are wanted).
2008 					//	Set the flag before showing the error message because the command handler
2009 					//	for the next IME command may be called when showing the dialog.
2010 					if ( bFromCommand )
2011 						bCommandErrorShown = sal_True;
2012 
2013 					pActiveViewSh->GetActiveWin()->GrabFocus();
2014 					pActiveViewSh->ErrorMessage(aTester.GetMessageId());
2015 				}
2016 			}
2017 		}
2018 
2019 		if (!bProtected && pInputWin)
2020 			pInputWin->SetOkCancelMode();
2021 	}
2022 
2023 	return bNewTable;
2024 }
2025 
2026 void lcl_SetTopSelection( EditView* pEditView, ESelection& rSel )
2027 {
2028 	DBG_ASSERT( rSel.nStartPara==0 && rSel.nEndPara==0, "SetTopSelection: Para != 0" );
2029 
2030 	EditEngine* pEngine = pEditView->GetEditEngine();
2031 	sal_uInt16 nCount = pEngine->GetParagraphCount();
2032 	if (nCount > 1)
2033 	{
2034 		xub_StrLen nParLen = pEngine->GetTextLen(rSel.nStartPara);
2035 		while (rSel.nStartPos > nParLen && rSel.nStartPara+1 < nCount)
2036 		{
2037 			rSel.nStartPos -= nParLen + 1;			// incl. Leerzeichen vom Umbruch
2038 			nParLen = pEngine->GetTextLen(++rSel.nStartPara);
2039 		}
2040 
2041 		nParLen = pEngine->GetTextLen(rSel.nEndPara);
2042 		while (rSel.nEndPos > nParLen && rSel.nEndPara+1 < nCount)
2043 		{
2044 			rSel.nEndPos -= nParLen + 1;			// incl. Leerzeichen vom Umbruch
2045 			nParLen = pEngine->GetTextLen(++rSel.nEndPara);
2046 		}
2047 	}
2048 
2049 	ESelection aSel = pEditView->GetSelection();
2050 
2051 	if (   rSel.nStartPara != aSel.nStartPara || rSel.nEndPara != aSel.nEndPara
2052 		|| rSel.nStartPos  != aSel.nStartPos  || rSel.nEndPos  != aSel.nEndPos )
2053 		pEditView->SetSelection( rSel );
2054 }
2055 
2056 void ScInputHandler::SyncViews( EditView* pSourceView )
2057 {
2058 	ESelection aSel;
2059 
2060 	if (pSourceView)
2061 	{
2062 		aSel = pSourceView->GetSelection();
2063 		if (pTopView && pTopView != pSourceView)
2064 			pTopView->SetSelection( aSel );
2065 		if (pTableView && pTableView != pSourceView)
2066 			lcl_SetTopSelection( pTableView, aSel );
2067 	}
2068 	else if (pTopView && pTableView)
2069 	{
2070 		aSel = pTopView->GetSelection();
2071 		lcl_SetTopSelection( pTableView, aSel );
2072 	}
2073 }
2074 
2075 IMPL_LINK( ScInputHandler, ModifyHdl, void *, EMPTYARG )
2076 {
2077 	if ( !bInOwnChange && ( eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE ) &&
2078 		 pEngine && pEngine->GetUpdateMode() && pInputWin )
2079 	{
2080 		//	#102745# update input line from ModifyHdl for changes that are not
2081 		//	wrapped by DataChanging/DataChanged calls (like Drag&Drop)
2082 
2083 		String aText = GetEditText(pEngine);
2084 		lcl_RemoveTabs(aText);
2085 		pInputWin->SetTextString(aText);
2086 	}
2087 	return 0;
2088 }
2089 
2090 sal_Bool ScInputHandler::DataChanging( sal_Unicode cTyped, sal_Bool bFromCommand )		// return sal_True = new view created
2091 {
2092 	bInOwnChange = sal_True;				// disable ModifyHdl (reset in DataChanged)
2093 
2094 	if ( eMode == SC_INPUT_NONE )
2095 		return StartTable( cTyped, bFromCommand );
2096 	else
2097 		return sal_False;
2098 }
2099 
2100 void ScInputHandler::DataChanged( sal_Bool bFromTopNotify, sal_Bool bSetModified )
2101 {
2102 	ImplCreateEditEngine();
2103 
2104 	if (eMode==SC_INPUT_NONE)
2105 		eMode = SC_INPUT_TYPE;
2106 
2107 	if ( eMode == SC_INPUT_TOP && pTopView && !bFromTopNotify )
2108 	{
2109 		//	table EditEngine is formatted below, input line needs formatting after paste
2110 		//	#i20282# not when called from the input line's modify handler
2111 		pTopView->GetEditEngine()->QuickFormatDoc( sal_True );
2112 
2113 		//	#i23720# QuickFormatDoc hides the cursor, but can't show it again because it
2114 		//	can't safely access the EditEngine's current view, so the cursor has to be
2115 		//	shown again here.
2116 		pTopView->ShowCursor();
2117 	}
2118 
2119     if (bSetModified)
2120         bModified = sal_True;
2121 	bSelIsRef = sal_False;
2122 
2123 	if ( pRangeFindList && !bInRangeUpdate )
2124 		RemoveRangeFinder();					// Attribute und Markierung loeschen
2125 
2126 	UpdateParenthesis();	//	Hervorhebung der Klammern neu
2127 
2128 	// ER 31.08.00  New SetDefaults sets ParaAttribs, don't clear them away ...
2129 //	RemoveAdjust();		//	#40255# harte Ausrichtungs-Attribute loeschen
2130 
2131 	if (eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE)
2132 	{
2133 		String aText = GetEditText(pEngine);
2134 		lcl_RemoveTabs(aText);
2135 
2136 		if ( pInputWin )
2137 			pInputWin->SetTextString(aText);
2138 	}
2139 
2140 		//	wenn der Cursor vor dem Absatzende steht, werden Teile rechts rausgeschoben
2141 		//	(unabhaengig von eMode)		-> View anpassen!
2142 		//	wenn der Cursor am Ende steht, reicht der Status-Handler an der ViewData
2143 
2144 	//	#93767# first make sure the status handler is called now if the cursor
2145 	//	is outside the visible area
2146 	pEngine->QuickFormatDoc();
2147 
2148 	EditView* pActiveView = pTopView ? pTopView : pTableView;
2149 	if (pActiveView && pActiveViewSh)
2150 	{
2151 		ScViewData* pViewData = pActiveViewSh->GetViewData();
2152 
2153 		sal_Bool bNeedGrow = ( nEditAdjust != SVX_ADJUST_LEFT );		// rechtsbuendig immer
2154 		if (!bNeedGrow)
2155 		{
2156 				//	Cursor vor dem Ende?
2157 			ESelection aSel = pActiveView->GetSelection();
2158 			aSel.Adjust();
2159 			bNeedGrow = ( aSel.nEndPos != pEngine->GetTextLen(aSel.nEndPara) );
2160 		}
2161 		if (!bNeedGrow)
2162 		{
2163 			bNeedGrow = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
2164 		}
2165 		if (bNeedGrow)
2166 		{
2167 			// adjust inplace view
2168 			pViewData->EditGrowY();
2169 			pViewData->EditGrowX();
2170 		}
2171 	}
2172 
2173 	UpdateFormulaMode();
2174 	bTextValid = sal_False;			// Aenderungen sind nur in der Edit-Engine
2175 	bInOwnChange = sal_False;
2176 }
2177 
2178 void ScInputHandler::UpdateFormulaMode()
2179 {
2180 	SfxApplication* pSfxApp = SFX_APP();
2181 
2182     if ( pEngine->GetParagraphCount() == 1 &&
2183          ( pEngine->GetText((sal_uInt16)0).GetChar(0) == '=' ||
2184            pEngine->GetText((sal_uInt16)0).GetChar(0) == '+' ||
2185            pEngine->GetText((sal_uInt16)0).GetChar(0) == '-' ) &&
2186          !bProtected )
2187 	{
2188 		if (!bFormulaMode)
2189 		{
2190 			bFormulaMode = sal_True;
2191 			pRefViewSh = pActiveViewSh;
2192 			pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
2193 			SC_MOD()->SetRefInputHdl(this);
2194 			if (pInputWin)
2195 				pInputWin->SetFormulaMode(sal_True);
2196 
2197 			if ( bAutoComplete )
2198 				GetFormulaData();
2199 
2200 			UpdateParenthesis();
2201 			UpdateAutoCorrFlag();
2202 		}
2203 	}
2204 	else		// ausschalten
2205 	{
2206 		if (bFormulaMode)
2207 		{
2208 			ShowRefFrame();
2209 			bFormulaMode = sal_False;
2210 			pRefViewSh = NULL;
2211 			pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
2212 			SC_MOD()->SetRefInputHdl(NULL);
2213 			if (pInputWin)
2214 				pInputWin->SetFormulaMode(sal_False);
2215 			UpdateAutoCorrFlag();
2216 		}
2217 	}
2218 }
2219 
2220 void ScInputHandler::ShowRefFrame()
2221 {
2222     // #123169# Modifying pActiveViewSh here would interfere with the bInEnterHandler / bRepeat
2223     // checks in NotifyChange, and lead to keeping the wrong value in pActiveViewSh.
2224     // A local variable is used instead.
2225     ScTabViewShell* pVisibleSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
2226     if ( pRefViewSh && pRefViewSh != pVisibleSh )
2227 	{
2228 		sal_Bool bFound = sal_False;
2229 		SfxViewFrame* pRefFrame = pRefViewSh->GetViewFrame();
2230 		SfxViewFrame* pOneFrame = SfxViewFrame::GetFirst();
2231 		while ( pOneFrame && !bFound )
2232 		{
2233 			if ( pOneFrame == pRefFrame )
2234 				bFound = sal_True;
2235 			pOneFrame = SfxViewFrame::GetNext( *pOneFrame );
2236 		}
2237 
2238 		if (bFound)
2239 		{
2240 			//	Hier wird sich darauf verlassen, dass Activate synchron funktioniert
2241 			//	(dabei wird pActiveViewSh umgesetzt)
2242 
2243 			pRefViewSh->SetActive();	// Appear und SetViewFrame
2244 
2245 			//	pLastState wird im NotifyChange aus dem Activate richtig gesetzt
2246 		}
2247 		else
2248 		{
2249 			DBG_ERROR("ViewFrame fuer Referenzeingabe ist nicht mehr da");
2250 		}
2251 	}
2252 }
2253 
2254 void ScInputHandler::RemoveSelection()
2255 {
2256 	EditView* pActiveView = pTopView ? pTopView : pTableView;
2257 	if (!pActiveView)
2258 		return;
2259 
2260 	ESelection aSel = pActiveView->GetSelection();
2261 	aSel.nStartPara = aSel.nEndPara;
2262 	aSel.nStartPos  = aSel.nEndPos;
2263 	if (pTableView)
2264 		pTableView->SetSelection( aSel );
2265 	if (pTopView)
2266 		pTopView->SetSelection( aSel );
2267 }
2268 
2269 void ScInputHandler::InvalidateAttribs()
2270 {
2271 	SfxViewFrame* pViewFrm = SfxViewFrame::Current();
2272 	if (pViewFrm)
2273 	{
2274 		SfxBindings& rBindings = pViewFrm->GetBindings();
2275 
2276 		rBindings.Invalidate( SID_ATTR_CHAR_FONT );
2277 		rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
2278 		rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
2279 
2280 		rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
2281 		rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
2282 		rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
2283 		rBindings.Invalidate( SID_ULINE_VAL_NONE );
2284 		rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
2285 		rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
2286 		rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
2287 
2288 		rBindings.Invalidate( SID_HYPERLINK_GETLINK );
2289 	}
2290 }
2291 
2292 
2293 //
2294 //		--------------- public Methoden --------------------------------------------
2295 //
2296 
2297 void ScInputHandler::SetMode( ScInputMode eNewMode )
2298 {
2299 	if ( eMode == eNewMode )
2300 		return;
2301 
2302 	ImplCreateEditEngine();
2303 
2304 	if (bProtected)
2305 	{
2306 		eMode = SC_INPUT_NONE;
2307 		StopInputWinEngine( sal_True );
2308 		if (pActiveViewSh)
2309 			pActiveViewSh->GetActiveWin()->GrabFocus();
2310 		return;
2311 	}
2312 
2313 	bInOwnChange = sal_True;				// disable ModifyHdl (reset below)
2314 
2315 	ScInputMode eOldMode = eMode;
2316 	eMode = eNewMode;
2317 	if (eOldMode == SC_INPUT_TOP && eNewMode != eOldMode)
2318 		StopInputWinEngine( sal_False );
2319 
2320 	if (eMode==SC_INPUT_TOP || eMode==SC_INPUT_TABLE)
2321 	{
2322 		if (eOldMode == SC_INPUT_NONE)		// not when switching between modes
2323 		{
2324 			if (StartTable(0, sal_False))		// 0 = look at existing document content for text or number
2325 			{
2326 				if (pActiveViewSh)
2327 					pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
2328 			}
2329 		}
2330 
2331 		sal_uInt16 nPara    = pEngine->GetParagraphCount()-1;
2332 		xub_StrLen nLen = pEngine->GetText(nPara).Len();
2333 		sal_uInt16 nCount   = pEngine->GetViewCount();
2334 
2335 		for (sal_uInt16 i=0; i<nCount; i++)
2336 		{
2337 			if ( eMode == SC_INPUT_TABLE && eOldMode == SC_INPUT_TOP )
2338 			{
2339 				//	Selektion bleibt
2340 			}
2341 			else
2342 			{
2343 				pEngine->GetView(i)->
2344 					SetSelection( ESelection( nPara, nLen, nPara, nLen ) );
2345 			}
2346 			pEngine->GetView(i)->ShowCursor(sal_False);
2347 		}
2348 	}
2349 
2350 	UpdateActiveView();
2351 	if (eMode==SC_INPUT_TABLE || eMode==SC_INPUT_TYPE)
2352 	{
2353 		if (pTableView)
2354 			pTableView->SetEditEngineUpdateMode(sal_True);
2355 	}
2356 	else
2357 	{
2358 		if (pTopView)
2359 			pTopView->SetEditEngineUpdateMode(sal_True);
2360 	}
2361 
2362 	if (eNewMode != eOldMode)
2363 		UpdateFormulaMode();
2364 
2365 	bInOwnChange = sal_False;
2366 }
2367 
2368 //----------------------------------------------------------------------------------------
2369 
2370 //	lcl_IsNumber - sal_True, wenn nur Ziffern (dann keine Autokorrektur)
2371 
2372 sal_Bool lcl_IsNumber(const String& rString)
2373 {
2374 	xub_StrLen nLen = rString.Len();
2375 	for (xub_StrLen i=0; i<nLen; i++)
2376 	{
2377 		sal_Unicode c = rString.GetChar(i);
2378 		if ( c < '0' || c > '9' )
2379 			return sal_False;
2380 	}
2381 	return sal_True;
2382 }
2383 
2384 void lcl_SelectionToEnd( EditView* pView )
2385 {
2386     if ( pView )
2387     {
2388         EditEngine* pEngine = pView->GetEditEngine();
2389         sal_uInt16 nParCnt = pEngine->GetParagraphCount();
2390         if ( nParCnt == 0 )
2391             nParCnt = 1;
2392         ESelection aSel( nParCnt-1, pEngine->GetTextLen(nParCnt-1) );   // empty selection, cursor at the end
2393         pView->SetSelection( aSel );
2394     }
2395 }
2396 
2397 void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode )
2398 {
2399 	//	#62806# Bei Makro-Aufrufen fuer Gueltigkeit kann Tod und Teufel passieren,
2400 	//	darum dafuer sorgen, dass EnterHandler nicht verschachtelt gerufen wird:
2401 
2402 	if (bInEnterHandler) return;
2403 	bInEnterHandler = sal_True;
2404 	bInOwnChange = sal_True;				// disable ModifyHdl (reset below)
2405 
2406 	ImplCreateEditEngine();
2407 
2408 	sal_Bool bMatrix = ( nBlockMode == SC_ENTER_MATRIX );
2409 
2410 	SfxApplication*	pSfxApp		= SFX_APP();
2411 	EditTextObject* pObject		= NULL;
2412 	ScPatternAttr*	pCellAttrs	= NULL;
2413 	sal_Bool			bAttrib		= sal_False;	// Formatierung vorhanden ?
2414 	sal_Bool			bForget		= sal_False;	// wegen Gueltigkeit streichen ?
2415 
2416 	String aString = GetEditText(pEngine);
2417 	EditView* pActiveView = pTopView ? pTopView : pTableView;
2418 	if (bModified && pActiveView && aString.Len() && !lcl_IsNumber(aString))
2419 	{
2420         if ( pColumnData && nAutoPos != SCPOS_INVALID )
2421         {
2422             // #i47125# If AutoInput appended something, do the final AutoCorrect
2423             // with the cursor at the end of the input.
2424 
2425             lcl_SelectionToEnd(pTopView);
2426             lcl_SelectionToEnd(pTableView);
2427         }
2428 
2429 		if (pTopView)
2430 			pTopView->CompleteAutoCorrect();	// #59759# CompleteAutoCorrect fuer beide Views
2431 		if (pTableView)
2432 			pTableView->CompleteAutoCorrect();
2433 		aString = GetEditText(pEngine);
2434 	}
2435 	lcl_RemoveTabs(aString);
2436 
2437 	//	Test, ob zulaessig (immer mit einfachem String)
2438 
2439 	if ( bModified && nValidation && pActiveViewSh )
2440 	{
2441 		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
2442 		const ScValidationData*	pData = pDoc->GetValidationEntry( nValidation );
2443 		if (pData && pData->HasErrMsg())
2444 		{
2445             // #i67990# don't use pLastPattern in EnterHandler
2446             const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
2447 			sal_Bool bOk = pData->IsDataValid( aString, *pPattern, aCursorPos );
2448 
2449 			if (!bOk)
2450 			{
2451 				if ( pActiveViewSh )				// falls aus MouseButtonDown gekommen
2452 					pActiveViewSh->StopMarking();	// (die InfoBox verschluckt das MouseButtonUp)
2453 
2454 					//!	es gibt noch Probleme, wenn die Eingabe durch Aktivieren einer
2455 					//!	anderen View ausgeloest wurde
2456 
2457 				Window* pParent = Application::GetDefDialogParent();
2458 				if ( pData->DoError( pParent, aString, aCursorPos ) )
2459 					bForget = sal_True;					// Eingabe nicht uebernehmen
2460 			}
2461 		}
2462 	}
2463 
2464     // check for input into DataPilot table
2465 
2466 	if ( bModified && pActiveViewSh && !bForget )
2467 	{
2468 		ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
2469         ScDPObject* pDPObj = pDoc->GetDPAtCursor( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
2470         if ( pDPObj )
2471         {
2472             // any input within the DataPilot table is either a valid renaming
2473             // or an invalid action - normal cell input is always aborted
2474 
2475             pActiveViewSh->DataPilotInput( aCursorPos, aString );
2476             bForget = sal_True;
2477         }
2478 	}
2479 
2480 	pEngine->CompleteOnlineSpelling();
2481 	sal_Bool bSpellErrors = !bFormulaMode && pEngine->HasOnlineSpellErrors();
2482 	if ( bSpellErrors )
2483 	{
2484 		//	#i3820# If the spell checker flags numerical input as error,
2485 		//	it still has to be treated as number, not EditEngine object.
2486 
2487         if ( pActiveViewSh )
2488 		{
2489 			ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
2490             // #i67990# don't use pLastPattern in EnterHandler
2491             const ScPatternAttr* pPattern = pDoc->GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
2492 			SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
2493 			// without conditional format, as in ScColumn::SetString
2494             sal_uInt32 nFormat = pPattern->GetNumberFormat( pFormatter );
2495 			double nVal;
2496 			if ( pFormatter->IsNumberFormat( aString, nFormat, nVal ) )
2497 			{
2498 				bSpellErrors = sal_False;		// ignore the spelling errors
2499 			}
2500 		}
2501 	}
2502 
2503 	//	After RemoveAdjust, the EditView must not be repainted (has wrong font size etc).
2504 	//	SetUpdateMode must come after CompleteOnlineSpelling.
2505 	//	The view is hidden in any case below (Broadcast).
2506 	pEngine->SetUpdateMode( sal_False );
2507 
2508 	if ( bModified && !bForget )			// was wird eingeben (Text/Objekt) ?
2509 	{
2510 		sal_uInt16 nParCnt = pEngine->GetParagraphCount();
2511 		if ( nParCnt == 0 )
2512 			nParCnt = 1;
2513 		ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) );
2514 		SfxItemSet aOldAttribs = pEngine->GetAttribs( aSel );
2515 		const SfxPoolItem* pItem = NULL;
2516 
2517 		//	find common (cell) attributes before RemoveAdjust
2518 
2519 		if ( pActiveViewSh )
2520 		{
2521 			SfxItemSet* pCommonAttrs = NULL;
2522 			for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END; nId++)
2523 			{
2524 				SfxItemState eState = aOldAttribs.GetItemState( nId, sal_False, &pItem );
2525 				if ( eState == SFX_ITEM_SET &&
2526 						nId != EE_CHAR_ESCAPEMENT && nId != EE_CHAR_PAIRKERNING &&
2527 						nId != EE_CHAR_KERNING && nId != EE_CHAR_XMLATTRIBS &&
2528 							*pItem != pEditDefaults->Get(nId) )
2529 				{
2530 					if ( !pCommonAttrs )
2531 						pCommonAttrs = new SfxItemSet( pEngine->GetEmptyItemSet() );
2532 					pCommonAttrs->Put( *pItem );
2533 				}
2534 			}
2535 
2536 			if ( pCommonAttrs )
2537 			{
2538 				ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocument();
2539 				pCellAttrs = new ScPatternAttr( pDoc->GetPool() );
2540 				pCellAttrs->GetFromEditItemSet( pCommonAttrs );
2541 				delete pCommonAttrs;
2542 			}
2543 		}
2544 
2545 		//	clear ParaAttribs (including adjustment)
2546 
2547 		RemoveAdjust();
2548 
2549 		//	check if EditObject is needed
2550 
2551 		if ( bSpellErrors || nParCnt > 1 )
2552 			bAttrib = sal_True;
2553 		else
2554 		{
2555 			for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && !bAttrib; nId++)
2556 			{
2557 				SfxItemState eState = aOldAttribs.GetItemState( nId, sal_False, &pItem );
2558 				if (eState == SFX_ITEM_DONTCARE)
2559 					bAttrib = sal_True;
2560 				else if (eState == SFX_ITEM_SET)
2561 				{
2562 					//	keep same items in EditEngine as in ScEditAttrTester
2563 					if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
2564 						 nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS )
2565 					{
2566 						if ( *pItem != pEditDefaults->Get(nId) )
2567 							bAttrib = sal_True;
2568 					}
2569 				}
2570 			}
2571 
2572 			//	Feldbefehle enthalten?
2573 
2574 			SfxItemState eFieldState = aOldAttribs.GetItemState( EE_FEATURE_FIELD, sal_False );
2575 			if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
2576 				bAttrib = sal_True;
2577 
2578 			//	not converted characters?
2579 
2580 			SfxItemState eConvState = aOldAttribs.GetItemState( EE_FEATURE_NOTCONV, sal_False );
2581 			if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET )
2582 				bAttrib = sal_True;
2583 
2584 			//	Formeln immer als Formeln erkennen (#38309#)
2585 			//	(der Test vorher ist trotzdem noetig wegen Zell-Attributen)
2586 		}
2587 
2588 		if (bMatrix)
2589 			bAttrib = sal_False;
2590 
2591 		if (bAttrib)
2592 		{
2593 			sal_uLong nCtrl = pEngine->GetControlWord();
2594 			sal_uLong nWantBig = bSpellErrors ? EE_CNTRL_ALLOWBIGOBJS : 0;
2595 			if ( ( nCtrl & EE_CNTRL_ALLOWBIGOBJS ) != nWantBig )
2596 				pEngine->SetControlWord( (nCtrl & ~EE_CNTRL_ALLOWBIGOBJS) | nWantBig );
2597 			pObject = pEngine->CreateTextObject();
2598 		}
2599 		else if (bAutoComplete)			// Gross-/Kleinschreibung anpassen
2600 		{
2601 			if (pColumnData)
2602 				pColumnData->GetExactMatch( aString );
2603 
2604 			//!	effizienter in der Liste suchen (ScUserList, nur einmal ToUpper)
2605 
2606 			sal_uInt16 nIndex;
2607 			ScUserListData* pData = ScGlobal::GetUserList()->GetData(aString);
2608 			if ( pData && pData->GetSubIndex( aString, nIndex ) )
2609 				aString = pData->GetSubStr( nIndex );
2610 		}
2611 	}
2612 
2613 	//	don't rely on ShowRefFrame switching the active view synchronously
2614 	//	execute the function directly on the correct view's bindings instead
2615 	//	pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call
2616 	ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh;
2617 
2618 	if (bFormulaMode)
2619 	{
2620 		ShowRefFrame();
2621 
2622 		if (pExecuteSh)
2623         {
2624 			pExecuteSh->SetTabNo(aCursorPos.Tab());
2625             pExecuteSh->ActiveGrabFocus();
2626         }
2627 
2628 		bFormulaMode = sal_False;
2629 		pSfxApp->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
2630 		SC_MOD()->SetRefInputHdl(NULL);
2631 		if (pInputWin)
2632 			pInputWin->SetFormulaMode(sal_False);
2633 		UpdateAutoCorrFlag();
2634 	}
2635 	pRefViewSh = NULL;			// auch ohne FormulaMode wegen Funktions-AP
2636 	DeleteRangeFinder();
2637 	ResetAutoPar();
2638 
2639 	sal_Bool bOldMod = bModified;
2640 
2641 	bModified = sal_False;
2642 	bSelIsRef = sal_False;
2643 	eMode 	  = SC_INPUT_NONE;
2644 	StopInputWinEngine( sal_True );
2645 
2646     // #123344# Text input (through number formats) or ApplySelectionPattern modify
2647     // the cell's attributes, so pLastPattern is no longer valid
2648     pLastPattern = NULL;
2649 
2650 	if (bOldMod && !bProtected && !bForget)
2651 	{
2652 		//	keine typographische Anfuehrungszeichen in Formeln
2653 
2654 		if ( aString.GetChar(0) == '=' )
2655 		{
2656 			SvxAutoCorrect* pAuto = SvxAutoCorrCfg::Get()->GetAutoCorrect();
2657 			if ( pAuto )
2658 			{
2659 				sal_Unicode cReplace = pAuto->GetStartDoubleQuote();
2660 				if( !cReplace )
2661                     cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkStart().GetChar(0);
2662 				if ( cReplace != '"' )
2663 					aString.SearchAndReplaceAll( cReplace, '"' );
2664 
2665 				cReplace = pAuto->GetEndDoubleQuote();
2666 				if( !cReplace )
2667                     cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkEnd().GetChar(0);
2668 				if ( cReplace != '"' )
2669 					aString.SearchAndReplaceAll( cReplace, '"' );
2670 
2671 				cReplace = pAuto->GetStartSingleQuote();
2672 				if( !cReplace )
2673                     cReplace = ScGlobal::pLocaleData->getQuotationMarkStart().GetChar(0);
2674 				if ( cReplace != '\'' )
2675 					aString.SearchAndReplaceAll( cReplace, '\'' );
2676 
2677 				cReplace = pAuto->GetEndSingleQuote();
2678 				if( !cReplace )
2679                     cReplace = ScGlobal::pLocaleData->getQuotationMarkEnd().GetChar(0);
2680 				if ( cReplace != '\'' )
2681 					aString.SearchAndReplaceAll( cReplace, '\'' );
2682 			}
2683 		}
2684 
2685 		pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW_NOPAINT ) );
2686 
2687 		if ( pExecuteSh )
2688 		{
2689 			SfxBindings& rBindings = pExecuteSh->GetViewFrame()->GetBindings();
2690 
2691 			sal_uInt16 nId = FID_INPUTLINE_ENTER;
2692 			if ( nBlockMode == SC_ENTER_BLOCK )
2693 				nId = FID_INPUTLINE_BLOCK;
2694 			else if ( nBlockMode == SC_ENTER_MATRIX )
2695 				nId = FID_INPUTLINE_MATRIX;
2696 
2697 			ScInputStatusItem aItem( FID_INPUTLINE_STATUS,
2698 									 aCursorPos, aCursorPos, aCursorPos,
2699 									 aString, pObject );
2700 			const SfxPoolItem* aArgs[2];
2701 			aArgs[0] = &aItem;
2702 			aArgs[1] = NULL;
2703 			rBindings.Execute( nId, aArgs );
2704 		}
2705 
2706 		delete pLastState;		// pLastState enthaelt noch den alten Text
2707 		pLastState = NULL;
2708 	}
2709 	else
2710 		pSfxApp->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
2711 
2712 	if ( bOldMod && pExecuteSh && pCellAttrs && !bForget )
2713 	{
2714 		//	mit Eingabe zusammenfassen ?
2715 		pExecuteSh->ApplySelectionPattern( *pCellAttrs, sal_True, sal_True );
2716 		pExecuteSh->AdjustBlockHeight();
2717 	}
2718 
2719 	delete pCellAttrs;
2720 	delete pObject;
2721 
2722 	HideTip();
2723     HideTipBelow();
2724 
2725 	nFormSelStart = nFormSelEnd = 0;
2726 	aFormText.Erase();
2727 
2728 	bInOwnChange = sal_False;
2729 	bInEnterHandler = sal_False;
2730 }
2731 
2732 void ScInputHandler::CancelHandler()
2733 {
2734 	bInOwnChange = sal_True;				// disable ModifyHdl (reset below)
2735 
2736 	ImplCreateEditEngine();
2737 
2738 	bModified = sal_False;
2739 
2740 	//	don't rely on ShowRefFrame switching the active view synchronously
2741 	//	execute the function directly on the correct view's bindings instead
2742 	//	pRefViewSh is reset in ShowRefFrame - get pointer before ShowRefFrame call
2743 	ScTabViewShell* pExecuteSh = pRefViewSh ? pRefViewSh : pActiveViewSh;
2744 
2745 	if (bFormulaMode)
2746 	{
2747 		ShowRefFrame();
2748 		if (pExecuteSh)
2749         {
2750 			pExecuteSh->SetTabNo(aCursorPos.Tab());
2751             pExecuteSh->ActiveGrabFocus();
2752         }
2753 		bFormulaMode = sal_False;
2754 		SFX_APP()->Broadcast( SfxSimpleHint( FID_REFMODECHANGED ) );
2755 		SC_MOD()->SetRefInputHdl(NULL);
2756 		if (pInputWin)
2757 			pInputWin->SetFormulaMode(sal_False);
2758 		UpdateAutoCorrFlag();
2759 	}
2760 	pRefViewSh = NULL;			// auch ohne FormulaMode wegen Funktions-AP
2761 	DeleteRangeFinder();
2762 	ResetAutoPar();
2763 
2764 	eMode = SC_INPUT_NONE;
2765 	StopInputWinEngine( sal_True );
2766 	if (pExecuteSh)
2767 		pExecuteSh->StopEditShell();
2768 
2769 	aCursorPos.Set(MAXCOL+1,0,0);		// Flag, dass ungueltig
2770 	pEngine->SetText(String());
2771 
2772 	if ( !pLastState && pExecuteSh )
2773 		pExecuteSh->UpdateInputHandler( sal_True );		// Status neu holen
2774 	else
2775 		NotifyChange( pLastState, sal_True );
2776 
2777 	nFormSelStart = nFormSelEnd = 0;
2778 	aFormText.Erase();
2779 
2780 	bInOwnChange = sal_False;
2781 }
2782 
2783 sal_Bool ScInputHandler::IsModalMode( SfxObjectShell* pDocSh )
2784 {
2785 	//	Referenzen auf unbenanntes Dokument gehen nicht
2786 
2787 	return bFormulaMode && pRefViewSh
2788 			&& pRefViewSh->GetViewData()->GetDocument()->GetDocumentShell() != pDocSh
2789 			&& !pDocSh->HasName();
2790 }
2791 
2792 void ScInputHandler::AddRefEntry()
2793 {
2794     const sal_Unicode cSep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
2795 	UpdateActiveView();
2796 	if (!pTableView && !pTopView)
2797 		return; 							// z.B. FillMode
2798 
2799 	DataChanging(); 						// kann nicht neu sein
2800 
2801 	RemoveSelection();
2802 	if (pTableView)
2803         pTableView->InsertText( cSep, sal_False );
2804 	if (pTopView)
2805         pTopView->InsertText( cSep, sal_False );
2806 
2807 	DataChanged();
2808 }
2809 
2810 void ScInputHandler::SetReference( const ScRange& rRef, ScDocument* pDoc )
2811 {
2812 	HideTip();
2813 
2814 	sal_Bool bOtherDoc = ( pRefViewSh &&
2815 						pRefViewSh->GetViewData()->GetDocument() != pDoc );
2816 	if (bOtherDoc)
2817 		if (!pDoc->GetDocumentShell()->HasName())
2818 		{
2819 			//	Referenzen auf unbenanntes Dokument gehen nicht
2820 			//	(SetReference sollte dann auch nicht gerufen werden)
2821 
2822 			return;
2823 		}
2824 
2825 	UpdateActiveView();
2826 	if (!pTableView && !pTopView)
2827 		return; 							// z.B. FillMode
2828 
2829 	//	nie das "=" ueberschreiben!
2830 	EditView* pActiveView = pTopView ? pTopView : pTableView;
2831 	ESelection aSel = pActiveView->GetSelection();
2832 	aSel.Adjust();
2833 	if ( aSel.nStartPara == 0 && aSel.nStartPos == 0 )
2834 		return;
2835 
2836 	DataChanging(); 						// kann nicht neu sein
2837 
2838 			//	Selektion umdrehen, falls rueckwaerts (noetig ???)
2839 
2840 	if (pTableView)
2841 	{
2842         ESelection aTabSel = pTableView->GetSelection();
2843         if (aTabSel.nStartPos > aTabSel.nEndPos && aTabSel.nStartPara == aTabSel.nEndPara)
2844 		{
2845             aTabSel.Adjust();
2846             pTableView->SetSelection(aTabSel);
2847 		}
2848 	}
2849 	if (pTopView)
2850 	{
2851         ESelection aTopSel = pTopView->GetSelection();
2852         if (aTopSel.nStartPos > aTopSel.nEndPos && aTopSel.nStartPara == aTopSel.nEndPara)
2853 		{
2854             aTopSel.Adjust();
2855             pTopView->SetSelection(aTopSel);
2856 		}
2857 	}
2858 
2859 	//	String aus Referenz erzeugen
2860 
2861 	String aRefStr;
2862 	const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
2863 	if (bOtherDoc)
2864 	{
2865 		//	Referenz auf anderes Dokument
2866 
2867 		DBG_ASSERT(rRef.aStart.Tab()==rRef.aEnd.Tab(), "nStartTab!=nEndTab");
2868 
2869 		String aTmp;
2870 		rRef.Format( aTmp, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails );		// immer 3d
2871 
2872 		SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
2873         // #i75893# convert escaped URL of the document to something user friendly
2874 //       String aFileName = pObjSh->GetMedium()->GetName();
2875         String aFileName = pObjSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
2876 
2877 		aRefStr = '\'';
2878 		aRefStr += aFileName;
2879 		aRefStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "'#" ));
2880 		aRefStr += aTmp;
2881 	}
2882 	else
2883 	{
2884 		if ( ( rRef.aStart.Tab() != aCursorPos.Tab() ||
2885 				rRef.aStart.Tab() != rRef.aEnd.Tab() ) && pDoc )
2886 			rRef.Format( aRefStr, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails );
2887 		else
2888 			rRef.Format( aRefStr, SCA_VALID, pDoc, aAddrDetails );
2889 	}
2890 
2891 	if (pTableView || pTopView)
2892 	{
2893 		if (pTableView)
2894 			pTableView->InsertText( aRefStr, sal_True );
2895 		if (pTopView)
2896 			pTopView->InsertText( aRefStr, sal_True );
2897 
2898 		DataChanged();
2899 	}
2900 
2901 	bSelIsRef = sal_True;
2902 }
2903 
2904 void ScInputHandler::InsertFunction( const String& rFuncName, sal_Bool bAddPar )
2905 {
2906 	if ( eMode == SC_INPUT_NONE )
2907 	{
2908 		DBG_ERROR("InsertFunction, nicht im Eingabemodus");
2909 		return;
2910 	}
2911 
2912 	UpdateActiveView();
2913 	if (!pTableView && !pTopView)
2914 		return; 							// z.B. FillMode
2915 
2916 	DataChanging(); 						// kann nicht neu sein
2917 
2918 	String aText = rFuncName;
2919 	if (bAddPar)
2920 		aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" ));
2921 
2922 	if (pTableView)
2923 	{
2924 		pTableView->InsertText( aText, sal_False );
2925 		if (bAddPar)
2926 		{
2927 			ESelection aSel = pTableView->GetSelection();
2928 			--aSel.nStartPos;
2929 			--aSel.nEndPos;
2930 			pTableView->SetSelection(aSel);
2931 		}
2932 	}
2933 	if (pTopView)
2934 	{
2935 		pTopView->InsertText( aText, sal_False );
2936 		if (bAddPar)
2937 		{
2938 			ESelection aSel = pTopView->GetSelection();
2939 			--aSel.nStartPos;
2940 			--aSel.nEndPos;
2941 			pTopView->SetSelection(aSel);
2942 		}
2943 	}
2944 
2945 	DataChanged();
2946 
2947 	if (bAddPar)
2948 		AutoParAdded();
2949 }
2950 
2951 void ScInputHandler::ClearText()
2952 {
2953 	if ( eMode == SC_INPUT_NONE )
2954 	{
2955 		DBG_ERROR("ClearText, nicht im Eingabemodus");
2956 		return;
2957 	}
2958 
2959 	UpdateActiveView();
2960 	if (!pTableView && !pTopView)
2961 		return; 							// z.B. FillMode
2962 
2963 	DataChanging(); 						// darf nicht neu sein
2964 
2965 	String aEmpty;
2966 	if (pTableView)
2967 	{
2968 		pTableView->GetEditEngine()->SetText( aEmpty );
2969 		pTableView->SetSelection( ESelection(0,0, 0,0) );
2970 	}
2971 	if (pTopView)
2972 	{
2973 		pTopView->GetEditEngine()->SetText( aEmpty );
2974 		pTopView->SetSelection( ESelection(0,0, 0,0) );
2975 	}
2976 
2977 	DataChanged();
2978 }
2979 
2980 sal_Bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, sal_Bool bStartEdit /* = sal_False */ )
2981 {
2982 	if (!bOptLoaded)
2983 	{
2984 		bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete();
2985 		bOptLoaded = sal_True;
2986 	}
2987 
2988 	KeyCode aCode = rKEvt.GetKeyCode();
2989 	sal_uInt16 nModi  = aCode.GetModifier();
2990 	sal_Bool bShift   = aCode.IsShift();
2991 	sal_Bool bControl = aCode.IsMod1();
2992 	sal_Bool bAlt	  = aCode.IsMod2();
2993 	sal_uInt16 nCode  = aCode.GetCode();
2994 	sal_Unicode nChar = rKEvt.GetCharCode();
2995 
2996 	//	Alt-Return is accepted, everything else with ALT, or CTRL-TAB are not:
2997 	if (( bAlt && !bControl && nCode != KEY_RETURN ) ||
2998 			( bControl && aCode.GetCode() == KEY_TAB ))
2999 		return sal_False;
3000 
3001 	sal_Bool bInputLine = ( eMode==SC_INPUT_TOP );
3002 
3003 	sal_Bool bUsed = sal_False;
3004 	sal_Bool bSkip = sal_False;
3005 	sal_Bool bDoEnter = sal_False;
3006 
3007 	switch ( nCode )
3008 	{
3009 		case KEY_RETURN:
3010 			if (bControl && !bShift && !bInputLine)
3011 				bDoEnter = sal_True;
3012 			else if ( nModi == 0 && nTipVisible && pFormulaData && nAutoPos != SCPOS_INVALID )
3013 			{
3014 				PasteFunctionData();
3015 				bUsed = sal_True;
3016 			}
3017 			else if ( nModi == 0 && nTipVisible && aManualTip.Len() )
3018 			{
3019 				PasteManualTip();
3020 				bUsed = sal_True;
3021 			}
3022 			else
3023 			{
3024 				sal_uInt8 nMode = SC_ENTER_NORMAL;
3025 				if ( bShift && bControl )
3026 					nMode = SC_ENTER_MATRIX;
3027 				else if ( bAlt )
3028 					nMode = SC_ENTER_BLOCK;
3029 				EnterHandler( nMode );
3030 
3031 				if (pActiveViewSh)
3032 					pActiveViewSh->MoveCursorEnter( bShift && !bControl );
3033 
3034 				bUsed = sal_True;
3035 			}
3036 			break;
3037 		case KEY_TAB:
3038 			if (!bControl && !bAlt)
3039 			{
3040 				if ( pFormulaData && nTipVisible && nAutoPos != SCPOS_INVALID )
3041 				{
3042 					//	blaettern
3043 
3044 					NextFormulaEntry( bShift );
3045 				}
3046 				else if ( pColumnData && bUseTab && nAutoPos != SCPOS_INVALID )
3047 				{
3048 					//	in den Eintraegen der AutoEingabe blaettern
3049 
3050 					NextAutoEntry( bShift );
3051 				}
3052 				else
3053 				{
3054 					EnterHandler();
3055 
3056 					//	TabKeyInput gibt auf manchen Rechnern unter W95 Stackueberlaeufe,
3057 					//	darum direkter Aufruf:
3058 					if (pActiveViewSh)
3059 						pActiveViewSh->FindNextUnprot( bShift );
3060 				}
3061 				bUsed = sal_True;
3062 			}
3063 			break;
3064 		case KEY_ESCAPE:
3065 			if ( nTipVisible )
3066 			{
3067 				HideTip();
3068 				bUsed = sal_True;
3069 			}
3070             else if( nTipVisibleSec )
3071             {
3072                 HideTipBelow();
3073                 bUsed = sal_True;
3074             }
3075 			else if (eMode != SC_INPUT_NONE)
3076 			{
3077 				CancelHandler();
3078 				bUsed = sal_True;
3079 			}
3080 			else
3081 				bSkip = sal_True;
3082 			break;
3083 		case KEY_F2:
3084 			if ( !bShift && !bControl && !bAlt && eMode == SC_INPUT_TABLE )
3085 			{
3086 				eMode = SC_INPUT_TYPE;
3087 				bUsed = sal_True;
3088 			}
3089 			break;
3090 	}
3091 
3092 	//	Cursortasten nur ausfuehren, wenn schon im Edit-Modus
3093 	//	z.B. wegen Shift-Ctrl-PageDn (ist nicht als Accelerator definiert)
3094 
3095 	sal_Bool bCursorKey = EditEngine::DoesKeyMoveCursor(rKEvt);
3096 	sal_Bool bInsKey = ( nCode == KEY_INSERT && !nModi );	// Insert wie Cursortasten behandeln
3097 	if ( !bUsed && !bSkip && ( bDoEnter || EditEngine::DoesKeyChangeText(rKEvt) ||
3098 					( eMode != SC_INPUT_NONE && ( bCursorKey || bInsKey ) ) ) )
3099 	{
3100 		HideTip();
3101         HideTipBelow();
3102 
3103 		if (bSelIsRef)
3104 		{
3105 			RemoveSelection();
3106 			bSelIsRef = sal_False;
3107 		}
3108 
3109 		UpdateActiveView();
3110 		sal_Bool bNewView = DataChanging( nChar );
3111 
3112 		if (bProtected)								// Zelle geschuetzt?
3113 			bUsed = sal_True;							// Key-Event nicht weiterleiten
3114 		else										// Aenderungen erlaubt
3115 		{
3116 			if (bNewView )							// neu anlegen
3117 			{
3118 				if (pActiveViewSh)
3119 					pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
3120 				UpdateActiveView();
3121 				if (eMode==SC_INPUT_NONE)
3122 					if (pTableView || pTopView)
3123 					{
3124 						String aStrLoP;
3125 
3126 						if ( bStartEdit && bCellHasPercentFormat && ((nChar >= '0' && nChar <= '9') || nChar == '-') )
3127 							aStrLoP = '%';
3128 
3129 						if (pTableView)
3130 						{
3131 							pTableView->GetEditEngine()->SetText( aStrLoP );
3132 							if ( aStrLoP.Len() )
3133 								pTableView->SetSelection( ESelection(0,0, 0,0) );	// before the '%'
3134 
3135 							// don't call SetSelection if the string is empty anyway,
3136 							// to avoid breaking the bInitial handling in ScViewData::EditGrowY
3137 						}
3138 						if (pTopView)
3139 						{
3140 							pTopView->GetEditEngine()->SetText( aStrLoP );
3141 							if ( aStrLoP.Len() )
3142 								pTopView->SetSelection( ESelection(0,0, 0,0) );		// before the '%'
3143 						}
3144 					}
3145 				SyncViews();
3146 			}
3147 
3148 			if (pTableView || pTopView)
3149 			{
3150 //				pActiveView->SetEditEngineUpdateMode(sal_True); 		//! gibt Muell !!!!
3151 
3152 				if (bDoEnter)
3153 				{
3154 					if (pTableView)
3155 						if( pTableView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) )
3156 							bUsed = sal_True;
3157 					if (pTopView)
3158 						if( pTopView->PostKeyEvent( KeyEvent( CHAR_CR, KeyCode(KEY_RETURN) ) ) )
3159 							bUsed = sal_True;
3160 				}
3161 				else if ( nAutoPar && nChar == ')' && CursorAtClosingPar() )
3162 				{
3163 					SkipClosingPar();
3164 					bUsed = sal_True;
3165 				}
3166 				else
3167 				{
3168 					if (pTableView)
3169 						if ( pTableView->PostKeyEvent( rKEvt ) )
3170 							bUsed = sal_True;
3171 					if (pTopView)
3172 						if ( pTopView->PostKeyEvent( rKEvt ) )
3173 							bUsed = sal_True;
3174 				}
3175 
3176 				//	Auto-Eingabe:
3177 
3178 				if ( bUsed && bAutoComplete )
3179 				{
3180 					bUseTab = sal_False;
3181 					nAutoPos = SCPOS_INVALID;						// do not search further
3182 
3183 					KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
3184 					if ( nChar && nChar != 8 && nChar != 127 &&		// no 'backspace', no 'delete'
3185 						 KEYFUNC_CUT != eFunc)						// and no 'CTRL-X'
3186 					{
3187 						if (bFormulaMode)
3188 							UseFormulaData();
3189 						else
3190 							UseColData();
3191 					}
3192 				}
3193 
3194 				//	when the selection is changed manually or an opening parenthesis
3195 				//	is typed, stop overwriting parentheses
3196 				if ( bUsed && nChar == '(' )
3197 					ResetAutoPar();
3198 
3199 				if ( KEY_INSERT == nCode )
3200 				{
3201 					SfxViewFrame* pViewFrm = SfxViewFrame::Current();
3202 					if (pViewFrm)
3203 						pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
3204 				}
3205                 if( bUsed && bFormulaMode && ( bCursorKey || bInsKey || nCode == KEY_DELETE || nCode == KEY_BACKSPACE ) )
3206                 {
3207                     ShowTipCursor();
3208                 }
3209 			}
3210 
3211             // #i114511# don't count cursor keys as modification
3212             sal_Bool bSetModified = !bCursorKey;
3213             DataChanged(sal_False, bSetModified);  // also calls UpdateParenthesis()
3214 			InvalidateAttribs();		//! in DataChanged ?
3215 		}
3216 	}
3217 
3218 	if (pTopView && eMode != SC_INPUT_NONE)
3219 		SyncViews();
3220 
3221 	return bUsed;
3222 }
3223 
3224 sal_Bool ScInputHandler::InputCommand( const CommandEvent& rCEvt, sal_Bool bForce )
3225 {
3226 	sal_Bool bUsed = sal_False;
3227 
3228 	if ( rCEvt.GetCommand() == COMMAND_CURSORPOS )
3229 	{
3230 		//	#90346# for COMMAND_CURSORPOS, do as little as possible, because
3231 		//	with remote VCL, even a ShowCursor will generate another event.
3232 		if ( eMode != SC_INPUT_NONE )
3233 		{
3234 			UpdateActiveView();
3235 			if (pTableView || pTopView)
3236 			{
3237 				if (pTableView)
3238 					pTableView->Command( rCEvt );
3239 				else if (pTopView)						// call only once
3240 					pTopView->Command( rCEvt );
3241 				bUsed = sal_True;
3242 			}
3243 		}
3244 	}
3245 	else
3246 	{
3247 		if ( bForce || eMode != SC_INPUT_NONE )
3248 		{
3249 			if (!bOptLoaded)
3250 			{
3251 				bAutoComplete = SC_MOD()->GetAppOptions().GetAutoComplete();
3252 				bOptLoaded = sal_True;
3253 			}
3254 
3255 			HideTip();
3256             HideTipBelow();
3257 
3258 			if ( bSelIsRef )
3259 			{
3260 				RemoveSelection();
3261 				bSelIsRef = sal_False;
3262 			}
3263 
3264 			UpdateActiveView();
3265 			sal_Bool bNewView = DataChanging( 0, sal_True );
3266 
3267 			if (bProtected)								// cell protected
3268 				bUsed = sal_True;							// event is used
3269 			else										// changes allowed
3270 			{
3271 				if (bNewView)							// create new edit view
3272 				{
3273 					if (pActiveViewSh)
3274 						pActiveViewSh->GetViewData()->GetDocShell()->PostEditView( pEngine, aCursorPos );
3275 					UpdateActiveView();
3276 					if (eMode==SC_INPUT_NONE)
3277 						if (pTableView || pTopView)
3278 						{
3279 							String aStrLoP;
3280 							if (pTableView)
3281 							{
3282 								pTableView->GetEditEngine()->SetText( aStrLoP );
3283 								pTableView->SetSelection( ESelection(0,0, 0,0) );
3284 							}
3285 							if (pTopView)
3286 							{
3287 								pTopView->GetEditEngine()->SetText( aStrLoP );
3288 								pTopView->SetSelection( ESelection(0,0, 0,0) );
3289 							}
3290 						}
3291 					SyncViews();
3292 				}
3293 
3294 				if (pTableView || pTopView)
3295 				{
3296 					if (pTableView)
3297 						pTableView->Command( rCEvt );
3298 					if (pTopView)
3299 						pTopView->Command( rCEvt );
3300 
3301 					bUsed = sal_True;
3302 
3303 					if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT )
3304 					{
3305 						//	AutoInput after ext text input
3306 
3307 						nAutoPos = SCPOS_INVALID;
3308 						if (bFormulaMode)
3309 							UseFormulaData();
3310 						else
3311 							UseColData();
3312 					}
3313 				}
3314 
3315 				DataChanged();				//	calls UpdateParenthesis()
3316 				InvalidateAttribs();		//! in DataChanged ?
3317 			}
3318 		}
3319 
3320 		if (pTopView && eMode != SC_INPUT_NONE)
3321 			SyncViews();
3322 	}
3323 
3324 	return bUsed;
3325 }
3326 
3327 void ScInputHandler::NotifyChange( const ScInputHdlState* pState,
3328 								   sal_Bool bForce, ScTabViewShell* pSourceSh,
3329                                    sal_Bool bStopEditing)
3330 {
3331 	//	#62806# Wenn der Aufruf aus einem Makro-Aufruf im EnterHandler kommt,
3332 	//	gleich abbrechen und nicht den Status durcheinander bringen
3333 	if (bInEnterHandler)
3334 		return;
3335 
3336 	sal_Bool bRepeat = (pState == pLastState);
3337 	if (!bRepeat && pState && pLastState)
3338         bRepeat = sal::static_int_cast<sal_Bool>(*pState == *pLastState);
3339 	if (bRepeat && !bForce)
3340 		return;
3341 
3342 	bInOwnChange = sal_True;				// disable ModifyHdl (reset below)
3343 
3344 	if ( pState && !pLastState )		// wieder enablen
3345 		bForce = sal_True;
3346 
3347 	sal_Bool bHadObject = pLastState && pLastState->GetEditData();
3348 
3349 	//! Before EditEngine gets eventually created (so it gets the right pools)
3350 	if ( pSourceSh )
3351 		pActiveViewSh = pSourceSh;
3352 	else
3353 		pActiveViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
3354 
3355 	ImplCreateEditEngine();
3356 
3357 	if ( pState != pLastState )
3358 	{
3359 		delete pLastState;
3360 		pLastState = pState ? new ScInputHdlState( *pState ) : NULL;
3361 	}
3362 
3363 	if ( pState && pActiveViewSh )
3364 	{
3365 		ScModule* pScMod = SC_MOD();
3366 
3367 		if ( pState )
3368 		{
3369 			sal_Bool bIgnore = sal_False;
3370 
3371 			//	hier auch fremde Referenzeingabe beruecksichtigen (z.B. Funktions-AP),
3372 			//	FormEditData falls gerade von der Hilfe auf Calc umgeschaltet wird:
3373 
3374 			if ( !bFormulaMode && !pScMod->IsFormulaMode() && !pScMod->GetFormEditData() )
3375 			{
3376 				if ( bModified )
3377 				{
3378 					if (pState->GetPos() != aCursorPos)
3379 					{
3380 						if (!bProtected)
3381 							EnterHandler();
3382 					}
3383 					else
3384 						bIgnore = sal_True;
3385 				}
3386 
3387 				if ( !bIgnore /* || bRepeat */ )
3388 				{
3389 					const ScAddress& 		rSPos	= pState->GetStartPos();
3390 					const ScAddress& 		rEPos	= pState->GetEndPos();
3391 					const EditTextObject*	pData	= pState->GetEditData();
3392 					String					aString = pState->GetString();
3393 					sal_Bool					bTxtMod = sal_False;
3394 					ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
3395 					ScDocument* pDoc = pDocSh->GetDocument();
3396 
3397 					aCursorPos	= pState->GetPos();
3398 
3399 					if ( pData /* || bRepeat */ )
3400 						bTxtMod = sal_True;
3401 					else if ( bHadObject )
3402 						bTxtMod = sal_True;
3403 					else if ( bTextValid )
3404 						bTxtMod = ( aString != aCurrentText );
3405 					else
3406 						bTxtMod = ( aString != GetEditText(pEngine) );
3407 
3408 					if ( bTxtMod || bForce )
3409 					{
3410 						if (pData)
3411 						{
3412 							pEngine->SetText( *pData );
3413 							aString = GetEditText(pEngine);
3414 							lcl_RemoveTabs(aString);
3415 							bTextValid = sal_False;
3416 							aCurrentText.Erase();
3417 						}
3418 						else
3419 						{
3420 							aCurrentText = aString;
3421 							bTextValid = sal_True;				//! erst nur als String merken
3422 						}
3423 
3424 						if ( pInputWin )
3425 							pInputWin->SetTextString(aString);
3426 					}
3427 
3428 					if ( pInputWin )						// Bereichsanzeige
3429 					{
3430 						String aPosStr;
3431 						const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
3432 
3433 						//	Ist der Bereich ein Name?
3434 						//!	per Timer suchen ???
3435 
3436 						if ( pActiveViewSh )
3437 							pActiveViewSh->GetViewData()->GetDocument()->
3438 								GetRangeAtBlock( ScRange( rSPos, rEPos ), &aPosStr );
3439 
3440 						if ( !aPosStr.Len() )			// kein Name -> formatieren
3441 						{
3442 							sal_uInt16 nFlags = 0;
3443 							if( aAddrDetails.eConv == formula::FormulaGrammar::CONV_XL_R1C1 )
3444 								nFlags |= SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE;
3445 							if ( rSPos != rEPos )
3446 							{
3447 								ScRange r(rSPos, rEPos);
3448 								nFlags |= (nFlags << 4);
3449 								r.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
3450 							}
3451 							else
3452 								aCursorPos.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
3453 						}
3454 						//IAccessibility2 Implementation 2009-----
3455 						// Disable the accessible VALUE_CHANGE event
3456 						sal_Bool bIsSuppressed = pInputWin->IsAccessibilityEventsSuppressed(sal_False);
3457 						pInputWin->SetAccessibilityEventsSuppressed(sal_True);
3458 						pInputWin->SetPosString(aPosStr);
3459 						pInputWin->SetAccessibilityEventsSuppressed(bIsSuppressed);
3460 						//-----IAccessibility2 Implementation 2009
3461 						pInputWin->SetSumAssignMode();
3462 					}
3463 
3464                     if (bStopEditing)
3465 					    SFX_APP()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
3466 
3467 					//	As long as the content is not edited, turn off online spelling.
3468 					//	Online spelling is turned back on in StartTable, after setting
3469 					//	the right language from cell attributes.
3470 
3471 					sal_uLong nCntrl = pEngine->GetControlWord();
3472 					if ( nCntrl & EE_CNTRL_ONLINESPELLING )
3473 						pEngine->SetControlWord( nCntrl & ~EE_CNTRL_ONLINESPELLING );
3474 
3475 					bModified = sal_False;
3476 					bSelIsRef = sal_False;
3477 					bProtected = sal_False;
3478 					bCommandErrorShown = sal_False;
3479 				}
3480 			}
3481 		}
3482 
3483 //		bProtected = sal_False;
3484 
3485 		if ( pInputWin)
3486 		{
3487 			if(!pScMod->IsFormulaMode()&& !pScMod->IsRefDialogOpen())	//BugID 54702
3488 			{															//Wenn RefDialog offen, dann nicht enablen
3489 				if ( !pInputWin->IsEnabled())
3490 				{
3491 					pInputWin->Enable();
3492 					if(pDelayTimer )
3493 					{
3494 						DELETEZ( pDelayTimer );
3495 					}
3496 				}
3497 			}
3498 			else if(pScMod->IsRefDialogOpen())
3499 			{									// Da jedes Dokument eigenes InputWin hat, sollte
3500 				if ( !pDelayTimer )				// nochmals Timer gestartet werden, da sonst Ein-
3501 				{								// gabezeile evt. noch aktiv ist.
3502 					pDelayTimer = new Timer;
3503 					pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung
3504 					pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) );
3505 					pDelayTimer->Start();
3506 				}
3507 			}
3508 		}
3509 	}
3510 	else // !pState || !pActiveViewSh
3511 	{
3512 		if ( !pDelayTimer )
3513 		{
3514 			pDelayTimer = new Timer;
3515 			pDelayTimer->SetTimeout( 500 ); // 100ms Verzoegerung
3516 			pDelayTimer->SetTimeoutHdl( LINK( this, ScInputHandler, DelayTimer ) );
3517 			pDelayTimer->Start();
3518 		}
3519 	}
3520 
3521 	HideTip();
3522     HideTipBelow();
3523 	bInOwnChange = sal_False;
3524 }
3525 
3526 void ScInputHandler::UpdateCellAdjust( SvxCellHorJustify eJust )
3527 {
3528     eAttrAdjust = eJust;
3529     UpdateAdjust( 0 );
3530 }
3531 
3532 void ScInputHandler::ResetDelayTimer()
3533 {
3534 	if(pDelayTimer!=NULL)
3535 	{
3536 		DELETEZ( pDelayTimer );
3537 
3538 		if ( pInputWin)
3539 		{
3540 			pInputWin->Enable();
3541 		}
3542 	}
3543 }
3544 
3545 IMPL_LINK( ScInputHandler, DelayTimer, Timer*, pTimer )
3546 {
3547 	if ( pTimer == pDelayTimer )
3548 	{
3549 		DELETEZ( pDelayTimer );
3550 
3551 		if ( NULL == pLastState || SC_MOD()->IsFormulaMode() || SC_MOD()->IsRefDialogOpen())
3552 		{
3553 			//!	new method at ScModule to query if function autopilot is open
3554 
3555 			SfxViewFrame* pViewFrm = SfxViewFrame::Current();
3556 			if ( pViewFrm && pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
3557 			{
3558 				if ( pInputWin)
3559 				{
3560 					pInputWin->EnableButtons( sal_False );
3561 					pInputWin->Disable();
3562 				}
3563 			}
3564 			else if ( !bFormulaMode )	// #39210# Formel auch z.B. bei Hilfe behalten
3565 			{
3566 				bInOwnChange = sal_True;	// disable ModifyHdl (reset below)
3567 
3568 				pActiveViewSh = NULL;
3569 				pEngine->SetText( EMPTY_STRING );
3570 				if ( pInputWin )
3571 				{
3572 					pInputWin->SetPosString( EMPTY_STRING );
3573 					pInputWin->SetTextString( EMPTY_STRING );
3574 					pInputWin->Disable();
3575 				}
3576 
3577 				bInOwnChange = sal_False;
3578 			}
3579 		}
3580 	}
3581 	return 0;
3582 }
3583 
3584 void ScInputHandler::InputSelection( EditView* pView )
3585 {
3586 	SyncViews( pView );
3587     ShowTipCursor();
3588 	UpdateParenthesis();	//	Selektion geaendert -> Klammer-Hervorhebung neu
3589 
3590 	//	when the selection is changed manually, stop overwriting parentheses
3591 	ResetAutoPar();
3592 }
3593 
3594 void ScInputHandler::InputChanged( EditView* pView, sal_Bool bFromNotify )
3595 {
3596 	ESelection aSelection = pView->GetSelection();
3597 
3598 	UpdateActiveView();
3599 
3600 	// #i20282# DataChanged needs to know if this is from the input line's modify handler
3601 	sal_Bool bFromTopNotify = ( bFromNotify && pView == pTopView );
3602 
3603 	sal_Bool bNewView = DataChanging();						//!	kann das hier ueberhaupt sein?
3604 	aCurrentText = pView->GetEditEngine()->GetText();	// auch den String merken
3605 	pEngine->SetText( aCurrentText );
3606 	DataChanged( bFromTopNotify );
3607 	bTextValid = sal_True;		// wird in DataChanged auf sal_False gesetzt
3608 
3609 	if ( pActiveViewSh )
3610 	{
3611 		ScViewData* pViewData = pActiveViewSh->GetViewData();
3612 		if ( bNewView )
3613 			pViewData->GetDocShell()->PostEditView( pEngine, aCursorPos );
3614 
3615 		pViewData->EditGrowY();
3616 		pViewData->EditGrowX();
3617 	}
3618 
3619 	SyncViews( pView );
3620 }
3621 
3622 const String& ScInputHandler::GetEditString()
3623 {
3624 	if (pEngine)
3625 	{
3626 		aCurrentText = pEngine->GetText();		// immer neu aus Engine
3627 		bTextValid = sal_True;
3628 	}
3629 
3630 	return aCurrentText;
3631 }
3632 
3633 Size ScInputHandler::GetTextSize()
3634 {
3635 	Size aSize;
3636 	if ( pEngine )
3637 		aSize = Size( pEngine->CalcTextWidth(), pEngine->GetTextHeight() );
3638 
3639 	return aSize;
3640 }
3641 
3642 sal_Bool ScInputHandler::GetTextAndFields( ScEditEngineDefaulter& rDestEngine )
3643 {
3644 	sal_Bool bRet = sal_False;
3645 	if (pEngine)
3646 	{
3647 		//	Feldbefehle enthalten?
3648 
3649 		sal_uInt16 nParCnt = pEngine->GetParagraphCount();
3650 		SfxItemSet aSet = pEngine->GetAttribs( ESelection(0,0,nParCnt,0) );
3651 		SfxItemState eFieldState = aSet.GetItemState( EE_FEATURE_FIELD, sal_False );
3652 		if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
3653 		{
3654 			//	Inhalt kopieren
3655 
3656 			EditTextObject* pObj = pEngine->CreateTextObject();
3657 			rDestEngine.SetText(*pObj);
3658 			delete pObj;
3659 
3660 			//	Attribute loeschen
3661 
3662 			for (sal_uInt16 i=0; i<nParCnt; i++)
3663 				rDestEngine.QuickRemoveCharAttribs( i );
3664 
3665 			//	Absaetze zusammenfassen
3666 
3667 			while ( nParCnt > 1 )
3668 			{
3669 				xub_StrLen nLen = rDestEngine.GetTextLen( (sal_uInt16)0 );
3670 				ESelection aSel( 0,nLen, 1,0 );
3671 				rDestEngine.QuickInsertText( ' ', aSel );		// Umbruch durch Space ersetzen
3672 				--nParCnt;
3673 			}
3674 
3675 			bRet = sal_True;
3676 		}
3677 	}
3678 	return bRet;
3679 }
3680 
3681 
3682 //------------------------------------------------------------------------
3683 // Methoden fuer FunktionsAutopiloten:
3684 // InputGetSelection, InputSetSelection, InputReplaceSelection, InputGetFormulaStr
3685 //------------------------------------------------------------------------
3686 
3687 void ScInputHandler::InputGetSelection( xub_StrLen& rStart, xub_StrLen& rEnd )
3688 {
3689 	rStart = nFormSelStart;
3690 	rEnd = nFormSelEnd;
3691 }
3692 
3693 //------------------------------------------------------------------------
3694 
3695 EditView* ScInputHandler::GetFuncEditView()
3696 {
3697 	UpdateActiveView();		// wegen pTableView
3698 
3699 	EditView* pView = NULL;
3700 	if ( pInputWin )
3701 	{
3702 		pInputWin->MakeDialogEditView();
3703 		pView = pInputWin->GetEditView();
3704 	}
3705 	else
3706 	{
3707 		if ( eMode != SC_INPUT_TABLE )
3708 		{
3709 			bCreatingFuncView = sal_True;		// RangeFinder nicht anzeigen
3710 			SetMode( SC_INPUT_TABLE );
3711 			bCreatingFuncView = sal_False;
3712 			if ( pTableView )
3713 				pTableView->GetEditEngine()->SetText( EMPTY_STRING );
3714 		}
3715 		pView = pTableView;
3716 	}
3717 
3718 	return pView;
3719 }
3720 
3721 //------------------------------------------------------------------------
3722 
3723 void ScInputHandler::InputSetSelection( xub_StrLen nStart, xub_StrLen nEnd )
3724 {
3725 	if ( nStart <= nEnd )
3726 	{
3727 		nFormSelStart = nStart;
3728 		nFormSelEnd = nEnd;
3729 	}
3730 	else
3731 	{
3732 		nFormSelEnd = nStart;
3733 		nFormSelStart = nEnd;
3734 	}
3735 
3736 	EditView* pView = GetFuncEditView();
3737 	if (pView)
3738 		pView->SetSelection( ESelection(0,nStart, 0,nEnd) );
3739 
3740 	bModified = sal_True;
3741 }
3742 
3743 //------------------------------------------------------------------------
3744 
3745 void ScInputHandler::InputReplaceSelection( const String& rStr )
3746 {
3747 	if (!pRefViewSh)
3748 		pRefViewSh = pActiveViewSh;
3749 
3750 	DBG_ASSERT(nFormSelEnd>=nFormSelStart,"Selektion kaputt...");
3751 
3752 	xub_StrLen nOldLen = nFormSelEnd-nFormSelStart;
3753 	xub_StrLen nNewLen = rStr.Len();
3754 	if (nOldLen)
3755 		aFormText.Erase( nFormSelStart, nOldLen );
3756 	if (nNewLen)
3757 		aFormText.Insert( rStr, nFormSelStart );
3758 	nFormSelEnd = nFormSelStart + nNewLen;
3759 
3760 	EditView* pView = GetFuncEditView();
3761 	if (pView)
3762 	{
3763 		pView->SetEditEngineUpdateMode( sal_False );
3764 //		pView->InsertText( rStr, sal_True );
3765 		pView->GetEditEngine()->SetText( aFormText );
3766 		pView->SetSelection( ESelection(0,nFormSelStart, 0,nFormSelEnd) );
3767 		pView->SetEditEngineUpdateMode( sal_True );
3768 	}
3769 	bModified = sal_True;
3770 }
3771 
3772 //------------------------------------------------------------------------
3773 
3774 String ScInputHandler::InputGetFormulaStr()
3775 {
3776 	return aFormText;	//!	eigene Membervariable?
3777 }
3778 
3779 //========================================================================
3780 //	ScInputHdlState
3781 //========================================================================
3782 
3783 ScInputHdlState::ScInputHdlState( const ScAddress& rCurPos,
3784 								  const ScAddress& rStartPos,
3785 								  const ScAddress& rEndPos,
3786 								  const String& rString,
3787 								  const EditTextObject* pData )
3788 	:   aCursorPos	( rCurPos ),
3789 		aStartPos	( rStartPos ),
3790 		aEndPos		( rEndPos ),
3791 		aString		( rString ),
3792 		pEditData	( pData ? pData->Clone() : NULL )
3793 {
3794 }
3795 
3796 //------------------------------------------------------------------------
3797 
3798 ScInputHdlState::ScInputHdlState( const ScInputHdlState& rCpy )
3799 	:	pEditData	( NULL )
3800 {
3801 	*this = rCpy;
3802 }
3803 
3804 //------------------------------------------------------------------------
3805 
3806 ScInputHdlState::~ScInputHdlState()
3807 {
3808 	delete pEditData;
3809 }
3810 
3811 //------------------------------------------------------------------------
3812 
3813 int ScInputHdlState::operator==( const ScInputHdlState& r ) const
3814 {
3815 	return (    (aStartPos 	== r.aStartPos)
3816 			 &&	(aEndPos   	== r.aEndPos)
3817 			 &&	(aCursorPos == r.aCursorPos)
3818 			 && (aString   	== r.aString)
3819 			 && ScGlobal::EETextObjEqual( pEditData, r.pEditData ) );
3820 }
3821 
3822 //------------------------------------------------------------------------
3823 
3824 ScInputHdlState& ScInputHdlState::operator=( const ScInputHdlState& r )
3825 {
3826 	delete pEditData;
3827 
3828 	aCursorPos	= r.aCursorPos;
3829 	aStartPos	= r.aStartPos;
3830 	aEndPos		= r.aEndPos;
3831 	aString		= r.aString;
3832 	pEditData	= r.pEditData ? r.pEditData->Clone() : NULL;
3833 
3834 	return *this;
3835 }
3836 
3837 
3838 
3839 
3840