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