summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--oox/source/token/tokens.txt24
-rw-r--r--sc/Library_scfilt.mk1
-rw-r--r--sc/source/filter/inc/SparklineFragment.hxx94
-rw-r--r--sc/source/filter/oox/SparklineFragment.cxx189
-rw-r--r--sc/source/filter/oox/extlstcontext.cxx2
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;
}