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