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