sc/source/core/data/document10.cxx             |    1 
 sc/source/ui/dialogs/SelectSheetViewDialog.cxx |    4 --
 sc/source/ui/inc/viewdata.hxx                  |    4 ++
 sc/source/ui/view/hdrcont.cxx                  |    3 +
 sc/source/ui/view/tabcont.cxx                  |   32 ++++++++++++++++----
 sc/source/ui/view/tabview3.cxx                 |    6 ++-
 sc/source/ui/view/viewdata.cxx                 |   40 ++++++++++++++++++++++++-
 sc/source/ui/view/viewfun3.cxx                 |    3 +
 8 files changed, 80 insertions(+), 13 deletions(-)

New commits:
commit b213f6f1e5cf2c90f10b9453489686b2f44d7c47
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Mon Mar 2 11:52:16 2026 +0900
Commit:     Miklos Vajna <[email protected]>
CommitDate: Tue Mar 3 08:45:57 2026 +0100

    sc: Hide sheet views in the tab bar and make switching seamless
    
    Sheet view tabs are now hidden in the tab bar. The tab bar displays
    the default tab as the current one when the user is on a (hidden)
    sheet view. Clicking a default tab restores the last active sheet
    view for that sheet, enabling seamless switching.
    
    If a sheet view tab is unhidden, the tab bar still correctly shows
    it as the current tab and allows independent selection of default
    and sheet view tabs.
    
    Change-Id: I200073496e2b803e58c5a0e7b36fecec2c8011e4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200749
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/source/core/data/document10.cxx 
b/sc/source/core/data/document10.cxx
index a55e0f5f1b44..92e0bbefc608 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -1155,6 +1155,7 @@ std::pair<sc::SheetViewID, SCTAB> 
ScDocument::CreateNewSheetView(SCTAB nTab)
             if (ScTable* pSheetViewTable = FetchTable(nSheetViewTab))
             {
                 auto nSheetViewID = 
pTable->GetSheetViewManager()->create(pSheetViewTable);
+                pSheetViewTable->SetVisible(false);
                 pSheetViewTable->SetSheetViewHolder(nSheetViewID, pTable);
                 return { nSheetViewID, nSheetViewTab };
             }
diff --git a/sc/source/ui/dialogs/SelectSheetViewDialog.cxx 
b/sc/source/ui/dialogs/SelectSheetViewDialog.cxx
index a367600c5493..13a8d796047f 100644
--- a/sc/source/ui/dialogs/SelectSheetViewDialog.cxx
+++ b/sc/source/ui/dialogs/SelectSheetViewDialog.cxx
@@ -40,8 +40,6 @@ SelectSheetViewDialog::SelectSheetViewDialog(weld::Window* 
pParent, ScViewData&
 {
     m_xEntryTree->connect_changed(LINK(this, SelectSheetViewDialog, 
NameModifyHdl));
 
-    ScDocument& rDocument = mrViewData.GetDocument();
-
     m_xEntryTree->clear();
 
     m_xEntryTree->freeze();
@@ -49,7 +47,7 @@ SelectSheetViewDialog::SelectSheetViewDialog(weld::Window* 
pParent, ScViewData&
     OUString sActiveID = u"-1"_ustr;
     m_xEntryTree->append(u"-1"_ustr, SheetViewManager::defaultViewName());
 
-    if (auto pSheetManager = 
rDocument.GetSheetViewManager(mrViewData.GetTabNumber()))
+    if (auto pSheetManager = mrViewData.GetCurrentSheetViewManager())
     {
         for (auto const& rSheetView : pSheetManager->iterateValidSheetViews())
         {
diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx
index d9ea9b25b8f9..3bf7976b82e3 100644
--- a/sc/source/ui/inc/viewdata.hxx
+++ b/sc/source/ui/inc/viewdata.hxx
@@ -246,6 +246,7 @@ private:
     SCCOL           nMaxTiledCol;
     SCROW           nMaxTiledRow;
 
+    SCTAB           nLastSheetViewTab; // last active sheet view
     bool            bShowGrid;                  // per sheet show grid lines 
option.
     bool            mbOldCursorValid;           // "virtual" Cursor position 
when combined
 
@@ -429,6 +430,9 @@ public:
     /** Returns the default view tab for the sheet view */
     SCTAB GetDefaultViewTab() const;
 
+    SCTAB GetLastSheetViewTab(SCTAB nDefaultTab) const;
+    void ClearLastSheetViewTab(SCTAB nDefaultTab);
+
     SCCOL           MaxCol() const                          { return 
mrDoc.MaxCol(); }
     SCROW           MaxRow() const                          { return 
mrDoc.MaxRow(); }
     ScSplitPos      GetActivePart() const                   { return 
pThisTab->eWhichActive; }
diff --git a/sc/source/ui/view/hdrcont.cxx b/sc/source/ui/view/hdrcont.cxx
index 902973b28827..4e15c7461f56 100644
--- a/sc/source/ui/view/hdrcont.cxx
+++ b/sc/source/ui/view/hdrcont.cxx
@@ -330,7 +330,8 @@ void ScHeaderControl::Paint( vcl::RenderContext& 
/*rRenderContext*/, const tools
             sc::SheetViewID nSheetViewID = rViewData.GetSheetViewID();
             if (nSheetViewID >= 0)
             {
-                auto pSheetManager = 
rViewData.GetDocument().GetSheetViewManager(rViewData.GetTabNumber());
+                SCTAB nDefaultTab = rViewData.GetDefaultViewTab();
+                auto pSheetManager = 
rViewData.GetDocument().GetSheetViewManager(nDefaultTab);
                 if (pSheetManager)
                 {
                     auto pSheetView = pSheetManager->get(nSheetViewID);
diff --git a/sc/source/ui/view/tabcont.cxx b/sc/source/ui/view/tabcont.cxx
index fb7a5b7c71d4..e7bd638aae6c 100644
--- a/sc/source/ui/view/tabcont.cxx
+++ b/sc/source/ui/view/tabcont.cxx
@@ -76,7 +76,10 @@ ScTabControl::ScTabControl( vcl::Window* pParent, 
ScViewData* pData )
         }
     }
 
-    SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNumber()) + 1 );
+    SCTAB nCurTab = pViewData->GetTabNumber();
+    if (!rDoc.IsVisible(nCurTab))
+        nCurTab = pViewData->GetDefaultViewTab();
+    SetCurPageId(sal_uInt16(nCurTab) + 1);
 
     SetSizePixel( Size(SC_TABBAR_DEFWIDTH, 0) );
 
@@ -97,9 +100,10 @@ IMPL_LINK(ScTabControl, ShowPageList, const CommandEvent &, 
rEvent, void)
     std::unique_ptr<weld::Builder> 
xBuilder(Application::CreateBuilder(pPopupParent, 
u"modules/scalc/ui/pagelistmenu.ui"_ustr));
     std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu(u"menu"_ustr));
 
-    sal_uInt16 nCurPageId = GetCurPageId();
-
     ScDocument& rDoc = pViewData->GetDocument();
+    SCTAB nDefaultOfView = pViewData->GetDefaultViewTab();
+    sal_uInt16 nCurPageId = sal_uInt16(nDefaultOfView) + 1;
+
     SCTAB nCount = rDoc.GetTableCount();
     for (SCTAB i=0; i<nCount; ++i)
     {
@@ -264,7 +268,10 @@ void ScTabControl::Select()
 
         for (i=0; i<nCount; i++)
             SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) 
);
-        SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNumber()) + 1 );
+        SCTAB nLockedCurTab = pViewData->GetTabNumber();
+        if (!rDoc.IsVisible(nLockedCurTab))
+            nLockedCurTab = pViewData->GetDefaultViewTab();
+        SetCurPageId(sal_uInt16(nLockedCurTab) + 1);
 
         return;
     }
@@ -273,8 +280,17 @@ void ScTabControl::Select()
     if (!nCurId) return;            // for Excel import it can happen that 
everything is hidden
     sal_uInt16 nPage = nCurId - 1;
 
+    // If user clicked a default tab that has a last-active sheet view, 
restore it
+    {
+        SCTAB nClickedTab = SCTAB(nPage);
+        SCTAB nLastViewTab = pViewData->GetLastSheetViewTab(nClickedTab);
+        if (nLastViewTab != nClickedTab && !rDoc.IsVisible(nLastViewTab))
+            nPage = sal_uInt16(nLastViewTab);
+    }
+
     // OLE-inplace deactivate
-    if ( nPage != static_cast<sal_uInt16>(pViewData->GetTabNumber()) )
+    SCTAB nDefaultSheet = rDoc.GetDefaultViewTableNumber(SCTAB(nPage));
+    if (nDefaultSheet != pViewData->GetDefaultViewTab())
         pViewData->GetView()->DrawMarkListHasChanged();
 
     //  InputEnterHandler onlw when not reference input
@@ -395,7 +411,11 @@ void ScTabControl::UpdateStatus()
             }
         }
     }
-    SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNumber()) + 1 );
+    SCTAB nCurrentTab = pViewData->GetTabNumber();
+    // If on a hidden sheet view tab, show the default tab as current selected 
one in the tab bar
+    if (!rDoc.IsVisible(nCurrentTab))
+        nCurrentTab = pViewData->GetDefaultViewTab();
+    SetCurPageId(sal_uInt16(nCurrentTab) + 1);
 
     if (bActive)
     {
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 9e91839e4458..107adeac138d 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -1923,7 +1923,9 @@ void ScTabView::SetTabNo( SCTAB nTab, bool bNew, bool 
bExtendSelection, bool bSa
 
     SCTAB nTabCount = rDoc.GetTableCount();
     SCTAB nOldPos = nTab;
-    while (!rDoc.IsVisible(nTab))              // search for next visible
+
+    // Search for next visible
+    while (!rDoc.IsVisible(nTab) && !rDoc.IsSheetViewHolder(nTab))
     {
         bool bUp = (nTab>=nOldPos);
         if (bUp)
@@ -1978,7 +1980,7 @@ void ScTabView::SetTabNo( SCTAB nTab, bool bNew, bool 
bExtendSelection, bool bSa
     bool bAllSelected = true;
     for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
     {
-        if (!rDoc.IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
+        if ((!rDoc.IsVisible(nSelTab) && !rDoc.IsSheetViewHolder(nSelTab)) || 
rMark.GetTableSelect(nSelTab))
         {
             if (nTab == nSelTab)
                 // This tab is already in selection.  Keep the current
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index 2f3054ef5833..5b46f7ac7a9d 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -523,6 +523,7 @@ ScViewDataTable::ScViewDataTable(const ScDocument *pDoc) :
                 aHeightHelper(pDoc, false),
                 nMaxTiledCol( 20 ),
                 nMaxTiledRow( 50 ),
+                nLastSheetViewTab(sc::DefaultSheetViewID),
                 bShowGrid( true ),
                 mbOldCursorValid( false )
 {
@@ -2439,6 +2440,18 @@ void ScViewData::SetTabNo( SCTAB nNewTab )
         return;
     }
 
+    // Remember the current sheet view tab on the default sheet's per-tab data
+    if (ValidTab(mnTabNumber))
+    {
+        SCTAB nDefaultOfOld = mrDoc.GetDefaultViewTableNumber(mnTabNumber);
+        if (nDefaultOfOld != mnTabNumber
+            && nDefaultOfOld < SCTAB(maTabData.size())
+            && maTabData[nDefaultOfOld])
+        {
+            maTabData[nDefaultOfOld]->nLastSheetViewTab = mnTabNumber;
+        }
+    }
+
     mnTabNumber = nNewTab;
     CreateTabData(mnTabNumber);
     pThisTab = maTabData[mnTabNumber].get();
@@ -3974,7 +3987,10 @@ void ScViewData::ReadUserDataSequence(const 
uno::Sequence <beans::PropertyValue>
             {
                 SCTAB nTab(0);
                 if (GetDocument().GetTable(sTabName, nTab))
-                    mnTabNumber = nTab;
+                {
+                    // When opening a new window we shouldn't see a sheet view
+                    mnTabNumber = 
GetDocument().GetDefaultViewTableNumber(nTab);
+                }
             }
         }
         else if (sName == SC_HORIZONTALSCROLLBARWIDTH)
@@ -4545,4 +4561,26 @@ SCTAB ScViewData::GetDefaultViewTab() const
     return mrDoc.GetDefaultViewTableNumber(GetTabNumber());
 }
 
+SCTAB ScViewData::GetLastSheetViewTab(SCTAB nDefaultTab) const
+{
+    if (nDefaultTab >= 0
+        && nDefaultTab < static_cast<SCTAB>(maTabData.size())
+        && maTabData[nDefaultTab]
+        && maTabData[nDefaultTab]->nLastSheetViewTab != sc::DefaultSheetViewID)
+    {
+        return maTabData[nDefaultTab]->nLastSheetViewTab;
+    }
+    return nDefaultTab;
+}
+
+void ScViewData::ClearLastSheetViewTab(SCTAB nDefaultTab)
+{
+    if (nDefaultTab >= 0
+        && nDefaultTab < static_cast<SCTAB>(maTabData.size())
+        && maTabData[nDefaultTab])
+    {
+        maTabData[nDefaultTab]->nLastSheetViewTab = sc::DefaultSheetViewID;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index ed18c4d1b676..2b405aa0915b 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -2124,6 +2124,9 @@ void ScViewFunc::RemoveCurrentSheetView()
     // Switch back to the default tab before deleting
     SetTabNo(nDefaultTab);
 
+    // Last sheet view tab is the deleted one, so reset
+    GetViewData().ClearLastSheetViewTab(nDefaultTab);
+
     // DeleteTable also removes the sheet view from the manager
     GetViewData().GetDocFunc().DeleteTable(nSheetViewTab, true);
 

Reply via email to