officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu | 8 sc/CppunitTest_sc_sheetview_test.mk | 73 ++++++++ sc/Library_sc.mk | 2 sc/Module_sc.mk | 1 sc/inc/SheetView.hxx | 55 ++++++ sc/inc/SheetViewTypes.hxx | 21 ++ sc/inc/document.hxx | 12 + sc/inc/sc.hrc | 1 sc/inc/table.hxx | 15 + sc/qa/unit/helper/sctestviewcallback.hxx | 5 sc/qa/unit/tiledrendering/SheetViewTest.cxx | 91 ++++++++++ sc/qa/unit/tiledrendering/data/AutoFilter.ods |binary sc/sdi/scalc.sdi | 19 +- sc/sdi/tabvwsh.sdi | 1 sc/source/core/data/SheetView.cxx | 23 ++ sc/source/core/data/SheetViewManager.cxx | 35 +++ sc/source/core/data/document10.cxx | 51 +++++ sc/source/core/data/table1.cxx | 4 sc/source/core/data/table7.cxx | 6 sc/source/ui/inc/viewdata.hxx | 10 - sc/source/ui/inc/viewfunc.hxx | 4 sc/source/ui/view/tabcont.cxx | 10 - sc/source/ui/view/tabvwsh3.cxx | 4 sc/source/ui/view/tabvwsha.cxx | 6 sc/source/ui/view/viewdata.cxx | 17 + sc/source/ui/view/viewfun3.cxx | 15 + sc/source/ui/view/viewfunc.cxx | 7 27 files changed, 485 insertions(+), 11 deletions(-)
New commits: commit 22d9a204e43bbe01c5261345773b226b797d79dd Author: Tomaž Vajngerl <[email protected]> AuthorDate: Sun Jul 20 11:25:04 2025 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Wed Sep 3 10:15:21 2025 +0200 sc: add tests for sheet view - check auto filter sorting Check sorting the auto-filter in a sheet view doesn't influence the sorting in the other views. Change-Id: Id7b4be75b2071709b67c7cb27ed7b4303029efcc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189327 Reviewed-by: Kohei Yoshida <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sc/CppunitTest_sc_sheetview_test.mk b/sc/CppunitTest_sc_sheetview_test.mk new file mode 100644 index 000000000000..80a2e54fec05 --- /dev/null +++ b/sc/CppunitTest_sc_sheetview_test.mk @@ -0,0 +1,73 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# 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/. +# +#************************************************************************* + +$(eval $(call gb_CppunitTest_CppunitTest,sc_sheetview_test)) + +$(eval $(call gb_CppunitTest_use_common_precompiled_header,sc_sheetview_test)) + +$(eval $(call gb_CppunitTest_add_exception_objects,sc_sheetview_test, \ + sc/qa/unit/tiledrendering/SheetViewTest \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,sc_sheetview_test, \ + comphelper \ + cppu \ + cppuhelper \ + editeng \ + sal \ + sfx \ + sot \ + svl \ + svt \ + svxcore \ + sc \ + scfilt \ + scui \ + scqahelper \ + subsequenttest \ + test \ + unotest \ + $(call gb_Helper_optional,SCRIPTING, vbahelper) \ + vcl \ + tl \ + utl \ +)) + +$(eval $(call gb_CppunitTest_use_externals,sc_sheetview_test,\ + boost_headers \ + libxml2 \ +)) + +$(eval $(call gb_CppunitTest_set_include,sc_sheetview_test,\ + -I$(SRCDIR)/sc/source/ui/inc \ + -I$(SRCDIR)/sc/inc \ + -I$(SRCDIR)/sc/qa/unit/helper \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_CppunitTest_use_sdk_api,sc_sheetview_test)) +$(eval $(call gb_CppunitTest_use_api,sc_sheetview_test,oovbaapi)) +$(eval $(call gb_CppunitTest_use_ure,sc_sheetview_test)) +$(eval $(call gb_CppunitTest_use_vcl,sc_sheetview_test)) +$(eval $(call gb_CppunitTest_use_rdb,sc_sheetview_test,services)) +$(eval $(call gb_CppunitTest_use_configuration,sc_sheetview_test)) + +$(eval $(call gb_CppunitTest_add_arguments,sc_sheetview_test, \ + -env:arg-env=$(gb_Helper_LIBRARY_PATH_VAR)"$$$${$(gb_Helper_LIBRARY_PATH_VAR)+=$$$$$(gb_Helper_LIBRARY_PATH_VAR)}" \ +)) + +$(eval $(call gb_CppunitTest_use_uiconfigs,sc_sheetview_test, \ + modules/scalc \ + sfx \ + svt \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk index 8b4ebee3ed39..723eba9acbf1 100644 --- a/sc/Module_sc.mk +++ b/sc/Module_sc.mk @@ -227,6 +227,7 @@ $(eval $(call gb_Module_add_subsequentcheck_targets,sc,\ CppunitTest_sc_shapeobj \ CppunitTest_sc_sheetlinkobj \ CppunitTest_sc_sheetlinksobj \ + CppunitTest_sc_sheetview_test \ CppunitTest_sc_solverobj \ CppunitTest_sc_sortdescriptorbaseobj \ CppunitTest_sc_spreadsheetsettings \ diff --git a/sc/qa/unit/helper/sctestviewcallback.hxx b/sc/qa/unit/helper/sctestviewcallback.hxx index a5452a1f8f3e..78d5767649aa 100644 --- a/sc/qa/unit/helper/sctestviewcallback.hxx +++ b/sc/qa/unit/helper/sctestviewcallback.hxx @@ -18,6 +18,7 @@ #include <test/lokcallback.hxx> #include "scqahelperdllapi.h" +#include <tabvwsh.hxx> class SfxViewShell; @@ -89,6 +90,10 @@ public: void callbackImpl(int nType, const char* pPayload); void ClearAllInvalids(); + + SfxViewShell* getViewShell() { return mpViewShell; } + ScTabViewShell* getTabViewShell() { return dynamic_cast<ScTabViewShell*>(mpViewShell); } + int getViewID() { return mnView; } }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/tiledrendering/SheetViewTest.cxx b/sc/qa/unit/tiledrendering/SheetViewTest.cxx new file mode 100644 index 000000000000..2f4138943c37 --- /dev/null +++ b/sc/qa/unit/tiledrendering/SheetViewTest.cxx @@ -0,0 +1,91 @@ +/* -*- 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 <sctiledrenderingtest.hxx> + +#include <comphelper/propertyvalue.hxx> +#include <comphelper/propertysequence.hxx> +#include <sfx2/lokhelper.hxx> +#include <vcl/scheduler.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> +#include <sctestviewcallback.hxx> +#include <docuno.hxx> + +using namespace css; + +class SheetViewTest : public ScTiledRenderingTest +{ +}; + +/** Check auto-filter sorting. + * + * Auto filter sorting should only influence the values in the + * current sheet view and not in the other viewes. + */ +CPPUNIT_TEST_FIXTURE(SheetViewTest, testSheetViewAutoFilter) +{ + // Create two views, and leave the second one current. + ScModelObj* pModelObj = createDoc("AutoFilter.ods"); + pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + + // Setup 2 views + ScTestViewCallback aView1; + ScTabViewShell* pTabView1 = aView1.getTabViewShell(); + + SfxLokHelper::createView(); + + ScTestViewCallback aView2; + ScTabViewShell* pTabView2 = aView2.getTabViewShell(); + + CPPUNIT_ASSERT(pTabView1 != pTabView2); + CPPUNIT_ASSERT(aView1.getViewID() != aView2.getViewID()); + + // Switch to view 1 + SfxLokHelper::setView(aView1.getViewID()); + Scheduler::ProcessEventsToIdle(); + + // Check AutoFilter values + CPPUNIT_ASSERT_EQUAL(u"4"_ustr, pTabView1->GetCurrentString(0, 1)); + CPPUNIT_ASSERT_EQUAL(u"5"_ustr, pTabView1->GetCurrentString(0, 2)); + CPPUNIT_ASSERT_EQUAL(u"3"_ustr, pTabView1->GetCurrentString(0, 3)); + CPPUNIT_ASSERT_EQUAL(u"7"_ustr, pTabView1->GetCurrentString(0, 4)); + + // Switch to view 2 + SfxLokHelper::setView(aView2.getViewID()); + Scheduler::ProcessEventsToIdle(); + + // Check auto-filter values + CPPUNIT_ASSERT_EQUAL(u"4"_ustr, pTabView2->GetCurrentString(0, 1)); + CPPUNIT_ASSERT_EQUAL(u"5"_ustr, pTabView2->GetCurrentString(0, 2)); + CPPUNIT_ASSERT_EQUAL(u"3"_ustr, pTabView2->GetCurrentString(0, 3)); + CPPUNIT_ASSERT_EQUAL(u"7"_ustr, pTabView2->GetCurrentString(0, 4)); + + // Create a new sheet view for view 2 + dispatchCommand(mxComponent, u".uno:NewSheetView"_ustr, {}); + Scheduler::ProcessEventsToIdle(); + + // Sort AutoFilter descending + dispatchCommand(mxComponent, u".uno:SortDescending"_ustr, {}); + + // Check view 2 - sorted + CPPUNIT_ASSERT_EQUAL(u"7"_ustr, pTabView2->GetCurrentString(0, 1)); + CPPUNIT_ASSERT_EQUAL(u"5"_ustr, pTabView2->GetCurrentString(0, 2)); + CPPUNIT_ASSERT_EQUAL(u"4"_ustr, pTabView2->GetCurrentString(0, 3)); + CPPUNIT_ASSERT_EQUAL(u"3"_ustr, pTabView2->GetCurrentString(0, 4)); + + // Check view 1 - unsorted + CPPUNIT_ASSERT_EQUAL(u"4"_ustr, pTabView1->GetCurrentString(0, 1)); + CPPUNIT_ASSERT_EQUAL(u"5"_ustr, pTabView1->GetCurrentString(0, 2)); + CPPUNIT_ASSERT_EQUAL(u"3"_ustr, pTabView1->GetCurrentString(0, 3)); + CPPUNIT_ASSERT_EQUAL(u"7"_ustr, pTabView1->GetCurrentString(0, 4)); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/tiledrendering/data/AutoFilter.ods b/sc/qa/unit/tiledrendering/data/AutoFilter.ods new file mode 100644 index 000000000000..5feac17cce7e Binary files /dev/null and b/sc/qa/unit/tiledrendering/data/AutoFilter.ods differ diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index 2b7a047f9f3b..5352dc27d615 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -79,6 +79,8 @@ public: ~ScViewFunc(); SC_DLLPUBLIC const ScPatternAttr* GetSelectionPattern (); + SC_DLLPUBLIC OUString GetCurrentString(SCCOL nCol, SCROW nRow); + void GetSelectionFrame( std::shared_ptr<SvxBoxItem>& rLineOuter, std::shared_ptr<SvxBoxInfoItem>& rLineInner ); diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index b0b463e8dd2e..d241a3463d71 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -1062,6 +1062,13 @@ const ScPatternAttr* ScViewFunc::GetSelectionPattern() } } +OUString ScViewFunc::GetCurrentString(SCCOL nCol, SCROW nRow) +{ + SCTAB nTab = GetViewData().GetTabNo(); + ScDocument& rDoc = GetViewData().GetDocument(); + return rDoc.GetString({nCol, nRow, nTab}); +} + void ScViewFunc::GetSelectionFrame( std::shared_ptr<SvxBoxItem>& rLineOuter, std::shared_ptr<SvxBoxInfoItem>& rLineInner ) commit 9af7ea82a7e1dc9b46ab9a12144c9168aa0be66d Author: Tomaž Vajngerl <[email protected]> AuthorDate: Fri Jun 20 22:54:26 2025 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Wed Sep 3 10:15:14 2025 +0200 sc: initial commit of "sheet view" functionality The idea of a sheet view is that we can change the auto filter's fitlering and sorting in the current view without influencing the filter in other views. This is realised with a copy of a current sheet, which is shown in the current view instead of the default sheet (which still can be seen by other views). Very important aspect is to keep the tables in sync. There can be multiple sheet views and in the current view we can switch between the default view and other sheet views freely. This change adds a command to create a new sheet view. When the command is triggered, it then creates a copy of the current sheet and registers a new sheet view for that sheet/table. The current view automatically uses the copy of the sheet for all changes, but if the sheet is changed, nothing is synched yet. Change-Id: Ia77c5ab759113eaae237c638015401418ab56033 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189326 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Kohei Yoshida <[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 83c4ee8f1fc1..fc4876011a0e 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu @@ -2704,6 +2704,14 @@ <value>1</value> </prop> </node> + <node oor:name=".uno:NewSheetView" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">New 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/Library_sc.mk b/sc/Library_sc.mk index 3d63f7d6d603..d1a2cd484ca2 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -189,6 +189,8 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/rowheightcontext \ sc/source/core/data/segmenttree \ sc/source/core/data/sheetevents \ + sc/source/core/data/SheetView \ + sc/source/core/data/SheetViewManager \ sc/source/core/data/simpleformulacalc \ sc/source/core/data/SolverSettings \ sc/source/core/data/sortparam \ diff --git a/sc/inc/SheetView.hxx b/sc/inc/SheetView.hxx new file mode 100644 index 000000000000..abb0a3278ca7 --- /dev/null +++ b/sc/inc/SheetView.hxx @@ -0,0 +1,55 @@ +/* -*- 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 <vector> +#include "SheetViewTypes.hxx" + +class ScTable; + +namespace sc +{ +/** Stores information of a sheet view. + * + * A sheet view is a special view of a sheet that can be filtered and sorted + * independently from other views of the sheet. + **/ +class SheetView +{ +private: + ScTable* mpTable = nullptr; + +public: + SheetView() = default; + SheetView(ScTable* pTable); + + ScTable* getTablePointer() const; + + /** A sheet view is valid if the pointer to the table is set */ + bool isValid() const; +}; + +/** Manager and the holder of the sheet views for a sheet. */ +class SheetViewManager +{ +private: + std::vector<SheetView> maViews; + +public: + SheetViewManager(); + + /** Creates a new sheet view. */ + SheetViewID create(ScTable* pSheetViewTable); + + /** Returns a sheet view for the ID. */ + SheetView get(SheetViewID nID); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/SheetViewTypes.hxx b/sc/inc/SheetViewTypes.hxx new file mode 100644 index 000000000000..51e676423d5f --- /dev/null +++ b/sc/inc/SheetViewTypes.hxx @@ -0,0 +1,21 @@ +/* -*- 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 <sal/types.h> +namespace sc +{ +/** The ID of a sheet view */ +typedef sal_Int32 SheetViewID; + +/** Defines the value to identify the default view of the sheet */ +constexpr SheetViewID DefaultSheetViewID = -1; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index caa63a15fce8..61c914f532bc 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -58,6 +58,8 @@ #include "markdata.hxx" #include "drwlayer.hxx" +#include "SheetViewTypes.hxx" + #include <oox/helper/refvector.hxx> namespace com::sun::star::chart2 { class XChartDocument; } @@ -2394,6 +2396,16 @@ public: */ void CheckIntegrity( SCTAB nTab ) const; + /* Sheet View */ + + /** Creates a new sheet view for the table, using the sheet view table */ + sal_Int32 CreateNewSheetView(SCTAB nMainTable, SCTAB nSheetViewTable); + + /** Return the sheet view table for the ID */ + SCTAB GetSheetViewNumber(SCTAB nTab, sc::SheetViewID nID); + bool IsSheetView(SCTAB nTab) const; + void SetSheetView(SCTAB nTab, bool bSheetView); + private: ScDocument(const ScDocument& r) = delete; diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index 63ffdd2b6228..05badb5110a1 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -285,6 +285,7 @@ class SvxZoomSliderItem; #define FID_FUNCTION_BOX (VIEW_MENU_START + 8) #define FID_NORMALVIEWMODE (VIEW_MENU_START + 9) #define FID_TOGGLEFORMULA (VIEW_MENU_START + 10) +#define FID_NEW_SHEET_VIEW (VIEW_MENU_START + 11) #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/inc/table.hxx b/sc/inc/table.hxx index ccafa4a89fb2..0e87fb4753c7 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -84,6 +84,7 @@ class CompileFormulaContext; struct SetFormulaDirtyContext; class ColumnIterator; class ScDrawObjData; +class SheetViewManager; } class SfxItemSet; @@ -253,6 +254,9 @@ private: bool mbPageBreaksValid:1; bool mbForceBreaks:1; bool mbTotalsRowBelow:1; + + bool mbIsSheetView : 1 = false; + /** this is touched from formula group threading context */ std::atomic<bool> bStreamValid; @@ -262,6 +266,8 @@ private: // Default attributes for the unallocated columns. ScColumnData aDefaultColData; + std::shared_ptr<sc::SheetViewManager> mpSheetViewManager; + friend class ScDocument; // for FillInfo friend class ScColumn; friend class ScValueIterator; @@ -1191,6 +1197,15 @@ public: void CollectBroadcasterState(sc::BroadcasterState& rState) const; + std::shared_ptr<sc::SheetViewManager> const& GetSheetViewManager(); + + bool IsSheetView() const { return mbIsSheetView; } + + void SetSheetView(bool bValue) + { + mbIsSheetView = bValue; + } + private: void FillFormulaVertical( diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi index bfffd7800b7c..13cba78c815c 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -6015,7 +6015,6 @@ SfxBoolItem ViewRowColumnHeaders FID_TOGGLEHEADERS SfxBoolItem ToggleFormula FID_TOGGLEFORMULA - [ /* flags */ AutoUpdate = FALSE, @@ -6026,13 +6025,29 @@ SfxBoolItem ToggleFormula FID_TOGGLEFORMULA RecordAbsolute = FALSE, RecordPerSet; - /* config */ AccelConfig = TRUE, MenuConfig = FALSE, ToolBoxConfig = FALSE, GroupId = SfxGroupId::View +] + +SfxBoolItem NewSheetView FID_NEW_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 ] diff --git a/sc/sdi/tabvwsh.sdi b/sc/sdi/tabvwsh.sdi index af9f3458b0d1..ac40eb90b7f0 100644 --- a/sc/sdi/tabvwsh.sdi +++ b/sc/sdi/tabvwsh.sdi @@ -177,6 +177,7 @@ interface TableEditView FID_TOGGLECOLROWHIGHLIGHTING [ ExecMethod = Execute; StateMethod = GetState; ] FID_TOGGLEHEADERS [ ExecMethod = Execute; StateMethod = GetState; ] FID_TOGGLEFORMULA [ ExecMethod = Execute; StateMethod = GetState; ] + FID_NEW_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/SheetView.cxx b/sc/source/core/data/SheetView.cxx new file mode 100644 index 000000000000..05ae7a72cc70 --- /dev/null +++ b/sc/source/core/data/SheetView.cxx @@ -0,0 +1,23 @@ +/* -*- 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 <SheetView.hxx> + +namespace sc +{ +SheetView::SheetView(ScTable* pTable) + : mpTable(pTable) +{ +} + +ScTable* SheetView::getTablePointer() const { return mpTable; } +bool SheetView::isValid() const { return mpTable; } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/SheetViewManager.cxx b/sc/source/core/data/SheetViewManager.cxx new file mode 100644 index 000000000000..d2132d3ac610 --- /dev/null +++ b/sc/source/core/data/SheetViewManager.cxx @@ -0,0 +1,35 @@ +/* -*- 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 <SheetView.hxx> +#include <table.hxx> + +namespace sc +{ +SheetViewManager::SheetViewManager() {} + +SheetViewID SheetViewManager::create(ScTable* pSheetViewTable) +{ + sal_Int32 nID = maViews.size(); + maViews.emplace_back(pSheetViewTable); + return SheetViewID(nID); +} + +SheetView SheetViewManager::get(SheetViewID nID) +{ + if (nID >= 0 && o3tl::make_unsigned(nID) < maViews.size()) + { + if (maViews[nID].isValid()) + return maViews[nID]; + } + return SheetView(); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index 4c6527304a7e..57eac290b43c 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -28,6 +28,7 @@ #include <docsh.hxx> #include <bcaslot.hxx> #include <broadcast.hxx> +#include <SheetView.hxx> // Add totally brand-new methods to this source file. @@ -1114,4 +1115,54 @@ sc::BroadcasterState ScDocument::GetBroadcasterState() const return aState; } +bool ScDocument::IsSheetView(SCTAB nTab) const +{ + if (ScTable const* pTable = FetchTable(nTab)) + { + return pTable->IsSheetView(); + } + return false; +} + +void ScDocument::SetSheetView(SCTAB nTab, bool bSheetView) +{ + if (ScTable* pTable = FetchTable(nTab)) + { + pTable->SetSheetView(bSheetView); + } +} + +sc::SheetViewID ScDocument::CreateNewSheetView(SCTAB nMainTable, SCTAB nSheetViewTable) +{ + if (ScTable* pTable = FetchTable(nMainTable)) + { + if (pTable->IsSheetView()) + return -1; + + if (ScTable* pSheetViewTable = FetchTable(nSheetViewTable)) + { + auto nSheetViewID = pTable->GetSheetViewManager()->create(pSheetViewTable); + return nSheetViewID; + } + } + return -1; +} + +SCTAB ScDocument::GetSheetViewNumber(SCTAB nTab, sc::SheetViewID nID) +{ + if (ScTable* pMainSheet = FetchTable(nTab)) + { + if (pMainSheet->IsSheetView()) + return nTab; + + sc::SheetView aView = pMainSheet->GetSheetViewManager()->get(nID); + if (aView.isValid()) + { + return aView.getTablePointer()->GetTab(); + } + assert(false && "a non valid sheet view is unexpected..."); + } + return -1; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index e0ca615e0095..af27f9405c1b 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -53,6 +53,7 @@ #include <rowheightcontext.hxx> #include <compressedarray.hxx> #include <tabvwsh.hxx> +#include <SheetView.hxx> #include <vcl/svapp.hxx> #include <formula/vectortoken.hxx> @@ -277,7 +278,8 @@ ScTable::ScTable( ScDocument& rDoc, SCTAB nNewTab, const OUString& rNewName, mbPageBreaksValid(false), mbForceBreaks(false), mbTotalsRowBelow(true), - bStreamValid(false) + bStreamValid(false), + mpSheetViewManager(new sc::SheetViewManager()) { aDefaultColData.InitAttrArray(new ScAttrArray(static_cast<SCCOL>(-1), nNewTab, rDoc, nullptr)); if (bColInfo) diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx index 0f8cd8b06977..f79ca5f00396 100644 --- a/sc/source/core/data/table7.cxx +++ b/sc/source/core/data/table7.cxx @@ -666,4 +666,10 @@ const std::shared_ptr<sc::SolverSettings> & ScTable::GetSolverSettings() return m_pSolverSettings; } +std::shared_ptr<sc::SheetViewManager> const& ScTable::GetSheetViewManager() +{ + return mpSheetViewManager; +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx index ea9b1260ac54..ea57f68e05f8 100644 --- a/sc/source/ui/inc/viewdata.hxx +++ b/sc/source/ui/inc/viewdata.hxx @@ -245,6 +245,8 @@ 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); void InitData(const ScDocument& rDoc); @@ -397,7 +399,13 @@ public: SCTAB GetRefTabNo() const { return nRefTabNo; } void SetRefTabNo( SCTAB nNewTab ) { nRefTabNo = nNewTab; } - SCTAB GetTabNo() const { return mnTabNumber; } + SCTAB GetTab() const { return mnTabNumber; } + SC_DLLPUBLIC SCTAB GetTabNo() const; + void SetSheetViewID(sc::SheetViewID nID) + { + pThisTab->mnSheetViewID = nID; + } + SCCOL MaxCol() const { return mrDoc.MaxCol(); } SCROW MaxRow() const { return mrDoc.MaxRow(); } ScSplitPos GetActivePart() const { return pThisTab->eWhichActive; } diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index fbae8071aea8..2b7a047f9f3b 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -352,6 +352,8 @@ public: void DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab, bool bAttrChanged ); + void MakeNewSheetView(); + // Internal helper functions protected: static void UpdateLineAttrs( ::editeng::SvxBorderLine& rLine, diff --git a/sc/source/ui/view/tabcont.cxx b/sc/source/ui/view/tabcont.cxx index 7f474d8e8fef..b180d1de4bb7 100644 --- a/sc/source/ui/view/tabcont.cxx +++ b/sc/source/ui/view/tabcont.cxx @@ -76,7 +76,7 @@ ScTabControl::ScTabControl( vcl::Window* pParent, ScViewData* pData ) } } - SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 ); + SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTab()) + 1 ); SetSizePixel( Size(SC_TABBAR_DEFWIDTH, 0) ); @@ -264,7 +264,7 @@ 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->GetTabNo()) + 1 ); + SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTab()) + 1 ); return; } @@ -274,7 +274,7 @@ void ScTabControl::Select() sal_uInt16 nPage = nCurId - 1; // OLE-inplace deactivate - if ( nPage != static_cast<sal_uInt16>(pViewData->GetTabNo()) ) + if ( nPage != static_cast<sal_uInt16>(pViewData->GetTab()) ) pViewData->GetView()->DrawMarkListHasChanged(); // InputEnterHandler onlw when not reference input @@ -395,7 +395,7 @@ void ScTabControl::UpdateStatus() } } } - SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 ); + SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTab()) + 1 ); if (bActive) { @@ -488,7 +488,7 @@ void ScTabControl::DoDrag() ScDocShell* pDocSh = pViewData->GetDocShell(); ScDocument& rDoc = pDocSh->GetDocument(); - SCTAB nTab = pViewData->GetTabNo(); + SCTAB nTab = pViewData->GetTab(); ScRange aTabRange( 0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab ); ScMarkData aTabMark = pViewData->GetMarkData(); aTabMark.ResetMark(); // doesn't change marked table information diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx index 8c0c18aeb250..6f358145b896 100644 --- a/sc/source/ui/view/tabvwsh3.cxx +++ b/sc/source/ui/view/tabvwsh3.cxx @@ -1046,6 +1046,10 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) } break; + case FID_NEW_SHEET_VIEW: + MakeNewSheetView(); + break; + case SID_ATTR_ZOOM: // status row case FID_SCALE: { diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx index 67e2fe125430..cd236ada9642 100644 --- a/sc/source/ui/view/tabvwsha.cxx +++ b/sc/source/ui/view/tabvwsha.cxx @@ -396,6 +396,12 @@ void ScTabViewShell::GetState( SfxItemSet& rSet ) } break; + case FID_NEW_SHEET_VIEW: + { + // TODO + } + break; + case FID_NORMALVIEWMODE: case FID_PAGEBREAKMODE: // always handle both slots - they exclude each other diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index b25646f181e8..3e01c18c88b0 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -934,7 +934,7 @@ void ScViewData::DeleteTab( SCTAB nTab ) assert(nTab < static_cast<SCTAB>(maTabData.size())); maTabData.erase(maTabData.begin() + nTab); - if (o3tl::make_unsigned(GetTabNo()) >= maTabData.size()) + if (o3tl::make_unsigned(GetTab()) >= maTabData.size()) { EnsureTabDataSize(1); mnTabNumber = maTabData.size() - 1; @@ -950,7 +950,7 @@ void ScViewData::DeleteTabs( SCTAB nTab, SCTAB nSheets ) maMarkData.DeleteTab(nTab + i); } maTabData.erase(maTabData.begin() + nTab, maTabData.begin()+ nTab+nSheets); - if (o3tl::make_unsigned(GetTabNo()) >= maTabData.size()) + if (o3tl::make_unsigned(GetTab()) >= maTabData.size()) { EnsureTabDataSize(1); mnTabNumber = maTabData.size() - 1; @@ -4480,4 +4480,17 @@ void ScViewData::OverrideWithLOKFreeze(ScSplitMode& eExHSplitMode, ScSplitMode& } } +SCTAB ScViewData::GetTabNo() const +{ + if (!pThisTab) + return GetTab(); + auto nSheetViewID = pThisTab->mnSheetViewID; + if (nSheetViewID != sc::DefaultSheetViewID) + { + SCTAB nTab = mrDoc.GetSheetViewNumber(GetTab(), nSheetViewID); + return nTab; + } + return GetTab(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index a0bd3ff432fe..cc11d6e45f8e 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -2061,4 +2061,19 @@ void ScViewFunc::DataFormPutData( SCROW nCurrentRow , pDocSh->UpdateOle(GetViewData()); } +void ScViewFunc::MakeNewSheetView() +{ + SCTAB nTab = GetViewData().GetTab(); + ScDocument& rDoc = GetViewData().GetDocument(); + + SCTAB nSheetViewTab = nTab + 1; + if (rDoc.CopyTab(nTab, nSheetViewTab)) + { + SetTabNo(nSheetViewTab); + rDoc.SetSheetView(nSheetViewTab, true); + sc::SheetViewID nSheetViewID = rDoc.CreateNewSheetView(nTab, nSheetViewTab); + GetViewData().SetSheetViewID(nSheetViewID); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
