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 aTextWindow.SetTextString( '=' ); 465 466 EditView* pView = aTextWindow.GetEditView(); 467 if (pView) 468 { 469 pView->SetSelection( ESelection(0,1, 0,1) ); 470 pScMod->InputChanged(pView); 471 SetOkCancelMode(); 472 pView->SetEditEngineUpdateMode(sal_True); 473 } 474 } 475 break; 476 } 477 } 478 } 479 480 void __EXPORT ScInputWindow::Resize() 481 { 482 ToolBox::Resize(); 483 484 long nWidth = GetSizePixel().Width(); 485 long nLeft = aTextWindow.GetPosPixel().X(); 486 Size aSize = aTextWindow.GetSizePixel(); 487 488 aSize.Width() = Max( ((long)(nWidth - nLeft - 5)), (long)0 ); 489 aTextWindow.SetSizePixel( aSize ); 490 aTextWindow.Invalidate(); 491 } 492 493 void ScInputWindow::SetFuncString( const String& rString, sal_Bool bDoEdit ) 494 { 495 //! new method at ScModule to query if function autopilot is open 496 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 497 EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ); 498 aTextWindow.StartEditEngine(); 499 500 ScModule* pScMod = SC_MOD(); 501 if ( pScMod->IsEditMode() ) 502 { 503 if ( bDoEdit ) 504 aTextWindow.GrabFocus(); 505 aTextWindow.SetTextString( rString ); 506 EditView* pView = aTextWindow.GetEditView(); 507 if (pView) 508 { 509 xub_StrLen nLen = rString.Len(); 510 511 if ( nLen > 0 ) 512 { 513 nLen--; 514 pView->SetSelection( ESelection( 0, nLen, 0, nLen ) ); 515 } 516 517 pScMod->InputChanged(pView); 518 if ( bDoEdit ) 519 SetOkCancelMode(); // nicht, wenn gleich hinterher Enter/Cancel 520 521 pView->SetEditEngineUpdateMode(sal_True); 522 } 523 } 524 } 525 526 void ScInputWindow::SetPosString( const String& rStr ) 527 { 528 aWndPos.SetPos( rStr ); 529 } 530 531 void ScInputWindow::SetTextString( const String& rString ) 532 { 533 if (rString.Len() <= 32767) 534 aTextWindow.SetTextString(rString); 535 else 536 { 537 String aNew = rString; 538 aNew.Erase(32767); 539 aTextWindow.SetTextString(aNew); 540 } 541 } 542 543 void ScInputWindow::SetOkCancelMode() 544 { 545 //! new method at ScModule to query if function autopilot is open 546 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 547 EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ); 548 549 ScModule* pScMod = SC_MOD(); 550 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); 551 if (!bIsOkCancelMode) 552 { 553 sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 554 555 RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen 556 RemoveItem( 3 ); 557 InsertItem( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ), 0, 3 ); 558 InsertItem( SID_INPUT_OK, IMAGE( SID_INPUT_OK ), 0, 4 ); 559 SetItemText ( SID_INPUT_CANCEL, aTextCancel ); 560 SetHelpId ( SID_INPUT_CANCEL, HID_INSWIN_CANCEL ); 561 SetItemText ( SID_INPUT_OK, aTextOk ); 562 SetHelpId ( SID_INPUT_OK, HID_INSWIN_OK ); 563 bIsOkCancelMode = sal_True; 564 } 565 } 566 567 void ScInputWindow::SetSumAssignMode() 568 { 569 //! new method at ScModule to query if function autopilot is open 570 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 571 EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ); 572 573 ScModule* pScMod = SC_MOD(); 574 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); 575 if (bIsOkCancelMode) 576 { 577 sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 578 579 // SID_INPUT_CANCEL, und SID_INPUT_OK entfernen 580 RemoveItem( 3 ); 581 RemoveItem( 3 ); 582 InsertItem( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 ); 583 InsertItem( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 ); 584 SetItemText ( SID_INPUT_SUM, aTextSum ); 585 SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME ); 586 SetItemText ( SID_INPUT_EQUAL, aTextEqual ); 587 SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC ); 588 bIsOkCancelMode = sal_False; 589 590 SetFormulaMode(sal_False); // kein editieren -> keine Formel 591 } 592 } 593 594 void ScInputWindow::SetFormulaMode( sal_Bool bSet ) 595 { 596 aWndPos.SetFormulaMode(bSet); 597 aTextWindow.SetFormulaMode(bSet); 598 } 599 600 void __EXPORT ScInputWindow::SetText( const String& rString ) 601 { 602 ToolBox::SetText(rString); 603 } 604 605 String __EXPORT ScInputWindow::GetText() const 606 { 607 return ToolBox::GetText(); 608 } 609 610 611 //UNUSED2008-05 EditView* ScInputWindow::ActivateEdit( const String& rText, 612 //UNUSED2008-05 const ESelection& rSel ) 613 //UNUSED2008-05 { 614 //UNUSED2008-05 if ( !aTextWindow.IsInputActive() ) 615 //UNUSED2008-05 { 616 //UNUSED2008-05 aTextWindow.StartEditEngine(); 617 //UNUSED2008-05 aTextWindow.GrabFocus(); 618 //UNUSED2008-05 aTextWindow.SetTextString( rText ); 619 //UNUSED2008-05 aTextWindow.GetEditView()->SetSelection( rSel ); 620 //UNUSED2008-05 } 621 //UNUSED2008-05 622 //UNUSED2008-05 return aTextWindow.GetEditView(); 623 //UNUSED2008-05 } 624 625 sal_Bool ScInputWindow::IsInputActive() 626 { 627 return aTextWindow.IsInputActive(); 628 } 629 630 EditView* ScInputWindow::GetEditView() 631 { 632 return aTextWindow.GetEditView(); 633 } 634 635 void ScInputWindow::MakeDialogEditView() 636 { 637 aTextWindow.MakeDialogEditView(); 638 } 639 640 void ScInputWindow::StopEditEngine( sal_Bool bAll ) 641 { 642 aTextWindow.StopEditEngine( bAll ); 643 } 644 645 void ScInputWindow::TextGrabFocus() 646 { 647 aTextWindow.GrabFocus(); 648 } 649 650 void ScInputWindow::TextInvalidate() 651 { 652 aTextWindow.Invalidate(); 653 } 654 655 void ScInputWindow::SwitchToTextWin() 656 { 657 // used for shift-ctrl-F2 658 659 aTextWindow.StartEditEngine(); 660 if ( SC_MOD()->IsEditMode() ) 661 { 662 aTextWindow.GrabFocus(); 663 EditView* pView = aTextWindow.GetEditView(); 664 if (pView) 665 { 666 xub_StrLen nLen = pView->GetEditEngine()->GetTextLen(0); 667 ESelection aSel( 0, nLen, 0, nLen ); 668 pView->SetSelection( aSel ); // set cursor to end of text 669 } 670 } 671 } 672 673 void ScInputWindow::PosGrabFocus() 674 { 675 aWndPos.GrabFocus(); 676 } 677 678 void ScInputWindow::EnableButtons( sal_Bool bEnable ) 679 { 680 // when enabling buttons, always also enable the input window itself 681 if ( bEnable && !IsEnabled() ) 682 Enable(); 683 684 EnableItem( SID_INPUT_FUNCTION, bEnable ); 685 EnableItem( bIsOkCancelMode ? SID_INPUT_CANCEL : SID_INPUT_SUM, bEnable ); 686 EnableItem( bIsOkCancelMode ? SID_INPUT_OK : SID_INPUT_EQUAL, bEnable ); 687 // Invalidate(); 688 } 689 690 void ScInputWindow::StateChanged( StateChangedType nType ) 691 { 692 ToolBox::StateChanged( nType ); 693 694 if ( nType == STATE_CHANGE_INITSHOW ) Resize(); 695 } 696 697 void ScInputWindow::DataChanged( const DataChangedEvent& rDCEvt ) 698 { 699 if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 700 { 701 // update item images 702 703 ScModule* pScMod = SC_MOD(); 704 SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod ); 705 sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 706 // IMAGE macro uses pScMod, pImgMgr, bHC 707 708 SetItemImage( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ) ); 709 if ( bIsOkCancelMode ) 710 { 711 SetItemImage( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ) ); 712 SetItemImage( SID_INPUT_OK, IMAGE( SID_INPUT_OK ) ); 713 } 714 else 715 { 716 SetItemImage( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ) ); 717 SetItemImage( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ) ); 718 } 719 } 720 721 ToolBox::DataChanged( rDCEvt ); 722 } 723 724 //======================================================================== 725 // Eingabefenster 726 //======================================================================== 727 728 ScTextWnd::ScTextWnd( Window* pParent ) 729 : Window ( pParent, WinBits(WB_HIDE | WB_BORDER) ), 730 DragSourceHelper( this ), 731 pEditEngine ( NULL ), 732 pEditView ( NULL ), 733 bIsInsertMode( sal_True ), 734 bFormulaMode ( sal_False ), 735 bInputMode ( sal_False ) 736 { 737 EnableRTL( sal_False ); // #106269# EditEngine can't be used with VCL EnableRTL 738 739 bIsRTL = GetSettings().GetLayoutRTL(); 740 741 // #79096# always use application font, so a font with cjk chars can be installed 742 Font aAppFont = GetFont(); 743 aTextFont = aAppFont; 744 aTextFont.SetSize( PixelToLogic( aAppFont.GetSize(), MAP_TWIP ) ); // AppFont ist in Pixeln 745 746 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 747 748 Color aBgColor= rStyleSettings.GetWindowColor(); 749 Color aTxtColor= rStyleSettings.GetWindowTextColor(); 750 751 aTextFont.SetTransparent ( sal_True ); 752 aTextFont.SetFillColor ( aBgColor ); 753 //aTextFont.SetColor ( COL_FIELDTEXT ); 754 aTextFont.SetColor (aTxtColor); 755 aTextFont.SetWeight ( WEIGHT_NORMAL ); 756 757 Size aSize(1,TBX_WINDOW_HEIGHT); 758 Size aMinEditSize( Edit::GetMinimumEditSize() ); 759 if( aMinEditSize.Height() > aSize.Height() ) 760 aSize.Height() = aMinEditSize.Height(); 761 SetSizePixel ( aSize ); 762 SetBackground ( aBgColor ); 763 SetLineColor ( COL_BLACK ); 764 SetMapMode ( MAP_TWIP ); 765 SetPointer ( POINTER_TEXT ); 766 } 767 768 __EXPORT ScTextWnd::~ScTextWnd() 769 { 770 while (!maAccTextDatas.empty()) { 771 maAccTextDatas.back()->Dispose(); 772 } 773 delete pEditView; 774 delete pEditEngine; 775 } 776 777 void __EXPORT ScTextWnd::Paint( const Rectangle& rRec ) 778 { 779 if (pEditView) 780 pEditView->Paint( rRec ); 781 else 782 { 783 SetFont( aTextFont ); 784 785 long nDiff = GetOutputSizePixel().Height() 786 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height(); 787 // if (nDiff<2) nDiff=2; // mind. 1 Pixel 788 789 long nStartPos = TEXT_STARTPOS; 790 if ( bIsRTL ) 791 { 792 // right-align 793 nStartPos += GetOutputSizePixel().Width() - 2*TEXT_STARTPOS - 794 LogicToPixel( Size( GetTextWidth( aString ), 0 ) ).Width(); 795 796 // LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include SvxFrameDirectionItem 797 } 798 799 DrawText( PixelToLogic( Point( nStartPos, nDiff/2 ) ), aString ); 800 } 801 } 802 803 void __EXPORT ScTextWnd::Resize() 804 { 805 if (pEditView) 806 { 807 Size aSize = GetOutputSizePixel(); 808 long nDiff = aSize.Height() 809 - LogicToPixel( Size( 0, GetTextHeight() ) ).Height(); 810 811 #ifdef OS2_DOCH_NICHT 812 nDiff-=2; // wird durch 2 geteilt 813 // passt sonst nicht zur normalen Textausgabe 814 #endif 815 816 aSize.Width() -= 2 * TEXT_STARTPOS - 1; 817 818 pEditView->SetOutputArea( 819 PixelToLogic( Rectangle( Point( TEXT_STARTPOS, (nDiff > 0) ? nDiff/2 : 1 ), 820 aSize ) ) ); 821 } 822 } 823 824 void __EXPORT ScTextWnd::MouseMove( const MouseEvent& rMEvt ) 825 { 826 if (pEditView) 827 pEditView->MouseMove( rMEvt ); 828 } 829 830 void __EXPORT ScTextWnd::MouseButtonDown( const MouseEvent& rMEvt ) 831 { 832 if (!HasFocus()) 833 { 834 StartEditEngine(); 835 if ( SC_MOD()->IsEditMode() ) 836 GrabFocus(); 837 } 838 839 if (pEditView) 840 { 841 pEditView->SetEditEngineUpdateMode( sal_True ); 842 pEditView->MouseButtonDown( rMEvt ); 843 } 844 } 845 846 void __EXPORT ScTextWnd::MouseButtonUp( const MouseEvent& rMEvt ) 847 { 848 if (pEditView) 849 if (pEditView->MouseButtonUp( rMEvt )) 850 { 851 if ( rMEvt.IsMiddle() && 852 GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION ) 853 { 854 // EditView may have pasted from selection 855 SC_MOD()->InputChanged( pEditView ); 856 } 857 else 858 SC_MOD()->InputSelection( pEditView ); 859 } 860 } 861 862 void __EXPORT ScTextWnd::Command( const CommandEvent& rCEvt ) 863 { 864 bInputMode = sal_True; 865 sal_uInt16 nCommand = rCEvt.GetCommand(); 866 if ( pEditView /* && ( nCommand == COMMAND_STARTDRAG || nCommand == COMMAND_VOICE ) */ ) 867 { 868 ScModule* pScMod = SC_MOD(); 869 ScTabViewShell* pStartViewSh = ScTabViewShell::GetActiveViewShell(); 870 871 // #109441# don't modify the font defaults here - the right defaults are 872 // already set in StartEditEngine when the EditEngine is created 873 874 // #63263# verhindern, dass die EditView beim View-Umschalten wegkommt 875 pScMod->SetInEditCommand( sal_True ); 876 pEditView->Command( rCEvt ); 877 pScMod->SetInEditCommand( sal_False ); 878 879 // #48929# COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde 880 // darum in dem Fall kein InputChanged 881 //! erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten 882 883 if ( nCommand == COMMAND_STARTDRAG ) 884 { 885 // ist auf eine andere View gedraggt worden? 886 ScTabViewShell* pEndViewSh = ScTabViewShell::GetActiveViewShell(); 887 if ( pEndViewSh != pStartViewSh && pStartViewSh != NULL ) 888 { 889 ScViewData* pViewData = pStartViewSh->GetViewData(); 890 ScInputHandler* pHdl = pScMod->GetInputHdl( pStartViewSh ); 891 if ( pHdl && pViewData->HasEditView( pViewData->GetActivePart() ) ) 892 { 893 pHdl->CancelHandler(); 894 pViewData->GetView()->ShowCursor(); // fehlt bei KillEditView, weil nicht aktiv 895 } 896 } 897 } 898 else if ( nCommand == COMMAND_CURSORPOS ) 899 { 900 // don't call InputChanged for COMMAND_CURSORPOS 901 } 902 else if ( nCommand == COMMAND_INPUTLANGUAGECHANGE ) 903 { 904 // #i55929# Font and font size state depends on input language if nothing is selected, 905 // so the slots have to be invalidated when the input language is changed. 906 907 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 908 if (pViewFrm) 909 { 910 SfxBindings& rBindings = pViewFrm->GetBindings(); 911 rBindings.Invalidate( SID_ATTR_CHAR_FONT ); 912 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); 913 } 914 } 915 else 916 SC_MOD()->InputChanged( pEditView ); 917 } 918 else 919 Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern... 920 921 bInputMode = sal_False; 922 } 923 924 void ScTextWnd::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel ) 925 { 926 if ( pEditView ) 927 { 928 CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True ); 929 pEditView->Command( aDragEvent ); 930 931 // handling of d&d to different view (CancelHandler) can't be done here, 932 // because the call returns before d&d is complete. 933 } 934 } 935 936 void __EXPORT ScTextWnd::KeyInput(const KeyEvent& rKEvt) 937 { 938 bInputMode = sal_True; 939 if (!SC_MOD()->InputKeyEvent( rKEvt )) 940 { 941 sal_Bool bUsed = sal_False; 942 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 943 if ( pViewSh ) 944 bUsed = pViewSh->SfxKeyInput(rKEvt); // nur Acceleratoren, keine Eingabe 945 if (!bUsed) 946 Window::KeyInput( rKEvt ); 947 } 948 bInputMode = sal_False; 949 } 950 951 void __EXPORT ScTextWnd::GetFocus() 952 { 953 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 954 if ( pViewSh ) 955 pViewSh->SetFormShellAtTop( sal_False ); // focus in input line -> FormShell no longer on top 956 } 957 958 void __EXPORT ScTextWnd::LoseFocus() 959 { 960 } 961 962 String __EXPORT ScTextWnd::GetText() const 963 { 964 // ueberladen, um per Testtool an den Text heranzukommen 965 966 if ( pEditEngine ) 967 return pEditEngine->GetText(); 968 else 969 return GetTextString(); 970 } 971 972 void ScTextWnd::SetFormulaMode( sal_Bool bSet ) 973 { 974 if ( bSet != bFormulaMode ) 975 { 976 bFormulaMode = bSet; 977 UpdateAutoCorrFlag(); 978 } 979 } 980 981 void ScTextWnd::UpdateAutoCorrFlag() 982 { 983 if ( pEditEngine ) 984 { 985 sal_uLong nControl = pEditEngine->GetControlWord(); 986 sal_uLong nOld = nControl; 987 if ( bFormulaMode ) 988 nControl &= ~EE_CNTRL_AUTOCORRECT; // keine Autokorrektur in Formeln 989 else 990 nControl |= EE_CNTRL_AUTOCORRECT; // sonst schon 991 if ( nControl != nOld ) 992 pEditEngine->SetControlWord( nControl ); 993 } 994 } 995 996 void lcl_ExtendEditFontAttribs( SfxItemSet& rSet ) 997 { 998 const SfxPoolItem& rFontItem = rSet.Get( EE_CHAR_FONTINFO ); 999 rSet.Put( rFontItem, EE_CHAR_FONTINFO_CJK ); 1000 rSet.Put( rFontItem, EE_CHAR_FONTINFO_CTL ); 1001 const SfxPoolItem& rHeightItem = rSet.Get( EE_CHAR_FONTHEIGHT ); 1002 rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CJK ); 1003 rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CTL ); 1004 const SfxPoolItem& rWeightItem = rSet.Get( EE_CHAR_WEIGHT ); 1005 rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK ); 1006 rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL ); 1007 const SfxPoolItem& rItalicItem = rSet.Get( EE_CHAR_ITALIC ); 1008 rSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK ); 1009 rSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL ); 1010 const SfxPoolItem& rLangItem = rSet.Get( EE_CHAR_LANGUAGE ); 1011 rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK ); 1012 rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL ); 1013 } 1014 1015 void lcl_ModifyRTLDefaults( SfxItemSet& rSet ) 1016 { 1017 rSet.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) ); 1018 1019 // always using rtl writing direction would break formulas 1020 //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) ); 1021 1022 // PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's 1023 // sal_uInt16 values in EditLine), so the text may be wrapped and line spacing must be 1024 // increased to not see the beginning of the next line. 1025 SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL ); 1026 aItem.SetPropLineSpace( 200 ); 1027 rSet.Put( aItem ); 1028 } 1029 1030 void lcl_ModifyRTLVisArea( EditView* pEditView ) 1031 { 1032 Rectangle aVisArea = pEditView->GetVisArea(); 1033 Size aPaper = pEditView->GetEditEngine()->GetPaperSize(); 1034 long nDiff = aPaper.Width() - aVisArea.Right(); 1035 aVisArea.Left() += nDiff; 1036 aVisArea.Right() += nDiff; 1037 pEditView->SetVisArea(aVisArea); 1038 } 1039 1040 void ScTextWnd::StartEditEngine() 1041 { 1042 // #31147# Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren 1043 SfxObjectShell* pObjSh = SfxObjectShell::Current(); 1044 if ( pObjSh && pObjSh->IsInModalMode() ) 1045 return; 1046 1047 if ( !pEditView || !pEditEngine ) 1048 { 1049 ScFieldEditEngine* pNew; 1050 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 1051 if ( pViewSh ) 1052 { 1053 const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); 1054 pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() ); 1055 } 1056 else 1057 pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, sal_True ); 1058 pNew->SetExecuteURL( sal_False ); 1059 pEditEngine = pNew; 1060 1061 pEditEngine->SetUpdateMode( sal_False ); 1062 pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) ); 1063 pEditEngine->SetWordDelimiters( 1064 ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) ); 1065 1066 UpdateAutoCorrFlag(); 1067 1068 { 1069 SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() ); 1070 pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont ); 1071 lcl_ExtendEditFontAttribs( *pSet ); 1072 // turn off script spacing to match DrawText output 1073 pSet->Put( SvxScriptSpaceItem( sal_False, EE_PARA_ASIANCJKSPACING ) ); 1074 if ( bIsRTL ) 1075 lcl_ModifyRTLDefaults( *pSet ); 1076 pEditEngine->SetDefaults( pSet ); 1077 } 1078 1079 // #57254# Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in 1080 // die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen. 1081 1082 sal_Bool bFilled = sal_False; 1083 ScInputHandler* pHdl = SC_MOD()->GetInputHdl(); 1084 if ( pHdl ) //! Testen, ob's der richtige InputHdl ist? 1085 bFilled = pHdl->GetTextAndFields( *pEditEngine ); 1086 1087 pEditEngine->SetUpdateMode( sal_True ); 1088 1089 // aString ist die Wahrheit... 1090 if ( bFilled && pEditEngine->GetText() == aString ) 1091 Invalidate(); // Repaint fuer (hinterlegte) Felder 1092 else 1093 pEditEngine->SetText(aString); // dann wenigstens den richtigen Text 1094 1095 pEditView = new EditView( pEditEngine, this ); 1096 pEditView->SetInsertMode(bIsInsertMode); 1097 1098 // Text aus Clipboard wird als ASCII einzeilig uebernommen 1099 sal_uLong n = pEditView->GetControlWord(); 1100 pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE ); 1101 1102 pEditEngine->InsertView( pEditView, EE_APPEND ); 1103 1104 Resize(); 1105 1106 if ( bIsRTL ) 1107 lcl_ModifyRTLVisArea( pEditView ); 1108 1109 pEditEngine->SetModifyHdl(LINK(this, ScTextWnd, NotifyHdl)); 1110 1111 if (!maAccTextDatas.empty()) 1112 maAccTextDatas.back()->StartEdit(); 1113 1114 // as long as EditEngine and DrawText sometimes differ for CTL text, 1115 // repaint now to have the EditEngine's version visible 1116 // SfxObjectShell* pObjSh = SfxObjectShell::Current(); 1117 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 1118 { 1119 ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); // any document 1120 sal_uInt8 nScript = pDoc->GetStringScriptType( aString ); 1121 if ( nScript & SCRIPTTYPE_COMPLEX ) 1122 Invalidate(); 1123 } 1124 } 1125 1126 SC_MOD()->SetInputMode( SC_INPUT_TOP ); 1127 1128 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 1129 if (pViewFrm) 1130 pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT ); 1131 } 1132 1133 IMPL_LINK(ScTextWnd, NotifyHdl, EENotify*, EMPTYARG) 1134 { 1135 if (pEditView && !bInputMode) 1136 { 1137 ScInputHandler* pHdl = SC_MOD()->GetInputHdl(); 1138 1139 // #105354# Use the InputHandler's InOwnChange flag to prevent calling InputChanged 1140 // while an InputHandler method is modifying the EditEngine content 1141 1142 if ( pHdl && !pHdl->IsInOwnChange() ) 1143 pHdl->InputChanged( pEditView, sal_True ); // #i20282# InputChanged must know if called from modify handler 1144 } 1145 1146 return 0; 1147 } 1148 1149 void ScTextWnd::StopEditEngine( sal_Bool bAll ) 1150 { 1151 if (pEditView) 1152 { 1153 if (!maAccTextDatas.empty()) 1154 maAccTextDatas.back()->EndEdit(); 1155 1156 ScModule* pScMod = SC_MOD(); 1157 1158 if (!bAll) 1159 pScMod->InputSelection( pEditView ); 1160 aString = pEditEngine->GetText(); 1161 bIsInsertMode = pEditView->IsInsertMode(); 1162 sal_Bool bSelection = pEditView->HasSelection(); 1163 pEditEngine->SetModifyHdl(Link()); 1164 DELETEZ(pEditView); 1165 DELETEZ(pEditEngine); 1166 1167 if ( pScMod->IsEditMode() && !bAll ) 1168 pScMod->SetInputMode(SC_INPUT_TABLE); 1169 1170 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 1171 if (pViewFrm) 1172 pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT ); 1173 1174 if (bSelection) 1175 Invalidate(); // damit Selektion nicht stehenbleibt 1176 } 1177 } 1178 1179 void ScTextWnd::SetTextString( const String& rNewString ) 1180 { 1181 if ( rNewString != aString ) 1182 { 1183 bInputMode = sal_True; 1184 1185 // Position der Aenderung suchen, nur Rest painten 1186 1187 long nInvPos = 0; 1188 long nStartPos = 0; 1189 long nTextSize = 0; 1190 1191 if (!pEditEngine) 1192 { 1193 sal_Bool bPaintAll; 1194 if ( bIsRTL ) 1195 bPaintAll = sal_True; 1196 else 1197 { 1198 // test if CTL script type is involved 1199 sal_uInt8 nOldScript = 0; 1200 sal_uInt8 nNewScript = 0; 1201 SfxObjectShell* pObjSh = SfxObjectShell::Current(); 1202 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 1203 { 1204 // any document can be used (used only for its break iterator) 1205 ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); 1206 nOldScript = pDoc->GetStringScriptType( aString ); 1207 nNewScript = pDoc->GetStringScriptType( rNewString ); 1208 } 1209 bPaintAll = ( nOldScript & SCRIPTTYPE_COMPLEX ) || ( nNewScript & SCRIPTTYPE_COMPLEX ); 1210 } 1211 1212 if ( bPaintAll ) 1213 { 1214 // if CTL is involved, the whole text has to be redrawn 1215 Invalidate(); 1216 } 1217 else 1218 { 1219 xub_StrLen nDifPos; 1220 if (rNewString.Len() > aString.Len()) 1221 nDifPos = rNewString.Match(aString); 1222 else 1223 nDifPos = aString.Match(rNewString); 1224 1225 long nSize1 = GetTextWidth(aString); 1226 long nSize2 = GetTextWidth(rNewString); 1227 if ( nSize1>0 && nSize2>0 ) 1228 nTextSize = Max( nSize1, nSize2 ); 1229 else 1230 nTextSize = GetOutputSize().Width(); // Ueberlauf 1231 1232 if (nDifPos == STRING_MATCH) 1233 nDifPos = 0; 1234 1235 // -1 wegen Rundung und "A" 1236 Point aLogicStart = PixelToLogic(Point(TEXT_STARTPOS-1,0)); 1237 nStartPos = aLogicStart.X(); 1238 nInvPos = nStartPos; 1239 if (nDifPos) 1240 nInvPos += GetTextWidth(aString,0,nDifPos); 1241 1242 sal_uInt16 nFlags = 0; 1243 if ( nDifPos == aString.Len() ) // only new characters appended 1244 nFlags = INVALIDATE_NOERASE; // then background is already clear 1245 1246 Invalidate( Rectangle( nInvPos, 0, 1247 nStartPos+nTextSize, GetOutputSize().Height()-1 ), 1248 nFlags ); 1249 } 1250 } 1251 else 1252 { 1253 pEditEngine->SetText(rNewString); 1254 } 1255 1256 aString = rNewString; 1257 1258 if (!maAccTextDatas.empty()) 1259 maAccTextDatas.back()->TextChanged(); 1260 1261 bInputMode = sal_False; 1262 } 1263 } 1264 1265 const String& ScTextWnd::GetTextString() const 1266 { 1267 return aString; 1268 } 1269 1270 sal_Bool ScTextWnd::IsInputActive() 1271 { 1272 return HasFocus(); 1273 } 1274 1275 EditView* ScTextWnd::GetEditView() 1276 { 1277 return pEditView; 1278 } 1279 1280 void ScTextWnd::MakeDialogEditView() 1281 { 1282 if ( pEditView ) return; 1283 1284 ScFieldEditEngine* pNew; 1285 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 1286 if ( pViewSh ) 1287 { 1288 const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument(); 1289 pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() ); 1290 } 1291 else 1292 pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, sal_True ); 1293 pNew->SetExecuteURL( sal_False ); 1294 pEditEngine = pNew; 1295 1296 pEditEngine->SetUpdateMode( sal_False ); 1297 pEditEngine->SetWordDelimiters( pEditEngine->GetWordDelimiters() += '=' ); 1298 pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) ); 1299 1300 SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() ); 1301 pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont ); 1302 lcl_ExtendEditFontAttribs( *pSet ); 1303 if ( bIsRTL ) 1304 lcl_ModifyRTLDefaults( *pSet ); 1305 pEditEngine->SetDefaults( pSet ); 1306 pEditEngine->SetUpdateMode( sal_True ); 1307 1308 pEditView = new EditView( pEditEngine, this ); 1309 pEditEngine->InsertView( pEditView, EE_APPEND ); 1310 1311 Resize(); 1312 1313 if ( bIsRTL ) 1314 lcl_ModifyRTLVisArea( pEditView ); 1315 1316 if (!maAccTextDatas.empty()) 1317 maAccTextDatas.back()->StartEdit(); 1318 } 1319 1320 void ScTextWnd::ImplInitSettings() 1321 { 1322 bIsRTL = GetSettings().GetLayoutRTL(); 1323 1324 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 1325 1326 Color aBgColor= rStyleSettings.GetWindowColor(); 1327 Color aTxtColor= rStyleSettings.GetWindowTextColor(); 1328 1329 aTextFont.SetFillColor ( aBgColor ); 1330 aTextFont.SetColor (aTxtColor); 1331 SetBackground ( aBgColor ); 1332 Invalidate(); 1333 } 1334 1335 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScTextWnd::CreateAccessible() 1336 { 1337 return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL, this, 1338 rtl::OUString(String(ScResId(STR_ACC_EDITLINE_NAME))), 1339 rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), EditLine); 1340 } 1341 1342 void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData ) 1343 { 1344 OSL_ENSURE( ::std::find( maAccTextDatas.begin(), maAccTextDatas.end(), &rTextData ) == maAccTextDatas.end(), 1345 "ScTextWnd::InsertAccessibleTextData - passed object already registered" ); 1346 maAccTextDatas.push_back( &rTextData ); 1347 } 1348 1349 void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData ) 1350 { 1351 AccTextDataVector::iterator aEnd = maAccTextDatas.end(); 1352 AccTextDataVector::iterator aIt = ::std::find( maAccTextDatas.begin(), aEnd, &rTextData ); 1353 OSL_ENSURE( aIt != aEnd, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" ); 1354 if( aIt != aEnd ) 1355 maAccTextDatas.erase( aIt ); 1356 } 1357 1358 // ----------------------------------------------------------------------- 1359 1360 void ScTextWnd::DataChanged( const DataChangedEvent& rDCEvt ) 1361 { 1362 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && 1363 (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 1364 { 1365 ImplInitSettings(); 1366 Invalidate(); 1367 } 1368 else 1369 Window::DataChanged( rDCEvt ); 1370 } 1371 1372 1373 //======================================================================== 1374 // Positionsfenster 1375 //======================================================================== 1376 1377 ScPosWnd::ScPosWnd( Window* pParent ) : 1378 ComboBox ( pParent, WinBits(WB_HIDE | WB_DROPDOWN) ), 1379 pAccel ( NULL ), 1380 nTipVisible ( 0 ), 1381 bFormulaMode( sal_False ) 1382 { 1383 Size aSize( GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:GW99999")) ), 1384 GetTextHeight() ); 1385 aSize.Width() += 25; // ?? 1386 aSize.Height() = CalcWindowSizePixel(11); // Funktionen: 10 MRU + "andere..." 1387 SetSizePixel( aSize ); 1388 1389 FillRangeNames(); 1390 1391 StartListening( *SFX_APP() ); // fuer Navigator-Bereichsnamen-Updates 1392 } 1393 1394 __EXPORT ScPosWnd::~ScPosWnd() 1395 { 1396 EndListening( *SFX_APP() ); 1397 1398 HideTip(); 1399 1400 delete pAccel; 1401 } 1402 1403 void ScPosWnd::SetFormulaMode( sal_Bool bSet ) 1404 { 1405 if ( bSet != bFormulaMode ) 1406 { 1407 bFormulaMode = bSet; 1408 1409 if ( bSet ) 1410 FillFunctions(); 1411 else 1412 FillRangeNames(); 1413 1414 HideTip(); 1415 } 1416 } 1417 1418 void ScPosWnd::SetPos( const String& rPosStr ) 1419 { 1420 if ( aPosStr != rPosStr ) 1421 { 1422 aPosStr = rPosStr; 1423 SetText(aPosStr); 1424 } 1425 } 1426 1427 void ScPosWnd::FillRangeNames() 1428 { 1429 Clear(); 1430 1431 SfxObjectShell* pObjSh = SfxObjectShell::Current(); 1432 if ( pObjSh && pObjSh->ISA(ScDocShell) ) 1433 { 1434 ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); 1435 1436 // per Hand sortieren, weil Funktionen nicht sortiert werden: 1437 1438 ScRangeName* pRangeNames = pDoc->GetRangeName(); 1439 sal_uInt16 nCount = pRangeNames->GetCount(); 1440 if ( nCount > 0 ) 1441 { 1442 sal_uInt16 nValidCount = 0; 1443 ScRange aDummy; 1444 sal_uInt16 i; 1445 for ( i=0; i<nCount; i++ ) 1446 { 1447 ScRangeData* pData = (*pRangeNames)[i]; 1448 if (pData->IsValidReference(aDummy)) 1449 nValidCount++; 1450 } 1451 if ( nValidCount ) 1452 { 1453 ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ]; 1454 sal_uInt16 j; 1455 for ( i=0, j=0; i<nCount; i++ ) 1456 { 1457 ScRangeData* pData = (*pRangeNames)[i]; 1458 if (pData->IsValidReference(aDummy)) 1459 ppSortArray[j++] = pData; 1460 } 1461 #ifndef ICC 1462 qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), 1463 &ScRangeData_QsortNameCompare ); 1464 #else 1465 qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), 1466 ICCQsortNameCompare ); 1467 #endif 1468 for ( j=0; j<nValidCount; j++ ) 1469 InsertEntry( ppSortArray[j]->GetName() ); 1470 delete [] ppSortArray; 1471 } 1472 } 1473 } 1474 SetText(aPosStr); 1475 } 1476 1477 void ScPosWnd::FillFunctions() 1478 { 1479 Clear(); 1480 1481 String aFirstName; 1482 const ScAppOptions& rOpt = SC_MOD()->GetAppOptions(); 1483 sal_uInt16 nMRUCount = rOpt.GetLRUFuncListCount(); 1484 const sal_uInt16* pMRUList = rOpt.GetLRUFuncList(); 1485 if (pMRUList) 1486 { 1487 const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); 1488 sal_uLong nListCount = pFuncList->GetCount(); 1489 for (sal_uInt16 i=0; i<nMRUCount; i++) 1490 { 1491 sal_uInt16 nId = pMRUList[i]; 1492 for (sal_uLong j=0; j<nListCount; j++) 1493 { 1494 const ScFuncDesc* pDesc = pFuncList->GetFunction( j ); 1495 if ( pDesc->nFIndex == nId && pDesc->pFuncName ) 1496 { 1497 InsertEntry( *pDesc->pFuncName ); 1498 if (!aFirstName.Len()) 1499 aFirstName = *pDesc->pFuncName; 1500 break; // nicht weitersuchen 1501 } 1502 } 1503 } 1504 } 1505 1506 //! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen, 1507 //! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann! 1508 1509 // InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) ); 1510 1511 SetText(aFirstName); 1512 } 1513 1514 void __EXPORT ScPosWnd::Notify( SfxBroadcaster&, const SfxHint& rHint ) 1515 { 1516 if ( !bFormulaMode ) 1517 { 1518 // muss die Liste der Bereichsnamen updgedated werden? 1519 1520 if ( rHint.ISA(SfxSimpleHint) ) 1521 { 1522 sal_uLong nHintId = ((SfxSimpleHint&)rHint).GetId(); 1523 if ( nHintId == SC_HINT_AREAS_CHANGED || nHintId == SC_HINT_NAVIGATOR_UPDATEALL) 1524 FillRangeNames(); 1525 } 1526 else if ( rHint.ISA(SfxEventHint) ) 1527 { 1528 sal_uLong nEventId = ((SfxEventHint&)rHint).GetEventId(); 1529 if ( nEventId == SFX_EVENT_ACTIVATEDOC ) 1530 FillRangeNames(); 1531 } 1532 } 1533 } 1534 1535 void ScPosWnd::HideTip() 1536 { 1537 if ( nTipVisible ) 1538 { 1539 Help::HideTip( nTipVisible ); 1540 nTipVisible = 0; 1541 } 1542 } 1543 1544 ScNameInputType lcl_GetInputType( const String& rText ) 1545 { 1546 ScNameInputType eRet = SC_NAME_INPUT_BAD_NAME; // the more general error 1547 1548 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 1549 if ( pViewSh ) 1550 { 1551 ScViewData* pViewData = pViewSh->GetViewData(); 1552 ScDocument* pDoc = pViewData->GetDocument(); 1553 SCTAB nTab = pViewData->GetTabNo(); 1554 formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); 1555 1556 // test in same order as in SID_CURRENTCELL execute 1557 1558 ScRange aRange; 1559 ScAddress aAddress; 1560 ScRangeUtil aRangeUtil; 1561 SCTAB nNameTab; 1562 sal_Int32 nNumeric; 1563 1564 if ( aRange.Parse( rText, pDoc, eConv ) & SCA_VALID ) 1565 eRet = SC_NAME_INPUT_NAMEDRANGE; 1566 else if ( aAddress.Parse( rText, pDoc, eConv ) & SCA_VALID ) 1567 eRet = SC_NAME_INPUT_CELL; 1568 else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_NAMES, eConv ) ) 1569 eRet = SC_NAME_INPUT_NAMEDRANGE; 1570 else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_DBASE, eConv ) ) 1571 eRet = SC_NAME_INPUT_DATABASE; 1572 else if ( ByteString( rText, RTL_TEXTENCODING_ASCII_US ).IsNumericAscii() && 1573 ( nNumeric = rText.ToInt32() ) > 0 && nNumeric <= MAXROW+1 ) 1574 eRet = SC_NAME_INPUT_ROW; 1575 else if ( pDoc->GetTable( rText, nNameTab ) ) 1576 eRet = SC_NAME_INPUT_SHEET; 1577 else if ( ScRangeData::IsNameValid( rText, pDoc ) ) // nothing found, create new range? 1578 { 1579 if ( pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE ) 1580 eRet = SC_NAME_INPUT_DEFINE; 1581 else 1582 eRet = SC_NAME_INPUT_BAD_SELECTION; 1583 } 1584 else 1585 eRet = SC_NAME_INPUT_BAD_NAME; 1586 } 1587 1588 return eRet; 1589 } 1590 1591 void ScPosWnd::Modify() 1592 { 1593 ComboBox::Modify(); 1594 1595 HideTip(); 1596 1597 if ( !IsTravelSelect() && !bFormulaMode ) 1598 { 1599 // determine the action that would be taken for the current input 1600 1601 ScNameInputType eType = lcl_GetInputType( GetText() ); // uses current view 1602 sal_uInt16 nStrId = 0; 1603 switch ( eType ) 1604 { 1605 case SC_NAME_INPUT_CELL: 1606 nStrId = STR_NAME_INPUT_CELL; 1607 break; 1608 case SC_NAME_INPUT_RANGE: 1609 case SC_NAME_INPUT_NAMEDRANGE: 1610 nStrId = STR_NAME_INPUT_RANGE; // named range or range reference 1611 break; 1612 case SC_NAME_INPUT_DATABASE: 1613 nStrId = STR_NAME_INPUT_DBRANGE; 1614 break; 1615 case SC_NAME_INPUT_ROW: 1616 nStrId = STR_NAME_INPUT_ROW; 1617 break; 1618 case SC_NAME_INPUT_SHEET: 1619 nStrId = STR_NAME_INPUT_SHEET; 1620 break; 1621 case SC_NAME_INPUT_DEFINE: 1622 nStrId = STR_NAME_INPUT_DEFINE; 1623 break; 1624 default: 1625 // other cases (error): no tip help 1626 break; 1627 } 1628 1629 if ( nStrId ) 1630 { 1631 // show the help tip at the text cursor position 1632 1633 Window* pWin = GetSubEdit(); 1634 if (!pWin) 1635 pWin = this; 1636 Point aPos; 1637 Cursor* pCur = pWin->GetCursor(); 1638 if (pCur) 1639 aPos = pWin->LogicToPixel( pCur->GetPos() ); 1640 aPos = pWin->OutputToScreenPixel( aPos ); 1641 Rectangle aRect( aPos, aPos ); 1642 1643 String aText = ScGlobal::GetRscString( nStrId ); 1644 sal_uInt16 nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM; 1645 nTipVisible = Help::ShowTip(pWin, aRect, aText, nAlign); 1646 } 1647 } 1648 } 1649 1650 void __EXPORT ScPosWnd::Select() 1651 { 1652 ComboBox::Select(); // in VCL gibt GetText() erst danach den ausgewaehlten Eintrag 1653 1654 HideTip(); 1655 1656 if (!IsTravelSelect()) 1657 DoEnter(); 1658 } 1659 1660 void ScPosWnd::DoEnter() 1661 { 1662 String aText = GetText(); 1663 if ( aText.Len() ) 1664 { 1665 if ( bFormulaMode ) 1666 { 1667 ScModule* pScMod = SC_MOD(); 1668 if ( aText == ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) ) 1669 { 1670 // Funktions-Autopilot 1671 //! mit dem bisher eingegebenen Text weiterarbeiten !!! 1672 1673 //! new method at ScModule to query if function autopilot is open 1674 SfxViewFrame* pViewFrm = SfxViewFrame::Current(); 1675 if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) ) 1676 pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION, 1677 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); 1678 } 1679 else 1680 { 1681 ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); 1682 ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh ); 1683 if (pHdl) 1684 pHdl->InsertFunction( aText ); 1685 } 1686 } 1687 else 1688 { 1689 // depending on the input, select something or create a new named range 1690 1691 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); 1692 if ( pViewSh ) 1693 { 1694 ScNameInputType eType = lcl_GetInputType( aText ); 1695 if ( eType == SC_NAME_INPUT_BAD_NAME || eType == SC_NAME_INPUT_BAD_SELECTION ) 1696 { 1697 sal_uInt16 nId = ( eType == SC_NAME_INPUT_BAD_NAME ) ? STR_NAME_ERROR_NAME : STR_NAME_ERROR_SELECTION; 1698 pViewSh->ErrorMessage( nId ); 1699 } 1700 else if ( eType == SC_NAME_INPUT_DEFINE ) 1701 { 1702 ScViewData* pViewData = pViewSh->GetViewData(); 1703 ScDocShell* pDocShell = pViewData->GetDocShell(); 1704 ScDocument* pDoc = pDocShell->GetDocument(); 1705 ScRangeName* pNames = pDoc->GetRangeName(); 1706 ScRange aSelection; 1707 sal_uInt16 nIndex = 0; 1708 if ( pNames && !pNames->SearchName( aText, nIndex ) && 1709 (pViewData->GetSimpleArea( aSelection ) == SC_MARK_SIMPLE) ) 1710 { 1711 ScRangeName aNewRanges( *pNames ); 1712 ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ); 1713 String aContent; 1714 aSelection.Format( aContent, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() ); 1715 ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor ); 1716 if ( aNewRanges.Insert(pNew) ) 1717 { 1718 ScDocFunc aFunc(*pDocShell); 1719 aFunc.ModifyRangeNames( aNewRanges, sal_False ); 1720 pViewSh->UpdateInputHandler(sal_True); 1721 } 1722 else 1723 delete pNew; // shouldn't happen 1724 } 1725 } 1726 else 1727 { 1728 // for all selection types, excecute the SID_CURRENTCELL slot 1729 1730 SfxStringItem aPosItem( SID_CURRENTCELL, aText ); 1731 SfxBoolItem aUnmarkItem( FN_PARAM_1, sal_True ); // remove existing selection 1732 1733 pViewSh->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL, 1734 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD, 1735 &aPosItem, &aUnmarkItem, 0L ); 1736 } 1737 } 1738 } 1739 } 1740 else 1741 SetText( aPosStr ); 1742 1743 ReleaseFocus_Impl(); 1744 } 1745 1746 long __EXPORT ScPosWnd::Notify( NotifyEvent& rNEvt ) 1747 { 1748 long nHandled = 0; 1749 1750 if ( rNEvt.GetType() == EVENT_KEYINPUT ) 1751 { 1752 const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); 1753 1754 switch ( pKEvt->GetKeyCode().GetCode() ) 1755 { 1756 case KEY_RETURN: 1757 DoEnter(); 1758 nHandled = 1; 1759 break; 1760 1761 case KEY_ESCAPE: 1762 if (nTipVisible) 1763 { 1764 // escape when the tip help is shown: only hide the tip 1765 HideTip(); 1766 } 1767 else 1768 { 1769 if (!bFormulaMode) 1770 SetText( aPosStr ); 1771 ReleaseFocus_Impl(); 1772 } 1773 nHandled = 1; 1774 break; 1775 } 1776 } 1777 1778 if ( !nHandled ) 1779 nHandled = ComboBox::Notify( rNEvt ); 1780 1781 if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) 1782 HideTip(); 1783 1784 return nHandled; 1785 } 1786 1787 void ScPosWnd::ReleaseFocus_Impl() 1788 { 1789 HideTip(); 1790 1791 SfxViewShell* pCurSh = SfxViewShell::Current(); 1792 ScInputHandler* pHdl = SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell, pCurSh ) ); 1793 if ( pHdl && pHdl->IsTopMode() ) 1794 { 1795 // Focus wieder in die Eingabezeile? 1796 1797 ScInputWindow* pInputWin = pHdl->GetInputWindow(); 1798 if (pInputWin) 1799 { 1800 pInputWin->TextGrabFocus(); 1801 return; 1802 } 1803 } 1804 1805 // Focus auf die aktive View 1806 1807 if ( pCurSh ) 1808 { 1809 Window* pShellWnd = pCurSh->GetWindow(); 1810 1811 if ( pShellWnd ) 1812 pShellWnd->GrabFocus(); 1813 } 1814 } 1815 1816 1817 1818 1819 1820 1821