sc/Library_sc.mk | 2 sc/inc/document.hxx | 3 sc/inc/globstr.hrc | 1 sc/qa/unit/tiledrendering/SheetViewTest.cxx | 20 ++- sc/source/core/data/document10.cxx | 12 ++ sc/source/ui/docshell/SheetViewOperationsTester.cxx | 2 sc/source/ui/docshell/docfunc.cxx | 9 + sc/source/ui/inc/docfunc.hxx | 3 sc/source/ui/inc/operation/InsertSheetViewOperation.hxx | 39 +++++++ sc/source/ui/inc/operation/OperationType.hxx | 1 sc/source/ui/inc/undo/UndoInsertSheetView.hxx | 44 ++++++++ sc/source/ui/inc/viewdata.hxx | 9 - sc/source/ui/operation/InsertSheetViewOperation.cxx | 66 ++++++++++++ sc/source/ui/operation/Operation.cxx | 25 ++-- sc/source/ui/operation/OperationType.cxx | 2 sc/source/ui/operation/SortOperation.cxx | 6 - sc/source/ui/undo/UndoInsertSheetView.cxx | 84 ++++++++++++++++ sc/source/ui/view/gridwin4.cxx | 10 - sc/source/ui/view/viewdata.cxx | 49 +++++---- sc/source/ui/view/viewfun3.cxx | 66 ++++-------- 20 files changed, 352 insertions(+), 101 deletions(-)
New commits: commit fc18dae7143d81b08a92590b7a79d8bfb189dea8 Author: Tomaž Vajngerl <[email protected]> AuthorDate: Mon Mar 2 00:02:25 2026 +0900 Commit: Miklos Vajna <[email protected]> CommitDate: Mon Mar 2 16:29:02 2026 +0100 sc: Remove tab redirection inside ViewData Remove the tab redirection inside ViewData, which changes how sheet views work. Sheet views are now used as normal sheets for both the UI and data, instead of relying on redirection. Sheet view handling is done in the UI itself. This simplifies the approach and likely avoids bugs that would arise from redirection. For this to work, all functions that deal with sheet views need to be changed. A new InsertSheetViewOperation was added for inserting sheet views, along with the sc::UndoInsertSheetView undo class. Tests were adjusted, especially the asserts for tab names and tab numbers of sheet views. Change-Id: I08044afcff2bb64be73c05c1bda0262c73197e90 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200712 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 385c96d18ebd..33d8839923a3 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -533,6 +533,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/ui/operation/DeleteCellOperation \ sc/source/ui/operation/DeleteContentOperation \ sc/source/ui/operation/InsertCellsOperation \ + sc/source/ui/operation/InsertSheetViewOperation \ sc/source/ui/operation/Operation \ sc/source/ui/operation/OperationType \ sc/source/ui/operation/SetEditTextOperation \ @@ -602,6 +603,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/ui/undo/UndoUngroupSparklines \ sc/source/ui/undo/UndoGroupSparklines \ sc/source/ui/undo/UndoEditSparkline \ + sc/source/ui/undo/UndoInsertSheetView \ sc/source/ui/undo/UndoThemeChange \ sc/source/ui/unoobj/ChartRangeSelectionListener \ sc/source/ui/unoobj/addruno \ diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 81244baa0536..5bf596cf71cc 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -2440,6 +2440,9 @@ public: SC_DLLPUBLIC bool IsSheetViewHolder(SCTAB nTab) const; SC_DLLPUBLIC SCTAB GetDefaultViewTableNumber(SCTAB nTab) const; + /** Returns the sheet view ID for a given tab. */ + sc::SheetViewID GetTableSheetViewID(SCTAB nTab) const; + private: ScDocument(const ScDocument& r) = delete; diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc index d16a04581ceb..173bbc80fd2b 100644 --- a/sc/inc/globstr.hrc +++ b/sc/inc/globstr.hrc @@ -582,6 +582,7 @@ #define STR_UNDO_EDIT_SPARKLINE NC_("STR_UNDO_EDIT_SPARKLINE", "Edit Sparkline") #define STR_UNDO_THEME_CHANGE NC_("STR_UNDO_THEME_CHANGE", "Theme Change") #define STR_UNDO_THEME_COLOR_CHANGE NC_("STR_UNDO_THEME_COLOR_CHANGE", "Theme Color Change") +#define STR_UNDO_INSERT_SHEET_VIEW NC_("STR_UNDO_INSERT_SHEET_VIEW", "Insert Sheet View") #define STR_ERR_INSERT_CELLS NC_("STR_ERR_INSERT_CELLS", "Failed to insert cells") #define STR_SOLVER_ENGINE NC_("STR_SOLVER_ENGINE", "Solver Engine:") #define STR_SENSITIVITY NC_("STR_SENSITIVITY", "Sensitivity") diff --git a/sc/qa/unit/tiledrendering/SheetViewTest.cxx b/sc/qa/unit/tiledrendering/SheetViewTest.cxx index 589d801a609e..ef5fc57d52c0 100644 --- a/sc/qa/unit/tiledrendering/SheetViewTest.cxx +++ b/sc/qa/unit/tiledrendering/SheetViewTest.cxx @@ -257,13 +257,13 @@ CPPUNIT_TEST_FIXTURE(SheetViewTest, testSheetViewAutoFilter) // Check what sheet we currently have selected for view 1 & 2 CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabView1->GetViewData().GetTabNumber()); - CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabView2->GetViewData().GetTabNumber()); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), pTabView2->GetViewData().GetTabNumber()); // Sort AutoFilter descending sortDescendingForCell(u"A1"); CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabView1->GetViewData().GetTabNumber()); - CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabView2->GetViewData().GetTabNumber()); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), pTabView2->GetViewData().GetTabNumber()); // Check view 2 - sorted CPPUNIT_ASSERT_EQUAL(expectedValues({ u"7", u"5", u"4", u"3" }), getValues(pTabView2, 0, 1, 4)); @@ -701,7 +701,8 @@ CPPUNIT_TEST_FIXTURE(SheetViewTest, testRemoveTableWithSheetViews) CPPUNIT_ASSERT(pSheetViewManager); CPPUNIT_ASSERT_EQUAL(size_t(1), pSheetViewManager->size()); - CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabView1->GetViewData().GetTabNumber()); + // View is now on the sheet view tab + CPPUNIT_ASSERT_EQUAL(SCTAB(1), pTabView1->GetViewData().GetTabNumber()); auto pSheetView1 = pSheetViewManager->get(0); CPPUNIT_ASSERT_EQUAL(SCTAB(1), pSheetView1->getTableNumber()); @@ -715,7 +716,8 @@ CPPUNIT_TEST_FIXTURE(SheetViewTest, testRemoveTableWithSheetViews) createNewSheetViewInCurrentView(); { - CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabView1->GetViewData().GetTabNumber()); + // View is now on the latest sheet view tab + CPPUNIT_ASSERT_EQUAL(SCTAB(1), pTabView1->GetViewData().GetTabNumber()); CPPUNIT_ASSERT_EQUAL(SCTAB(4), rDocument.GetTableCount()); CPPUNIT_ASSERT_EQUAL(u"NewTab"_ustr, rDocument.GetAllTableNames()[0]); @@ -776,7 +778,7 @@ CPPUNIT_TEST_FIXTURE(SheetViewTest, testRemoveSheetViewHolderTable) CPPUNIT_ASSERT(pSheetViewManager); CPPUNIT_ASSERT_EQUAL(size_t(1), pSheetViewManager->size()); - CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabView1->GetViewData().GetTabNumber()); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), pTabView1->GetViewData().GetTabNumber()); auto pSheetView1 = pSheetViewManager->get(0); CPPUNIT_ASSERT_EQUAL(SCTAB(1), pSheetView1->getTableNumber()); @@ -789,7 +791,7 @@ CPPUNIT_TEST_FIXTURE(SheetViewTest, testRemoveSheetViewHolderTable) createNewSheetViewInCurrentView(); { - CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabView1->GetViewData().GetTabNumber()); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), pTabView1->GetViewData().GetTabNumber()); CPPUNIT_ASSERT_EQUAL(SCTAB(3), rDocument.GetTableCount()); CPPUNIT_ASSERT_EQUAL(u"Hoja1"_ustr, rDocument.GetAllTableNames()[0]); @@ -919,7 +921,7 @@ CPPUNIT_TEST_FIXTURE(SheetViewTest, testSyncAfterSorting_DefaultViewSort) createNewSheetViewInCurrentView(); - CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabViewSheetView->GetViewData().GetTabNumber()); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), pTabViewSheetView->GetViewData().GetTabNumber()); CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabViewDefaultView->GetViewData().GetTabNumber()); } @@ -928,13 +930,13 @@ CPPUNIT_TEST_FIXTURE(SheetViewTest, testSyncAfterSorting_DefaultViewSort) SfxLokHelper::setView(aDefaultView.getViewID()); Scheduler::ProcessEventsToIdle(); - CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabViewSheetView->GetViewData().GetTabNumber()); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), pTabViewSheetView->GetViewData().GetTabNumber()); CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabViewDefaultView->GetViewData().GetTabNumber()); // Sort AutoFilter ascending sortAscendingForCell(u"A1"); - CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabViewSheetView->GetViewData().GetTabNumber()); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), pTabViewSheetView->GetViewData().GetTabNumber()); CPPUNIT_ASSERT_EQUAL(SCTAB(0), pTabViewDefaultView->GetViewData().GetTabNumber()); // Check values diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index f144b0108144..a55e0f5f1b44 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -1134,6 +1134,17 @@ SCTAB ScDocument::GetDefaultViewTableNumber(SCTAB nTab) const return nTab; } +sc::SheetViewID ScDocument::GetTableSheetViewID(SCTAB nTab) const +{ + if (ScTable const* pTable = FetchTable(nTab)) + { + sc::SheetViewID nID = pTable->GetSheetViewID(); + if (nID != sc::InvalidSheetViewID) + return nID; + } + return sc::DefaultSheetViewID; +} + std::pair<sc::SheetViewID, SCTAB> ScDocument::CreateNewSheetView(SCTAB nTab) { if (ScTable* pTable = FetchTable(nTab)) @@ -1144,7 +1155,6 @@ 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/docshell/SheetViewOperationsTester.cxx b/sc/source/ui/docshell/SheetViewOperationsTester.cxx index 675d49f9bd6c..1b2f9185788f 100644 --- a/sc/source/ui/docshell/SheetViewOperationsTester.cxx +++ b/sc/source/ui/docshell/SheetViewOperationsTester.cxx @@ -53,7 +53,7 @@ bool SheetViewOperationsTester::check(OperationType eOperationType) const return true; auto& rDocument = mpViewData->GetDocument(); - SCTAB nTab = mpViewData->GetTabNumber(); + SCTAB nTab = mpViewData->GetDefaultViewTab(); // Never allow direct changes to the data holder sheet of the sheet view. if (rDocument.IsSheetViewHolder(nTab)) diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index a2661304eef1..85b5baa96631 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -120,6 +120,7 @@ #include <operation/SetEditTextOperation.hxx> #include <operation/ApplyAttributesOperation.hxx> #include <operation/InsertCellsOperation.hxx> +#include <operation/InsertSheetViewOperation.hxx> #include <basic/basmgr.hxx> #include <set> #include <vector> @@ -2359,6 +2360,14 @@ bool ScDocFunc::InsertTable( SCTAB nTab, const OUString& rName, bool bRecord, bo return bSuccess; } +std::pair<sc::SheetViewID, SCTAB> ScDocFunc::InsertSheetView( SCTAB nTab, bool bRecord ) +{ + sc::InsertSheetViewOperation aOperation(rDocShell, nTab, bRecord); + if (!aOperation.run()) + return { sc::InvalidSheetViewID, -1 }; + return { aOperation.getSheetViewID(), aOperation.getSheetViewTab() }; +} + bool ScDocFunc::DeleteTable( SCTAB nTab, bool bRecord ) { weld::WaitObject aWait( ScDocShell::GetActiveDialogParent() ); diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx index ae6de45fd044..9727e1673588 100644 --- a/sc/source/ui/inc/docfunc.hxx +++ b/sc/source/ui/inc/docfunc.hxx @@ -24,8 +24,10 @@ #include <formula/grammar.hxx> #include <tabbgcolor.hxx> #include <unotools/resmgr.hxx> +#include <SheetViewTypes.hxx> #include <memory> +#include <utility> #include <vector> #include <map> @@ -151,6 +153,7 @@ public: bool bCut, bool bRecord, bool bPaint, bool bApi ); SC_DLLPUBLIC bool InsertTable( SCTAB nTab, const OUString& rName, bool bRecord, bool bApi ); + std::pair<sc::SheetViewID, SCTAB> InsertSheetView( SCTAB nTab, bool bRecord ); SC_DLLPUBLIC bool RenameTable( SCTAB nTab, const OUString& rName, bool bRecord, bool bApi ); bool DeleteTable( SCTAB nTab, bool bRecord ); diff --git a/sc/source/ui/inc/operation/InsertSheetViewOperation.hxx b/sc/source/ui/inc/operation/InsertSheetViewOperation.hxx new file mode 100644 index 000000000000..f7143f6dd5e6 --- /dev/null +++ b/sc/source/ui/inc/operation/InsertSheetViewOperation.hxx @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Operation.hxx" +#include <address.hxx> +#include <SheetViewTypes.hxx> + +class ScDocShell; + +namespace sc +{ +/** Operation which inserts a new sheet view for a given tab. */ +class InsertSheetViewOperation : public Operation +{ +private: + ScDocShell& mrDocShell; + SCTAB mnTab; + SheetViewID mnSheetViewID = InvalidSheetViewID; + SCTAB mnSheetViewTab = -1; + + bool runImplementation() override; + +public: + InsertSheetViewOperation(ScDocShell& rDocShell, SCTAB nTab, bool bRecord); + + SheetViewID getSheetViewID() const { return mnSheetViewID; } + SCTAB getSheetViewTab() const { return mnSheetViewTab; } +}; +} // end sc namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/operation/OperationType.hxx b/sc/source/ui/inc/operation/OperationType.hxx index 522095acf674..a7d85f0d2c68 100644 --- a/sc/source/ui/inc/operation/OperationType.hxx +++ b/sc/source/ui/inc/operation/OperationType.hxx @@ -66,6 +66,7 @@ enum class OperationType SparklineGroupDelete, SparklineGroupChange, EnterData, + InsertSheetView, }; std::string_view operationTypeString(OperationType eType); diff --git a/sc/source/ui/inc/undo/UndoInsertSheetView.hxx b/sc/source/ui/inc/undo/UndoInsertSheetView.hxx new file mode 100644 index 000000000000..6b582cdefaa5 --- /dev/null +++ b/sc/source/ui/inc/undo/UndoInsertSheetView.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <undobase.hxx> +#include <address.hxx> +#include <SheetViewTypes.hxx> +#include <memory> + +class SdrUndoAction; + +namespace sc +{ +/** Undo action for inserting a sheet view. */ +class UndoInsertSheetView : public ScSimpleUndo +{ +private: + std::unique_ptr<SdrUndoAction> mpDrawUndo; + SCTAB mnTab; // the default/source tab + SCTAB mnSheetViewTab; // the sheet view tab + SheetViewID mnSheetViewID; + +public: + UndoInsertSheetView(ScDocShell& rDocShell, SCTAB nTab, SCTAB nSheetViewTab, + SheetViewID nSheetViewID); + virtual ~UndoInsertSheetView() override; + + void Undo() override; + void Redo() override; + void Repeat(SfxRepeatTarget& rTarget) override; + bool CanRepeat(SfxRepeatTarget& rTarget) const override; + OUString GetComment() const override; +}; + +} // namespace sc + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx index 05753470e82b..d9ea9b25b8f9 100644 --- a/sc/source/ui/inc/viewdata.hxx +++ b/sc/source/ui/inc/viewdata.hxx @@ -248,7 +248,6 @@ private: bool bShowGrid; // per sheet show grid lines option. bool mbOldCursorValid; // "virtual" Cursor position when combined - sc::SheetViewID mnSheetViewID = sc::DefaultSheetViewID; ScViewDataTable(const ScDocument *pDoc = nullptr); @@ -421,15 +420,15 @@ public: void SetSheetViewID(sc::SheetViewID nID); - sc::SheetViewID GetSheetViewID() const - { - return pThisTab->mnSheetViewID; - } + sc::SheetViewID GetSheetViewID() const; sc::SheetViewID GetSheetViewIDForSheet(SCTAB nTab) const; std::shared_ptr<sc::SheetViewManager> GetCurrentSheetViewManager() const; + /** Returns the default view tab for the sheet view */ + SCTAB GetDefaultViewTab() const; + SCCOL MaxCol() const { return mrDoc.MaxCol(); } SCROW MaxRow() const { return mrDoc.MaxRow(); } ScSplitPos GetActivePart() const { return pThisTab->eWhichActive; } diff --git a/sc/source/ui/operation/InsertSheetViewOperation.cxx b/sc/source/ui/operation/InsertSheetViewOperation.cxx new file mode 100644 index 000000000000..bb4e3c009ff9 --- /dev/null +++ b/sc/source/ui/operation/InsertSheetViewOperation.cxx @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <operation/InsertSheetViewOperation.hxx> + +#include <docsh.hxx> +#include <document.hxx> +#include <undo/UndoInsertSheetView.hxx> +#include <tabvwsh.hxx> +#include <uiitems.hxx> +#include <SheetViewTypes.hxx> + +#include <sfx2/app.hxx> +#include <vcl/weld.hxx> + +#include <memory> + +namespace sc +{ +InsertSheetViewOperation::InsertSheetViewOperation(ScDocShell& rDocShell, SCTAB nTab, bool bRecord) + : Operation(OperationType::InsertSheetView, bRecord, false) + , mrDocShell(rDocShell) + , mnTab(nTab) +{ +} + +bool InsertSheetViewOperation::runImplementation() +{ + weld::WaitObject aWait(ScDocShell::GetActiveDialogParent()); + + ScDocShellModificator aModificator(mrDocShell); + + ScDocument& rDoc = mrDocShell.GetDocument(); + if (mbRecord && !rDoc.IsUndoEnabled()) + mbRecord = false; + + if (mbRecord) + rDoc.BeginDrawUndo(); + + auto[nSheetViewID, nSheetViewTab] = rDoc.CreateNewSheetView(mnTab); + if (nSheetViewID == InvalidSheetViewID) + return false; + + mnSheetViewID = nSheetViewID; + mnSheetViewTab = nSheetViewTab; + + if (mbRecord) + mrDocShell.GetUndoManager()->AddUndoAction( + std::make_unique<UndoInsertSheetView>(mrDocShell, mnTab, nSheetViewTab, nSheetViewID)); + + mrDocShell.Broadcast(ScTablesHint(SC_TAB_INSERTED, nSheetViewTab)); + mrDocShell.PostPaintExtras(); + aModificator.SetDocumentModified(); + SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScTablesChanged)); + + return true; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/operation/Operation.cxx b/sc/source/ui/operation/Operation.cxx index a6fc2a546eaa..49845e6ea875 100644 --- a/sc/source/ui/operation/Operation.cxx +++ b/sc/source/ui/operation/Operation.cxx @@ -62,19 +62,21 @@ ScAddress Operation::convertAddress(ScAddress const& rAddress) if (!pSheetView) return rAddress; + SCTAB nSheetViewTab = pViewData->GetTabNumber(); + SCTAB nDefaultTab = pViewData->GetDefaultViewTab(); + ScAddress aAddress = rAddress; - // Change the tab number if it is the one from sheet view - if (aAddress.Tab() == pViewData->CurrentTabForData()) - aAddress.SetTab(pViewData->GetTabNumber()); + // Change the tab number from sheet view tab to default tab + if (aAddress.Tab() == nSheetViewTab) + aAddress.SetTab(nDefaultTab); // Should be the default view tab - if (aAddress.Tab() != pViewData->GetTabNumber()) + if (aAddress.Tab() != nDefaultTab) return aAddress; SCCOL nColumn = aAddress.Col(); SCROW nRow = aAddress.Row(); - SCTAB nTab = aAddress.Tab(); SCROW nReversedRow = pSheetView->reverseSortingToDefaultView(nRow, nColumn); @@ -82,7 +84,7 @@ ScAddress Operation::convertAddress(ScAddress const& rAddress) if (nReversedRow == nRow) return aAddress; - return ScAddress(nColumn, nReversedRow, nTab); + return ScAddress(nColumn, nReversedRow, nDefaultTab); } ScMarkData Operation::convertMark(ScMarkData const& rMarkData) @@ -95,13 +97,13 @@ ScMarkData Operation::convertMark(ScMarkData const& rMarkData) if (!pSheetView) return rMarkData; + SCTAB nSheetViewTab = pViewData->GetTabNumber(); + SCTAB nDefaultViewTab = pViewData->GetDefaultViewTab(); + ScMarkData aNewMark(rMarkData); aNewMark.MarkToMulti(); bool bChanged = false; - SCTAB nDefaultViewTab = pViewData->GetTabNumber(); - SCTAB nSheetViewTab = pViewData->CurrentTabForData(); - // Adjust tab to default view in ranges if (nSheetViewTab == aNewMark.GetArea().aStart.Tab() && nSheetViewTab == aNewMark.GetArea().aEnd.Tab()) @@ -192,10 +194,7 @@ void Operation::syncSheetViews() return; auto& rDocument = mpViewData->GetDocument(); - SCTAB nTab = mpViewData->GetTabNumber(); - - if (rDocument.IsSheetViewHolder(nTab)) - return; + SCTAB nTab = mpViewData->GetDefaultViewTab(); std::shared_ptr<sc::SheetViewManager> pManager = rDocument.GetSheetViewManager(nTab); if (!pManager || pManager->isEmpty()) diff --git a/sc/source/ui/operation/OperationType.cxx b/sc/source/ui/operation/OperationType.cxx index 8dc3b06d629c..2853f1474039 100644 --- a/sc/source/ui/operation/OperationType.cxx +++ b/sc/source/ui/operation/OperationType.cxx @@ -116,6 +116,8 @@ std::string_view operationTypeString(OperationType eOperation) return "SparklineGroupChange"; case OperationType::EnterData: return "EnterData"; + case OperationType::InsertSheetView: + return "InsertSheetView"; } return ""; } diff --git a/sc/source/ui/operation/SortOperation.cxx b/sc/source/ui/operation/SortOperation.cxx index 13a33e6de95f..ac7520c7f5a3 100644 --- a/sc/source/ui/operation/SortOperation.cxx +++ b/sc/source/ui/operation/SortOperation.cxx @@ -60,12 +60,12 @@ bool SortOperation::runImplementation() ScSortParam aLocalParam(mrSortParam); // If we are in a sheet view and aren't sorting auto-filtered cell range, we need - // to sync the sorted cells. If this is the case then we need to convert the tab - // from the sheet view tab to default view tab. + // to sync the sorted cells. If this is the case then we need to convert the tab + // from the sheet view tab to the default view tab. if (mpViewData && rDoc.IsSheetViewHolder(mnTab) && !pDBData->HasAutoFilter()) { SCTAB nSheetViewTab = mnTab; - mnTab = mpViewData->GetTabNumber(); + mnTab = rDoc.GetDefaultViewTableNumber(nSheetViewTab); if (aLocalParam.nSourceTab == nSheetViewTab) aLocalParam.nSourceTab = mnTab; diff --git a/sc/source/ui/undo/UndoInsertSheetView.cxx b/sc/source/ui/undo/UndoInsertSheetView.cxx new file mode 100644 index 000000000000..76001e26cf97 --- /dev/null +++ b/sc/source/ui/undo/UndoInsertSheetView.cxx @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <undo/UndoInsertSheetView.hxx> +#include <globstr.hrc> +#include <scresid.hxx> +#include <document.hxx> +#include <docsh.hxx> +#include <tabvwsh.hxx> +#include <undoolk.hxx> + +namespace sc +{ +UndoInsertSheetView::UndoInsertSheetView(ScDocShell& rDocShell, SCTAB nTab, SCTAB nSheetViewTab, + SheetViewID nSheetViewID) + : ScSimpleUndo(&rDocShell) + , mnTab(nTab) + , mnSheetViewTab(nSheetViewTab) + , mnSheetViewID(nSheetViewID) +{ + mpDrawUndo = GetSdrUndoAction(&pDocShell->GetDocument()); +} + +UndoInsertSheetView::~UndoInsertSheetView() = default; + +OUString UndoInsertSheetView::GetComment() const { return ScResId(STR_UNDO_INSERT_SHEET_VIEW); } + +void UndoInsertSheetView::Undo() +{ + ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); + if (!pViewShell) + return; + + // Switch back to the default tab first + pViewShell->SetTabNo(mnTab); + + pDocShell->SetInUndo(true); + bDrawIsInUndo = true; + pViewShell->DeleteTable(mnSheetViewTab, false); + bDrawIsInUndo = false; + pDocShell->SetInUndo(false); + + DoSdrUndoAction(mpDrawUndo.get(), &pDocShell->GetDocument()); + + pDocShell->Broadcast(SfxHint(SfxHintId::ScForceSetTab)); +} + +void UndoInsertSheetView::Redo() +{ + ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); + if (!pViewShell) + return; + + RedoSdrUndoAction(mpDrawUndo.get()); + + pDocShell->SetInUndo(true); + bDrawIsInUndo = true; + + ScDocument& rDoc = pDocShell->GetDocument(); + auto[nNewID, nNewTab] = rDoc.CreateNewSheetView(mnTab); + if (nNewID != InvalidSheetViewID) + { + mnSheetViewID = nNewID; + mnSheetViewTab = nNewTab; + pViewShell->SetTabNo(mnSheetViewTab); + } + + bDrawIsInUndo = false; + pDocShell->SetInUndo(false); +} + +void UndoInsertSheetView::Repeat(SfxRepeatTarget& /*rTarget*/) {} + +bool UndoInsertSheetView::CanRepeat(SfxRepeatTarget& /*rTarget*/) const { return false; } + +} // end sc namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index b900ae9256b8..80357315de27 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -714,8 +714,8 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI && comphelper::LibreOfficeKit::isCompatFlagSet( comphelper::LibreOfficeKit::Compat::scNoGridBackground); - SCTAB nTab = aOutputData.mnTab; - nTab = rDoc.GetDefaultViewTableNumber(nTab); // convert to default view tab + SCTAB nViewTab = aOutputData.mnTab; // the actual view tab (may be sheet view tab) + SCTAB nTab = rDoc.GetDefaultViewTableNumber(nViewTab); // default/logical tab for structural lookups SCCOL nX1 = aOutputData.mnX1; SCROW nY1 = aOutputData.mnY1; SCCOL nX2 = aOutputData.mnX2; @@ -758,7 +758,7 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI EditView* pEditView = nullptr; bool bEditMode = mrViewData.HasEditView(eWhich); - if ( bEditMode && mrViewData.GetRefTabNo() == nTab ) + if ( bEditMode && mrViewData.GetRefTabNo() == nViewTab ) { SCCOL nEditCol; SCROW nEditRow; @@ -840,7 +840,7 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI aDrawingRectLogic = PixelToLogic(aDrawingRectPixel, aDrawMode); } - bool bInPlaceEditing = bEditMode && (mrViewData.GetRefTabNo() == mrViewData.GetTabNumber()); + bool bInPlaceEditing = bEditMode && (mrViewData.GetRefTabNo() == nViewTab); vcl::Cursor* pInPlaceCrsr = nullptr; bool bInPlaceVisCursor = false; if (bInPlaceEditing) @@ -1174,7 +1174,7 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI if (!(bOtherEditMode && ( nCol2 >= nX1 && nCol1 <= nX2 && nRow2 >= nY1 && nRow1 <= nY2 ) - && rOtherViewData.GetRefTabNo() == nTab)) + && rOtherViewData.GetRefTabNo() == nViewTab)) continue; // only views where in place editing is occurring need to be rendered EditView* pOtherEditView = rOtherViewData.GetEditView(eOtherWhich); diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index b2f408454f44..2f3054ef5833 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -4503,41 +4503,46 @@ void ScViewData::OverrideWithLOKFreeze(ScSplitMode& eExHSplitMode, ScSplitMode& SCTAB ScViewData::CurrentTabForData() const { - if (!pThisTab) - return GetTabNumber(); - auto nSheetViewID = GetSheetViewID(); - if (nSheetViewID != sc::DefaultSheetViewID) - { - SCTAB nTab = mrDoc.GetSheetViewNumber(GetTabNumber(), nSheetViewID); - if (ValidTab(nTab)) - return nTab; - SAL_WARN("sc.ui","ScViewData::CurrentTabForData - invalid tab: " << nTab); - } return GetTabNumber(); } -void ScViewData::SetSheetViewID(sc::SheetViewID nID) +sc::SheetViewID ScViewData::GetSheetViewID() const { - pThisTab->mnSheetViewID = nID; + return mrDoc.GetTableSheetViewID(GetTabNumber()); +} - CalcPPT(); - RecalcPixPos(); +void ScViewData::SetSheetViewID(sc::SheetViewID nID) +{ + if (nID != sc::DefaultSheetViewID) + { + // Get the default tab (in case we're currently on a sheet view tab) + SCTAB nDefaultTab = GetDefaultViewTab(); + SCTAB nSheetViewTab = mrDoc.GetSheetViewNumber(nDefaultTab, nID); + if (ValidTab(nSheetViewTab)) + SetTabNo(nSheetViewTab); + } + else + { + // Returning to default view — switch back to the default tab + SCTAB nDefaultTab = GetDefaultViewTab(); + if (nDefaultTab != GetTabNumber()) + SetTabNo(nDefaultTab); + } } sc::SheetViewID ScViewData::GetSheetViewIDForSheet(SCTAB nTab) const { - if (!IsValidTabNumber(nTab)) - return sc::InvalidSheetViewID; - - if (!maTabData[nTab]) - return sc::InvalidSheetViewID; - - return maTabData[nTab]->mnSheetViewID; + return mrDoc.GetTableSheetViewID(nTab); } std::shared_ptr<sc::SheetViewManager> ScViewData::GetCurrentSheetViewManager() const { - return GetDocument().GetSheetViewManager(GetTabNumber()); + return GetDocument().GetSheetViewManager(GetDefaultViewTab()); +} + +SCTAB ScViewData::GetDefaultViewTab() const +{ + return mrDoc.GetDefaultViewTableNumber(GetTabNumber()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index 685fc5512dfe..ed18c4d1b676 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -2070,21 +2070,8 @@ void ScViewFunc::DataFormPutData( SCROW nCurrentRow , void ScViewFunc::SheetViewChanged() { - ScViewData& rViewData = GetViewData(); - ScDocShell& rDocSh = *rViewData.GetDocShell(); - ScDocument& rDocument = rViewData.GetDocument(); - SCTAB nTab = rViewData.GetTabNumber(); - rDocSh.PostPaint(0, 0, nTab, rDocument.MaxCol(), rDocument.MaxRow(), nTab, PaintPartFlags::All); - - if (ScTabViewShell* pViewShell = GetViewData().GetViewShell()) - { - ScModelObj* pModel = comphelper::getFromUnoTunnel<ScModelObj>(pViewShell->GetCurrentDocument()); - SfxLokHelper::notifyViewRenderState(pViewShell, pModel); - pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_HEADER, "all"_ostr); - pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY, "all"_ostr); - } - // Invalidate for all views (connected to the current document) - ScTabViewShell* pThisViewShell = rViewData.GetViewShell(); + // Invalidate the sheet view selector for all views connected to this document + ScTabViewShell* pThisViewShell = GetViewData().GetViewShell(); if (pThisViewShell) { ViewShellDocId nDocID = pThisViewShell->GetDocId(); @@ -2104,27 +2091,17 @@ void ScViewFunc::SheetViewChanged() void ScViewFunc::MakeNewSheetView() { - SCTAB nTab = GetViewData().GetTabNumber(); - ScDocument& rDocument = GetViewData().GetDocument(); - - auto[nSheetViewID, nSheetViewTab] = rDocument.CreateNewSheetView(nTab); + // Convert to default view, if we are in sheet view. + SCTAB nTab = GetViewData().GetDefaultViewTab(); + auto [nSheetViewID, nSheetViewTab] = GetViewData().GetDocShell()->GetDocFunc().InsertSheetView(nTab, true); if (nSheetViewID == sc::InvalidSheetViewID) { SAL_WARN("sc", "Sheet view couldn't be created"); return; } - GetViewData().SetSheetViewID(nSheetViewID); - - // Update - - ScDocShell& rDocSh = *GetViewData().GetDocShell(); - rDocSh.Broadcast(ScTablesHint(SC_TAB_INSERTED, nSheetViewTab)); - SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScTablesChanged)); - - // Need to make sure we return to the main sheet, to make sure we are not at a different location after inserting - SetTabNo(nTab); + SetTabNo(nSheetViewTab); SheetViewChanged(); } @@ -2136,17 +2113,16 @@ void ScViewFunc::RemoveCurrentSheetView() return; ScDocument& rDocument = GetViewData().GetDocument(); - SCTAB nTab = GetViewData().GetTabNumber(); - if (rDocument.IsSheetViewHolder(nTab)) - return; + SCTAB nDefaultTab = GetViewData().GetDefaultViewTab(); - auto pSheetManager = rDocument.GetSheetViewManager(nTab); + auto pSheetManager = rDocument.GetSheetViewManager(nDefaultTab); if (!pSheetManager) return; - GetViewData().SetSheetViewID(sc::DefaultSheetViewID); + SCTAB nSheetViewTab = rDocument.GetSheetViewNumber(nDefaultTab, nSheetViewID); - SCTAB nSheetViewTab = rDocument.GetSheetViewNumber(nTab, nSheetViewID); + // Switch back to the default tab before deleting + SetTabNo(nDefaultTab); // DeleteTable also removes the sheet view from the manager GetViewData().GetDocFunc().DeleteTable(nSheetViewTab, true); @@ -2157,7 +2133,7 @@ void ScViewFunc::RemoveCurrentSheetView() void ScViewFunc::SwitchSheetView(sc::SwitchSheetViewDirection eDirection) { ScDocument& rDocument = GetViewData().GetDocument(); - SCTAB nTab = GetViewData().GetTabNumber(); + SCTAB nTab = GetViewData().GetDefaultViewTab(); auto pSheetManager = rDocument.GetSheetViewManager(nTab); sc::SheetViewID nSheetViewID = GetViewData().GetSheetViewID(); @@ -2174,16 +2150,22 @@ void ScViewFunc::ExitSheetView() void ScViewFunc::SelectSheetView(sc::SheetViewID nSelectSheetViewID) { - SCTAB nTab = GetViewData().GetTabNumber(); - - if (GetViewData().GetDocument().IsSheetViewHolder(nTab)) - return; - if (nSelectSheetViewID == GetViewData().GetSheetViewID()) return; - GetViewData().SetSheetViewID(nSelectSheetViewID); + ScDocument& rDocument = GetViewData().GetDocument(); + SCTAB nDefaultTab = GetViewData().GetDefaultViewTab(); + if (nSelectSheetViewID == sc::DefaultSheetViewID) + { + SetTabNo(nDefaultTab); + } + else + { + SCTAB nSheetViewTab = rDocument.GetSheetViewNumber(nDefaultTab, nSelectSheetViewID); + if (ValidTab(nSheetViewTab)) + SetTabNo(nSheetViewTab); + } SheetViewChanged(); }
