1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <sfx2/viewfrm.hxx> 21 #include <sfx2/dispatch.hxx> 22 #include <sfx2/docfile.hxx> 23 #include <tools/urlobj.hxx> 24 #include <vcl/commandevent.hxx> 25 #include <vcl/svapp.hxx> 26 #include <vcl/weldutils.hxx> 27 #include <tabcont.hxx> 28 #include <tabvwsh.hxx> 29 #include <docsh.hxx> 30 #include <scmod.hxx> 31 #include <sc.hrc> 32 #include <globstr.hrc> 33 #include <transobj.hxx> 34 #include <clipparam.hxx> 35 #include <dragdata.hxx> 36 #include <markdata.hxx> 37 #include <gridwin.hxx> 38 #include <LibreOfficeKit/LibreOfficeKitEnums.h> 39 #include <comphelper/lok.hxx> 40 41 ScTabControl::ScTabControl( vcl::Window* pParent, ScViewData* pData ) 42 : TabBar(pParent, WB_3DLOOK | WB_MINSCROLL | WB_SCROLL | WB_RANGESELECT | WB_MULTISELECT | WB_DRAG) 43 , DropTargetHelper(this) 44 , DragSourceHelper(this) 45 , pViewData(pData) 46 , nMouseClickPageId(TabBar::PAGE_NOT_FOUND) 47 , nSelPageIdByMouse(TabBar::PAGE_NOT_FOUND) 48 , bErrorShown(false) 49 { 50 ScDocument& rDoc = pViewData->GetDocument(); 51 52 OUString aString; 53 Color aTabBgColor; 54 SCTAB nCount = rDoc.GetTableCount(); 55 for (SCTAB i=0; i<nCount; i++) 56 { 57 if (rDoc.IsVisible(i)) 58 { 59 if (rDoc.GetName(i,aString)) 60 { 61 if ( rDoc.IsScenario(i) ) 62 InsertPage( static_cast<sal_uInt16>(i)+1, aString, TabBarPageBits::Blue); 63 else 64 InsertPage( static_cast<sal_uInt16>(i)+1, aString ); 65 66 if ( rDoc.IsTabProtected(i) ) 67 SetProtectionSymbol(static_cast<sal_uInt16>(i)+1, true); 68 69 if ( !rDoc.IsDefaultTabBgColor(i) ) 70 { 71 aTabBgColor = rDoc.GetTabBgColor(i); 72 SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor ); 73 } 74 } 75 } 76 } 77 78 SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 ); 79 80 SetSizePixel( Size(SC_TABBAR_DEFWIDTH, 0) ); 81 82 SetSplitHdl( LINK( pViewData->GetView(), ScTabView, TabBarResize ) ); 83 84 EnableEditMode(); 85 UpdateInputContext(); 86 87 SetScrollAlwaysEnabled(false); 88 89 SetScrollAreaContextHdl( LINK( this, ScTabControl, ShowPageList ) ); 90 } 91 92 IMPL_LINK(ScTabControl, ShowPageList, const CommandEvent &, rEvent, void) 93 { 94 tools::Rectangle aRect(rEvent.GetMousePosPixel(), Size(1, 1)); 95 weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect); 96 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "modules/scalc/ui/pagelistmenu.ui")); 97 std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu("menu")); 98 99 sal_uInt16 nCurPageId = GetCurPageId(); 100 101 ScDocument& rDoc = pViewData->GetDocument(); 102 SCTAB nCount = rDoc.GetTableCount(); 103 for (SCTAB i=0; i<nCount; ++i) 104 { 105 if (!rDoc.IsVisible(i)) 106 continue; 107 OUString aString; 108 if (!rDoc.GetName(i, aString)) 109 continue; 110 sal_uInt16 nId = static_cast<sal_uInt16>(i)+1; 111 OUString sId = OUString::number(nId); 112 xPopup->append_radio(sId, aString); 113 if (nId == nCurPageId) 114 xPopup->set_active(sId.toUtf8(), true); 115 } 116 117 OString sIdent(xPopup->popup_at_rect(pPopupParent, aRect)); 118 if (!sIdent.isEmpty()) 119 SwitchToPageId(sIdent.toUInt32()); 120 } 121 122 ScTabControl::~ScTabControl() 123 { 124 disposeOnce(); 125 } 126 127 void ScTabControl::dispose() 128 { 129 DragSourceHelper::dispose(); 130 DropTargetHelper::dispose(); 131 TabBar::dispose(); 132 } 133 134 sal_uInt16 ScTabControl::GetMaxId() const 135 { 136 sal_uInt16 nVisCnt = GetPageCount(); 137 if (nVisCnt) 138 return GetPageId(nVisCnt-1); 139 140 return 0; 141 } 142 143 SCTAB ScTabControl::GetPrivatDropPos(const Point& rPos ) 144 { 145 sal_uInt16 nPos = ShowDropPos(rPos); 146 147 SCTAB nRealPos = static_cast<SCTAB>(nPos); 148 149 if(nPos !=0 ) 150 { 151 ScDocument& rDoc = pViewData->GetDocument(); 152 153 SCTAB nCount = rDoc.GetTableCount(); 154 155 sal_uInt16 nViewPos=0; 156 nRealPos = nCount; 157 for (SCTAB i=0; i<nCount; i++) 158 { 159 if (rDoc.IsVisible(i)) 160 { 161 nViewPos++; 162 if(nViewPos==nPos) 163 { 164 SCTAB j; 165 for (j=i+1; j<nCount; j++) 166 { 167 if (rDoc.IsVisible(j)) 168 { 169 break; 170 } 171 } 172 nRealPos =j; 173 break; 174 } 175 } 176 } 177 } 178 return nRealPos ; 179 } 180 181 void ScTabControl::MouseButtonDown( const MouseEvent& rMEvt ) 182 { 183 ScModule* pScMod = SC_MOD(); 184 if ( !pScMod->IsModalMode() && !pScMod->IsFormulaMode() && !IsInEditMode() ) 185 { 186 // activate View 187 pViewData->GetViewShell()->SetActive(); // Appear and SetViewFrame 188 pViewData->GetView()->ActiveGrabFocus(); 189 } 190 191 if (rMEvt.IsLeft() && rMEvt.GetModifier() == 0) 192 nMouseClickPageId = GetPageId(rMEvt.GetPosPixel()); 193 194 TabBar::MouseButtonDown( rMEvt ); 195 } 196 197 void ScTabControl::MouseButtonUp( const MouseEvent& rMEvt ) 198 { 199 Point aPos = PixelToLogic( rMEvt.GetPosPixel() ); 200 201 // mouse button down and up on same page? 202 if( nMouseClickPageId != GetPageId(aPos)) 203 nMouseClickPageId = TabBar::PAGE_NOT_FOUND; 204 205 if ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() && nMouseClickPageId != 0 && nMouseClickPageId != TabBar::PAGE_NOT_FOUND ) 206 { 207 SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame()->GetDispatcher(); 208 pDispatcher->Execute( FID_TAB_MENU_RENAME, SfxCallMode::SYNCHRON | SfxCallMode::RECORD ); 209 return; 210 } 211 212 if( nMouseClickPageId == 0 ) 213 { 214 // Click in the area next to the existing tabs: 215 // #i70320# if several sheets are selected, deselect all except the current sheet, 216 // otherwise add new sheet 217 sal_uInt16 nSlot = ( GetSelectPageCount() > 1 ) ? FID_TAB_DESELECTALL : FID_INS_TABLE; 218 SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame()->GetDispatcher(); 219 pDispatcher->Execute( nSlot, SfxCallMode::SYNCHRON | SfxCallMode::RECORD ); 220 // forget page ID, to be really sure that the dialog is not called twice 221 nMouseClickPageId = TabBar::PAGE_NOT_FOUND; 222 } 223 224 TabBar::MouseButtonUp( rMEvt ); 225 } 226 227 void ScTabControl::AddTabClick() 228 { 229 TabBar::AddTabClick(); 230 231 // Insert a new sheet at the right end, with default name. 232 ScDocument& rDoc = pViewData->GetDocument(); 233 ScModule* pScMod = SC_MOD(); 234 if (!rDoc.IsDocEditable() || pScMod->IsTableLocked()) 235 return; 236 OUString aName; 237 rDoc.CreateValidTabName(aName); 238 SCTAB nTabCount = rDoc.GetTableCount(); 239 pViewData->GetViewShell()->InsertTable(aName, nTabCount); 240 } 241 242 void ScTabControl::Select() 243 { 244 /* Remember last clicked page ID. */ 245 nSelPageIdByMouse = nMouseClickPageId; 246 /* Reset nMouseClickPageId, so that next Select() call may invalidate 247 nSelPageIdByMouse (i.e. if called from keyboard). */ 248 nMouseClickPageId = TabBar::PAGE_NOT_FOUND; 249 250 ScModule* pScMod = SC_MOD(); 251 ScDocument& rDoc = pViewData->GetDocument(); 252 ScMarkData& rMark = pViewData->GetMarkData(); 253 SCTAB nCount = rDoc.GetTableCount(); 254 SCTAB i; 255 256 if ( pScMod->IsTableLocked() ) // may not be switched now ? 257 { 258 // restore the old state of TabControls 259 260 for (i=0; i<nCount; i++) 261 SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) ); 262 SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 ); 263 264 return; 265 } 266 267 sal_uInt16 nCurId = GetCurPageId(); 268 if (!nCurId) return; // for Excel import it can happen that everything is hidden 269 sal_uInt16 nPage = nCurId - 1; 270 271 // OLE-inplace deactivate 272 if ( nPage != static_cast<sal_uInt16>(pViewData->GetTabNo()) ) 273 pViewData->GetView()->DrawMarkListHasChanged(); 274 275 // InputEnterHandler onlw when not reference input 276 277 bool bRefMode = pScMod->IsFormulaMode(); 278 if (!bRefMode) 279 pScMod->InputEnterHandler(); 280 281 for (i=0; i<nCount; i++) 282 rMark.SelectTable( i, IsPageSelected(static_cast<sal_uInt16>(i)+1) ); 283 284 SfxDispatcher& rDisp = pViewData->GetDispatcher(); 285 if (rDisp.IsLocked()) 286 pViewData->GetView()->SetTabNo( static_cast<SCTAB>(nPage) ); 287 else 288 { 289 // sheet for basic is 1-based 290 SfxUInt16Item aItem( SID_CURRENTTAB, nPage + 1 ); 291 rDisp.ExecuteList(SID_CURRENTTAB, 292 SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem }); 293 } 294 295 SfxBindings& rBind = pViewData->GetBindings(); 296 rBind.Invalidate( FID_FILL_TAB ); 297 rBind.Invalidate( FID_TAB_DESELECTALL ); 298 299 rBind.Invalidate( FID_INS_TABLE ); 300 rBind.Invalidate( FID_TAB_APPEND ); 301 rBind.Invalidate( FID_TAB_MOVE ); 302 rBind.Invalidate( FID_TAB_RENAME ); 303 rBind.Invalidate( FID_DELETE_TABLE ); 304 rBind.Invalidate( FID_TABLE_SHOW ); 305 rBind.Invalidate( FID_TABLE_HIDE ); 306 rBind.Invalidate( FID_TAB_SET_TAB_BG_COLOR ); 307 308 // Recalculate status bar functions. 309 rBind.Invalidate( SID_TABLE_CELL ); 310 311 // SetReference onlw when the consolidate dialog is open 312 // (for references over multiple sheets) 313 // for others this is only needed fidgeting 314 315 if ( bRefMode && pViewData->GetRefType() == SC_REFTYPE_REF ) 316 if ( pViewData->GetViewShell()->GetViewFrame()->HasChildWindow(SID_OPENDLG_CONSOLIDATE) ) 317 { 318 ScRange aRange( 319 pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(), 320 pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() ); 321 pScMod->SetReference( aRange, rDoc, &rMark ); 322 pScMod->EndReference(); // due to Auto-Hide 323 } 324 } 325 326 void ScTabControl::UpdateInputContext() 327 { 328 ScDocument& rDoc = pViewData->GetDocument(); 329 WinBits nStyle = GetStyle(); 330 if (rDoc.GetDocumentShell()->IsReadOnly()) 331 // no insert sheet tab for readonly doc. 332 SetStyle(nStyle & ~WB_INSERTTAB); 333 else 334 SetStyle(nStyle | WB_INSERTTAB); 335 } 336 337 void ScTabControl::UpdateStatus() 338 { 339 ScDocument& rDoc = pViewData->GetDocument(); 340 ScMarkData& rMark = pViewData->GetMarkData(); 341 bool bActive = pViewData->IsActive(); 342 343 SCTAB nCount = rDoc.GetTableCount(); 344 SCTAB i; 345 OUString aString; 346 SCTAB nMaxCnt = std::max( nCount, static_cast<SCTAB>(GetMaxId()) ); 347 Color aTabBgColor; 348 349 bool bModified = false; // sheet name 350 for (i=0; i<nMaxCnt && !bModified; i++) 351 { 352 if (rDoc.IsVisible(i)) 353 { 354 rDoc.GetName(i,aString); 355 aTabBgColor = rDoc.GetTabBgColor(i); 356 } 357 else 358 { 359 aString.clear(); 360 } 361 362 if ( aString != GetPageText(static_cast<sal_uInt16>(i)+1) || (GetTabBgColor(static_cast<sal_uInt16>(i)+1) != aTabBgColor) ) 363 bModified = true; 364 } 365 366 if (bModified) 367 { 368 Clear(); 369 for (i=0; i<nCount; i++) 370 { 371 if (rDoc.IsVisible(i)) 372 { 373 if (rDoc.GetName(i,aString)) 374 { 375 if ( rDoc.IsScenario(i) ) 376 InsertPage(static_cast<sal_uInt16>(i)+1, aString, TabBarPageBits::Blue); 377 else 378 InsertPage( static_cast<sal_uInt16>(i)+1, aString ); 379 380 if ( rDoc.IsTabProtected(i) ) 381 SetProtectionSymbol(static_cast<sal_uInt16>(i)+1, true); 382 383 if ( !rDoc.IsDefaultTabBgColor(i) ) 384 { 385 aTabBgColor = rDoc.GetTabBgColor(i); 386 SetTabBgColor(static_cast<sal_uInt16>(i)+1, aTabBgColor ); 387 } 388 } 389 } 390 } 391 } 392 SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 ); 393 394 if (bActive) 395 { 396 bModified = false; // selection 397 for (i=0; i<nMaxCnt && !bModified; i++) 398 if ( rMark.GetTableSelect(i) != IsPageSelected(static_cast<sal_uInt16>(i)+1) ) 399 bModified = true; 400 401 if ( bModified ) 402 for (i=0; i<nCount; i++) 403 SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) ); 404 } 405 } 406 407 void ScTabControl::SetSheetLayoutRTL( bool bSheetRTL ) 408 { 409 SetEffectiveRTL( bSheetRTL ); 410 nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; 411 } 412 413 void ScTabControl::SwitchToPageId(sal_uInt16 nId) 414 { 415 if (!nId) 416 return; 417 418 bool bAlreadySelected = IsPageSelected( nId ); 419 //make the clicked page the current one 420 SetCurPageId( nId ); 421 //change the selection when the current one is not already 422 //selected or part of a multi selection 423 if(bAlreadySelected) 424 return; 425 426 sal_uInt16 nCount = GetMaxId(); 427 428 for (sal_uInt16 i=1; i<=nCount; i++) 429 SelectPage( i, i==nId ); 430 Select(); 431 432 if (comphelper::LibreOfficeKit::isActive()) 433 { 434 // notify LibreOfficeKit about changed page 435 OString aPayload = OString::number(nId - 1); 436 pViewData->GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SET_PART, aPayload.getStr()); 437 } 438 } 439 440 void ScTabControl::Command( const CommandEvent& rCEvt ) 441 { 442 ScModule* pScMod = SC_MOD(); 443 ScTabViewShell* pViewSh = pViewData->GetViewShell(); 444 bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode(); 445 446 // first activate ViewFrame (Bug 19493): 447 pViewSh->SetActive(); 448 449 if (rCEvt.GetCommand() != CommandEventId::ContextMenu || bDisable) 450 return; 451 452 // #i18735# select the page that is under the mouse cursor 453 // if multiple tables are selected and the one under the cursor 454 // is not part of them then unselect them 455 sal_uInt16 nId = GetPageId( rCEvt.GetMousePosPixel() ); 456 SwitchToPageId(nId); 457 458 // #i52073# OLE inplace editing has to be stopped before showing the sheet tab context menu 459 pViewSh->DeactivateOle(); 460 461 // Popup-Menu: 462 // get Dispatcher from ViewData (ViewFrame) instead of Shell (Frame), so it can't be null 463 pViewData->GetDispatcher().ExecutePopup( "sheettab" ); 464 } 465 466 void ScTabControl::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel ) 467 { 468 ScModule* pScMod = SC_MOD(); 469 bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode(); 470 471 if (!bDisable) 472 { 473 vcl::Region aRegion( tools::Rectangle(0,0,0,0) ); 474 CommandEvent aCEvt( rPosPixel, CommandEventId::StartDrag, true ); // needed for StartDrag 475 if (TabBar::StartDrag( aCEvt, aRegion )) 476 DoDrag(); 477 } 478 } 479 480 void ScTabControl::DoDrag() 481 { 482 ScDocShell* pDocSh = pViewData->GetDocShell(); 483 ScDocument& rDoc = pDocSh->GetDocument(); 484 485 SCTAB nTab = pViewData->GetTabNo(); 486 ScRange aTabRange( 0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab ); 487 ScMarkData aTabMark = pViewData->GetMarkData(); 488 aTabMark.ResetMark(); // doesn't change marked table information 489 aTabMark.SetMarkArea( aTabRange ); 490 491 ScDocumentUniquePtr pClipDoc(new ScDocument( SCDOCMODE_CLIP )); 492 ScClipParam aClipParam(aTabRange, false); 493 rDoc.CopyToClip(aClipParam, pClipDoc.get(), &aTabMark, false, false); 494 495 TransferableObjectDescriptor aObjDesc; 496 pDocSh->FillTransferableObjectDescriptor( aObjDesc ); 497 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); 498 // maSize is set in ScTransferObj ctor 499 500 rtl::Reference<ScTransferObj> pTransferObj = new ScTransferObj( std::move(pClipDoc), aObjDesc ); 501 502 pTransferObj->SetDragSourceFlags(ScDragSrc::Table); 503 504 pTransferObj->SetDragSource( pDocSh, aTabMark ); 505 506 pTransferObj->SetSourceCursorPos( pViewData->GetCurX(), pViewData->GetCurY() ); 507 508 vcl::Window* pWindow = pViewData->GetActiveWin(); 509 SC_MOD()->SetDragObject( pTransferObj.get(), nullptr ); // for internal D&D 510 pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK ); 511 } 512 513 static sal_uInt16 lcl_DocShellNr( const ScDocument& rDoc ) 514 { 515 sal_uInt16 nShellCnt = 0; 516 SfxObjectShell* pShell = SfxObjectShell::GetFirst(); 517 while ( pShell ) 518 { 519 if ( auto pDocShell = dynamic_cast<const ScDocShell *>(pShell) ) 520 { 521 if ( &pDocShell->GetDocument() == &rDoc ) 522 return nShellCnt; 523 524 ++nShellCnt; 525 } 526 pShell = SfxObjectShell::GetNext( *pShell ); 527 } 528 529 OSL_FAIL("Document not found"); 530 return 0; 531 } 532 533 sal_Int8 ScTabControl::ExecuteDrop( const ExecuteDropEvent& rEvt ) 534 { 535 EndSwitchPage(); 536 537 ScDocument& rDoc = pViewData->GetDocument(); 538 const ScDragData& rData = SC_MOD()->GetDragData(); 539 if ( rData.pCellTransfer && (rData.pCellTransfer->GetDragSourceFlags() & ScDragSrc::Table) && 540 rData.pCellTransfer->GetSourceDocument() == &rDoc ) 541 { 542 // moving of tables within the document 543 SCTAB nPos = GetPrivatDropPos( rEvt.maPosPixel ); 544 HideDropPos(); 545 546 if ( nPos == rData.pCellTransfer->GetVisibleTab() && rEvt.mnAction == DND_ACTION_MOVE ) 547 { 548 // #i83005# do nothing - don't move to the same position 549 // (too easily triggered unintentionally, and might take a long time in large documents) 550 } 551 else 552 { 553 if ( !rDoc.GetChangeTrack() && rDoc.IsDocEditable() ) 554 { 555 //! use table selection from the tab control where dragging was started? 556 pViewData->GetView()->MoveTable( lcl_DocShellNr(rDoc), nPos, rEvt.mnAction != DND_ACTION_MOVE ); 557 558 rData.pCellTransfer->SetDragWasInternal(); // don't delete 559 return DND_ACTION_COPY; 560 } 561 } 562 } 563 564 return DND_ACTION_NONE; 565 } 566 567 sal_Int8 ScTabControl::AcceptDrop( const AcceptDropEvent& rEvt ) 568 { 569 if ( rEvt.mbLeaving ) 570 { 571 EndSwitchPage(); 572 HideDropPos(); 573 return rEvt.mnAction; 574 } 575 576 const ScDocument& rDoc = pViewData->GetDocument(); 577 const ScDragData& rData = SC_MOD()->GetDragData(); 578 if ( rData.pCellTransfer && (rData.pCellTransfer->GetDragSourceFlags() & ScDragSrc::Table) && 579 rData.pCellTransfer->GetSourceDocument() == &rDoc ) 580 { 581 // moving of tables within the document 582 if ( !rDoc.GetChangeTrack() && rDoc.IsDocEditable() ) 583 { 584 ShowDropPos( rEvt.maPosPixel ); 585 return rEvt.mnAction; 586 } 587 } 588 else // switch sheets for all formats 589 { 590 SwitchPage( rEvt.maPosPixel ); // switch sheet after timeout 591 return 0; // nothing can be dropped here 592 } 593 594 return 0; 595 } 596 597 bool ScTabControl::StartRenaming() 598 { 599 return pViewData->GetDocument().IsDocEditable(); 600 } 601 602 TabBarAllowRenamingReturnCode ScTabControl::AllowRenaming() 603 { 604 ScTabViewShell* pViewSh = pViewData->GetViewShell(); 605 OSL_ENSURE( pViewSh, "pViewData->GetViewShell()" ); 606 607 TabBarAllowRenamingReturnCode nRet = TABBAR_RENAMING_CANCEL; 608 sal_uInt16 nId = GetEditPageId(); 609 if ( nId ) 610 { 611 SCTAB nTab = nId - 1; 612 OUString aNewName = GetEditText(); 613 bool bDone = pViewSh->RenameTable( aNewName, nTab ); 614 if ( bDone ) 615 nRet = TABBAR_RENAMING_YES; 616 else if ( bErrorShown ) 617 { 618 // if the error message from this TabControl is currently visible, 619 // don't end edit mode now, to avoid problems when returning to 620 // the other call (showing the error) - this should not happen 621 OSL_FAIL("ScTabControl::AllowRenaming: nested calls"); 622 nRet = TABBAR_RENAMING_NO; 623 } 624 else if (pViewData->GetDocShell()->IsInModalMode()) 625 { 626 // don't show error message above any modal dialog 627 // instead cancel renaming without error message 628 // e.g. start with default Sheet1, add another sheet 629 // alt+left click on Sheet2 tab, edit to say Sheet1 630 // ctrl+S to trigger modal file save dialog 631 nRet = TABBAR_RENAMING_CANCEL; 632 } 633 else 634 { 635 bErrorShown = true; 636 pViewSh->ErrorMessage( STR_INVALIDTABNAME ); 637 bErrorShown = false; 638 nRet = TABBAR_RENAMING_NO; 639 } 640 } 641 return nRet; 642 } 643 644 void ScTabControl::EndRenaming() 645 { 646 if ( HasFocus() ) 647 pViewData->GetView()->ActiveGrabFocus(); 648 } 649 650 void ScTabControl::Mirror() 651 { 652 TabBar::Mirror(); 653 if( nSelPageIdByMouse != TabBar::PAGE_NOT_FOUND ) 654 { 655 tools::Rectangle aRect( GetPageRect( GetCurPageId() ) ); 656 if( !aRect.IsEmpty() ) 657 SetPointerPosPixel( aRect.Center() ); 658 nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; // only once after a Select() 659 } 660 } 661 662 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 663
