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 #include <algorithm> 28 29 #include "scitems.hxx" 30 #include <editeng/eeitem.hxx> 31 32 #include <sfx2/app.hxx> 33 #include <editeng/adjitem.hxx> 34 #include <editeng/editview.hxx> 35 #include <editeng/editstat.hxx> 36 #include <editeng/frmdiritem.hxx> 37 #include <editeng/lspcitem.hxx> 38 #include <sfx2/bindings.hxx> 39 #include <sfx2/viewfrm.hxx> 40 #include <sfx2/dispatch.hxx> 41 #include <sfx2/event.hxx> 42 #include <sfx2/imgmgr.hxx> 43 #include <stdlib.h> // qsort 44 #include <editeng/scriptspaceitem.hxx> 45 #include <editeng/scripttypeitem.hxx> 46 #include <vcl/cursor.hxx> 47 #include <vcl/help.hxx> 48 #include <svl/stritem.hxx> 49 50 #include "inputwin.hxx" 51 #include "scmod.hxx" 52 #include "uiitems.hxx" 53 #include "global.hxx" 54 #include "scresid.hxx" 55 #include "sc.hrc" 56 #include "globstr.hrc" 57 #include "editutil.hxx" 58 #include "inputhdl.hxx" 59 #include "tabvwsh.hxx" 60 #include "document.hxx" 61 #include "docsh.hxx" 62 #include "appoptio.hxx" 63 #include "rangenam.hxx" 64 #include <formula/compiler.hrc> 65 #include "dbcolect.hxx" 66 #include "rangeutl.hxx" 67 #include "docfunc.hxx" 68 #include "funcdesc.hxx" 69 #include <editeng/fontitem.hxx> 70 #include <com/sun/star/accessibility/XAccessible.hpp> 71 #include "AccessibleEditObject.hxx" 72 #include "AccessibleText.hxx" 73 74 #define TEXT_STARTPOS 3 75 #define THESIZE 1000000 //!!! langt... :-) 76 #define TBX_WINDOW_HEIGHT 22 // in Pixeln - fuer alle Systeme gleich? 77 78 enum ScNameInputType 79 { 80 SC_NAME_INPUT_CELL, 81 SC_NAME_INPUT_RANGE, 82 SC_NAME_INPUT_NAMEDRANGE, 83 SC_NAME_INPUT_DATABASE, 84 SC_NAME_INPUT_ROW, 85 SC_NAME_INPUT_SHEET, 86 SC_NAME_INPUT_DEFINE, 87 SC_NAME_INPUT_BAD_NAME, 88 SC_NAME_INPUT_BAD_SELECTION 89 }; 90 91 92 //================================================================== 93 // class ScInputWindowWrapper 94 //================================================================== 95 96 SFX_IMPL_CHILDWINDOW(ScInputWindowWrapper,FID_INPUTLINE_STATUS) 97 98 ScInputWindowWrapper::ScInputWindowWrapper( Window* pParentP, 99 sal_uInt16 nId, 100 SfxBindings* pBindings, 101 SfxChildWinInfo* /* pInfo */ ) 102 : SfxChildWindow( pParentP, nId ) 103 { 104 ScInputWindow* pWin=new ScInputWindow( pParentP, pBindings ); 105 pWindow = pWin; 106 107 pWin->Show(); 108 109 pWin->SetSizePixel( pWin->CalcWindowSizePixel() ); 110 111 eChildAlignment = SFX_ALIGN_LOWESTTOP; 112 pBindings->Invalidate( FID_TOGGLEINPUTLINE ); 113 } 114 115 // GetInfo fliegt wieder raus, wenn es ein SFX_IMPL_TOOLBOX gibt !!!! 116 117 SfxChildWinInfo __EXPORT ScInputWindowWrapper::GetInfo() const 118 { 119 SfxChildWinInfo aInfo = SfxChildWindow::GetInfo(); 120 return aInfo; 121 } 122 123 //================================================================== 124 125 #define IMAGE(id) pImgMgr->SeekImage(id, bHC) 126 127 //================================================================== 128 // class ScInputWindow 129 //================================================================== 130 131 ScInputWindow::ScInputWindow( Window* pParent, SfxBindings* pBind ) : 132 #ifdef OS2 133 // #37192# ohne WB_CLIPCHILDREN wg. os/2 Paintproblem 134 ToolBox ( pParent, WinBits(WB_BORDER|WB_3DLOOK) ), 135 #else 136 // mit WB_CLIPCHILDREN, sonst Flicker 137 ToolBox ( pParent, WinBits(WB_BORDER|WB_3DLOOK|WB_CLIPCHILDREN) ), 138 #endif 139 aWndPos ( this ), 140 aTextWindow ( this ), 141 pInputHdl ( NULL ), 142 pBindings ( pBind ), 143 aTextOk ( ScResId( SCSTR_QHELP_BTNOK ) ), // nicht immer neu aus Resource 144 aTextCancel ( ScResId( SCSTR_QHELP_BTNCANCEL ) ), 145 aTextSum ( ScResId( SCSTR_QHELP_BTNSUM ) ), 146 aTextEqual ( ScResId( SCSTR_QHELP_BTNEQUAL ) ), 147 bIsOkCancelMode ( sal_False ) 148 { 149 ScModule* pScMod = SC_MOD(); 150 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); 151 152 // #i73615# don't rely on SfxViewShell::Current while constructing the input line 153 // (also for GetInputHdl below) 154 ScTabViewShell* pViewSh = NULL; 155 SfxDispatcher* pDisp = pBind->GetDispatcher(); 156 if ( pDisp ) 157 { 158 SfxViewFrame* pViewFrm = pDisp->GetFrame(); 159 if ( pViewFrm ) 160 pViewSh = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() ); 161 } 162 DBG_ASSERT( pViewSh, "no view shell for input window" ); 163 164 sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 165 166 // Positionsfenster, 3 Buttons, Eingabefenster 167 InsertWindow ( 1, &aWndPos, 0, 0 ); 168 InsertSeparator ( 1 ); 169 InsertItem ( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ), 0, 2 ); 170 InsertItem ( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 ); 171 InsertItem ( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 ); 172 InsertSeparator ( 5 ); 173 InsertWindow ( 7, &aTextWindow, 0, 6 ); 174 175 aWndPos .SetQuickHelpText( ScResId( SCSTR_QHELP_POSWND ) ); 176 aWndPos .SetHelpId ( HID_INSWIN_POS ); 177 aTextWindow.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND ) ); 178 aTextWindow.SetHelpId ( HID_INSWIN_INPUT ); 179 180 // kein SetHelpText, die Hilfetexte kommen aus der Hilfe 181 182 SetItemText ( SID_INPUT_FUNCTION, ScResId( SCSTR_QHELP_BTNCALC ) ); 183 SetHelpId ( SID_INPUT_FUNCTION, HID_INSWIN_CALC ); 184 185 SetItemText ( SID_INPUT_SUM, aTextSum ); 186 SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME ); 187 188 SetItemText ( SID_INPUT_EQUAL, aTextEqual ); 189 SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC ); 190 191 SetHelpId( HID_SC_INPUTWIN ); // fuer die ganze Eingabezeile 192 193 aWndPos .Show(); 194 aTextWindow .Show(); 195 196 pInputHdl = SC_MOD()->GetInputHdl( pViewSh, sal_False ); // use own handler even if ref-handler is set 197 if (pInputHdl) 198 pInputHdl->SetInputWindow( this ); 199 200 if ( pInputHdl && pInputHdl->GetFormString().Len() ) 201 { 202 // Umschalten waehrend der Funktionsautopilot aktiv ist 203 // -> Inhalt des Funktionsautopiloten wieder anzeigen 204 //! auch Selektion (am InputHdl gemerkt) wieder anzeigen 205 206 aTextWindow.SetTextString( pInputHdl->GetFormString() ); 207 } 208 else if ( pInputHdl && pInputHdl->IsInputMode() ) 209 { 210 // wenn waehrend des Editierens die Eingabezeile weg war 211 // (Editieren einer Formel, dann umschalten zu fremdem Dokument/Hilfe), 212 // wieder den gerade editierten Text aus dem InputHandler anzeigen 213 214 aTextWindow.SetTextString( pInputHdl->GetEditString() ); // Text anzeigen 215 if ( pInputHdl->IsTopMode() ) 216 pInputHdl->SetMode( SC_INPUT_TABLE ); // Focus kommt eh nach unten 217 } 218 else if ( pViewSh ) 219 pViewSh->UpdateInputHandler( sal_True ); // unbedingtes Update 220 221 pImgMgr->RegisterToolBox( this ); 222 SetAccessibleName(ScResId(STR_ACC_TOOLBAR_FORMULA)); 223 } 224 225 __EXPORT ScInputWindow::~ScInputWindow() 226 { 227 sal_Bool bDown = ( ScGlobal::pSysLocale == NULL ); // after Clear? 228 229 // if any view's input handler has a pointer to this input window, reset it 230 // (may be several ones, #74522#) 231 // member pInputHdl is not used here 232 233 if ( !bDown ) 234 { 235 TypeId aScType = TYPE(ScTabViewShell); 236 SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType ); 237 while ( pSh ) 238 { 239 ScInputHandler* pHdl = ((ScTabViewShell*)pSh)->GetInputHandler(); 240 if ( pHdl && pHdl->GetInputWindow() == this ) 241 { 242 pHdl->SetInputWindow( NULL ); 243 pHdl->StopInputWinEngine( sal_False ); // #125841# reset pTopView pointer 244 } 245 pSh = SfxViewShell::GetNext( *pSh, &aScType ); 246 } 247 } 248 249 SfxImageManager::GetImageManager( SC_MOD() )->ReleaseToolBox( this ); 250 } 251 252 void ScInputWindow::SetInputHandler( ScInputHandler* pNew ) 253 { 254 // wird im Activate der View gerufen... 255 256 if ( pNew != pInputHdl ) 257 { 258 // Bei Reload (letzte Version) ist pInputHdl der Input-Handler der alten, 259 // geloeschten ViewShell, darum hier auf keinen Fall anfassen! 260 261 pInputHdl = pNew; 262 if (pInputHdl) 263 pInputHdl->SetInputWindow( this ); 264 } 265 } 266 267 sal_Bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const 268 { 269 sal_Bool bSubTotal(sal_False); 270 ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); 271 if ( pViewSh ) 272 { 273 ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); 274 sal_Int32 nRangeCount (pRangeList->Count()); 275 sal_Int32 nRangeIndex (0); 276 while (!bSubTotal && nRangeIndex < nRangeCount) 277 { 278 const ScRange* pRange = pRangeList->GetObject( nRangeIndex ); 279 if( pRange ) 280 { 281 SCTAB nTabEnd(pRange->aEnd.Tab()); 282 SCTAB nTab(pRange->aStart.Tab()); 283 while (!bSubTotal && nTab <= nTabEnd) 284 { 285 SCROW nRowEnd(pRange->aEnd.Row()); 286 SCROW nRow(pRange->aStart.Row()); 287 while (!bSubTotal && nRow <= nRowEnd) 288 { 289 if (pDoc->RowFiltered(nRow, nTab)) 290 bSubTotal = sal_True; 291 else 292 ++nRow; 293 } 294 ++nTab; 295 } 296 } 297 ++nRangeIndex; 298 } 299 300 ScDBCollection* pDBCollection = pDoc->GetDBCollection(); 301 sal_uInt16 nDBCount (pDBCollection->GetCount()); 302 sal_uInt16 nDBIndex (0); 303 while (!bSubTotal && nDBIndex < nDBCount) 304 { 305 ScDBData* pDB = (*pDBCollection)[nDBIndex]; 306 if (pDB && pDB->HasAutoFilter()) 307 { 308 nRangeIndex = 0; 309 while (!bSubTotal && nRangeIndex < nRangeCount) 310 { 311 const ScRange* pRange = pRangeList->GetObject( nRangeIndex ); 312 if( pRange ) 313 { 314 ScRange aDBArea; 315 pDB->GetArea(aDBArea); 316 if (aDBArea.Intersects(*pRange)) 317 bSubTotal = sal_True; 318 } 319 ++nRangeIndex; 320 } 321 } 322 ++nDBIndex; 323 } 324 } 325 return bSubTotal; 326 } 327 328 void __EXPORT ScInputWindow::Select() 329 { 330 ScModule* pScMod = SC_MOD(); 331 ToolBox::Select(); 332 333 switch ( GetCurItemId() ) 334 { 335 case SID_INPUT_FUNCTION: 336 { 337 //! new method at ScModule to query if function autopilot is open 338 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 339 if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ) 340 { 341 pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION, 342 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); 343 344 // die Toolbox wird sowieso disabled, also braucht auch nicht umgeschaltet 345 // zu werden, egal ob's geklappt hat oder nicht 346 // SetOkCancelMode(); 347 } 348 } 349 break; 350 351 case SID_INPUT_CANCEL: 352 pScMod->InputCancelHandler(); 353 SetSumAssignMode(); 354 break; 355 356 case SID_INPUT_OK: 357 pScMod->InputEnterHandler(); 358 SetSumAssignMode(); 359 aTextWindow.Invalidate(); // sonst bleibt Selektion stehen 360 break; 361 362 case SID_INPUT_SUM: 363 { 364 ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); 365 if ( pViewSh ) 366 { 367 const ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData(); 368 if ( rMark.IsMarked() || rMark.IsMultiMarked() ) 369 { 370 ScRangeList aMarkRangeList; 371 rMark.FillRangeListWithMarks( &aMarkRangeList, sal_False ); 372 ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); 373 374 // check if one of the marked ranges is empty 375 bool bEmpty = false; 376 const sal_uLong nCount = aMarkRangeList.Count(); 377 for ( sal_uLong i = 0; i < nCount; ++i ) 378 { 379 const ScRange aRange( *aMarkRangeList.GetObject( i ) ); 380 if ( pDoc->IsBlockEmpty( aRange.aStart.Tab(), 381 aRange.aStart.Col(), aRange.aStart.Row(), 382 aRange.aEnd.Col(), aRange.aEnd.Row() ) ) 383 { 384 bEmpty = true; 385 break; 386 } 387 } 388 389 if ( bEmpty ) 390 { 391 ScRangeList aRangeList; 392 const sal_Bool bDataFound = pViewSh->GetAutoSumArea( aRangeList ); 393 if ( bDataFound ) 394 { 395 const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) ); 396 pViewSh->EnterAutoSum( aRangeList, bSubTotal ); // Block mit Summen fuellen 397 } 398 } 399 else 400 { 401 const sal_Bool bSubTotal( UseSubTotal( &aMarkRangeList ) ); 402 for ( sal_uLong i = 0; i < nCount; ++i ) 403 { 404 const ScRange aRange( *aMarkRangeList.GetObject( i ) ); 405 const bool bSetCursor = ( i == nCount - 1 ? true : false ); 406 const bool bContinue = ( i != 0 ? true : false ); 407 if ( !pViewSh->AutoSum( aRange, bSubTotal, bSetCursor, bContinue ) ) 408 { 409 pViewSh->MarkRange( aRange, sal_False, sal_False ); 410 pViewSh->SetCursor( aRange.aEnd.Col(), aRange.aEnd.Row() ); 411 const ScRangeList aRangeList; 412 const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal ); 413 SetFuncString( aFormula ); 414 break; 415 } 416 } 417 } 418 } 419 else // nur in Eingabezeile einfuegen 420 { 421 ScRangeList aRangeList; 422 const sal_Bool bDataFound = pViewSh->GetAutoSumArea( aRangeList ); 423 const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) ); 424 const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal ); 425 SetFuncString( aFormula ); 426 427 if ( bDataFound && pScMod->IsEditMode() ) 428 { 429 ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh ); 430 if ( pHdl ) 431 { 432 pHdl->InitRangeFinder( aFormula ); 433 434 //! SetSelection am InputHandler ??? 435 //! bSelIsRef setzen ??? 436 const xub_StrLen nOpen = aFormula.Search('('); 437 const xub_StrLen nLen = aFormula.Len(); 438 if ( nOpen != STRING_NOTFOUND && nLen > nOpen ) 439 { 440 sal_uInt8 nAdd(1); 441 if (bSubTotal) 442 nAdd = 3; 443 ESelection aSel(0,nOpen+nAdd,0,nLen-1); 444 EditView* pTableView = pHdl->GetTableView(); 445 if (pTableView) 446 pTableView->SetSelection(aSel); 447 EditView* pTopView = pHdl->GetTopView(); 448 if (pTopView) 449 pTopView->SetSelection(aSel); 450 } 451 } 452 } 453 } 454 } 455 } 456 break; 457 458 case SID_INPUT_EQUAL: 459 { 460 aTextWindow.StartEditEngine(); 461 if ( pScMod->IsEditMode() ) // nicht, wenn z.B. geschuetzt 462 { 463 aTextWindow.GrabFocus(); 464 465 xub_StrLen nStartPos = 1; 466 xub_StrLen nEndPos = 1; 467 468 ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); 469 if ( pViewSh ) 470 { 471 const String& aString = aTextWindow.GetTextString(); 472 const xub_StrLen nLen = aString.Len(); 473 474 ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); 475 CellType eCellType = pDoc->GetCellType( pViewSh->GetViewData()->GetCurPos() ); 476 switch ( eCellType ) 477 { 478 case CELLTYPE_VALUE: 479 { 480 nEndPos = nLen +1; 481 String aNewStr( '=' ); 482 aNewStr.Append( aString ); 483 aTextWindow.SetTextString( aNewStr ); 484 break; 485 } 486 case CELLTYPE_STRING: 487 case CELLTYPE_EDIT: 488 nStartPos = 0; 489 nEndPos = nLen; 490 break; 491 case CELLTYPE_FORMULA: 492 nEndPos = nLen; 493 break; 494 default: 495 aTextWindow.SetTextString( '=' ); 496 break; 497 } 498 } 499 500 EditView* pView = aTextWindow.GetEditView(); 501 if (pView) 502 { 503 pView->SetSelection( ESelection(0, nStartPos, 0, nEndPos) ); 504 pScMod->InputChanged(pView); 505 SetOkCancelMode(); 506 pView->SetEditEngineUpdateMode(sal_True); 507 } 508 } 509 break; 510 } 511 } 512 } 513 514 void __EXPORT ScInputWindow::Resize() 515 { 516 ToolBox::Resize(); 517 518 long nWidth = GetSizePixel().Width(); 519 long nLeft = aTextWindow.GetPosPixel().X(); 520 Size aSize = aTextWindow.GetSizePixel(); 521 522 aSize.Width() = Max( ((long)(nWidth - nLeft - 5)), (long)0 ); 523 aTextWindow.SetSizePixel( aSize ); 524 aTextWindow.Invalidate(); 525 } 526 527 void ScInputWindow::SetFuncString( const String& rString, sal_Bool bDoEdit ) 528 { 529 //! new method at ScModule to query if function autopilot is open 530 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 531 EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ); 532 aTextWindow.StartEditEngine(); 533 534 ScModule* pScMod = SC_MOD(); 535 if ( pScMod->IsEditMode() ) 536 { 537 if ( bDoEdit ) 538 aTextWindow.GrabFocus(); 539 aTextWindow.SetTextString( rString ); 540 EditView* pView = aTextWindow.GetEditView(); 541 if (pView) 542 { 543 xub_StrLen nLen = rString.Len(); 544 545 if ( nLen > 0 ) 546 { 547 nLen--; 548 pView->SetSelection( ESelection( 0, nLen, 0, nLen ) ); 549 } 550 551 pScMod->InputChanged(pView); 552 if ( bDoEdit ) 553 SetOkCancelMode(); // nicht, wenn gleich hinterher Enter/Cancel 554 555 pView->SetEditEngineUpdateMode(sal_True); 556 } 557 } 558 } 559 560 void ScInputWindow::SetPosString( const String& rStr ) 561 { 562 aWndPos.SetPos( rStr ); 563 } 564 565 void ScInputWindow::SetTextString( const String& rString ) 566 { 567 if (rString.Len() <= 32767) 568 aTextWindow.SetTextString(rString); 569 else 570 { 571 String aNew = rString; 572 aNew.Erase(32767); 573 aTextWindow.SetTextString(aNew); 574 } 575 } 576 577 void ScInputWindow::SetOkCancelMode() 578 { 579 //! new method at ScModule to query if function autopilot is open 580 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 581 EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ); 582 583 ScModule* pScMod = SC_MOD(); 584 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); 585 if (!bIsOkCancelMode) 586 { 587 sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 588 589 RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen 590 RemoveItem( 3 ); 591 InsertItem( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ), 0, 3 ); 592 InsertItem( SID_INPUT_OK, IMAGE( SID_INPUT_OK ), 0, 4 ); 593 SetItemText ( SID_INPUT_CANCEL, aTextCancel ); 594 SetHelpId ( SID_INPUT_CANCEL, HID_INSWIN_CANCEL ); 595 SetItemText ( SID_INPUT_OK, aTextOk ); 596 SetHelpId ( SID_INPUT_OK, HID_INSWIN_OK ); 597 bIsOkCancelMode = sal_True; 598 } 599 } 600 601 void ScInputWindow::SetSumAssignMode() 602 { 603 //! new method at ScModule to query if function autopilot is open 604 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 605 EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ); 606 607 ScModule* pScMod = SC_MOD(); 608 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); 609 if (bIsOkCancelMode) 610 { 611 sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 612 613 // SID_INPUT_CANCEL, und SID_INPUT_OK entfernen 614 RemoveItem( 3 ); 615 RemoveItem( 3 ); 616 InsertItem( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 ); 617 InsertItem( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 ); 618 SetItemText ( SID_INPUT_SUM, aTextSum ); 619 SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME ); 620 SetItemText ( SID_INPUT_EQUAL, aTextEqual ); 621 SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC ); 622 bIsOkCancelMode = sal_False; 623 624 SetFormulaMode(sal_False); // kein editieren -> keine Formel 625 } 626 } 627 628 void ScInputWindow::SetFormulaMode( sal_Bool bSet ) 629 { 630 aWndPos.SetFormulaMode(bSet); 631 aTextWindow.SetFormulaMode(bSet); 632 } 633 634 void __EXPORT ScInputWindow::SetText( const String& rString ) 635 { 636 ToolBox::SetText(rString); 637 } 638 639 String __EXPORT ScInputWindow::GetText() const 640 { 641 return ToolBox::GetText(); 642 } 643 644 645 //UNUSED2008-05 EditView* ScInputWindow::ActivateEdit( const String& rText, 646 //UNUSED2008-05 const ESelection& rSel ) 647 //UNUSED2008-05 { 648 //UNUSED2008-05 if ( !aTextWindow.IsInputActive() ) 649 //UNUSED2008-05 { 650 //UNUSED2008-05 aTextWindow.StartEditEngine(); 651 //UNUSED2008-05 aTextWindow.GrabFocus(); 652 //UNUSED2008-05 aTextWindow.SetTextString( rText ); 653 //UNUSED2008-05 aTextWindow.GetEditView()->SetSelection( rSel ); 654 //UNUSED2008-05 } 655 //UNUSED2008-05 656 //UNUSED2008-05 return aTextWindow.GetEditView(); 657 //UNUSED2008-05 } 658 659 sal_Bool ScInputWindow::IsInputActive() 660 { 661 return aTextWindow.IsInputActive(); 662 } 663 664 EditView* ScInputWindow::GetEditView() 665 { 666 return aTextWindow.GetEditView(); 667 } 668 669 void ScInputWindow::MakeDialogEditView() 670 { 671 aTextWindow.MakeDialogEditView(); 672 } 673 674 void ScInputWindow::StopEditEngine( sal_Bool bAll ) 675 { 676 aTextWindow.StopEditEngine( bAll ); 677 } 678 679 void ScInputWindow::TextGrabFocus() 680 { 681 aTextWindow.GrabFocus(); 682 } 683 684 void ScInputWindow::TextInvalidate() 685 { 686 aTextWindow.Invalidate(); 687 } 688 689 void ScInputWindow::SwitchToTextWin() 690 { 691 // used for shift-ctrl-F2 692 693 aTextWindow.StartEditEngine(); 694 if ( SC_MOD()->IsEditMode() ) 695 { 696 aTextWindow.GrabFocus(); 697 EditView* pView = aTextWindow.GetEditView(); 698 if (pView) 699 { 700 xub_StrLen nLen = pView->GetEditEngine()->GetTextLen(0); 701 ESelection aSel( 0, nLen, 0, nLen ); 702 pView->SetSelection( aSel ); // set cursor to end of text 703 } 704 } 705 } 706 707 void ScInputWindow::PosGrabFocus() 708 { 709 aWndPos.GrabFocus(); 710 } 711 712 void ScInputWindow::EnableButtons( sal_Bool bEnable ) 713 { 714 // when enabling buttons, always also enable the input window itself 715 if ( bEnable && !IsEnabled() ) 716 Enable(); 717 718 EnableItem( SID_INPUT_FUNCTION, bEnable ); 719 EnableItem( bIsOkCancelMode ? SID_INPUT_CANCEL : SID_INPUT_SUM, bEnable ); 720 EnableItem( bIsOkCancelMode ? SID_INPUT_OK : SID_INPUT_EQUAL, bEnable ); 721 // Invalidate(); 722 } 723 724 void ScInputWindow::StateChanged( StateChangedType nType ) 725 { 726 ToolBox::StateChanged( nType ); 727 728 if ( nType == STATE_CHANGE_INITSHOW ) Resize(); 729 } 730 731 void ScInputWindow::DataChanged( const DataChangedEvent& rDCEvt ) 732 { 733 if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 734 { 735 // update item images 736 737 ScModule* pScMod = SC_MOD(); 738 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); 739 sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 740 // IMAGE macro uses pScMod, pImgMgr, bHC 741 742 SetItemImage( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ) ); 743 if ( bIsOkCancelMode ) 744 { 745 SetItemImage( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ) ); 746 SetItemImage( SID_INPUT_OK, IMAGE( SID_INPUT_OK ) ); 747 } 748 else 749 { 750 SetItemImage( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ) ); 751 SetItemImage( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ) ); 752 } 753 } 754 755 ToolBox::DataChanged( rDCEvt ); 756 } 757 758 //======================================================================== 759 // Eingabefenster 760 //======================================================================== 761 762 ScTextWnd::ScTextWnd( Window* pParent ) 763 : Window ( pParent, WinBits(WB_HIDE | WB_BORDER) ), 764 DragSourceHelper( this ), 765 pEditEngine ( NULL ), 766 pEditView ( NULL ), 767 bIsInsertMode( sal_True ), 768 bFormulaMode ( sal_False ), 769 bInputMode ( sal_False ) 770 { 771 EnableRTL( sal_False ); // #106269# EditEngine can't be used with VCL EnableRTL 772 773 bIsRTL = GetSettings().GetLayoutRTL(); 774 775 // #79096# always use application font, so a font with cjk chars can be installed 776 Font aAppFont = GetFont(); 777 aTextFont = aAppFont; 778 aTextFont.SetSize( PixelToLogic( aAppFont.GetSize(), MAP_TWIP ) ); // AppFont ist in Pixeln 779 780 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 781 782 Color aBgColor= rStyleSettings.GetWindowColor(); 783 Color aTxtColor= rStyleSettings.GetWindowTextColor(); 784 785 aTextFont.SetTransparent ( sal_True ); 786 aTextFont.SetFillColor ( aBgColor ); 787 //aTextFont.SetColor ( COL_FIELDTEXT ); 788 aTextFont.SetColor (aTxtColor); 789 aTextFont.SetWeight ( WEIGHT_NORMAL ); 790 791 Size aSize(1,TBX_WINDOW_HEIGHT); 792 Size aMinEditSize( Edit::GetMinimumEditSize() ); 793 if( aMinEditSize.Height() > aSize.Height() ) 794 aSize.Height() = aMinEditSize.Height(); 795 SetSizePixel ( aSize ); 796 SetBackground ( aBgColor ); 797 SetLineColor ( COL_BLACK ); 798 SetMapMode ( MAP_TWIP ); 799 SetPointer ( POINTER_TEXT ); 800 } 801 802 __EXPORT ScTextWnd::~ScTextWnd() 803 { 804 while (!maAccTextDatas.empty()) { 805 maAccTextDatas.back()->Dispose(); 806 } 807 delete pEditView; 808 delete pEditEngine; 809 } 810 811 void __EXPORT ScTextWnd::Paint( const Rectangle& rRec ) 812 { 813 if (pEditView) 814 pEditView->Paint( rRec ); 815 else 816 { 817 SetFont( aTextFont ); 818 819 long nDiff = GetOutputSizePixel().Height() 820 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height(); 821 // if (nDiff<2) nDiff=2; // mind. 1 Pixel 822 823 long nStartPos = TEXT_STARTPOS; 824 if ( bIsRTL ) 825 { 826 // right-align 827 nStartPos += GetOutputSizePixel().Width() - 2*TEXT_STARTPOS - 828 LogicToPixel( Size( GetTextWidth( aString ), 0 ) ).Width(); 829 830 // LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include SvxFrameDirectionItem 831 } 832 833 DrawText( PixelToLogic( Point( nStartPos, nDiff/2 ) ), aString ); 834 } 835 } 836 837 void __EXPORT ScTextWnd::Resize() 838 { 839 if (pEditView) 840 { 841 Size aSize = GetOutputSizePixel(); 842 long nDiff = aSize.Height() 843 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height(); 844 845 #ifdef OS2_DOCH_NICHT 846 nDiff-=2; // wird durch 2 geteilt 847 // passt sonst nicht zur normalen Textausgabe 848 #endif 849 850 aSize.Width() -= 2 * TEXT_STARTPOS - 1; 851 852 pEditView->SetOutputArea( 853 PixelToLogic( Rectangle( Point( TEXT_STARTPOS, (nDiff > 0) ? nDiff/2 : 1 ), 854 aSize ) ) ); 855 } 856 } 857 858 void __EXPORT ScTextWnd::MouseMove( const MouseEvent& rMEvt ) 859 { 860 if (pEditView) 861 pEditView->MouseMove( rMEvt ); 862 } 863 864 void __EXPORT ScTextWnd::MouseButtonDown( const MouseEvent& rMEvt ) 865 { 866 if (!HasFocus()) 867 { 868 StartEditEngine(); 869 if ( SC_MOD()->IsEditMode() ) 870 GrabFocus(); 871 } 872 873 if (pEditView) 874 { 875 pEditView->SetEditEngineUpdateMode( sal_True ); 876 pEditView->MouseButtonDown( rMEvt ); 877 } 878 } 879 880 void __EXPORT ScTextWnd::MouseButtonUp( const MouseEvent& rMEvt ) 881 { 882 if (pEditView) 883 if (pEditView->MouseButtonUp( rMEvt )) 884 { 885 if ( rMEvt.IsMiddle() && 886 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION ) 887 { 888 // EditView may have pasted from selection 889 SC_MOD()->InputChanged( pEditView ); 890 } 891 else 892 SC_MOD()->InputSelection( pEditView ); 893 } 894 } 895 896 void __EXPORT ScTextWnd::Command( const CommandEvent& rCEvt ) 897 { 898 bInputMode = sal_True; 899 sal_uInt16 nCommand = rCEvt.GetCommand(); 900 if ( pEditView /* && ( nCommand == COMMAND_STARTDRAG || nCommand == COMMAND_VOICE ) */ ) 901 { 902 ScModule* pScMod = SC_MOD(); 903 ScTabViewShell* pStartViewSh = ScTabViewShell::GetActiveViewShell(); 904 905 // #109441# don't modify the font defaults here - the right defaults are 906 // already set in StartEditEngine when the EditEngine is created 907 908 // #63263# verhindern, dass die EditView beim View-Umschalten wegkommt 909 pScMod->SetInEditCommand( sal_True ); 910 pEditView->Command( rCEvt ); 911 pScMod->SetInEditCommand( sal_False ); 912 913 // #48929# COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde 914 // darum in dem Fall kein InputChanged 915 //! erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten 916 917 if ( nCommand == COMMAND_STARTDRAG ) 918 { 919 // ist auf eine andere View gedraggt worden? 920 ScTabViewShell* pEndViewSh = ScTabViewShell::GetActiveViewShell(); 921 if ( pEndViewSh != pStartViewSh && pStartViewSh != NULL ) 922 { 923 ScViewData* pViewData = pStartViewSh->GetViewData(); 924 ScInputHandler* pHdl = pScMod->GetInputHdl( pStartViewSh ); 925 if ( pHdl && pViewData->HasEditView( pViewData->GetActivePart() ) ) 926 { 927 pHdl->CancelHandler(); 928 pViewData->GetView()->ShowCursor(); // fehlt bei KillEditView, weil nicht aktiv 929 } 930 } 931 } 932 else if ( nCommand == COMMAND_CURSORPOS ) 933 { 934 // don't call InputChanged for COMMAND_CURSORPOS 935 } 936 else if ( nCommand == COMMAND_INPUTLANGUAGECHANGE ) 937 { 938 // #i55929# Font and font size state depends on input language if nothing is selected, 939 // so the slots have to be invalidated when the input language is changed. 940 941 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 942 if (pViewFrm) 943 { 944 SfxBindings& rBindings = pViewFrm->GetBindings(); 945 rBindings.Invalidate( SID_ATTR_CHAR_FONT ); 946 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); 947 } 948 } 949 else 950 SC_MOD()->InputChanged( pEditView ); 951 } 952 else 953 Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern... 954 955 bInputMode = sal_False; 956 } 957 958 void ScTextWnd::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel ) 959 { 960 if ( pEditView ) 961 { 962 CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True ); 963 pEditView->Command( aDragEvent ); 964 965 // handling of d&d to different view (CancelHandler) can't be done here, 966 // because the call returns before d&d is complete. 967 } 968 } 969 970 void __EXPORT ScTextWnd::KeyInput(const KeyEvent& rKEvt) 971 { 972 bInputMode = sal_True; 973 if (!SC_MOD()->InputKeyEvent( rKEvt )) 974 { 975 sal_Bool bUsed = sal_False; 976 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 977 if ( pViewSh ) 978 bUsed = pViewSh->SfxKeyInput(rKEvt); // nur Acceleratoren, keine Eingabe 979 if (!bUsed) 980 Window::KeyInput( rKEvt ); 981 } 982 bInputMode = sal_False; 983 } 984 985 void __EXPORT ScTextWnd::GetFocus() 986 { 987 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 988 if ( pViewSh ) 989 pViewSh->SetFormShellAtTop( sal_False ); // focus in input line -> FormShell no longer on top 990 } 991 992 void __EXPORT ScTextWnd::LoseFocus() 993 { 994 } 995 996 String __EXPORT ScTextWnd::GetText() const 997 { 998 // ueberladen, um per Testtool an den Text heranzukommen 999 1000 if ( pEditEngine ) 1001 return pEditEngine->GetText(); 1002 else 1003 return GetTextString(); 1004 } 1005 1006 void ScTextWnd::SetFormulaMode( sal_Bool bSet ) 1007 { 1008 if ( bSet != bFormulaMode ) 1009 { 1010 bFormulaMode = bSet; 1011 UpdateAutoCorrFlag(); 1012 } 1013 } 1014 1015 void ScTextWnd::UpdateAutoCorrFlag() 1016 { 1017 if ( pEditEngine ) 1018 { 1019 sal_uLong nControl = pEditEngine->GetControlWord(); 1020 sal_uLong nOld = nControl; 1021 if ( bFormulaMode ) 1022 nControl &= ~EE_CNTRL_AUTOCORRECT; // keine Autokorrektur in Formeln 1023 else 1024 nControl |= EE_CNTRL_AUTOCORRECT; // sonst schon 1025 if ( nControl != nOld ) 1026 pEditEngine->SetControlWord( nControl ); 1027 } 1028 } 1029 1030 void lcl_ExtendEditFontAttribs( SfxItemSet& rSet ) 1031 { 1032 const SfxPoolItem& rFontItem = rSet.Get( EE_CHAR_FONTINFO ); 1033 rSet.Put( rFontItem, EE_CHAR_FONTINFO_CJK ); 1034 rSet.Put( rFontItem, EE_CHAR_FONTINFO_CTL ); 1035 const SfxPoolItem& rHeightItem = rSet.Get( EE_CHAR_FONTHEIGHT ); 1036 rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CJK ); 1037 rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CTL ); 1038 const SfxPoolItem& rWeightItem = rSet.Get( EE_CHAR_WEIGHT ); 1039 rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK ); 1040 rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL ); 1041 const SfxPoolItem& rItalicItem = rSet.Get( EE_CHAR_ITALIC ); 1042 rSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK ); 1043 rSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL ); 1044 const SfxPoolItem& rLangItem = rSet.Get( EE_CHAR_LANGUAGE ); 1045 rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK ); 1046 rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL ); 1047 } 1048 1049 void lcl_ModifyRTLDefaults( SfxItemSet& rSet ) 1050 { 1051 rSet.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) ); 1052 1053 // always using rtl writing direction would break formulas 1054 //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) ); 1055 1056 // PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's 1057 // sal_uInt16 values in EditLine), so the text may be wrapped and line spacing must be 1058 // increased to not see the beginning of the next line. 1059 SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL ); 1060 aItem.SetPropLineSpace( 200 ); 1061 rSet.Put( aItem ); 1062 } 1063 1064 void lcl_ModifyRTLVisArea( EditView* pEditView ) 1065 { 1066 Rectangle aVisArea = pEditView->GetVisArea(); 1067 Size aPaper = pEditView->GetEditEngine()->GetPaperSize(); 1068 long nDiff = aPaper.Width() - aVisArea.Right(); 1069 aVisArea.Left() += nDiff; 1070 aVisArea.Right() += nDiff; 1071 pEditView->SetVisArea(aVisArea); 1072 } 1073 1074 void ScTextWnd::StartEditEngine() 1075 { 1076 // #31147# Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren 1077 SfxObjectShell* pObjSh = SfxObjectShell::Current(); 1078 if ( pObjSh && pObjSh->IsInModalMode() ) 1079 return; 1080 1081 if ( !pEditView || !pEditEngine ) 1082 { 1083 ScFieldEditEngine* pNew; 1084 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 1085 if ( pViewSh ) 1086 { 1087 const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); 1088 pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() ); 1089 } 1090 else 1091 pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, sal_True ); 1092 pNew->SetExecuteURL( sal_False ); 1093 pEditEngine = pNew; 1094 1095 pEditEngine->SetUpdateMode( sal_False ); 1096 pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) ); 1097 pEditEngine->SetWordDelimiters( 1098 ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) ); 1099 1100 UpdateAutoCorrFlag(); 1101 1102 { 1103 SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() ); 1104 pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont ); 1105 lcl_ExtendEditFontAttribs( *pSet ); 1106 // turn off script spacing to match DrawText output 1107 pSet->Put( SvxScriptSpaceItem( sal_False, EE_PARA_ASIANCJKSPACING ) ); 1108 if ( bIsRTL ) 1109 lcl_ModifyRTLDefaults( *pSet ); 1110 pEditEngine->SetDefaults( pSet ); 1111 } 1112 1113 // #57254# Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in 1114 // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen. 1115 1116 sal_Bool bFilled = sal_False; 1117 ScInputHandler* pHdl = SC_MOD()->GetInputHdl(); 1118 if ( pHdl ) //! Testen, ob's der richtige InputHdl ist? 1119 bFilled = pHdl->GetTextAndFields( *pEditEngine ); 1120 1121 pEditEngine->SetUpdateMode( sal_True ); 1122 1123 // aString ist die Wahrheit... 1124 if ( bFilled && pEditEngine->GetText() == aString ) 1125 Invalidate(); // Repaint fuer (hinterlegte) Felder 1126 else 1127 pEditEngine->SetText(aString); // dann wenigstens den richtigen Text 1128 1129 pEditView = new EditView( pEditEngine, this ); 1130 pEditView->SetInsertMode(bIsInsertMode); 1131 1132 // Text aus Clipboard wird als ASCII einzeilig uebernommen 1133 sal_uLong n = pEditView->GetControlWord(); 1134 pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE ); 1135 1136 pEditEngine->InsertView( pEditView, EE_APPEND ); 1137 1138 Resize(); 1139 1140 if ( bIsRTL ) 1141 lcl_ModifyRTLVisArea( pEditView ); 1142 1143 pEditEngine->SetModifyHdl(LINK(this, ScTextWnd, NotifyHdl)); 1144 1145 if (!maAccTextDatas.empty()) 1146 maAccTextDatas.back()->StartEdit(); 1147 1148 // as long as EditEngine and DrawText sometimes differ for CTL text, 1149 // repaint now to have the EditEngine's version visible 1150 // SfxObjectShell* pObjSh = SfxObjectShell::Current(); 1151 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 1152 { 1153 ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); // any document 1154 sal_uInt8 nScript = pDoc->GetStringScriptType( aString ); 1155 if ( nScript & SCRIPTTYPE_COMPLEX ) 1156 Invalidate(); 1157 } 1158 } 1159 1160 SC_MOD()->SetInputMode( SC_INPUT_TOP ); 1161 1162 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 1163 if (pViewFrm) 1164 pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT ); 1165 } 1166 1167 IMPL_LINK(ScTextWnd, NotifyHdl, EENotify*, EMPTYARG) 1168 { 1169 if (pEditView && !bInputMode) 1170 { 1171 ScInputHandler* pHdl = SC_MOD()->GetInputHdl(); 1172 1173 // #105354# Use the InputHandler's InOwnChange flag to prevent calling InputChanged 1174 // while an InputHandler method is modifying the EditEngine content 1175 1176 if ( pHdl && !pHdl->IsInOwnChange() ) 1177 pHdl->InputChanged( pEditView, sal_True ); // #i20282# InputChanged must know if called from modify handler 1178 } 1179 1180 return 0; 1181 } 1182 1183 void ScTextWnd::StopEditEngine( sal_Bool bAll ) 1184 { 1185 if (pEditView) 1186 { 1187 if (!maAccTextDatas.empty()) 1188 maAccTextDatas.back()->EndEdit(); 1189 1190 ScModule* pScMod = SC_MOD(); 1191 1192 if (!bAll) 1193 pScMod->InputSelection( pEditView ); 1194 aString = pEditEngine->GetText(); 1195 bIsInsertMode = pEditView->IsInsertMode(); 1196 sal_Bool bSelection = pEditView->HasSelection(); 1197 pEditEngine->SetModifyHdl(Link()); 1198 DELETEZ(pEditView); 1199 DELETEZ(pEditEngine); 1200 1201 if ( pScMod->IsEditMode() && !bAll ) 1202 pScMod->SetInputMode(SC_INPUT_TABLE); 1203 1204 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 1205 if (pViewFrm) 1206 pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT ); 1207 1208 if (bSelection) 1209 Invalidate(); // damit Selektion nicht stehenbleibt 1210 } 1211 } 1212 1213 void ScTextWnd::SetTextString( const String& rNewString ) 1214 { 1215 if ( rNewString != aString ) 1216 { 1217 bInputMode = sal_True; 1218 1219 // Position der Aenderung suchen, nur Rest painten 1220 1221 long nInvPos = 0; 1222 long nStartPos = 0; 1223 long nTextSize = 0; 1224 1225 if (!pEditEngine) 1226 { 1227 sal_Bool bPaintAll; 1228 if ( bIsRTL ) 1229 bPaintAll = sal_True; 1230 else 1231 { 1232 // test if CTL script type is involved 1233 sal_uInt8 nOldScript = 0; 1234 sal_uInt8 nNewScript = 0; 1235 SfxObjectShell* pObjSh = SfxObjectShell::Current(); 1236 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 1237 { 1238 // any document can be used (used only for its break iterator) 1239 ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); 1240 nOldScript = pDoc->GetStringScriptType( aString ); 1241 nNewScript = pDoc->GetStringScriptType( rNewString ); 1242 } 1243 bPaintAll = ( nOldScript & SCRIPTTYPE_COMPLEX ) || ( nNewScript & SCRIPTTYPE_COMPLEX ); 1244 } 1245 1246 if ( bPaintAll ) 1247 { 1248 // if CTL is involved, the whole text has to be redrawn 1249 Invalidate(); 1250 } 1251 else 1252 { 1253 xub_StrLen nDifPos; 1254 if (rNewString.Len() > aString.Len()) 1255 nDifPos = rNewString.Match(aString); 1256 else 1257 nDifPos = aString.Match(rNewString); 1258 1259 long nSize1 = GetTextWidth(aString); 1260 long nSize2 = GetTextWidth(rNewString); 1261 if ( nSize1>0 && nSize2>0 ) 1262 nTextSize = Max( nSize1, nSize2 ); 1263 else 1264 nTextSize = GetOutputSize().Width(); // Ueberlauf 1265 1266 if (nDifPos == STRING_MATCH) 1267 nDifPos = 0; 1268 1269 // -1 wegen Rundung und "A" 1270 Point aLogicStart = PixelToLogic(Point(TEXT_STARTPOS-1,0)); 1271 nStartPos = aLogicStart.X(); 1272 nInvPos = nStartPos; 1273 if (nDifPos) 1274 nInvPos += GetTextWidth(aString,0,nDifPos); 1275 1276 sal_uInt16 nFlags = 0; 1277 if ( nDifPos == aString.Len() ) // only new characters appended 1278 nFlags = INVALIDATE_NOERASE; // then background is already clear 1279 1280 Invalidate( Rectangle( nInvPos, 0, 1281 nStartPos+nTextSize, GetOutputSize().Height()-1 ), 1282 nFlags ); 1283 } 1284 } 1285 else 1286 { 1287 pEditEngine->SetText(rNewString); 1288 } 1289 1290 aString = rNewString; 1291 1292 if (!maAccTextDatas.empty()) 1293 maAccTextDatas.back()->TextChanged(); 1294 1295 bInputMode = sal_False; 1296 } 1297 } 1298 1299 const String& ScTextWnd::GetTextString() const 1300 { 1301 return aString; 1302 } 1303 1304 sal_Bool ScTextWnd::IsInputActive() 1305 { 1306 return HasFocus(); 1307 } 1308 1309 EditView* ScTextWnd::GetEditView() 1310 { 1311 return pEditView; 1312 } 1313 1314 void ScTextWnd::MakeDialogEditView() 1315 { 1316 if ( pEditView ) return; 1317 1318 ScFieldEditEngine* pNew; 1319 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 1320 if ( pViewSh ) 1321 { 1322 const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); 1323 pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() ); 1324 } 1325 else 1326 pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, sal_True ); 1327 pNew->SetExecuteURL( sal_False ); 1328 pEditEngine = pNew; 1329 1330 pEditEngine->SetUpdateMode( sal_False ); 1331 pEditEngine->SetWordDelimiters( pEditEngine->GetWordDelimiters() += '=' ); 1332 pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) ); 1333 1334 SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() ); 1335 pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont ); 1336 lcl_ExtendEditFontAttribs( *pSet ); 1337 if ( bIsRTL ) 1338 lcl_ModifyRTLDefaults( *pSet ); 1339 pEditEngine->SetDefaults( pSet ); 1340 pEditEngine->SetUpdateMode( sal_True ); 1341 1342 pEditView = new EditView( pEditEngine, this ); 1343 pEditEngine->InsertView( pEditView, EE_APPEND ); 1344 1345 Resize(); 1346 1347 if ( bIsRTL ) 1348 lcl_ModifyRTLVisArea( pEditView ); 1349 1350 if (!maAccTextDatas.empty()) 1351 maAccTextDatas.back()->StartEdit(); 1352 } 1353 1354 void ScTextWnd::ImplInitSettings() 1355 { 1356 bIsRTL = GetSettings().GetLayoutRTL(); 1357 1358 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 1359 1360 Color aBgColor= rStyleSettings.GetWindowColor(); 1361 Color aTxtColor= rStyleSettings.GetWindowTextColor(); 1362 1363 aTextFont.SetFillColor ( aBgColor ); 1364 aTextFont.SetColor (aTxtColor); 1365 SetBackground ( aBgColor ); 1366 Invalidate(); 1367 } 1368 1369 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScTextWnd::CreateAccessible() 1370 { 1371 return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL, this, 1372 rtl::OUString(String(ScResId(STR_ACC_EDITLINE_NAME))), 1373 rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), EditLine); 1374 } 1375 1376 void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData ) 1377 { 1378 OSL_ENSURE( ::std::find( maAccTextDatas.begin(), maAccTextDatas.end(), &rTextData ) == maAccTextDatas.end(), 1379 "ScTextWnd::InsertAccessibleTextData - passed object already registered" ); 1380 maAccTextDatas.push_back( &rTextData ); 1381 } 1382 1383 void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData ) 1384 { 1385 AccTextDataVector::iterator aEnd = maAccTextDatas.end(); 1386 AccTextDataVector::iterator aIt = ::std::find( maAccTextDatas.begin(), aEnd, &rTextData ); 1387 OSL_ENSURE( aIt != aEnd, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" ); 1388 if( aIt != aEnd ) 1389 maAccTextDatas.erase( aIt ); 1390 } 1391 1392 // ----------------------------------------------------------------------- 1393 1394 void ScTextWnd::DataChanged( const DataChangedEvent& rDCEvt ) 1395 { 1396 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && 1397 (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 1398 { 1399 ImplInitSettings(); 1400 Invalidate(); 1401 } 1402 else 1403 Window::DataChanged( rDCEvt ); 1404 } 1405 1406 1407 //======================================================================== 1408 // Positionsfenster 1409 //======================================================================== 1410 1411 ScPosWnd::ScPosWnd( Window* pParent ) : 1412 ComboBox ( pParent, WinBits(WB_HIDE | WB_DROPDOWN) ), 1413 pAccel ( NULL ), 1414 nTipVisible ( 0 ), 1415 bFormulaMode( sal_False ) 1416 { 1417 Size aSize( GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:GW99999")) ), 1418 GetTextHeight() ); 1419 aSize.Width() += 25; // ?? 1420 aSize.Height() = CalcWindowSizePixel(11); // Funktionen: 10 MRU + "andere..." 1421 SetSizePixel( aSize ); 1422 1423 FillRangeNames(); 1424 1425 StartListening( *SFX_APP() ); // fuer Navigator-Bereichsnamen-Updates 1426 } 1427 1428 __EXPORT ScPosWnd::~ScPosWnd() 1429 { 1430 EndListening( *SFX_APP() ); 1431 1432 HideTip(); 1433 1434 delete pAccel; 1435 } 1436 1437 void ScPosWnd::SetFormulaMode( sal_Bool bSet ) 1438 { 1439 if ( bSet != bFormulaMode ) 1440 { 1441 bFormulaMode = bSet; 1442 1443 if ( bSet ) 1444 FillFunctions(); 1445 else 1446 FillRangeNames(); 1447 1448 HideTip(); 1449 } 1450 } 1451 1452 void ScPosWnd::SetPos( const String& rPosStr ) 1453 { 1454 if ( aPosStr != rPosStr ) 1455 { 1456 aPosStr = rPosStr; 1457 SetText(aPosStr); 1458 } 1459 } 1460 1461 void ScPosWnd::FillRangeNames() 1462 { 1463 Clear(); 1464 1465 SfxObjectShell* pObjSh = SfxObjectShell::Current(); 1466 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 1467 { 1468 ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); 1469 1470 // per Hand sortieren, weil Funktionen nicht sortiert werden: 1471 1472 ScRangeName* pRangeNames = pDoc->GetRangeName(); 1473 sal_uInt16 nCount = pRangeNames->GetCount(); 1474 if ( nCount > 0 ) 1475 { 1476 sal_uInt16 nValidCount = 0; 1477 ScRange aDummy; 1478 sal_uInt16 i; 1479 for ( i=0; i<nCount; i++ ) 1480 { 1481 ScRangeData* pData = (*pRangeNames)[i]; 1482 if (pData->IsValidReference(aDummy)) 1483 nValidCount++; 1484 } 1485 if ( nValidCount ) 1486 { 1487 ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ]; 1488 sal_uInt16 j; 1489 for ( i=0, j=0; i<nCount; i++ ) 1490 { 1491 ScRangeData* pData = (*pRangeNames)[i]; 1492 if (pData->IsValidReference(aDummy)) 1493 ppSortArray[j++] = pData; 1494 } 1495 #ifndef ICC 1496 qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), 1497 &ScRangeData_QsortNameCompare ); 1498 #else 1499 qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), 1500 ICCQsortNameCompare ); 1501 #endif 1502 for ( j=0; j<nValidCount; j++ ) 1503 InsertEntry( ppSortArray[j]->GetName() ); 1504 delete [] ppSortArray; 1505 } 1506 } 1507 } 1508 SetText(aPosStr); 1509 } 1510 1511 void ScPosWnd::FillFunctions() 1512 { 1513 Clear(); 1514 1515 String aFirstName; 1516 const ScAppOptions& rOpt = SC_MOD()->GetAppOptions(); 1517 sal_uInt16 nMRUCount = rOpt.GetLRUFuncListCount(); 1518 const sal_uInt16* pMRUList = rOpt.GetLRUFuncList(); 1519 if (pMRUList) 1520 { 1521 const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); 1522 sal_uLong nListCount = pFuncList->GetCount(); 1523 for (sal_uInt16 i=0; i<nMRUCount; i++) 1524 { 1525 sal_uInt16 nId = pMRUList[i]; 1526 for (sal_uLong j=0; j<nListCount; j++) 1527 { 1528 const ScFuncDesc* pDesc = pFuncList->GetFunction( j ); 1529 if ( pDesc->nFIndex == nId && pDesc->pFuncName ) 1530 { 1531 InsertEntry( *pDesc->pFuncName ); 1532 if (!aFirstName.Len()) 1533 aFirstName = *pDesc->pFuncName; 1534 break; // nicht weitersuchen 1535 } 1536 } 1537 } 1538 } 1539 1540 //! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen, 1541 //! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann! 1542 1543 // InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) ); 1544 1545 SetText(aFirstName); 1546 } 1547 1548 void __EXPORT ScPosWnd::Notify( SfxBroadcaster&, const SfxHint& rHint ) 1549 { 1550 if ( !bFormulaMode ) 1551 { 1552 // muss die Liste der Bereichsnamen updgedated werden? 1553 1554 if ( rHint.ISA(SfxSimpleHint) ) 1555 { 1556 sal_uLong nHintId = ((SfxSimpleHint&)rHint).GetId(); 1557 if ( nHintId == SC_HINT_AREAS_CHANGED || nHintId == SC_HINT_NAVIGATOR_UPDATEALL) 1558 FillRangeNames(); 1559 } 1560 else if ( rHint.ISA(SfxEventHint) ) 1561 { 1562 sal_uLong nEventId = ((SfxEventHint&)rHint).GetEventId(); 1563 if ( nEventId == SFX_EVENT_ACTIVATEDOC ) 1564 FillRangeNames(); 1565 } 1566 } 1567 } 1568 1569 void ScPosWnd::HideTip() 1570 { 1571 if ( nTipVisible ) 1572 { 1573 Help::HideTip( nTipVisible ); 1574 nTipVisible = 0; 1575 } 1576 } 1577 1578 ScNameInputType lcl_GetInputType( const String& rText ) 1579 { 1580 ScNameInputType eRet = SC_NAME_INPUT_BAD_NAME; // the more general error 1581 1582 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 1583 if ( pViewSh ) 1584 { 1585 ScViewData* pViewData = pViewSh->GetViewData(); 1586 ScDocument* pDoc = pViewData->GetDocument(); 1587 SCTAB nTab = pViewData->GetTabNo(); 1588 formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); 1589 1590 // test in same order as in SID_CURRENTCELL execute 1591 1592 ScRange aRange; 1593 ScAddress aAddress; 1594 ScRangeUtil aRangeUtil; 1595 SCTAB nNameTab; 1596 sal_Int32 nNumeric; 1597 1598 if ( aRange.Parse( rText, pDoc, eConv ) & SCA_VALID ) 1599 eRet = SC_NAME_INPUT_NAMEDRANGE; 1600 else if ( aAddress.Parse( rText, pDoc, eConv ) & SCA_VALID ) 1601 eRet = SC_NAME_INPUT_CELL; 1602 else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_NAMES, eConv ) ) 1603 eRet = SC_NAME_INPUT_NAMEDRANGE; 1604 else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_DBASE, eConv ) ) 1605 eRet = SC_NAME_INPUT_DATABASE; 1606 else if ( ByteString( rText, RTL_TEXTENCODING_ASCII_US ).IsNumericAscii() && 1607 ( nNumeric = rText.ToInt32() ) > 0 && nNumeric <= MAXROW+1 ) 1608 eRet = SC_NAME_INPUT_ROW; 1609 else if ( pDoc->GetTable( rText, nNameTab ) ) 1610 eRet = SC_NAME_INPUT_SHEET; 1611 else if ( ScRangeData::IsNameValid( rText, pDoc ) ) // nothing found, create new range? 1612 { 1613 if ( pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE ) 1614 eRet = SC_NAME_INPUT_DEFINE; 1615 else 1616 eRet = SC_NAME_INPUT_BAD_SELECTION; 1617 } 1618 else 1619 eRet = SC_NAME_INPUT_BAD_NAME; 1620 } 1621 1622 return eRet; 1623 } 1624 1625 void ScPosWnd::Modify() 1626 { 1627 ComboBox::Modify(); 1628 1629 HideTip(); 1630 1631 if ( !IsTravelSelect() && !bFormulaMode ) 1632 { 1633 // determine the action that would be taken for the current input 1634 1635 ScNameInputType eType = lcl_GetInputType( GetText() ); // uses current view 1636 sal_uInt16 nStrId = 0; 1637 switch ( eType ) 1638 { 1639 case SC_NAME_INPUT_CELL: 1640 nStrId = STR_NAME_INPUT_CELL; 1641 break; 1642 case SC_NAME_INPUT_RANGE: 1643 case SC_NAME_INPUT_NAMEDRANGE: 1644 nStrId = STR_NAME_INPUT_RANGE; // named range or range reference 1645 break; 1646 case SC_NAME_INPUT_DATABASE: 1647 nStrId = STR_NAME_INPUT_DBRANGE; 1648 break; 1649 case SC_NAME_INPUT_ROW: 1650 nStrId = STR_NAME_INPUT_ROW; 1651 break; 1652 case SC_NAME_INPUT_SHEET: 1653 nStrId = STR_NAME_INPUT_SHEET; 1654 break; 1655 case SC_NAME_INPUT_DEFINE: 1656 nStrId = STR_NAME_INPUT_DEFINE; 1657 break; 1658 default: 1659 // other cases (error): no tip help 1660 break; 1661 } 1662 1663 if ( nStrId ) 1664 { 1665 // show the help tip at the text cursor position 1666 1667 Window* pWin = GetSubEdit(); 1668 if (!pWin) 1669 pWin = this; 1670 Point aPos; 1671 Cursor* pCur = pWin->GetCursor(); 1672 if (pCur) 1673 aPos = pWin->LogicToPixel( pCur->GetPos() ); 1674 aPos = pWin->OutputToScreenPixel( aPos ); 1675 Rectangle aRect( aPos, aPos ); 1676 1677 String aText = ScGlobal::GetRscString( nStrId ); 1678 sal_uInt16 nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM; 1679 nTipVisible = Help::ShowTip(pWin, aRect, aText, nAlign); 1680 } 1681 } 1682 } 1683 1684 void __EXPORT ScPosWnd::Select() 1685 { 1686 ComboBox::Select(); // in VCL gibt GetText() erst danach den ausgewaehlten Eintrag 1687 1688 HideTip(); 1689 1690 if (!IsTravelSelect()) 1691 DoEnter(); 1692 } 1693 1694 void ScPosWnd::DoEnter() 1695 { 1696 String aText = GetText(); 1697 if ( aText.Len() ) 1698 { 1699 if ( bFormulaMode ) 1700 { 1701 ScModule* pScMod = SC_MOD(); 1702 if ( aText == ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) ) 1703 { 1704 // Funktions-Autopilot 1705 //! mit dem bisher eingegebenen Text weiterarbeiten !!! 1706 1707 //! new method at ScModule to query if function autopilot is open 1708 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 1709 if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ) 1710 pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION, 1711 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); 1712 } 1713 else 1714 { 1715 ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); 1716 ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh ); 1717 if (pHdl) 1718 pHdl->InsertFunction( aText ); 1719 } 1720 } 1721 else 1722 { 1723 // depending on the input, select something or create a new named range 1724 1725 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 1726 if ( pViewSh ) 1727 { 1728 ScNameInputType eType = lcl_GetInputType( aText ); 1729 if ( eType == SC_NAME_INPUT_BAD_NAME || eType == SC_NAME_INPUT_BAD_SELECTION ) 1730 { 1731 sal_uInt16 nId = ( eType == SC_NAME_INPUT_BAD_NAME ) ? STR_NAME_ERROR_NAME : STR_NAME_ERROR_SELECTION; 1732 pViewSh->ErrorMessage( nId ); 1733 } 1734 else if ( eType == SC_NAME_INPUT_DEFINE ) 1735 { 1736 ScViewData* pViewData = pViewSh->GetViewData(); 1737 ScDocShell* pDocShell = pViewData->GetDocShell(); 1738 ScDocument* pDoc = pDocShell->GetDocument(); 1739 ScRangeName* pNames = pDoc->GetRangeName(); 1740 ScRange aSelection; 1741 sal_uInt16 nIndex = 0; 1742 if ( pNames && !pNames->SearchName( aText, nIndex ) && 1743 (pViewData->GetSimpleArea( aSelection ) == SC_MARK_SIMPLE) ) 1744 { 1745 ScRangeName aNewRanges( *pNames ); 1746 ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ); 1747 String aContent; 1748 aSelection.Format( aContent, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() ); 1749 ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor ); 1750 if ( aNewRanges.Insert(pNew) ) 1751 { 1752 ScDocFunc aFunc(*pDocShell); 1753 aFunc.ModifyRangeNames( aNewRanges, sal_False ); 1754 pViewSh->UpdateInputHandler(sal_True); 1755 } 1756 else 1757 delete pNew; // shouldn't happen 1758 } 1759 } 1760 else 1761 { 1762 // for all selection types, excecute the SID_CURRENTCELL slot 1763 1764 SfxStringItem aPosItem( SID_CURRENTCELL, aText ); 1765 SfxBoolItem aUnmarkItem( FN_PARAM_1, sal_True ); // remove existing selection 1766 1767 pViewSh->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL, 1768 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD, 1769 &aPosItem, &aUnmarkItem, 0L ); 1770 } 1771 } 1772 } 1773 } 1774 else 1775 SetText( aPosStr ); 1776 1777 ReleaseFocus_Impl(); 1778 } 1779 1780 long __EXPORT ScPosWnd::Notify( NotifyEvent& rNEvt ) 1781 { 1782 long nHandled = 0; 1783 1784 if ( rNEvt.GetType() == EVENT_KEYINPUT ) 1785 { 1786 const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); 1787 1788 switch ( pKEvt->GetKeyCode().GetCode() ) 1789 { 1790 case KEY_RETURN: 1791 DoEnter(); 1792 nHandled = 1; 1793 break; 1794 1795 case KEY_ESCAPE: 1796 if (nTipVisible) 1797 { 1798 // escape when the tip help is shown: only hide the tip 1799 HideTip(); 1800 } 1801 else 1802 { 1803 if (!bFormulaMode) 1804 SetText( aPosStr ); 1805 ReleaseFocus_Impl(); 1806 } 1807 nHandled = 1; 1808 break; 1809 } 1810 } 1811 1812 if ( !nHandled ) 1813 nHandled = ComboBox::Notify( rNEvt ); 1814 1815 if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 1816 HideTip(); 1817 1818 return nHandled; 1819 } 1820 1821 void ScPosWnd::ReleaseFocus_Impl() 1822 { 1823 HideTip(); 1824 1825 SfxViewShell* pCurSh = SfxViewShell::Current(); 1826 ScInputHandler* pHdl = SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell, pCurSh ) ); 1827 if ( pHdl && pHdl->IsTopMode() ) 1828 { 1829 // Focus wieder in die Eingabezeile? 1830 1831 ScInputWindow* pInputWin = pHdl->GetInputWindow(); 1832 if (pInputWin) 1833 { 1834 pInputWin->TextGrabFocus(); 1835 return; 1836 } 1837 } 1838 1839 // Focus auf die aktive View 1840 1841 if ( pCurSh ) 1842 { 1843 Window* pShellWnd = pCurSh->GetWindow(); 1844 1845 if ( pShellWnd ) 1846 pShellWnd->GrabFocus(); 1847 } 1848 } 1849 1850 1851 1852 1853 1854 1855