include/oox/export/chartexport.hxx | 3 + include/oox/token/relationship.hxx | 4 + oox/source/export/chartexport.cxx | 91 ++++++++++++++++++++++++++++--------- oox/source/token/namespaces.txt | 1 oox/source/token/relationship.cxx | 3 - oox/source/token/relationship.inc | 1 oox/source/token/tokens.txt | 1 7 files changed, 80 insertions(+), 24 deletions(-)
New commits: commit a94f960d8c14e6926d9e4eebf434d5ffc78c3ae5 Author: knordback <kurt.nordb...@collabora.com> AuthorDate: Fri Apr 4 14:27:06 2025 -0600 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Tue Apr 29 05:07:51 2025 +0200 tdf#165742 Step 4.2: Establish a narrow export path for chartex This is a subtask of tdf#165742: Chartex charts are lost on input from OOXML and re-export. Fix some incorrect URLs and ordering of elements in a <xsd:sequence>. Change-Id: I4092e91851e80114d3cb8e22f602c33faf146969 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183736 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx index 62bc770ea45b..2e11299ed20c 100644 --- a/include/oox/export/chartexport.hxx +++ b/include/oox/export/chartexport.hxx @@ -174,6 +174,9 @@ private: void exportChart( const css::uno::Reference< css::chart::XChartDocument >& rChartDoc, bool bIsChartex); + void exportData( const css::uno::Reference< + css::chart::XChartDocument >& rChartDoc, + bool bIsChartex); void exportExternalData( const css::uno::Reference< css::chart::XChartDocument >& rChartDoc, bool bIsChartex); diff --git a/include/oox/token/relationship.hxx b/include/oox/token/relationship.hxx index c1ae205154cd..3a5e69a5a0f5 100644 --- a/include/oox/token/relationship.hxx +++ b/include/oox/token/relationship.hxx @@ -20,6 +20,7 @@ enum class Relationship { ACTIVEXCONTROLBINARY, CHART, + CHARTEX, CHARTUSERSHAPES, COMMENTS, COMMENTAUTHORS, @@ -66,7 +67,8 @@ enum class Relationship AUDIO, VMLDRAWING, WORDVBADATA, - WORKSHEET + WORKSHEET, + NUM_ENTRIES // last, unused }; OUString OOX_DLLPUBLIC getRelationship(Relationship eRelationship); diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index 07de1964f48a..5e4c0f43cef9 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -787,7 +787,8 @@ void ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nI if (bIsChartex) { // Do the AlternateContent header - mpFS->startElementNS(XML_mc, XML_AlternateContent); + mpFS->startElementNS(XML_mc, XML_AlternateContent, FSNS(XML_xmlns, XML_mc), + "http://schemas.openxmlformats.org/markup-compatibility/2006"); mpFS->startElementNS(XML_mc, XML_Choice, FSNS(XML_xmlns, XML_cx2), "http://schemas.microsoft.com/office/drawing/2015/10/21/chartex", XML_Requires, "cx2"); @@ -893,21 +894,29 @@ void ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nI .appendAscii(sChartFnamePrefix) .append(OUString::number(nChartCount) + ".xml" ) .makeStringAndClear(); + + const OUString sAppURL = bIsChartex? + u"application/vnd.ms-office.chartex+xml"_ustr : + u"application/vnd.openxmlformats-officedocument.drawingml.chart+xml"_ustr; + + const Relationship eChartRel = bIsChartex ? + Relationship::CHARTEX : + Relationship::CHART; + FSHelperPtr pChart = CreateOutputStream( sFullStream, sRelativeStream, pFS->getOutputStream(), - u"application/vnd.openxmlformats-officedocument.drawingml.chart+xml"_ustr, - oox::getRelationship(Relationship::CHART), + sAppURL, + oox::getRelationship(eChartRel), &sId ); XmlFilterBase* pFB = GetFB(); if (bIsChartex) { - // There's no dmlChartex namespace, but using that to avoid hard-coding - // the URL here + // Use chartex namespace pFS->singleElement( FSNS( XML_cx, XML_chart ), - FSNS(XML_xmlns, XML_cx), pFB->getNamespaceURL(OOX_NS(dmlChartex)), + FSNS(XML_xmlns, XML_cx), pFB->getNamespaceURL(OOX_NS(cx)), FSNS(XML_xmlns, XML_r), pFB->getNamespaceURL(OOX_NS(officeRel)), FSNS(XML_r, XML_id), sId ); } else { @@ -925,8 +934,6 @@ void ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nI // Do the AlternateContent fallback path pFS->endElementNS(XML_mc, XML_Choice); pFS->startElementNS(XML_mc, XML_Fallback); - // TODO: export bitmap shape as fallback - pFS->startElementNS(XML_xdr, XML_sp, XML_macro, "", XML_textlink, ""); pFS->startElementNS(XML_xdr, XML_nvSpPr); pFS->singleElementNS(XML_xdr, XML_cNvPr, XML_id, "0", XML_name, ""); @@ -1048,16 +1055,26 @@ void ChartExport::exportChartSpace( const Reference< css::chart::XChartDocument const sal_Int32 nChartNS = bIsChartex ? XML_cx : XML_c; - pFS->startElement( FSNS( nChartNS, XML_chartSpace ), - FSNS( XML_xmlns, nChartNS ), pFB->getNamespaceURL(OOX_NS(dmlChart)), - FSNS( XML_xmlns, XML_a ), pFB->getNamespaceURL(OOX_NS(dml)), - FSNS( XML_xmlns, XML_r ), pFB->getNamespaceURL(OOX_NS(officeRel))); + if (bIsChartex) { + pFS->startElement( FSNS( nChartNS, XML_chartSpace ), + FSNS( XML_xmlns, XML_a ), pFB->getNamespaceURL(OOX_NS(dml)), + FSNS( XML_xmlns, XML_r ), pFB->getNamespaceURL(OOX_NS(officeRel)), + FSNS( XML_xmlns, XML_cx ), pFB->getNamespaceURL(OOX_NS(cx))); + } else { + pFS->startElement( FSNS( nChartNS, XML_chartSpace ), + FSNS( XML_xmlns, XML_c ), pFB->getNamespaceURL(OOX_NS(dmlChart)), + FSNS( XML_xmlns, XML_a ), pFB->getNamespaceURL(OOX_NS(dml)), + FSNS( XML_xmlns, XML_r ), pFB->getNamespaceURL(OOX_NS(officeRel))); + } // TODO: get the correct editing language if (bIsChartex) { // chartData pFS->startElement(FSNS(XML_cx, XML_chartData)); + exportExternalData(xChartDoc, true); + exportData(xChartDoc, true); + pFS->endElement(FSNS(XML_cx, XML_chartData)); } else { pFS->singleElement(FSNS(XML_c, XML_lang), XML_val, "en-US"); @@ -1094,6 +1111,25 @@ void ChartExport::exportChartSpace( const Reference< css::chart::XChartDocument pFS->endElement( FSNS( nChartNS, XML_chartSpace ) ); } +void ChartExport::exportData( [[maybe_unused]] const Reference< css::chart::XChartDocument >& xChartDoc, + bool bIsChartex) +{ + if (bIsChartex) { + FSHelperPtr pFS = GetFS(); + + pFS->startElement(FSNS(XML_cx, XML_data), XML_id, "0"); + // Just hard-coding this for now + pFS->startElement(FSNS(XML_cx, XML_numDim), XML_type, "val"); + pFS->startElement(FSNS(XML_cx, XML_f)); + pFS->writeEscaped("_xlchart.v2.0"); // I have no idea what this + // means or what it should be in + // general + pFS->endElement(FSNS(XML_cx, XML_f)); + pFS->endElement(FSNS(XML_cx, XML_numDim)); + pFS->endElement(FSNS(XML_cx, XML_data)); + } +} + void ChartExport::exportExternalData( const Reference< css::chart::XChartDocument >& xChartDoc, bool bIsChartex) { @@ -1293,7 +1329,6 @@ void ChartExport::exportChart( const Reference< css::chart::XChartDocument >& xC pFS->startElement(FSNS(nChartNS, XML_chart)); // titles - const char * const sTitleDelVal = "1"; if( bHasMainTitle ) { exportTitle( xChartDoc->getTitle(), bIsChartex, xFormattedSubTitle); @@ -1309,7 +1344,7 @@ void ChartExport::exportChart( const Reference< css::chart::XChartDocument >& xC } } else if (!bIsChartex) { - pFS->singleElement(FSNS(XML_c, XML_autoTitleDeleted), XML_val, sTitleDelVal); + pFS->singleElement(FSNS(XML_c, XML_autoTitleDeleted), XML_val, "1"); } InitPlotArea( ); @@ -1646,14 +1681,22 @@ void ChartExport::exportTitle( const Reference< XShape >& xShape, bool bIsCharte pFS->endElement(FSNS(XML_cx, XML_v)); pFS->endElement(FSNS(XML_cx, XML_txData)); pFS->endElement(FSNS(XML_cx, XML_tx)); - - pFS->startElement(FSNS(XML_cx, XML_txPr)); } else { pFS->startElement(FSNS(XML_c, XML_title)); pFS->startElement(FSNS(XML_c, XML_tx)); pFS->startElement(FSNS(XML_c, XML_rich)); } + if (bIsChartex) { + // shape properties + if( xPropSet.is() ) + { + exportShapeProps( xPropSet, bIsChartex ); + } + + pFS->startElement(FSNS(XML_cx, XML_txPr)); + } + // TODO: bodyPr const char* sWritingMode = nullptr; bool bVertical = false; @@ -1766,10 +1809,12 @@ void ChartExport::exportTitle( const Reference< XShape >& xShape, bool bIsCharte pFS->singleElement(FSNS(XML_c, XML_overlay), XML_val, "0"); } - // shape properties - if( xPropSet.is() ) - { - exportShapeProps( xPropSet, bIsChartex ); + if (!bIsChartex) { + // shape properties + if( xPropSet.is() ) + { + exportShapeProps( xPropSet, bIsChartex ); + } } if (bIsChartex) { @@ -2004,6 +2049,11 @@ void ChartExport::exportPlotArea(const Reference< css::chart::XChartDocument >& } } + + if (bIsChartex) { + pFS->endElement( FSNS( XML_cx, XML_plotAreaRegion ) ); + } + //Axis Data exportAxes( bIsChartex ); @@ -2042,7 +2092,6 @@ void ChartExport::exportPlotArea(const Reference< css::chart::XChartDocument >& } if (bIsChartex) { - pFS->endElement( FSNS( XML_cx, XML_plotAreaRegion ) ); pFS->endElement( FSNS( XML_cx, XML_plotArea ) ); } else { pFS->endElement( FSNS( XML_c, XML_plotArea ) ); diff --git a/oox/source/token/namespaces.txt b/oox/source/token/namespaces.txt index 4cd929671823..e1d56b2a1bf8 100644 --- a/oox/source/token/namespaces.txt +++ b/oox/source/token/namespaces.txt @@ -48,7 +48,6 @@ ppt http://schemas.openxmlformats.org/presentationml/2006/ma dml http://schemas.openxmlformats.org/drawingml/2006/main dsp http://schemas.microsoft.com/office/drawing/2008/diagram dmlChart http://schemas.openxmlformats.org/drawingml/2006/chart -dmlChartex http://schemas.microsoft.com/office/drawing/2014/chartex dmlChartDr http://schemas.openxmlformats.org/drawingml/2006/chartDrawing dmlDiagram http://schemas.openxmlformats.org/drawingml/2006/diagram dmlLockedCanvas http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas diff --git a/oox/source/token/relationship.cxx b/oox/source/token/relationship.cxx index c146a7e0b8c0..a0f48de4ce7b 100644 --- a/oox/source/token/relationship.cxx +++ b/oox/source/token/relationship.cxx @@ -20,7 +20,8 @@ namespace oox namespace { -constexpr frozen::unordered_map<Relationship, std::u16string_view, 49> constRelationshipMap +constexpr frozen::unordered_map<Relationship, std::u16string_view, + static_cast<sal_Int32>(Relationship::NUM_ENTRIES)> constRelationshipMap { #include "relationship.inc" }; diff --git a/oox/source/token/relationship.inc b/oox/source/token/relationship.inc index 11898133eb06..20185c31816c 100644 --- a/oox/source/token/relationship.inc +++ b/oox/source/token/relationship.inc @@ -1,5 +1,6 @@ {Relationship::ACTIVEXCONTROLBINARY, u"http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary"}, {Relationship::CHART, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"}, +{Relationship::CHARTEX, u"http://schemas.microsoft.com/office/2014/relationships/chartEx"}, {Relationship::CHARTUSERSHAPES, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes"}, {Relationship::COMMENTS, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"}, {Relationship::COMMENTAUTHORS, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors"}, diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index 0ad9e11b0247..b6051ead0324 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -3662,6 +3662,7 @@ null num numCache numCol +numDim numFmt numFmtId numFmts