chart2/qa/extras/chart2export.cxx | 16 +++ chart2/qa/extras/data/docx/tdf123206.docx |binary include/xmloff/xmltoken.hxx | 1 schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng | 9 + xmloff/source/chart/SchXMLExport.cxx | 63 ++++++++++-- xmloff/source/chart/SchXMLPlotAreaContext.cxx | 9 + xmloff/source/chart/SchXMLSeries2Context.cxx | 15 ++ xmloff/source/chart/transporttypes.hxx | 1 xmloff/source/core/xmltoken.cxx | 1 xmloff/source/token/tokens.txt | 1 10 files changed, 107 insertions(+), 9 deletions(-)
New commits: commit 6afe2368a9ffa8e97148efc719d9983de803e2f9 Author: Tamas Bunth <tamas.bu...@collabora.co.uk> AuthorDate: Thu Oct 3 19:49:57 2019 +0200 Commit: Tamás Bunth <btom...@gmail.com> CommitDate: Sun Dec 1 22:13:25 2019 +0100 tdf#123206 Import/Export chart custom label text OOX import supports custom label texts in chart diagrams (produced by e.g. double clicking on a data label, and write custom text), but - since embedded objects are exported and imported to odf right after migration - it is not displayed in case of a Writer document. In order to make it work, we have to support custom label text in the odf structure. This commit only allows the import/export of pure text, it should be improved to store and load formatted string. A new XML token is added, which currently refers to an attribute of the chart:data-point tag. If we want to store formatted string, something more clever has to be done. Change-Id: I80c4a3a0dbcf59f1dc732d795fb716da318411cb Reviewed-on: https://gerrit.libreoffice.org/80156 Tested-by: Jenkins Reviewed-by: Tamás Bunth <btom...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/84075 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/chart2/qa/extras/chart2export.cxx b/chart2/qa/extras/chart2export.cxx index 77bc24a7ac46..e15cd39a20da 100644 --- a/chart2/qa/extras/chart2export.cxx +++ b/chart2/qa/extras/chart2export.cxx @@ -127,6 +127,7 @@ public: void testTdf119029(); void testTdf121744(); void testTdf122031(); + void testTdf123206_customLabelText(); CPPUNIT_TEST_SUITE(Chart2ExportTest); CPPUNIT_TEST(testErrorBarXLSX); @@ -216,6 +217,8 @@ public: CPPUNIT_TEST(testTdf119029); CPPUNIT_TEST(testTdf121744); CPPUNIT_TEST(testTdf122031); + CPPUNIT_TEST(testTdf123206_customLabelText); + CPPUNIT_TEST_SUITE_END(); protected: @@ -2022,6 +2025,19 @@ void Chart2ExportTest::testTdf122031() assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:pieChart/c:ser/c:dLbls/c:dLbl[3]/c:numFmt", "formatCode", "0.000%"); } +void Chart2ExportTest::testTdf123206_customLabelText() +{ + load("/chart2/qa/extras/data/docx/", "tdf123206.docx"); + + Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY); + CPPUNIT_ASSERT(xChartDoc.is()); + + xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text"); + CPPUNIT_ASSERT(pXmlDoc); + + assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:pieChart/c:ser/c:dLbls/c:dLbl[2]/c:tx/c:rich/a:p/a:r/a:t", "kiscica"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/chart2/qa/extras/data/docx/tdf123206.docx b/chart2/qa/extras/data/docx/tdf123206.docx new file mode 100755 index 000000000000..f47089fe3b1b Binary files /dev/null and b/chart2/qa/extras/data/docx/tdf123206.docx differ diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index aba87d7d5825..a750c7fe4587 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -534,6 +534,7 @@ namespace xmloff { namespace token { XML_CUSTOM_ICONSET, XML_CUSTOM_ICONSET_INDEX, XML_CUSTOM_ICONSET_NAME, + XML_CUSTOM_LABEL_FIELD, XML_CUT, XML_CUT_OFFS, XML_CX, diff --git a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng index 8e8fecbf7895..24607fe6cf2f 100644 --- a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng +++ b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng @@ -2361,4 +2361,13 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. </rng:optional> </rng:define> + <!-- TODO no proposal --> + <rng:define name="chart-data-point-attlist" combine="interleave"> + <rng:optional> + <rng:attribute name="loext:custom-label-field"> + <rng:ref name="string"/> + </rng:attribute> + </rng:optional> + </rng:define> + </rng:grammar> diff --git a/xmloff/source/chart/SchXMLExport.cxx b/xmloff/source/chart/SchXMLExport.cxx index e9e755dde3d1..d13f58e19a62 100644 --- a/xmloff/source/chart/SchXMLExport.cxx +++ b/xmloff/source/chart/SchXMLExport.cxx @@ -86,6 +86,7 @@ #include <com/sun/star/chart2/XRegressionCurveContainer.hpp> #include <com/sun/star/chart2/XChartTypeContainer.hpp> #include <com/sun/star/chart2/XDataSeriesContainer.hpp> +#include <com/sun/star/chart2/XDataPointCustomLabelField.hpp> #include <com/sun/star/chart2/data/XDataSource.hpp> #include <com/sun/star/chart2/data/XDataSink.hpp> #include <com/sun/star/chart2/data/XDataReceiver.hpp> @@ -117,6 +118,19 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Any; using ::std::vector; + +namespace +{ + struct SchXMLDataPointStruct + { + OUString maStyleName; + sal_Int32 mnRepeat; + OUString msCustomLabelText; + + SchXMLDataPointStruct() : mnRepeat( 1 ) {} + }; +} + // class SchXMLExportHelper_Impl class SchXMLExportHelper_Impl @@ -278,6 +292,33 @@ constexpr OUStringLiteral SchXMLExportHelper_Impl::gsTableName; namespace { +OUString lcl_getCustomLabelField(sal_Int32 nDataPointIndex, + const uno::Reference< chart2::XDataSeries >& rSeries) +{ + if( !rSeries.is() ) + return OUString{}; + + const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() ); + if( nCurrentODFVersion <= SvtSaveOptions::ODFVER_012 )//do not export to ODF 1.2 or older + return OUString{}; + + // export custom label text + if(Reference<beans::XPropertySet> xLabels = rSeries->getDataPointByIndex(nDataPointIndex); xLabels.is()) + { + if(Any aAny = xLabels->getPropertyValue("CustomLabelFields"); aAny.hasValue()) + { + Sequence<uno::Reference<chart2::XDataPointCustomLabelField>> aCustomLabels; + aAny >>= aCustomLabels; + OUString sLabel; + // TODO export formatted string instead of simple characters + for(auto& aLabel : aCustomLabels) + sLabel += aLabel->getString(); + return sLabel; + } + } + return OUString{}; +} + class lcl_MatchesRole { public: @@ -956,14 +997,6 @@ bool lcl_exportDomainForThisSequence( const Reference< chart2::data::XDataSequen } // anonymous namespace -struct SchXMLDataPointStruct -{ - OUString maStyleName; - sal_Int32 mnRepeat; - - SchXMLDataPointStruct() : mnRepeat( 1 ) {} -}; - // class SchXMLExportHelper SchXMLExportHelper::SchXMLExportHelper( SvXMLExport& rExport, SvXMLAutoStylePoolP& rASPool ) @@ -3289,6 +3322,8 @@ void SchXMLExportHelper_Impl::exportDataPoints( SchXMLDataPointStruct aPoint; aPoint.maStyleName = maAutoStyleNameQueue.front(); + if(bExportNumFmt) + aPoint.msCustomLabelText = lcl_getCustomLabelField(nElement, xSeries); maAutoStyleNameQueue.pop(); aDataPointVector.push_back( aPoint ); } @@ -3317,6 +3352,7 @@ void SchXMLExportHelper_Impl::exportDataPoints( { SchXMLDataPointStruct aPoint; aPoint.mnRepeat = nCurrIndex - nLastIndex - 1; + aPoint.msCustomLabelText = lcl_getCustomLabelField(nCurrIndex, xSeries); aDataPointVector.push_back( aPoint ); } @@ -3349,6 +3385,7 @@ void SchXMLExportHelper_Impl::exportDataPoints( SAL_WARN_IF( maAutoStyleNameQueue.empty(), "xmloff.chart", "Autostyle queue empty!" ); SchXMLDataPointStruct aPoint; aPoint.maStyleName = maAutoStyleNameQueue.front(); + aPoint.msCustomLabelText = lcl_getCustomLabelField(nCurrIndex, xSeries); maAutoStyleNameQueue.pop(); aDataPointVector.push_back( aPoint ); @@ -3364,6 +3401,7 @@ void SchXMLExportHelper_Impl::exportDataPoints( // if we get here the property states are empty SchXMLDataPointStruct aPoint; + aPoint.msCustomLabelText = lcl_getCustomLabelField(nCurrIndex, xSeries); aDataPointVector.push_back( aPoint ); nLastIndex = nCurrIndex; @@ -3393,10 +3431,13 @@ void SchXMLExportHelper_Impl::exportDataPoints( { aPoint = rPoint; - if( aPoint.maStyleName == aLastPoint.maStyleName ) + if( aPoint.maStyleName == aLastPoint.maStyleName && aPoint.msCustomLabelText.isEmpty() ) aPoint.mnRepeat += aLastPoint.mnRepeat; else if( aLastPoint.mnRepeat > 0 ) { + // export custom label text + if(!aLastPoint.msCustomLabelText.isEmpty()) + mrExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_CUSTOM_LABEL_FIELD, aLastPoint.msCustomLabelText); // write last element if( !aLastPoint.maStyleName.isEmpty() ) mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_STYLE_NAME, aLastPoint.maStyleName ); @@ -3412,6 +3453,10 @@ void SchXMLExportHelper_Impl::exportDataPoints( // write last element if it hasn't been written in last iteration if( aPoint.maStyleName == aLastPoint.maStyleName ) { + // export custom label text + if(!aLastPoint.msCustomLabelText.isEmpty()) + mrExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_CUSTOM_LABEL_FIELD, aLastPoint.msCustomLabelText); + if( !aLastPoint.maStyleName.isEmpty() ) mrExport.AddAttribute( XML_NAMESPACE_CHART, XML_STYLE_NAME, aLastPoint.maStyleName ); diff --git a/xmloff/source/chart/SchXMLPlotAreaContext.cxx b/xmloff/source/chart/SchXMLPlotAreaContext.cxx index 46fee917baf1..f94d3dea67a4 100644 --- a/xmloff/source/chart/SchXMLPlotAreaContext.cxx +++ b/xmloff/source/chart/SchXMLPlotAreaContext.cxx @@ -618,6 +618,7 @@ void SchXMLDataPointContext::StartElement( const uno::Reference< xml::sax::XAttr sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; OUString sAutoStyleName; sal_Int32 nRepeat = 1; + OUString sCustomLabelField; for( sal_Int16 i = 0; i < nAttrCount; i++ ) { @@ -632,6 +633,13 @@ void SchXMLDataPointContext::StartElement( const uno::Reference< xml::sax::XAttr else if( IsXMLToken( aLocalName, XML_REPEATED ) ) nRepeat = xAttrList->getValueByIndex( i ).toInt32(); } + else if( nPrefix == XML_NAMESPACE_LO_EXT) + { + if( IsXMLToken( aLocalName, XML_CUSTOM_LABEL_FIELD)) + { + sCustomLabelField = xAttrList->getValueByIndex( i ); + } + } } if( !sAutoStyleName.isEmpty()) @@ -640,6 +648,7 @@ void SchXMLDataPointContext::StartElement( const uno::Reference< xml::sax::XAttr DataRowPointStyle::DATA_POINT, m_xSeries, mrIndex, nRepeat, sAutoStyleName ); aStyle.mbSymbolSizeForSeriesIsMissingInFile = mbSymbolSizeForSeriesIsMissingInFile; + aStyle.msCustomLabelField = sCustomLabelField; mrStyleVector.push_back( aStyle ); } mrIndex += nRepeat; diff --git a/xmloff/source/chart/SchXMLSeries2Context.cxx b/xmloff/source/chart/SchXMLSeries2Context.cxx index c1c3c46a4b56..e40145613db0 100644 --- a/xmloff/source/chart/SchXMLSeries2Context.cxx +++ b/xmloff/source/chart/SchXMLSeries2Context.cxx @@ -32,6 +32,10 @@ #include <com/sun/star/chart2/data/XDataReceiver.hpp> #include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp> +#include <com/sun/star/chart2/XDataPointCustomLabelField.hpp> +#include <com/sun/star/chart2/DataPointCustomLabelFieldType.hpp> +#include <com/sun/star/chart2/DataPointCustomLabelField.hpp> + #include <com/sun/star/chart/ChartAxisAssign.hpp> #include <com/sun/star/chart/ChartSymbolType.hpp> #include <com/sun/star/container/XChild.hpp> @@ -1081,6 +1085,17 @@ void SchXMLSeries2Context::setStylesToDataPoints( SeriesDefaultsAndStyles& rSeri if( seriesStyle.mbSymbolSizeForSeriesIsMissingInFile ) lcl_resetSymbolSizeForPointsIfNecessary( xPointProp, rImport, pPropStyleContext, pStylesCtxt ); } + + if(!seriesStyle.msCustomLabelField.isEmpty()) + { + Sequence< Reference<chart2::XDataPointCustomLabelField>> xLabels(1); + Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() ); + Reference< chart2::XDataPointCustomLabelField > xCustomLabel = chart2::DataPointCustomLabelField::create(xContext); + xLabels[0] = xCustomLabel; + xCustomLabel->setString(seriesStyle.msCustomLabelField); + xCustomLabel->setFieldType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT); + xPointProp->setPropertyValue("CustomLabelFields", uno::Any(xLabels)); + } } catch( const uno::Exception & rEx ) { diff --git a/xmloff/source/chart/transporttypes.hxx b/xmloff/source/chart/transporttypes.hxx index 44d3bc3a7b22..6481cfb1c004 100644 --- a/xmloff/source/chart/transporttypes.hxx +++ b/xmloff/source/chart/transporttypes.hxx @@ -168,6 +168,7 @@ struct DataRowPointStyle sal_Int32 m_nPointRepeat; OUString msStyleName; OUString msSeriesStyleNameForDonuts; + OUString msCustomLabelField; sal_Int32 mnAttachedAxis; bool mbSymbolSizeForSeriesIsMissingInFile; diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index a6a463c795d8..8b2b4dcb80f8 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -534,6 +534,7 @@ namespace xmloff { namespace token { TOKEN( "custom-iconset", XML_CUSTOM_ICONSET ), TOKEN( "custom-iconset-index", XML_CUSTOM_ICONSET_INDEX ), TOKEN( "custom-iconset-name", XML_CUSTOM_ICONSET_NAME ), + TOKEN( "custom-label-field", XML_CUSTOM_LABEL_FIELD ), TOKEN( "cut", XML_CUT ), TOKEN( "cut-offs", XML_CUT_OFFS ), TOKEN( "cx", XML_CX ), diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 9594a6c526ff..f6f0d485b1bb 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -457,6 +457,7 @@ custom5 custom-iconset custom-iconset-index custom-iconset-name +custom-label-field cut cut-offs cx _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits