include/svl/poolitem.hxx | 1 offapi/com/sun/star/sheet/DatabaseRange.idl | 30 officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu | 34 oox/source/token/properties.txt | 5 sc/Library_sc.mk | 3 sc/Library_scfilt.mk | 1 sc/UIConfig_scalc.mk | 1 sc/inc/dbdata.hxx | 55 + sc/inc/document.hxx | 5 sc/inc/mid.h | 3 sc/inc/sc.hrc | 1 sc/inc/scitems.hxx | 4 sc/inc/shellids.hxx | 1 sc/inc/tablestyle.hxx | 109 ++ sc/inc/unonames.hxx | 5 sc/sdi/scalc.sdi | 17 sc/sdi/scslots.sdi | 13 sc/sdi/tableshell.sdi | 18 sc/source/core/data/documen2.cxx | 13 sc/source/core/data/fillinfo.cxx | 92 + sc/source/core/data/tablestyle.cxx | 313 +++++ sc/source/core/tool/dbdata.cxx | 267 +++++ sc/source/filter/excel/xedbdata.cxx | 11 sc/source/filter/excel/xeroot.cxx | 2 sc/source/filter/excel/xestyle.cxx | 83 + sc/source/filter/inc/defaulttablestyles.hxx | 103 + sc/source/filter/inc/stylesbuffer.hxx | 53 - sc/source/filter/inc/stylesfragment.hxx | 15 sc/source/filter/inc/tablebuffer.hxx | 15 sc/source/filter/inc/xeroot.hxx | 3 sc/source/filter/inc/xestyle.hxx | 30 sc/source/filter/oox/defaulttablestyles.cxx | 142 ++ sc/source/filter/oox/defaulttablestyles.inc | 33 sc/source/filter/oox/stylesbuffer.cxx | 151 ++ sc/source/filter/oox/stylesfragment.cxx | 32 sc/source/filter/oox/tablebuffer.cxx | 29 sc/source/filter/oox/tablefragment.cxx | 2 sc/source/filter/oox/workbookfragment.cxx | 4 sc/source/ui/app/msgpool.cxx | 4 sc/source/ui/app/scdll.cxx | 2 sc/source/ui/app/typemap.cxx | 1 sc/source/ui/inc/tableshell.hxx | 42 sc/source/ui/inc/tabvwsh.hxx | 8 sc/source/ui/sidebar/DatabasePropertyPanel.cxx | 140 ++ sc/source/ui/sidebar/DatabasePropertyPanel.hxx | 67 + sc/source/ui/sidebar/ScPanelFactory.cxx | 6 sc/source/ui/unoobj/datauno.cxx | 63 + sc/source/ui/view/tableshell.cxx | 128 ++ sc/source/ui/view/tabview3.cxx | 8 sc/source/ui/view/tabvwsh4.cxx | 37 sc/uiconfig/scalc/ui/sidebardatabase.ui | 124 ++ sc/workben/generate_ooxml_tablestyle_info.py | 582 +++++++++++ svx/source/sidebar/paragraph/ParaPropertyPanel.cxx | 1 53 files changed, 2891 insertions(+), 21 deletions(-)
New commits: commit f1fcfc86d0b85ca2f01b0ee908226c2689bf1f27 Author: Markus Mohrhard <[email protected]> AuthorDate: Mon Aug 4 02:21:26 2025 +0800 Commit: Andras Timar <[email protected]> CommitDate: Mon Nov 17 18:59:30 2025 +0100 add sidebar entry for calc database ranges Change-Id: I0b141c4e6fefd78bfcc7b30f4aad7fdcc42eee23 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193667 Tested-by: Andras Timar <[email protected]> Reviewed-by: Andras Timar <[email protected]> diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx index f0573a80140f..aa0642093dd0 100644 --- a/include/svl/poolitem.hxx +++ b/include/svl/poolitem.hxx @@ -135,6 +135,7 @@ enum class SfxItemType : sal_uInt16 SbxItemType, ScCondFormatItemType, ScConsolidateItemType, + ScDatabaseSettingItemType, ScHyphenateCellType, ScIndentItemType, ScInputStatusItemType, diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu index a292b7dae985..c375f7e30dec 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu @@ -450,6 +450,7 @@ Calc, EditCell, visible ; Calc, Pivot, visible ; Calc, Sparkline, visible ; + Calc, Table, visible ; </value> </prop> <prop oor:name="ImplementationURL" oor:type="xs:string"> @@ -486,6 +487,7 @@ Calc, EditCell, visible ; Calc, Pivot, visible, .uno:CellTextDlg ; Calc, Sparkline, visible ; + Calc, Table, visible ; DrawImpress, Draw, hidden ; DrawImpress, DrawFontwork, hidden ; DrawImpress, DrawText, visible ; @@ -1476,6 +1478,7 @@ Calc, EditCell, visible ; Calc, Pivot, visible ; Calc, Sparkline, visible ; + Calc, Table, visible ; </value> </prop> <prop oor:name="ImplementationURL" oor:type="xs:string"> @@ -1510,6 +1513,7 @@ Calc, default, visible ; Calc, Pivot, visible ; Calc, Sparkline, visible ; + Calc, Table, visible ; </value> </prop> <prop oor:name="ImplementationURL" oor:type="xs:string"> @@ -1523,6 +1527,35 @@ </prop> </node> + <node oor:name="ScDatabasePropertyPanel" oor:op="replace"> + <prop oor:name="Title" oor:type="xs:string"> + <value xml:lang="en-US">Database Range</value> + </prop> + <prop oor:name="Id" oor:type="xs:string"> + <value>ScDatabasePropertyPanel</value> + </prop> + <prop oor:name="DeckId" oor:type="xs:string"> + <value>PropertyDeck</value> + </prop> + <prop oor:name="DefaultMenuCommand"> + <value>.uno:FormatCellDialog</value> + </prop> + <prop oor:name="ContextList"> + <value oor:separator=";"> + Calc, Table, visible ; + </value> + </prop> + <prop oor:name="ImplementationURL" oor:type="xs:string"> + <value>private:resource/toolpanel/ScPanelFactory/DatabasePropertyPanel</value> + </prop> + <prop oor:name="OrderIndex" oor:type="xs:int"> + <value>500</value> + </prop> + <prop oor:name="WantsAWT" oor:type="xs:boolean"> + <value>false</value> + </prop> + </node> + <node oor:name="ScNumberFormatPropertyPanel" oor:op="replace"> <prop oor:name="Title" oor:type="xs:string"> <value xml:lang="en-US">Number Format</value> @@ -1544,6 +1577,7 @@ Calc, default, visible ; Calc, Pivot, visible ; Calc, Sparkline, visible ; + Calc, Table, visible ; </value> </prop> <prop oor:name="ImplementationURL" oor:type="xs:string"> diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 0b374efe5cc6..0fa088f7b7a4 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -532,6 +532,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/ui/sidebar/CellLineStyleValueSet \ sc/source/ui/sidebar/CellAppearancePropertyPanel \ sc/source/ui/sidebar/CellBorderStyleControl \ + sc/source/ui/sidebar/DatabasePropertyPanel \ sc/source/ui/sidebar/NumberFormatControl \ sc/source/ui/sidebar/NumberFormatPropertyPanel \ sc/source/ui/sidebar/ScPanelFactory \ @@ -688,6 +689,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/ui/view/spelleng \ sc/source/ui/view/spellcheckcontext \ sc/source/ui/view/tabcont \ + sc/source/ui/view/tableshell \ sc/source/ui/view/tabsplit \ sc/source/ui/view/tabview \ sc/source/ui/view/tabview2 \ diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk index 11dffab28675..98bc564378fd 100644 --- a/sc/UIConfig_scalc.mk +++ b/sc/UIConfig_scalc.mk @@ -245,6 +245,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\ sc/uiconfig/scalc/ui/sidebaralignment \ sc/uiconfig/scalc/ui/sidebarnumberformat \ sc/uiconfig/scalc/ui/sidebarcellappearance \ + sc/uiconfig/scalc/ui/sidebardatabase \ sc/uiconfig/scalc/ui/simplerefdialog \ sc/uiconfig/scalc/ui/solverdlg \ sc/uiconfig/scalc/ui/solveroptionsdialog \ diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx index 8a4270912913..8ff355c3dc98 100644 --- a/sc/inc/dbdata.hxx +++ b/sc/inc/dbdata.hxx @@ -26,6 +26,7 @@ #include "rangelst.hxx" #include <svl/listener.hxx> +#include <svl/poolitem.hxx> #include <memory> #include <set> @@ -36,6 +37,40 @@ struct ScSortParam; struct ScQueryParam; struct ScSubTotalParam; +class SC_DLLPUBLIC ScDatabaseSettingItem final : public SfxPoolItem +{ + bool mbHeaderRow; + bool mbTotalRow; + bool mbFirstCol; + bool mbLastCol; + bool mbStripedRows; + bool mbStripedCols; + bool mbShowFilters; + +public: + static SfxPoolItem* CreateDefault(); + DECLARE_ITEM_TYPE_FUNCTION(ScDatabaseSettingItem) + ScDatabaseSettingItem(); + ScDatabaseSettingItem(bool bHeaderRow, bool bTotalRow, bool bFirstCol, bool bLastCol, bool bStripedRows, bool bStripedCols, bool bShowFilter); + ScDatabaseSettingItem( const ScDatabaseSettingItem& rItem ); + virtual ~ScDatabaseSettingItem() override; + + virtual bool QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const override; + virtual bool PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId ) override; + + ScDatabaseSettingItem& operator=( const ScDatabaseSettingItem& rItem ); + virtual bool operator==( const SfxPoolItem& ) const override; + virtual ScDatabaseSettingItem* Clone( SfxItemPool *pPool = nullptr ) const override; + + bool HasHeaderRow() const; + bool HasTotalRow() const; + bool HasFirstCol() const; + bool HasLastCol() const; + bool HasStripedRows() const; + bool HasStripedCols() const; + bool HasShowFilters() const; +}; + /** Enum used to indicate which portion of the DBArea is to be considered. */ enum class ScDBDataPortion { @@ -95,6 +130,7 @@ struct SAL_DLLPUBLIC ScTableStyleParam bool mbLastColumn; ScTableStyleParam(); + ScTableStyleParam(const ScTableStyleParam& rParam) = default; bool operator== (const ScTableStyleParam& rData) const; }; diff --git a/sc/inc/mid.h b/sc/inc/mid.h index 614bcf91ee02..e609a184e7ff 100644 --- a/sc/inc/mid.h +++ b/sc/inc/mid.h @@ -24,6 +24,9 @@ #define MID_2 2 #define MID_3 3 #define MID_4 4 +#define MID_5 4 +#define MID_6 4 +#define MID_7 4 #endif diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index cd6f885a7c59..4d5ff4ad684c 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -637,6 +637,7 @@ static_assert(SID_PREVIEW_END < SID_KEYFUNC_START, "calc slots ids trampling inf #define SID_UNGROUP_SPARKLINES (SID_NEW_SLOTS+115) #define SID_EDIT_SPARKLINE (SID_NEW_SLOTS+116) #define SID_SC_OPT_LINKS TypedWhichId<SfxBoolItem>(SID_NEW_SLOTS + 117) +#define SID_DATABASE_SETTINGS (SID_NEW_SLOTS+118) // idl parameter diff --git a/sc/inc/scitems.hxx b/sc/inc/scitems.hxx index c2485993546e..cf372fb99a15 100644 --- a/sc/inc/scitems.hxx +++ b/sc/inc/scitems.hxx @@ -75,6 +75,7 @@ class SfxUInt16Item; class ScPageHFItem; class ScPageScaleToItem; class SvxSetItem; +class ScDatabaseSetting; // EditEngine is not allowed to define its own ITEMID's #define INCLUDED_EDITENG_EEITEMID_HXX @@ -94,8 +95,9 @@ class SvxSetItem; #define SCITEM_PIVOTDATA TypedWhichId<ScPivotItem>(1106) #define SCITEM_SOLVEDATA TypedWhichId<ScSolveItem>(1107) #define SCITEM_USERLIST TypedWhichId<ScUserListItem>(1108) +#define SCITEM_DATABASE_SETTING TypedWhichId<ScDatabaseSetting>(1109) -#define MSGPOOL_END 1108 +#define MSGPOOL_END 1109 // Item-IDs for attributes: diff --git a/sc/inc/shellids.hxx b/sc/inc/shellids.hxx index ecef989d87bb..f8db5abcddc5 100644 --- a/sc/inc/shellids.hxx +++ b/sc/inc/shellids.hxx @@ -40,5 +40,6 @@ #define SCID_PAGEBREAK_SHELL (SFX_INTERFACE_SC_START+SfxInterfaceId(16)) #define SCID_MEDIA_SHELL (SFX_INTERFACE_SC_START+SfxInterfaceId(17)) #define SCID_SPARKLINE_SHELL (SFX_INTERFACE_SC_START+SfxInterfaceId(18)) +#define SCID_TABLE_SHELL (SFX_INTERFACE_SC_START+SfxInterfaceId(19)) /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi index a5f1dd2bb660..58d577c16954 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -6441,6 +6441,23 @@ SfxBoolItem CellProtection SID_SCATTR_CELLPROTECTION GroupId = SfxGroupId::Format; ] +ScDatabaseSettingItem DatabaseSettings SID_DATABASE_SETTINGS + +[ + AutoUpdate = FALSE, + FastCall = TRUE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = FALSE, + MenuConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = SfxGroupId::Table; +] + SfxVoidItem SelectArrayFormula SID_MARKARRAYFORMULA () diff --git a/sc/sdi/scslots.sdi b/sc/sdi/scslots.sdi index f6ccd7113d5b..77b97f36baa7 100644 --- a/sc/sdi/scslots.sdi +++ b/sc/sdi/scslots.sdi @@ -21,6 +21,18 @@ module StarCalc SlotIdFile( "scslots.hrc" ) ] { + struct ScDatabaseSetting + { + BOOL HeaderRow MID_1; + BOOL TotalRow MID_2; + BOOL FirstCol MID_3; + BOOL LastCol MID_4; + BOOL StripedRows MID_5; + BOOL StripedCols MID_6; + BOOL ShowFilters MID_7; + }; + item ScDatabaseSetting ScDatabaseSettingItem; + struct ScProtection { BOOL Locked MID_1; @@ -59,6 +71,7 @@ module StarCalc include "pgbrksh.sdi" include "mediash.sdi" include "SparklineShell.sdi" + include "tableshell.sdi" } diff --git a/sc/sdi/tableshell.sdi b/sc/sdi/tableshell.sdi new file mode 100644 index 000000000000..c3147e933208 --- /dev/null +++ b/sc/sdi/tableshell.sdi @@ -0,0 +1,18 @@ +/* + * 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/. + * + */ + +interface Table +{ + SID_DATABASE_SETTINGS [ ExecMethod = ExecuteDatabaseSettings; StateMethod = GetDatabaseSettings; ] +} + +shell ScTableShell +{ + import Table; +} diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index 026a5e16dcac..30c2d64a1631 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -42,6 +42,187 @@ #include <memory> #include <utility> +using namespace com::sun::star; + +ScDatabaseSettingItem::ScDatabaseSettingItem(): + SfxPoolItem(SCITEM_DATABASE_SETTING), + mbHeaderRow(false), + mbTotalRow(false), + mbFirstCol(false), + mbLastCol(false), + mbStripedRows(false), + mbStripedCols(false), + mbShowFilters(false) +{ +} + +ScDatabaseSettingItem::ScDatabaseSettingItem(bool bHeaderRow, bool bTotalRow, bool bFirstCol, bool bLastCol, bool bStripedRows, bool bStripedCols, bool bShowFilters): + SfxPoolItem(SCITEM_DATABASE_SETTING), + mbHeaderRow(bHeaderRow), + mbTotalRow(bTotalRow), + mbFirstCol(bFirstCol), + mbLastCol(bLastCol), + mbStripedRows(bStripedRows), + mbStripedCols(bStripedCols), + mbShowFilters(bShowFilters) +{ +} + +ScDatabaseSettingItem::ScDatabaseSettingItem(const ScDatabaseSettingItem& rItem): + SfxPoolItem(SCITEM_DATABASE_SETTING), + mbHeaderRow(rItem.mbHeaderRow), + mbTotalRow(rItem.mbTotalRow), + mbFirstCol(rItem.mbFirstCol), + mbLastCol(rItem.mbLastCol), + mbStripedRows(rItem.mbStripedRows), + mbStripedCols(rItem.mbStripedCols), + mbShowFilters(rItem.mbShowFilters) +{ +} + +ScDatabaseSettingItem::~ScDatabaseSettingItem() +{ +} + +bool ScDatabaseSettingItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + switch (nMemberId) + { + case 0: + rVal <<= mbHeaderRow; + break; + case 1: + rVal <<= mbTotalRow; + break; + case 2: + rVal <<= mbFirstCol; + break; + case 3: + rVal <<= mbLastCol; + break; + case 4: + rVal <<= mbStripedRows; + break; + case 5: + rVal <<= mbStripedCols; + break; + case 6: + rVal <<= mbShowFilters; + break; + default: + return false; + } + + return true; +} + +bool ScDatabaseSettingItem::PutValue(const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bVal = false; + + bool bRet = (rVal >>= bVal); + + if(!bRet) + return false; + + switch (nMemberId) + { + case 0: + mbHeaderRow = bVal; + break; + case 1: + mbTotalRow = bVal; + break; + case 2: + mbFirstCol = bVal; + break; + case 3: + mbLastCol = bVal; + break; + case 4: + mbStripedRows = bVal; + break; + case 5: + mbStripedCols = bVal; + break; + case 6: + mbShowFilters = bVal; + break; + default: + return false; + } + + return true; +} + +ScDatabaseSettingItem* ScDatabaseSettingItem::Clone(SfxItemPool* ) const +{ + return new ScDatabaseSettingItem(*this); +} + +SfxPoolItem* ScDatabaseSettingItem::CreateDefault() +{ + return new ScDatabaseSettingItem; +} + +ScDatabaseSettingItem& ScDatabaseSettingItem::operator=(const ScDatabaseSettingItem& rItem) +{ + mbHeaderRow = rItem.mbHeaderRow; + mbTotalRow = rItem.mbTotalRow; + mbFirstCol = rItem.mbFirstCol; + mbLastCol = rItem.mbLastCol; + mbStripedRows = rItem.mbStripedRows; + mbStripedCols = rItem.mbStripedCols; + mbShowFilters = rItem.mbShowFilters; + + return *this; +} + +bool ScDatabaseSettingItem::operator==(const SfxPoolItem& rItem) const +{ + bool bSameBase = SfxPoolItem::operator==(rItem); + if (!bSameBase) + return false; + + const ScDatabaseSettingItem& rDBItem = static_cast<const ScDatabaseSettingItem&>(rItem); + return mbHeaderRow == rDBItem.mbHeaderRow && mbTotalRow == rDBItem.mbTotalRow && mbFirstCol == rDBItem.mbFirstCol && mbLastCol == rDBItem.mbLastCol && mbStripedRows == rDBItem.mbStripedRows && mbStripedCols == rDBItem.mbStripedCols && mbShowFilters == rDBItem.mbShowFilters; +} + +bool ScDatabaseSettingItem::HasHeaderRow() const +{ + return mbHeaderRow; +} + +bool ScDatabaseSettingItem::HasTotalRow() const +{ + return mbTotalRow; +} + +bool ScDatabaseSettingItem::HasFirstCol() const +{ + return mbFirstCol; +} + +bool ScDatabaseSettingItem::HasLastCol() const +{ + return mbLastCol; +} + +bool ScDatabaseSettingItem::HasStripedRows() const +{ + return mbStripedRows; +} + +bool ScDatabaseSettingItem::HasStripedCols() const +{ + return mbStripedCols; +} + +bool ScDatabaseSettingItem::HasShowFilters() const +{ + return mbShowFilters; +} + ScTableStyleParam::ScTableStyleParam(): mbRowStripes(true), mbColumnStripes(false), diff --git a/sc/source/ui/app/msgpool.cxx b/sc/source/ui/app/msgpool.cxx index 4675dc285ea0..00289f3bb6f9 100644 --- a/sc/source/ui/app/msgpool.cxx +++ b/sc/source/ui/app/msgpool.cxx @@ -22,6 +22,7 @@ #include <sc.hrc> #include <docpool.hxx> #include <msgpool.hxx> +#include <dbdata.hxx> static ItemInfoPackage& getItemInfoPackageScMessage() { @@ -38,7 +39,8 @@ static ItemInfoPackage& getItemInfoPackageScMessage() { SCITEM_CONSOLIDATEDATA, new ScConsolidateItem(SCITEM_CONSOLIDATEDATA, nullptr ), SID_CONSOLIDATE, SFX_ITEMINFOFLAG_NONE }, { SCITEM_PIVOTDATA, new ScPivotItem(SCITEM_PIVOTDATA, nullptr, nullptr, false ), SID_PIVOT_TABLE, SFX_ITEMINFOFLAG_NONE }, { SCITEM_SOLVEDATA, new ScSolveItem(SCITEM_SOLVEDATA, nullptr ), SID_SOLVE, SFX_ITEMINFOFLAG_NONE }, - { SCITEM_USERLIST, new ScUserListItem(SCITEM_USERLIST ), SID_SCUSERLISTS, SFX_ITEMINFOFLAG_NONE } + { SCITEM_USERLIST, new ScUserListItem(SCITEM_USERLIST ), SID_SCUSERLISTS, SFX_ITEMINFOFLAG_NONE }, + { SCITEM_DATABASE_SETTING, new ScDatabaseSettingItem(), SID_DATABASE_SETTINGS, SFX_ITEMINFOFLAG_NONE } }}; virtual const ItemInfoStatic& getItemInfoStatic(size_t nIndex) const override { return maItemInfos[nIndex]; } diff --git a/sc/source/ui/app/scdll.cxx b/sc/source/ui/app/scdll.cxx index 24980df11a36..bfd87973c762 100644 --- a/sc/source/ui/app/scdll.cxx +++ b/sc/source/ui/app/scdll.cxx @@ -52,6 +52,7 @@ #include <pgbrksh.hxx> #include <scdll.hxx> #include <SparklineShell.hxx> +#include <tableshell.hxx> #include <appoptio.hxx> #include <searchresults.hxx> @@ -129,6 +130,7 @@ void ScDLL::Init() ScEditShell ::RegisterInterface(pMod); ScPivotShell ::RegisterInterface(pMod); sc::SparklineShell ::RegisterInterface(pMod); + ScTableShell ::RegisterInterface(pMod); ScAuditingShell ::RegisterInterface(pMod); ScFormatShell ::RegisterInterface(pMod); ScCellShell ::RegisterInterface(pMod); diff --git a/sc/source/ui/app/typemap.cxx b/sc/source/ui/app/typemap.cxx index 067d9bf40b99..df9d4d79e98d 100644 --- a/sc/source/ui/app/typemap.cxx +++ b/sc/source/ui/app/typemap.cxx @@ -86,6 +86,7 @@ #include <avmedia/mediaitem.hxx> #include <sfx2/frame.hxx> #include <attrib.hxx> +#include <dbdata.hxx> #include <svx/sdprcitm.hxx> #include <svx/sdmetitm.hxx> #include <svx/pageitem.hxx> diff --git a/sc/source/ui/inc/tableshell.hxx b/sc/source/ui/inc/tableshell.hxx new file mode 100644 index 000000000000..4466d190caf7 --- /dev/null +++ b/sc/source/ui/inc/tableshell.hxx @@ -0,0 +1,42 @@ +/* -*- 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 <sfx2/shell.hxx> + +#include <shellids.hxx> + +class ScTabViewShell; +class SfxModule; +class ScDBData; + +class ScTableShell final : public SfxShell +{ +public: + SFX_DECL_INTERFACE(SCID_TABLE_SHELL) + +private: + /// SfxInterface initializer. + static void InitInterface_Impl(); + const ScDBData* GetDBDataAtCursor(); + +public: + ScTableShell(ScTabViewShell* pView); + virtual ~ScTableShell() override; + + void ExecuteDatabaseSettings(SfxRequest& rReq); + void GetDatabaseSettings(SfxItemSet& rSet); + +private: + ScTabViewShell* m_pViewShell; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx index e80964ec44fa..8975a687d248 100644 --- a/sc/source/ui/inc/tabvwsh.hxx +++ b/sc/source/ui/inc/tabvwsh.hxx @@ -68,8 +68,11 @@ class ScRangeName; class ScDrawTransferObj; class ScCondFormatDlgData; class ScDispatchProviderInterceptor; +class ScTableShell; -namespace sc { class SparklineShell; } +namespace sc { + class SparklineShell; +} struct ScHeaderFieldData; @@ -97,6 +100,7 @@ enum ObjectSelectionType OST_Graphic, OST_Media, OST_Sparkline, + OST_Table, }; class ScFormEditData; @@ -132,6 +136,7 @@ private: std::unique_ptr<ScEditShell> pEditShell; std::unique_ptr<ScPivotShell> pPivotShell; std::unique_ptr<sc::SparklineShell> m_pSparklineShell; + std::unique_ptr<ScTableShell> m_pTableShell; std::unique_ptr<ScAuditingShell> pAuditingShell; std::unique_ptr<ScDrawFormShell> pDrawFormShell; std::unique_ptr<ScCellShell> pCellShell; @@ -336,6 +341,7 @@ public: void SetPivotShell( bool bActive ); void SetSparklineShell(bool bActive); + void SetTableShell(bool bActive); void SetDialogDPObject( std::unique_ptr<ScDPObject> pObj ); const ScDPObject* GetDialogDPObject() const { return pDialogDPObject.get(); } diff --git a/sc/source/ui/sidebar/DatabasePropertyPanel.cxx b/sc/source/ui/sidebar/DatabasePropertyPanel.cxx new file mode 100644 index 000000000000..c2dcc3825124 --- /dev/null +++ b/sc/source/ui/sidebar/DatabasePropertyPanel.cxx @@ -0,0 +1,140 @@ +/* -*- 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 "DatabasePropertyPanel.hxx" +#include <editeng/justifyitem.hxx> +#include <sc.hrc> +#include <attrib.hxx> +#include <scitems.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <svl/intitem.hxx> +#include <svl/itemset.hxx> +#include <svx/rotmodit.hxx> +#include <svtools/unitconv.hxx> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <dbdata.hxx> + +using namespace css; +using namespace css::uno; + +// namespace open + +namespace sc::sidebar +{ +ScDatabasePropertyPanel::ScDatabasePropertyPanel(weld::Widget* pParent, + const css::uno::Reference<css::frame::XFrame>&, + SfxBindings* pBindings) + : PanelLayout(pParent, u"DatabasePropertyPanel"_ustr, + u"modules/scalc/ui/sidebardatabase.ui"_ustr) + , m_xChkHeaderRow(m_xBuilder->weld_check_button(u"chk_header_row"_ustr)) + , m_xChkTotalRow(m_xBuilder->weld_check_button(u"chk_total_row"_ustr)) + , m_xChkFilterButtons(m_xBuilder->weld_check_button(u"chk_filter_buttons"_ustr)) + , m_xChkBandedRows(m_xBuilder->weld_check_button(u"chk_banded_rows"_ustr)) + , m_xChkBandedColumns(m_xBuilder->weld_check_button(u"chk_banded_cols"_ustr)) + , m_xChkFirstColumn(m_xBuilder->weld_check_button(u"chk_first_column"_ustr)) + , m_xChkLastColumn(m_xBuilder->weld_check_button(u"chk_last_column"_ustr)) + , maHeaderRowCtrl(SID_DATABASE_SETTINGS, *pBindings, *this) + , mpBindings(pBindings) +{ + Initialize(); +} + +ScDatabasePropertyPanel::~ScDatabasePropertyPanel() +{ + m_xChkHeaderRow.reset(); + m_xChkTotalRow.reset(); + m_xChkFilterButtons.reset(); + m_xChkBandedRows.reset(); + m_xChkBandedColumns.reset(); + m_xChkFirstColumn.reset(); + m_xChkLastColumn.reset(); + + maHeaderRowCtrl.dispose(); +} + +void ScDatabasePropertyPanel::Initialize() +{ + m_xChkHeaderRow->connect_toggled(LINK(this, ScDatabasePropertyPanel, EntryChanged)); + m_xChkTotalRow->connect_toggled(LINK(this, ScDatabasePropertyPanel, EntryChanged)); + m_xChkFilterButtons->connect_toggled(LINK(this, ScDatabasePropertyPanel, EntryChanged)); + m_xChkBandedRows->connect_toggled(LINK(this, ScDatabasePropertyPanel, EntryChanged)); + m_xChkBandedColumns->connect_toggled(LINK(this, ScDatabasePropertyPanel, EntryChanged)); + m_xChkFirstColumn->connect_toggled(LINK(this, ScDatabasePropertyPanel, EntryChanged)); + m_xChkLastColumn->connect_toggled(LINK(this, ScDatabasePropertyPanel, EntryChanged)); +} + +std::unique_ptr<PanelLayout> +ScDatabasePropertyPanel::Create(weld::Widget* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException( + u"no parent Window given to ScDatabasePropertyPanel::Create"_ustr, nullptr, 0); + if (!rxFrame.is()) + throw lang::IllegalArgumentException( + u"no XFrame given to ScDatabasePropertyPanel::Create"_ustr, nullptr, 1); + if (pBindings == nullptr) + throw lang::IllegalArgumentException( + u"no SfxBindings given to ScDatabasePropertyPanel::Create"_ustr, nullptr, 2); + + return std::make_unique<ScDatabasePropertyPanel>(pParent, rxFrame, pBindings); +} + +void ScDatabasePropertyPanel::HandleContextChange(const vcl::EnumContext& rContext) +{ + if (maContext == rContext) + { + // Nothing to do. + return; + } + + maContext = rContext; +} + +void ScDatabasePropertyPanel::NotifyItemUpdate(sal_uInt16 nSID, SfxItemState eState, + const SfxPoolItem* pState) +{ + switch (nSID) + { + case SID_DATABASE_SETTINGS: + if (eState >= SfxItemState::DEFAULT + && dynamic_cast<const ScDatabaseSettingItem*>(pState)) + { + const ScDatabaseSettingItem* pItem + = static_cast<const ScDatabaseSettingItem*>(pState); + m_xChkHeaderRow->set_active(pItem->HasHeaderRow()); + m_xChkTotalRow->set_active(pItem->HasTotalRow()); + m_xChkFirstColumn->set_active(pItem->HasFirstCol()); + m_xChkLastColumn->set_active(pItem->HasLastCol()); + m_xChkBandedRows->set_active(pItem->HasStripedRows()); + m_xChkBandedColumns->set_active(pItem->HasStripedCols()); + m_xChkFilterButtons->set_active(pItem->HasShowFilters()); + } + break; + } +} + +IMPL_LINK_NOARG(ScDatabasePropertyPanel, EntryChanged, weld::Toggleable&, void) +{ + ScDatabaseSettingItem aItem(m_xChkHeaderRow->get_active(), m_xChkTotalRow->get_active(), + m_xChkFirstColumn->get_active(), m_xChkLastColumn->get_active(), + m_xChkBandedRows->get_active(), m_xChkBandedColumns->get_active(), + m_xChkFilterButtons->get_active()); + GetBindings()->GetDispatcher()->ExecuteList(SID_DATABASE_SETTINGS, SfxCallMode::RECORD, + { &aItem }); +} + +// namespace close + +} // end of namespace ::sc::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/sidebar/DatabasePropertyPanel.hxx b/sc/source/ui/sidebar/DatabasePropertyPanel.hxx new file mode 100644 index 000000000000..d1d6f6e39c99 --- /dev/null +++ b/sc/source/ui/sidebar/DatabasePropertyPanel.hxx @@ -0,0 +1,67 @@ +/* -*- 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 <sfx2/sidebar/ControllerItem.hxx> +#include <sfx2/sidebar/IContextChangeReceiver.hxx> +#include <sfx2/weldutils.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> +#include <vcl/EnumContext.hxx> + +namespace sc::sidebar +{ +class ScDatabasePropertyPanel : public PanelLayout, + public ::sfx2::sidebar::IContextChangeReceiver, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + static std::unique_ptr<PanelLayout> + Create(weld::Widget* pParent, const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual void HandleContextChange(const vcl::EnumContext& rContext) override; + + virtual void NotifyItemUpdate(const sal_uInt16 nSId, const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState(const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override{}; + + SfxBindings* GetBindings() { return mpBindings; } + + // constructor/destructor + ScDatabasePropertyPanel(weld::Widget* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + virtual ~ScDatabasePropertyPanel() override; + +private: + //ui controls + std::unique_ptr<weld::CheckButton> m_xChkHeaderRow; + std::unique_ptr<weld::CheckButton> m_xChkTotalRow; + std::unique_ptr<weld::CheckButton> m_xChkFilterButtons; + std::unique_ptr<weld::CheckButton> m_xChkBandedRows; + std::unique_ptr<weld::CheckButton> m_xChkBandedColumns; + std::unique_ptr<weld::CheckButton> m_xChkFirstColumn; + std::unique_ptr<weld::CheckButton> m_xChkLastColumn; + + ::sfx2::sidebar::ControllerItem maHeaderRowCtrl; + + DECL_LINK(EntryChanged, weld::Toggleable&, void); + + vcl::EnumContext maContext; + SfxBindings* mpBindings; + + void Initialize(); +}; + +} // end of namespace ::sc::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/sidebar/ScPanelFactory.cxx b/sc/source/ui/sidebar/ScPanelFactory.cxx index 37df0fc263ab..c68311106249 100644 --- a/sc/source/ui/sidebar/ScPanelFactory.cxx +++ b/sc/source/ui/sidebar/ScPanelFactory.cxx @@ -22,6 +22,7 @@ #include "AlignmentPropertyPanel.hxx" #include "CellAppearancePropertyPanel.hxx" #include "NumberFormatPropertyPanel.hxx" +#include "DatabasePropertyPanel.hxx" #include <navipi.hxx> #include <dwfunctr.hxx> @@ -94,6 +95,11 @@ Reference<ui::XUIElement> SAL_CALL ScPanelFactory::createUIElement ( xPanel = std::make_unique<ScFunctionWin>(pParent, pBindings); nMinimumSize = 0; } + else if (rsResourceURL.endsWith("/DatabasePropertyPanel")) + { + xPanel = ScDatabasePropertyPanel::Create( pParent, xFrame, pBindings ); + nMinimumSize = 0; + } if (xPanel) xElement = sfx2::sidebar::SidebarPanelBase::Create( diff --git a/sc/source/ui/view/tableshell.cxx b/sc/source/ui/view/tableshell.cxx new file mode 100644 index 000000000000..8fc525e1d5a1 --- /dev/null +++ b/sc/source/ui/view/tableshell.cxx @@ -0,0 +1,128 @@ +/* -*- 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 <scitems.hxx> +#include <sfx2/objface.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/request.hxx> +#include <svl/whiter.hxx> +#include <vcl/EnumContext.hxx> + +#include <sc.hrc> +#include <tableshell.hxx> +#include <tabvwsh.hxx> +#include <docsh.hxx> +#include <document.hxx> +#include <dbdata.hxx> +#include <dbdocfun.hxx> + +#define ShellClass_ScTableShell +#include <scslots.hxx> + +SFX_IMPL_INTERFACE(ScTableShell, SfxShell) + +void ScTableShell::InitInterface_Impl() {} + +ScTableShell::ScTableShell(ScTabViewShell* pViewShell) + : SfxShell(pViewShell) + , m_pViewShell(pViewShell) +{ + SetPool(&m_pViewShell->GetPool()); + ScViewData& rViewData = m_pViewShell->GetViewData(); + SfxUndoManager* pUndoManager = rViewData.GetSfxDocShell()->GetUndoManager(); + SetUndoManager(pUndoManager); + if (!rViewData.GetDocument().IsUndoEnabled()) + { + pUndoManager->SetMaxUndoActionCount(0); + } + SetName("Table"); + SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Table)); +} + +ScTableShell::~ScTableShell() = default; + +const ScDBData* ScTableShell::GetDBDataAtCursor() +{ + ScViewData& rViewData = m_pViewShell->GetViewData(); + const ScAddress aAddr = rViewData.GetCurPos(); + return rViewData.GetDocument().GetDBAtCursor(aAddr.Col(), aAddr.Row(), aAddr.Tab(), + ScDBDataPortion::AREA); +} + +void ScTableShell::ExecuteDatabaseSettings(SfxRequest& rReq) +{ + const SfxItemSet* pSet = rReq.GetArgs(); + sal_uInt16 nSlot = rReq.GetSlot(); + ScViewData& rViewData = m_pViewShell->GetViewData(); + SfxBindings& rBindings = rViewData.GetBindings(); + + switch (nSlot) + { + case SID_DATABASE_SETTINGS: + { + const SfxPoolItem* pItem; + SfxItemState eItemState = pSet->GetItemState(SCITEM_DATABASE_SETTING, true, &pItem); + if (eItemState == SfxItemState::SET + && dynamic_cast<const ScDatabaseSettingItem*>(pItem)) + { + const ScDatabaseSettingItem* pDBItem + = static_cast<const ScDatabaseSettingItem*>(pItem); + const ScDBData* pDBData = GetDBDataAtCursor(); + if (pDBData) + { + ScDBData aNewDBData(*pDBData); + aNewDBData.SetAutoFilter(pDBItem->HasShowFilters()); + aNewDBData.SetHeader(pDBItem->HasHeaderRow()); + aNewDBData.SetTotals(pDBItem->HasTotalRow()); + + ScTableStyleParam aNewParam(*pDBData->GetTableStyleInfo()); + aNewParam.mbRowStripes = pDBItem->HasStripedRows(); + aNewParam.mbColumnStripes = pDBItem->HasStripedCols(); + aNewParam.mbFirstColumn = pDBItem->HasFirstCol(); + aNewParam.mbLastColumn = pDBItem->HasLastCol(); + aNewDBData.SetTableStyleInfo(aNewParam); + + ScDBDocFunc aFunc(*rViewData.GetDocShell()); + aFunc.ModifyDBData(aNewDBData); + } + } + break; + } + } + + rBindings.Invalidate(SID_DATABASE_SETTINGS); +} + +void ScTableShell::GetDatabaseSettings(SfxItemSet& rSet) +{ + SfxWhichIter aIter(rSet); + sal_uInt16 nWhich = aIter.FirstWhich(); + while (nWhich) + { + switch (nWhich) + { + case SCITEM_DATABASE_SETTING: + const ScDBData* pDBData = GetDBDataAtCursor(); + if (pDBData) + { + const ScTableStyleParam* pParam = pDBData->GetTableStyleInfo(); + rSet.Put(ScDatabaseSettingItem(pDBData->HasHeader(), pDBData->HasTotals(), + pParam->mbFirstColumn, pParam->mbLastColumn, + pParam->mbRowStripes, pParam->mbColumnStripes, + pDBData->HasAutoFilter())); + } + break; + } + nWhich = aIter.NextWhich(); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index eb82f2f89077..acfbfb0673f3 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -661,8 +661,14 @@ void ScTabView::CursorPosChanged() if (!bDataPilot) { - bool bSparkline = rDocument.HasSparkline(aViewData.GetCurPos()); + const ScAddress rAddr = aViewData.GetCurPos(); + bool bSparkline = rDocument.HasSparkline(rAddr); aViewData.GetViewShell()->SetSparklineShell(bSparkline); + if (!bSparkline) + { + bool bHasDBTable = rDocument.GetDBAtCursor(rAddr.Col(), rAddr.Row(), rAddr.Tab(), ScDBDataPortion::AREA) != nullptr; + aViewData.GetViewShell()->SetTableShell(bHasDBTable); + } } // UpdateInputHandler now in CellContentChanged diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index d3a46ec9b0bd..eec78f7cdef5 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -47,6 +47,7 @@ #include <editsh.hxx> #include <pivotsh.hxx> #include <SparklineShell.hxx> +#include <tableshell.hxx> #include <auditsh.hxx> #include <drtxtob.hxx> #include <inputhdl.hxx> @@ -754,6 +755,25 @@ void ScTabViewShell::SetSparklineShell(bool bActive) SetCurSubShell(OST_Cell); } +void ScTabViewShell::SetTableShell(bool bActive) +{ + if (eCurOST != OST_Table && eCurOST != OST_Cell) + return; + + if (bActive) + { + bActiveDrawTextSh = bActiveDrawSh = false; + bActiveDrawFormSh=false; + bActiveGraphicSh=false; + bActiveMediaSh=false; + bActiveOleObjectSh=false; + bActiveChartSh=false; + SetCurSubShell(OST_Table); + } + else + SetCurSubShell(OST_Cell); +} + void ScTabViewShell::SetAuditShell( bool bActive ) { if ( bActive ) @@ -1027,6 +1047,20 @@ void ScTabViewShell::SetCurSubShell(ObjectSelectionType eOST, bool bForce) bCellBrush = true; } break; + case OST_Table: + { + AddSubShell(*pCellShell); + if(bPgBrk) AddSubShell(*pPageBreakShell); + + if (!m_pTableShell) + { + m_pTableShell.reset(new ScTableShell(this)); + m_pTableShell->SetRepeatTarget(&aTarget); + } + AddSubShell(*m_pTableShell); + bCellBrush = true; + } + break; default: OSL_FAIL("wrong shell requested"); break; @@ -1075,7 +1109,7 @@ SfxShell* ScTabViewShell::GetMySubShell() const pSub == pPivotShell.get() || pSub == pAuditingShell.get() || pSub == pDrawFormShell.get() || pSub == pCellShell.get() || pSub == pOleObjectShell.get() || pSub == pChartShell.get() || pSub == pGraphicShell.get() || pSub == pMediaShell.get() || pSub == pPageBreakShell.get() || - pSub == m_pSparklineShell.get()) + pSub == m_pSparklineShell.get() || pSub == m_pTableShell.get()) { return pSub; // found } @@ -2229,6 +2263,7 @@ ScTabViewShell::~ScTabViewShell() pEditShell.reset(); pPivotShell.reset(); m_pSparklineShell.reset(); + m_pTableShell.reset(); pAuditingShell.reset(); pCurFrameLine.reset(); mpFormEditData.reset(); diff --git a/sc/uiconfig/scalc/ui/sidebardatabase.ui b/sc/uiconfig/scalc/ui/sidebardatabase.ui new file mode 100644 index 000000000000..52a8c15760a0 --- /dev/null +++ b/sc/uiconfig/scalc/ui/sidebardatabase.ui @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.40.0 --> +<interface domain="sc"> + <requires lib="gtk+" version="3.24"/> + <!-- n-columns=2 n-rows=5 --> + <object class="GtkGrid" id="DatabasePropertyPanel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkCheckButton" id="chk_header_row"> + <property name="label" translatable="yes" context="sidebardatabase|show_header_row_checkbox">Show Header Row</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chk_first_column"> + <property name="label" translatable="yes" context="sidebardatabase|first_column_formatting_checkbox">First Column</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">4</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chk_last_column"> + <property name="label" translatable="yes" context="sidebardatabase|last_column_formatting_checkbox">Last Column</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">4</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chk_banded_cols"> + <property name="label" translatable="yes" context="sidebardatabase|banded_columns_formatting_checkbox">Banded Columns</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">3</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chk_banded_rows"> + <property name="label" translatable="yes" context="sidebardatabase|banded_rows_formatting_checkbox">Banded Rows</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">3</property> + </packing> + </child> + <child> + <object class="GtkSeparator"> + <property name="visible">True</property> + <property name="can-focus">False</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">2</property> + </packing> + </child> + <child> + <object class="GtkSeparator"> + <property name="visible">True</property> + <property name="can-focus">False</property> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">2</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chk_filter_buttons"> + <property name="label" translatable="yes" context="sidebardatabase|show_filter_buttons_checkbox">Show Filter Buttons</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="chk_total_row"> + <property name="label" translatable="yes" context="sidebardatabase|show_total_row_checkbox">Show Total Row</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> +</interface> diff --git a/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx b/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx index 412bc71c480f..4e1022d3c8c9 100644 --- a/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx +++ b/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx @@ -125,6 +125,7 @@ void ParaPropertyPanel::HandleContextChange ( case CombinedEnumContext(Application::Calc, Context::Cell): case CombinedEnumContext(Application::Calc, Context::Pivot): case CombinedEnumContext(Application::Calc, Context::Sparkline): + case CombinedEnumContext(Application::Calc, Context::Table): case CombinedEnumContext(Application::DrawImpress, Context::Text): case CombinedEnumContext(Application::DrawImpress, Context::OutlineText): set_hyphenation_base_visible(false); commit fc38794991dc85de1821c527b3e4cdfc71026a75 Author: Markus Mohrhard <[email protected]> AuthorDate: Tue Jul 29 12:25:53 2025 +0800 Commit: Andras Timar <[email protected]> CommitDate: Mon Nov 17 18:59:17 2025 +0100 add initial version of Calc table styles cherry-pick from: b4fd9f4e5aed28df48427440c4219928f04a6bf4 Add the new UNO props properly. Change-Id: Ib0d3fc7fcf9eb39e2551b426b9c6075ef758010f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193666 Tested-by: Andras Timar <[email protected]> Reviewed-by: Andras Timar <[email protected]> diff --git a/offapi/com/sun/star/sheet/DatabaseRange.idl b/offapi/com/sun/star/sheet/DatabaseRange.idl index 09b452e7463e..c92c6f063dfb 100644 --- a/offapi/com/sun/star/sheet/DatabaseRange.idl +++ b/offapi/com/sun/star/sheet/DatabaseRange.idl @@ -116,6 +116,36 @@ published service DatabaseRange @since LibreOffice 5.0 */ [optional, property] boolean ContainsHeader; + + /** specifies the name of the table style. + + @since LibreOffice 26.2 + */ + [optional, property] string TableStyleName; + + /** specifies that the first and second row colors are different. + + @since LibreOffice 26.2 + */ + [optional, property] boolean UseRowStripes; + + /** specifies that the first and second col colors are different. + + @since LibreOffice 26.2 + */ + [optional, property] boolean UseColStripes; + + /** specifies that the first col has different format or not. + + @since LibreOffice 26.2 + */ + [optional, property] boolean UseFirstColumnFormatting; + + /** specifies that the last col has different format or not. + + @since LibreOffice 26.2 + */ + [optional, property] boolean UseLastColumnFormatting; }; diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index ef939a44c063..4da8fc442536 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -580,6 +580,7 @@ TableBorder TableLayout TableSelected Tables +TableStyleName TableType Tabstop Tag @@ -630,9 +631,13 @@ Type URL UnnamedDatabaseRanges Url +UseColStripes UseFilterCriteriaSource +UseFirstColumnFormatting +UseLastColumnFormatting UseRegularExpressions UseRings +UseRowStripes UseSelectedPage VScroll Validation diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 63636ab4a587..0b374efe5cc6 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -205,6 +205,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/table5 \ sc/source/core/data/table6 \ sc/source/core/data/table7 \ + sc/source/core/data/tablestyle \ sc/source/core/data/tabprotection \ sc/source/core/data/types \ sc/source/core/data/userdat \ diff --git a/sc/Library_scfilt.mk b/sc/Library_scfilt.mk index e4936656676e..b5cc10ea39e2 100644 --- a/sc/Library_scfilt.mk +++ b/sc/Library_scfilt.mk @@ -177,6 +177,7 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\ sc/source/filter/oox/connectionsbuffer \ sc/source/filter/oox/connectionsfragment \ sc/source/filter/oox/defnamesbuffer \ + sc/source/filter/oox/defaulttablestyles \ sc/source/filter/oox/drawingbase \ sc/source/filter/oox/drawingfragment \ sc/source/filter/oox/excelchartconverter \ diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx index 868c3c23f506..8a4270912913 100644 --- a/sc/inc/dbdata.hxx +++ b/sc/inc/dbdata.hxx @@ -85,6 +85,20 @@ protected: ScRangeList maDirtyTableColumnNames; }; + +struct SAL_DLLPUBLIC ScTableStyleParam +{ + OUString maStyleName; + bool mbRowStripes; + bool mbColumnStripes; + bool mbFirstColumn; + bool mbLastColumn; + + ScTableStyleParam(); + + bool operator== (const ScTableStyleParam& rData) const; +}; + class SAL_DLLPUBLIC_RTTI ScDBData final : public SvtListener, public ScRefreshTimer { private: @@ -92,6 +106,7 @@ private: std::unique_ptr<ScQueryParam> mpQueryParam; std::unique_ptr<ScSubTotalParam> mpSubTotal; std::unique_ptr<ScImportParam> mpImportParam; + std::unique_ptr<ScTableStyleParam> mpTableStyles; ScDBDataContainerBase* mpContainer; @@ -257,6 +272,9 @@ public: void CalcSaveFilteredCount(SCSIZE nNonFilteredRowCount); void GetFilterSelCount(SCSIZE& nSelected, SCSIZE& nTotal); + void SetTableStyleInfo(const ScTableStyleParam& rParams); + const ScTableStyleParam* GetTableStyleInfo() const; + private: void AdjustTableColumnAttributes( UpdateRefMode eUpdateRefMode, SCCOL nDx, SCCOL nCol1, @@ -366,6 +384,7 @@ public: SC_DLLPUBLIC ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); SC_DLLPUBLIC ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab ); SC_DLLPUBLIC std::vector<ScDBData*> GetAllDBsFromTab(SCTAB nTab); + std::vector<const ScDBData*> GetAllDBsInArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab) const; void RefreshDirtyTableColumnNames(); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index c487a5f81216..436a8b3cb113 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -226,6 +226,7 @@ typedef o3tl::sorted_vector<sal_uInt32> ScCondFormatIndexes; struct ScSheetLimits; struct ScDataAreaExtras; enum class ScConditionMode; +class ScTableStyles; namespace sc { @@ -452,6 +453,7 @@ private: std::unique_ptr<ScExternalRefManager> pExternalRefMgr; std::unique_ptr<ScMacroManager> mpMacroMgr; + std::unique_ptr<ScTableStyles> mpTableStyles; // mutable for lazy construction mutable std::unique_ptr< ScFormulaParserPool > @@ -2771,6 +2773,9 @@ public: bool SetLOKFreezeCol(SCCOL nFreezeCol, SCTAB nTab); bool SetLOKFreezeRow(SCROW nFreezeRow, SCTAB nTab); + SC_DLLPUBLIC ScTableStyles& GetTableStyles(); + SC_DLLPUBLIC const ScTableStyles& GetTableStyles() const; + private: /** diff --git a/sc/inc/tablestyle.hxx b/sc/inc/tablestyle.hxx new file mode 100644 index 000000000000..87d05c623190 --- /dev/null +++ b/sc/inc/tablestyle.hxx @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 <memory> + +#include "document.hxx" +#include "scdllapi.h" +#include "dbdata.hxx" + +class ScPatternAttr; + +enum class ScTableStyleElement +{ + WholeTable, + FirstColumnStripe, + SecondColumnStripe, + FirstRowStripe, + SecondRowStripe, + LastColumn, + FirstColumn, + HeaderRow, + TotalRow, + FirstHeaderCell, + LastHeaderCell, +}; + +class SC_DLLPUBLIC ScTableStyle +{ +private: + std::unique_ptr<ScPatternAttr> mpTablePattern; + std::unique_ptr<ScPatternAttr> mpFirstColumnStripePattern; + std::unique_ptr<ScPatternAttr> mpSecondColumnStripePattern; + std::unique_ptr<ScPatternAttr> mpFirstRowStripePattern; + std::unique_ptr<ScPatternAttr> mpSecondRowStripePattern; + std::unique_ptr<ScPatternAttr> mpLastColumnPattern; + std::unique_ptr<ScPatternAttr> mpFirstColumnPattern; + std::unique_ptr<ScPatternAttr> mpHeaderRowPattern; + std::unique_ptr<ScPatternAttr> mpTotalRowPattern; + std::unique_ptr<ScPatternAttr> mpFirstHeaderCellPattern; + std::unique_ptr<ScPatternAttr> mpLastHeaderCellPattern; + + sal_Int32 mnFirstRowStripeSize; + sal_Int32 mnSecondRowStripeSize; + sal_Int32 mnFirstColStripeSize; + sal_Int32 mnSecondColStripeSize; + + OUString maStyleName; + std::optional<OUString> maUIName; + bool mbIsOOXMLDefault; + +public: + ScTableStyle(const OUString& rName, const std::optional<OUString>& rUIName); + + const ScPatternAttr* GetPattern(const ScDBData& rDBData, SCCOL nCol, SCROW nRow, + SCROW nRowIndex) const; + + void SetRowStripeSize(sal_Int32 nFirstRowStripeSize, sal_Int32 nSecondRowStripeSize); + void SetColStripeSize(sal_Int32 nFirstColStripeSize, sal_Int32 nSecondColStripeSize); + + void SetPattern(ScTableStyleElement eTableStyleElement, + std::unique_ptr<ScPatternAttr> pPattern); + void SetTablePattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetFirstColumnStripePattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetSecondColumnStripePattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetFirstRowStripePattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetSecondRowStripePattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetLastColumnPattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetFirstColumnPattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetHeaderRowPattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetTotalRowPattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetFirstHeaderCellPattern(std::unique_ptr<ScPatternAttr> pPattern); + void SetLastHeaderCellPattern(std::unique_ptr<ScPatternAttr> pPattern); + + std::map<ScTableStyleElement, const ScPatternAttr*> GetSetPatterns() const; + + sal_Int32 GetFirstRowStripeSize() const; + sal_Int32 GetFirstColumnStripeSize() const; + sal_Int32 GetSecondRowStripeSize() const; + sal_Int32 GetSecondColumnStripeSize() const; + + void SetOOXMLDefault(bool bDefault); + bool IsOOXMLDefault() const; + + const OUString& GetName() const; + const OUString& GetUIName() const; +}; + +class SC_DLLPUBLIC ScTableStyles +{ +private: + std::unordered_map<OUString, std::unique_ptr<ScTableStyle>> maTableStyles; + +public: + ScTableStyles(); + + void AddTableStyle(std::unique_ptr<ScTableStyle> pTableStyle); + void DeleteTableStyle(const OUString& rName); + const ScTableStyle* GetTableStyle(const OUString& rName) const; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx index a1dd70ad3892..7e6b1e63bec1 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -330,6 +330,11 @@ inline constexpr OUString SC_UNONAME_TOKENINDEX = u"TokenIndex"_ustr; inline constexpr OUString SC_UNONAME_ISSHAREDFMLA = u"IsSharedFormula"_ustr; inline constexpr OUString SC_UNONAME_TOTALSROW = u"TotalsRow"_ustr; inline constexpr OUString SC_UNONAME_TABLETYPE = u"TableType"_ustr; +inline constexpr OUString SC_UNONAME_TABLE_STYLENAME = u"TableStyleName"_ustr; +inline constexpr OUString SC_UNONAME_ROW_STRIPES = u"UseRowStripes"_ustr; +inline constexpr OUString SC_UNONAME_COL_STRIPES = u"UseColStripes"_ustr; +inline constexpr OUString SC_UNONAME_FIRST_COL = u"UseFirstColumnFormatting"_ustr; +inline constexpr OUString SC_UNONAME_LAST_COL = u"UseLastColumnFormatting"_ustr; // text fields inline constexpr OUString SC_UNONAME_ANCTYPE = u"AnchorType"_ustr; diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index a49a93568e8c..00f7448a11ca 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -91,6 +91,7 @@ #include <sharedstringpoolpurge.hxx> #include <docpool.hxx> #include <config_features.h> +#include <tablestyle.hxx> using namespace com::sun::star; @@ -140,6 +141,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, ScDocShell* pDocShell ) : pEOFormulaTree( nullptr ), pFormulaTrack( nullptr ), pEOFormulaTrack( nullptr ), + mpTableStyles(new ScTableStyles), pPreviewCellStyle( nullptr ), maPreviewSelection(*mxSheetLimits), nUnoObjectId( 0 ), @@ -394,6 +396,7 @@ ScDocument::~ScDocument() pUnoRefUndoList.reset(); pUnoListenerCalls.reset(); + mpTableStyles.reset(); Clear( true ); // true = from destructor (needed for SdrModel::ClearModel) @@ -1527,4 +1530,14 @@ sc::IconSetBitmapMap& ScDocument::GetIconSetBitmapMap() return *m_pIconSetBitmapMap; } +ScTableStyles& ScDocument::GetTableStyles() +{ + return *mpTableStyles; +} + +const ScTableStyles& ScDocument::GetTableStyles() const +{ + return *mpTableStyles; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx index 34da5ff9c10e..9a594352be0a 100644 --- a/sc/source/core/data/fillinfo.cxx +++ b/sc/source/core/data/fillinfo.cxx @@ -40,6 +40,8 @@ #include <stlpool.hxx> #include <cellvalue.hxx> #include <mtvcellfunc.hxx> +#include <dbdata.hxx> +#include <tablestyle.hxx> #include <algorithm> #include <limits> @@ -185,7 +187,7 @@ public: }; void initRowInfo(const ScDocument* pDoc, RowInfo* pRowInfo, const SCSIZE nMaxRow, - double fRowScale, SCROW nRow1, SCTAB nTab, SCROW& rYExtra, SCSIZE& rArrRow, SCROW& rRow2) + double fRowScale, SCROW nRow1, SCTAB nTab, SCROW& rYExtra, SCSIZE& rArrRow, SCROW& rRow2, std::unordered_map<SCROW, SCROW>& rRowLookup) { sal_uInt16 nDocHeight = pDoc->GetSheetOptimalMinRowHeight(nTab); SCROW nDocHeightEndRow = -1; @@ -214,6 +216,7 @@ void initRowInfo(const ScDocument* pDoc, RowInfo* pRowInfo, const SCSIZE nMaxRow std::clamp( nDocHeight * fRowScale, 1.0, double(std::numeric_limits<sal_uInt16>::max()))); + rRowLookup.insert({nY, rArrRow}); pThisRowInfo->nRowNo = nY; //TODO: case < 0 ? pThisRowInfo->nHeight = nHeight; pThisRowInfo->bEmptyBack = true; @@ -370,13 +373,14 @@ void ScDocument::FillInfo( bool bAnyPreview = false; bool bTabProtect = IsTabProtected(nTab); + std::unordered_map<SCROW, SCROW> aRowLookup; // first only the entries for the entire column nArrRow=0; SCROW nYExtra = nRow2+1; initRowInfo(this, pRowInfo, rTabInfo.mnArrCapacity, fRowScale, nRow1, - nTab, nYExtra, nArrRow, nRow2); + nTab, nYExtra, nArrRow, nRow2, aRowLookup); nArrCount = nArrRow; // incl. Dummys // Rotated text... @@ -406,6 +410,64 @@ void ScDocument::FillInfo( if (pCondFormList) pCondFormList->startRendering(); + ScRange aTargetRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab); + std::vector<const ScDBData*> aDBData = pDBCollection->GetAllDBsInArea(nCol1, nRow1, nCol2, nRow2, nTab); + for (const ScDBData* pDBData : aDBData) + { + const ScTableStyleParam* pTableStyleInfo = pDBData->GetTableStyleInfo(); + if (!pTableStyleInfo) + continue; + + ScRange aDBRange; + pDBData->GetArea(aDBRange); + ScRange aIntersectionRange = aDBRange.Intersection(aTargetRange); + const ScTableStyle* pTableStyle = mpTableStyles->GetTableStyle(pTableStyleInfo->maStyleName); + if (!pTableStyle) + continue; + + SCROW nNonEmptyRowsBeforePaintRange = -static_cast<SCROW>(pDBData->HasHeader()); + if (aDBRange.aStart.Row() < aIntersectionRange.aStart.Row()) + { + nNonEmptyRowsBeforePaintRange += this->CountNonFilteredRows(aDBRange.aStart.Row(), aIntersectionRange.aStart.Row() - 1, nTab); + } + SCROW nRowIndex = nNonEmptyRowsBeforePaintRange; + for (SCROW nRow = aIntersectionRange.aStart.Row(); nRow <= aIntersectionRange.aEnd.Row(); ++nRow) + { + auto itrRow = aRowLookup.find(nRow); + if (itrRow == aRowLookup.end()) + continue; + + RowInfo* pThisRowInfo = &pRowInfo[itrRow->second]; + for (SCCOL nCol = aIntersectionRange.aStart.Col(); nCol <= aIntersectionRange.aEnd.Col(); ++nCol) + { + if (!ValidCol(nCol)) + continue; + + ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nCol); + + const ScPatternAttr* pPattern = pTableStyle->GetPattern(*pDBData, nCol, nRow, nRowIndex); + if (!pPattern) + continue; + + const SfxItemSet& rItemSet = pPattern->GetItemSet(); + const SvxBrushItem* pBackground = rItemSet.GetItemIfSet(ATTR_BACKGROUND); + if (pBackground) + { + pInfo->maBackground = SfxPoolItemHolder(*pPool, pBackground); + pThisRowInfo->bEmptyBack = false; + } + + const SvxBoxItem* pLinesAttr = rItemSet.GetItemIfSet(ATTR_BORDER); + if (pLinesAttr) + { + pInfo->pLinesAttr = pLinesAttr; + } + } + + ++nRowIndex; + } + } + SCCOL nLastHiddenCheckedCol = -2; bool bColHidden = false; for (SCCOL nCol=-1; nCol<=nCol2+1; nCol++) // collect basic info also for all previous cols, and left & right + 1 @@ -474,7 +536,9 @@ void ScDocument::FillInfo( } const SvxBrushItem* pBackground = &pPattern->GetItem(ATTR_BACKGROUND); + const SvxBrushItem* pExplicitBackground = pPattern->GetItemSet().GetItemIfSet(ATTR_BACKGROUND); const SvxBoxItem* pLinesAttr = &pPattern->GetItem(ATTR_BORDER); + const SvxBoxItem* pExplicitLinesAttr = pPattern->GetItemSet().GetItemIfSet(ATTR_BORDER); const SvxLineItem* pTLBRLine = &pPattern->GetItem( ATTR_BORDER_TLBR ); const SvxLineItem* pBLTRLine = &pPattern->GetItem( ATTR_BORDER_BLTR ); @@ -535,7 +599,17 @@ void ScDocument::FillInfo( ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nCol); ScBasicCellInfo* pBasicInfo = &pThisRowInfo->basicCellInfo(nCol); - pInfo->maBackground = SfxPoolItemHolder(*pPool, pBackground); + if (pInfo->maBackground) + { + if (pExplicitBackground) + { + pInfo->maBackground = SfxPoolItemHolder(*pPool, pExplicitBackground); + } + } + else + { + pInfo->maBackground = SfxPoolItemHolder(*pPool, pBackground); + } pInfo->pPatternAttr = pPattern; pInfo->bMerged = bMerged; pInfo->bHOverlapped = bHOverlapped; @@ -547,7 +621,17 @@ void ScDocument::FillInfo( pInfo->bPivotExpandButton = bPivotExpandButton; pInfo->bPivotPopupButtonMulti = bPivotPopupButtonMulti; pInfo->bFilterActive = bFilterActive; - pInfo->pLinesAttr = pLinesAttr; + if (pInfo->pLinesAttr) + { + if (pExplicitBackground) + { + pInfo->pLinesAttr = pExplicitLinesAttr; + } + } + else + { + pInfo->pLinesAttr = pLinesAttr; + } pInfo->mpTLBRLine = pTLBRLine; pInfo->mpBLTRLine = pBLTRLine; pInfo->pShadowAttr = pShadowAttr; diff --git a/sc/source/core/data/tablestyle.cxx b/sc/source/core/data/tablestyle.cxx new file mode 100644 index 000000000000..c337032fb7c7 --- /dev/null +++ b/sc/source/core/data/tablestyle.cxx @@ -0,0 +1,313 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 <tablestyle.hxx> + +ScTableStyle::ScTableStyle(const OUString& rName, const std::optional<OUString>& rUIName) + : mnFirstRowStripeSize(1) + , mnSecondRowStripeSize(1) + , mnFirstColStripeSize(1) + , mnSecondColStripeSize(1) + , maStyleName(rName) + , maUIName(rUIName) + , mbIsOOXMLDefault(false) +{ +} + +const ScPatternAttr* ScTableStyle::GetPattern(const ScDBData& rDBData, SCCOL nCol, SCROW nRow, + SCROW nRowIndex) const +{ + const ScTableStyleParam* pParam = rDBData.GetTableStyleInfo(); + ScRange aRange; + rDBData.GetArea(aRange); + + bool bHasHeader = rDBData.HasHeader(); + bool bHasTotal = rDBData.HasTotals(); + if (bHasHeader && mpLastHeaderCellPattern && nRow == aRange.aStart.Row() + && nCol == aRange.aEnd.Col()) + { + return mpLastHeaderCellPattern.get(); + } + + if (bHasHeader && mpFirstHeaderCellPattern && nRow == aRange.aStart.Row() + && nCol == aRange.aStart.Col()) + { + return mpFirstHeaderCellPattern.get(); + } + + if (bHasTotal && mpTotalRowPattern && nRow == aRange.aEnd.Row()) + { + return mpTotalRowPattern.get(); + } + + if (bHasHeader && mpHeaderRowPattern && nRow == aRange.aStart.Row()) + { + return mpHeaderRowPattern.get(); + } + + if (pParam->mbFirstColumn && mpFirstColumnPattern && nCol == aRange.aStart.Col()) + { + return mpFirstColumnPattern.get(); + } + + if (pParam->mbLastColumn && mpLastColumnPattern && nCol == aRange.aEnd.Col()) + { + return mpLastColumnPattern.get(); + } + + if (pParam->mbRowStripes && nRowIndex >= 0) + { + sal_Int32 nTotalRowStripPattern = mnFirstRowStripeSize + mnSecondRowStripeSize; + bool bFirstRowStripe = (nRowIndex % nTotalRowStripPattern) < mnFirstRowStripeSize; + if (mpSecondRowStripePattern && !bFirstRowStripe) + { + return mpSecondRowStripePattern.get(); + } + + if (mpFirstRowStripePattern && bFirstRowStripe) + { + return mpFirstRowStripePattern.get(); + } + } + + if (pParam->mbColumnStripes) + { + SCCOL nRelativeCol = nCol - aRange.aStart.Col(); + sal_Int32 nTotalColStripePattern = mnFirstColStripeSize + mnSecondColStripeSize; + bool bFirstColStripe = (nRelativeCol % nTotalColStripePattern) < mnFirstColStripeSize; + if (mpSecondColumnStripePattern && !bFirstColStripe) + { + return mpSecondColumnStripePattern.get(); + } + + if (mpFirstColumnStripePattern && bFirstColStripe) + { + return mpFirstColumnStripePattern.get(); + } + } + + return mpTablePattern.get(); +} + +void ScTableStyle::SetRowStripeSize(sal_Int32 nFirstRowStripeSize, sal_Int32 nSecondRowStripeSize) +{ + if (nFirstRowStripeSize >= 1) + mnFirstRowStripeSize = nFirstRowStripeSize; + + if (nSecondRowStripeSize >= 1) + mnSecondRowStripeSize = nSecondRowStripeSize; +} + +void ScTableStyle::SetColStripeSize(sal_Int32 nFirstColStripeSize, sal_Int32 nSecondColStripeSize) +{ + if (nFirstColStripeSize >= 1) + mnFirstColStripeSize = nFirstColStripeSize; + + if (nSecondColStripeSize >= 1) + mnSecondColStripeSize = nSecondColStripeSize; +} + +void ScTableStyle::SetOOXMLDefault(bool bDefault) { mbIsOOXMLDefault = bDefault; } + +bool ScTableStyle::IsOOXMLDefault() const { return mbIsOOXMLDefault; } + +const OUString& ScTableStyle::GetName() const { return maStyleName; } + +const OUString& ScTableStyle::GetUIName() const +{ + if (maUIName) + return *maUIName; + + return maStyleName; +} + +void ScTableStyle::SetPattern(ScTableStyleElement eTableStyleElement, + std::unique_ptr<ScPatternAttr> pPattern) +{ + switch (eTableStyleElement) + { + case ScTableStyleElement::WholeTable: + mpTablePattern = std::move(pPattern); + break; + case ScTableStyleElement::FirstColumnStripe: + mpFirstColumnStripePattern = std::move(pPattern); + break; + case ScTableStyleElement::SecondColumnStripe: + mpSecondColumnStripePattern = std::move(pPattern); + break; + case ScTableStyleElement::FirstRowStripe: + mpFirstRowStripePattern = std::move(pPattern); + break; + case ScTableStyleElement::SecondRowStripe: + mpSecondRowStripePattern = std::move(pPattern); + break; + case ScTableStyleElement::LastColumn: + mpLastColumnPattern = std::move(pPattern); + break; + case ScTableStyleElement::FirstColumn: + mpFirstColumnPattern = std::move(pPattern); + break; + case ScTableStyleElement::HeaderRow: + mpHeaderRowPattern = std::move(pPattern); + break; + case ScTableStyleElement::TotalRow: + mpTotalRowPattern = std::move(pPattern); + break; + case ScTableStyleElement::FirstHeaderCell: + mpFirstHeaderCellPattern = std::move(pPattern); + break; + case ScTableStyleElement::LastHeaderCell: + mpLastHeaderCellPattern = std::move(pPattern); + break; + } +} + +void ScTableStyle::SetTablePattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpTablePattern = std::move(pPattern); +} + +void ScTableStyle::SetFirstColumnStripePattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpFirstColumnStripePattern = std::move(pPattern); +} + +void ScTableStyle::SetSecondColumnStripePattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpSecondColumnStripePattern = std::move(pPattern); +} + +void ScTableStyle::SetFirstRowStripePattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpFirstRowStripePattern = std::move(pPattern); +} + +void ScTableStyle::SetSecondRowStripePattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpSecondRowStripePattern = std::move(pPattern); +} + +void ScTableStyle::SetLastColumnPattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpLastColumnPattern = std::move(pPattern); +} + +void ScTableStyle::SetFirstColumnPattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpFirstColumnPattern = std::move(pPattern); +} + +void ScTableStyle::SetHeaderRowPattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpHeaderRowPattern = std::move(pPattern); +} + +void ScTableStyle::SetTotalRowPattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpTotalRowPattern = std::move(pPattern); +} + +void ScTableStyle::SetFirstHeaderCellPattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpFirstHeaderCellPattern = std::move(pPattern); +} + +void ScTableStyle::SetLastHeaderCellPattern(std::unique_ptr<ScPatternAttr> pPattern) +{ + mpLastHeaderCellPattern = std::move(pPattern); +} + +std::map<ScTableStyleElement, const ScPatternAttr*> ScTableStyle::GetSetPatterns() const +{ + std::map<ScTableStyleElement, const ScPatternAttr*> aPatterns; + if (mpTablePattern) + { + aPatterns.emplace(ScTableStyleElement::WholeTable, mpTablePattern.get()); + } + + if (mpFirstColumnStripePattern) + { + aPatterns.emplace(ScTableStyleElement::FirstColumnStripe, mpFirstColumnStripePattern.get()); + } + + if (mpSecondColumnStripePattern) + { + aPatterns.emplace(ScTableStyleElement::SecondColumnStripe, + mpSecondColumnStripePattern.get()); + } + + if (mpFirstRowStripePattern) + { + aPatterns.emplace(ScTableStyleElement::FirstRowStripe, mpFirstRowStripePattern.get()); + } + + if (mpSecondRowStripePattern) + { + aPatterns.emplace(ScTableStyleElement::SecondRowStripe, mpSecondRowStripePattern.get()); + } + + if (mpLastColumnPattern) + { + aPatterns.emplace(ScTableStyleElement::LastColumn, mpLastColumnPattern.get()); + } + + if (mpFirstColumnPattern) + { + aPatterns.emplace(ScTableStyleElement::FirstColumn, mpFirstColumnPattern.get()); + } + + if (mpHeaderRowPattern) + { + aPatterns.emplace(ScTableStyleElement::HeaderRow, mpHeaderRowPattern.get()); + } + + if (mpTotalRowPattern) + { + aPatterns.emplace(ScTableStyleElement::TotalRow, mpTotalRowPattern.get()); + } + + if (mpFirstHeaderCellPattern) + { + aPatterns.emplace(ScTableStyleElement::FirstHeaderCell, mpFirstHeaderCellPattern.get()); + } + + if (mpLastHeaderCellPattern) + { + aPatterns.emplace(ScTableStyleElement::LastHeaderCell, mpLastHeaderCellPattern.get()); + } + + return aPatterns; +} + +sal_Int32 ScTableStyle::GetFirstRowStripeSize() const { return mnFirstRowStripeSize; } + +sal_Int32 ScTableStyle::GetSecondRowStripeSize() const { return mnSecondRowStripeSize; } + +sal_Int32 ScTableStyle::GetFirstColumnStripeSize() const { return mnFirstColStripeSize; } + +sal_Int32 ScTableStyle::GetSecondColumnStripeSize() const { return mnSecondColStripeSize; } + +ScTableStyles::ScTableStyles() {} + +void ScTableStyles::AddTableStyle(std::unique_ptr<ScTableStyle> pTableStyle) +{ + maTableStyles.insert({ pTableStyle->GetName(), std::move(pTableStyle) }); +} + +void ScTableStyles::DeleteTableStyle(const OUString& rName) { maTableStyles.erase(rName); } + +const ScTableStyle* ScTableStyles::GetTableStyle(const OUString& rName) const +{ + if (maTableStyles.find(rName) == maTableStyles.end()) + return nullptr; + + return maTableStyles.find(rName)->second.get(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index 7992d10e916f..026a5e16dcac 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -42,6 +42,34 @@ #include <memory> #include <utility> +ScTableStyleParam::ScTableStyleParam(): + mbRowStripes(true), + mbColumnStripes(false), + mbFirstColumn(false), + mbLastColumn(false) +{ +} + +bool ScTableStyleParam::operator==(const ScTableStyleParam& rParam) const +{ + if(maStyleName != rParam.maStyleName) + return false; + + if (mbRowStripes != rParam.mbRowStripes) + return false; + + if (mbColumnStripes != rParam.mbColumnStripes) + return false; + + if (mbFirstColumn != rParam.mbFirstColumn) + return false; + + if (mbLastColumn != rParam.mbLastColumn) + return false; + + return true; +} + bool ScDBData::less::operator() (const std::unique_ptr<ScDBData>& left, const std::unique_ptr<ScDBData>& right) const { return ScGlobal::GetTransliteration().compareString(left->GetUpperName(), right->GetUpperName()) < 0; @@ -116,6 +144,8 @@ ScDBData::ScDBData( const ScDBData& rData ) : mbTableColumnNamesDirty(rData.mbTableColumnNamesDirty), nFilteredRowCount (rData.nFilteredRowCount) { + if (rData.mpTableStyles) + mpTableStyles.reset(new ScTableStyleParam(*rData.mpTableStyles)); } ScDBData::ScDBData( const OUString& rName, const ScDBData& rData ) : @@ -153,6 +183,8 @@ ScDBData::ScDBData( const OUString& rName, const ScDBData& rData ) : nFilteredRowCount (rData.nFilteredRowCount) { aUpper = ScGlobal::getCharClass().uppercase(aUpper); + if (rData.mpTableStyles) + mpTableStyles.reset(new ScTableStyleParam(*rData.mpTableStyles)); } ScDBData& ScDBData::operator= (const ScDBData& rData) @@ -193,6 +225,11 @@ ScDBData& ScDBData::operator= (const ScDBData& rData) nIndex = rData.nIndex; bAutoFilter = rData.bAutoFilter; nFilteredRowCount = rData.nFilteredRowCount; + if (rData.mpTableStyles) + mpTableStyles.reset(new ScTableStyleParam(*rData.mpTableStyles)); + else + mpTableStyles.reset(); + if (bHeaderRangeDiffers) InvalidateTableColumnNames( true); @@ -245,6 +282,12 @@ bool ScDBData::operator== (const ScDBData& rData) const if (!(aSubTotal1 == aSubTotal2)) return false; + if ((mpTableStyles && !rData.mpTableStyles ) || (!mpTableStyles && rData.mpTableStyles)) + return false; + + if (mpTableStyles && ((*mpTableStyles) != (*rData.mpTableStyles))) + return false; + ScImportParam aImport1, aImport2; GetImportParam(aImport1); rData.GetImportParam(aImport2); @@ -1004,6 +1047,16 @@ void ScDBData::GetFilterSelCount( SCSIZE& nSelected, SCSIZE& nTotal ) nSelected = nFilteredRowCount; } +void ScDBData::SetTableStyleInfo(const ScTableStyleParam& rParam) +{ + mpTableStyles.reset(new ScTableStyleParam(rParam)); +} + +const ScTableStyleParam* ScDBData::GetTableStyleInfo() const +{ + return mpTableStyles.get(); +} + namespace { class FindByTable @@ -1501,6 +1554,39 @@ ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCO return nullptr; } +namespace { + +bool intersectsRange(const ScDBData* pDBData, ScRange& rRange) +{ + ScRange aRange; + pDBData->GetArea(aRange); + return rRange.Intersects(aRange); +} + +} + +std::vector<const ScDBData*> ScDBCollection::GetAllDBsInArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab) const +{ + ScRange aTargetRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab); + std::vector<const ScDBData*> aDBData; + for (const auto& rxNamedDB: maNamedDBs) + { + if (rxNamedDB->GetTab() != nTab) + continue; + + if (intersectsRange(rxNamedDB.get(), aTargetRange)) + { + aDBData.emplace_back(rxNamedDB.get()); + } + } + const ScDBData* pAnonDBData = rDoc.GetAnonymousDBData(nTab); + if (pAnonDBData && intersectsRange(pAnonDBData, aTargetRange)) + { + aDBData.emplace_back(pAnonDBData); + } + return aDBData; +} + void ScDBCollection::RefreshDirtyTableColumnNames() { for (size_t i=0; i < maNamedDBs.maDirtyTableColumnNames.size(); ++i) diff --git a/sc/source/filter/excel/xedbdata.cxx b/sc/source/filter/excel/xedbdata.cxx index 6b67bc28b836..dd37b4030b38 100644 --- a/sc/source/filter/excel/xedbdata.cxx +++ b/sc/source/filter/excel/xedbdata.cxx @@ -11,6 +11,7 @@ #include <excrecds.hxx> #include <dbdata.hxx> #include <document.hxx> +#include <tablestyle.hxx> #include <oox/export/utils.hxx> #include <oox/token/namespaces.hxx> #include <sax/fastattribs.hxx> @@ -294,7 +295,15 @@ void XclExpTables::SaveTableXml( XclExpXmlStream& rStrm, const Entry& rEntry ) pTableStrm->endElement( XML_tableColumns); } - // OOXTODO: write <tableStyleInfo> once we have table styles. + if (const ScTableStyleParam* pParam = rData.GetTableStyleInfo()) + { + const OUString& rStyleName = pParam->maStyleName; + const ScTableStyle* pTableStyle = rStrm.GetRoot().GetDoc().GetTableStyles().GetTableStyle(rStyleName); + if (pTableStyle) + { + pTableStrm->singleElement( XML_tableStyleInfo, XML_name, rStyleName.toUtf8(), XML_showFirstColumn, ToPsz10(pParam->mbFirstColumn), XML_showLastColumn, ToPsz10(pParam->mbLastColumn), XML_showRowStripes, ToPsz10(pParam->mbRowStripes), XML_showColumnStripes, ToPsz10(pParam->mbColumnStripes)); + } + } pTableStrm->endElement( XML_table); } diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx index ede76264ca05..2aa51073ed90 100644 --- a/sc/source/filter/excel/xeroot.cxx +++ b/sc/source/filter/excel/xeroot.cxx @@ -221,6 +221,7 @@ void XclExpRoot::InitializeGlobals() { mrExpData.mxXmlPTableMgr = std::make_shared<XclExpXmlPivotTableManager>(GetRoot()); mrExpData.mxTablesMgr = std::make_shared<XclExpTablesManager>(GetRoot()); + mrExpData.mxTableStyles = new XclExpXmlTableStyles( GetRoot() ); do { @@ -293,6 +294,7 @@ XclExpRecordRef XclExpRoot::CreateRecord( sal_uInt16 nRecId ) const case EXC_ID_EXTERNSHEET: xRec = GetLocalLinkMgrRef(); break; case EXC_ID_NAME: xRec = mrExpData.mxNameMgr; break; case EXC_ID_DXFS: xRec = mrExpData.mxDxfs; break; + case EXC_ID_TABLESTYLES: xRec = mrExpData.mxTableStyles; break; } OSL_ENSURE( xRec, "XclExpRoot::CreateRecord - unknown record ID or missing object" ); return xRec; diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx index c8adf2b9c3ab..9f92e224868e 100644 --- a/sc/source/filter/excel/xestyle.cxx +++ b/sc/source/filter/excel/xestyle.cxx @@ -48,6 +48,7 @@ #include <xltools.hxx> #include <conditio.hxx> #include <dbdata.hxx> +#include <tablestyle.hxx> #include <filterentries.hxx> #include <export/ExportTools.hxx> #include <dpobject.hxx> @@ -3068,12 +3069,12 @@ void XclExpXFBuffer::AddBorderAndFill( const XclExpXF& rXF ) XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot ) : XclExpRoot( rRoot ), + mxFormatter(new SvNumberFormatter( comphelper::getProcessComponentContext(), LANGUAGE_ENGLISH_US )), mpKeywordTable( new NfKeywordTable ) { sal_Int32 nDxfId = 0; // Special number formatter for conversion. - SvNumberFormatterPtr xFormatter(new SvNumberFormatter( comphelper::getProcessComponentContext(), LANGUAGE_ENGLISH_US )); - xFormatter->FillKeywordTableForExcel( *mpKeywordTable ); + mxFormatter->FillKeywordTableForExcel( *mpKeywordTable ); SCTAB nTables = rRoot.GetDoc().GetTableCount(); for(SCTAB nTab = 0; nTab < nTables; ++nTab) @@ -3149,7 +3150,7 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot ) continue; SfxItemSet& rSet = pStyle->GetItemSet(); - fillDxfFrom(rSet, xFormatter); + fillDxfFrom(rSet); nDxfId++; } @@ -3172,7 +3173,7 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot ) continue; SfxItemSet& rItemSet = rFormat.pPattern->GetItemSet(); - fillDxfFrom(rItemSet, xFormatter); + fillDxfFrom(rItemSet); maPatternToDxfId.emplace(rFormat.pPattern.get(), nDxfId); nDxfId++; } @@ -3180,7 +3181,14 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot ) } } -void XclExpDxfs::fillDxfFrom(SfxItemSet& rItemSet, SvNumberFormatterPtr& xFormatter) +sal_Int32 XclExpDxfs::fillFromPattern(const ScPatternAttr* pPattern) +{ + sal_Int32 nIndex = maDxf.size(); + fillDxfFrom(pPattern->GetItemSet()); + return nIndex; +} + +void XclExpDxfs::fillDxfFrom(const SfxItemSet& rItemSet) { std::unique_ptr<XclExpCellBorder> pBorder(new XclExpCellBorder); if (!pBorder->FillFromItemSet(rItemSet, GetPalette(), GetBiff())) @@ -3205,7 +3213,7 @@ void XclExpDxfs::fillDxfFrom(SfxItemSet& rItemSet, SvNumberFormatterPtr& xFormat { sal_uInt32 nScNumberFormat = pPoolItem->GetValue(); sal_Int32 nXclNumberFormat = GetRoot().GetNumFmtBuffer().Insert(nScNumberFormat); - pNumberFormat.reset(new XclExpNumFmt(nScNumberFormat, nXclNumberFormat, GetNumberFormatCode(*this, nScNumberFormat, xFormatter.get(), mpKeywordTable.get()))); + pNumberFormat.reset(new XclExpNumFmt(nScNumberFormat, nXclNumberFormat, GetNumberFormatCode(*this, nScNumberFormat, mxFormatter.get(), mpKeywordTable.get()))); } maDxf.push_back(std::make_unique<XclExpDxf>(GetRoot(), std::move(pAlign), std::move(pBorder), @@ -3341,6 +3349,68 @@ void XclExpDxf::SaveXmlExt( XclExpXmlStream& rStrm ) rStyleSheet->endElementNS( XML_x14, XML_dxf ); } +XclExpXmlTableStyle::XclExpXmlTableStyle(const XclExpRoot& rRoot, const ScTableStyle* pTableStyle): + XclExpRoot(rRoot), + maStyleName(pTableStyle->GetName()) +{ + XclExpDxfs& rDxfs = GetDxfs(); + std::map<ScTableStyleElement, const ScPatternAttr*> aTableElements = pTableStyle->GetSetPatterns(); + for (auto& rElement : aTableElements) + { + maTableElements.emplace(rElement.first, rDxfs.fillFromPattern(rElement.second)); + } +} + +const std::map<ScTableStyleElement, const char*> aTableStyleElementToOOXML = { {ScTableStyleElement::WholeTable, "wholeTable"}, {ScTableStyleElement::FirstColumnStripe, "firstColumnStripe"}, {ScTableStyleElement::SecondColumnStripe, "secondColumnStripe"}, {ScTableStyleElement::FirstRowStripe, "firstRowStripe"}, {ScTableStyleElement::SecondRowStripe, "secondRowStripe"}, {ScTableStyleElement::LastColumn, "lastColumn"}, {ScTableStyleElement::FirstColumn, "firstColumn"}, {ScTableStyleElement::HeaderRow, "headerRow"}, {ScTableStyleElement::TotalRow, "totalRow"}, {ScTableStyleElement::FirstHeaderCell, "firstHeaderCell"}, {ScTableStyleElement::LastHeaderCell, "LastHeaderCell"} }; + +void XclExpXmlTableStyle::SaveXml( XclExpXmlStream& rStrm ) +{ + sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream(); + rStyleSheet->startElement( XML_tableStyle, XML_count, OString::number(maTableElements.size()), XML_name, maStyleName.toUtf8()); + for (auto& rTableStyleElement : maTableElements) + { + rStyleSheet->singleElement( XML_tableStyleElement, XML_dxfId, OString::number(rTableStyleElement.second), XML_type, aTableStyleElementToOOXML.find(rTableStyleElement.first)->second); + } + rStyleSheet->endElement(XML_tableStyle); +} + +XclExpXmlTableStyles::XclExpXmlTableStyles( const XclExpRoot& rRoot): + XclExpRoot(rRoot) +{ + std::set<OUString> aTableStyleNames; + + const ScDBCollection* pDBCollection = GetDoc().GetDBCollection(); + const ScDBCollection::NamedDBs& rDBs = pDBCollection->getNamedDBs(); + const ScTableStyles& rTableStyles = GetDoc().GetTableStyles(); + for (auto itr = rDBs.begin(); itr != rDBs.end(); ++itr) + { + const ScTableStyleParam* pParam = itr->get()->GetTableStyleInfo(); + if (pParam && rTableStyles.GetTableStyle(pParam->maStyleName)) + { + aTableStyleNames.insert(pParam->maStyleName); + } + } + + for (const OUString& aTableStyleName : aTableStyleNames) + { + const ScTableStyle* pTableStyle = rTableStyles.GetTableStyle(aTableStyleName); + maTableStyles.push_back(std::make_unique<XclExpXmlTableStyle>(rRoot, pTableStyle)); + } +} + +void XclExpXmlTableStyles::SaveXml( XclExpXmlStream& rStrm ) +{ + sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream(); + if (maTableStyles.empty()) + return; + + rStyleSheet->startElement( XML_tableStyles, XML_count, OString::number(maTableStyles.size()) ); + for (auto& rTableStyleElement : maTableStyles) + { + rTableStyleElement->SaveXml(rStrm); + } + rStyleSheet->endElement( XML_tableStyles ); +} XclExpXmlStyleSheet::XclExpXmlStyleSheet( const XclExpRoot& rRoot ) : XclExpRoot( rRoot ) @@ -3363,6 +3433,7 @@ void XclExpXmlStyleSheet::SaveXml( XclExpXmlStream& rStrm ) CreateRecord( EXC_ID_FONTLIST )->SaveXml( rStrm ); CreateRecord( EXC_ID_XFLIST )->SaveXml( rStrm ); CreateRecord( EXC_ID_DXFS )->SaveXml( rStrm ); + CreateRecord( EXC_ID_TABLESTYLES )->SaveXml( rStrm ); CreateRecord( EXC_ID_PALETTE )->SaveXml( rStrm ); aStyleSheet->endElement( XML_styleSheet ); diff --git a/sc/source/filter/inc/defaulttablestyles.hxx b/sc/source/filter/inc/defaulttablestyles.hxx new file mode 100644 index 000000000000..2cd524f30249 --- /dev/null +++ b/sc/source/filter/inc/defaulttablestyles.hxx @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 <tablestyle.hxx> +#include "stylesbuffer.hxx" + +// structs used by the script generated code from the original OOXML spec + +struct ThemeColor +{ + int nThemeId; + float fTint; +}; + +struct Font +{ + bool bBold; + int nThemeColorId; +}; + +struct Fill +{ + int nFgColorId; + int nBgColorId; +}; + +enum class BorderElementStyle +{ + THIN, + MEDIUM, + THICK, + DOUBLE +}; + +struct BorderElement +{ + BorderElementStyle eBorderStyle; + int nColorId; +}; + +struct Border +{ + int nTopId; + int nBottomId; + int nLeftId; + int nRightId; + int nHorizontalId; + int nVerticalId; +}; + +struct Dxf +{ + int nFillId; + int nBorderId; + int nFontId; +}; + +struct TableStyleElement +{ + ScTableStyleElement eElement; + int nDxfId; +}; + +struct TableStyle +{ + const char* pName; + size_t nElements; + int pTableStyleElementIds[9]; +}; + +// the actual import class + +class DefaultOOXMLTableStyles : public oox::xls::WorkbookHelper +{ +private: + std::vector<oox::xls::XlsColor> maColors; + oox::xls::FillVector maFills; + oox::xls::BorderVector maBorders; + oox::xls::FontVector maFonts; + + oox::xls::DxfVector maDxfs; + + void importColors(); + void importFills(); + void importBorderElement(oox::xls::BorderRef xBorder, sal_Int32 nBorderElement, + sal_Int32 nBorderElementId); + void importBorders(); + void importFonts(); + void importDxfs(); + void importTableStyle(const TableStyle& rTableStyleInfo); + +public: + DefaultOOXMLTableStyles(const oox::xls::WorkbookHelper& rHelper); + void importTableStyles(); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sc/source/filter/inc/stylesbuffer.hxx b/sc/source/filter/inc/stylesbuffer.hxx index 95ec8b8806ff..3f9613f8d01d 100644 --- a/sc/source/filter/inc/stylesbuffer.hxx +++ b/sc/source/filter/inc/stylesbuffer.hxx @@ -37,6 +37,7 @@ #include <vector> class ScPatternCache; +enum class ScTableStyleElement; namespace oox { class SequenceInputStream; } @@ -451,6 +452,9 @@ public: /** Imports a border from a DXF record from the passed stream. */ void importDxfBorder( sal_Int32 nElement, SequenceInputStream& rStrm ); + // for OOXML default table styles + void setBorderElement(sal_Int32 nElement, const XlsColor& rColor, sal_Int32 nStyle); + /** Final processing after import of all style settings. */ void finalizeImport( bool bRTL ); @@ -556,6 +560,9 @@ public: /** Imports gradient stop settings from a DXF record. */ void importDxfStop( SequenceInputStream& rStrm ); + // for dealing with OOXML default table styles + void setFillColors(const XlsColor& rFgColor, const XlsColor& rBgColor); + /** Final processing after import of all style settings. */ void finalizeImport(); @@ -676,6 +683,11 @@ public: /** Creates a new empty protection object. */ ProtectionRef const & createProtection( bool bAlwaysNew = true ); + // methods for OOXML default table style import + void setFill(FillRef xFill); + void setBorder(BorderRef xBorder); + void setFont(FontRef xFont); + /** Inserts a new number format code. */ void importNumFmt( const AttributeList& rAttribs ); @@ -801,6 +813,39 @@ struct AutoFormatModel explicit AutoFormatModel(); }; +struct TableStyleElementInfo +{ + sal_Int32 mnDxfID; + sal_Int32 mnStripeCount; + + TableStyleElementInfo(); +}; + +typedef RefVector< Dxf > DxfVector; +typedef RefVector< Border > BorderVector; +typedef RefVector< Fill > FillVector; +typedef RefVector< Font > FontVector; + +class TableStyle : public WorkbookHelper +{ + OUString maName; + std::unordered_map<ScTableStyleElement, TableStyleElementInfo> maTableStyleElements; + bool mbDefaultOOXMLStyle; + std::optional<OUString> maUIName; +public: + explicit TableStyle( const WorkbookHelper& rHelper, bool bDefaultOOXMLStyle ); + + void setName(const OUString& rName); + void setUIName(const OUString& rName); + void importTableStyleElement(const AttributeList& rAttribs); + void finalizeImport(const DxfVector& mrDxfs); + + // for OOXML default table styles + void setTableStyleElement(ScTableStyleElement eTableStyleElement, sal_Int32 nDxfId); +}; + +typedef std::shared_ptr< TableStyle > TableStyleRef; + class StylesBuffer : public WorkbookHelper { public: @@ -823,6 +868,8 @@ public: DxfRef createDxf(); DxfRef createExtDxf(); + TableStyleRef createTableStyle(); + /** Appends a new color to the color palette. */ void importPaletteColor( const AttributeList& rAttribs ); /** Inserts a new number format code. */ @@ -886,12 +933,9 @@ public: const RefVector< Dxf >& getExtDxfs() const { return maExtDxfs; } private: - typedef RefVector< Font > FontVector; - typedef RefVector< Border > BorderVector; - typedef RefVector< Fill > FillVector; typedef RefVector< Xf > XfVector; - typedef RefVector< Dxf > DxfVector; typedef ::std::map< sal_Int32, OUString > DxfStyleMap; + typedef RefVector< TableStyle > TableStyleVector; ColorPalette maPalette; /// Color palette. FontVector maFonts; /// List of font objects. @@ -904,6 +948,7 @@ private: DxfVector maDxfs; /// List of differential cell styles. DxfVector maExtDxfs; /// List of differential extlst cell styles. mutable DxfStyleMap maDxfStyles; /// Maps DXF identifiers to Calc style sheet names. + TableStyleVector maTableStyles; }; } // namespace oox::xls diff --git a/sc/source/filter/inc/stylesfragment.hxx b/sc/source/filter/inc/stylesfragment.hxx index ead5a20f16db..562b3b76f515 100644 --- a/sc/source/filter/inc/stylesfragment.hxx +++ b/sc/source/filter/inc/stylesfragment.hxx @@ -125,6 +125,21 @@ protected: virtual void finalizeImport() override; }; +class TableStyleContext : public WorkbookContextBase +{ +public: + template< typename ParentType > + explicit TableStyleContext( ParentType& rParent, const TableStyleRef& rxTableStyle ) : + WorkbookContextBase( rParent ), mxTableStyle( rxTableStyle ) {} + +protected: + virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; + virtual void onStartElement( const AttributeList& rAttribs ) override; + +private: + TableStyleRef mxTableStyle; +}; + } // namespace oox::xls /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/inc/tablebuffer.hxx b/sc/source/filter/inc/tablebuffer.hxx index 40facdd3e9a7..bf995393000c 100644 --- a/sc/source/filter/inc/tablebuffer.hxx +++ b/sc/source/filter/inc/tablebuffer.hxx @@ -20,11 +20,23 @@ #pragma once #include "autofilterbuffer.hxx" +#include "stylesbuffer.hxx" #include "tablecolumnsbuffer.hxx" #include "workbookhelper.hxx" namespace oox::xls { +struct TableStyleInfo +{ + std::optional<OUString> maStyleName; + bool mbShowFirstColumn; + bool mbShowLastColumn; + bool mbShowRowStripes; + bool mbShowColStripes; + + explicit TableStyleInfo(); +}; + struct TableModel { ScRange maRange; /// Original (unchecked) range of the table. @@ -52,6 +64,8 @@ public: /** Creates a new tableColumns handler and stores it internally. */ TableColumns& createTableColumns() { return maTableColumns.createTableColumns(); } + void importTableStyleInfo(const AttributeList& rAttribs); + /** Creates a database range from this tables. */ void finalizeImport(); void applyAutoFilters(); @@ -79,6 +93,7 @@ public: private: TableModel maModel; + std::optional<TableStyleInfo> maStyleInfo; AutoFilterBuffer maAutoFilters; /// Filter settings for this table. TableColumnsBuffer maTableColumns; /// Column names of this table. OUString maDBRangeName; /// Name of the database range in the Calc document. diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx index f2c1984506c3..c604e403a1aa 100644 --- a/sc/source/filter/inc/xeroot.hxx +++ b/sc/source/filter/inc/xeroot.hxx @@ -51,6 +51,7 @@ class XclExpObjectManager; class XclExpFilterManager; class XclExpPivotTableManager; class XclExpDxfs; +class XclExpXmlTableStyles; class XclExpXmlPivotTableManager; class XclExpTablesManager; namespace sc { class CompileFormulaContext; } @@ -74,6 +75,7 @@ struct XclExpRootData : public XclRootData typedef std::shared_ptr< XclExpFilterManager > XclExpFilterMgrRef; typedef std::shared_ptr< XclExpPivotTableManager > XclExpPTableMgrRef; typedef rtl::Reference< XclExpDxfs > XclExpDxfsRef; + typedef rtl::Reference< XclExpXmlTableStyles > XclExpXmlTableStylesRef; XclExpTabInfoRef mxTabInfo; /// Calc->Excel sheet index conversion. XclExpAddrConvRef mxAddrConv; /// The address converter. @@ -92,6 +94,7 @@ struct XclExpRootData : public XclRootData XclExpFilterMgrRef mxFilterMgr; /// Manager for filtered areas in all sheets. -e ... etc. - the rest is truncated
