/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish * street, Riga, Latvia, EU, LV-1050. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ #pragma once #include "Styles.h" #include "../../XlsbFormat/Xlsb.h" #include "../XlsxFlat.h" #include "Borders.h" #include "Fills.h" #include "Fonts.h" #include "NumFmts.h" #include "Xfs.h" #include "CellStyles.h" #include "rPr.h" #include "Colors.h" #include "dxf.h" #include "TableStyles.h" #include "../../DocxFormat/Drawing/DrawingExt.h" #include "../../Common/SimpleTypes_Shared.h" #include "../ComplexTypes_Spreadsheet.h" #include "../../XlsbFormat/StylesStream.h" #include "../../XlsbFormat/Biff12_unions/FMTS.h" #include "../../XlsbFormat/Biff12_unions/FONTS.h" #include "../../XlsbFormat/Biff12_unions/FILLS.h" #include "../../XlsbFormat/Biff12_unions/BORDERS.h" #include "../../XlsbFormat/Biff12_unions/CELLSTYLEXFS.h" #include "../../XlsbFormat/Biff12_unions/CELLXFS.h" #include "../../XlsbFormat/Biff12_unions/STYLES.h" #include "../../XlsbFormat/Biff12_unions/DXFS.h" #include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/DXF.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.h" namespace OOX { namespace Spreadsheet { CStyle2003::CStyle2003(OOX::Document* pMain) : WritingElement(pMain) { } CStyle2003::~CStyle2003() { } void CStyle2003::fromXML(XmlUtils::CXmlNode& node) { } std::wstring CStyle2003::toXML() const { return L""; } void CStyle2003::toXML(NSStringUtils::CStringBuilder& writer) const { } EElementType CStyle2003::getType () const { return et_x_Style2003; } void CStyle2003::fromXML(XmlUtils::CXmlLiteReader& oReader) { ReadAttributes(oReader); if (oReader.IsEmptyNode()) return; int nDocumentDepth = oReader.GetDepth(); std::wstring sName; while (oReader.ReadNextSiblingNode(nDocumentDepth)) { sName = XmlUtils::GetNameNoNS(oReader.GetName()); if (L"Borders" == sName) { m_oBorder = oReader; if (m_oBorder.IsInit()) { bStyleContinuous = m_oBorder->bBorderContinuous; // todooo - one border exclusive } } else if (L"Alignment" == sName) m_oAligment = oReader; else if (L"Font" == sName) m_oFont = oReader; else if (L"Interior" == sName) m_oFill = oReader; else if (L"NumberFormat" == sName) m_oNumFmt = oReader; } } void CStyle2003::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"ss:ID", m_sId) WritingElement_ReadAttributes_Read_if(oReader, L"ss:Name", m_sName) WritingElement_ReadAttributes_Read_if(oReader, L"ss:Parent", m_sParentId) WritingElement_ReadAttributes_End(oReader) } //---------------------------------------------------------------------------------------------------------------------- CStyles::CStyles(OOX::Document* pMain) : OOX::File(pMain), OOX::IFileContainer(pMain), WritingElement(pMain) { m_bSpreadsheets = true; CXlsx* xlsx = dynamic_cast(File::m_pMainDocument); if (xlsx) { xlsx->m_pStyles = this; } } CStyles::CStyles(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain), OOX::IFileContainer(pMain), WritingElement(pMain) { m_bSpreadsheets = true; CXlsx* xlsx = dynamic_cast(File::m_pMainDocument); if (xlsx) { xlsx->m_pStyles = this; } read(oRootPath, oPath); } CStyles::~CStyles() { for (size_t i = 0; i < m_arrStyles2003.size(); i++) { if (m_arrStyles2003[i]) delete m_arrStyles2003[i]; m_arrStyles2003[i] = NULL; } m_arrStyles2003.clear(); m_mapStyles2003.clear(); } void CStyles::readBin(const CPath& oPath) { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); if (xlsb) { XLSB::StylesStreamPtr stylesStream(new XLSB::StylesStream); xlsb->ReadBin(oPath, stylesStream.get()); if (stylesStream != nullptr) { if (stylesStream->m_FMTS != nullptr) m_oNumFmts = static_cast(stylesStream->m_FMTS.get())->m_arBrtFmt; if (stylesStream->m_FONTS != nullptr) m_oFonts = static_cast(stylesStream->m_FONTS.get())->m_arBrtFont; if (stylesStream->m_FILLS != nullptr) m_oFills = static_cast(stylesStream->m_FILLS.get())->m_arBrtFill; if (stylesStream->m_BORDERS != nullptr) m_oBorders = static_cast(stylesStream->m_BORDERS.get())->m_arBrtBorder; if (stylesStream->m_CELLSTYLEXFS != nullptr) m_oCellStyleXfs = static_cast(stylesStream->m_CELLSTYLEXFS.get())->m_arBrtXF; if (stylesStream->m_CELLXFS != nullptr) m_oCellXfs = static_cast(stylesStream->m_CELLXFS.get())->m_arBrtXF; if (stylesStream->m_STYLES != nullptr) m_oCellStyles = static_cast(stylesStream->m_STYLES.get())->m_arBrtStyle; if (stylesStream->m_DXFS != nullptr) m_oDxfs = static_cast(stylesStream->m_DXFS.get())->m_aruDXF; if (stylesStream->m_TABLESTYLES != nullptr) m_oTableStyles = stylesStream->m_TABLESTYLES; if (stylesStream->m_COLORPALETTE != nullptr) m_oColors = stylesStream->m_COLORPALETTE; if (stylesStream->m_FRTSTYLESHEET != nullptr) m_oExtLst = stylesStream->m_FRTSTYLESHEET; AfterRead(); } //stylesStream.reset(); } } XLS::BaseObjectPtr CStyles::WriteBin() const { XLSB::StylesStreamPtr stylesStream(new XLSB::StylesStream); XLS::BaseObjectPtr objectPtr(stylesStream); if (m_oNumFmts.IsInit()) stylesStream->m_FMTS = m_oNumFmts->toBin(); if (m_oFonts.IsInit()) stylesStream->m_FONTS = m_oFonts->toBin(); if (m_oFills.IsInit()) stylesStream->m_FILLS = m_oFills->toBin(); if (m_oBorders.IsInit()) stylesStream->m_BORDERS = m_oBorders->toBin(); if (m_oCellStyleXfs.IsInit()) stylesStream->m_CELLSTYLEXFS = m_oCellStyleXfs->toBin(); if (m_oCellXfs.IsInit()) stylesStream->m_CELLXFS = m_oCellXfs->toBin(); if (m_oCellStyles.IsInit()) stylesStream->m_STYLES = m_oCellStyles->toBin(); if (m_oDxfs.IsInit()) stylesStream->m_DXFS = m_oDxfs->toBin(); if (m_oTableStyles.IsInit()) stylesStream->m_TABLESTYLES = m_oTableStyles->toBin(); if (m_oColors.IsInit()) stylesStream->m_COLORPALETTE = m_oColors->toBin(); if (m_oExtLst.IsInit()) stylesStream->m_FRTSTYLESHEET = m_oExtLst->toBinStyles(); return objectPtr; } _UINT16 GetClrIndex(const OOX::Spreadsheet::CColors &colors, const SimpleTypes::Spreadsheet::CHexColor & rgba) { _UINT16 result = 0; if(!colors.m_oIndexedColors.IsInit()) return result; for(auto i : colors.m_oIndexedColors->mapIndexedColors) if(i.second->m_oRgb == rgba) { result = i.first; return result; } return result; } void SetColor(const OOX::Spreadsheet::CColors &colors, nullable color) { if(color.IsInit() && color->m_oRgb.IsInit()) { auto mruColor = new OOX::Spreadsheet::CColor; *mruColor = color.get(); colors.m_oMruColors->m_arrItems.push_back(mruColor); } else if(color.IsInit() && color->m_oIndexed.IsInit()) { if(colors.m_oIndexedColors->mapIndexedColors.find(color->m_oIndexed->GetValue()) == colors.m_oIndexedColors->mapIndexedColors.end()) { auto IndexedColor = new OOX::Spreadsheet::CRgbColor; IndexedColor->m_oRgb.Init(); unsigned char red = 0; unsigned char green = 0; unsigned char alpha = 0; unsigned char blue = 0; colors.m_oIndexedColors->GetDefaultRGBAByIndex(color->m_oIndexed->GetValue(), red, green, blue, alpha); IndexedColor->m_oRgb->Set_A(alpha); IndexedColor->m_oRgb->Set_R(red); IndexedColor->m_oRgb->Set_G(green); IndexedColor->m_oRgb->Set_B(blue); colors.m_oIndexedColors->m_arrItems.push_back(IndexedColor); colors.m_oIndexedColors->mapIndexedColors.emplace(color->m_oIndexed->GetValue(), IndexedColor); } } } void MapColors(const OOX::Spreadsheet::CColors &colors) { for(auto i = 8; i <= 56; i++) { if(colors.m_oIndexedColors->mapIndexedColors.find(i) == colors.m_oIndexedColors->mapIndexedColors.end()) { if(!colors.m_oMruColors->m_arrItems.empty()) { if(GetClrIndex(colors, colors.m_oMruColors->m_arrItems.back()->m_oRgb.get()) == 0) { auto tempClr = colors.m_oMruColors->m_arrItems.back()->m_oRgb.get(); auto IndexedColor = new OOX::Spreadsheet::CRgbColor; IndexedColor->m_oRgb.Init(); IndexedColor->m_oRgb->Set_A(tempClr.Get_A()); IndexedColor->m_oRgb->Set_R(tempClr.Get_R()); IndexedColor->m_oRgb->Set_G(tempClr.Get_G()); IndexedColor->m_oRgb->Set_B(tempClr.Get_B()); colors.m_oIndexedColors->m_arrItems.push_back(IndexedColor); colors.m_oIndexedColors->mapIndexedColors.emplace(i, IndexedColor); } delete colors.m_oMruColors->m_arrItems.back(); colors.m_oMruColors->m_arrItems.pop_back(); } else { auto IndexedColor = new OOX::Spreadsheet::CRgbColor; IndexedColor->m_oRgb.Init(); unsigned char red = 0; unsigned char green = 0; unsigned char alpha = 0; unsigned char blue = 0; colors.m_oIndexedColors->GetDefaultRGBAByIndex(i, red, green, blue, alpha); IndexedColor->m_oRgb->Set_A(alpha); IndexedColor->m_oRgb->Set_R(red); IndexedColor->m_oRgb->Set_G(green); IndexedColor->m_oRgb->Set_B(blue); colors.m_oIndexedColors->m_arrItems.push_back(IndexedColor); colors.m_oIndexedColors->mapIndexedColors.emplace(i, IndexedColor); } } } } void CStyles::toXLS(XLS::BaseObjectPtr globalsStreamPtr) { auto workbookPtr = static_cast(globalsStreamPtr.get()); auto FormatPtr = new XLS::FORMATTING; workbookPtr->m_Formating = XLS::BaseObjectPtr(FormatPtr); auto globalInfo = workbookPtr->global_info_; //prepare colors if(!m_oColors.IsInit()) { m_oColors = OOX::Spreadsheet::CColors(); m_oColors->m_oIndexedColors.Init(); m_oColors->m_oMruColors.Init(); { for(auto i : globalInfo->colors_palette) { nullable tempColor; tempColor.Init(); tempColor->m_oRgb.Init(); tempColor->m_oRgb->FromString(i.second); SetColor(m_oColors.get(), tempColor); } } if (m_oFonts.IsInit()) { for(auto i : m_oFonts->m_arrItems) { SetColor(m_oColors.get(), i->m_oColor); } } if(m_oFills.IsInit()) { for(auto i : m_oFills->m_arrItems) { if(i->m_oPatternFill.IsInit()) { auto pattern = &i->m_oPatternFill; SetColor(m_oColors.get(), (*pattern)->m_oBgColor); SetColor(m_oColors.get(), (*pattern)->m_oFgColor); } } } for(auto i : m_oBorders->m_arrItems) { if(i->m_oTop.IsInit()) { SetColor(m_oColors.get(), i->m_oTop->m_oColor); } if(i->m_oBottom.IsInit()) { SetColor(m_oColors.get(), i->m_oBottom->m_oColor); } if(i->m_oStart.IsInit()) { SetColor(m_oColors.get(), i->m_oStart->m_oColor); } if(i->m_oEnd.IsInit()) { SetColor(m_oColors.get(), i->m_oEnd->m_oColor); } if(i->m_oDiagonal.IsInit()) { SetColor(m_oColors.get(), i->m_oDiagonal->m_oColor); } } MapColors(m_oColors.get()); } FormatPtr->m_Palette = m_oColors->toXLS(); if (m_oFonts.IsInit()) { for(auto i : m_oFonts->m_arrItems) { if(i->m_oColor.IsInit() && i->m_oColor->m_oRgb.IsInit()) { i->m_oColor->m_oIndexed = GetClrIndex(m_oColors.get(), i->m_oColor->m_oRgb.get()); } //finding registred theme clr else if(i->m_oColor.IsInit() && i->m_oColor->m_oThemeColor.IsInit() && globalInfo->colors_palette.find(i->m_oColor->m_oThemeColor->GetValue()) != globalInfo->colors_palette.end()) { auto rgb = globalInfo->colors_palette.find(i->m_oColor->m_oThemeColor->GetValue())->second; SimpleTypes::Spreadsheet::CHexColor hexClr; hexClr.FromString(rgb); i->m_oColor->m_oIndexed = GetClrIndex(m_oColors.get(), hexClr); } } FormatPtr->m_arFonts = m_oFonts->toXLS(); } if (m_oNumFmts.IsInit()) { auto remap = [&](OOX::Spreadsheet::CXfs* xf) { if (xf->m_oNumFmtId.IsInit()) { auto val = xf->m_oNumFmtId->GetValue(); if (val) { auto it = m_oNumFmts->m_mapNumFmtIndex.find(val); if (it != m_oNumFmts->m_mapNumFmtIndex.end()) { xf->m_oNumFmtId = static_cast(it->second + 164); } } } }; for (auto& cellStyleXF : m_oCellStyleXfs->m_arrItems) remap(cellStyleXF); for (auto& cellXF : m_oCellXfs->m_arrItems) remap(cellXF); FormatPtr->m_arFormats = m_oNumFmts->toXLS(); } if(m_oCellStyleXfs.IsInit() || m_oCellXfs.IsInit()) { auto xfs = new XLS::XFS; FormatPtr->m_XFS = XLS::BaseObjectPtr(xfs); if(m_oCellStyleXfs.IsInit()) m_oCellStyleXfs->toXLS(FormatPtr->m_XFS); if(m_oCellXfs.IsInit()) m_oCellXfs->toXLS(FormatPtr->m_XFS); SetFillXLS(FormatPtr->m_XFS, globalsStreamPtr); SetBordersXLS(FormatPtr->m_XFS, globalsStreamPtr); } if(m_oDxfs.IsInit()) { FormatPtr->m_arDXF = m_oDxfs->toXLS(); if(globalInfo != nullptr) { for(auto i : m_oDxfs->m_arrItems) if(i != nullptr) globalInfo->arrUserDxfs.push_back(i->toXML()); } } if (m_oCellStyles.IsInit()) FormatPtr->m_Styles = m_oCellStyles->toXLS(); if(m_oTableStyles.IsInit()) FormatPtr->m_TABLESTYLES = m_oTableStyles->toXLS(); } void CStyles::SetFillXLS(XLS::BaseObjectPtr XFSPtr, XLS::BaseObjectPtr workbookPtr) { if(!m_oFills.IsInit()) return; auto castedWorkbook = static_cast(workbookPtr.get()); auto globalInfo = castedWorkbook->global_info_; auto setFillClr = [](nullable &color, nullable &colors, XLS::GlobalWorkbookInfoPtr globInfo) { if(color.IsInit() && !color->m_oIndexed.IsInit() && color->m_oRgb.IsInit()) color->m_oIndexed = GetClrIndex(colors.get(), color->m_oRgb.get()); else if(color.IsInit() && color->m_oThemeColor.IsInit() && globInfo->colors_palette.find(color->m_oThemeColor->GetValue()) != globInfo->colors_palette.end()) { auto rgb = globInfo->colors_palette.find(color->m_oThemeColor->GetValue())->second; SimpleTypes::Spreadsheet::CHexColor hexClr; hexClr.FromString(rgb); color->m_oIndexed = GetClrIndex(colors.get(), hexClr); } return 0; }; //preparing clr indexes for(auto i : m_oFills->m_arrItems) { if(i->m_oPatternFill.IsInit()) { auto pattern = &i->m_oPatternFill; setFillClr((*pattern)->m_oBgColor, m_oColors, globalInfo); setFillClr((*pattern)->m_oFgColor, m_oColors, globalInfo); } } auto CastedPtr = static_cast(XFSPtr.get()); if(m_oCellStyleXfs.IsInit()) { for(auto i = 0; i < m_oCellStyleXfs->m_arrItems.size(); i++) { if(CastedPtr->m_arCellStyles.size() > i) { if(m_oCellStyleXfs->m_arrItems[i]->m_oFillId.IsInit() && m_oFills->m_arrItems.size() > m_oCellStyleXfs->m_arrItems[i]->m_oFillId->GetValue()) { auto xf = static_cast(CastedPtr->m_arCellStyles[i].get()); auto xfFill = m_oFills->m_arrItems[m_oCellStyleXfs->m_arrItems[i]->m_oFillId->GetValue()]; if(xfFill->m_oPatternFill.IsInit()) { if(xfFill->m_oPatternFill->m_oBgColor.IsInit()) { if(xfFill->m_oPatternFill->m_oBgColor->m_oIndexed.IsInit()) xf->fill.icvBack = xfFill->m_oPatternFill->m_oBgColor->m_oIndexed->GetValue(); if(xfFill->m_oPatternFill->m_oFgColor->m_oIndexed.IsInit()) xf->fill.icvFore = xfFill->m_oPatternFill->m_oFgColor->m_oIndexed->GetValue(); } } } } } } if(m_oCellXfs.IsInit()) { for(auto i = 0; i < m_oCellXfs->m_arrItems.size(); i++) { if(CastedPtr->m_arCellXFs.size() > i) { if(m_oCellXfs->m_arrItems[i]->m_oFillId.IsInit() && m_oFills->m_arrItems.size() > m_oCellXfs->m_arrItems[i]->m_oFillId->GetValue()) { auto xf = static_cast(CastedPtr->m_arCellXFs[i].get()); auto xfFill = m_oFills->m_arrItems[m_oCellXfs->m_arrItems[i]->m_oFillId->GetValue()]; if(xfFill->m_oPatternFill.IsInit()) { if(xfFill->m_oPatternFill->m_oBgColor.IsInit() && xfFill->m_oPatternFill->m_oBgColor->m_oIndexed.IsInit()) xf->fill.icvBack = xfFill->m_oPatternFill->m_oBgColor->m_oIndexed->GetValue(); if(xfFill->m_oPatternFill->m_oFgColor.IsInit() && xfFill->m_oPatternFill->m_oFgColor->m_oIndexed.IsInit()) xf->fill.icvFore = xfFill->m_oPatternFill->m_oFgColor->m_oIndexed->GetValue(); if(xfFill->m_oPatternFill->m_oPatternType.IsInit()) { if(xfFill->m_oPatternFill->m_oPatternType->m_eValue == SimpleTypes::Spreadsheet::EPatternType::patterntypeSolid) xf->fill.fls = 1; else if(xfFill->m_oPatternFill->m_oPatternType->m_eValue == SimpleTypes::Spreadsheet::EPatternType::patterntypeGray0625) xf->fill.fls = 12; else if(xfFill->m_oPatternFill->m_oPatternType->m_eValue == SimpleTypes::Spreadsheet::EPatternType::patterntypeGray125) xf->fill.fls = 11; else if(xfFill->m_oPatternFill->m_oPatternType->m_eValue == SimpleTypes::Spreadsheet::EPatternType::patterntypeDarkGray) xf->fill.fls = 3; else if(xfFill->m_oPatternFill->m_oPatternType->m_eValue == SimpleTypes::Spreadsheet::EPatternType::patterntypeNone) xf->fill.fls = 0; } } } } } } } void ProcessBorderProp(CBorderProp* prop, unsigned char& DgPtr, unsigned char& icvPtr) { if(prop->m_oStyle.IsInit()) { switch(prop->m_oStyle->GetValue()) { case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleNone: { DgPtr = 0; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleThin: { DgPtr = 1; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMedium: { DgPtr = 2; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDashed: { DgPtr = 3; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDotted: { DgPtr = 4; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleThick: { DgPtr = 5; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDouble: { DgPtr = 6; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleHair: { DgPtr = 7; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMediumDashed: { DgPtr = 8; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDashDot: { DgPtr = 9; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleMediumDashDot: { DgPtr = 10; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleDashDotDot: { DgPtr = 11; break; } case SimpleTypes::Spreadsheet::EBorderStyle::borderstyleSlantDashDot: { DgPtr = 13; break; } default: break; } } if(prop->m_oColor.IsInit() && prop->m_oColor->m_oIndexed.IsInit()) icvPtr = prop->m_oColor->m_oIndexed->GetValue(); } void CStyles::SetBordersXLS(XLS::BaseObjectPtr XFSPtr, XLS::BaseObjectPtr workbookPtr) { if(!m_oBorders.IsInit()) return; auto castedWorkbook = static_cast(workbookPtr.get()); auto globalInfo = castedWorkbook->global_info_; auto setBorderClr = [](nullable &border, nullable &colors, XLS::GlobalWorkbookInfoPtr &globInfo) { if(border.IsInit() && border->m_oColor.IsInit() && !border->m_oColor->m_oIndexed.IsInit() && border->m_oColor->m_oRgb.IsInit()) border->m_oColor->m_oIndexed = GetClrIndex(colors.get(), border->m_oColor->m_oRgb.get()); else if(border.IsInit() && border->m_oColor.IsInit() && border->m_oColor->m_oThemeColor.IsInit() && globInfo->colors_palette.find(border->m_oColor->m_oThemeColor->GetValue()) != globInfo->colors_palette.end()) { auto rgb = globInfo->colors_palette.find(border->m_oColor->m_oThemeColor->GetValue())->second; SimpleTypes::Spreadsheet::CHexColor hexClr; hexClr.FromString(rgb); border->m_oColor->m_oIndexed = GetClrIndex(colors.get(), hexClr); } return 0; }; for(auto i : m_oBorders->m_arrItems) { setBorderClr(i->m_oTop, m_oColors, globalInfo); setBorderClr(i->m_oBottom, m_oColors, globalInfo); setBorderClr(i->m_oStart, m_oColors, globalInfo); setBorderClr(i->m_oEnd, m_oColors, globalInfo); setBorderClr(i->m_oDiagonal, m_oColors, globalInfo); } auto CastedPtr = static_cast(XFSPtr.get()); for(auto i = 0; i < m_oCellXfs->m_arrItems.size(); i++) { if(CastedPtr->m_arCellXFs.size() > i) { if(m_oCellXfs->m_arrItems[i]->m_oBorderId.IsInit() && m_oBorders->m_arrItems.size() > m_oCellXfs->m_arrItems[i]->m_oBorderId->GetValue()) { auto xf = static_cast(CastedPtr->m_arCellXFs[i].get()); auto xfBorder = m_oBorders->m_arrItems[m_oCellXfs->m_arrItems[i]->m_oBorderId->GetValue()]; if(xfBorder->m_oBottom.IsInit()) { ProcessBorderProp(xfBorder->m_oBottom.GetPointer(), xf->border.dgBottom, xf->border.icvBottom); } if(xfBorder->m_oTop.IsInit()) { ProcessBorderProp(xfBorder->m_oTop.GetPointer(), xf->border.dgTop, xf->border.icvTop); } if(xfBorder->m_oStart.IsInit()) { ProcessBorderProp(xfBorder->m_oStart.GetPointer(), xf->border.dgLeft, xf->border.icvLeft); } if(xfBorder->m_oEnd.IsInit()) { ProcessBorderProp(xfBorder->m_oEnd.GetPointer(), xf->border.dgRight, xf->border.icvRight); } if(xfBorder->m_oDiagonal.IsInit()) { ProcessBorderProp(xfBorder->m_oDiagonal.GetPointer(), xf->border.dgDiag, xf->border.icvDiag); } } } } } void CStyles::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) CPath oRootPath; read(oRootPath, oPath); } void CStyles::fromXML(XmlUtils::CXmlNode& node) { } std::wstring CStyles::toXML() const { return _T(""); } void CStyles::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; IFileContainer::Read(oRootPath, oPath); if (m_oReadPath.GetExtention() == _T(".bin")) { readBin(m_oReadPath); return; } XmlUtils::CXmlLiteReader oReader; if (!oReader.FromFile(oPath.GetPath())) return; if (!oReader.ReadNextNode()) return; std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); if (_T("styleSheet") == sName) { fromXML(oReader); } } void CStyles::toXML(NSStringUtils::CStringBuilder& writer) const { if (m_oNumFmts.IsInit()) m_oNumFmts->toXML(writer); if (m_oFonts.IsInit()) m_oFonts->toXML(writer); if (m_oFills.IsInit()) m_oFills->toXML(writer); if (m_oBorders.IsInit()) m_oBorders->toXML(writer); if (m_oCellStyleXfs.IsInit()) m_oCellStyleXfs->toXML(writer); if (m_oCellXfs.IsInit()) m_oCellXfs->toXML(writer); if (m_oCellStyles.IsInit()) m_oCellStyles->toXML(writer); if (m_oColors.IsInit()) m_oColors->toXML(writer); if (m_oDxfs.IsInit()) m_oDxfs->toXML(writer); if (m_oTableStyles.IsInit()) m_oTableStyles->toXML(writer); if (m_oExtLst.IsInit()) writer.WriteString(m_oExtLst->toXMLWithNS(L"")); } void CStyles::fromXML(XmlUtils::CXmlLiteReader& oReader) { if (oReader.IsEmptyNode()) return; int nStylesDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nStylesDepth)) { std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); if (L"borders" == sName) m_oBorders = oReader; else if (_T("cellStyles") == sName) m_oCellStyles = oReader; else if (L"cellStyleXfs" == sName) m_oCellStyleXfs = oReader; else if (L"cellXfs" == sName) m_oCellXfs = oReader; else if (L"colors" == sName) m_oColors = oReader; else if (L"dxfs" == sName) m_oDxfs = oReader; //else if ( _T("extLst") == sName ) // pItem = new CSi( oReader ); else if (L"fills" == sName) m_oFills = oReader; else if (L"fonts" == sName) m_oFonts = oReader; else if (L"numFmts" == sName) m_oNumFmts = oReader; else if (L"tableStyles" == sName) m_oTableStyles = oReader; else if (L"Style" == sName) { CStyle2003 *style = new CStyle2003(WritingElement::m_pMainDocument); style->fromXML(oReader); if ( ((style->m_sName.IsInit()) && (style->m_sName == L"Normal" || style->m_sName == L"Default")) || ((style->m_sId.IsInit()) && (style->m_sId == L"Normal" || style->m_sId == L"Default"))) { m_nStyleNormal2003 = m_arrStyles2003.size(); } m_arrStyles2003.push_back(style); } else if (L"extLst" == sName) m_oExtLst = oReader; } AfterRead(); } void CStyles::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); if ((xlsb) && (xlsb->m_bWriteToXlsb)) { XLS::BaseObjectPtr object = WriteBin(); xlsb->WriteBin(oPath, object.get()); } else { NSStringUtils::CStringBuilder sXml; sXml.WriteString(L"\ "); toXML(sXml); sXml.WriteString(L""); std::wstring sPath = oPath.GetPath(); NSFile::CFileBinary::SaveToFile(sPath.c_str(), sXml.GetData()); } oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); } void CStyles::AfterRead() { if (m_arrStyles2003.empty()) return; if (!m_oCellStyles.IsInit()) m_oCellStyles.Init(); if (!m_oCellStyleXfs.IsInit()) m_oCellStyleXfs.Init(); if (!m_oCellXfs.IsInit()) m_oCellXfs.Init(); if (!m_oBorders.IsInit()) m_oBorders.Init(); if (!m_oFills.IsInit()) m_oFills.Init(); if (!m_oFonts.IsInit()) m_oFonts.Init(); if (!m_oNumFmts.IsInit()) m_oNumFmts.Init(); m_oFills->m_arrItems.push_back(new CFill); m_oFills->m_arrItems.back()->m_oPatternFill.Init(); m_oFills->m_arrItems.back()->m_oPatternFill->m_oPatternType.Init(); m_oFills->m_arrItems.back()->m_oPatternFill->m_oPatternType->SetValue(SimpleTypes::Spreadsheet::patterntypeNone); m_oFills->m_arrItems.push_back(new CFill); m_oFills->m_arrItems.back()->m_oPatternFill.Init(); m_oFills->m_arrItems.back()->m_oPatternFill->m_oPatternType.Init(); m_oFills->m_arrItems.back()->m_oPatternFill->m_oPatternType->SetValue(SimpleTypes::Spreadsheet::patterntypeGray125); if (m_nStyleNormal2003 != 0xffffffff) { ConvertStyle2003(m_arrStyles2003[m_nStyleNormal2003], true); } else { m_oBorders->m_arrItems.push_back(new CBorder); m_oBorders->m_arrItems.back()->m_oBottom.Init(); m_oBorders->m_arrItems.back()->m_oTop.Init(); m_oBorders->m_arrItems.back()->m_oStart.Init(); m_oBorders->m_arrItems.back()->m_oEnd.Init(); m_oFonts->m_arrItems.push_back(new CFont); m_oFonts->m_arrItems.back()->m_oSz.Init(); m_oFonts->m_arrItems.back()->m_oSz->m_oVal.Init(); m_oFonts->m_arrItems.back()->m_oSz->m_oVal->SetValue(11); m_oFonts->m_arrItems.back()->m_oRFont.Init(); m_oFonts->m_arrItems.back()->m_oRFont->m_sVal = L"Calibri"; CXfs *pStyleXfs = new CXfs(); int iXfs = m_oCellStyleXfs->m_arrItems.size(); pStyleXfs->m_oNumFmtId.Init(); pStyleXfs->m_oNumFmtId->SetValue(0); pStyleXfs->m_oFontId.Init(); pStyleXfs->m_oFontId->SetValue(0); m_oCellStyleXfs->m_arrItems.push_back(pStyleXfs); CCellStyle *cell_style = new CCellStyle(); cell_style->m_oXfId = iXfs; cell_style->m_oName = L"Normal"; m_oCellStyles->m_arrItems.push_back(cell_style); CXfs *cell_xfs = new CXfs(); cell_xfs->m_oXfId = iXfs; m_oCellXfs->m_arrItems.push_back(cell_xfs); } //-------------------------------------------------------------------------------------------- for (size_t i = 0; i < m_arrStyles2003.size(); ++i) { if (m_arrStyles2003[i]->m_sId.IsInit() == false) continue; ConvertStyle2003(m_arrStyles2003[i]); } } void CStyles::ConvertStyle2003(CStyle2003 *style2003, bool bDefault) { if (!style2003) return; if (style2003->bUsed) return; style2003->bUsed = true; if (style2003->m_sParentId.IsInit()) { std::map::iterator pFind = m_mapStyles2003.find(*style2003->m_sParentId); if (pFind != m_mapStyles2003.end()) { MergeStyles2003(style2003, m_arrStyles2003[pFind->second]); } } CXfs *pStyleXfs = new CXfs(); if (style2003->m_oBorder.IsInit()) { nullable borderCopy = style2003->m_oBorder; int index = m_oBorders->m_arrItems.size(); m_oBorders->m_arrItems.push_back(borderCopy.GetPointerEmptyNullable()); m_oBorders->m_mapBorders.insert(std::make_pair(index, m_oBorders->m_arrItems.back())); pStyleXfs->m_oBorderId = index; pStyleXfs->m_oApplyBorder.Init(); pStyleXfs->m_oApplyBorder->FromBool(true); } if ((style2003->m_oFill.IsInit())/* && (style2003->m_oFill->m_oPatternFill.IsInit())*/) { nullable fillCopy = style2003->m_oFill; int index = m_oFills->m_arrItems.size(); m_oFills->m_arrItems.push_back(fillCopy.GetPointerEmptyNullable()); m_oFills->m_mapFills.insert(std::make_pair(index, m_oFills->m_arrItems.back())); pStyleXfs->m_oFillId = index; pStyleXfs->m_oApplyFill.Init(); pStyleXfs->m_oApplyFill->FromBool(true); } if (style2003->m_oFont.IsInit() || bDefault) { int index = m_oFonts->m_arrItems.size(); if (style2003->m_oFont.IsInit()) { nullable fontCopy = style2003->m_oFont; m_oFonts->m_arrItems.push_back(fontCopy.GetPointerEmptyNullable()); m_oFonts->m_mapFonts.insert(std::make_pair(index, m_oFonts->m_arrItems.back())); } else { m_oFonts->m_arrItems.push_back(new CFont); } if (false == m_oFonts->m_arrItems.back()->m_oSz.IsInit()) { m_oFonts->m_arrItems.back()->m_oSz.Init(); m_oFonts->m_arrItems.back()->m_oSz->m_oVal.Init(); m_oFonts->m_arrItems.back()->m_oSz->m_oVal->SetValue(10); } if (false == m_oFonts->m_arrItems.back()->m_oRFont.IsInit()) { m_oFonts->m_arrItems.back()->m_oRFont.Init(); m_oFonts->m_arrItems.back()->m_oRFont->m_sVal = L"Arial"; } pStyleXfs->m_oFontId = index; pStyleXfs->m_oApplyFont.Init(); pStyleXfs->m_oApplyFont->FromBool(true); } if (style2003->m_oNumFmt.IsInit()) { int index = 0; if (style2003->m_oNumFmt->m_oFormatCode.IsInit()) { if (*style2003->m_oNumFmt->m_oFormatCode == L"General" || *style2003->m_oNumFmt->m_oFormatCode == L"@") index = 0; else if (*style2003->m_oNumFmt->m_oFormatCode == L"General Number") index = 0; else if (*style2003->m_oNumFmt->m_oFormatCode == L"0") index = 0; else if (*style2003->m_oNumFmt->m_oFormatCode == L"0.0") index = 0; else if (*style2003->m_oNumFmt->m_oFormatCode == L"0.00") index = 2; else if (*style2003->m_oNumFmt->m_oFormatCode == L"General Date") index = 22; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Long Date") index = 15; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Medium Date") index = 14; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Short Date") index = 16; else if (std::wstring::npos != style2003->m_oNumFmt->m_oFormatCode->find(L"d/m/yy")) index = 16; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Long Time") index = 21; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Medium Time") index = 20; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Short Time") index = 20; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Fixed") index = 2; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Standard") index = 0; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Percent") index = 10; else if (*style2003->m_oNumFmt->m_oFormatCode == L"Scientific") index = 11; //Yes/No, True/False, or On/Off else { std::map::iterator pFind = m_oNumFmts->m_mapFormatCode.find(*style2003->m_oNumFmt->m_oFormatCode); if (pFind == m_oNumFmts->m_mapFormatCode.end()) { index = 168 + m_oNumFmts->m_arrItems.size(); style2003->m_oNumFmt->m_oNumFmtId = index; m_oNumFmts->m_mapFormatCode.insert(std::make_pair(*style2003->m_oNumFmt->m_oFormatCode, index)); nullable numFmtCopy = style2003->m_oNumFmt; m_oNumFmts->m_arrItems.push_back(numFmtCopy.GetPointerEmptyNullable()); style2003->m_oNumFmt.Init(); //repair } else { index = pFind->second; } } pStyleXfs->m_oApplyNumberFormat.Init(); pStyleXfs->m_oApplyNumberFormat->FromBool(true); } pStyleXfs->m_oNumFmtId = index; } if (style2003->m_oAligment.IsInit()) { pStyleXfs->m_oAligment = style2003->m_oAligment; pStyleXfs->m_oApplyAlignment.Init(); pStyleXfs->m_oApplyAlignment->FromBool(true); } CXfs *pCellXfs = new CXfs(*pStyleXfs); int iXfs = m_oCellStyleXfs->m_arrItems.size(); m_oCellStyleXfs->m_arrItems.push_back(pStyleXfs); pCellXfs->m_oXfId = iXfs; m_oCellXfs->m_arrItems.push_back(pCellXfs); if (style2003->m_sName.IsInit()) { CCellStyle *cell_style = new CCellStyle(); cell_style->m_oXfId = iXfs; cell_style->m_oName = style2003->m_sName; m_oCellStyles->m_arrItems.push_back(cell_style); } if (style2003->m_sId.IsInit()) { m_mapStyles2003.insert(std::make_pair(*style2003->m_sId, iXfs)); } if (style2003->bStyleContinuous) m_mapStylesContinues2003.insert(std::make_pair(m_oCellXfs->m_arrItems.size() - 1, true)); } void CStyles::MergeStyles2003(CStyle2003 *style2003, CStyle2003 *parent) { if (!style2003 || !parent) return; if (false == style2003->m_oNumFmt.IsInit()) { style2003->m_oNumFmt = parent->m_oNumFmt; } if (false == style2003->m_oBorder.IsInit()) { style2003->m_oBorder = parent->m_oBorder; } if (false == style2003->m_oFill.IsInit()) { style2003->m_oFill = parent->m_oFill; } if (false == style2003->m_oFont.IsInit()) { style2003->m_oFont = parent->m_oFont; } if (false == style2003->m_oAligment.IsInit()) { style2003->m_oAligment = parent->m_oAligment; } //--------------------------------------- if (parent->m_sParentId.IsInit()) { std::map::iterator pFind = m_mapStyles2003.find(*parent->m_sParentId); if (pFind != m_mapStyles2003.end()) { MergeStyles2003(style2003, m_arrStyles2003[pFind->second]); } } } void CStyles::PrepareToWrite() { //fonts if (false == m_oFonts.IsInit()) { m_oFonts.Init(); OOX::Spreadsheet::CFont* pFont = new OOX::Spreadsheet::CFont(); pFont->m_oSz.Init(); pFont->m_oSz->m_oVal.Init(); pFont->m_oSz->m_oVal->SetValue(11); pFont->m_oColor.Init(); pFont->m_oColor->m_oThemeColor.Init(); pFont->m_oColor->m_oThemeColor->SetValue(SimpleTypes::Spreadsheet::themecolorDark1); pFont->m_oRFont.Init(); pFont->m_oRFont->m_sVal = L"Calibri"; pFont->m_oFamily.Init(); pFont->m_oFamily->m_oFontFamily.Init(); pFont->m_oFamily->m_oFontFamily->SetValue(SimpleTypes::Spreadsheet::fontfamilySwiss); pFont->m_oScheme.Init(); pFont->m_oScheme->m_oFontScheme.Init(); pFont->m_oScheme->m_oFontScheme->SetValue(SimpleTypes::Spreadsheet::fontschemeMinor); m_oFonts->m_arrItems.push_back(pFont); } if (false == m_oFonts->m_oCount.IsInit()) { m_oFonts->m_oCount.Init(); m_oFonts->m_oCount->SetValue((unsigned int)m_oFonts->m_arrItems.size()); } //fills if (false == m_oFills.IsInit()) { m_oFills.Init(); OOX::Spreadsheet::CFill* pFill1 = new OOX::Spreadsheet::CFill(); pFill1->m_oPatternFill.Init(); pFill1->m_oPatternFill->m_oPatternType.Init(); pFill1->m_oPatternFill->m_oPatternType->SetValue(SimpleTypes::Spreadsheet::patterntypeNone); OOX::Spreadsheet::CFill* pFill2 = new OOX::Spreadsheet::CFill(); pFill2->m_oPatternFill.Init(); pFill2->m_oPatternFill->m_oPatternType.Init(); pFill2->m_oPatternFill->m_oPatternType->SetValue(SimpleTypes::Spreadsheet::patterntypeGray125); m_oFills->m_arrItems.push_back(pFill1); m_oFills->m_arrItems.push_back(pFill2); } if (false == m_oFills->m_oCount.IsInit()) { m_oFills->m_oCount.Init(); m_oFills->m_oCount->SetValue((unsigned int)m_oFills->m_arrItems.size()); } //borders if (false == m_oBorders.IsInit()) { m_oBorders.Init(); OOX::Spreadsheet::CBorder* pBorder = new OOX::Spreadsheet::CBorder(); pBorder->m_oStart.Init(); pBorder->m_oEnd.Init(); pBorder->m_oTop.Init(); pBorder->m_oBottom.Init(); pBorder->m_oDiagonal.Init(); m_oBorders->m_arrItems.push_back(pBorder); } if (false == m_oBorders->m_oCount.IsInit()) { m_oBorders->m_oCount.Init(); m_oBorders->m_oCount->SetValue((unsigned int)m_oBorders->m_arrItems.size()); } //cellXfs if (m_oCellXfs.IsInit()) { for (size_t i = 0; i < m_oCellXfs->m_arrItems.size(); ++i) { CXfs* xfs = m_oCellXfs->m_arrItems[i]; if ((xfs) && (false == xfs->m_oXfId.IsInit())) { xfs->m_oXfId.Init(); xfs->m_oXfId->SetValue(0); } } } //cellStyles if (false == m_oCellStyles.IsInit()) m_oCellStyles.Init(); if (m_oCellStyles->m_arrItems.empty()) { CCellStyle* pCellStyle = new CCellStyle(); pCellStyle->m_oName = _T("Normal"); pCellStyle->m_oXfId.Init(); pCellStyle->m_oXfId->SetValue(0); pCellStyle->m_oBuiltinId.Init(); pCellStyle->m_oBuiltinId->SetValue(0); m_oCellStyles->m_arrItems.push_back(pCellStyle); } if (false == m_oCellStyles->m_oCount.IsInit()) { m_oCellStyles->m_oCount.Init(); m_oCellStyles->m_oCount->SetValue((unsigned int)m_oCellStyles->m_arrItems.size()); } //cellStyleXfs if (false == m_oCellStyleXfs.IsInit()) m_oCellStyleXfs.Init(); if (0 == m_oCellStyleXfs->m_arrItems.size()) { CXfs* pXfs = new CXfs(); pXfs->m_oNumFmtId.Init(); pXfs->m_oNumFmtId->SetValue(0); pXfs->m_oFontId.Init(); pXfs->m_oFontId->SetValue(0); pXfs->m_oFillId.Init(); pXfs->m_oFillId->SetValue(0); pXfs->m_oBorderId.Init(); pXfs->m_oBorderId->SetValue(0); m_oCellStyleXfs->m_arrItems.push_back(pXfs); } if (false == m_oCellStyleXfs->m_oCount.IsInit()) { m_oCellStyleXfs->m_oCount.Init(); m_oCellStyleXfs->m_oCount->SetValue((unsigned int)m_oCellStyleXfs->m_arrItems.size()); } //dxfs if (false == m_oDxfs.IsInit()) m_oDxfs.Init(); if (false == m_oDxfs->m_oCount.IsInit()) { m_oDxfs->m_oCount.Init(); m_oDxfs->m_oCount->SetValue(0); } //tableStyles if (false == m_oTableStyles.IsInit()) { m_oTableStyles.Init(); m_oTableStyles->m_oCount.Init(); m_oTableStyles->m_oCount->SetValue(0); } if (false == m_oTableStyles->m_oDefaultPivotStyle.IsInit()) m_oTableStyles->m_oDefaultTableStyle = _T("TableStyleMedium2"); if (false == m_oTableStyles->m_oDefaultPivotStyle.IsInit()) m_oTableStyles->m_oDefaultPivotStyle = _T("PivotStyleLight16"); } const OOX::FileType CStyles::type() const { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); if ((xlsb) && (xlsb->m_bWriteToXlsb)) { return OOX::SpreadsheetBin::FileTypes::StylesBin; } return OOX::Spreadsheet::FileTypes::Styles; } const CPath CStyles::DefaultDirectory() const { return type().DefaultDirectory(); } const CPath CStyles::DefaultFileName() const { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); if ((xlsb) && (xlsb->m_bWriteToXlsb)) { CPath name = type().DefaultFileName(); name.SetExtention(L"bin"); return name; } else { return type().DefaultFileName(); } } const CPath& CStyles::GetReadPath() { return m_oReadPath; } } //Spreadsheet } // namespace OOX