[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - 3 commits - chart2/source download.lst include/oox include/xmloff offapi/com oox/inc oox/source schema/libreoffice svx/uiconfig xmloff/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Mon Aug 30 08:31:05 UTC 2021
chart2/source/model/main/FormattedString.cxx | 18 +
chart2/source/model/main/FormattedString.hxx | 3
chart2/source/view/charttypes/VSeriesPlotter.cxx | 25 +
download.lst | 4
include/oox/export/chartexport.hxx | 26 +-
include/xmloff/xmltoken.hxx | 2
offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl | 10
oox/inc/drawingml/chart/datasourcecontext.hxx | 1
oox/inc/drawingml/chart/seriesmodel.hxx | 15 +
oox/source/drawingml/chart/datasourcecontext.cxx | 21 +
oox/source/drawingml/chart/seriescontext.cxx | 55 +++-
oox/source/drawingml/chart/seriesconverter.cxx | 51 +++-
oox/source/drawingml/chart/seriesmodel.cxx | 4
oox/source/export/chartexport.cxx | 153 +++++++++++-
oox/source/token/tokens.txt | 3
schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng | 12
svx/uiconfig/ui/sidebarparagraph.ui | 18 -
xmloff/source/chart/SchXMLExport.cxx | 78 +++++-
xmloff/source/chart/SchXMLPlotAreaContext.cxx | 21 +
xmloff/source/chart/SchXMLPlotAreaContext.hxx | 4
xmloff/source/chart/SchXMLSeries2Context.cxx | 25 +
xmloff/source/chart/transporttypes.hxx | 10
xmloff/source/core/xmltoken.cxx | 2
xmloff/source/token/tokens.txt | 2
24 files changed, 499 insertions(+), 64 deletions(-)
New commits:
commit 74324c80b33d20721285bd1e4afe244082ae468e
Author: Michael Stahl <michael.stahl at allotropia.de>
AuthorDate: Wed Aug 25 11:16:46 2021 +0200
Commit: Andras Timar <andras.timar at collabora.com>
CommitDate: Mon Aug 30 10:27:16 2021 +0200
openssl: upgrade to release 1.1.1l
Fixes CVE-2021-3712, CVE-2021-3711 (not obvious if any of them affect LO)
Change-Id: I98652348977a5a3c728f1d4fdf7293b76a93b630
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121026
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at allotropia.de>
(cherry picked from commit 5c391f4346e86bd5d7528fbb42a3af64f98a03d3)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120987
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/download.lst b/download.lst
index a2a08016976e..82dc3e21626f 100644
--- a/download.lst
+++ b/download.lst
@@ -226,8 +226,8 @@ export OFFICEOTRON_SHA256SUM := f2443f27561af52324eee03a1892d9f569adc8db9e7bca55
export OFFICEOTRON_JAR := 8249374c274932a21846fa7629c2aa9b-officeotron-0.7.4-master.jar
export OPENLDAP_SHA256SUM := cdd6cffdebcd95161a73305ec13fc7a78e9707b46ca9f84fb897cd5626df3824
export OPENLDAP_TARBALL := openldap-2.4.45.tgz
-export OPENSSL_SHA256SUM := 892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5
-export OPENSSL_TARBALL := openssl-1.1.1k.tar.gz
+export OPENSSL_SHA256SUM := 0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1
+export OPENSSL_TARBALL := openssl-1.1.1l.tar.gz
export ORCUS_SHA256SUM := c700d1325f744104d9fca0d5a019434901e9d51a16eedfb05792f90a298587a4
export ORCUS_TARBALL := liborcus-0.16.1.tar.bz2
export OWNCLOUD_ANDROID_LIB_SHA256SUM := b18b3e3ef7fae6a79b62f2bb43cc47a5346b6330f6a383dc4be34439aca5e9fb
commit 5b04f8fbd7e9e41c653734b03c9c930b5d75908b
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Aug 26 16:12:42 2021 +0100
Commit: Andras Timar <andras.timar at collabora.com>
CommitDate: Mon Aug 30 10:27:10 2021 +0200
tdf#139660 one of the group needs to be active
in this case using ToolButtons instead of ToggleToolButtons will work ok
Change-Id: I806a8fc409ae346dd6734be13d69c4b171e54c08
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121123
Tested-by: Jenkins
Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>
diff --git a/svx/uiconfig/ui/sidebarparagraph.ui b/svx/uiconfig/ui/sidebarparagraph.ui
index 2db34a7d6ef3..1f34c35b1c67 100644
--- a/svx/uiconfig/ui/sidebarparagraph.ui
+++ b/svx/uiconfig/ui/sidebarparagraph.ui
@@ -55,7 +55,7 @@
<property name="show_arrow">False</property>
<property name="icon_size">2</property>
<child>
- <object class="GtkToggleToolButton" id=".uno:LeftPara">
+ <object class="GtkToolButton" id=".uno:LeftPara">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -66,7 +66,7 @@
</packing>
</child>
<child>
- <object class="GtkToggleToolButton" id=".uno:CenterPara">
+ <object class="GtkToolButton" id=".uno:CenterPara">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -77,7 +77,7 @@
</packing>
</child>
<child>
- <object class="GtkToggleToolButton" id=".uno:RightPara">
+ <object class="GtkToolButton" id=".uno:RightPara">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -88,7 +88,7 @@
</packing>
</child>
<child>
- <object class="GtkToggleToolButton" id=".uno:JustifyPara">
+ <object class="GtkToolButton" id=".uno:JustifyPara">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -115,7 +115,7 @@
<property name="show_arrow">False</property>
<property name="icon_size">2</property>
<child>
- <object class="GtkToggleToolButton" id=".uno:ParaLeftToRight">
+ <object class="GtkToolButton" id=".uno:ParaLeftToRight">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -126,7 +126,7 @@
</packing>
</child>
<child>
- <object class="GtkToggleToolButton" id=".uno:ParaRightToLeft">
+ <object class="GtkToolButton" id=".uno:ParaRightToLeft">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -152,7 +152,7 @@
<property name="show_arrow">False</property>
<property name="icon_size">2</property>
<child>
- <object class="GtkToggleToolButton" id=".uno:CellVertTop">
+ <object class="GtkToolButton" id=".uno:CellVertTop">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -163,7 +163,7 @@
</packing>
</child>
<child>
- <object class="GtkToggleToolButton" id=".uno:CellVertCenter">
+ <object class="GtkToolButton" id=".uno:CellVertCenter">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
@@ -174,7 +174,7 @@
</packing>
</child>
<child>
- <object class="GtkToggleToolButton" id=".uno:CellVertBottom">
+ <object class="GtkToolButton" id=".uno:CellVertBottom">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
commit 2ca9ba73573a1b579b1711ce72dc5859d2dfea52
Author: Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Wed Aug 25 20:51:56 2021 +0530
Commit: Andras Timar <andras.timar at collabora.com>
CommitDate: Mon Aug 30 10:26:40 2021 +0200
tdf#143942: oox: import/export labels from <c15:datalabelsRange>
When <c15:showDataLabelsRange> boolean flag is present, the imported
label texts are added as the first text field in oox data label model.
The cell-range associated is also preserved. The export part preserves
the how labels were store originally in <c15:datalabelsRange>.
However in order to make the custom labels reflect the contents of the
cells in the associated cell-range, more work needs to be done. For this
the labels present in <c15:datalabelsRange> needs to be made available
as a data-sequence with a new "role" like "point-labels" in
XInternalDataProvider implementation and and make the label renderer
read this data source rather than consulting the custom label fields
property which is static after import.
Change-Id: Ibc7045fa5ea209d463680c96efb49a06662d2500
diff --git a/chart2/source/model/main/FormattedString.cxx b/chart2/source/model/main/FormattedString.cxx
index 0d6e733a2c31..55960c081336 100644
--- a/chart2/source/model/main/FormattedString.cxx
+++ b/chart2/source/model/main/FormattedString.cxx
@@ -100,6 +100,7 @@ FormattedString::FormattedString() :
m_aString(),
m_aType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT),
m_aGuid(),
+ m_bDataLabelsRange(false),
m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
{}
@@ -109,6 +110,7 @@ FormattedString::FormattedString( const FormattedString & rOther ) :
m_aString( rOther.m_aString ),
m_aType(rOther.m_aType),
m_aGuid(rOther.m_aGuid),
+ m_bDataLabelsRange(rOther.m_bDataLabelsRange),
m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
{}
@@ -174,6 +176,22 @@ void SAL_CALL FormattedString::setGuid( const OUString& guid )
}
+sal_Bool SAL_CALL FormattedString::getDataLabelsRange()
+{
+ MutexGuard aGuard( m_aMutex);
+ return m_bDataLabelsRange;
+}
+
+void SAL_CALL FormattedString::setDataLabelsRange( sal_Bool dataLabelsRange )
+{
+ {
+ MutexGuard aGuard( m_aMutex);
+ m_bDataLabelsRange = dataLabelsRange;
+ }
+ //don't keep the mutex locked while calling out
+ fireModifyEvent();
+}
+
// ____ XModifyBroadcaster ____
void SAL_CALL FormattedString::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
{
diff --git a/chart2/source/model/main/FormattedString.hxx b/chart2/source/model/main/FormattedString.hxx
index a7f9e36bb134..763c929d6589 100644
--- a/chart2/source/model/main/FormattedString.hxx
+++ b/chart2/source/model/main/FormattedString.hxx
@@ -87,6 +87,8 @@ private:
setFieldType( const css::chart2::DataPointCustomLabelFieldType FieldType ) override;
virtual OUString SAL_CALL getGuid() override;
void SAL_CALL setGuid( const OUString& guid ) override;
+ virtual sal_Bool SAL_CALL getDataLabelsRange() override;
+ virtual void SAL_CALL setDataLabelsRange( sal_Bool dataLabelsRange ) override;
// ____ OPropertySet ____
virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override;
@@ -127,6 +129,7 @@ private:
// ____ XDataPointCustomLabelField ____
css::chart2::DataPointCustomLabelFieldType m_aType;
OUString m_aGuid;
+ bool m_bDataLabelsRange;
css::uno::Reference< css::util::XModifyListener > m_xModifyEventForwarder;
};
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index f405396e113c..6f2b3f820ff5 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -502,6 +502,7 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
Sequence< OUString > aTextList( nTextListLength );
bool bUseCustomLabel = nCustomLabelsCount > 0;
+ size_t nVisibleFieldLen = 0;
if( bUseCustomLabel )
{
nTextListLength = ( nCustomLabelsCount > 3 ) ? nCustomLabelsCount : 3;
@@ -509,6 +510,8 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
aTextList = Sequence< OUString >( nTextListLength );
for( sal_uInt32 i = 0; i < nCustomLabelsCount; ++i )
{
+ ++nVisibleFieldLen;
+ bool bPreserveContent = false;
switch( aCustomLabels[i]->getFieldType() )
{
case DataPointCustomLabelFieldType_VALUE:
@@ -541,8 +544,16 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
aTextList[i] = getLabelTextForValue(rDataSeries, nPointIndex, fValue, true);
break;
}
- case DataPointCustomLabelFieldType_CELLREF:
case DataPointCustomLabelFieldType_CELLRANGE:
+ {
+ if (aCustomLabels[i]->getDataLabelsRange())
+ {
+ bPreserveContent = true;
+ --nVisibleFieldLen;
+ }
+ }
+ [[fallthrough]];
+ case DataPointCustomLabelFieldType_CELLREF:
{
// TODO: for now doesn't show placeholder
aTextList[i] = OUString();
@@ -561,7 +572,8 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
default:
break;
}
- aCustomLabels[i]->setString( aTextList[i] );
+ if (!bPreserveContent)
+ aCustomLabels[i]->setString( aTextList[i] );
}
}
else
@@ -613,10 +625,13 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
if( bUseCustomLabel )
{
- Sequence< uno::Reference< XFormattedString > > aFormattedLabels( aCustomLabels.getLength() );
- for( int i = 0; i < aFormattedLabels.getLength(); i++ )
+ Sequence< uno::Reference< XFormattedString > > aFormattedLabels( nVisibleFieldLen );
+ int nFormattedIndex = 0;
+ for( int i = 0; i < aCustomLabels.getLength(); i++ )
{
- aFormattedLabels[i] = aCustomLabels[i];
+ if (aCustomLabels[i]->getFieldType() == DataPointCustomLabelFieldType_CELLRANGE && aCustomLabels[i]->getDataLabelsRange())
+ continue;
+ aFormattedLabels[nFormattedIndex++] = aCustomLabels[i];
}
// create text shape
diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx
index b900c68b51a2..3771809c9d87 100644
--- a/include/oox/export/chartexport.hxx
+++ b/include/oox/export/chartexport.hxx
@@ -90,6 +90,29 @@ struct AxisIdPair{
{}
};
+class DataLabelsRange
+{
+public:
+
+ typedef std::map<sal_Int32, OUString> LabelsRangeMap;
+
+ bool empty() const;
+ size_t count() const;
+ bool hasLabel(sal_Int32 nIndex) const;
+ OUString getRange() const;
+
+ void setRange(const OUString& rRange);
+ void setLabel(sal_Int32 nIndex, const OUString& rText);
+
+ LabelsRangeMap::const_iterator begin() const;
+ LabelsRangeMap::const_iterator end() const;
+
+private:
+ OUString maRange;
+ LabelsRangeMap maLabels;
+};
+
+
class OOX_DLLPUBLIC ChartExport final : public DrawingML {
public:
@@ -182,7 +205,8 @@ private:
void exportDataPoints(
const css::uno::Reference< css::beans::XPropertySet >& xSeriesProperties,
sal_Int32 nSeriesLength, sal_Int32 eChartType );
- void exportDataLabels( const css::uno::Reference<css::chart2::XDataSeries>& xSeries, sal_Int32 nSeriesLength, sal_Int32 eChartType );
+ void exportDataLabels( const css::uno::Reference<css::chart2::XDataSeries>& xSeries, sal_Int32 nSeriesLength,
+ sal_Int32 eChartType, DataLabelsRange& rDLblsRange );
void exportGrouping( bool isBar = false );
void exportTrendlines( const css::uno::Reference< css::chart2::XDataSeries >& xSeries );
void exportMarker( const css::uno::Reference< css::beans::XPropertySet >& xPropSet );
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 1b145de4854a..1f4739c770e9 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -574,9 +574,11 @@ namespace xmloff::token {
XML_DATA_BAR_ENTRY,
XML_DATA_CELL_RANGE_ADDRESS,
XML_DATA_LABEL,
+ XML_DATA_LABEL_GUID,
XML_DATA_LABEL_NUMBER,
XML_DATA_LABEL_SYMBOL,
XML_DATA_LABEL_TEXT,
+ XML_DATA_LABELS_CELL_RANGE,
XML_DATA_PILOT_SOURCE,
XML_DATA_PILOT_FIELD,
XML_DATA_PILOT_GRAND_TOTAL,
diff --git a/offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl b/offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl
index a6a1b0151c94..376e4ad751d2 100644
--- a/offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl
+++ b/offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl
@@ -29,6 +29,16 @@ interface XDataPointCustomLabelField : XFormattedString2
void setGuid( [in] string guid );
+ /**
+ @since LibreOffice 7.3
+ */
+ boolean getDataLabelsRange();
+
+ /**
+ @since LibreOffice 7.3
+ */
+ void setDataLabelsRange( [in] boolean dataLabelsRange );
+
};
diff --git a/oox/inc/drawingml/chart/datasourcecontext.hxx b/oox/inc/drawingml/chart/datasourcecontext.hxx
index 8c893c1973a8..c90122282a2f 100644
--- a/oox/inc/drawingml/chart/datasourcecontext.hxx
+++ b/oox/inc/drawingml/chart/datasourcecontext.hxx
@@ -67,6 +67,7 @@ public:
private:
sal_Int32 mnPtIndex; /// Current data point index.
+ bool mbReadC15; /// Allow reading extension tags data under c15 namespace.
};
diff --git a/oox/inc/drawingml/chart/seriesmodel.hxx b/oox/inc/drawingml/chart/seriesmodel.hxx
index c4fb557d282d..460293a5feee 100644
--- a/oox/inc/drawingml/chart/seriesmodel.hxx
+++ b/oox/inc/drawingml/chart/seriesmodel.hxx
@@ -41,12 +41,18 @@ struct DataLabelModelBase
OptValue< bool > mobShowPercent; /// True = show percentual value in pie/doughnut charts.
OptValue< bool > mobShowSerName; /// True = show series name.
OptValue< bool > mobShowVal; /// True = show data point value.
+
+ /// True = the value from the <c15:datalabelsRange> corresponding to the
+ /// index of this label is used as the label text.
+ OptValue< bool > mobShowDataLabelsRange;
bool mbDeleted; /// True = data label(s) deleted.
explicit DataLabelModelBase(bool bMSO2007Doc);
~DataLabelModelBase();
};
+struct DataLabelsModel;
+
struct DataLabelModel : public DataLabelModelBase
{
typedef ModelRef< LayoutModel > LayoutRef;
@@ -54,9 +60,10 @@ struct DataLabelModel : public DataLabelModelBase
LayoutRef mxLayout; /// Layout/position of the data point label frame.
TextRef mxText; /// Manual or linked text for this data point label.
+ const DataLabelsModel& mrParent; /// Reference to the labels container.
sal_Int32 mnIndex; /// Data point index for this data label.
- explicit DataLabelModel(bool bMSO2007Doc);
+ explicit DataLabelModel(const DataLabelsModel& rParent, bool bMSO2007Doc);
~DataLabelModel();
};
@@ -67,6 +74,9 @@ struct DataLabelsModel : public DataLabelModelBase
DataLabelVector maPointLabels; /// Settings for individual data point labels.
ShapeRef mxLeaderLines; /// Formatting of connector lines between data points and labels.
+
+ /// Labels source (owned by SeriesModel's DataSourceMap)
+ const DataSourceModel* mpLabelsSource;
bool mbShowLeaderLines; /// True = show connector lines between data points and labels.
explicit DataLabelsModel(bool bMSO2007Doc);
@@ -171,7 +181,8 @@ struct SeriesModel
{
CATEGORIES, /// Data point categories.
VALUES, /// Data point values.
- POINTS /// Data point size (e.g. bubble size in bubble charts).
+ POINTS, /// Data point size (e.g. bubble size in bubble charts).
+ DATALABELS, /// Data point labels.
};
typedef ModelMap< SourceType, DataSourceModel > DataSourceMap;
diff --git a/oox/source/drawingml/chart/datasourcecontext.cxx b/oox/source/drawingml/chart/datasourcecontext.cxx
index e9f2f3b189f6..15ca02975137 100644
--- a/oox/source/drawingml/chart/datasourcecontext.cxx
+++ b/oox/source/drawingml/chart/datasourcecontext.cxx
@@ -165,6 +165,7 @@ SvNumberFormatter* DoubleSequenceContext::getNumberFormatter()
StringSequenceContext::StringSequenceContext( ContextHandler2Helper& rParent, DataSequenceModel& rModel )
: DataSequenceContextBase( rParent, rModel )
, mnPtIndex(-1)
+ , mbReadC15(false)
{
}
@@ -185,6 +186,16 @@ ContextHandlerRef StringSequenceContext::onCreateContext( sal_Int32 nElement, co
}
break;
+ case C15_TOKEN( datalabelsRange ):
+ mbReadC15 = true;
+ switch( nElement )
+ {
+ case C15_TOKEN( f ):
+ case C15_TOKEN( dlblRangeCache ):
+ return this;
+ }
+ break;
+
case C_TOKEN( strRef ):
switch( nElement )
{
@@ -196,6 +207,10 @@ ContextHandlerRef StringSequenceContext::onCreateContext( sal_Int32 nElement, co
case C_TOKEN( strCache ):
case C_TOKEN( strLit ):
+ case C15_TOKEN( dlblRangeCache ):
+ if (nElement == C15_TOKEN( dlblRangeCache ) && !mbReadC15)
+ break;
+
switch( nElement )
{
case C_TOKEN( ptCount ):
@@ -247,6 +262,10 @@ void StringSequenceContext::onCharacters( const OUString& rChars )
case C_TOKEN( f ):
mrModel.maFormula = rChars;
break;
+ case C15_TOKEN( f ):
+ if (mbReadC15)
+ mrModel.maFormula = rChars;
+ break;
case C_TOKEN( v ):
if( mnPtIndex >= 0 )
mrModel.maData[ (mrModel.mnLevelCount-1) * mrModel.mnPointCount + mnPtIndex ] <<= rChars;
@@ -269,11 +288,13 @@ ContextHandlerRef DataSourceContext::onCreateContext( sal_Int32 nElement, const
{
case C_TOKEN( cat ):
case C_TOKEN( xVal ):
+ case C_TOKEN( ext ):
switch( nElement )
{
case C_TOKEN( multiLvlStrRef ):
case C_TOKEN( strLit ):
case C_TOKEN( strRef ):
+ case C15_TOKEN( datalabelsRange ):
OSL_ENSURE( !mrModel.mxDataSeq, "DataSourceContext::onCreateContext - multiple data sequences" );
return new StringSequenceContext( *this, mrModel.mxDataSeq.create() );
diff --git a/oox/source/drawingml/chart/seriescontext.cxx b/oox/source/drawingml/chart/seriescontext.cxx
index 3f92818c5544..5afc32c1497d 100644
--- a/oox/source/drawingml/chart/seriescontext.cxx
+++ b/oox/source/drawingml/chart/seriescontext.cxx
@@ -100,15 +100,37 @@ DataLabelContext::~DataLabelContext()
ContextHandlerRef DataLabelContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
{
- if( isRootElement() ) switch( nElement )
+ if( isRootElement() )
{
- case C_TOKEN( idx ):
- mrModel.mnIndex = rAttribs.getInteger( XML_val, -1 );
- return nullptr;
- case C_TOKEN( layout ):
- return new LayoutContext( *this, mrModel.mxLayout.create() );
- case C_TOKEN( tx ):
- return new TextContext( *this, mrModel.mxText.create() );
+ switch( nElement )
+ {
+ case C_TOKEN( idx ):
+ mrModel.mnIndex = rAttribs.getInteger( XML_val, -1 );
+ return nullptr;
+ case C_TOKEN( layout ):
+ return new LayoutContext( *this, mrModel.mxLayout.create() );
+ case C_TOKEN( tx ):
+ return new TextContext( *this, mrModel.mxText.create() );
+ case C_TOKEN( extLst ):
+ return this;
+ }
+ }
+ else
+ {
+ switch( getCurrentElement() )
+ {
+ case C_TOKEN( extLst ):
+ if ( nElement == C_TOKEN( ext ) )
+ return this;
+ break;
+ case C_TOKEN( ext ):
+ if ( nElement == C15_TOKEN( showDataLabelsRange ) )
+ {
+ mrModel.mobShowDataLabelsRange = rAttribs.getBool( XML_val );
+ return nullptr;
+ }
+ break;
+ }
}
bool bMSO2007 = getFilter().isMSO2007Document();
return lclDataLabelSharedCreateContext( *this, nElement, rAttribs, mrModel, bMSO2007 );
@@ -135,7 +157,7 @@ ContextHandlerRef DataLabelsContext::onCreateContext( sal_Int32 nElement, const
if( isRootElement() ) switch( nElement )
{
case C_TOKEN( dLbl ):
- return new DataLabelContext( *this, mrModel.maPointLabels.create(bMSO2007Doc) );
+ return new DataLabelContext( *this, mrModel.maPointLabels.create(mrModel, bMSO2007Doc) );
case C_TOKEN( leaderLines ):
return new ShapePrWrapperContext( *this, mrModel.mxLeaderLines.create() );
case C_TOKEN( showLeaderLines ):
@@ -390,6 +412,8 @@ ContextHandlerRef SeriesContextBase::onCreateContext( sal_Int32 nElement, const
return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
case C_TOKEN( tx ):
return new TextContext( *this, mrModel.mxText.create() );
+ case C_TOKEN( extLst ):
+ return this;
}
break;
@@ -406,6 +430,19 @@ ContextHandlerRef SeriesContextBase::onCreateContext( sal_Int32 nElement, const
return nullptr;
}
break;
+
+ case C_TOKEN( extLst ):
+ switch( nElement )
+ {
+ case C_TOKEN( ext ):
+ if (mrModel.maSources.has( SeriesModel::DATALABELS ))
+ break;
+
+ DataSourceModel& rLabelsSource = mrModel.maSources.create( SeriesModel::DATALABELS );
+ if (mrModel.mxLabels.is())
+ mrModel.mxLabels->mpLabelsSource = &rLabelsSource;
+ return new DataSourceContext( *this, rLabelsSource );
+ }
}
return nullptr;
}
diff --git a/oox/source/drawingml/chart/seriesconverter.cxx b/oox/source/drawingml/chart/seriesconverter.cxx
index 2de8ee82d2f9..6f57cc8e73e4 100644
--- a/oox/source/drawingml/chart/seriesconverter.cxx
+++ b/oox/source/drawingml/chart/seriesconverter.cxx
@@ -318,9 +318,47 @@ void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDat
if( nParagraphs > 1 )
nSequenceSize += nParagraphs - 1;
+ OptValue< OUString > oaLabelText;
+ OptValue< OUString > oaCellRange;
+ if (mrModel.mobShowDataLabelsRange.get(false))
+ {
+ const DataSourceModel* pLabelSource = mrModel.mrParent.mpLabelsSource;
+ if (pLabelSource && pLabelSource->mxDataSeq.is())
+ {
+ oaCellRange = pLabelSource->mxDataSeq->maFormula;
+ const auto& rLabelMap = pLabelSource->mxDataSeq->maData;
+ const auto& rKV = rLabelMap.find(mrModel.mnIndex);
+ if (rKV != rLabelMap.end())
+ rKV->second >>= oaLabelText.use();
+ }
+ }
+
+ if (oaLabelText.has())
+ ++nSequenceSize;
+
aSequence.realloc( nSequenceSize );
int nPos = 0;
+ if (oaLabelText.has())
+ {
+ // Insert a "text" custom label field with the text found in the labels data source.
+ css::uno::Reference< XDataPointCustomLabelField > xCustomLabelText = DataPointCustomLabelField::create( xContext );
+
+ // Store properties
+ oox::PropertySet aPropertySet( xCustomLabelText );
+ convertTextProperty( aPropertySet, getFormatter(), mrModel.mxText->mxTextBody );
+ if (nParagraphs && rParagraphs[0])
+ {
+ auto& pRuns = rParagraphs[0]->getRuns();
+ if (pRuns.size())
+ pRuns[0]->getTextCharacterProperties().pushToPropSet( aPropertySet, getFilter() );
+ }
+ xCustomLabelText->setString(oaLabelText.get());
+ xCustomLabelText->setFieldType( DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT );
+
+ aSequence[ nPos++ ] = xCustomLabelText;
+ }
+
for( auto& pParagraph : rParagraphs )
{
for( auto& pRun : pParagraph->getRuns() )
@@ -335,8 +373,17 @@ void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDat
TextField* pField = nullptr;
if( ( pField = dynamic_cast< TextField* >( pRun.get() ) ) )
{
- xCustomLabel->setString( pField->getText() );
- xCustomLabel->setFieldType( lcl_ConvertFieldNameToFieldEnum( pField->getType() ) );
+ DataPointCustomLabelFieldType eType = lcl_ConvertFieldNameToFieldEnum( pField->getType() );
+
+ if (eType == DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLRANGE && oaCellRange.has())
+ {
+ xCustomLabel->setString( oaCellRange.get() );
+ xCustomLabel->setDataLabelsRange( true );
+ }
+ else
+ xCustomLabel->setString( pField->getText() );
+
+ xCustomLabel->setFieldType( eType );
xCustomLabel->setGuid( pField->getUuid() );
}
else if( pRun )
diff --git a/oox/source/drawingml/chart/seriesmodel.cxx b/oox/source/drawingml/chart/seriesmodel.cxx
index 563e0e48e3bf..4ad9b2593af4 100644
--- a/oox/source/drawingml/chart/seriesmodel.cxx
+++ b/oox/source/drawingml/chart/seriesmodel.cxx
@@ -31,8 +31,9 @@ DataLabelModelBase::~DataLabelModelBase()
{
}
-DataLabelModel::DataLabelModel(bool bMSO2007Doc) :
+DataLabelModel::DataLabelModel(const DataLabelsModel& rParent, bool bMSO2007Doc) :
DataLabelModelBase(bMSO2007Doc),
+ mrParent( rParent ),
mnIndex( -1 )
{
}
@@ -43,6 +44,7 @@ DataLabelModel::~DataLabelModel()
DataLabelsModel::DataLabelsModel(bool bMSO2007Doc) :
DataLabelModelBase(bMSO2007Doc),
+ mpLabelsSource( nullptr ),
mbShowLeaderLines( !bMSO2007Doc )
{
}
diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx
index 38295504105b..18fbfad9e7a9 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -485,6 +485,46 @@ static sal_Int32 lcl_getAlphaFromTransparenceGradient(const awt::Gradient& rGrad
return (255 - nRed) * oox::drawingml::MAX_PERCENT / 255;
}
+bool DataLabelsRange::empty() const
+{
+ return maLabels.empty();
+}
+
+size_t DataLabelsRange::count() const
+{
+ return maLabels.size();
+}
+
+bool DataLabelsRange::hasLabel(sal_Int32 nIndex) const
+{
+ return maLabels.find(nIndex) != maLabels.end();
+}
+
+OUString DataLabelsRange::getRange() const
+{
+ return maRange;
+}
+
+void DataLabelsRange::setRange(const OUString& rRange)
+{
+ maRange = rRange;
+}
+
+void DataLabelsRange::setLabel(sal_Int32 nIndex, const OUString& rText)
+{
+ maLabels.emplace(nIndex, rText);
+}
+
+DataLabelsRange::LabelsRangeMap::const_iterator DataLabelsRange::begin() const
+{
+ return maLabels.begin();
+}
+
+DataLabelsRange::LabelsRangeMap::const_iterator DataLabelsRange::end() const
+{
+ return maLabels.end();
+}
+
ChartExport::ChartExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, Reference< frame::XModel > const & xModel, XmlFilterBase* pFB, DocumentType eDocumentType )
: DrawingML( std::move(pFS), pFB, eDocumentType )
, mnXmlNamespace( nXmlNamespace )
@@ -2047,6 +2087,40 @@ std::vector<Sequence<Reference<chart2::XDataSeries> > > splitDataSeriesByAxis(co
return aSplitSeries;
}
+void writeDataLabelsRange(FSHelperPtr& pFS, XmlFilterBase* pFB, DataLabelsRange& rDLblsRange)
+{
+ if (rDLblsRange.empty())
+ return;
+
+ pFS->startElement(FSNS(XML_c, XML_extLst));
+ pFS->startElement(FSNS(XML_c, XML_ext), XML_uri, "{02D57815-91ED-43cb-92C2-25804820EDAC}", FSNS(XML_xmlns, XML_c15), pFB->getNamespaceURL(OOX_NS(c15)));
+ // pFS->singleElement(FSNS(XML_c15, XML_showLeaderLines), XML_val, ToPsz10(bShowLeaderLines));
+ pFS->startElement(FSNS(XML_c15, XML_datalabelsRange));
+
+ // Write cell range.
+ pFS->startElement(FSNS(XML_c15, XML_f));
+ pFS->writeEscaped(rDLblsRange.getRange());
+ pFS->endElement(FSNS(XML_c15, XML_f));
+
+ // Write all labels.
+ pFS->startElement(FSNS(XML_c15, XML_dlblRangeCache));
+ pFS->singleElement(FSNS(XML_c, XML_ptCount), XML_val, OString::number(rDLblsRange.count()));
+ for (const auto& rLabelKV: rDLblsRange)
+ {
+ pFS->startElement(FSNS(XML_c, XML_pt), XML_idx, OString::number(rLabelKV.first));
+ pFS->startElement(FSNS(XML_c, XML_v));
+ pFS->writeEscaped(rLabelKV.second);
+ pFS->endElement(FSNS( XML_c, XML_v ));
+ pFS->endElement(FSNS(XML_c, XML_pt));
+ }
+
+ pFS->endElement(FSNS(XML_c15, XML_dlblRangeCache));
+
+ pFS->endElement(FSNS(XML_c15, XML_datalabelsRange));
+ pFS->endElement(FSNS(XML_c, XML_ext));
+ pFS->endElement(FSNS(XML_c, XML_extLst));
+}
+
}
void ChartExport::exportLineChart( const Reference< chart2::XChartType >& xChartType )
@@ -2431,8 +2505,9 @@ void ChartExport::exportSeries( const Reference<chart2::XChartType>& xChartType,
// export data points
exportDataPoints( uno::Reference< beans::XPropertySet >( rSeries, uno::UNO_QUERY ), nSeriesLength, eChartType );
+ DataLabelsRange aDLblsRange;
// export data labels
- exportDataLabels(rSeries, nSeriesLength, eChartType);
+ exportDataLabels(rSeries, nSeriesLength, eChartType, aDLblsRange);
exportTrendlines( rSeries );
@@ -2505,6 +2580,9 @@ void ChartExport::exportSeries( const Reference<chart2::XChartType>& xChartType,
if( eChartType == chart::TYPEID_BUBBLE )
pFS->singleElement(FSNS(XML_c, XML_bubble3D), XML_val, "0");
+ if (!aDLblsRange.empty())
+ writeDataLabelsRange(pFS, GetFB(), aDLblsRange);
+
pFS->endElement( FSNS( XML_c, XML_ser ) );
}
}
@@ -3421,7 +3499,8 @@ void writeRunProperties( ChartExport* pChartExport, Reference<XPropertySet> cons
}
void writeCustomLabel( const FSHelperPtr& pFS, ChartExport* pChartExport,
- const Sequence<Reference<chart2::XDataPointCustomLabelField>>& rCustomLabelFields )
+ const Sequence<Reference<chart2::XDataPointCustomLabelField>>& rCustomLabelFields,
+ sal_Int32 nLabelIndex, DataLabelsRange& rDLblsRange )
{
pFS->startElement(FSNS(XML_c, XML_tx));
pFS->startElement(FSNS(XML_c, XML_rich));
@@ -3430,15 +3509,54 @@ void writeCustomLabel( const FSHelperPtr& pFS, ChartExport* pChartExport,
pFS->singleElement(FSNS(XML_a, XML_bodyPr));
OUString sFieldType;
+ OUString sContent;
+ OUString sUid;
+ bool bShowDataLabelsRange = false;
pFS->startElement(FSNS(XML_a, XML_p));
+ for (auto& rField : rCustomLabelFields)
+ {
+ if (rField->getFieldType() == chart2::DataPointCustomLabelFieldType_CELLRANGE &&
+ rField->getDataLabelsRange())
+ bShowDataLabelsRange = true;
+ }
+
for (auto& rField : rCustomLabelFields)
{
Reference<XPropertySet> xPropertySet(rField, UNO_QUERY);
chart2::DataPointCustomLabelFieldType aType = rField->getFieldType();
sFieldType.clear();
+ sContent.clear();
+ sUid.clear();
bool bNewParagraph = false;
+ if (bShowDataLabelsRange)
+ {
+ if (aType == chart2::DataPointCustomLabelFieldType_TEXT)
+ {
+ if (rDLblsRange.hasLabel(nLabelIndex))
+ continue;
+
+ rDLblsRange.setLabel(nLabelIndex, rField->getString());
+ // Don't write the text field here.
+ // This is written under the extension root <c15:datalabelsRange>
+ continue;
+ }
+
+ if (aType == chart2::DataPointCustomLabelFieldType_CELLRANGE)
+ {
+ if (rDLblsRange.getRange().isEmpty())
+ rDLblsRange.setRange(rField->getString());
+ sContent = "[CELLRANGE]";
+ }
+ }
+ else
+ {
+ sContent = rField->getString();
+ }
+
+ sUid = rField->getGuid();
+
if (aType == chart2::DataPointCustomLabelFieldType_NEWLINE)
bNewParagraph = true;
else if (aType != chart2::DataPointCustomLabelFieldType_TEXT)
@@ -3458,7 +3576,7 @@ void writeCustomLabel( const FSHelperPtr& pFS, ChartExport* pChartExport,
writeRunProperties(pChartExport, xPropertySet);
pFS->startElement(FSNS(XML_a, XML_t));
- pFS->writeEscaped(rField->getString());
+ pFS->writeEscaped(sContent);
pFS->endElement(FSNS(XML_a, XML_t));
pFS->endElement(FSNS(XML_a, XML_r));
@@ -3466,12 +3584,12 @@ void writeCustomLabel( const FSHelperPtr& pFS, ChartExport* pChartExport,
else
{
// Field
- pFS->startElement(FSNS(XML_a, XML_fld), XML_id, rField->getGuid(), XML_type,
+ pFS->startElement(FSNS(XML_a, XML_fld), XML_id, sUid, XML_type,
sFieldType);
writeRunProperties(pChartExport, xPropertySet);
pFS->startElement(FSNS(XML_a, XML_t));
- pFS->writeEscaped(rField->getString());
+ pFS->writeEscaped(sContent);
pFS->endElement(FSNS(XML_a, XML_t));
pFS->endElement(FSNS(XML_a, XML_fld));
@@ -3484,7 +3602,8 @@ void writeCustomLabel( const FSHelperPtr& pFS, ChartExport* pChartExport,
}
void writeLabelProperties( const FSHelperPtr& pFS, ChartExport* pChartExport,
- const uno::Reference<beans::XPropertySet>& xPropSet, const LabelPlacementParam& rLabelParam )
+ const uno::Reference<beans::XPropertySet>& xPropSet, const LabelPlacementParam& rLabelParam,
+ sal_Int32 nLabelIndex, DataLabelsRange& rDLblsRange )
{
if (!xPropSet.is())
return;
@@ -3539,7 +3658,7 @@ void writeLabelProperties( const FSHelperPtr& pFS, ChartExport* pChartExport,
pChartExport->exportTextProps(xPropSet);
if (aCustomLabelFields.hasElements())
- writeCustomLabel(pFS, pChartExport, aCustomLabelFields);
+ writeCustomLabel(pFS, pChartExport, aCustomLabelFields, nLabelIndex, rDLblsRange);
if (rLabelParam.mbExport)
{
@@ -3568,12 +3687,26 @@ void writeLabelProperties( const FSHelperPtr& pFS, ChartExport* pChartExport,
pFS->writeEscaped( nLabelSeparator );
pFS->endElement( FSNS( XML_c, XML_separator ) );
}
+
+ if (rDLblsRange.hasLabel(nLabelIndex))
+ {
+ pFS->startElement(FSNS(XML_c, XML_extLst));
+ pFS->startElement(FSNS(XML_c, XML_ext), XML_uri,
+ "{CE6537A1-D6FC-4f65-9D91-7224C49458BB}", FSNS(XML_xmlns, XML_c15),
+ pChartExport->GetFB()->getNamespaceURL(OOX_NS(c15)));
+
+ pFS->singleElement(FSNS(XML_c15, XML_showDataLabelsRange), XML_val, "1");
+
+ pFS->endElement(FSNS(XML_c, XML_ext));
+ pFS->endElement(FSNS(XML_c, XML_extLst));
+ }
}
}
void ChartExport::exportDataLabels(
- const uno::Reference<chart2::XDataSeries> & xSeries, sal_Int32 nSeriesLength, sal_Int32 eChartType )
+ const uno::Reference<chart2::XDataSeries> & xSeries, sal_Int32 nSeriesLength, sal_Int32 eChartType,
+ DataLabelsRange& rDLblsRange)
{
if (!xSeries.is() || nSeriesLength <= 0)
return;
@@ -3704,12 +3837,12 @@ void ChartExport::exportDataLabels(
}
// Individual label property that overwrites the baseline.
- writeLabelProperties(pFS, this, xLabelPropSet, aParam);
+ writeLabelProperties(pFS, this, xLabelPropSet, aParam, nIdx, rDLblsRange);
pFS->endElement(FSNS(XML_c, XML_dLbl));
}
// Baseline label properties for all labels.
- writeLabelProperties(pFS, this, xPropSet, aParam);
+ writeLabelProperties(pFS, this, xPropSet, aParam, -1, rDLblsRange);
bool bShowLeaderLines = false;
xPropSet->getPropertyValue("ShowCustomLeaderLines") >>= bShowLeaderLines;
diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt
index 76dad54c8904..3bd4106b9c44 100644
--- a/oox/source/token/tokens.txt
+++ b/oox/source/token/tokens.txt
@@ -1656,6 +1656,7 @@ dataValidation
dataValidations
database
databaseField
+datalabelsRange
datastoreItem
date
date1904
@@ -1871,6 +1872,7 @@ dkTurquoise
dkUpDiag
dkVert
dkViolet
+dlblRangeCache
dllVersion
dm
dn
@@ -4645,6 +4647,7 @@ showComments
showDLblsOverMax
showDataAs
showDataDropDown
+showDataLabelsRange
showDataTips
showDrill
showDropDown
diff --git a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng
index 89913cbf7e63..19653c45cd35 100644
--- a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng
+++ b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng
@@ -2493,4 +2493,16 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
</rng:optional>
</rng:define>
+ <!-- TODO no proposal -->
+ <rng:define name="chart-data-label-attlist" combine="interleave">
+ <rng:optional>
+ <rng:attribute name="loext:data-label-guid">
+ <rng:ref name="string"/>
+ </rng:attribute>
+ <rng:attribute name="loext:data-labels-cell-range">
+ <rng:ref name="cellRangeAddress"/>
+ </rng:attribute>
+ </rng:optional>
+ </rng:define>
+
</rng:grammar>
diff --git a/xmloff/source/chart/SchXMLExport.cxx b/xmloff/source/chart/SchXMLExport.cxx
index 0ee68425c6fc..3c41c52fefcf 100644
--- a/xmloff/source/chart/SchXMLExport.cxx
+++ b/xmloff/source/chart/SchXMLExport.cxx
@@ -113,7 +113,18 @@ using ::std::vector;
namespace
{
- using CustomLabelSeq = Sequence<Reference<chart2::XDataPointCustomLabelField>>;
+ struct CustomLabelData
+ {
+ CustomLabelData():
+ mbDataLabelsRange( false )
+ {
+ }
+
+ Sequence<Reference<chart2::XDataPointCustomLabelField>> maFields;
+ bool mbDataLabelsRange;
+ OUString maRange;
+ OUString maGuid;
+ };
struct SchXMLDataPointStruct
{
@@ -123,7 +134,7 @@ namespace
// There is no internal equivalent for <chart:data-label>. It will be generated on the fly
// on export. All about data label is hold in the data point.
- CustomLabelSeq mCustomLabelText; // <text:p> child element in <chart:data-label>
+ CustomLabelData mCustomLabel; // <text:p> child element in <chart:data-label>
OUString msDataLabelStyleName; // chart:style-name attribute in <chart:data-label>
SchXMLDataPointStruct() : mnRepeat( 1 ) {}
@@ -282,30 +293,58 @@ public:
namespace
{
-CustomLabelSeq lcl_getCustomLabelField(SvXMLExport const& rExport,
+CustomLabelData lcl_getCustomLabelField(SvXMLExport const& rExport,
sal_Int32 nDataPointIndex,
const uno::Reference< chart2::XDataSeries >& rSeries)
{
if (!rSeries.is())
- return CustomLabelSeq();
+ return CustomLabelData();
// Custom data label text will be written to the <text:p> child element of a
// <chart:data-label> element. That exists only since ODF 1.2.
const SvtSaveOptions::ODFSaneDefaultVersion nCurrentODFVersion(
rExport.getSaneDefaultVersion());
if (nCurrentODFVersion < SvtSaveOptions::ODFSVER_012)
- return CustomLabelSeq();
+ return CustomLabelData();
if(Reference<beans::XPropertySet> xLabels = rSeries->getDataPointByIndex(nDataPointIndex); xLabels.is())
{
if(Any aAny = xLabels->getPropertyValue("CustomLabelFields"); aAny.hasValue())
{
+ CustomLabelData aData;
+ uno::Reference<chart2::XDataPointCustomLabelField> aTextField;
Sequence<uno::Reference<chart2::XDataPointCustomLabelField>> aCustomLabels;
aAny >>= aCustomLabels;
- return aCustomLabels;
+ for (auto& rField: aCustomLabels)
+ {
+ if (rField->getFieldType() == chart2::DataPointCustomLabelFieldType_CELLRANGE)
+ {
+ if (rField->getDataLabelsRange())
+ aData.mbDataLabelsRange = true;
+ aData.maRange = rField->getString();
+ aData.maGuid = rField->getGuid();
+ }
+
+ if (!aTextField.is() && rField->getFieldType() == chart2::DataPointCustomLabelFieldType_TEXT)
+ {
+ aTextField = rField;
+ }
+ }
+
+ if (aData.mbDataLabelsRange)
+ {
+ aData.maFields = Sequence<uno::Reference<chart2::XDataPointCustomLabelField>>(1);
+ aData.maFields[0] = aTextField;
+ }
+ else
+ {
+ aData.maFields = aCustomLabels;
+ }
+
+ return aData;
}
}
- return CustomLabelSeq();
+ return CustomLabelData();
}
css::chart2::RelativePosition lcl_getCustomLabelPosition(
@@ -3466,7 +3505,7 @@ void SchXMLExportHelper_Impl::exportDataPoints(
maAutoStyleNameQueue.pop();
}
if(bExportNumFmt)
- aPoint.mCustomLabelText = lcl_getCustomLabelField(mrExport, nElement, xSeries);
+ aPoint.mCustomLabel = lcl_getCustomLabelField(mrExport, nElement, xSeries);
aPoint.mCustomLabelPos = lcl_getCustomLabelPosition(mrExport, nElement, xSeries);
aDataPointVector.push_back( aPoint );
@@ -3545,7 +3584,7 @@ void SchXMLExportHelper_Impl::exportDataPoints(
aPoint.maStyleName = maAutoStyleNameQueue.front();
maAutoStyleNameQueue.pop();
}
- aPoint.mCustomLabelText = lcl_getCustomLabelField(mrExport, nCurrIndex, xSeries);
+ aPoint.mCustomLabel = lcl_getCustomLabelField(mrExport, nCurrIndex, xSeries);
aPoint.mCustomLabelPos = lcl_getCustomLabelPosition(mrExport, nCurrIndex, xSeries);
if (!aDataLabelPropertyStates.empty())
{
@@ -3601,7 +3640,7 @@ void SchXMLExportHelper_Impl::exportDataPoints(
aPoint = rPoint;
if (aPoint.maStyleName == aLastPoint.maStyleName
- && aLastPoint.mCustomLabelText.getLength() < 1
+ && aLastPoint.mCustomLabel.maFields.getLength() < 1
&& aLastPoint.mCustomLabelPos.Primary == 0.0
&& aLastPoint.mCustomLabelPos.Secondary == 0.0
&& aPoint.msDataLabelStyleName == aLastPoint.msDataLabelStyleName)
@@ -3658,15 +3697,30 @@ void SchXMLExportHelper_Impl::exportDataPoints(
void SchXMLExportHelper_Impl::exportCustomLabel(const SchXMLDataPointStruct& rPoint)
{
- if (rPoint.mCustomLabelText.getLength() < 1 && rPoint.msDataLabelStyleName.isEmpty())
+ if (rPoint.mCustomLabel.maFields.getLength() < 1 && rPoint.msDataLabelStyleName.isEmpty())
return; // nothing to export
if (!rPoint.msDataLabelStyleName.isEmpty())
mrExport.AddAttribute(XML_NAMESPACE_CHART, XML_STYLE_NAME, rPoint.msDataLabelStyleName);
+
+ if (rPoint.mCustomLabel.mbDataLabelsRange)
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_DATA_LABELS_CELL_RANGE, rPoint.mCustomLabel.maRange);
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_DATA_LABEL_GUID, rPoint.mCustomLabel.maGuid);
+ }
// TODO svg:x and svg:y for <chart:data-label>
SvXMLElementExport aLabelElem( mrExport, XML_NAMESPACE_CHART, XML_DATA_LABEL, true, true);
SvXMLElementExport aPara( mrExport, XML_NAMESPACE_TEXT, XML_P, true, false );
- for (const Reference<chart2::XDataPointCustomLabelField>& label : rPoint.mCustomLabelText)
+ if (rPoint.mCustomLabel.mbDataLabelsRange)
+ {
+ // Will have only a single text field in this case.
+ // TODO add style
+ SvXMLElementExport aSpan( mrExport, XML_NAMESPACE_TEXT, XML_SPAN, true, false);
+ mrExport.GetDocHandler()->characters(rPoint.mCustomLabel.maFields[0]->getString());
+ return;
+ }
+
+ for (const Reference<chart2::XDataPointCustomLabelField>& label : rPoint.mCustomLabel.maFields)
{
// TODO add style
SvXMLElementExport aSpan( mrExport, XML_NAMESPACE_TEXT, XML_SPAN, true, false);
diff --git a/xmloff/source/chart/SchXMLPlotAreaContext.cxx b/xmloff/source/chart/SchXMLPlotAreaContext.cxx
index 521fcb58ce41..ce8f915f7c4b 100644
--- a/xmloff/source/chart/SchXMLPlotAreaContext.cxx
+++ b/xmloff/source/chart/SchXMLPlotAreaContext.cxx
@@ -617,7 +617,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLDataLabelParaCon
}
SchXMLDataLabelContext::SchXMLDataLabelContext(SvXMLImport& rImport,
- ::std::vector<OUString>& rLabels,
+ CustomLabelsInfo& rLabels,
DataRowPointStyle& rDataLabelStyle)
: SvXMLImportContext(rImport)
, mrLabels(rLabels)
@@ -630,7 +630,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLDataLabelContext
const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
{
if ( nElement == XML_ELEMENT(TEXT, XML_P) )
- return new SchXMLDataLabelParaContext(GetImport(), mrLabels);
+ return new SchXMLDataLabelParaContext(GetImport(), mrLabels.mLabels);
else
XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
return nullptr;
@@ -669,6 +669,19 @@ void SchXMLDataLabelContext::StartElement(const uno::Reference<xml::sax::XAttrib
mrDataLabelStyle.msStyleName = sValue;
}
}
+ else if (nPrefix == XML_NAMESPACE_LO_EXT)
+ {
+ if (IsXMLToken(aLocalName, XML_DATA_LABEL_GUID))
+ {
+ mrLabels.msLabelGuid = sValue;
+ mrLabels.mbDataLabelsRange = true;
+ }
+ else if (IsXMLToken(aLocalName, XML_DATA_LABELS_CELL_RANGE))
+ {
+ mrLabels.msLabelsCellRange = sValue;
+ mrLabels.mbDataLabelsRange = true;
+ }
+ }
}
}
@@ -744,7 +757,7 @@ void SchXMLDataPointContext::StartElement( const uno::Reference< xml::sax::XAttr
if( IsXMLToken( aLocalName, XML_CUSTOM_LABEL_FIELD) && !mbHasLabelParagraph)
{
sCustomLabelField = xAttrList->getValueByIndex( i );
- mDataPoint.mCustomLabels.push_back(sCustomLabelField);
+ mDataPoint.mCustomLabels.mLabels.push_back(sCustomLabelField);
}
else if (IsXMLToken(aLocalName, XML_HIDE_LEGEND))
{
@@ -779,7 +792,7 @@ void SchXMLDataPointContext::StartElement( const uno::Reference< xml::sax::XAttr
void SchXMLDataPointContext::endFastElement(sal_Int32 )
{
- if(!mDataPoint.msStyleName.isEmpty() || mDataPoint.mCustomLabels.size() > 0)
+ if(!mDataPoint.msStyleName.isEmpty() || mDataPoint.mCustomLabels.mLabels.size() > 0)
{
mrStyleVector.push_back(mDataPoint);
}
diff --git a/xmloff/source/chart/SchXMLPlotAreaContext.hxx b/xmloff/source/chart/SchXMLPlotAreaContext.hxx
index 1e392e8a3b3c..487d2a93a382 100644
--- a/xmloff/source/chart/SchXMLPlotAreaContext.hxx
+++ b/xmloff/source/chart/SchXMLPlotAreaContext.hxx
@@ -163,11 +163,11 @@ public:
class SchXMLDataLabelContext: public SvXMLImportContext
{
private:
- ::std::vector<OUString>& mrLabels;
+ CustomLabelsInfo& mrLabels;
DataRowPointStyle& mrDataLabelStyle;
public:
SchXMLDataLabelContext(SvXMLImport& rImport,
- ::std::vector<OUString>& rLabels, DataRowPointStyle& rDataLabel);
+ CustomLabelsInfo& rLabels, DataRowPointStyle& rDataLabel);
virtual void StartElement(const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList) override;
diff --git a/xmloff/source/chart/SchXMLSeries2Context.cxx b/xmloff/source/chart/SchXMLSeries2Context.cxx
index 992a03d64113..e9469e6822ec 100644
--- a/xmloff/source/chart/SchXMLSeries2Context.cxx
+++ b/xmloff/source/chart/SchXMLSeries2Context.cxx
@@ -1220,15 +1220,20 @@ void SchXMLSeries2Context::setStylesToDataPoints( SeriesDefaultsAndStyles& rSeri
}
// Custom labels might be passed as property
- if(auto nLabelCount = seriesStyle.mCustomLabels.size(); nLabelCount > 0)
+ if(const size_t nLabelCount = seriesStyle.mCustomLabels.mLabels.size(); nLabelCount > 0)
{
- Sequence< Reference<chart2::XDataPointCustomLabelField>> xLabels(nLabelCount);
+ auto& rCustomLabels = seriesStyle.mCustomLabels;
+ size_t nFields = nLabelCount;
+ if (rCustomLabels.mbDataLabelsRange)
+ ++nFields; // For appending CELLRANGE field.
+
+ Sequence< Reference<chart2::XDataPointCustomLabelField>> xLabels(nFields);
Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
- for( auto j = 0; j< xLabels.getLength(); ++j )
+ for( size_t j = 0; j < nLabelCount; ++j )
{
Reference< chart2::XDataPointCustomLabelField > xCustomLabel = chart2::DataPointCustomLabelField::create(xContext);
xLabels[j] = xCustomLabel;
- xCustomLabel->setString(seriesStyle.mCustomLabels[j]);
+ xCustomLabel->setString(rCustomLabels.mLabels[j]);
xCustomLabel->setFieldType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT);
// Restore character properties on the text span manually, till
@@ -1251,6 +1256,18 @@ void SchXMLSeries2Context::setStylesToDataPoints( SeriesDefaultsAndStyles& rSeri
}
}
}
+
+ if (rCustomLabels.mbDataLabelsRange)
+ {
+ // append CELLRANGE field using the attributes of <chart:data-label>.
+ Reference< chart2::XDataPointCustomLabelField > xCustomLabel = chart2::DataPointCustomLabelField::create(xContext);
+ xCustomLabel->setDataLabelsRange(true);
+ xCustomLabel->setFieldType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLRANGE);
+ xCustomLabel->setString(rCustomLabels.msLabelsCellRange);
+ xCustomLabel->setGuid(rCustomLabels.msLabelGuid);
+ xLabels[nFields - 1] = xCustomLabel;
+ }
+
xPointProp->setPropertyValue("CustomLabelFields", uno::Any(xLabels));
xPointProp->setPropertyValue("DataCaption", uno::Any(chart::ChartDataCaption::CUSTOM));
}
diff --git a/xmloff/source/chart/transporttypes.hxx b/xmloff/source/chart/transporttypes.hxx
index 28527c6c06f8..4e395ead292c 100644
--- a/xmloff/source/chart/transporttypes.hxx
+++ b/xmloff/source/chart/transporttypes.hxx
@@ -146,6 +146,14 @@ struct RegressionStyle
{}
};
+struct CustomLabelsInfo
+{
+ ::std::vector<OUString> mLabels;
+ bool mbDataLabelsRange = false;
+ OUString msLabelGuid;
+ OUString msLabelsCellRange;
+};
+
struct DataRowPointStyle
{
enum StyleType
@@ -171,7 +179,7 @@ struct DataRowPointStyle
sal_Int32 m_nPointRepeat;
OUString msStyleName;
OUString msStyleNameOfParent; // e.g. target of line and fill styles of data-labels
- ::std::vector<OUString> mCustomLabels;
+ CustomLabelsInfo mCustomLabels;
double mCustomLabelPos[2] = { 0.0, 0.0 };
// for svg:x and svg:y attribute (in core unit), of element <chart:data-label>
std::optional<sal_Int32> mo_nLabelAbsolutePosX;
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 02482b39515e..9600a0689fc5 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -579,9 +579,11 @@ namespace xmloff::token {
TOKEN( "data-bar-entry", XML_DATA_BAR_ENTRY ),
TOKEN( "data-cell-range-address", XML_DATA_CELL_RANGE_ADDRESS ),
TOKEN( "data-label", XML_DATA_LABEL ),
+ TOKEN( "data-label-guid", XML_DATA_LABEL_GUID ),
TOKEN( "data-label-number", XML_DATA_LABEL_NUMBER ),
TOKEN( "data-label-symbol", XML_DATA_LABEL_SYMBOL ),
TOKEN( "data-label-text", XML_DATA_LABEL_TEXT ),
+ TOKEN( "data-labels-cell-range", XML_DATA_LABELS_CELL_RANGE ),
TOKEN( "data-pilot-source", XML_DATA_PILOT_SOURCE ),
TOKEN( "data-pilot-field", XML_DATA_PILOT_FIELD ),
TOKEN( "data-pilot-grand-total", XML_DATA_PILOT_GRAND_TOTAL ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index ead900650328..bb5e0e89f311 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -491,9 +491,11 @@ data-bar
data-bar-entry
data-cell-range-address
data-label
+data-label-guid
data-label-number
data-label-symbol
data-label-text
+data-labels-cell-range
data-pilot-source
data-pilot-field
data-pilot-grand-total
More information about the Libreoffice-commits
mailing list