diff options
-rw-r--r-- | oox/source/token/tokens.txt | 24 | ||||
-rw-r--r-- | sc/Library_scfilt.mk | 1 | ||||
-rw-r--r-- | sc/source/filter/inc/SparklineFragment.hxx | 94 | ||||
-rw-r--r-- | sc/source/filter/oox/SparklineFragment.cxx | 189 | ||||
-rw-r--r-- | sc/source/filter/oox/extlstcontext.cxx | 2 |
5 files changed, 310 insertions, 0 deletions
diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index 9a10000c1fc8..593ef0b23a5d 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -1291,9 +1291,17 @@ collapsedLevelsAreSubtotals colon color color2 +colorAxis colorFilter +colorFirst +colorHigh colorId +colorLast +colorLow +colorMarkers +colorNegative colorScale +colorSeries colorTemp colorTemperature colormenu @@ -1662,6 +1670,7 @@ datastoreItem date date1904 dateAx +dateAxis dateBetween dateCompatibility dateEqual @@ -1825,12 +1834,15 @@ dispUnitsLbl displacedByCustomXml display displayBackgroundShape +displayEmptyCellsAs displayFolder displayHangulFixedWidth +displayHidden displayHorizontalDrawingGridEvery displayName displayText displayVerticalDrawingGridEvery +displayXAxis displayed dissolve dist @@ -3136,6 +3148,7 @@ lineMarker linePitch lineRule lineTo +lineWeight lineWrapLikeWord6 linear linen @@ -3283,6 +3296,8 @@ manifestLocation manual manualBreakCount manualLayout +manualMax +manualMin map mapId mapPins @@ -3303,6 +3318,7 @@ marTop marW margin marker +markers markup maroon marquee @@ -3325,6 +3341,7 @@ mathPr matrix matte max +maxAxisType maxAng maxDate maxDepth @@ -3402,6 +3419,7 @@ middleDot midnightBlue millions min +minAxisType minAng minDate minLength @@ -3505,6 +3523,7 @@ nc nd ndxf neCell +negative negativeBarColorSameAsPositive negativeFillColor negativeInteger @@ -4868,6 +4887,10 @@ span spanAng spans sparkle +sparklineGroups +sparklineGroup +sparklines +sparkline spc spcAft spcBef @@ -5488,6 +5511,7 @@ ui8 uiCompat97To2003 uiExpand uiPriority +uid uint ulTrailSpace un diff --git a/sc/Library_scfilt.mk b/sc/Library_scfilt.mk index 79170313b121..8e23db6662fa 100644 --- a/sc/Library_scfilt.mk +++ b/sc/Library_scfilt.mk @@ -202,6 +202,7 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\ sc/source/filter/oox/sharedstringsfragment \ sc/source/filter/oox/sheetdatabuffer \ sc/source/filter/oox/sheetdatacontext \ + sc/source/filter/oox/SparklineFragment \ sc/source/filter/oox/stylesbuffer \ sc/source/filter/oox/stylesfragment \ sc/source/filter/oox/tablebuffer \ diff --git a/sc/source/filter/inc/SparklineFragment.hxx b/sc/source/filter/inc/SparklineFragment.hxx new file mode 100644 index 000000000000..36a7b5ca9f05 --- /dev/null +++ b/sc/source/filter/inc/SparklineFragment.hxx @@ -0,0 +1,94 @@ +/* -*- 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 "excelhandlers.hxx" +#include <oox/core/contexthandler.hxx> + +#include <vector> +#include <memory> +#include <optional> + +namespace oox +{ +class AttributeList; +} + +namespace oox::xls +{ +class Sparkline +{ +public: + ScRangeList m_aInputRange; + ScRangeList m_aTargetRange; + Sparkline() {} +}; + +class SparklineGroup +{ +private: + std::vector<Sparkline> m_aSparklines; + +public: + Color m_aColorSeries; + Color m_aColorNegative; + Color m_aColorAxis; + Color m_aColorMarkers; + Color m_aColorFirst; + Color m_aColorLast; + Color m_aColorHigh; + Color m_aColorLow; + + OUString m_sMinAxisType; // individual, group, custom + OUString m_sMaxAxisType; + + double m_fLineWeight; // In pt + + OUString m_sType; // line, column, stacked + + bool m_bDateAxis; + + OUString m_sDisplayEmptyCellsAs; // span, gap, zero + + bool m_bMarkers; + bool m_bHigh; + bool m_bLow; + bool m_bFirst; + bool m_bLast; + bool m_bNegative; + bool m_bDisplayXAxis; + bool m_bDisplayHidden; + bool m_bRightToLeft; + + std::optional<double> m_aManualMax; + std::optional<double> m_aManualMin; + OUString m_sUID; + + std::vector<Sparkline>& getSparklines() { return m_aSparklines; } +}; + +class SparklineGroupsContext : public WorksheetContextBase +{ +private: + std::vector<SparklineGroup> m_aSparklineGroups; + +public: + explicit SparklineGroupsContext(WorksheetContextBase& rFragment); + + oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, + const AttributeList& rAttribs) override; + void onStartElement(const AttributeList& rAttribs) override; + void onCharacters(const OUString& rCharacters) override; + void onEndElement() override; +}; + +} //namespace oox::xls + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/oox/SparklineFragment.cxx b/sc/source/filter/oox/SparklineFragment.cxx new file mode 100644 index 000000000000..a743b886b7db --- /dev/null +++ b/sc/source/filter/oox/SparklineFragment.cxx @@ -0,0 +1,189 @@ +/* -*- 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 <SparklineFragment.hxx> +#include <oox/core/contexthandler.hxx> +#include <oox/token/tokens.hxx> +#include <oox/token/namespaces.hxx> +#include <oox/helper/helper.hxx> +#include <oox/helper/attributelist.hxx> +#include <document.hxx> +#include <rangeutl.hxx> + +using ::oox::core::ContextHandlerRef; + +namespace oox::xls +{ +namespace +{ +Color getColor(const AttributeList& rAttribs) +{ + if (rAttribs.hasAttribute(XML_rgb)) + { + return Color(ColorTransparency, + rAttribs.getIntegerHex(XML_rgb, sal_Int32(API_RGB_TRANSPARENT))); + } + return Color(); +} + +void addColorsToSparklineGroup(SparklineGroup& rSparklineGroup, sal_Int32 nElement, + const AttributeList& rAttribs) +{ + switch (nElement) + { + case XLS14_TOKEN(colorSeries): + rSparklineGroup.m_aColorSeries = getColor(rAttribs); + break; + case XLS14_TOKEN(colorNegative): + rSparklineGroup.m_aColorNegative = getColor(rAttribs); + break; + case XLS14_TOKEN(colorAxis): + rSparklineGroup.m_aColorAxis = getColor(rAttribs); + break; + case XLS14_TOKEN(colorMarkers): + rSparklineGroup.m_aColorMarkers = getColor(rAttribs); + break; + case XLS14_TOKEN(colorFirst): + rSparklineGroup.m_aColorFirst = getColor(rAttribs); + break; + case XLS14_TOKEN(colorLast): + rSparklineGroup.m_aColorLast = getColor(rAttribs); + break; + case XLS14_TOKEN(colorHigh): + rSparklineGroup.m_aColorHigh = getColor(rAttribs); + break; + case XLS14_TOKEN(colorLow): + rSparklineGroup.m_aColorLow = getColor(rAttribs); + break; + default: + break; + } +} + +void addAttributesToSparklineGroup(SparklineGroup& rSparklineGroup, const AttributeList& rAttribs) +{ + auto oManualMax = rAttribs.getDouble(XML_manualMax); + auto oManualMin = rAttribs.getDouble(XML_manualMin); + + rSparklineGroup.m_fLineWeight = rAttribs.getDouble(XML_lineWeight, 0.75); + + rSparklineGroup.m_sType = rAttribs.getString(XML_type, "line"); + + rSparklineGroup.m_bDateAxis = rAttribs.getBool(XML_dateAxis, false); + + rSparklineGroup.m_sDisplayEmptyCellsAs = rAttribs.getString(XML_displayEmptyCellsAs, "zero"); + + rSparklineGroup.m_bMarkers = rAttribs.getBool(XML_markers, false); + rSparklineGroup.m_bHigh = rAttribs.getBool(XML_high, false); + rSparklineGroup.m_bLow = rAttribs.getBool(XML_low, false); + rSparklineGroup.m_bFirst = rAttribs.getBool(XML_first, false); + rSparklineGroup.m_bLast = rAttribs.getBool(XML_last, false); + rSparklineGroup.m_bNegative = rAttribs.getBool(XML_negative, false); + rSparklineGroup.m_bDisplayXAxis = rAttribs.getBool(XML_displayXAxis, false); + rSparklineGroup.m_bDisplayHidden = rAttribs.getBool(XML_displayHidden, false); + + rSparklineGroup.m_sMinAxisType = rAttribs.getString(XML_minAxisType, "individual"); + rSparklineGroup.m_sMaxAxisType = rAttribs.getString(XML_maxAxisType, "individual"); + + rSparklineGroup.m_bRightToLeft = rAttribs.getBool(XML_rightToLeft, false); + + rSparklineGroup.m_sUID = rAttribs.getString(XML_uid, OUString()); + + if (rSparklineGroup.m_sMaxAxisType == "custom") + rSparklineGroup.m_aManualMax = oManualMax.get(); + if (rSparklineGroup.m_sMinAxisType == "custom") + rSparklineGroup.m_aManualMin = oManualMin.get(); +} + +} // end anonymous namespace + +SparklineGroupsContext::SparklineGroupsContext(WorksheetContextBase& rFragment) + : WorksheetContextBase(rFragment) +{ +} + +ContextHandlerRef SparklineGroupsContext::onCreateContext(sal_Int32 nElement, + const AttributeList& rAttribs) +{ + switch (nElement) + { + case XLS14_TOKEN(sparklineGroup): + { + auto& rLastGroup = m_aSparklineGroups.emplace_back(); + addAttributesToSparklineGroup(rLastGroup, rAttribs); + return this; + } + case XLS14_TOKEN(colorSeries): + case XLS14_TOKEN(colorNegative): + case XLS14_TOKEN(colorAxis): + case XLS14_TOKEN(colorMarkers): + case XLS14_TOKEN(colorFirst): + case XLS14_TOKEN(colorLast): + case XLS14_TOKEN(colorHigh): + case XLS14_TOKEN(colorLow): + { + auto& rLastGroup = m_aSparklineGroups.back(); + addColorsToSparklineGroup(rLastGroup, nElement, rAttribs); + return this; + } + case XLS14_TOKEN(sparklines): + { + return this; + } + case XLS14_TOKEN(sparkline): + { + auto& rLastGroup = m_aSparklineGroups.back(); + rLastGroup.getSparklines().emplace_back(); + return this; + } + } + return this; +} + +void SparklineGroupsContext::onStartElement(const AttributeList&) {} + +void SparklineGroupsContext::onCharacters(const OUString& rChars) +{ + if (getCurrentElement() == XM_TOKEN(sqref) || getCurrentElement() == XM_TOKEN(f)) + { + ScDocument& rDocument = getScDocument(); + auto& rLastGroup = m_aSparklineGroups.back(); + auto& rLastSparkline = rLastGroup.getSparklines().back(); + + ScRangeList aRange; + if (ScRangeStringConverter::GetRangeListFromString(aRange, rChars, rDocument, + formula::FormulaGrammar::CONV_XL_OOX)) + { + if (!aRange.empty()) + { + if (getCurrentElement() == XM_TOKEN(sqref)) + { + rLastSparkline.m_aTargetRange = aRange; + + // Need to set the current sheet index to the range as + // it is assumed that the address string referes to + // the current sheet and is not defined in the string. + for (auto& rRange : rLastSparkline.m_aTargetRange) + { + rRange.aStart.SetTab(getSheetIndex()); + rRange.aEnd.SetTab(getSheetIndex()); + } + } + else if (getCurrentElement() == XM_TOKEN(f)) + rLastSparkline.m_aInputRange = aRange; + } + } + } +} + +void SparklineGroupsContext::onEndElement() {} + +} //namespace oox::xls + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/oox/extlstcontext.cxx b/sc/source/filter/oox/extlstcontext.cxx index eee453a7242c..67d52fc69da9 100644 --- a/sc/source/filter/oox/extlstcontext.cxx +++ b/sc/source/filter/oox/extlstcontext.cxx @@ -22,6 +22,7 @@ #include <workbookfragment.hxx> #include <stylesbuffer.hxx> #include <stylesfragment.hxx> +#include <SparklineFragment.hxx> #include <rangeutl.hxx> #include <sal/log.hxx> @@ -350,6 +351,7 @@ ContextHandlerRef ExtGlobalContext::onCreateContext( sal_Int32 nElement, const A { case XLS14_TOKEN(conditionalFormatting): return new ExtConditionalFormattingContext(*this); case XLS14_TOKEN(dataValidations): return new ExtDataValidationsContext(*this); + case XLS14_TOKEN(sparklineGroups): return new SparklineGroupsContext(*this); } return this; } |