sc: support reading sparklines from OOXML document
Read sparklines and sparkline groups from the OOXML document and add store it into a (temporary local) doc. model. Change-Id: Id2d34db70300957735571875d6defb3d560fbb26 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131161 Tested-by: Tomaž Vajngerl <quikee@gmail.com> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
committed by
Tomaž Vajngerl
parent
f35d1a9f16
commit
04b3a9baf5
@@ -1291,9 +1291,17 @@ collapsedLevelsAreSubtotals
|
|||||||
colon
|
colon
|
||||||
color
|
color
|
||||||
color2
|
color2
|
||||||
|
colorAxis
|
||||||
colorFilter
|
colorFilter
|
||||||
|
colorFirst
|
||||||
|
colorHigh
|
||||||
colorId
|
colorId
|
||||||
|
colorLast
|
||||||
|
colorLow
|
||||||
|
colorMarkers
|
||||||
|
colorNegative
|
||||||
colorScale
|
colorScale
|
||||||
|
colorSeries
|
||||||
colorTemp
|
colorTemp
|
||||||
colorTemperature
|
colorTemperature
|
||||||
colormenu
|
colormenu
|
||||||
@@ -1662,6 +1670,7 @@ datastoreItem
|
|||||||
date
|
date
|
||||||
date1904
|
date1904
|
||||||
dateAx
|
dateAx
|
||||||
|
dateAxis
|
||||||
dateBetween
|
dateBetween
|
||||||
dateCompatibility
|
dateCompatibility
|
||||||
dateEqual
|
dateEqual
|
||||||
@@ -1825,12 +1834,15 @@ dispUnitsLbl
|
|||||||
displacedByCustomXml
|
displacedByCustomXml
|
||||||
display
|
display
|
||||||
displayBackgroundShape
|
displayBackgroundShape
|
||||||
|
displayEmptyCellsAs
|
||||||
displayFolder
|
displayFolder
|
||||||
displayHangulFixedWidth
|
displayHangulFixedWidth
|
||||||
|
displayHidden
|
||||||
displayHorizontalDrawingGridEvery
|
displayHorizontalDrawingGridEvery
|
||||||
displayName
|
displayName
|
||||||
displayText
|
displayText
|
||||||
displayVerticalDrawingGridEvery
|
displayVerticalDrawingGridEvery
|
||||||
|
displayXAxis
|
||||||
displayed
|
displayed
|
||||||
dissolve
|
dissolve
|
||||||
dist
|
dist
|
||||||
@@ -3136,6 +3148,7 @@ lineMarker
|
|||||||
linePitch
|
linePitch
|
||||||
lineRule
|
lineRule
|
||||||
lineTo
|
lineTo
|
||||||
|
lineWeight
|
||||||
lineWrapLikeWord6
|
lineWrapLikeWord6
|
||||||
linear
|
linear
|
||||||
linen
|
linen
|
||||||
@@ -3283,6 +3296,8 @@ manifestLocation
|
|||||||
manual
|
manual
|
||||||
manualBreakCount
|
manualBreakCount
|
||||||
manualLayout
|
manualLayout
|
||||||
|
manualMax
|
||||||
|
manualMin
|
||||||
map
|
map
|
||||||
mapId
|
mapId
|
||||||
mapPins
|
mapPins
|
||||||
@@ -3303,6 +3318,7 @@ marTop
|
|||||||
marW
|
marW
|
||||||
margin
|
margin
|
||||||
marker
|
marker
|
||||||
|
markers
|
||||||
markup
|
markup
|
||||||
maroon
|
maroon
|
||||||
marquee
|
marquee
|
||||||
@@ -3325,6 +3341,7 @@ mathPr
|
|||||||
matrix
|
matrix
|
||||||
matte
|
matte
|
||||||
max
|
max
|
||||||
|
maxAxisType
|
||||||
maxAng
|
maxAng
|
||||||
maxDate
|
maxDate
|
||||||
maxDepth
|
maxDepth
|
||||||
@@ -3402,6 +3419,7 @@ middleDot
|
|||||||
midnightBlue
|
midnightBlue
|
||||||
millions
|
millions
|
||||||
min
|
min
|
||||||
|
minAxisType
|
||||||
minAng
|
minAng
|
||||||
minDate
|
minDate
|
||||||
minLength
|
minLength
|
||||||
@@ -3505,6 +3523,7 @@ nc
|
|||||||
nd
|
nd
|
||||||
ndxf
|
ndxf
|
||||||
neCell
|
neCell
|
||||||
|
negative
|
||||||
negativeBarColorSameAsPositive
|
negativeBarColorSameAsPositive
|
||||||
negativeFillColor
|
negativeFillColor
|
||||||
negativeInteger
|
negativeInteger
|
||||||
@@ -4868,6 +4887,10 @@ span
|
|||||||
spanAng
|
spanAng
|
||||||
spans
|
spans
|
||||||
sparkle
|
sparkle
|
||||||
|
sparklineGroups
|
||||||
|
sparklineGroup
|
||||||
|
sparklines
|
||||||
|
sparkline
|
||||||
spc
|
spc
|
||||||
spcAft
|
spcAft
|
||||||
spcBef
|
spcBef
|
||||||
@@ -5488,6 +5511,7 @@ ui8
|
|||||||
uiCompat97To2003
|
uiCompat97To2003
|
||||||
uiExpand
|
uiExpand
|
||||||
uiPriority
|
uiPriority
|
||||||
|
uid
|
||||||
uint
|
uint
|
||||||
ulTrailSpace
|
ulTrailSpace
|
||||||
un
|
un
|
||||||
|
@@ -202,6 +202,7 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\
|
|||||||
sc/source/filter/oox/sharedstringsfragment \
|
sc/source/filter/oox/sharedstringsfragment \
|
||||||
sc/source/filter/oox/sheetdatabuffer \
|
sc/source/filter/oox/sheetdatabuffer \
|
||||||
sc/source/filter/oox/sheetdatacontext \
|
sc/source/filter/oox/sheetdatacontext \
|
||||||
|
sc/source/filter/oox/SparklineFragment \
|
||||||
sc/source/filter/oox/stylesbuffer \
|
sc/source/filter/oox/stylesbuffer \
|
||||||
sc/source/filter/oox/stylesfragment \
|
sc/source/filter/oox/stylesfragment \
|
||||||
sc/source/filter/oox/tablebuffer \
|
sc/source/filter/oox/tablebuffer \
|
||||||
|
94
sc/source/filter/inc/SparklineFragment.hxx
Normal file
94
sc/source/filter/inc/SparklineFragment.hxx
Normal file
@@ -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: */
|
189
sc/source/filter/oox/SparklineFragment.cxx
Normal file
189
sc/source/filter/oox/SparklineFragment.cxx
Normal file
@@ -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: */
|
@@ -22,6 +22,7 @@
|
|||||||
#include <workbookfragment.hxx>
|
#include <workbookfragment.hxx>
|
||||||
#include <stylesbuffer.hxx>
|
#include <stylesbuffer.hxx>
|
||||||
#include <stylesfragment.hxx>
|
#include <stylesfragment.hxx>
|
||||||
|
#include <SparklineFragment.hxx>
|
||||||
|
|
||||||
#include <rangeutl.hxx>
|
#include <rangeutl.hxx>
|
||||||
#include <sal/log.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(conditionalFormatting): return new ExtConditionalFormattingContext(*this);
|
||||||
case XLS14_TOKEN(dataValidations): return new ExtDataValidationsContext(*this);
|
case XLS14_TOKEN(dataValidations): return new ExtDataValidationsContext(*this);
|
||||||
|
case XLS14_TOKEN(sparklineGroups): return new SparklineGroupsContext(*this);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user