[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - 4 commits - chart2/qa chart2/source configure.ac download.lst include/oox include/xmloff offapi/com oox/inc oox/source schema/libreoffice svx/uiconfig xmloff/source
Dennis Francis (via logerrit)
logerrit at kemper.freedesktop.org
Mon Aug 30 10:09:04 UTC 2021
Rebased ref, commits from common ancestor:
commit 32b0289cc53527b3eb45a4b6600cd26472f59282
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 12:08:22 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/qa/extras/chart2export.cxx b/chart2/qa/extras/chart2export.cxx
index d92e06cdc01c..67d1b7dcb83c 100644
--- a/chart2/qa/extras/chart2export.cxx
+++ b/chart2/qa/extras/chart2export.cxx
@@ -185,6 +185,7 @@ public:
void testTdf138204();
void testTdf138181();
void testCustomShapeText();
+ void testTdf143942();
CPPUNIT_TEST_SUITE(Chart2ExportTest);
CPPUNIT_TEST(testErrorBarXLSX);
@@ -332,6 +333,7 @@ public:
CPPUNIT_TEST(testTdf138204);
CPPUNIT_TEST(testTdf138181);
CPPUNIT_TEST(testCustomShapeText);
+ CPPUNIT_TEST(testTdf143942);
CPPUNIT_TEST_SUITE_END();
@@ -2997,21 +2999,56 @@ void Chart2ExportTest::testTdf138204()
// Check the first data label field type
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:dLbls/c:dLbl/c:tx/c:rich/a:p/a:fld", "type", "CELLRANGE");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[2]/c:dLbls/c:dLbl/c:tx/c:rich/a:p/a:fld", "type", "CELLRANGE");
Reference< chart2::XChartDocument> xChartDoc = getChartDocFromSheet(0, mxComponent);
CPPUNIT_ASSERT(xChartDoc.is());
- uno::Reference<chart2::XDataSeries> xDataSeries(getDataSeriesFromDoc(xChartDoc, 1));
- CPPUNIT_ASSERT(xDataSeries.is());
+ struct CustomLabelsTestData
+ {
+ sal_Int32 nSeriesIdx;
+ sal_Int32 nNumFields;
+ // First field attributes.
+ chart2::DataPointCustomLabelFieldType eFieldType;
+ OUString aCellRange;
+ OUString aString;
+ };
- uno::Reference<beans::XPropertySet> xPropertySet;
- uno::Sequence<uno::Reference<chart2::XDataPointCustomLabelField>> aFields;
- xPropertySet.set(xDataSeries->getDataPointByIndex(0), uno::UNO_SET_THROW);
- xPropertySet->getPropertyValue("CustomLabelFields") >>= aFields;
- CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aFields.getLength());
+ const CustomLabelsTestData aTestEntries[2] = {
+ {
+ // series id of c:ser[1] is 0.
+ 0, // nSeriesIdx
+ 1, // nNumFields
+ chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLRANGE,
+ "Munka1!$F$9", // aCellRange
+ "67,5%", // aString
+ },
+ {
- CPPUNIT_ASSERT_EQUAL(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLRANGE, aFields[0]->getFieldType());
- //CPPUNIT_ASSERT_EQUAL(OUString("67.5%"), aFields[0]->getString()); TODO: Not implemented yet
+ // series id of c:ser[2] is 1.
+ 1, // nSeriesIdx
+ 1, // nNumFields
+ chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLRANGE,
+ "Munka1!$G$9", // aCellRange
+ "32,3%", // aString
+ },
+ };
+
+ for (const auto& aTestEntry: aTestEntries)
+ {
+ uno::Reference<chart2::XDataSeries> xDataSeries(getDataSeriesFromDoc(xChartDoc, aTestEntry.nSeriesIdx));
+ CPPUNIT_ASSERT(xDataSeries.is());
+
+ uno::Reference<beans::XPropertySet> xPropertySet;
+ uno::Sequence<uno::Reference<chart2::XDataPointCustomLabelField>> aFields;
+ xPropertySet.set(xDataSeries->getDataPointByIndex(0), uno::UNO_SET_THROW);
+ xPropertySet->getPropertyValue("CustomLabelFields") >>= aFields;
+ CPPUNIT_ASSERT_EQUAL(aTestEntry.nNumFields, aFields.getLength());
+
+ CPPUNIT_ASSERT_EQUAL(aTestEntry.eFieldType, aFields[0]->getFieldType());
+ CPPUNIT_ASSERT_EQUAL(aTestEntry.aCellRange, aFields[0]->getCellRange());
+ CPPUNIT_ASSERT_EQUAL(aTestEntry.aString, aFields[0]->getString());
+ }
}
void Chart2ExportTest::testTdf138181()
@@ -3056,6 +3093,53 @@ void Chart2ExportTest::testCustomShapeText()
CPPUNIT_ASSERT(!xRange->getString().isEmpty());
}
+void Chart2ExportTest::testTdf143942()
+{
+ load("/chart2/qa/extras/data/xlsx/", "tdf143942.xlsx");
+ xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ constexpr size_t nLabels = 4;
+ OUString aCellRange = "Sheet1!$A$2:$A$5";
+ OUString aLabels[nLabels] = {
+ "Test1",
+ "Test2",
+ "Tes3",
+ "Test4",
+ };
+
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:scatterChart/c:ser[1]/c:extLst/c:ext", "uri", "{02D57815-91ED-43cb-92C2-25804820EDAC}");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:scatterChart/c:ser[1]/c:extLst/c:ext/c15:datalabelsRange/c15:dlblRangeCache/c:ptCount", "val", "4");
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:scatterChart/c:ser[1]/c:extLst/c:ext/c15:datalabelsRange/c15:f", aCellRange);
+ for (size_t i = 0; i < nLabels; ++i)
+ {
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:scatterChart/c:ser[1]/c:dLbls/c:dLbl[" +
+ OString::number(i + 1) + "]/c:tx/c:rich/a:p/a:fld", "type", "CELLRANGE");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:scatterChart/c:ser[1]/c:dLbls/c:dLbl[" +
+ OString::number(i + 1) + "]/c:extLst/c:ext/c15:showDataLabelsRange", "val", "1");
+ // Check if the actual label is stored under c15:datalabelsRange
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:scatterChart/c:ser[1]/c:extLst/c:ext/c15:datalabelsRange/c15:dlblRangeCache/c:pt[" +
+ OString::number(i + 1) + "]/c:v", aLabels[i]);
+ }
+
+ Reference< chart2::XChartDocument> xChartDoc = getChartDocFromSheet(0, mxComponent);
+ CPPUNIT_ASSERT(xChartDoc.is());
+ uno::Reference<chart2::XDataSeries> xDataSeries(getDataSeriesFromDoc(xChartDoc, 0));
+ CPPUNIT_ASSERT(xDataSeries.is());
+
+ uno::Reference<beans::XPropertySet> xPropertySet;
+ uno::Sequence<uno::Reference<chart2::XDataPointCustomLabelField>> aFields;
+ for (size_t i = 0; i < nLabels; ++i)
+ {
+ xPropertySet.set(xDataSeries->getDataPointByIndex(i), uno::UNO_SET_THROW);
+ xPropertySet->getPropertyValue("CustomLabelFields") >>= aFields;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aFields.getLength());
+ CPPUNIT_ASSERT_EQUAL(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLRANGE, aFields[0]->getFieldType());
+ CPPUNIT_ASSERT_EQUAL(aCellRange, aFields[0]->getCellRange());
+ CPPUNIT_ASSERT_EQUAL(aLabels[i], aFields[0]->getString());
+ }
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/chart2/qa/extras/data/xlsx/tdf143942.xlsx b/chart2/qa/extras/data/xlsx/tdf143942.xlsx
new file mode 100644
index 000000000000..33ff6696b7e6
Binary files /dev/null and b/chart2/qa/extras/data/xlsx/tdf143942.xlsx differ
diff --git a/chart2/source/model/main/FormattedString.cxx b/chart2/source/model/main/FormattedString.cxx
index 0d6e733a2c31..2c7f6cddbbaa 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,38 @@ 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();
+}
+
+OUString SAL_CALL FormattedString::getCellRange()
+{
+ MutexGuard aGuard( m_aMutex);
+ return m_aCellRange;
+}
+
+void SAL_CALL FormattedString::setCellRange( const OUString& cellRange )
+{
+ {
+ MutexGuard aGuard( m_aMutex);
+ m_aCellRange = cellRange;
+ }
+ //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..bd7415fb921a 100644
--- a/chart2/source/model/main/FormattedString.hxx
+++ b/chart2/source/model/main/FormattedString.hxx
@@ -87,6 +87,10 @@ 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;
+ virtual OUString SAL_CALL getCellRange() override;
+ virtual void SAL_CALL setCellRange( const OUString& cellRange ) override;
// ____ OPropertySet ____
virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override;
@@ -127,6 +131,8 @@ private:
// ____ XDataPointCustomLabelField ____
css::chart2::DataPointCustomLabelFieldType m_aType;
OUString m_aGuid;
+ OUString m_aCellRange;
+ 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..f463cb04f9b2 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -541,8 +541,15 @@ 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())
+ aTextList[i] = aCustomLabels[i]->getString();
+ else
+ aTextList[i] = OUString();
+ break;
+ }
+ case DataPointCustomLabelFieldType_CELLREF:
{
// TODO: for now doesn't show placeholder
aTextList[i] = OUString();
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..434edb779775 100644
--- a/offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl
+++ b/offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl
@@ -29,6 +29,26 @@ interface XDataPointCustomLabelField : XFormattedString2
void setGuid( [in] string guid );
+ /**
+ @since LibreOffice 7.3
+ */
+ boolean getDataLabelsRange();
+
+ /**
+ @since LibreOffice 7.3
+ */
+ void setDataLabelsRange( [in] boolean dataLabelsRange );
+
+ /**
+ @since LibreOffice 7.3
+ */
+ string getCellRange();
+
+ /**
+ @since LibreOffice 7.3
+ */
+ void setCellRange( [in] string cellRange );
+
};
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..a9a7e980e69f 100644
--- a/oox/source/drawingml/chart/seriesconverter.cxx
+++ b/oox/source/drawingml/chart/seriesconverter.cxx
@@ -318,9 +318,25 @@ 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();
+ }
+ }
+
aSequence.realloc( nSequenceSize );
int nPos = 0;
+
for( auto& pParagraph : rParagraphs )
{
for( auto& pRun : pParagraph->getRuns() )
@@ -335,8 +351,18 @@ 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->setCellRange( oaCellRange.get() );
+ xCustomLabel->setString( oaLabelText.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..83f7ad8d5d93 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,39 @@ 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->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 +2504,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 +2579,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 +3498,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,6 +3508,7 @@ void writeCustomLabel( const FSHelperPtr& pFS, ChartExport* pChartExport,
pFS->singleElement(FSNS(XML_a, XML_bodyPr));
OUString sFieldType;
+ OUString sContent;
pFS->startElement(FSNS(XML_a, XML_p));
for (auto& rField : rCustomLabelFields)
@@ -3437,8 +3516,25 @@ void writeCustomLabel( const FSHelperPtr& pFS, ChartExport* pChartExport,
Reference<XPropertySet> xPropertySet(rField, UNO_QUERY);
chart2::DataPointCustomLabelFieldType aType = rField->getFieldType();
sFieldType.clear();
+ sContent.clear();
bool bNewParagraph = false;
+ if (aType == chart2::DataPointCustomLabelFieldType_CELLRANGE &&
+ rField->getDataLabelsRange())
+ {
+ if (rDLblsRange.getRange().isEmpty())
+ rDLblsRange.setRange(rField->getCellRange());
+
+ if (!rDLblsRange.hasLabel(nLabelIndex))
+ rDLblsRange.setLabel(nLabelIndex, rField->getString());
+
+ sContent = "[CELLRANGE]";
+ }
+ else
+ {
+ sContent = rField->getString();
+ }
+
if (aType == chart2::DataPointCustomLabelFieldType_NEWLINE)
bNewParagraph = true;
else if (aType != chart2::DataPointCustomLabelFieldType_TEXT)
@@ -3458,7 +3554,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));
@@ -3471,7 +3567,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_fld));
@@ -3484,7 +3580,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 +3636,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 +3665,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 +3815,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..51fdec8f3175 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,43 @@ 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;
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->getCellRange();
+ aData.maGuid = rField->getGuid();
+ }
+ }
+
+ aData.maFields = aCustomLabels;
+ return aData;
}
}
- return CustomLabelSeq();
+ return CustomLabelData();
}
css::chart2::RelativePosition lcl_getCustomLabelPosition(
@@ -3466,7 +3490,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 +3569,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 +3625,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 +3682,22 @@ 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)
+
+ 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..c7c86ca49e77 100644
--- a/xmloff/source/chart/SchXMLSeries2Context.cxx
+++ b/xmloff/source/chart/SchXMLSeries2Context.cxx
@@ -1220,16 +1220,28 @@ 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)
{
+ auto& rCustomLabels = seriesStyle.mCustomLabels;
+
Sequence< Reference<chart2::XDataPointCustomLabelField>> xLabels(nLabelCount);
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->setFieldType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT);
+ xCustomLabel->setString(rCustomLabels.mLabels[j]);
+ if ( j == 0 && rCustomLabels.mbDataLabelsRange)
+ {
+ xCustomLabel->setFieldType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLRANGE);
+ xCustomLabel->setGuid(rCustomLabels.msLabelGuid);
+ xCustomLabel->setCellRange(rCustomLabels.msLabelsCellRange);
+ xCustomLabel->setDataLabelsRange(true);
+ }
+ else
+ {
+ xCustomLabel->setFieldType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT);
+ }
// Restore character properties on the text span manually, till
// SchXMLExportHelper_Impl::exportCustomLabel() does not write the style.
@@ -1251,6 +1263,7 @@ void SchXMLSeries2Context::setStylesToDataPoints( SeriesDefaultsAndStyles& rSeri
}
}
}
+
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
commit f567bddaad3de2ac02f0d0cbec6e3816b730fae9
Author: Andras Timar <andras.timar at collabora.com>
AuthorDate: Mon Aug 30 10:32:17 2021 +0200
Commit: Andras Timar <andras.timar at collabora.com>
CommitDate: Mon Aug 30 12:07:23 2021 +0200
Bump version to 21.06.4
Change-Id: Ibb0cf6dd46cbe2c6996d02e65e670638b3e242d4
diff --git a/configure.ac b/configure.ac
index 6b0e72a5d573..a9e1f80f74a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,7 @@ dnl in order to create a configure script.
# several non-alphanumeric characters, those are split off and used only for the
# ABOUTBOXPRODUCTVERSIONSUFFIX in openoffice.lst. Why that is necessary, no idea.
-AC_INIT([Collabora Office],[21.06.3.1],[],[],[https://collaboraoffice.com/])
+AC_INIT([Collabora Office],[21.06.4.1],[],[],[https://collaboraoffice.com/])
dnl libnumbertext needs autoconf 2.68, but that can pick up autoconf268 just fine if it is installed
dnl whereas aclocal (as run by autogen.sh) insists on using autoconf and fails hard
commit 5124b5a5cb97eaa1d5a3dd65e082b98f17d75072
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 12:07:22 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 cfde9897d56b0ec076b7350160da9ff8eab6bc45
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 12:07:22 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>
More information about the Libreoffice-commits
mailing list