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