chart2/inc/ChartModel.hxx | 3 chart2/qa/extras/chart2export.cxx | 11 +++ chart2/qa/extras/data/xlsx/column-style.xlsx |binary chart2/source/model/main/ChartModel.cxx | 16 ++++ docmodel/Library_docmodel.mk | 3 docmodel/source/styles/ChartColorStyle.cxx | 21 ++++++ docmodel/source/uno/UnoChartColorStyle.cxx | 40 ++++++++++++ include/docmodel/styles/ChartColorStyle.hxx | 64 +++++++++++++++++++ include/docmodel/uno/UnoChartColorStyle.hxx | 45 +++++++++++++ include/oox/drawingml/chart/chartconverter.hxx | 24 +++++++ offapi/UnoApi_offapi.mk | 1 offapi/com/sun/star/chart2/XChartColorStyle.idl | 24 +++++++ offapi/com/sun/star/chart2/XChartDocument.idl | 5 + oox/inc/drawingml/chart/colorsmodel.hxx | 33 ++++++++++ oox/inc/drawingml/chart/stylefragment.hxx | 15 ++++ oox/inc/drawingml/colorchoicecontext.hxx | 18 +++++ oox/source/drawingml/chart/chartconverter.cxx | 24 +++++++ oox/source/drawingml/chart/colorsmodel.cxx | 51 +++++++++++++++ oox/source/drawingml/chart/stylefragment.cxx | 79 ++++++++++++++++++++++++ oox/source/drawingml/colorchoicecontext.cxx | 32 +++++++++ oox/source/drawingml/shape.cxx | 18 +++++ oox/source/export/chartexport.cxx | 52 +++++++++++++-- oox/source/token/tokens.txt | 1 23 files changed, 572 insertions(+), 8 deletions(-)
New commits: commit 0686b1972806fe8b711de5ba64039fb38cd14889 Author: Kurt Nordback <[email protected]> AuthorDate: Thu Dec 4 22:16:26 2025 +0900 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Fri Dec 5 02:12:41 2025 +0100 tdf#167941 - Chart color sequence OOXML import/export Support import, storage, and export of OOXML chart color styles (color sequence). In OOXML, chart color styles are in files such as colors1.xml, and conform to the chartStyle schema. This commit supports I/O of color styles, and provides supports storing them in the chart document model. It does not include any features for using or modifying the color styles, so at this point it has no appreciable effect on users. Change-Id: I5c02137ebf9c25e11951eea55c4c77fda35b0e80 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194998 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <[email protected]> diff --git a/chart2/inc/ChartModel.hxx b/chart2/inc/ChartModel.hxx index b24c5c459d79..428cfe7e297e 100644 --- a/chart2/inc/ChartModel.hxx +++ b/chart2/inc/ChartModel.hxx @@ -71,6 +71,7 @@ class SvNumberFormatter; class SvNumberFormatsSupplierObj; class UnoChartStyle; +class UnoChartColorStyle; namespace model { class Theme; } @@ -191,6 +192,7 @@ private: std::optional<css::util::DateTime> m_aNullDate; rtl::Reference<UnoChartStyle> m_aStyles; + rtl::Reference<UnoChartColorStyle> m_aColorStyles; private: //private methods @@ -386,6 +388,7 @@ public: virtual css::uno::Reference< css::chart2::XChartTypeManager > SAL_CALL getChartTypeManager() override; virtual css::uno::Reference< css::chart2::XChartStyle> SAL_CALL getStyles() override; + virtual css::uno::Reference< css::chart2::XChartColorStyle> SAL_CALL getColorStyles() override; virtual css::uno::Reference< css::beans::XPropertySet > SAL_CALL getPageBackground() override; diff --git a/chart2/qa/extras/chart2export.cxx b/chart2/qa/extras/chart2export.cxx index 84cf592be6eb..bed05f40097c 100644 --- a/chart2/qa/extras/chart2export.cxx +++ b/chart2/qa/extras/chart2export.cxx @@ -1386,6 +1386,17 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest, testStyleImportExport) assertXPath(pXmlDoc, "/cs:chartStyle/cs:axisTitle/cs:fontRef", "idx", std::u16string_view(u"major")); } +CPPUNIT_TEST_FIXTURE(Chart2ExportTest, testColorStyleImportExport) +{ + loadFromFile(std::u16string_view(u"xlsx/column-style.xlsx")); + + save(TestFilter::XLSX); + xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/colors1.xml"); + CPPUNIT_ASSERT(pXmlDoc); + assertXPath(pXmlDoc, "/cs:colorStyle", "meth", u"acrossLinear"); + assertXPath(pXmlDoc, "/cs:colorStyle/a:schemeClr", "val", u"dk2"); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/qa/extras/data/xlsx/column-style.xlsx b/chart2/qa/extras/data/xlsx/column-style.xlsx index 087102a0ec85..802a42ff85ad 100644 Binary files a/chart2/qa/extras/data/xlsx/column-style.xlsx and b/chart2/qa/extras/data/xlsx/column-style.xlsx differ diff --git a/chart2/source/model/main/ChartModel.cxx b/chart2/source/model/main/ChartModel.cxx index 4fd9041f67f3..96fe84cc99dc 100644 --- a/chart2/source/model/main/ChartModel.cxx +++ b/chart2/source/model/main/ChartModel.cxx @@ -78,6 +78,7 @@ #include <docmodel/uno/UnoTheme.hxx> #include <docmodel/theme/Theme.hxx> #include <docmodel/uno/UnoChartStyle.hxx> +#include <docmodel/uno/UnoChartColorStyle.hxx> using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Reference; @@ -130,6 +131,7 @@ ChartModel::ChartModel(uno::Reference<uno::XComponentContext > xContext) , m_eColorPaletteType(ChartColorPaletteType::Unknown) , m_nColorPaletteIndex(0) , m_aStyles(new UnoChartStyle) + , m_aColorStyles(new UnoChartColorStyle) , mnStart(0) , mnEnd(0) { @@ -143,6 +145,7 @@ ChartModel::ChartModel(uno::Reference<uno::XComponentContext > xContext) m_xPageBackground->addModifyListener( this ); #if 0 // TODO m_aStyles->addModifyListener( this ); + m_aColorStyles->addModifyListener( this ); #endif m_xChartTypeManager = new ::chart::ChartTypeManager( m_xContext ); } @@ -191,6 +194,8 @@ ChartModel::ChartModel( const ChartModel & rOther ) xNewDiagram = new ::chart::Diagram( *rOther.m_xDiagram ); rtl::Reference< ::chart::PageBackground > xNewPageBackground = new PageBackground( *rOther.m_xPageBackground ); rtl::Reference<UnoChartStyle> xNewChartStyle = new UnoChartStyle(*rOther.m_aStyles); + rtl::Reference<UnoChartColorStyle> xNewChartColorStyle = new + UnoChartColorStyle(*rOther.m_aColorStyles); { rtl::Reference< ::chart::ChartTypeManager > xChartTypeManager; // does not implement XCloneable @@ -203,6 +208,7 @@ ChartModel::ChartModel( const ChartModel & rOther ) m_xDiagram = xNewDiagram; m_xPageBackground = xNewPageBackground; m_aStyles = xNewChartStyle; + m_aColorStyles = xNewChartColorStyle; m_xChartTypeManager = std::move(xChartTypeManager); m_xXMLNamespaceMap = std::move(xXMLNamespaceMap); } @@ -217,6 +223,9 @@ ChartModel::ChartModel( const ChartModel & rOther ) if( xNewChartStyle && xListener) { xNewChartStyle->addModifyListener( xListener ); } + if( xNewChartColorStyle && xListener) { + xNewChartColorStyle->addModifyListener( xListener ); + } #endif xListener.clear(); } @@ -598,6 +607,7 @@ void SAL_CALL ChartModel::dispose() m_xPageBackground.clear(); m_xXMLNamespaceMap.clear(); m_aStyles.clear(); + m_aColorStyles.clear(); m_xStorage.clear(); // just clear, don't dispose - we're not the owner @@ -831,6 +841,12 @@ uno::Reference< chart2::XChartStyle > SAL_CALL ChartModel::getStyles() return m_aStyles; } +uno::Reference< chart2::XChartColorStyle > SAL_CALL ChartModel::getColorStyles() +{ + MutexGuard aGuard( m_aModelMutex ); + return m_aColorStyles; +} + // ____ XDataReceiver ____ void SAL_CALL ChartModel::attachDataProvider( const uno::Reference< chart2::data::XDataProvider >& xDataProvider ) diff --git a/docmodel/Library_docmodel.mk b/docmodel/Library_docmodel.mk index 83a4cadcbcee..1de5c254a110 100644 --- a/docmodel/Library_docmodel.mk +++ b/docmodel/Library_docmodel.mk @@ -12,12 +12,14 @@ $(eval $(call gb_Library_Library,docmodel)) $(eval $(call gb_Library_add_exception_objects,docmodel,\ docmodel/source/uno/UnoComplexColor \ docmodel/source/uno/UnoChartStyle \ + docmodel/source/uno/UnoChartColorStyle \ docmodel/source/uno/UnoGradientTools \ docmodel/source/uno/UnoTheme \ docmodel/source/theme/ColorSet \ docmodel/source/theme/Theme \ docmodel/source/color/ComplexColorJSON \ docmodel/source/styles/ChartStyle \ + docmodel/source/styles/ChartColorStyle \ )) $(eval $(call gb_Library_set_include,docmodel,\ @@ -28,6 +30,7 @@ $(eval $(call gb_Library_set_include,docmodel,\ $(eval $(call gb_Library_use_externals,docmodel,\ libxml2 \ boost_headers \ + frozen \ )) $(eval $(call gb_Library_add_defs,docmodel,\ diff --git a/docmodel/source/styles/ChartColorStyle.cxx b/docmodel/source/styles/ChartColorStyle.cxx new file mode 100644 index 000000000000..297e2afa1077 --- /dev/null +++ b/docmodel/source/styles/ChartColorStyle.cxx @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <docmodel/styles/ChartColorStyle.hxx> +#include <utility> + +using namespace model; + +void ColorStyleSet::addEntry(std::vector<model::ComplexColor>& aComplexColors, + ColorStyleMethod eMethod, sal_Int32 nId) +{ + maEntryList.emplace_front(aComplexColors, eMethod, nId); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/docmodel/source/uno/UnoChartColorStyle.cxx b/docmodel/source/uno/UnoChartColorStyle.cxx new file mode 100644 index 000000000000..2bf4d02cd743 --- /dev/null +++ b/docmodel/source/uno/UnoChartColorStyle.cxx @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <docmodel/uno/UnoChartColorStyle.hxx> +#include <cppuhelper/queryinterface.hxx> + +using namespace css; + +namespace model::style +{ +uno::Reference<chart2::XChartColorStyle> +createXChartColorStyle(model::ColorStyleSet const& rColorStyle) +{ + return new UnoChartColorStyle(rColorStyle); +} + +model::ColorStyleSet* +getFromXChartColorStyle(uno::Reference<chart2::XChartColorStyle> const& rxColorStyle) +{ + UnoChartColorStyle* pUnoChartColorStyle = static_cast<UnoChartColorStyle*>(rxColorStyle.get()); + + if (pUnoChartColorStyle) + { + return &pUnoChartColorStyle->getChartColorStyle(); + } + else + { + return nullptr; + } +} + +} // end model::style + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/docmodel/styles/ChartColorStyle.hxx b/include/docmodel/styles/ChartColorStyle.hxx new file mode 100644 index 000000000000..99606aaff8ab --- /dev/null +++ b/include/docmodel/styles/ChartColorStyle.hxx @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#pragma once + +#include <com/sun/star/uno/Reference.hxx> + +#include <docmodel/color/ComplexColor.hxx> +#include <comphelper/string.hxx> +#include <rtl/ustring.hxx> +#include <memory> +#include <forward_list> + +namespace com::sun::star::beans +{ +class XPropertySet; +} + +using namespace com::sun::star; + +namespace model +{ +enum class ColorStyleMethod +{ + CYCLE, + WITHIN_LINEAR, + ACROSS_LINEAR, + WITHIN_LINEAR_REVERSED, + ACROSS_LINEAR_REVERSED +}; + +struct DOCMODEL_DLLPUBLIC ColorStyleEntry +{ + std::vector<model::ComplexColor> maComplexColors; + ColorStyleMethod meMethod; + sal_Int32 mnId; + + ColorStyleEntry(std::vector<model::ComplexColor>& aCColors, ColorStyleMethod eMethod, + sal_Int32 nId) + : maComplexColors(std::move(aCColors)) + , meMethod(eMethod) + , mnId(nId) + { + } +}; + +struct DOCMODEL_DLLPUBLIC ColorStyleSet +{ + std::forward_list<ColorStyleEntry> maEntryList; + + void addEntry(std::vector<model::ComplexColor>& aComplexColors, ColorStyleMethod eMethod, + sal_Int32 nId); +}; + +} // namespace model + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/docmodel/uno/UnoChartColorStyle.hxx b/include/docmodel/uno/UnoChartColorStyle.hxx new file mode 100644 index 000000000000..7b2201716a57 --- /dev/null +++ b/include/docmodel/uno/UnoChartColorStyle.hxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <config_options.h> +#include <cppuhelper/implbase.hxx> + +#include <com/sun/star/chart2/XChartColorStyle.hpp> + +#include <docmodel/dllapi.h> +#include <docmodel/styles/ChartColorStyle.hxx> + +class UNLESS_MERGELIBS(DOCMODEL_DLLPUBLIC) UnoChartColorStyle final + : public cppu::WeakImplHelper<css::chart2::XChartColorStyle> +{ +private: + model::ColorStyleSet maColorStyle; + +public: + UnoChartColorStyle() = default; + + UnoChartColorStyle(model::ColorStyleSet const& rStyle) + : maColorStyle(rStyle) + { + } + + model::ColorStyleSet& getChartColorStyle() { return maColorStyle; } +}; + +namespace model::style +{ +DOCMODEL_DLLPUBLIC css::uno::Reference<css::chart2::XChartColorStyle> +createXChartColorStyle(model::ColorStyleSet const& rColorStyle); +DOCMODEL_DLLPUBLIC model::ColorStyleSet* +getFromXChartColorStyle(css::uno::Reference<css::chart2::XChartColorStyle> const& rxColorStyle); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/drawingml/chart/chartconverter.hxx b/include/oox/drawingml/chart/chartconverter.hxx index 0e97752d5f22..d83520381090 100644 --- a/include/oox/drawingml/chart/chartconverter.hxx +++ b/include/oox/drawingml/chart/chartconverter.hxx @@ -32,6 +32,7 @@ namespace com::sun::star { namespace drawing { class XShapes; } namespace chart2 { class XChartDocument; } namespace chart2 { class XChartStyle; } + namespace chart2 { class XChartColorStyle; } namespace chart2::data { class XDataProvider; } namespace chart2::data { class XDataSequence; } } @@ -43,6 +44,7 @@ namespace oox::drawingml::chart { struct ChartSpaceModel; struct DataSequenceModel; struct StyleModel; +struct ColorStyleModel; struct StyleEntryModel; typedef ModelRef< StyleEntryModel > StyleEntryRef; @@ -120,6 +122,28 @@ private: ChartStyleConverter& operator=( const ChartStyleConverter& ) = delete; }; +class OOX_DLLPUBLIC ChartColorStyleConverter +{ +public: + explicit ChartColorStyleConverter() = default; + + /** Converts the passed ChartColorStyleModel to the passed chart2 + * XChartColorStyle. + + @param rChartColorStyleModel The filled chart colorstyle model structure. + + @param rxColorChartStyle The UNO chart colorstyle structure to be initialized. + + */ + static void convertFromModel( + oox::core::XmlFilterBase& rFilter, + ColorStyleModel& rChartColorStyleModel, + const css::uno::Reference< css::chart2::XChartColorStyle >& rxChartColorStyle); +private: + ChartColorStyleConverter( const ChartColorStyleConverter& ) = delete; + ChartColorStyleConverter& operator=( const ChartColorStyleConverter& ) = delete; +}; + } // namespace oox::drawingml::chart diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 9ea3611da259..b200f0e02541 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -1992,6 +1992,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/chart2,\ TransparencyStyle \ XAnyDescriptionAccess \ XAxis \ + XChartColorStyle \ XChartDocument \ XChartShape \ XChartShapeContainer \ diff --git a/offapi/com/sun/star/chart2/XChartColorStyle.idl b/offapi/com/sun/star/chart2/XChartColorStyle.idl new file mode 100644 index 000000000000..54e8cd7e4eec --- /dev/null +++ b/offapi/com/sun/star/chart2/XChartColorStyle.idl @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + + +module com { module sun { module star { module chart2 { + +/** Interface for chart colors + + @since LibreOffice 26.2 +*/ + +interface XChartColorStyle : com::sun::star::uno::XInterface +{ +}; + +}; }; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/offapi/com/sun/star/chart2/XChartDocument.idl b/offapi/com/sun/star/chart2/XChartDocument.idl index d75fb65af4f6..881078db5d14 100644 --- a/offapi/com/sun/star/chart2/XChartDocument.idl +++ b/offapi/com/sun/star/chart2/XChartDocument.idl @@ -123,6 +123,11 @@ interface XChartDocument : ::com::sun::star::frame::XModel @since LibreOffice 26.02 */ XChartStyle getStyles(); + + /** Get colorstyle information + @since LibreOffice 26.02 + */ + XChartColorStyle getColorStyles(); }; } ; // chart2 diff --git a/oox/inc/drawingml/chart/colorsmodel.hxx b/oox/inc/drawingml/chart/colorsmodel.hxx new file mode 100644 index 000000000000..1972cba650dd --- /dev/null +++ b/oox/inc/drawingml/chart/colorsmodel.hxx @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/config.h> +#include <variant> + +#include <oox/core/xmlfilterbase.hxx> +#include <oox/drawingml/chart/modelbase.hxx> +#include <oox/drawingml/shape.hxx> +#include <docmodel/styles/ChartColorStyle.hxx> + +namespace oox::drawingml::chart +{ +// Holds the contents of a cs:CT_ColorStyle +struct ColorStyleModel +{ + std::vector<Color> maColors; + std::vector<model::ComplexColor> maComplexColors; + ::model::ColorStyleMethod meMethod; + sal_Int32 mnId; +}; + +} // namespace oox::drawingml::chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/inc/drawingml/chart/stylefragment.hxx b/oox/inc/drawingml/chart/stylefragment.hxx index 9adbea526aba..71875479092b 100644 --- a/oox/inc/drawingml/chart/stylefragment.hxx +++ b/oox/inc/drawingml/chart/stylefragment.hxx @@ -85,6 +85,21 @@ public: const AttributeList& rAttribs) override; }; +struct ColorStyleModel; + +/** Handler for a color fragment (cs:colorStyle root element). + */ +class ColorsFragment final : public FragmentBase<ColorStyleModel> +{ +public: + explicit ColorsFragment(::oox::core::XmlFilterBase& rFilter, const OUString& rFragmentPath, + ColorStyleModel& rModel); + virtual ~ColorsFragment() override; + + virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, + const AttributeList& rAttribs) override; +}; + } // namespace oox::drawingml::chart /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/inc/drawingml/colorchoicecontext.hxx b/oox/inc/drawingml/colorchoicecontext.hxx index c3736bfbb46b..4c46d5f7be50 100644 --- a/oox/inc/drawingml/colorchoicecontext.hxx +++ b/oox/inc/drawingml/colorchoicecontext.hxx @@ -64,6 +64,24 @@ protected: ::model::ComplexColor* mpComplexColor; }; +/** Context handler for cs:variation elements, which describe transformations on + * colours. + */ +class VariationContext : public ColorValueContext +{ +public: + explicit VariationContext(::oox::core::ContextHandler2Helper const & rParent, + Color* pColor, ::model::ComplexColor* pComplexColor); + + virtual ::oox::core::ContextHandlerRef onCreateContext( + sal_Int32 nElement, const ::oox::AttributeList& rAttribs) override; + +private: + Color* mpColor; + ::model::ComplexColor* mpComplexColor; +}; + + /// Same as ColorContext, but handles multiple colors. class ColorsContext final : public ::oox::core::ContextHandler2 { diff --git a/oox/source/drawingml/chart/chartconverter.cxx b/oox/source/drawingml/chart/chartconverter.cxx index 1b281bd6cbc5..db4291acb929 100644 --- a/oox/source/drawingml/chart/chartconverter.cxx +++ b/oox/source/drawingml/chart/chartconverter.cxx @@ -23,8 +23,11 @@ #include <drawingml/chart/chartspaceconverter.hxx> #include <drawingml/chart/chartspacemodel.hxx> #include <drawingml/chart/stylemodel.hxx> +#include <drawingml/chart/colorsmodel.hxx> #include <docmodel/uno/UnoChartStyle.hxx> +#include <docmodel/uno/UnoChartColorStyle.hxx> #include <docmodel/styles/ChartStyle.hxx> +#include <docmodel/styles/ChartColorStyle.hxx> #include <oox/helper/containerhelper.hxx> #include <oox/core/xmlfilterbase.hxx> #include <osl/diagnose.h> @@ -175,6 +178,27 @@ void ChartStyleConverter::convertFromModel(XmlFilterBase& rFilter, aStyles.mnId = rChartStyleModel.mnId; } +// =========== +// ChartColorStyleConverter +// =========== +void ChartColorStyleConverter::convertFromModel([[maybe_unused]] XmlFilterBase& rFilter, + ColorStyleModel& rChartColorStyleModel, + const Reference< XChartColorStyle >& rxChartColorStyle) +{ + OSL_ENSURE( rxChartColorStyle.is(), "ChartColorStyleConverter::convertFromModel - missing chart colorstyle" ); + if (!rxChartColorStyle.is()) return; + + UnoChartColorStyle *pUnoCS = static_cast<UnoChartColorStyle*>(rxChartColorStyle.get()); + assert(pUnoCS); + + model::ColorStyleSet& aColorStyles = pUnoCS->getChartColorStyle(); + + if (!rChartColorStyleModel.maComplexColors.empty()) { + aColorStyles.addEntry(rChartColorStyleModel.maComplexColors, + rChartColorStyleModel.meMethod, rChartColorStyleModel.mnId); + } +} + } // namespace oox::drawingml::chart diff --git a/oox/source/drawingml/chart/colorsmodel.cxx b/oox/source/drawingml/chart/colorsmodel.cxx new file mode 100644 index 000000000000..8c026ed2af33 --- /dev/null +++ b/oox/source/drawingml/chart/colorsmodel.cxx @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <tools/gen.hxx> +#include <drawingml/chart/stylemodel.hxx> +#include <docmodel/text/TextBodyProps.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> + +using namespace com::sun::star; + +namespace oox::drawingml::chart +{ +model::StyleEntry StyleEntryModel::toStyleEntry([[maybe_unused]] oox::core::XmlFilterBase& rFilter) +{ + std::shared_ptr<model::ShapeBase> pShapePr; + // Down-cast to ShapeBase* and deep copy so the shared_ptr can have ownership + if (mxShapeProp) + { + pShapePr = std::make_shared<model::ShapeBase>( + *static_cast<model::ShapeBase*>(mxShapeProp.get())); + } + + std::shared_ptr<model::TextCharPropsBase> pCharPr; + // Down-cast to TextCharPropsBase* and deep copy so the shared_ptr can have ownership + if (mrTextCharacterProperties) + { + pCharPr = std::make_shared<model::TextCharPropsBase>( + *static_cast<model::TextCharPropsBase*>(mrTextCharacterProperties.get())); + } + + std::shared_ptr<model::TextBodyProps> pBodyPr; + if (mxBodyPr) + { + // Down-cast to TextBodyProps* and deep copy so the shared_ptr can have ownership + pBodyPr = std::make_shared<model::TextBodyProps>( + *static_cast<model::TextBodyProps*>(mxBodyPr.get())); + } + + return model::StyleEntry(mxLnRef, mfLineWidthScale, mxFillRef, mxEffectRef, mxFontRef, + std::move(pShapePr), std::move(pCharPr), std::move(pBodyPr)); +} + +} // namespace oox::drawingml::chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/chart/stylefragment.cxx b/oox/source/drawingml/chart/stylefragment.cxx index 90f3fdcc7481..262ce7c79ad1 100644 --- a/oox/source/drawingml/chart/stylefragment.cxx +++ b/oox/source/drawingml/chart/stylefragment.cxx @@ -26,6 +26,7 @@ #include <drawingml/textbodypropertiescontext.hxx> #include <drawingml/textcharacterpropertiescontext.hxx> #include <drawingml/chart/stylemodel.hxx> +#include <drawingml/chart/colorsmodel.hxx> #include <drawingml/colorchoicecontext.hxx> #include <docmodel/styles/ChartStyle.hxx> #include <oox/drawingml/color.hxx> @@ -34,6 +35,8 @@ #include <oox/token/namespaces.hxx> #include <oox/token/tokens.hxx> +#include <tools/UnitConversion.hxx> + namespace oox::drawingml::chart { using namespace ::oox::core; @@ -258,6 +261,82 @@ ContextHandlerRef StyleFragment::onCreateContext(sal_Int32 nElement, const Attri return nullptr; } +//======= +// ColorsFragment +//======= +ColorsFragment::ColorsFragment(XmlFilterBase& rFilter, const OUString& rFragmentPath, + ColorStyleModel& rModel) + : FragmentBase<ColorStyleModel>(rFilter, rFragmentPath, rModel) +{ +} + +ColorsFragment::~ColorsFragment() {} + +ContextHandlerRef ColorsFragment::onCreateContext(sal_Int32 nElement, const AttributeList& rAttribs) +{ + switch (getCurrentElement()) + { + case XML_ROOT_CONTEXT: + switch (nElement) + { + case CS_TOKEN(colorStyle): + mrModel.mnId = rAttribs.getInteger(XML_id, -1); + std::optional<OUString> sMethod = rAttribs.getString(XML_meth); + if (sMethod) + { + if (*sMethod == "cycle") + { + mrModel.meMethod = ColorStyleMethod::CYCLE; + } + else if (*sMethod == "withinLinear") + { + mrModel.meMethod = ColorStyleMethod::WITHIN_LINEAR; + } + else if (*sMethod == "acrossLinear") + { + mrModel.meMethod = ColorStyleMethod::ACROSS_LINEAR; + } + else if (*sMethod == "withinLinearReversed") + { + mrModel.meMethod = ColorStyleMethod::WITHIN_LINEAR_REVERSED; + } + else if (*sMethod == "acrossLinearReversed") + { + mrModel.meMethod = ColorStyleMethod::ACROSS_LINEAR_REVERSED; + } + else + { + assert(false); + } + } + return this; + } + break; + + case CS_TOKEN(colorStyle): + switch (nElement) + { + case A_TOKEN(scrgbClr): + case A_TOKEN(srgbClr): + case A_TOKEN(hslClr): + case A_TOKEN(sysClr): + case A_TOKEN(schemeClr): + case A_TOKEN(prstClr): + mrModel.maColors.emplace_back(); + mrModel.maComplexColors.emplace_back(); + return new ColorValueContext(*this, &mrModel.maColors.back(), + &mrModel.maComplexColors.back()); + + case CS_TOKEN(variation): + // "variation"s presumably apply to the preceding color entry + return new VariationContext(*this, &mrModel.maColors.back(), + &mrModel.maComplexColors.back()); + } + break; + } + return nullptr; +} + } // namespace oox::drawingml::chart /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/colorchoicecontext.cxx b/oox/source/drawingml/colorchoicecontext.cxx index 41c2180a1a87..3122d7917f4f 100644 --- a/oox/source/drawingml/colorchoicecontext.cxx +++ b/oox/source/drawingml/colorchoicecontext.cxx @@ -282,6 +282,38 @@ ColorContext::ColorContext(ContextHandler2Helper const & rParent, Color* pColor, return nullptr; } +//=========== +// VariationContext +//=========== + +VariationContext::VariationContext(ContextHandler2Helper const & rParent, + Color* pColor, model::ComplexColor* pComplexColor) + : ColorValueContext(rParent, pColor, pComplexColor) + , mpColor(pColor) + , mpComplexColor(pComplexColor) +{ +} + +::oox::core::ContextHandlerRef VariationContext::onCreateContext( + sal_Int32 nElement, const AttributeList& ) +{ + switch( nElement ) + { + case A_TOKEN( scrgbClr ): + case A_TOKEN( srgbClr ): + case A_TOKEN( hslClr ): + case A_TOKEN( sysClr ): + case A_TOKEN( schemeClr ): + case A_TOKEN( prstClr ): + return new ColorValueContext(*this, mpColor, mpComplexColor); + } + return nullptr; +} + +//=========== +// ColorsContext +//=========== + ColorsContext::ColorsContext(ContextHandler2Helper const& rParent, std::vector<Color>& rColors) : ContextHandler2(rParent) , mrColors(rColors) diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index dedfffde0f48..ff2d2edabea7 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -39,6 +39,7 @@ #include <drawingml/chart/chartspacefragment.hxx> #include <drawingml/chart/stylefragment.hxx> #include <drawingml/chart/stylemodel.hxx> +#include <drawingml/chart/colorsmodel.hxx> #include <drawingml/chart/chartspacemodel.hxx> #include <o3tl/safeint.hxx> #include <o3tl/unit_conversion.hxx> @@ -91,6 +92,7 @@ #include <com/sun/star/table/ShadowFormat.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/chart2/XChartStyle.hpp> +#include <com/sun/star/chart2/XChartColorStyle.hpp> #include <com/sun/star/style/ParagraphAdjust.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/lang/Locale.hpp> @@ -2660,6 +2662,19 @@ void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rFilter, sStylePath, aStyleModel ); rFilter.importFragment( pStyleFragment ); + // Import colors file. + OUString sColorPath(pFPath, nLastSlash + 1); + sColorPath += u"colors"_ustr; + sChartFName = sFullPath.copy(nLastSlash + 1, sFullPath.getLength() - nLastSlash - 1); + sColorPath += sNumber; + sColorPath += u".xml"_ustr; + + chart::ColorStyleModel aColorsModel; + rtl::Reference<chart::ColorsFragment> pColorsFragment = + new chart::ColorsFragment( rFilter, sColorPath, aColorsModel ); + rFilter.importFragment( pColorsFragment ); + + // The original theme. ThemePtr pTheme; const OUString aThemeOverrideFragmentPath( pChartSpaceFragment-> @@ -2708,6 +2723,9 @@ void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& // convert chart style model to docmodel style data Reference<com::sun::star::chart2::XChartStyle> xStyle = xChartDoc->getStyles(); oox::drawingml::chart::ChartStyleConverter::convertFromModel(rFilter, aStyleModel, xStyle); + // convert color style model to docmodel colors data + Reference<com::sun::star::chart2::XChartColorStyle> xCStyle = xChartDoc->getColorStyles(); + oox::drawingml::chart::ChartColorStyleConverter::convertFromModel(rFilter, aColorsModel, xCStyle); if (pPowerPointImport) { diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index ad4141186896..083b304f5ec4 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -32,6 +32,8 @@ #include <cstdio> #include <limits> +#include <tools/UnitConversion.hxx> + #include <com/sun/star/awt/Gradient2.hpp> #include <com/sun/star/chart/XChartDocument.hpp> #include <com/sun/star/chart/ChartLegendPosition.hpp> @@ -115,9 +117,12 @@ #include <o3tl/temporary.hxx> #include <o3tl/sorted_vector.hxx> +#include <o3tl/enumrange.hxx> #include <docmodel/styles/ChartStyle.hxx> #include <docmodel/uno/UnoChartStyle.hxx> +#include <docmodel/styles/ChartColorStyle.hxx> +#include <docmodel/uno/UnoChartColorStyle.hxx> #include <oox/export/ThemeExport.hxx> @@ -1282,16 +1287,47 @@ void ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nI SetFS( pColorStyle ); pFS = GetFS(); - pFS->startElement(FSNS(XML_cs, XML_colorStyle), - FSNS( XML_xmlns, XML_cs ), pFB->getNamespaceURL(OOX_NS(cs)), - FSNS( XML_xmlns, XML_a ), pFB->getNamespaceURL(OOX_NS(dml)), - XML_meth, "cycle", - XML_id, "10" /* no idea what this number is supposed to be */); + Reference<com::sun::star::chart2::XChartColorStyle> xColorStyle = xChartDoc->getColorStyles(); + model::ColorStyleSet* aCSS = model::style::getFromXChartColorStyle(xColorStyle); + + if (!aCSS->maEntryList.empty()) { + // use the stored data in the document model + + static const std::map<model::ColorStyleMethod, std::string> aMethMap { + { model::ColorStyleMethod::CYCLE, "cycle" }, + { model::ColorStyleMethod::WITHIN_LINEAR, "withinLinear" }, + { model::ColorStyleMethod::ACROSS_LINEAR, "acrossLinear" }, + { model::ColorStyleMethod::WITHIN_LINEAR_REVERSED, "withinLinearReversed" }, + { model::ColorStyleMethod::ACROSS_LINEAR_REVERSED, "acrossLinearReversed" } + }; + + for (const model::ColorStyleEntry& rCStyleEntry : aCSS->maEntryList) { + pFS->startElement(FSNS(XML_cs, XML_colorStyle), + FSNS( XML_xmlns, XML_cs ), pFB->getNamespaceURL(OOX_NS(cs)), + FSNS( XML_xmlns, XML_a ), pFB->getNamespaceURL(OOX_NS(dml)), + XML_meth, aMethMap.at(rCStyleEntry.meMethod).c_str(), + XML_id, OUString::number(rCStyleEntry.mnId)); + + ThemeExport aTE(mpFB, GetDocumentType(), pFS); + for (const model::ComplexColor& rColor : rCStyleEntry.maComplexColors) { + aTE.writeComplexColor(rColor); + } - pFS->singleElement(FSNS(XML_a, XML_schemeClr), - XML_val, "accent1"); + pFS->endElement(FSNS(XML_cs, XML_colorStyle)); + } + } else { + // output a default value to make MS Office happy + pFS->startElement(FSNS(XML_cs, XML_colorStyle), + FSNS( XML_xmlns, XML_cs ), pFB->getNamespaceURL(OOX_NS(cs)), + FSNS( XML_xmlns, XML_a ), pFB->getNamespaceURL(OOX_NS(dml)), + XML_meth, "cycle", + XML_id, "10" /* no idea what this number is supposed to be */); - pFS->endElement(FSNS(XML_cs, XML_colorStyle)); + pFS->singleElement(FSNS(XML_a, XML_schemeClr), + XML_val, "accent1"); + + pFS->endElement(FSNS(XML_cs, XML_colorStyle)); + } pColorStyle->endDocument(); diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index 900cc8c74ecc..25b7aa189190 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -5727,6 +5727,7 @@ varScale varSubtotal variable variant +variation varp varyColors vbProcedure
