1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 28 29 // INCLUDE --------------------------------------------------------------- 30 31 #include <sfx2/viewfrm.hxx> 32 #include <sfx2/dispatch.hxx> 33 #include <sfx2/docfile.hxx> 34 #include <vcl/sound.hxx> 35 #include <tools/urlobj.hxx> 36 #include <vcl/svapp.hxx> 37 #include "tabcont.hxx" 38 #include "tabvwsh.hxx" 39 #include "docsh.hxx" 40 #include "scmod.hxx" 41 #include "scresid.hxx" 42 #include "sc.hrc" 43 #include "globstr.hrc" 44 #include "transobj.hxx" 45 #include "clipparam.hxx" 46 47 48 // STATIC DATA ----------------------------------------------------------- 49 50 //================================================================== 51 52 ScTabControl::ScTabControl( Window* pParent, ScViewData* pData ) : 53 TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL | 54 WB_RANGESELECT | WB_MULTISELECT | WB_DRAG | WB_SIZEABLE ) ), 55 DropTargetHelper( this ), 56 DragSourceHelper( this ), 57 pViewData( pData ), 58 nMouseClickPageId( TabBar::PAGE_NOT_FOUND ), 59 nSelPageIdByMouse( TabBar::PAGE_NOT_FOUND ), 60 bErrorShown( sal_False ) 61 { 62 ScDocument* pDoc = pViewData->GetDocument(); 63 64 String aString; 65 Color aTabBgColor; 66 SCTAB nCount = pDoc->GetTableCount(); 67 for (SCTAB i=0; i<nCount; i++) 68 { 69 if (pDoc->IsVisible(i)) 70 { 71 if (pDoc->GetName(i,aString)) 72 { 73 if ( pDoc->IsScenario(i) ) 74 InsertPage( static_cast<sal_uInt16>(i)+1, aString, TPB_SPECIAL ); 75 else 76 InsertPage( static_cast<sal_uInt16>(i)+1, aString ); 77 if ( !pDoc->IsDefaultTabBgColor(i) ) 78 { 79 aTabBgColor = pDoc->GetTabBgColor(i); 80 SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor ); 81 } 82 } 83 } 84 } 85 86 SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 ); 87 88 SetSizePixel( Size(SC_TABBAR_DEFWIDTH, 0) ); 89 90 SetSplitHdl( LINK( pViewData->GetView(), ScTabView, TabBarResize ) ); 91 92 EnableEditMode(); 93 } 94 95 ScTabControl::~ScTabControl() 96 { 97 } 98 99 sal_uInt16 ScTabControl::GetMaxId() const 100 { 101 sal_uInt16 nVisCnt = GetPageCount(); 102 if (nVisCnt) 103 return GetPageId(nVisCnt-1); 104 105 return 0; 106 } 107 108 SCTAB ScTabControl::GetPrivatDropPos(const Point& rPos ) 109 { 110 sal_uInt16 nPos = ShowDropPos(rPos); 111 112 SCTAB nRealPos = static_cast<SCTAB>(nPos); 113 114 if(nPos !=0 ) 115 { 116 ScDocument* pDoc = pViewData->GetDocument(); 117 118 SCTAB nCount = pDoc->GetTableCount(); 119 120 sal_uInt16 nViewPos=0; 121 nRealPos = nCount; 122 for (SCTAB i=0; i<nCount; i++) 123 { 124 if (pDoc->IsVisible(i)) 125 { 126 nViewPos++; 127 if(nViewPos==nPos) 128 { 129 SCTAB j; 130 for (j=i+1; j<nCount; j++) 131 { 132 if (pDoc->IsVisible(j)) 133 { 134 break; 135 } 136 } 137 nRealPos =j; 138 break; 139 } 140 } 141 } 142 } 143 return nRealPos ; 144 } 145 146 void ScTabControl::MouseButtonDown( const MouseEvent& rMEvt ) 147 { 148 ScModule* pScMod = SC_MOD(); 149 if ( !pScMod->IsModalMode() && !pScMod->IsFormulaMode() && !IsInEditMode() ) 150 { 151 // View aktivieren 152 pViewData->GetViewShell()->SetActive(); // Appear und SetViewFrame 153 pViewData->GetView()->ActiveGrabFocus(); 154 } 155 156 /* #47745# Click into free area -> insert new sheet (like in Draw). 157 Needing clean left click without modifiers (may be context menu). 158 #106948# Remember clicks to all pages, to be able to move mouse pointer later. */ 159 if( rMEvt.IsLeft() && (rMEvt.GetModifier() == 0) ) 160 nMouseClickPageId = GetPageId( rMEvt.GetPosPixel() ); 161 else 162 nMouseClickPageId = TabBar::PAGE_NOT_FOUND; 163 164 TabBar::MouseButtonDown( rMEvt ); 165 } 166 167 void ScTabControl::MouseButtonUp( const MouseEvent& rMEvt ) 168 { 169 Point aPos = PixelToLogic( rMEvt.GetPosPixel() ); 170 171 // mouse button down and up on same page? 172 if( nMouseClickPageId != GetPageId( aPos ) ) 173 nMouseClickPageId = TabBar::PAGE_NOT_FOUND; 174 175 if ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() && nMouseClickPageId != 0 && nMouseClickPageId != TAB_PAGE_NOTFOUND ) 176 { 177 SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame()->GetDispatcher(); 178 pDispatcher->Execute( FID_TAB_MENU_RENAME, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); 179 } 180 181 if( nMouseClickPageId == 0 ) 182 { 183 // Click in the area next to the existing tabs: 184 // #i70320# if several sheets are selected, deselect all ecxept the current sheet, 185 // otherwise add new sheet 186 sal_uInt16 nSlot = ( GetSelectPageCount() > 1 ) ? FID_TAB_DESELECTALL : FID_INS_TABLE; 187 SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame()->GetDispatcher(); 188 pDispatcher->Execute( nSlot, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); 189 // forget page ID, to be really sure that the dialog is not called twice 190 nMouseClickPageId = TabBar::PAGE_NOT_FOUND; 191 } 192 193 TabBar::MouseButtonUp( rMEvt ); 194 } 195 196 void ScTabControl::Select() 197 { 198 /* Remember last clicked page ID. */ 199 nSelPageIdByMouse = nMouseClickPageId; 200 /* Reset nMouseClickPageId, so that next Select() call may invalidate 201 nSelPageIdByMouse (i.e. if called from keyboard). */ 202 nMouseClickPageId = TabBar::PAGE_NOT_FOUND; 203 204 ScModule* pScMod = SC_MOD(); 205 ScDocument* pDoc = pViewData->GetDocument(); 206 ScMarkData& rMark = pViewData->GetMarkData(); 207 SCTAB nCount = pDoc->GetTableCount(); 208 SCTAB i; 209 210 if ( pScMod->IsTableLocked() ) // darf jetzt nicht umgeschaltet werden ? 211 { 212 // den alten Zustand des TabControls wiederherstellen: 213 214 for (i=0; i<nCount; i++) 215 SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) ); 216 SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 ); 217 218 Sound::Beep(); 219 return; 220 } 221 222 sal_uInt16 nCurId = GetCurPageId(); 223 if (!nCurId) return; // kann vorkommen, wenn bei Excel-Import alles versteckt ist 224 sal_uInt16 nPage = nCurId - 1; 225 226 // OLE-inplace deaktivieren 227 if ( nPage != static_cast<sal_uInt16>(pViewData->GetTabNo()) ) 228 pViewData->GetView()->DrawMarkListHasChanged(); 229 230 // InputEnterHandler nur wenn nicht Referenzeingabe 231 232 sal_Bool bRefMode = pScMod->IsFormulaMode(); 233 if (!bRefMode) 234 pScMod->InputEnterHandler(); 235 236 for (i=0; i<nCount; i++) 237 rMark.SelectTable( i, IsPageSelected(static_cast<sal_uInt16>(i)+1) ); 238 239 /* Markierungen werden per Default nicht pro Tabelle gehalten 240 sal_uInt16 nSelCnt = GetSelectPageCount(); 241 if (nSelCnt>1) 242 pDoc->ExtendMarksFromTable( nPage ); 243 */ 244 245 SfxDispatcher& rDisp = pViewData->GetDispatcher(); 246 if (rDisp.IsLocked()) 247 pViewData->GetView()->SetTabNo( static_cast<SCTAB>(nPage) ); 248 else 249 { 250 // Tabelle fuer Basic ist 1-basiert 251 SfxUInt16Item aItem( SID_CURRENTTAB, nPage + 1 ); 252 rDisp.Execute( SID_CURRENTTAB, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, 253 &aItem, (void*) NULL ); 254 } 255 256 SfxBindings& rBind = pViewData->GetBindings(); 257 rBind.Invalidate( FID_FILL_TAB ); 258 rBind.Invalidate( FID_TAB_DESELECTALL ); 259 260 rBind.Invalidate( FID_INS_TABLE ); 261 rBind.Invalidate( FID_TAB_APPEND ); 262 rBind.Invalidate( FID_TAB_MOVE ); 263 rBind.Invalidate( FID_TAB_RENAME ); 264 rBind.Invalidate( FID_DELETE_TABLE ); 265 rBind.Invalidate( FID_TABLE_SHOW ); 266 rBind.Invalidate( FID_TABLE_HIDE ); 267 rBind.Invalidate( FID_TAB_SET_TAB_BG_COLOR ); 268 269 // SetReference nur wenn der Konsolidieren-Dialog offen ist 270 // (fuer Referenzen ueber mehrere Tabellen) 271 // bei anderen gibt das nur unnoetiges Gezappel 272 273 if ( bRefMode && pViewData->GetRefType() == SC_REFTYPE_REF ) 274 if ( pViewData->GetViewShell()->GetViewFrame()->HasChildWindow(SID_OPENDLG_CONSOLIDATE) ) 275 { 276 ScRange aRange( 277 pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(), 278 pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() ); 279 pScMod->SetReference( aRange, pDoc, &rMark ); 280 pScMod->EndReference(); // wegen Auto-Hide 281 } 282 } 283 284 void ScTabControl::UpdateStatus() 285 { 286 ScDocument* pDoc = pViewData->GetDocument(); 287 ScMarkData& rMark = pViewData->GetMarkData(); 288 sal_Bool bActive = pViewData->IsActive(); 289 290 SCTAB nCount = pDoc->GetTableCount(); 291 SCTAB i; 292 String aString; 293 SCTAB nMaxCnt = Max( nCount, static_cast<SCTAB>(GetMaxId()) ); 294 Color aTabBgColor; 295 296 sal_Bool bModified = sal_False; // Tabellen-Namen 297 for (i=0; i<nMaxCnt && !bModified; i++) 298 { 299 if (pDoc->IsVisible(i)) 300 { 301 pDoc->GetName(i,aString); 302 aTabBgColor = pDoc->GetTabBgColor(i); 303 } 304 else 305 { 306 aString.Erase(); 307 } 308 309 if ( (GetPageText(static_cast<sal_uInt16>(i)+1) != aString) || (GetTabBgColor(static_cast<sal_uInt16>(i)+1) != aTabBgColor) ) 310 bModified = sal_True; 311 } 312 313 if (bModified) 314 { 315 Clear(); 316 for (i=0; i<nCount; i++) 317 { 318 if (pDoc->IsVisible(i)) 319 { 320 if (pDoc->GetName(i,aString)) 321 { 322 if ( pDoc->IsScenario(i) ) 323 InsertPage( static_cast<sal_uInt16>(i)+1, aString, TPB_SPECIAL ); 324 else 325 InsertPage( static_cast<sal_uInt16>(i)+1, aString ); 326 if ( !pDoc->IsDefaultTabBgColor(i) ) 327 { 328 aTabBgColor = pDoc->GetTabBgColor(i); 329 SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor ); 330 } 331 } 332 } 333 } 334 } 335 SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 ); 336 337 if (bActive) 338 { 339 bModified = sal_False; // Selektion 340 for (i=0; i<nMaxCnt && !bModified; i++) 341 if ( rMark.GetTableSelect(i) != IsPageSelected(static_cast<sal_uInt16>(i)+1) ) 342 bModified = sal_True; 343 344 // #i99576# the following loop is mis-optimized on unxsoli4 and the reason 345 // why this file is in NOOPTFILES. 346 if ( bModified ) 347 for (i=0; i<nCount; i++) 348 SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) ); 349 } 350 else 351 { 352 } 353 } 354 355 void ScTabControl::ActivateView(sal_Bool bActivate) 356 { 357 // ScDocument* pDoc = pViewData->GetDocument(); 358 ScMarkData& rMark = pViewData->GetMarkData(); 359 360 // ResetMark direkt in TabView 361 // pDoc->ResetMark(); 362 363 sal_uInt16 nCurId = GetCurPageId(); 364 if (!nCurId) return; // kann vorkommen, wenn bei Excel-Import alles versteckt ist 365 sal_uInt16 nPage = nCurId - 1; 366 // sal_uInt16 nCount = GetMaxId(); 367 368 /* 369 sal_uInt16 i; 370 for (i=0; i<nCount; i++) 371 { 372 SelectPage( i+1, sal_False ); 373 if (bActivate) 374 rMark.SelectTable( i, sal_False ); 375 } 376 */ 377 if (bActivate) 378 { 379 SelectPage( nPage+1, sal_True ); 380 rMark.SelectTable( static_cast<SCTAB>(nPage), sal_True ); 381 } 382 Invalidate(); 383 } 384 385 void ScTabControl::SetSheetLayoutRTL( sal_Bool bSheetRTL ) 386 { 387 SetEffectiveRTL( bSheetRTL ); 388 nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; 389 } 390 391 392 void ScTabControl::Command( const CommandEvent& rCEvt ) 393 { 394 ScModule* pScMod = SC_MOD(); 395 ScTabViewShell* pViewSh = pViewData->GetViewShell(); 396 sal_Bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode(); 397 398 // ViewFrame erstmal aktivieren (Bug 19493): 399 pViewSh->SetActive(); 400 401 sal_uInt16 nCmd = rCEvt.GetCommand(); 402 if ( nCmd == COMMAND_CONTEXTMENU ) 403 { 404 if (!bDisable) 405 { 406 // #i18735# select the page that is under the mouse cursor 407 // if multiple tables are selected and the one under the cursor 408 // is not part of them then unselect them 409 sal_uInt16 nId = GetPageId( rCEvt.GetMousePosPixel() ); 410 if (nId) 411 { 412 sal_Bool bAlreadySelected = IsPageSelected( nId ); 413 //make the clicked page the current one 414 SetCurPageId( nId ); 415 //change the selection when the current one is not already 416 //selected or part of a multi selection 417 if(!bAlreadySelected) 418 { 419 sal_uInt16 nCount = GetMaxId(); 420 421 for (sal_uInt16 i=1; i<=nCount; i++) 422 SelectPage( i, i==nId ); 423 Select(); 424 } 425 } 426 427 // #i52073# OLE inplace editing has to be stopped before showing the sheet tab context menu 428 pViewSh->DeactivateOle(); 429 430 // Popup-Menu: 431 // get Dispatcher from ViewData (ViewFrame) instead of Shell (Frame), so it can't be null 432 pViewData->GetDispatcher().ExecutePopup( ScResId(RID_POPUP_TAB) ); 433 } 434 } 435 } 436 437 void ScTabControl::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel ) 438 { 439 ScModule* pScMod = SC_MOD(); 440 sal_Bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode(); 441 442 if (!bDisable) 443 { 444 Region aRegion( Rectangle(0,0,0,0) ); 445 CommandEvent aCEvt( rPosPixel, COMMAND_STARTDRAG, sal_True ); // needed for StartDrag 446 if (TabBar::StartDrag( aCEvt, aRegion )) 447 DoDrag( aRegion ); 448 } 449 } 450 451 void ScTabControl::DoDrag( const Region& /* rRegion */ ) 452 { 453 ScDocShell* pDocSh = pViewData->GetDocShell(); 454 ScDocument* pDoc = pDocSh->GetDocument(); 455 456 SCTAB nTab = pViewData->GetTabNo(); 457 ScRange aTabRange( 0, 0, nTab, MAXCOL, MAXROW, nTab ); 458 ScMarkData aTabMark = pViewData->GetMarkData(); 459 aTabMark.ResetMark(); // doesn't change marked table information 460 aTabMark.SetMarkArea( aTabRange ); 461 462 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); 463 ScClipParam aClipParam(aTabRange, false); 464 pDoc->CopyToClip(aClipParam, pClipDoc, &aTabMark, false); 465 466 TransferableObjectDescriptor aObjDesc; 467 pDocSh->FillTransferableObjectDescriptor( aObjDesc ); 468 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); 469 // maSize is set in ScTransferObj ctor 470 471 ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); 472 com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> xTransferable( pTransferObj ); 473 474 pTransferObj->SetDragSourceFlags( SC_DROP_TABLE ); 475 476 pTransferObj->SetDragSource( pDocSh, aTabMark ); 477 478 Window* pWindow = pViewData->GetActiveWin(); 479 SC_MOD()->SetDragObject( pTransferObj, NULL ); // for internal D&D 480 pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK ); 481 } 482 483 sal_uInt16 lcl_DocShellNr( ScDocument* pDoc ) 484 { 485 sal_uInt16 nShellCnt = 0; 486 SfxObjectShell* pShell = SfxObjectShell::GetFirst(); 487 while ( pShell ) 488 { 489 if ( pShell->Type() == TYPE(ScDocShell) ) 490 { 491 if ( ((ScDocShell*)pShell)->GetDocument() == pDoc ) 492 return nShellCnt; 493 494 ++nShellCnt; 495 } 496 pShell = SfxObjectShell::GetNext( *pShell ); 497 } 498 499 DBG_ERROR("Dokument nicht gefunden"); 500 return 0; 501 } 502 503 sal_Int8 ScTabControl::ExecuteDrop( const ExecuteDropEvent& rEvt ) 504 { 505 EndSwitchPage(); 506 507 ScDocument* pDoc = pViewData->GetDocument(); 508 const ScDragData& rData = SC_MOD()->GetDragData(); 509 if ( rData.pCellTransfer && ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) && 510 rData.pCellTransfer->GetSourceDocument() == pDoc ) 511 { 512 // moving of tables within the document 513 SCTAB nPos = GetPrivatDropPos( rEvt.maPosPixel ); 514 HideDropPos(); 515 516 if ( nPos == rData.pCellTransfer->GetVisibleTab() && rEvt.mnAction == DND_ACTION_MOVE ) 517 { 518 // #i83005# do nothing - don't move to the same position 519 // (too easily triggered unintentionally, and might take a long time in large documents) 520 } 521 else 522 { 523 if ( !pDoc->GetChangeTrack() && pDoc->IsDocEditable() ) 524 { 525 //! use table selection from the tab control where dragging was started? 526 pViewData->GetView()->MoveTable( lcl_DocShellNr(pDoc), nPos, rEvt.mnAction != DND_ACTION_MOVE ); 527 528 rData.pCellTransfer->SetDragWasInternal(); // don't delete 529 return sal_True; 530 } 531 else 532 Sound::Beep(); 533 } 534 } 535 536 return 0; 537 } 538 539 sal_Int8 ScTabControl::AcceptDrop( const AcceptDropEvent& rEvt ) 540 { 541 if ( rEvt.mbLeaving ) 542 { 543 EndSwitchPage(); 544 HideDropPos(); 545 return rEvt.mnAction; 546 } 547 548 const ScDocument* pDoc = pViewData->GetDocument(); 549 const ScDragData& rData = SC_MOD()->GetDragData(); 550 if ( rData.pCellTransfer && ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) && 551 rData.pCellTransfer->GetSourceDocument() == pDoc ) 552 { 553 // moving of tables within the document 554 if ( !pDoc->GetChangeTrack() && pDoc->IsDocEditable() ) 555 { 556 ShowDropPos( rEvt.maPosPixel ); 557 return rEvt.mnAction; 558 } 559 } 560 else // switch sheets for all formats 561 { 562 SwitchPage( rEvt.maPosPixel ); // switch sheet after timeout 563 return 0; // nothing can be dropped here 564 } 565 566 return 0; 567 } 568 569 long ScTabControl::StartRenaming() 570 { 571 if ( pViewData->GetDocument()->IsDocEditable() ) 572 return TABBAR_RENAMING_YES; 573 else 574 return TABBAR_RENAMING_NO; 575 } 576 577 long ScTabControl::AllowRenaming() 578 { 579 ScTabViewShell* pViewSh = pViewData->GetViewShell(); 580 DBG_ASSERT( pViewSh, "pViewData->GetViewShell()" ); 581 582 long nRet = TABBAR_RENAMING_CANCEL; 583 sal_uInt16 nId = GetEditPageId(); 584 if ( nId ) 585 { 586 SCTAB nTab = nId - 1; 587 String aNewName = GetEditText(); 588 sal_Bool bDone = pViewSh->RenameTable( aNewName, nTab ); 589 if ( bDone ) 590 nRet = TABBAR_RENAMING_YES; 591 else if ( bErrorShown ) 592 { 593 // if the error message from this TabControl is currently visible, 594 // don't end edit mode now, to avoid problems when returning to 595 // the other call (showing the error) - this should not happen 596 DBG_ERROR("ScTabControl::AllowRenaming: nested calls"); 597 nRet = TABBAR_RENAMING_NO; 598 } 599 else if ( Application::IsInModalMode() ) 600 { 601 // #73472# don't show error message above any modal dialog 602 // instead cancel renaming without error message 603 nRet = TABBAR_RENAMING_CANCEL; 604 } 605 else 606 { 607 bErrorShown = sal_True; 608 pViewSh->ErrorMessage( STR_INVALIDTABNAME ); 609 bErrorShown = sal_False; 610 nRet = TABBAR_RENAMING_NO; 611 } 612 } 613 return nRet; 614 } 615 616 void ScTabControl::EndRenaming() 617 { 618 if ( HasFocus() ) 619 pViewData->GetView()->ActiveGrabFocus(); 620 } 621 622 void ScTabControl::Mirror() 623 { 624 TabBar::Mirror(); 625 if( nSelPageIdByMouse != TabBar::PAGE_NOT_FOUND ) 626 { 627 Rectangle aRect( GetPageRect( GetCurPageId() ) ); 628 if( !aRect.IsEmpty() ) 629 SetPointerPosPixel( aRect.Center() ); 630 nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; // only once after a Select() 631 } 632 } 633 634 635 636