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