File bsc1135597.patch of Package libreoffice

From 6afe2368a9ffa8e97148efc719d9983de803e2f9 Mon Sep 17 00:00:00 2001
From: Tamas Bunth <tamas.bunth@collabora.co.uk>
Date: Thu, 3 Oct 2019 19:49:57 +0200
Subject: [PATCH] tdf#123206 Import/Export chart custom label text
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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 <btomi96@gmail.com>
Reviewed-on: https://gerrit.libreoffice.org/84075
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
---
 chart2/qa/extras/chart2export.cxx                  |  16 ++++++
 chart2/qa/extras/data/docx/tdf123206.docx          | Bin 0 -> 24223 bytes
 include/xmloff/xmltoken.hxx                        |   1 +
 .../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(-)
 create mode 100755 chart2/qa/extras/data/docx/tdf123206.docx

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/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
--
2.16.4