officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu | 16 ++ sc/inc/SheetViewManager.hxx | 3 sc/inc/sc.hrc | 4 sc/qa/unit/tiledrendering/SheetViewTest.cxx | 72 ++++++++++ sc/sdi/scalc.sdi | 36 +++++ sc/sdi/tabvwsh.sdi | 2 sc/source/core/data/SheetViewManager.cxx | 42 +++++ sc/source/ui/inc/viewfunc.hxx | 19 ++ sc/source/ui/view/tabvwsh3.cxx | 11 + sc/source/ui/view/tabvwsha.cxx | 12 - sc/source/ui/view/viewfun3.cxx | 57 ++++--- 11 files changed, 239 insertions(+), 35 deletions(-)
New commits: commit 9a14540134a1227984ac96dbf3a265b3afb3f267 Author: Tomaž Vajngerl <[email protected]> AuthorDate: Mon Oct 6 23:28:03 2025 +0900 Commit: Miklos Vajna <[email protected]> CommitDate: Thu Oct 9 08:58:58 2025 +0200 sc: add ExitSheetView and SwitchToPreviousSheetView commands We can already switch to "next" sheet view, so this also adds a command to switch to a previous sheet view and to exit a sheet view (return to default view). Change-Id: Ia5c2eead3af4b2bdc0ace6b5e4a2ce5339013f2d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191976 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu index 9117c6e5fd9e..391b2caf9216 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu @@ -2728,6 +2728,22 @@ <value>1</value> </prop> </node> + <node oor:name=".uno:SwitchToPreviousSheetView" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Switch To Previous Sheet View</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> + <node oor:name=".uno:ExitSheetView" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Exit Sheet View</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> <node oor:name=".uno:AssignMacro" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">Assign Macro...</value> diff --git a/sc/inc/SheetViewManager.hxx b/sc/inc/SheetViewManager.hxx index d74d774bdedc..b8562c568eeb 100644 --- a/sc/inc/SheetViewManager.hxx +++ b/sc/inc/SheetViewManager.hxx @@ -53,6 +53,9 @@ public: /** Calculate the next sheet view ID from the current ID. */ SheetViewID getNextSheetView(SheetViewID nID); + /** Calculate the previous sheet view ID from the current ID. */ + SheetViewID getPreviousSheetView(SheetViewID nID); + void unsyncAllSheetViews(); }; } diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index 6010b15ffa2a..1adcf6dd6142 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -287,7 +287,9 @@ class SvxZoomSliderItem; #define FID_TOGGLEFORMULA (VIEW_MENU_START + 10) #define FID_NEW_SHEET_VIEW (VIEW_MENU_START + 11) #define FID_REMOVE_SHEET_VIEW (VIEW_MENU_START + 12) -#define FID_SWITCH_TO_NEXT_SHEET_VIEW (VIEW_MENU_START + 13) +#define FID_SWITCH_TO_NEXT_SHEET_VIEW (VIEW_MENU_START + 13) +#define FID_SWITCH_TO_PREVIOUS_SHEET_VIEW (VIEW_MENU_START + 14) +#define FID_EXIT_SHEET_VIEW (VIEW_MENU_START + 15) #define FID_CHG_ACCEPT (VIEW_MENU_START + 18)// DANGER DIRTY ID #define FID_CHG_COMMENT (VIEW_MENU_START + 19)// DANGER DIRTY ID diff --git a/sc/qa/unit/tiledrendering/SheetViewTest.cxx b/sc/qa/unit/tiledrendering/SheetViewTest.cxx index 8954c8d81cc6..8548b11e5e9f 100644 --- a/sc/qa/unit/tiledrendering/SheetViewTest.cxx +++ b/sc/qa/unit/tiledrendering/SheetViewTest.cxx @@ -406,6 +406,78 @@ CPPUNIT_TEST_FIXTURE(SheetViewTest, testSheetViewOperationRestrictions_SheetView CPPUNIT_ASSERT_EQUAL(true, pSheetView2->isSynced()); } +CPPUNIT_TEST_FIXTURE(SheetViewTest, testSheetViewManager) +{ + sc::SheetViewID nNonExistingID = 99; + + // Empty + sc::SheetViewManager maSheetViewManager; + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getNextSheetView(sc::DefaultSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getNextSheetView(0)); // First non existing + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getNextSheetView(1)); // Next non existing + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getNextSheetView(nNonExistingID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, + maSheetViewManager.getNextSheetView(sc::InvalidSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, maSheetViewManager.getNextSheetView(-99)); + + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getPreviousSheetView(sc::DefaultSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getPreviousSheetView(0)); // First non existing + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getPreviousSheetView(1)); // Next non existing + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getPreviousSheetView(nNonExistingID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, + maSheetViewManager.getPreviousSheetView(sc::InvalidSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, maSheetViewManager.getPreviousSheetView(-99)); + + // Add ID 1 + auto nID1 = maSheetViewManager.create(nullptr); + CPPUNIT_ASSERT(maSheetViewManager.get(nID1)); + + CPPUNIT_ASSERT_EQUAL(nID1, maSheetViewManager.getNextSheetView(sc::DefaultSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, maSheetViewManager.getNextSheetView(nID1)); + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getNextSheetView(nNonExistingID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, + maSheetViewManager.getNextSheetView(sc::InvalidSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, maSheetViewManager.getNextSheetView(-99)); + + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, maSheetViewManager.getPreviousSheetView(nID1)); + CPPUNIT_ASSERT_EQUAL(nID1, maSheetViewManager.getPreviousSheetView(sc::DefaultSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getPreviousSheetView(nNonExistingID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, + maSheetViewManager.getPreviousSheetView(sc::InvalidSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, maSheetViewManager.getPreviousSheetView(-99)); + + // Add ID 2 + auto nID2 = maSheetViewManager.create(nullptr); + CPPUNIT_ASSERT(maSheetViewManager.get(nID2)); + CPPUNIT_ASSERT_EQUAL(nID1, maSheetViewManager.getNextSheetView(sc::DefaultSheetViewID)); + CPPUNIT_ASSERT_EQUAL(nID2, maSheetViewManager.getNextSheetView(nID1)); + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, maSheetViewManager.getNextSheetView(nID2)); + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getNextSheetView(nNonExistingID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, + maSheetViewManager.getNextSheetView(sc::InvalidSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, maSheetViewManager.getNextSheetView(-99)); + + CPPUNIT_ASSERT_EQUAL(nID2, maSheetViewManager.getPreviousSheetView(sc::DefaultSheetViewID)); + CPPUNIT_ASSERT_EQUAL(nID1, maSheetViewManager.getPreviousSheetView(nID2)); + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, maSheetViewManager.getPreviousSheetView(nID1)); + CPPUNIT_ASSERT_EQUAL(sc::DefaultSheetViewID, + maSheetViewManager.getPreviousSheetView(nNonExistingID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, + maSheetViewManager.getPreviousSheetView(sc::InvalidSheetViewID)); + CPPUNIT_ASSERT_EQUAL(sc::InvalidSheetViewID, maSheetViewManager.getPreviousSheetView(-99)); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi index 18f9359d2c7f..a4cb60ce5ee8 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -6086,6 +6086,42 @@ SfxBoolItem SwitchToNextSheetView FID_SWITCH_TO_NEXT_SHEET_VIEW GroupId = SfxGroupId::View ] +SfxBoolItem SwitchToPreviousSheetView FID_SWITCH_TO_PREVIOUS_SHEET_VIEW +[ + /* flags */ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + /* config */ + AccelConfig = TRUE, + MenuConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = SfxGroupId::View +] + +SfxBoolItem ExitSheetView FID_EXIT_SHEET_VIEW +[ + /* flags */ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + /* config */ + AccelConfig = TRUE, + MenuConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = SfxGroupId::View +] + SfxBoolItem ViewValueHighlighting FID_TOGGLESYNTAX [ diff --git a/sc/sdi/tabvwsh.sdi b/sc/sdi/tabvwsh.sdi index 6506fe8e858b..060566f1c0a0 100644 --- a/sc/sdi/tabvwsh.sdi +++ b/sc/sdi/tabvwsh.sdi @@ -180,6 +180,8 @@ interface TableEditView FID_NEW_SHEET_VIEW [ ExecMethod = Execute; StateMethod = GetState; ] FID_REMOVE_SHEET_VIEW [ ExecMethod = Execute; StateMethod = GetState; ] FID_SWITCH_TO_NEXT_SHEET_VIEW [ ExecMethod = Execute; StateMethod = GetState; ] + FID_SWITCH_TO_PREVIOUS_SHEET_VIEW [ ExecMethod = Execute; StateMethod = GetState; ] + FID_EXIT_SHEET_VIEW [ ExecMethod = Execute; StateMethod = GetState; ] FID_NORMALVIEWMODE [ ExecMethod = Execute; StateMethod = GetState; ] FID_PAGEBREAKMODE [ ExecMethod = Execute; StateMethod = GetState; ] SID_REPAINT [ ExecMethod = Execute; StateMethod = GetState; ] diff --git a/sc/source/core/data/SheetViewManager.cxx b/sc/source/core/data/SheetViewManager.cxx index b3cc04eb3960..097f5f58346d 100644 --- a/sc/source/core/data/SheetViewManager.cxx +++ b/sc/source/core/data/SheetViewManager.cxx @@ -46,11 +46,14 @@ std::shared_ptr<SheetView> SheetViewManager::get(SheetViewID nID) const /// Calculate the next existing sheet view to use. SheetViewID SheetViewManager::getNextSheetView(SheetViewID nID) { + if (nID != DefaultSheetViewID && nID < 0) + return InvalidSheetViewID; + if (maViews.empty()) return DefaultSheetViewID; // Set to max, so we prevent the for loop to run - size_t startIndex = std::numeric_limits<size_t>::max(); + sal_Int32 startIndex = std::numeric_limits<sal_Int32>::max(); // Start with first index and search for the first sheet view in for loop. if (nID == DefaultSheetViewID) @@ -61,10 +64,43 @@ SheetViewID SheetViewManager::getNextSheetView(SheetViewID nID) // for then next valid sheet view in the for loop. else if (isValidSheetViewID(nID)) { - startIndex = size_t(nID) + 1; + startIndex = sal_Int32(nID) + 1; + } + + for (sal_Int32 nIndex = startIndex; nIndex < sal_Int32(maViews.size()); ++nIndex) + { + if (maViews[nIndex]) + return SheetViewID(nIndex); + } + + return DefaultSheetViewID; +} + +/// Calculate the previous existing sheet view to use. +SheetViewID SheetViewManager::getPreviousSheetView(SheetViewID nID) +{ + if (nID != DefaultSheetViewID && nID < 0) + return InvalidSheetViewID; + + if (maViews.empty()) + return DefaultSheetViewID; + + // Set to -1, so we prevent the for loop to run + sal_Int32 startIndex = -1; + + // Start with first index and search for the first sheet view in for loop. + if (nID == DefaultSheetViewID) + { + startIndex = sal_Int32(maViews.size()) - 1; + } + // If we assume currnet ID is valid, so set the start to current + 1 to search + // for then next valid sheet view in the for loop. + else if (isValidSheetViewID(nID)) + { + startIndex = sal_Int32(nID) - 1; } - for (size_t nIndex = startIndex; nIndex < maViews.size(); ++nIndex) + for (sal_Int32 nIndex = startIndex; nIndex >= 0; --nIndex) { if (maViews[nIndex]) return SheetViewID(nIndex); diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index c07ed4324da4..990e306e23da 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -67,6 +67,18 @@ struct ScDataFormFragment ScDataFormFragment(weld::Container* pGrid, int nLine); }; +namespace sc +{ + +/** Direction of searching for the sheet view to switch to relative to the current sheet view. */ +enum class SwitchSheetViewDirection +{ + Next, + Previous +}; + +} + class ScViewFunc : public ScTabView { private: @@ -354,9 +366,11 @@ public: void DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab, bool bAttrChanged ); + // SheetView methods void MakeNewSheetView(); void RemoveCurrentSheetView(); - void SwitchSheetView(); + void SwitchSheetView(sc::SwitchSheetViewDirection eDirection); + void ExitSheetView(); // Switch to default view // Internal helper functions protected: @@ -366,6 +380,9 @@ protected: bool bColor ); private: + // SheetView Private + void SheetViewChanged(); + void PasteRTF( SCCOL nCol, SCROW nStartRow, const css::uno::Reference< css::datatransfer::XTransferable >& rxTransferable ); diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx index a2785a63660e..b08a1e6e6372 100644 --- a/sc/source/ui/view/tabvwsh3.cxx +++ b/sc/source/ui/view/tabvwsh3.cxx @@ -1046,16 +1046,21 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) } break; + // Handle sheet views case FID_NEW_SHEET_VIEW: MakeNewSheetView(); break; - case FID_REMOVE_SHEET_VIEW: RemoveCurrentSheetView(); break; - case FID_SWITCH_TO_NEXT_SHEET_VIEW: - SwitchSheetView(); + SwitchSheetView(sc::SwitchSheetViewDirection::Next); + break; + case FID_SWITCH_TO_PREVIOUS_SHEET_VIEW: + SwitchSheetView(sc::SwitchSheetViewDirection::Previous); + break; + case FID_EXIT_SHEET_VIEW: + ExitSheetView(); break; case SID_ATTR_ZOOM: // status row diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx index 789b8af79e1a..bf309f14e293 100644 --- a/sc/source/ui/view/tabvwsha.cxx +++ b/sc/source/ui/view/tabvwsha.cxx @@ -399,15 +399,17 @@ void ScTabViewShell::GetState( SfxItemSet& rSet ) case FID_NEW_SHEET_VIEW: case FID_REMOVE_SHEET_VIEW: case FID_SWITCH_TO_NEXT_SHEET_VIEW: + case FID_SWITCH_TO_PREVIOUS_SHEET_VIEW: + case FID_EXIT_SHEET_VIEW: { if (GetViewData().GetDocShell()->IsReadOnly() || IsCurrentLokViewReadOnly()) { - rSet.DisableItem(FID_NEW_SHEET_VIEW); - rSet.DisableItem(FID_REMOVE_SHEET_VIEW); - rSet.DisableItem(FID_SWITCH_TO_NEXT_SHEET_VIEW); + rSet.DisableItem(nWhich); + } + else if (nWhich == FID_REMOVE_SHEET_VIEW && GetViewData().GetSheetViewID() == sc::DefaultSheetViewID) + { + rSet.DisableItem(nWhich); } - if (nWhich == FID_REMOVE_SHEET_VIEW && GetViewData().GetSheetViewID() == sc::DefaultSheetViewID) - rSet.DisableItem(FID_REMOVE_SHEET_VIEW); } break; diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index f5fe10d47d51..6b13ed094fd2 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -2063,6 +2063,13 @@ void ScViewFunc::DataFormPutData( SCROW nCurrentRow , pDocSh->UpdateOle(GetViewData()); } +void ScViewFunc::SheetViewChanged() +{ + ScDocShell& rDocSh = *GetViewData().GetDocShell(); + ScDocument& rDocument = GetViewData().GetDocument(); + rDocSh.PostPaint(0,0,0, rDocument.MaxCol(), rDocument.MaxRow(), MAXTAB, PaintPartFlags::All); +} + void ScViewFunc::MakeNewSheetView() { SCTAB nTab = GetViewData().GetTabNumber(); @@ -2079,15 +2086,12 @@ void ScViewFunc::MakeNewSheetView() GetViewData().SetSheetViewID(nSheetViewID); // Update - GetViewData().SetTabNo(nSheetViewTab); // force add the sheet view tab - GetViewData().SetTabNo(nTab); // then change back to the current tab ScDocShell& rDocSh = *GetViewData().GetDocShell(); - rDocSh.PostPaintGridAll(); - PaintExtras(); // update Tab Control - rDocSh.Broadcast(ScTablesHint(SC_TAB_INSERTED, nSheetViewTab)); SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScTablesChanged)); + + SheetViewChanged(); } void ScViewFunc::RemoveCurrentSheetView() @@ -2102,17 +2106,17 @@ void ScViewFunc::RemoveCurrentSheetView() if (!pSheetManager) return; + GetViewData().SetSheetViewID(sc::DefaultSheetViewID); + SCTAB nSheetViewTab = rDocument.GetSheetViewNumber(nTab, nSheetViewID); pSheetManager->remove(nSheetViewID); - GetViewData().SetSheetViewID(sc::DefaultSheetViewID); - GetViewData().SetTabNo(nTab); + GetViewData().GetDocFunc().DeleteTable(nSheetViewTab, true); - GetViewData().GetDocShell()->PostPaintGridAll(); - PaintExtras(); + SheetViewChanged(); } -void ScViewFunc::SwitchSheetView() +void ScViewFunc::SwitchSheetView(sc::SwitchSheetViewDirection eDirection) { SCTAB nTab = GetViewData().GetTabNumber(); ScDocument& rDocument = GetViewData().GetDocument(); @@ -2121,21 +2125,30 @@ void ScViewFunc::SwitchSheetView() sc::SheetViewID nSheetViewID = GetViewData().GetSheetViewID(); auto pSheetManager = rDocument.GetSheetViewManager(nTab); - sc::SheetViewID nNextSheetViewID = pSheetManager->getNextSheetView(nSheetViewID); - GetViewData().SetSheetViewID(nNextSheetViewID); + sc::SheetViewID nSwitchSheetViewID = eDirection == sc::SwitchSheetViewDirection::Next + ? pSheetManager->getNextSheetView(nSheetViewID) + : pSheetManager->getPreviousSheetView(nSheetViewID); - if (nNextSheetViewID != sc::DefaultSheetViewID) - { - SCTAB nNextSheetViewTab = rDocument.GetSheetViewNumber(nTab, nNextSheetViewID); - GetViewData().SetTabNo(nNextSheetViewTab); // force add the sheet view tab - } + GetViewData().SetSheetViewID(nSwitchSheetViewID); - // Update - GetViewData().SetTabNo(nTab); // then change back to the current tab - ScDocShell& rDocSh = *GetViewData().GetDocShell(); - rDocSh.PostPaintGridAll(); - PaintExtras(); // update Tab Control + SheetViewChanged(); +} + +void ScViewFunc::ExitSheetView() +{ + SCTAB nTab = GetViewData().GetTabNumber(); + ScDocument& rDocument = GetViewData().GetDocument(); + if (rDocument.IsSheetView(nTab)) + return; + + sc::SheetViewID nSheetViewID = GetViewData().GetSheetViewID(); + if (nSheetViewID == sc::DefaultSheetViewID) + return; + + GetViewData().SetSheetViewID(sc::DefaultSheetViewID); + + SheetViewChanged(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
