offapi/com/sun/star/sheet/DatabaseRange.idl | 30 + oox/source/token/properties.txt | 5 sc/Library_sc.mk | 1 sc/Library_scfilt.mk | 1 sc/inc/dbdata.hxx | 19 sc/inc/document.hxx | 5 sc/inc/tablestyle.hxx | 109 +++++ sc/inc/unonames.hxx | 5 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 | 86 +++ 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/docshell/dbdocfun.cxx | 19 sc/source/ui/unoobj/datauno.cxx | 63 ++ sc/workben/generate_ooxml_tablestyle_info.py | 582 +++++++++++++++++++++++++++ 31 files changed, 2034 insertions(+), 17 deletions(-)
New commits: commit 46b6455af7854795ac379a4a1f37c60b4414af02 Author: Markus Mohrhard <[email protected]> AuthorDate: Tue Jul 29 12:25:53 2025 +0800 Commit: Balazs Varga <[email protected]> CommitDate: Wed Jan 7 17:09:41 2026 +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]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196734 Tested-by: Balazs Varga <[email protected]> Reviewed-by: Balazs Varga <[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 e674b902f03a..43f7cff58391 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -586,6 +586,7 @@ TableBorder TableLayout TableSelected Tables +TableStyleName Tabstop Tag TargetFrame @@ -635,9 +636,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 5960a50e1fa4..32b5770be95d 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -209,6 +209,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 5c265503df12..941d0bc36998 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 4766e62a9493..9b7a148e49e3 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 743c642fcf51..3be6cfd1202f 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -215,6 +215,7 @@ struct ScFilterEntries; typedef o3tl::sorted_vector<sal_uInt32> ScCondFormatIndexes; struct ScDataAreaExtras; enum class ScConditionMode; +class ScTableStyles; namespace sc { @@ -438,6 +439,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 > @@ -2758,6 +2760,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 88e06748b110..69b327e87a57 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -331,6 +331,11 @@ inline constexpr OUString SC_UNONAME_ISSHAREDFMLA = u"IsSharedFormula"_ustr; inline constexpr OUString SC_UNONAME_TOTALSROW = u"TotalsRow"_ustr; inline constexpr OUString SC_UNONAME_NUMBERBEHAVIOR = u"NumberBehavior"_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 903800e29f47..ecdb8a1dd358 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -94,6 +94,7 @@ #include <sharedstringpoolpurge.hxx> #include <docpool.hxx> #include <config_features.h> +#include <tablestyle.hxx> using namespace com::sun::star; @@ -143,6 +144,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, ScDocShell* pDocShell ) : pEOFormulaTree( nullptr ), pFormulaTrack( nullptr ), pEOFormulaTrack( nullptr ), + mpTableStyles(new ScTableStyles), pPreviewCellStyle( nullptr ), maPreviewSelection(*mxSheetLimits), nUnoObjectId( 0 ), @@ -406,6 +408,7 @@ ScDocument::~ScDocument() pUnoRefUndoList.reset(); pUnoListenerCalls.reset(); + mpTableStyles.reset(); Clear( true ); // true = from destructor (needed for SdrModel::ClearModel) @@ -1540,4 +1543,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 fd1f56e0e365..94a0244efe5c 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 b1d714c55efa..1f5309050b5c 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 4fce1d001825..a327e1880df5 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->GetItemSetWritable(); - fillDxfFrom(rItemSet, xFormatter); + fillDxfFrom(rItemSet); maPatternToDxfId.emplace(rFormat.pPattern.get(), nDxfId); nDxfId++; } @@ -3180,7 +3181,14 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot ) } } -void XclExpDxfs::fillDxfFrom(const SfxItemSet& rItemSet, const 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(const SfxItemSet& rItemSet, const SvNumberFormatter { 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 9ab8c1b597aa..2d6245b3938a 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; } @@ -463,6 +464,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 ); @@ -574,6 +578,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(); @@ -699,6 +706,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 ); @@ -824,6 +836,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: @@ -846,6 +891,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. */ @@ -909,12 +956,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. @@ -927,6 +971,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. XclExpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches. XclExpDxfsRef mxDxfs; /// All delta formatting entries + XclExpXmlTableStylesRef mxTableStyles; std::shared_ptr<XclExpXmlPivotTableManager> mxXmlPTableMgr; std::shared_ptr<XclExpTablesManager> mxTablesMgr; diff --git a/sc/source/filter/inc/xestyle.hxx b/sc/source/filter/inc/xestyle.hxx index a54a1fe827c4..a564b2006eb1 100644 --- a/sc/source/filter/inc/xestyle.hxx +++ b/sc/source/filter/inc/xestyle.hxx @@ -32,6 +32,9 @@ #include <vector> #include <docmodel/color/ComplexColor.hxx> +class ScTableStyle; +enum class ScTableStyleElement; + /* ============================================================================ - Buffers for style records (PALETTE, FONT, FORMAT, XF, STYLE). ============================================================================ */ @@ -39,6 +42,7 @@ const sal_uInt16 EXC_ID_FONTLIST = 0x8031; /// For internal use only. const sal_uInt16 EXC_ID_FORMATLIST = 0x801E; /// For internal use only. const sal_uInt16 EXC_ID_XFLIST = 0x8043; /// For internal use only. +const sal_uInt16 EXC_ID_TABLESTYLES = 0x9998; const sal_uInt16 EXC_ID_DXFS = 0x9999; /// For internal use only. TODO:moggi: find a better/correct value // PALETTE record - color information ========================================= @@ -764,6 +768,7 @@ public: sal_Int32 GetDxfIdForPattern(ScPatternAttr* pPattern) const; sal_Int32 GetDxfByColor(Color aColor) const; void addColor(Color aColor); + sal_Int32 fillFromPattern(const ScPatternAttr* pPattern); virtual void SaveXml( XclExpXmlStream& rStrm) override; void Finalize(); @@ -774,10 +779,33 @@ private: std::map<Color, sal_Int32> maColorToDxfId; std::map<ScPatternAttr*, sal_Int32> maPatternToDxfId; DxfContainer maDxf; + SvNumberFormatterPtr mxFormatter; std::unique_ptr<NfKeywordTable> mpKeywordTable; /// Replacement table. - void fillDxfFrom(const SfxItemSet& rItemSet, const SvNumberFormatterPtr& xFormatter); + void fillDxfFrom(const SfxItemSet& rItemSet); + +}; + +class XclExpXmlTableStyle : public XclExpRecordBase, protected XclExpRoot +{ + std::map<ScTableStyleElement, sal_Int32> maTableElements; + OUString maStyleName; + +public: + explicit XclExpXmlTableStyle( const XclExpRoot& rRoot, const ScTableStyle* pTableStyle ); + virtual void SaveXml( XclExpXmlStream& rStrm ) override; +}; + +class XclExpXmlTableStyles : public XclExpRecordBase, protected XclExpRoot +{ +private: + typedef std::vector< std::unique_ptr<XclExpXmlTableStyle> > TableStyleContainer; + TableStyleContainer maTableStyles; +public: + explicit XclExpXmlTableStyles( const XclExpRoot& rRoot ); + + virtual void SaveXml( XclExpXmlStream& rStrm ) override; }; class XclExpXmlStyleSheet : public XclExpRecordBase, protected XclExpRoot diff --git a/sc/source/filter/oox/defaulttablestyles.cxx b/sc/source/filter/oox/defaulttablestyles.cxx new file mode 100644 index 000000000000..4bf970a0ded0 --- /dev/null +++ b/sc/source/filter/oox/defaulttablestyles.cxx @@ -0,0 +1,142 @@ +/* -*- 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 <oox/token/namespaces.hxx> +#include <oox/token/tokens.hxx> + +#include "defaulttablestyles.inc" +#include <workbookhelper.hxx> + +DefaultOOXMLTableStyles::DefaultOOXMLTableStyles(const oox::xls::WorkbookHelper& rHelper) + : WorkbookHelper(rHelper) +{ + importColors(); + importFills(); + importBorders(); + importFonts(); + importDxfs(); +} + +void DefaultOOXMLTableStyles::importColors() +{ + size_t nColors = sizeof(aThemeColors) / sizeof(ThemeColor); + for (size_t i = 0; i < nColors; ++i) + { + oox::xls::XlsColor aColor; + aColor.setTheme(aThemeColors[i].nThemeId, aThemeColors[i].fTint); + maColors.push_back(aColor); + } +} + +void DefaultOOXMLTableStyles::importFills() +{ + size_t nFills = sizeof(aFills) / sizeof(Fill); + for (size_t i = 0; i < nFills; ++i) + { + auto xFill = std::make_shared<oox::xls::Fill>(*this, true); + xFill->setFillColors(maColors[aFills[i].nFgColorId], maColors[aFills[i].nBgColorId]); + maFills.push_back(xFill); + } +} + +void DefaultOOXMLTableStyles::importBorderElement(oox::xls::BorderRef xBorder, + sal_Int32 nBorderElement, + sal_Int32 nBorderElementId) +{ + const BorderElement& rBorderElement = aBorderElements[nBorderElementId]; + if (rBorderElement.nColorId >= static_cast<sal_Int32>(maColors.size())) + return; + + sal_Int32 nBorderStyle; + switch (rBorderElement.eBorderStyle) + { + case BorderElementStyle::THIN: + nBorderStyle = oox::XML_thin; + break; + case BorderElementStyle::MEDIUM: + nBorderStyle = oox::XML_medium; + break; + case BorderElementStyle::THICK: + nBorderStyle = oox::XML_thick; + break; + case BorderElementStyle::DOUBLE: + nBorderStyle = oox::XML_double; + break; + } + + oox::xls::XlsColor& rColor = maColors[rBorderElement.nColorId]; + xBorder->setBorderElement(nBorderElement, rColor, nBorderStyle); +} + +void DefaultOOXMLTableStyles::importBorders() +{ + size_t nBorders = sizeof(aBorders) / sizeof(Border); + for (size_t i = 0; i < nBorders; ++i) + { + auto xBorder = std::make_shared<oox::xls::Border>(*this, true); + + const Border& rBorderInfo = aBorders[i]; + if (rBorderInfo.nTopId >= 0) + importBorderElement(xBorder, XLS_TOKEN(top), rBorderInfo.nTopId); + if (rBorderInfo.nBottomId >= 0) + importBorderElement(xBorder, XLS_TOKEN(bottom), rBorderInfo.nBottomId); + if (rBorderInfo.nLeftId >= 0) + importBorderElement(xBorder, XLS_TOKEN(left), rBorderInfo.nLeftId); + if (rBorderInfo.nRightId >= 0) + importBorderElement(xBorder, XLS_TOKEN(right), rBorderInfo.nRightId); + + maBorders.push_back(xBorder); + } +} + +void DefaultOOXMLTableStyles::importFonts() {} + +void DefaultOOXMLTableStyles::importDxfs() +{ + size_t nDxfs = sizeof(aDxfs) / sizeof(Dxf); + for (size_t i = 0; i < nDxfs; ++i) + { + auto xDxf = std::make_shared<oox::xls::Dxf>(*this); + auto aDxfInfo = aDxfs[i]; + + if (aDxfInfo.nFillId >= 0) + xDxf->setFill(maFills[aDxfInfo.nFillId]); + + if (aDxfInfo.nBorderId >= 0) + xDxf->setBorder(maBorders[aDxfInfo.nBorderId]); + + xDxf->finalizeImport(); + maDxfs.push_back(xDxf); + } +} + +void DefaultOOXMLTableStyles::importTableStyle(const TableStyle& rTableStyleInfo) +{ + oox::xls::TableStyle aTableStyle(*this, true); + aTableStyle.setName(OUString::createFromAscii(rTableStyleInfo.pName)); + for (size_t i = 0; i < rTableStyleInfo.nElements; ++i) + { + const TableStyleElement& rTableStyleElement + = aTableStyleElements[rTableStyleInfo.pTableStyleElementIds[i]]; + aTableStyle.setTableStyleElement(rTableStyleElement.eElement, rTableStyleElement.nDxfId); + } + + aTableStyle.finalizeImport(maDxfs); +} + +void DefaultOOXMLTableStyles::importTableStyles() +{ + size_t nTableStyles = sizeof(aTableStyles) / sizeof(TableStyle); + for (size_t i = 0; i < nTableStyles; ++i) + { + importTableStyle(aTableStyles[i]); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sc/source/filter/oox/defaulttablestyles.inc b/sc/source/filter/oox/defaulttablestyles.inc new file mode 100644 index 000000000000..84d84cf59d96 --- /dev/null +++ b/sc/source/filter/oox/defaulttablestyles.inc @@ -0,0 +1,33 @@ + +/* -*- 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/. + */ + +// WARNING: This file is automatically generated and should not be manually edited! + +#include <defaulttablestyles.hxx> + + +constexpr ThemeColor aThemeColors[] = { { 0, -0.3499862666707358 }, { 0, -0.1499984740745262 }, { 0, 0.0 }, { 1, 0.0 }, { 1, 0.1499984740745262 }, { 1, 0.249977111117893 }, { 1, 0.4499954222235786 }, { 4, -0.499984740745262 }, { 4, -0.249977111117893 }, { 4, 0.0 }, { 4, 0.3999755851924192 }, { 4, 0.5999938962981048 }, { 4, 0.7999816888943144 }, { 5, -0.499984740745262 }, { 5, -0.249977111117893 }, { 5, 0.0 }, { 5, 0.3999755851924192 }, { 5, 0.5999938962981048 }, { 5, 0.7999816888943144 }, { 6, -0.499984740745262 }, { 6, -0.249977111117893 }, { 6, 0.0 }, { 6, 0.3999755851924192 }, { 6, 0.5999938962981048 }, { 6, 0.7999816888943144 }, { 7, -0.499984740745262 }, { 7, -0.249977111117893 }, { 7, 0.0 }, { 7, 0.3999755851924192 }, { 7, 0.5999938962981048 }, { 7, 0.7999816888943144 }, { 8, -0.499984740745262 }, { 8, -0.249977111117893 }, { 8, 0.0 }, { 8, 0.3999755851924192 }, { 8, 0.5999938962981048 }, { 8, 0.7999816888943144 }, { 9, -0.499984740745262 }, { 9, -0.249977111117893 }, { 9, 0.0 }, { 9, 0.3999755851924192 }, { 9, 0.5999938962981048 }, { 9, 0.7999816888943144 } }; + +constexpr Fill aFills[] = { { 0, 0 }, { 1, 1 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 }, { 8, 8 }, { 9, 9 }, { 11, 11 }, { 12, 12 }, { 13, 13 }, { 14, 14 }, { 15, 15 }, { 17, 17 }, { 18, 18 }, { 19, 19 }, { 20, 20 }, { 21, 21 }, { 23, 23 }, { 24, 24 }, { 25, 25 }, { 26, 26 }, { 27, 27 }, { 29, 29 }, { 30, 30 }, { 31, 31 }, { 32, 32 }, { 33, 33 }, { 35, 35 }, { 36, 36 }, { 37, 37 }, { 38, 38 }, { 39, 39 }, { 41, 41 }, { 42, 42 } }; + +constexpr Font aFonts[] = { { false, 2 }, { false, 3 }, { false, 8 }, { false, 14 }, { false, 20 }, { false, 26 }, { false, 32 }, { false, 38 }, { true, 2 }, { true, 3 }, { true, 8 }, { true, 14 }, { true, 20 }, { true, 26 }, { true, 32 }, { true, 38 } }; + +constexpr BorderElement aBorderElements[] = { { BorderElementStyle::THIN, 2 }, { BorderElementStyle::THIN, 3 }, { BorderElementStyle::THIN, 9 }, { BorderElementStyle::THIN, 10 }, { BorderElementStyle::THIN, 15 }, { BorderElementStyle::THIN, 16 }, { BorderElementStyle::THIN, 21 }, { BorderElementStyle::THIN, 22 }, { BorderElementStyle::THIN, 27 }, { BorderElementStyle::THIN, 28 }, { BorderElementStyle::THIN, 33 }, { BorderElementStyle::THIN, 34 }, { BorderElementStyle::THIN, 39 }, { BorderElementStyle::THIN, 40 }, { BorderElementStyle::MEDIUM, 2 }, { BorderElementStyle::MEDIUM, 3 }, { BorderElementStyle::MEDIUM, 9 }, { BorderElementStyle::MEDIUM, 15 }, { BorderElementStyle::MEDIUM, 21 }, { BorderElementStyle::MEDIUM, 27 }, { BorderElementStyle::MEDIUM, 33 }, { BorderElementStyle::MEDIUM, 39 }, { BorderElementStyle::THICK, 2 }, { BorderElementStyle::DOUBLE, 3 }, { BorderElementStyle::DOUBLE, 9 }, { BorderElementStyle::DOUBLE, 15 }, { BorderElementStyle::DOUBLE, 21 }, { BorderElementSt yle::DOUBLE, 27 }, { BorderElementStyle::DOUBLE, 33 }, { BorderElementStyle::DOUBLE, 39 } }; + +constexpr Border aBorders[] = { { -1, -1, -1, -1, 0, 0 }, { -1, -1, -1, 14, -1, -1 }, { -1, -1, 1, -1, -1, -1 }, { -1, -1, 2, -1, -1, -1 }, { -1, -1, 4, -1, -1, -1 }, { -1, -1, 6, -1, -1, -1 }, { -1, -1, 8, -1, -1, -1 }, { -1, -1, 10, -1, -1, -1 }, { -1, -1, 12, -1, -1, -1 }, { -1, -1, 14, -1, -1, -1 }, { -1, 1, -1, -1, -1, -1 }, { -1, 2, -1, -1, -1, -1 }, { -1, 4, -1, -1, -1, -1 }, { -1, 6, -1, -1, -1, -1 }, { -1, 8, -1, -1, -1, -1 }, { -1, 10, -1, -1, -1, -1 }, { -1, 12, -1, -1, -1, -1 }, { -1, 14, -1, -1, -1, -1 }, { -1, 15, -1, -1, -1, -1 }, { -1, 16, -1, -1, -1, -1 }, { -1, 17, -1, -1, -1, -1 }, { -1, 18, -1, -1, -1, -1 }, { -1, 19, -1, -1, -1, -1 }, { -1, 20, -1, -1, -1, -1 }, { -1, 21, -1, -1, -1, -1 }, { -1, 22, -1, -1, -1, -1 }, { 1, -1, -1, -1, -1, -1 }, { 1, 1, -1, -1, -1, -1 }, { 1, 1, 1, 1, -1, -1 }, { 1, 1, 1, 1, 1, -1 }, { 1, 1, 1, 1, 1, 1 }, { 2, -1, -1, -1, -1, -1 }, { 2, 2, -1, -1, -1, -1 }, { 2, 2, 2, 2, -1, -1 }, { 2, 2, 2, 2, 2, 2 }, { 3, 3, 3, 3, 3, -1 }, { 3, 3, 3, 3, 3, 3 }, { 4, -1, -1, -1, -1, -1 }, { 4, 4, -1, -1, -1, -1 }, { 4, 4, 4, 4, -1, -1 }, { 4, 4, 4, 4, 4, 4 }, { 5, 5, 5, 5, 5, -1 }, { 5, 5, 5, 5, 5, 5 }, { 6, -1, -1, -1, -1, -1 }, { 6, 6, -1, -1, -1, -1 }, { 6, 6, 6, 6, -1, -1 }, { 6, 6, 6, 6, 6, 6 }, { 7, 7, 7, 7, 7, -1 }, { 7, 7, 7, 7, 7, 7 }, { 8, -1, -1, -1, -1, -1 }, { 8, 8, -1, -1, -1, -1 }, { 8, 8, 8, 8, -1, -1 }, { 8, 8, 8, 8, 8, 8 }, { 9, 9, 9, 9, 9, -1 }, { 9, 9, 9, 9, 9, 9 }, { 10, -1, -1, -1, -1, -1 }, { 10, 10, -1, -1, -1, -1 }, { 10, 10, 10, 10, -1, -1 }, { 10, 10, 10, 10, 10, 10 }, { 11, 11, 11, 11, 11, -1 }, { 11, 11, 11, 11, 11, 11 }, { 12, -1, -1, -1, -1, -1 }, { 12, 12, -1, -1, -1, -1 }, { 12, 12, 12, 12, -1, -1 }, { 12, 12, 12, 12, 12, 12 }, { 13, 13, 13, 13, 13, -1 }, { 13, 13, 13, 13, 13, 13 }, { 14, -1, -1, -1, -1, -1 }, { 15, -1, -1, -1, -1, -1 }, { 15, 15, -1, -1, -1, -1 }, { 15, 15, 1, 1, 1, 1 }, { 16, -1, -1, -1, -1, -1 }, { 17, -1, -1, -1, -1, -1 }, { 18, -1, -1, -1, -1, -1 }, { 19, -1, -1, -1, -1 , -1 }, { 20, -1, -1, -1, -1, -1 }, { 21, -1, -1, -1, -1, -1 }, { 22, -1, -1, -1, -1, -1 }, { 23, -1, -1, -1, -1, -1 }, { 24, -1, -1, -1, -1, -1 }, { 25, -1, -1, -1, -1, -1 }, { 26, -1, -1, -1, -1, -1 }, { 27, -1, -1, -1, -1, -1 }, { 28, -1, -1, -1, -1, -1 }, { 29, -1, -1, -1, -1, -1 } }; + +constexpr Dxf aDxfs[] = { { -1, 2, -1 }, { -1, 3, -1 }, { -1, 4, -1 }, { -1, 5, -1 }, { -1, 6, -1 }, { -1, 7, -1 }, { -1, 8, -1 }, { -1, 26, -1 }, { -1, 31, -1 }, { -1, 37, -1 }, { -1, 43, -1 }, { -1, 49, -1 }, { -1, 55, -1 }, { -1, 61, -1 }, { -1, 78, -1 }, { 0, -1, -1 }, { 1, -1, -1 }, { 4, -1, -1 }, { 7, -1, -1 }, { 9, -1, -1 }, { 10, -1, -1 }, { 12, -1, -1 }, { 14, -1, -1 }, { 15, -1, -1 }, { 17, -1, -1 }, { 19, -1, -1 }, { 20, -1, -1 }, { 22, -1, -1 }, { 24, -1, -1 }, { 25, -1, -1 }, { 27, -1, -1 }, { 29, -1, -1 }, { 30, -1, -1 }, { 32, -1, -1 }, { 34, -1, -1 }, { 35, -1, -1 }, { 2, -1, 0 }, { 5, -1, 0 }, { 8, -1, 0 }, { 13, -1, 0 }, { 18, -1, 0 }, { 23, -1, 0 }, { 28, -1, 0 }, { 33, -1, 0 }, { -1, 27, 1 }, { -1, 28, 1 }, { -1, 29, 1 }, { -1, 30, 1 }, { -1, 33, 1 }, { -1, 34, 1 }, { -1, 35, 1 }, { -1, 39, 1 }, { -1, 40, 1 }, { -1, 41, 1 }, { -1, 45, 1 }, { -1, 46, 1 }, { -1, 47, 1 }, { -1, 51, 1 }, { -1, 52, 1 }, { -1, 53, 1 }, { -1, 57, 1 }, { -1, 58, 1 }, { -1, 59, 1 }, { -1, 63, 1 }, { -1, 64, 1 }, { -1, 65, 1 }, { -1, 69, 1 }, { -1, 70, 1 }, { 1, 0, 1 }, { 1, 30, 1 }, { 10, 0, 1 }, { 10, 36, 1 }, { 15, 0, 1 }, { 15, 42, 1 }, { 20, 0, 1 }, { 20, 48, 1 }, { 25, 0, 1 }, { 25, 54, 1 }, { 30, 0, 1 }, { 30, 60, 1 }, { 35, 0, 1 }, { 35, 66, 1 }, { -1, 32, 2 }, { -1, 38, 3 }, { -1, 44, 4 }, { -1, 50, 5 }, { -1, 56, 6 }, { -1, 62, 7 }, { 2, -1, 8 }, { 2, 17, 8 }, { 2, 18, 8 }, { 2, 25, 8 }, { 2, 77, 8 }, { 3, 67, 8 }, { 4, 1, 8 }, { 4, 9, 8 }, { 6, 67, 8 }, { 7, 1, 8 }, { 7, 9, 8 }, { 8, -1, 8 }, { 8, 18, 8 }, { 8, 25, 8 }, { 8, 77, 8 }, { 11, 67, 8 }, { 12, 1, 8 }, { 12, 9, 8 }, { 13, -1, 8 }, { 13, 18, 8 }, { 13, 25, 8 }, { 13, 77, 8 }, { 16, 67, 8 }, { 17, 1, 8 }, { 17, 9, 8 }, { 18, -1, 8 }, { 18, 18, 8 }, { 18, 25, 8 }, { 18, 77, 8 }, { 21, 67, 8 }, { 22, 1, 8 }, { 22, 9, 8 }, { 23, -1, 8 }, { 23, 18, 8 }, { 23, 25, 8 }, { 23, 77, 8 }, { 26, 67, 8 }, { 27, 1, 8 }, { 27, 9, 8 }, { 28, -1, 8 }, { 28, 18, 8 }, { 28, 25, 8 }, { 28, 77, 8 }, { 31, 67, 8 }, { 3 2, 1, 8 }, { 32, 9, 8 }, { 33, -1, 8 }, { 33, 18, 8 }, { 33, 25, 8 }, { 33, 77, 8 }, { -1, -1, 9 }, { -1, 10, 9 }, { -1, 18, 9 }, { -1, 19, 9 }, { -1, 20, 9 }, { -1, 21, 9 }, { -1, 22, 9 }, { -1, 23, 9 }, { -1, 24, 9 }, { -1, 26, 9 }, { -1, 68, 9 }, { -1, 71, 9 }, { -1, 72, 9 }, { -1, 73, 9 }, { -1, 74, 9 }, { -1, 75, 9 }, { -1, 76, 9 }, { -1, 78, 9 }, { -1, 79, 9 }, { -1, 80, 9 }, { -1, 81, 9 }, { -1, 82, 9 }, { -1, 83, 9 }, { -1, 84, 9 }, { -1, -1, 10 }, { -1, 11, 10 }, { -1, 31, 10 }, { -1, -1, 11 }, { -1, 12, 11 }, { -1, 37, 11 }, { -1, -1, 12 }, { -1, 13, 12 }, { -1, 43, 12 }, { -1, -1, 13 }, { -1, 14, 13 }, { -1, 49, 13 }, { -1, -1, 14 }, { -1, 15, 14 }, { -1, 55, 14 }, { -1, -1, 15 }, { -1, 16, 15 }, { -1, 61, 15 } }; + +constexpr TableStyleElement aTableStyleElements[] = { { ScTableStyleElement::FirstColumnStripe, 0 }, { ScTableStyleElement::SecondColumnStripe, 0 }, { ScTableStyleElement::FirstColumnStripe, 1 }, { ScTableStyleElement::SecondColumnStripe, 1 }, { ScTableStyleElement::FirstColumnStripe, 2 }, { ScTableStyleElement::SecondColumnStripe, 2 }, { ScTableStyleElement::FirstColumnStripe, 3 }, { ScTableStyleElement::SecondColumnStripe, 3 }, { ScTableStyleElement::FirstColumnStripe, 4 }, { ScTableStyleElement::SecondColumnStripe, 4 }, { ScTableStyleElement::FirstColumnStripe, 5 }, { ScTableStyleElement::SecondColumnStripe, 5 }, { ScTableStyleElement::FirstColumnStripe, 6 }, { ScTableStyleElement::SecondColumnStripe, 6 }, { ScTableStyleElement::FirstRowStripe, 7 }, { ScTableStyleElement::SecondRowStripe, 7 }, { ScTableStyleElement::FirstRowStripe, 8 }, { ScTableStyleElement::SecondRowStripe, 8 }, { ScTableStyleElement::FirstRowStripe, 9 }, { ScTableStyleElement::SecondRowStripe, 9 }, { ScTableSt yleElement::FirstRowStripe, 10 }, { ScTableStyleElement::SecondRowStripe, 10 }, { ScTableStyleElement::FirstRowStripe, 11 }, { ScTableStyleElement::SecondRowStripe, 11 }, { ScTableStyleElement::FirstRowStripe, 12 }, { ScTableStyleElement::SecondRowStripe, 12 }, { ScTableStyleElement::FirstRowStripe, 13 }, { ScTableStyleElement::SecondRowStripe, 13 }, { ScTableStyleElement::TotalRow, 14 }, { ScTableStyleElement::FirstColumnStripe, 15 }, { ScTableStyleElement::FirstRowStripe, 15 }, { ScTableStyleElement::WholeTable, 16 }, { ScTableStyleElement::FirstColumnStripe, 16 }, { ScTableStyleElement::FirstRowStripe, 16 }, { ScTableStyleElement::FirstColumnStripe, 17 }, { ScTableStyleElement::FirstRowStripe, 17 }, { ScTableStyleElement::FirstColumnStripe, 18 }, { ScTableStyleElement::FirstRowStripe, 18 }, { ScTableStyleElement::FirstColumnStripe, 19 }, { ScTableStyleElement::FirstRowStripe, 19 }, { ScTableStyleElement::WholeTable, 20 }, { ScTableStyleElement::FirstColumnStripe, 20 }, { ScTableS tyleElement::FirstRowStripe, 20 }, { ScTableStyleElement::FirstColumnStripe, 21 }, { ScTableStyleElement::FirstRowStripe, 21 }, { ScTableStyleElement::FirstColumnStripe, 22 }, { ScTableStyleElement::FirstRowStripe, 22 }, { ScTableStyleElement::FirstColumnStripe, 23 }, { ScTableStyleElement::FirstRowStripe, 23 }, { ScTableStyleElement::FirstColumnStripe, 24 }, { ScTableStyleElement::FirstRowStripe, 24 }, { ScTableStyleElement::FirstColumnStripe, 25 }, { ScTableStyleElement::FirstRowStripe, 25 }, { ScTableStyleElement::WholeTable, 26 }, { ScTableStyleElement::FirstColumnStripe, 26 }, { ScTableStyleElement::FirstRowStripe, 26 }, { ScTableStyleElement::FirstColumnStripe, 27 }, { ScTableStyleElement::FirstRowStripe, 27 }, { ScTableStyleElement::FirstColumnStripe, 28 }, { ScTableStyleElement::FirstRowStripe, 28 }, { ScTableStyleElement::FirstColumnStripe, 29 }, { ScTableStyleElement::FirstRowStripe, 29 }, { ScTableStyleElement::FirstColumnStripe, 30 }, { ScTableStyleElement::FirstRowStrip e, 30 }, { ScTableStyleElement::FirstColumnStripe, 31 }, { ScTableStyleElement::FirstRowStripe, 31 }, { ScTableStyleElement::WholeTable, 32 }, { ScTableStyleElement::FirstColumnStripe, 32 }, { ScTableStyleElement::FirstRowStripe, 32 }, { ScTableStyleElement::FirstColumnStripe, 33 }, { ScTableStyleElement::FirstRowStripe, 33 }, { ScTableStyleElement::FirstColumnStripe, 34 }, { ScTableStyleElement::FirstRowStripe, 34 }, { ScTableStyleElement::FirstColumnStripe, 35 }, { ScTableStyleElement::FirstRowStripe, 35 }, { ScTableStyleElement::HeaderRow, 36 }, { ScTableStyleElement::WholeTable, 37 }, { ScTableStyleElement::WholeTable, 38 }, { ScTableStyleElement::WholeTable, 39 }, { ScTableStyleElement::HeaderRow, 39 }, { ScTableStyleElement::WholeTable, 40 }, { ScTableStyleElement::WholeTable, 41 }, { ScTableStyleElement::HeaderRow, 41 }, { ScTableStyleElement::WholeTable, 42 }, { ScTableStyleElement::WholeTable, 43 }, { ScTableStyleElement::HeaderRow, 43 }, { ScTableStyleElement::WholeTable, 44 }, { ScTableStyleElement::WholeTable, 45 }, { ScTableStyleElement::WholeTable, 46 }, { ScTableStyleElement::WholeTable, 47 }, { ScTableStyleElement::WholeTable, 48 }, { ScTableStyleElement::WholeTable, 49 }, { ScTableStyleElement::WholeTable, 50 }, { ScTableStyleElement::WholeTable, 51 }, { ScTableStyleElement::WholeTable, 52 }, { ScTableStyleElement::WholeTable, 53 }, { ScTableStyleElement::WholeTable, 54 }, { ScTableStyleElement::WholeTable, 55 }, { ScTableStyleElement::WholeTable, 56 }, { ScTableStyleElement::WholeTable, 57 }, { ScTableStyleElement::WholeTable, 58 }, { ScTableStyleElement::WholeTable, 59 }, { ScTableStyleElement::WholeTable, 60 }, { ScTableStyleElement::WholeTable, 61 }, { ScTableStyleElement::WholeTable, 62 }, { ScTableStyleElement::WholeTable, 63 }, { ScTableStyleElement::WholeTable, 64 }, { ScTableStyleElement::WholeTable, 65 }, { ScTableStyleElement::WholeTable, 66 }, { ScTableStyleElement::WholeTable, 67 }, { ScTableStyleElement::WholeTable, 68 }, { ScTab leStyleElement::WholeTable, 69 }, { ScTableStyleElement::WholeTable, 70 }, { ScTableStyleElement::WholeTable, 71 }, { ScTableStyleElement::WholeTable, 72 }, { ScTableStyleElement::WholeTable, 73 }, { ScTableStyleElement::WholeTable, 74 }, { ScTableStyleElement::WholeTable, 75 }, { ScTableStyleElement::WholeTable, 76 }, { ScTableStyleElement::WholeTable, 77 }, { ScTableStyleElement::WholeTable, 78 }, { ScTableStyleElement::WholeTable, 79 }, { ScTableStyleElement::WholeTable, 80 }, { ScTableStyleElement::WholeTable, 81 }, { ScTableStyleElement::WholeTable, 82 }, { ScTableStyleElement::WholeTable, 83 }, { ScTableStyleElement::WholeTable, 84 }, { ScTableStyleElement::WholeTable, 85 }, { ScTableStyleElement::WholeTable, 86 }, { ScTableStyleElement::WholeTable, 87 }, { ScTableStyleElement::LastColumn, 88 }, { ScTableStyleElement::FirstColumn, 88 }, { ScTableStyleElement::HeaderRow, 88 }, { ScTableStyleElement::HeaderRow, 89 }, { ScTableStyleElement::HeaderRow, 90 }, { ScTableStyleElement: :HeaderRow, 91 }, { ScTableStyleElement::TotalRow, 92 }, { ScTableStyleElement::TotalRow, 93 }, { ScTableStyleElement::FirstColumn, 94 }, { ScTableStyleElement::LastColumn, 95 }, { ScTableStyleElement::TotalRow, 96 }, { ScTableStyleElement::FirstColumn, 97 }, { ScTableStyleElement::LastColumn, 98 }, { ScTableStyleElement::LastColumn, 99 }, { ScTableStyleElement::FirstColumn, 99 }, { ScTableStyleElement::HeaderRow, 99 }, { ScTableStyleElement::HeaderRow, 100 }, { ScTableStyleElement::HeaderRow, 101 }, { ScTableStyleElement::TotalRow, 102 }, { ScTableStyleElement::TotalRow, 103 }, { ScTableStyleElement::FirstColumn, 104 }, { ScTableStyleElement::LastColumn, 105 }, { ScTableStyleElement::LastColumn, 106 }, { ScTableStyleElement::FirstColumn, 106 }, { ScTableStyleElement::HeaderRow, 106 }, { ScTableStyleElement::HeaderRow, 107 }, { ScTableStyleElement::HeaderRow, 108 }, { ScTableStyleElement::TotalRow, 109 }, { ScTableStyleElement::TotalRow, 110 }, { ScTableStyleElement::FirstColumn, 11 1 }, { ScTableStyleElement::LastColumn, 112 }, { ScTableStyleElement::LastColumn, 113 }, { ScTableStyleElement::FirstColumn, 113 }, { ScTableStyleElement::HeaderRow, 113 }, { ScTableStyleElement::HeaderRow, 114 }, { ScTableStyleElement::HeaderRow, 115 }, { ScTableStyleElement::TotalRow, 116 }, { ScTableStyleElement::TotalRow, 117 }, { ScTableStyleElement::FirstColumn, 118 }, { ScTableStyleElement::LastColumn, 119 }, { ScTableStyleElement::LastColumn, 120 }, { ScTableStyleElement::FirstColumn, 120 }, { ScTableStyleElement::HeaderRow, 120 }, { ScTableStyleElement::HeaderRow, 121 }, { ScTableStyleElement::HeaderRow, 122 }, { ScTableStyleElement::TotalRow, 123 }, { ScTableStyleElement::TotalRow, 124 }, { ScTableStyleElement::FirstColumn, 125 }, { ScTableStyleElement::LastColumn, 126 }, { ScTableStyleElement::LastColumn, 127 }, { ScTableStyleElement::FirstColumn, 127 }, { ScTableStyleElement::HeaderRow, 127 }, { ScTableStyleElement::HeaderRow, 128 }, { ScTableStyleElement::HeaderRow, 129 }, { ScTableStyleElement::TotalRow, 130 }, { ScTableStyleElement::TotalRow, 131 }, { ScTableStyleElement::FirstColumn, 132 }, { ScTableStyleElement::LastColumn, 133 }, { ScTableStyleElement::LastColumn, 134 }, { ScTableStyleElement::FirstColumn, 134 }, { ScTableStyleElement::HeaderRow, 134 }, { ScTableStyleElement::HeaderRow, 135 }, { ScTableStyleElement::HeaderRow, 136 }, { ScTableStyleElement::TotalRow, 137 }, { ScTableStyleElement::LastColumn, 138 }, { ScTableStyleElement::FirstColumn, 138 }, { ScTableStyleElement::HeaderRow, 138 }, { ScTableStyleElement::HeaderRow, 139 }, { ScTableStyleElement::HeaderRow, 140 }, { ScTableStyleElement::HeaderRow, 141 }, { ScTableStyleElement::HeaderRow, 142 }, { ScTableStyleElement::HeaderRow, 143 }, { ScTableStyleElement::HeaderRow, 144 }, { ScTableStyleElement::HeaderRow, 145 }, { ScTableStyleElement::HeaderRow, 146 }, { ScTableStyleElement::TotalRow, 147 }, { ScTableStyleElement::TotalRow, 148 }, { ScTableStyleElement::TotalRow, 149 }, { ScTa bleStyleElement::TotalRow, 150 }, { ScTableStyleElement::TotalRow, 151 }, { ScTableStyleElement::TotalRow, 152 }, { ScTableStyleElement::TotalRow, 153 }, { ScTableStyleElement::TotalRow, 154 }, { ScTableStyleElement::TotalRow, 155 }, { ScTableStyleElement::TotalRow, 156 }, { ScTableStyleElement::TotalRow, 157 }, { ScTableStyleElement::TotalRow, 158 }, { ScTableStyleElement::TotalRow, 159 }, { ScTableStyleElement::TotalRow, 160 }, { ScTableStyleElement::TotalRow, 161 }, { ScTableStyleElement::LastColumn, 162 }, { ScTableStyleElement::FirstColumn, 162 }, { ScTableStyleElement::HeaderRow, 163 }, { ScTableStyleElement::TotalRow, 164 }, { ScTableStyleElement::LastColumn, 165 }, { ScTableStyleElement::FirstColumn, 165 }, { ScTableStyleElement::HeaderRow, 166 }, { ScTableStyleElement::TotalRow, 167 }, { ScTableStyleElement::LastColumn, 168 }, { ScTableStyleElement::FirstColumn, 168 }, { ScTableStyleElement::HeaderRow, 169 }, { ScTableStyleElement::TotalRow, 170 }, { ScTableStyleElement::La stColumn, 171 }, { ScTableStyleElement::FirstColumn, 171 }, { ScTableStyleElement::HeaderRow, 172 }, { ScTableStyleElement::TotalRow, 173 }, { ScTableStyleElement::LastColumn, 174 }, { ScTableStyleElement::FirstColumn, 174 }, { ScTableStyleElement::HeaderRow, 175 }, { ScTableStyleElement::TotalRow, 176 }, { ScTableStyleElement::LastColumn, 177 }, { ScTableStyleElement::FirstColumn, 177 }, { ScTableStyleElement::HeaderRow, 178 }, { ScTableStyleElement::TotalRow, 179 } }; + +constexpr TableStyle aTableStyles[] = { { "TableStyleDark1", 7, { 76, 133, 137, 138, 139, 35, 34 } }, { "TableStyleDark10", 7, { 53, 82, 213, 195, 194, 52, 51 } }, { "TableStyleDark11", 7, { 66, 85, 213, 195, 194, 65, 64 } }, { "TableStyleDark2", 7, { 77, 133, 140, 141, 142, 37, 36 } }, { "TableStyleDark3", 7, { 78, 133, 149, 150, 151, 44, 43 } }, { "TableStyleDark4", 7, { 80, 133, 158, 159, 160, 50, 49 } }, { "TableStyleDark5", 7, { 81, 133, 167, 168, 169, 57, 56 } }, { "TableStyleDark6", 7, { 83, 133, 176, 177, 178, 63, 62 } }, { "TableStyleDark7", 7, { 84, 133, 185, 186, 187, 70, 69 } }, { "TableStyleDark8", 7, { 31, 75, 213, 195, 194, 30, 29 } }, { "TableStyleDark9 2", 7, { 40, 79, 213, 195, 194, 39, 38 } }, { "TableStyleLight1", 7, { 86, 197, 205, 195, 194, 33, 32 } }, { "TableStyleLight10", 9, { 93, 154, 215, 195, 194, 18, 19, 4, 5 } }, { "TableStyleLight11", 9, { 96, 163, 216, 195, 194, 20, 21, 6, 7 } }, { "TableStyleLight12", 9, { 99, 172, 217, 195, 194, 22, 23, 8, 9 } }, { "TableStyleLight13", 9, { 102, 181, 218, 195, 194, 24, 25, 10, 11 } }, { "TableStyleLight14 ", 9, { 105, 190, 219, 195, 194, 26, 27, 12, 13 } }, { "TableStyleLight15", 7, { 89, 198, 213, 195, 194, 33, 32 } }, { "TableStyleLight16", 7, { 91, 199, 214, 195, 194, 42, 41 } }, { "TableStyleLight17", 7, { 94, 200, 215, 195, 194, 48, 47 } }, { "TableStyleLight18", 7, { 97, 201, 216, 195, 194, 55, 54 } }, { "TableStyleLight19", 7, { 100, 202, 217, 195, 194, 61, 60 } }, { "TableStyleLight2", 7, { 124, 222, 223, 221, 220, 42, 41 } }, { "TableStyleLight20", 7, { 103, 203, 218, 195, 194, 68, 67 } }, { "TableStyleLight21", 7, { 106, 204, 219, 195, 194, 74, 73 } }, { "TableStyleLight3", 7, { 125, 226, 227, 225, 224, 48, 47 } }, { "TableStyleLight4", 7, { 126, 230, 231, 229, 228, 55, 54 } }, { "TableStyleLight5", 7, { 127, 234, 235, 233, 232, 61, 60 } }, { "TableStyleLight6", 7, { 128, 238, 239, 237, 236, 68, 67 } }, { "TableStyleLight7", 7, { 129, 242, 243, 241, 240, 74, 73 } }, { "TableStyleLigh t8", 9, { 87, 132, 213, 195, 194, 14, 15, 0, 1 } }, { "TableStyleLight9", 9, { 90, 145, 214, 195, 194, 16, 17, 2, 3 } }, { "TableStyleMedium1", 7, { 88, 132, 213, 195, 194, 33, 32 } }, { "TableStyleMedium10", 7, { 114, 156, 157, 153, 152, 46, 45 } }, { "TableStyleMedium11", 7, { 116, 165, 166, 162, 161, 52, 51 } }, { "TableStyleMedium12", 7, { 118, 174, 175, 171, 170, 59, 58 } }, { "TableStyleMedium13", 7, { 120, 183, 184, 180, 179, 65, 64 } }, { "TableStyleMedium14", 7, { 122, 192, 193, 189, 188, 72, 71 } }, { "TableStyleMedium15", 7, { 109, 134, 28, 131, 130, 33, 32 } }, { "TableStyleMedium16", 7, { 108, 146, 28, 144, 143, 33, 32 } }, { "TableStyleMedium17", 7, { 108, 155, 28, 153, 152, 33, 32 } }, { "TableStyleMedium18", 7, { 108, 164, 28, 162, 161, 33, 32 } }, { "TableStyleMedium19", 7, { 108, 173, 28, 171, 170, 33, 32 } }, { "TableStyleMedium2", 7, { 92, 145, 214, 195, 194, 42, 41 } }, { "TableStyleMedium20", 7, { 108, 182, 28, 180, 179, 33, 32 } }, { "TableStyleMedium21", 7, { 108, 191, 28, 189, 188, 33, 32 } }, { "TableStyleMedium22", 7, { 111, 196, 206, 195, 194, 30, 29 } }, { "TableStyleMedium23", 7, { 113, 196, 207, 195, 194, 39, 38 } }, { "TableStyleMedium24", 7, { 115, 196, 208, 195, 194, 46, 45 } }, { "TableStyleMedium25", 7, { 117, 196, 209, 195, 194, 52, 51 } }, { "TableStyleMedium26", 7, { 119, 196, 210, 195, 194, 59, 58 } }, { "TableStyleMedium27", 7, { 121, 196, 211, 195, 194, 65, 64 } }, { "TableStyleMedium28", 7, { 123, 196, 212, 195, 194, 72, 71 } }, { "TableStyleMedium3", 7, { 95, 154, 215, 195, 194, 48, 47 } }, { "TableStyleMedium4", 7, { 98, 163, 216, 195, 194, 55, 54 } }, { "TableStyleMedium5", 7, { 101, 172, 217, 195, 194, 61, 60 } }, { "TableStyleMedium6", 7, { 104, 181, 218, 195, 194, 68, 67 } }, { "TableStyleMedium7", 7, { 107, 190, 219, 195, 194, 74, 73 } }, { "TableStyleMedium8", 7, { 110, 135, 136, 131, 130, 30, 29 } }, { "TableStyleMedium9", 7, { 112, 147, 148, 144, 143, 39, 38 } } }; + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ \ No newline at end of file diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx index 15547d4b4e22..afc9dfcdd889 100644 --- a/sc/source/filter/oox/stylesbuffer.cxx +++ b/sc/source/filter/oox/stylesbuffer.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <memory> #include <stylesbuffer.hxx> #include <patterncache.hxx> @@ -87,6 +88,7 @@ #include <stlsheet.hxx> #include <biffhelper.hxx> #include <docuno.hxx> +#include <tablestyle.hxx> namespace oox::xls { @@ -1580,6 +1582,16 @@ void Border::importDxfBorder( sal_Int32 nElement, SequenceInputStream& rStrm ) } } +void Border::setBorderElement( sal_Int32 nElement, const XlsColor& rColor, sal_Int32 nStyle) +{ + if( BorderLineModel* pBorderLine = getBorderLine( nElement ) ) + { + pBorderLine->maColor = rColor; + pBorderLine->mnStyle = nStyle; + pBorderLine->mbUsed = true; + } +} + void Border::finalizeImport( bool bRTL ) { if (bRTL) @@ -1944,6 +1956,19 @@ void Fill::importDxfStop( SequenceInputStream& rStrm ) mxGradientModel->readGradientStop( rStrm, true ); } +void Fill::setFillColors(const XlsColor& rFgColor, const XlsColor& rBgColor) +{ + mxPatternModel = std::make_shared<PatternFillModel>(true); + mxPatternModel->mnPattern = XML_solid; + mxPatternModel->mbPatternUsed = true; + + mxPatternModel->maPatternColor = rFgColor; + mxPatternModel->mbPattColorUsed = true; + + mxPatternModel->maFillColor = rBgColor; + mxPatternModel->mbFillColorUsed = true; +} + void Fill::finalizeImport() { const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper(); @@ -2429,6 +2454,21 @@ ProtectionRef const & Dxf::createProtection( bool bAlwaysNew ) return mxProtection; } +void Dxf::setFill(FillRef xFill) +{ + mxFill = xFill; +} + +void Dxf::setBorder(BorderRef xBorder) +{ + mxBorder = xBorder; +} + +void Dxf::setFont(FontRef xFont) +{ + mxFont = xFont; +} + void Dxf::importNumFmt( const AttributeList& rAttribs ) { // don't propagate number formats defined in Dxf entries @@ -2528,6 +2568,109 @@ void Dxf::fillToItemSet( SfxItemSet& rSet ) const mxFill->fillToItemSet(rSet); } +TableStyleElementInfo::TableStyleElementInfo(): + mnDxfID(-1), + mnStripeCount(1) +{ +} + +TableStyle::TableStyle(const WorkbookHelper& rHelper, bool bDefaultOOXMLStyle): + WorkbookHelper( rHelper ), + mbDefaultOOXMLStyle(bDefaultOOXMLStyle) +{ +} + +void TableStyle::setName(const OUString& rName) +{ + maName = rName; +} + +void TableStyle::setUIName(const OUString& rName) +{ + maUIName = rName; +} + +void TableStyle::importTableStyleElement(const AttributeList& rAttribs) +{ + TableStyleElementInfo aInfo; + aInfo.mnDxfID = rAttribs.getInteger(XML_dxfId, -1); + OUString aTableStyleElementName = rAttribs.getString(XML_type, OUString()); + static const std::unordered_map<OUString, ScTableStyleElement> aTableStyleElementMap + = { { "wholeTable", ScTableStyleElement::WholeTable }, + { "firstColumnStripe", ScTableStyleElement::FirstColumnStripe }, + { "secondColumnStripe", ScTableStyleElement::SecondColumnStripe }, + { "firstRowStripe", ScTableStyleElement::FirstRowStripe }, + { "secondRowStripe", ScTableStyleElement::SecondRowStripe }, + { "firstColumn", ScTableStyleElement::FirstColumn }, + { "lastColumn", ScTableStyleElement::LastColumn }, + { "headerRow", ScTableStyleElement::HeaderRow }, + { "totalRow", ScTableStyleElement::TotalRow }, + { "firstHeaderCell", ScTableStyleElement::FirstHeaderCell }, + { "lastHeaderCell", ScTableStyleElement::LastHeaderCell } + }; + auto aElementItr = aTableStyleElementMap.find(aTableStyleElementName); + if (aElementItr == aTableStyleElementMap.end()) + { + SAL_WARN("sc", "TableStyle::importTableStyleElement - unknown Table Style Element"); + return; + } + + ScTableStyleElement eElement = aElementItr->second; + aInfo.mnStripeCount = rAttribs.getInteger(XML_size, 1); + + maTableStyleElements.insert({eElement, aInfo}); +} + +void TableStyle::setTableStyleElement(ScTableStyleElement eElement, sal_Int32 nDxfId) +{ + TableStyleElementInfo aInfo; + aInfo.mnDxfID = nDxfId; + maTableStyleElements.insert({eElement, aInfo}); +} + +void TableStyle::finalizeImport(const DxfVector& rDxfs) +{ + ::ScDocument& rDoc = getScDocument(); + ScTableStyles& rStyles = rDoc.GetTableStyles(); + std::unique_ptr<ScTableStyle> pTableStyle = std::make_unique<ScTableStyle>(maName, maUIName); + pTableStyle->SetOOXMLDefault(mbDefaultOOXMLStyle); + for (const auto& aTableStyleElementInfo : maTableStyleElements) + { + if (aTableStyleElementInfo.second.mnDxfID < 0 || aTableStyleElementInfo.second.mnDxfID >= sal_Int32(rDxfs.size())) + { + // TODO: report a warning message + continue; + } + ScTableStyleElement eElement = aTableStyleElementInfo.first; + DxfRef xDxf = rDxfs.get(aTableStyleElementInfo.second.mnDxfID); + std::unique_ptr<ScPatternAttr> pPattern = std::make_unique<ScPatternAttr>(rDoc.getCellAttributeHelper()); + xDxf->fillToItemSet(pPattern->GetItemSetWritable()); + + pTableStyle->SetPattern(eElement, std::move(pPattern)); + sal_Int32 nStripeCount = aTableStyleElementInfo.second.mnStripeCount; + if (nStripeCount <= 1) + continue; + + switch (eElement) { + case ScTableStyleElement::FirstRowStripe: + pTableStyle->SetRowStripeSize(nStripeCount, -1); + break; + case ScTableStyleElement::SecondRowStripe: + pTableStyle->SetRowStripeSize(-1, nStripeCount); + break; + case ScTableStyleElement::FirstColumnStripe: + pTableStyle->SetColStripeSize(nStripeCount, -1); + break; + case ScTableStyleElement::SecondColumnStripe: + pTableStyle->SetRowStripeSize(-1, nStripeCount); + break; + default: + SAL_WARN("sc", "the stripe count should only be set for row and column stripe elements"); + } + } + rStyles.AddTableStyle(std::move(pTableStyle)); +} + namespace { const char* const sppcStyleNames[] = @@ -2942,6 +3085,13 @@ DxfRef StylesBuffer::createDxf() return xDxf; } +TableStyleRef StylesBuffer::createTableStyle() +{ + TableStyleRef xTableStyle = std::make_shared<TableStyle>(*this, false); + maTableStyles.push_back(xTableStyle); + return xTableStyle; +} + DxfRef StylesBuffer::createExtDxf() { DxfRef xDxf = std::make_shared<Dxf>( *this ); @@ -2999,6 +3149,7 @@ void StylesBuffer::finalizeImport() maCellStyles.finalizeImport(); // differential formatting (for conditional formatting) maDxfs.forEachMem( &Dxf::finalizeImport ); + maTableStyles.forEachMem( &TableStyle::finalizeImport, maDxfs ); } ::Color StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const diff --git a/sc/source/filter/oox/stylesfragment.cxx b/sc/source/filter/oox/stylesfragment.cxx index 1d20b98519ff..c738016029c3 100644 --- a/sc/source/filter/oox/stylesfragment.cxx +++ b/sc/source/filter/oox/stylesfragment.cxx @@ -170,6 +170,34 @@ ContextHandlerRef DxfContext::onCreateContext( sal_Int32 nElement, const Attribu return nullptr; } +ContextHandlerRef TableStyleContext::onCreateContext( sal_Int32 nElement, const AttributeList& ) +{ + switch( getCurrentElement() ) + { + case XLS_TOKEN( tableStyle ): + switch( nElement ) + { + case XLS_TOKEN( tableStyleElement ): return this; + } + break; + } + return nullptr; +} + +void TableStyleContext::onStartElement( const AttributeList& rAttribs ) +{ + sal_Int32 nCurrentElement = getCurrentElement(); + switch(nCurrentElement) + { + case XLS_TOKEN(tableStyle): + mxTableStyle->setName(rAttribs.getString( XML_name, OUString())); + break; + case XLS_TOKEN(tableStyleElement): + mxTableStyle->importTableStyleElement(rAttribs); + break; + } +} + StylesFragment::StylesFragment( const WorkbookHelper& rHelper, const OUString& rFragmentPath ) : WorkbookFragmentBase( rHelper, rFragmentPath ) { @@ -194,6 +222,7 @@ ContextHandlerRef StylesFragment::onCreateContext( sal_Int32 nElement, const Att case XLS_TOKEN( cellXfs ): case XLS_TOKEN( cellStyleXfs ): case XLS_TOKEN( dxfs ): + case XLS_TOKEN( tableStyles ): case XLS_TOKEN( cellStyles ): return this; } break; @@ -222,6 +251,9 @@ ContextHandlerRef StylesFragment::onCreateContext( sal_Int32 nElement, const Att case XLS_TOKEN( dxfs ): if( nElement == XLS_TOKEN( dxf ) ) return new DxfContext( *this, getStyles().createDxf() ); break; + case XLS_TOKEN( tableStyles ): + if( nElement == XLS_TOKEN( tableStyle ) && rAttribs.getBool(XML_table, true)) return new TableStyleContext( *this, getStyles().createTableStyle() ); + break; case XLS_TOKEN( cellStyles ): if( nElement == XLS_TOKEN( cellStyle ) ) getStyles().importCellStyle( rAttribs ); break; diff --git a/sc/source/filter/oox/tablebuffer.cxx b/sc/source/filter/oox/tablebuffer.cxx index 2ac7e24e8400..f0e54ae8b34c 100644 --- a/sc/source/filter/oox/tablebuffer.cxx +++ b/sc/source/filter/oox/tablebuffer.cxx @@ -39,6 +39,14 @@ namespace oox::xls { using namespace ::com::sun::star::sheet; using namespace ::com::sun::star::uno; +TableStyleInfo::TableStyleInfo(): + mbShowFirstColumn(true), + mbShowLastColumn(true), + mbShowRowStripes(true), + mbShowColStripes(true) +{ +} + TableModel::TableModel() : mnId( -1 ), mnType( XML_worksheet ), @@ -85,6 +93,18 @@ void Table::importTable( SequenceInputStream& rStrm, sal_Int16 nSheet ) maModel.mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID ); } +void Table::importTableStyleInfo(const AttributeList& rAttribs) +{ + TableStyleInfo aInfo; + aInfo.maStyleName = rAttribs.getString(XML_name, OUString()); + aInfo.mbShowFirstColumn = rAttribs.getBool(XML_showFirstColumn, true); + aInfo.mbShowLastColumn = rAttribs.getBool(XML_showLastColumn, true); + aInfo.mbShowRowStripes = rAttribs.getBool(XML_showRowStripes, true); + aInfo.mbShowColStripes = rAttribs.getBool(XML_showColumnStripes, true); + + maStyleInfo = aInfo; +} + void Table::finalizeImport() { // Create database range. Note that Excel 2007 and later names database @@ -143,6 +163,15 @@ void Table::finalizeImport() // get formula token index of the database range if( !(xDatabaseRange->getPropertyValue(u"TokenIndex"_ustr) >>= mnTokenIndex)) mnTokenIndex = -1; + + if(maStyleInfo && maStyleInfo->maStyleName) + { + xDatabaseRange->setPropertyValue( u"TableStyleName"_ustr, css::uno::Any(*maStyleInfo->maStyleName)); + xDatabaseRange->setPropertyValue( u"UseRowStripes"_ustr, css::uno::Any(maStyleInfo->mbShowRowStripes)); + xDatabaseRange->setPropertyValue( u"UseColStripes"_ustr, css::uno::Any(maStyleInfo->mbShowColStripes)); + xDatabaseRange->setPropertyValue( u"UseFirstColumnFormatting"_ustr, css::uno::Any(maStyleInfo->mbShowFirstColumn)); + xDatabaseRange->setPropertyValue( u"UseLastColumnFormatting"_ustr, css::uno::Any(maStyleInfo->mbShowLastColumn)); + } } catch( Exception& ) { diff --git a/sc/source/filter/oox/tablefragment.cxx b/sc/source/filter/oox/tablefragment.cxx index 99f3ede7a0d8..1ad5380c2adb 100644 --- a/sc/source/filter/oox/tablefragment.cxx +++ b/sc/source/filter/oox/tablefragment.cxx @@ -53,6 +53,8 @@ ContextHandlerRef TableFragment::onCreateContext( sal_Int32 nElement, const Attr return new AutoFilterContext( *this, mrTable.createAutoFilter() ); case XLS_TOKEN( tableColumns ): return new TableColumnsContext( *this, mrTable.createTableColumns() ); + case XLS_TOKEN( tableStyleInfo ): + mrTable.importTableStyleInfo(rAttribs); } break; } diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx index 14db1335349d..ea52212cb2af 100644 --- a/sc/source/filter/oox/workbookfragment.cxx +++ b/sc/source/filter/oox/workbookfragment.cxx @@ -58,6 +58,7 @@ #include <scresid.hxx> #include <scmod.hxx> #include <formulaopt.hxx> +#include <defaulttablestyles.hxx> #include <vcl/svapp.hxx> #include <vcl/timer.hxx> @@ -375,6 +376,9 @@ void WorkbookFragment::finalizeImport() importOoxFragment(new ThemeFragmentHandler(getFilter(), aThemeFragmentPath, rOoxTheme, *pTheme)); xGlobalSegment->setPosition( 0.25 ); + DefaultOOXMLTableStyles aTableStyles(*this); + aTableStyles.importTableStyles(); + // read the styles substream (requires finalized theme buffer) OUString aStylesFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( u"styles" ); if( !aStylesFragmentPath.isEmpty() ) diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx index e182e8622a7e..27c6780621ff 100644 --- a/sc/source/ui/unoobj/datauno.cxx +++ b/sc/source/ui/unoobj/datauno.cxx @@ -128,6 +128,11 @@ static std::span<const SfxItemPropertyMapEntry> lcl_GetDBRangePropertyMap() { SC_UNONAME_USEFLTCRT,0, cppu::UnoType<bool>::get(), 0, 0}, { SC_UNONAME_TOTALSROW,0, cppu::UnoType<bool>::get(), 0, 0}, { SC_UNONAME_CONTHDR ,0, cppu::UnoType<bool>::get(), 0, 0}, + { SC_UNONAME_TABLE_STYLENAME,0, cppu::UnoType<OUString>::get(), 0, 0}, + { SC_UNONAME_ROW_STRIPES,0, cppu::UnoType<bool>::get(), 0, 0}, + { SC_UNONAME_COL_STRIPES,0, cppu::UnoType<bool>::get(), 0, 0}, + { SC_UNONAME_FIRST_COL,0, cppu::UnoType<bool>::get(), 0, 0}, + { SC_UNONAME_LAST_COL,0, cppu::UnoType<bool>::get(), 0, 0}, }; return aDBRangePropertyMap_Impl; } @@ -1984,6 +1989,40 @@ void SAL_CALL ScDatabaseRangeObj::setPropertyValue( aValue >>= aStrVal; aNewData.SetTableType(aStrVal); } + else if (aPropertyName == SC_UNONAME_TABLE_STYLENAME) + { + OUString aStyleName; -e ... etc. - the rest is truncated
