tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / tabcont.cxx
blobaa2ed2895ba1198f869ee4b0c472bcb38fac41d6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <osl/diagnose.h>
21 #include <sfx2/viewfrm.hxx>
22 #include <sfx2/dispatch.hxx>
23 #include <sfx2/docfile.hxx>
24 #include <tools/urlobj.hxx>
25 #include <vcl/commandevent.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/weldutils.hxx>
28 #include <tabcont.hxx>
29 #include <tabvwsh.hxx>
30 #include <docsh.hxx>
31 #include <scmod.hxx>
32 #include <sc.hrc>
33 #include <globstr.hrc>
34 #include <transobj.hxx>
35 #include <clipparam.hxx>
36 #include <dragdata.hxx>
37 #include <markdata.hxx>
38 #include <gridwin.hxx>
39 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
40 #include <comphelper/lok.hxx>
42 ScTabControl::ScTabControl( vcl::Window* pParent, ScViewData* pData )
43 : TabBar(pParent, WB_3DLOOK | WB_MINSCROLL | WB_SCROLL | WB_RANGESELECT | WB_MULTISELECT | WB_DRAG, true)
44 , DropTargetHelper(this)
45 , DragSourceHelper(this)
46 , pViewData(pData)
47 , nMouseClickPageId(TabBar::PAGE_NOT_FOUND)
48 , nSelPageIdByMouse(TabBar::PAGE_NOT_FOUND)
49 , bErrorShown(false)
51 ScDocument& rDoc = pViewData->GetDocument();
53 OUString aString;
54 Color aTabBgColor;
55 SCTAB nCount = rDoc.GetTableCount();
56 for (SCTAB i=0; i<nCount; i++)
58 if (!rDoc.IsVisible(i))
59 continue;
61 if (!rDoc.GetName(i,aString))
62 continue;
64 if ( rDoc.IsScenario(i) )
65 InsertPage( static_cast<sal_uInt16>(i)+1, aString, TabBarPageBits::Blue);
66 else
67 InsertPage( static_cast<sal_uInt16>(i)+1, aString );
69 if ( rDoc.IsTabProtected(i) )
70 SetProtectionSymbol(static_cast<sal_uInt16>(i)+1, true);
72 if ( !rDoc.IsDefaultTabBgColor(i) )
74 aTabBgColor = rDoc.GetTabBgColor(i);
75 SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor );
79 SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 );
81 SetSizePixel( Size(SC_TABBAR_DEFWIDTH, 0) );
83 SetSplitHdl( LINK( pViewData->GetView(), ScTabView, TabBarResize ) );
85 EnableEditMode();
86 UpdateInputContext();
88 SetScrollAlwaysEnabled(false);
90 SetScrollAreaContextHdl( LINK( this, ScTabControl, ShowPageList ) );
93 IMPL_LINK(ScTabControl, ShowPageList, const CommandEvent &, rEvent, void)
95 tools::Rectangle aRect(rEvent.GetMousePosPixel(), Size(1, 1));
96 weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect);
97 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, u"modules/scalc/ui/pagelistmenu.ui"_ustr));
98 std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu(u"menu"_ustr));
100 sal_uInt16 nCurPageId = GetCurPageId();
102 ScDocument& rDoc = pViewData->GetDocument();
103 SCTAB nCount = rDoc.GetTableCount();
104 for (SCTAB i=0; i<nCount; ++i)
106 if (!rDoc.IsVisible(i))
107 continue;
108 OUString aString;
109 if (!rDoc.GetName(i, aString))
110 continue;
111 sal_uInt16 nId = static_cast<sal_uInt16>(i)+1;
112 OUString sId = OUString::number(nId);
113 xPopup->append_radio(sId, aString);
114 if (nId == nCurPageId)
115 xPopup->set_active(sId, true);
118 OUString sIdent(xPopup->popup_at_rect(pPopupParent, aRect));
119 if (!sIdent.isEmpty())
120 SwitchToPageId(sIdent.toUInt32());
123 ScTabControl::~ScTabControl()
125 disposeOnce();
128 void ScTabControl::dispose()
130 DragSourceHelper::dispose();
131 DropTargetHelper::dispose();
132 TabBar::dispose();
135 sal_uInt16 ScTabControl::GetMaxId() const
137 sal_uInt16 nVisCnt = GetPageCount();
138 if (nVisCnt)
139 return GetPageId(nVisCnt-1);
141 return 0;
144 SCTAB ScTabControl::GetPrivatDropPos(const Point& rPos )
146 sal_uInt16 nPos = ShowDropPos(rPos);
148 SCTAB nRealPos = static_cast<SCTAB>(nPos);
150 if(nPos !=0 )
152 ScDocument& rDoc = pViewData->GetDocument();
154 SCTAB nCount = rDoc.GetTableCount();
156 sal_uInt16 nViewPos=0;
157 nRealPos = nCount;
158 for (SCTAB i=0; i<nCount; i++)
160 if (rDoc.IsVisible(i))
162 nViewPos++;
163 if(nViewPos==nPos)
165 SCTAB j;
166 for (j=i+1; j<nCount; j++)
168 if (rDoc.IsVisible(j))
170 break;
173 nRealPos =j;
174 break;
179 return nRealPos ;
182 void ScTabControl::MouseButtonDown( const MouseEvent& rMEvt )
184 ScModule* pScMod = ScModule::get();
185 if ( !pScMod->IsModalMode() && !pScMod->IsFormulaMode() && !IsInEditMode() )
187 // activate View
188 pViewData->GetViewShell()->SetActive(); // Appear and SetViewFrame
189 pViewData->GetView()->ActiveGrabFocus();
192 if (rMEvt.IsLeft() && rMEvt.GetModifier() == 0)
193 nMouseClickPageId = GetPageId(rMEvt.GetPosPixel());
195 TabBar::MouseButtonDown( rMEvt );
198 void ScTabControl::MouseButtonUp( const MouseEvent& rMEvt )
200 Point aPos = PixelToLogic( rMEvt.GetPosPixel() );
202 // mouse button down and up on same page?
203 if( nMouseClickPageId != GetPageId(aPos))
204 nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
206 if ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() && nMouseClickPageId != 0 && nMouseClickPageId != TabBar::PAGE_NOT_FOUND )
208 SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame().GetDispatcher();
209 pDispatcher->Execute( FID_TAB_MENU_RENAME, SfxCallMode::SYNCHRON | SfxCallMode::RECORD );
210 return;
213 if( nMouseClickPageId == 0 )
215 // Click in the area next to the existing tabs:
216 SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame().GetDispatcher();
217 pDispatcher->Execute( FID_TAB_DESELECTALL, SfxCallMode::SYNCHRON | SfxCallMode::RECORD );
218 // forget page ID, to be really sure that the dialog is not called twice
219 nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
222 TabBar::MouseButtonUp( rMEvt );
225 void ScTabControl::AddTabClick()
227 TabBar::AddTabClick();
229 // Insert a new sheet at the right end, with default name.
230 ScDocument& rDoc = pViewData->GetDocument();
231 ScModule* pScMod = ScModule::get();
232 if (!rDoc.IsDocEditable() || pScMod->IsTableLocked())
233 return;
235 // auto-accept any in-process input - which would otherwise end up on the new sheet
236 if (!pScMod->IsFormulaMode())
237 pScMod->InputEnterHandler();
239 OUString aName;
240 rDoc.CreateValidTabName(aName);
241 SCTAB nTabCount = rDoc.GetTableCount();
242 pViewData->GetViewShell()->InsertTable(aName, nTabCount);
243 if (!pScMod->IsModalMode() && !pScMod->IsFormulaMode() && !IsInEditMode())
244 pViewData->GetViewShell()->SetActive();
247 void ScTabControl::Select()
249 /* Remember last clicked page ID. */
250 nSelPageIdByMouse = nMouseClickPageId;
251 /* Reset nMouseClickPageId, so that next Select() call may invalidate
252 nSelPageIdByMouse (i.e. if called from keyboard). */
253 nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
255 ScModule* pScMod = ScModule::get();
256 ScDocument& rDoc = pViewData->GetDocument();
257 ScMarkData& rMark = pViewData->GetMarkData();
258 SCTAB nCount = rDoc.GetTableCount();
259 SCTAB i;
261 if ( pScMod->IsTableLocked() ) // may not be switched now ?
263 // restore the old state of TabControls
265 for (i=0; i<nCount; i++)
266 SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) );
267 SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 );
269 return;
272 sal_uInt16 nCurId = GetCurPageId();
273 if (!nCurId) return; // for Excel import it can happen that everything is hidden
274 sal_uInt16 nPage = nCurId - 1;
276 // OLE-inplace deactivate
277 if ( nPage != static_cast<sal_uInt16>(pViewData->GetTabNo()) )
278 pViewData->GetView()->DrawMarkListHasChanged();
280 // InputEnterHandler onlw when not reference input
282 bool bRefMode = pScMod->IsFormulaMode();
283 if (!bRefMode)
284 pScMod->InputEnterHandler();
286 for (i=0; i<nCount; i++)
287 rMark.SelectTable( i, IsPageSelected(static_cast<sal_uInt16>(i)+1) );
289 SfxDispatcher& rDisp = pViewData->GetDispatcher();
290 if (rDisp.IsLocked())
291 pViewData->GetView()->SetTabNo( static_cast<SCTAB>(nPage) );
292 else
294 // sheet for basic is 1-based
295 SfxUInt16Item aItem( SID_CURRENTTAB, nPage + 1 );
296 rDisp.ExecuteList(SID_CURRENTTAB,
297 SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem });
300 SfxBindings& rBind = pViewData->GetBindings();
301 rBind.Invalidate( FID_FILL_TAB );
302 rBind.Invalidate( FID_TAB_DESELECTALL );
304 rBind.Invalidate( FID_INS_TABLE );
305 rBind.Invalidate( FID_TAB_APPEND );
306 rBind.Invalidate( FID_TAB_MOVE );
307 rBind.Invalidate( FID_TAB_DUPLICATE );
308 rBind.Invalidate( FID_TAB_RENAME );
309 rBind.Invalidate( FID_DELETE_TABLE );
310 rBind.Invalidate( FID_TABLE_SHOW );
311 rBind.Invalidate( FID_TABLE_HIDE );
312 rBind.Invalidate( FID_TAB_SET_TAB_BG_COLOR );
314 // Recalculate status bar functions.
315 rBind.Invalidate( SID_TABLE_CELL );
317 // SetReference onlw when the consolidate dialog is open
318 // (for references over multiple sheets)
319 // for others this is only needed fidgeting
321 if ( bRefMode && pViewData->GetRefType() == SC_REFTYPE_REF )
322 if ( pViewData->GetViewShell()->GetViewFrame().HasChildWindow(SID_OPENDLG_CONSOLIDATE) )
324 ScRange aRange(
325 pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(),
326 pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() );
327 pScMod->SetReference( aRange, rDoc, &rMark );
328 pScMod->EndReference(); // due to Auto-Hide
332 void ScTabControl::UpdateInputContext()
334 ScDocument& rDoc = pViewData->GetDocument();
335 WinBits nStyle = GetStyle();
336 if (rDoc.GetDocumentShell()->IsReadOnly())
337 // no insert sheet tab for readonly doc.
338 SetStyle(nStyle & ~WB_INSERTTAB);
339 else
340 SetStyle(nStyle | WB_INSERTTAB);
343 void ScTabControl::UpdateStatus()
345 ScDocument& rDoc = pViewData->GetDocument();
346 ScMarkData& rMark = pViewData->GetMarkData();
347 bool bActive = pViewData->IsActive();
349 SCTAB nCount = rDoc.GetTableCount();
350 SCTAB i;
351 OUString aString;
352 SCTAB nMaxCnt = std::max( nCount, static_cast<SCTAB>(GetMaxId()) );
353 Color aTabBgColor;
355 bool bModified = false; // sheet name
356 for (i=0; i<nMaxCnt && !bModified; i++)
358 if (rDoc.IsVisible(i))
360 rDoc.GetName(i,aString);
361 aTabBgColor = rDoc.GetTabBgColor(i);
363 else
365 aString.clear();
368 if ( aString != GetPageText(static_cast<sal_uInt16>(i)+1) || (GetTabBgColor(static_cast<sal_uInt16>(i)+1) != aTabBgColor) )
369 bModified = true;
372 if (bModified)
374 Clear();
375 for (i=0; i<nCount; i++)
377 if (rDoc.IsVisible(i))
379 if (rDoc.GetName(i,aString))
381 if ( rDoc.IsScenario(i) )
382 InsertPage(static_cast<sal_uInt16>(i)+1, aString, TabBarPageBits::Blue);
383 else
384 InsertPage( static_cast<sal_uInt16>(i)+1, aString );
386 if ( rDoc.IsTabProtected(i) )
387 SetProtectionSymbol(static_cast<sal_uInt16>(i)+1, true);
389 if ( !rDoc.IsDefaultTabBgColor(i) )
391 aTabBgColor = rDoc.GetTabBgColor(i);
392 SetTabBgColor(static_cast<sal_uInt16>(i)+1, aTabBgColor );
398 SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 );
400 if (bActive)
402 bModified = false; // selection
403 for (i=0; i<nMaxCnt && !bModified; i++)
404 if ( rMark.GetTableSelect(i) != IsPageSelected(static_cast<sal_uInt16>(i)+1) )
405 bModified = true;
407 if ( bModified )
408 for (i=0; i<nCount; i++)
409 SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) );
413 void ScTabControl::SetSheetLayoutRTL( bool bSheetRTL )
415 SetEffectiveRTL( bSheetRTL );
416 nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND;
419 void ScTabControl::SwitchToPageId(sal_uInt16 nId)
421 if (!nId)
422 return;
424 bool bAlreadySelected = IsPageSelected( nId );
425 //make the clicked page the current one
426 SetCurPageId( nId );
427 //change the selection when the current one is not already
428 //selected or part of a multi selection
429 if(bAlreadySelected)
430 return;
432 sal_uInt16 nCount = GetMaxId();
434 for (sal_uInt16 i=1; i<=nCount; i++)
435 SelectPage( i, i==nId );
436 Select();
438 if (comphelper::LibreOfficeKit::isActive())
440 // notify LibreOfficeKit about changed page
441 OString aPayload = OString::number(nId - 1);
442 pViewData->GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_SET_PART, aPayload);
446 void ScTabControl::Command( const CommandEvent& rCEvt )
448 ScModule* pScMod = ScModule::get();
449 ScTabViewShell* pViewSh = pViewData->GetViewShell();
450 bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
452 // first activate ViewFrame (Bug 19493):
453 pViewSh->SetActive();
455 if (rCEvt.GetCommand() != CommandEventId::ContextMenu || bDisable)
456 return;
458 // #i18735# select the page that is under the mouse cursor
459 // if multiple tables are selected and the one under the cursor
460 // is not part of them then unselect them
461 sal_uInt16 nId = GetPageId( rCEvt.GetMousePosPixel() );
462 SwitchToPageId(nId);
464 // #i52073# OLE inplace editing has to be stopped before showing the sheet tab context menu
465 pViewSh->DeactivateOle();
467 // Popup-Menu:
468 // get Dispatcher from ViewData (ViewFrame) instead of Shell (Frame), so it can't be null
469 pViewData->GetDispatcher().ExecutePopup( u"sheettab"_ustr );
472 void ScTabControl::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
474 ScModule* pScMod = ScModule::get();
475 bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
477 if (!bDisable)
479 vcl::Region aRegion( tools::Rectangle(0,0,0,0) );
480 CommandEvent aCEvt( rPosPixel, CommandEventId::StartDrag, true ); // needed for StartDrag
481 if (TabBar::StartDrag( aCEvt, aRegion ))
482 DoDrag();
486 void ScTabControl::DoDrag()
488 ScDocShell* pDocSh = pViewData->GetDocShell();
489 ScDocument& rDoc = pDocSh->GetDocument();
491 SCTAB nTab = pViewData->GetTabNo();
492 ScRange aTabRange( 0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab );
493 ScMarkData aTabMark = pViewData->GetMarkData();
494 aTabMark.ResetMark(); // doesn't change marked table information
495 aTabMark.SetMarkArea( aTabRange );
497 ScDocumentUniquePtr pClipDoc(new ScDocument( SCDOCMODE_CLIP ));
498 ScClipParam aClipParam(aTabRange, false);
499 rDoc.CopyToClip(aClipParam, pClipDoc.get(), &aTabMark, false, false);
501 TransferableObjectDescriptor aObjDesc;
502 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
503 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
504 // maSize is set in ScTransferObj ctor
506 rtl::Reference<ScTransferObj> pTransferObj = new ScTransferObj( std::move(pClipDoc), std::move(aObjDesc) );
508 pTransferObj->SetDragSourceFlags(ScDragSrc::Table);
510 pTransferObj->SetDragSource( pDocSh, aTabMark );
512 pTransferObj->SetSourceCursorPos( pViewData->GetCurX(), pViewData->GetCurY() );
514 vcl::Window* pWindow = pViewData->GetActiveWin();
515 ScModule::get()->SetDragObject(pTransferObj.get(), nullptr); // for internal D&D
516 pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
519 static sal_uInt16 lcl_DocShellNr( const ScDocument& rDoc )
521 sal_uInt16 nShellCnt = 0;
522 SfxObjectShell* pShell = SfxObjectShell::GetFirst();
523 while ( pShell )
525 if ( auto pDocShell = dynamic_cast<const ScDocShell *>(pShell) )
527 if ( &pDocShell->GetDocument() == &rDoc )
528 return nShellCnt;
530 ++nShellCnt;
532 pShell = SfxObjectShell::GetNext( *pShell );
535 OSL_FAIL("Document not found");
536 return 0;
539 sal_Int8 ScTabControl::ExecuteDrop( const ExecuteDropEvent& rEvt )
541 EndSwitchPage();
543 ScDocument& rDoc = pViewData->GetDocument();
544 const ScDragData& rData = ScModule::get()->GetDragData();
545 if ( rData.pCellTransfer && (rData.pCellTransfer->GetDragSourceFlags() & ScDragSrc::Table) &&
546 rData.pCellTransfer->GetSourceDocument() == &rDoc )
548 // moving of tables within the document
549 SCTAB nPos = GetPrivatDropPos( rEvt.maPosPixel );
550 HideDropPos();
552 if ( nPos == rData.pCellTransfer->GetVisibleTab() && rEvt.mnAction == DND_ACTION_MOVE )
554 // #i83005# do nothing - don't move to the same position
555 // (too easily triggered unintentionally, and might take a long time in large documents)
557 else
559 if ( !rDoc.GetChangeTrack() && rDoc.IsDocEditable() )
561 //! use table selection from the tab control where dragging was started?
562 pViewData->GetView()->MoveTable( lcl_DocShellNr(rDoc), nPos, rEvt.mnAction != DND_ACTION_MOVE );
564 rData.pCellTransfer->SetDragWasInternal(); // don't delete
565 return DND_ACTION_COPY;
570 return DND_ACTION_NONE;
573 sal_Int8 ScTabControl::AcceptDrop( const AcceptDropEvent& rEvt )
575 if ( rEvt.mbLeaving )
577 EndSwitchPage();
578 HideDropPos();
579 return rEvt.mnAction;
582 const ScDocument& rDoc = pViewData->GetDocument();
583 const ScDragData& rData = ScModule::get()->GetDragData();
584 if ( rData.pCellTransfer && (rData.pCellTransfer->GetDragSourceFlags() & ScDragSrc::Table) &&
585 rData.pCellTransfer->GetSourceDocument() == &rDoc )
587 // moving of tables within the document
588 if ( !rDoc.GetChangeTrack() && rDoc.IsDocEditable() )
590 ShowDropPos( rEvt.maPosPixel );
591 return rEvt.mnAction;
594 else // switch sheets for all formats
596 SwitchPage( rEvt.maPosPixel ); // switch sheet after timeout
597 return 0; // nothing can be dropped here
600 return 0;
603 bool ScTabControl::StartRenaming()
605 return pViewData->GetDocument().IsDocEditable();
608 TabBarAllowRenamingReturnCode ScTabControl::AllowRenaming()
610 ScTabViewShell* pViewSh = pViewData->GetViewShell();
611 OSL_ENSURE( pViewSh, "pViewData->GetViewShell()" );
613 TabBarAllowRenamingReturnCode nRet = TABBAR_RENAMING_CANCEL;
614 sal_uInt16 nId = GetEditPageId();
615 if ( nId )
617 SCTAB nTab = nId - 1;
618 OUString aNewName = GetEditText();
619 bool bDone = pViewSh->RenameTable( aNewName, nTab );
620 if ( bDone )
621 nRet = TABBAR_RENAMING_YES;
622 else if ( bErrorShown )
624 // if the error message from this TabControl is currently visible,
625 // don't end edit mode now, to avoid problems when returning to
626 // the other call (showing the error) - this should not happen
627 OSL_FAIL("ScTabControl::AllowRenaming: nested calls");
628 nRet = TABBAR_RENAMING_NO;
630 else if (pViewData->GetDocShell()->IsInModalMode())
632 // don't show error message above any modal dialog
633 // instead cancel renaming without error message
634 // e.g. start with default Sheet1, add another sheet
635 // alt+left click on Sheet2 tab, edit to say Sheet1
636 // ctrl+S to trigger modal file save dialog
637 nRet = TABBAR_RENAMING_CANCEL;
639 else
641 bErrorShown = true;
642 pViewSh->ErrorMessage( STR_INVALIDTABNAME );
643 bErrorShown = false;
644 nRet = TABBAR_RENAMING_NO;
647 return nRet;
650 void ScTabControl::EndRenaming()
652 if ( HasFocus() )
653 pViewData->GetView()->ActiveGrabFocus();
656 void ScTabControl::Mirror()
658 TabBar::Mirror();
659 if( nSelPageIdByMouse != TabBar::PAGE_NOT_FOUND )
661 tools::Rectangle aRect( GetPageRect( GetCurPageId() ) );
662 if( !aRect.IsEmpty() )
663 SetPointerPosPixel( aRect.Center() );
664 nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; // only once after a Select()
668 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */