diff options
author | Balazs Varga <balazs.varga.extern@allotropia.de> | 2024-04-15 13:39:03 +0200 |
---|---|---|
committer | Balazs Varga <balazs.varga.extern@allotropia.de> | 2024-04-18 18:07:57 +0200 |
commit | d7214aba95bbdcbd40e87ef50fc66f2e2ec4f5ff (patch) | |
tree | a4a7b62270149e841b8510cb3e810de43ae9b8c5 /xmloff/source/chart | |
parent | 176406a07edc29f59a67464c7812358f46421f4d (diff) |
tdf#160517 - chart odf: import/export formatted chart titles
(main, sub, axis titles) texts properly to/from odf format.
Fix odf export of formatted chart titles. The exported data structure
will look like:
<chart:title svg:x="3.304cm" svg:y="0.285cm" chart:style-name="ch2">
<text:p>
<text:span text:style-name="T1">This</text:span>
<text:span text:style-name="T2"> is</text:span>
.
.
.
<text:span text:style-name="T3">3</text:span>
<text:span text:style-name="T2"> a </text:span>
</text:p>
</chart:title>
Fix import of formatted chart titles. Put the properties and related texts
into the chart2::XFormattedString2 uno objects.
Follow-up commit of:
55e9a27afd2d6a13cf76b39641bf121c3ec4b45c
Related: tdf#39052 - chart ooxml: export formatted chart titles
4f994cec388377cc5c2bddb804bd92eb4cd7dc8d
tdf#39052 - Chart: make characters formatable in editable chart textshapes
--
TODO: chart data point / dataseries labels are handled differently
since those are not editable objects, but that is a completily different
issue.
--
Change-Id: I1842f2c69c132bdf578bb2d354f451cc9d49c63c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166122
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Tested-by: Jenkins
Reviewed-by: Balazs Varga <balazs.varga.extern@allotropia.de>
Diffstat (limited to 'xmloff/source/chart')
-rw-r--r-- | xmloff/source/chart/SchXMLAxisContext.cxx | 22 | ||||
-rw-r--r-- | xmloff/source/chart/SchXMLChartContext.cxx | 39 | ||||
-rw-r--r-- | xmloff/source/chart/SchXMLChartContext.hxx | 6 | ||||
-rw-r--r-- | xmloff/source/chart/SchXMLExport.cxx | 77 | ||||
-rw-r--r-- | xmloff/source/chart/SchXMLParagraphContext.cxx | 131 | ||||
-rw-r--r-- | xmloff/source/chart/SchXMLParagraphContext.hxx | 44 | ||||
-rw-r--r-- | xmloff/source/chart/SchXMLTools.cxx | 92 | ||||
-rw-r--r-- | xmloff/source/chart/SchXMLTools.hxx | 4 | ||||
-rw-r--r-- | xmloff/source/chart/transporttypes.hxx | 2 |
9 files changed, 334 insertions, 83 deletions
diff --git a/xmloff/source/chart/SchXMLAxisContext.cxx b/xmloff/source/chart/SchXMLAxisContext.cxx index b54808790845..b6097590868f 100644 --- a/xmloff/source/chart/SchXMLAxisContext.cxx +++ b/xmloff/source/chart/SchXMLAxisContext.cxx @@ -552,26 +552,18 @@ void SchXMLAxisContext::CreateAxis() void SchXMLAxisContext::SetAxisTitle() { - if( m_aCurrentAxis.aTitle.isEmpty() ) + if( m_aCurrentAxis.maTitle.empty() ) return; Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) ); if( !xAxis.is() ) return; - Reference< beans::XPropertySet > xTitleProp( xAxis->getAxisTitle() ); - if( xTitleProp.is() ) - { - try - { - // TODO: ODF import for formatted chart titles - xTitleProp->setPropertyValue("String", uno::Any(m_aCurrentAxis.aTitle) ); - } - catch( beans::UnknownPropertyException & ) - { - SAL_INFO("xmloff.chart", "Property String for Title not available" ); - } - } + if (m_aCurrentAxis.maTitle.back().first.isEmpty() && + m_aCurrentAxis.maTitle.back().second == OUStringChar(u'\x0D')) + m_aCurrentAxis.maTitle.pop_back(); // remove last end of paragraph break + + SchXMLTools::importFormattedText(GetImport(), m_aCurrentAxis.maTitle, xAxis->getAxisTitle()); } css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLAxisContext::createFastChildContext( @@ -583,7 +575,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLAxisContext::cre case XML_ELEMENT(CHART, XML_TITLE): { return new SchXMLTitleContext( m_rImportHelper, GetImport(), - m_aCurrentAxis.aTitle, + m_aCurrentAxis.maTitle, getTitleShape() ); } break; diff --git a/xmloff/source/chart/SchXMLChartContext.cxx b/xmloff/source/chart/SchXMLChartContext.cxx index 6072a1a09622..7066bfe1ef71 100644 --- a/xmloff/source/chart/SchXMLChartContext.cxx +++ b/xmloff/source/chart/SchXMLChartContext.cxx @@ -729,37 +729,16 @@ void SchXMLChartContext::endFastElement(sal_Int32 ) if( xProp.is()) { - if( !maMainTitle.isEmpty()) + if( !maMainTitle.empty()) { - uno::Reference< beans::XPropertySet > xTitleProp( xDoc->getTitle(), uno::UNO_QUERY ); - if( xTitleProp.is()) - { - try - { - // TODO: ODF import for formatted chart titles - xTitleProp->setPropertyValue("String", uno::Any(maMainTitle) ); - } - catch(const beans::UnknownPropertyException&) - { - SAL_WARN("xmloff.chart", "Property String for Title not available" ); - } - } + uno::Reference< beans::XPropertySet > xTitleProp(xDoc->getTitle(), uno::UNO_QUERY); + SchXMLTools::importFormattedText(GetImport(), maMainTitle, xTitleProp); } - if( !maSubTitle.isEmpty()) + + if( !maSubTitle.empty()) { - uno::Reference< beans::XPropertySet > xTitleProp( xDoc->getSubTitle(), uno::UNO_QUERY ); - if( xTitleProp.is()) - { - try - { - // TODO: ODF import for formatted chart titles - xTitleProp->setPropertyValue("String", uno::Any(maSubTitle) ); - } - catch(const beans::UnknownPropertyException&) - { - SAL_WARN("xmloff.chart", "Property String for Title not available" ); - } - } + uno::Reference< beans::XPropertySet > xTitleProp(xDoc->getSubTitle(), uno::UNO_QUERY); + SchXMLTools::importFormattedText(GetImport(), maSubTitle, xTitleProp); } } @@ -1181,7 +1160,7 @@ void SchXMLChartContext::InitChart( } SchXMLTitleContext::SchXMLTitleContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, - OUString& rTitle, + std::vector<std::pair<OUString, OUString>>& rTitle, uno::Reference< drawing::XShape > xTitleShape ) : SvXMLImportContext( rImport ), mrImportHelper( rImpHelper ), @@ -1247,7 +1226,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLTitleContext::cr if( nElement == XML_ELEMENT(TEXT, XML_P) || nElement == XML_ELEMENT(LO_EXT, XML_P) ) { - pContext = new SchXMLParagraphContext( GetImport(), mrTitle ); + pContext = new SchXMLTitleParaContext(GetImport(), mrTitle); } else XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement); diff --git a/xmloff/source/chart/SchXMLChartContext.hxx b/xmloff/source/chart/SchXMLChartContext.hxx index f79be55b88d9..6c7b6ececfa2 100644 --- a/xmloff/source/chart/SchXMLChartContext.hxx +++ b/xmloff/source/chart/SchXMLChartContext.hxx @@ -91,7 +91,7 @@ private: SchXMLTable maTable; SchXMLImportHelper& mrImportHelper; - OUString maMainTitle, maSubTitle; + std::vector<std::pair<OUString, OUString>> maMainTitle, maSubTitle; OUString m_aXLinkHRefAttributeToIndicateDataProvider; bool m_bHasRangeAtPlotArea; bool m_bHasTableElement; @@ -130,14 +130,14 @@ class SchXMLTitleContext : public SvXMLImportContext { private: SchXMLImportHelper& mrImportHelper; - OUString& mrTitle; + std::vector<std::pair<OUString, OUString>>& mrTitle; css::uno::Reference< css::drawing::XShape > mxTitleShape; OUString msAutoStyleName; public: SchXMLTitleContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, - OUString& rTitle, + std::vector<std::pair<OUString, OUString>>& rTitle, css::uno::Reference< css::drawing::XShape > xTitleShape ); virtual ~SchXMLTitleContext() override; diff --git a/xmloff/source/chart/SchXMLExport.cxx b/xmloff/source/chart/SchXMLExport.cxx index 56cdca7bdefa..778969ecf83c 100644 --- a/xmloff/source/chart/SchXMLExport.cxx +++ b/xmloff/source/chart/SchXMLExport.cxx @@ -208,6 +208,8 @@ public: ::std::queue< OUString > maAutoStyleNameQueue; void CollectAutoStyle( std::vector< XMLPropertyState >&& aStates ); + void CollectAutoTextStyle( + const css::uno::Reference< css::beans::XPropertySet >& xTitlePropSet ); void AddAutoStyleAttribute( const std::vector< XMLPropertyState >& aStates ); @@ -276,6 +278,7 @@ public: void addSize( const css::uno::Reference< css::drawing::XShape >& xShape ); /// exports a string as a paragraph element void exportText( const OUString& rText ); + void exportFormattedText( const css::uno::Reference< beans::XPropertySet >& xTitleProps ); public: SvXMLExport& mrExport; @@ -1322,15 +1325,14 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > if( bHasMainTitle ) { // get property states for autostyles - if( mxExpPropMapper.is()) + Reference< drawing::XShape > xShape = rChartDoc->getTitle(); + Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY); + if( mxExpPropMapper.is() && xPropSet.is()) { - Reference< beans::XPropertySet > xPropSet( rChartDoc->getTitle(), uno::UNO_QUERY ); - if( xPropSet.is()) - aPropertyStates = mxExpPropMapper->Filter(mrExport, xPropSet); + aPropertyStates = mxExpPropMapper->Filter(mrExport, xPropSet); } if( bExportContent ) { - Reference< drawing::XShape > xShape = rChartDoc->getTitle(); if( xShape.is()) // && "hasTitleBeenMoved" addPosition( xShape ); @@ -1341,19 +1343,12 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > SvXMLElementExport aElTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, true, true ); // content (text:p) - Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY ); - if( xPropSet.is()) - { - // TODO: ODF export for formatted chart titles - Any aAny( xPropSet->getPropertyValue( "String" )); - OUString aText; - aAny >>= aText; - exportText( aText ); - } + exportFormattedText(xPropSet); } else // autostyles { CollectAutoStyle( std::move(aPropertyStates) ); + CollectAutoTextStyle( xPropSet ); } // remove property states for autostyles aPropertyStates.clear(); @@ -1363,16 +1358,15 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > if( bHasSubTitle ) { // get property states for autostyles - if( mxExpPropMapper.is()) + Reference< drawing::XShape > xShape = rChartDoc->getSubTitle(); + Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY); + if( mxExpPropMapper.is() && xPropSet.is()) { - Reference< beans::XPropertySet > xPropSet( rChartDoc->getSubTitle(), uno::UNO_QUERY ); - if( xPropSet.is()) - aPropertyStates = mxExpPropMapper->Filter(mrExport, xPropSet); + aPropertyStates = mxExpPropMapper->Filter(mrExport, xPropSet); } if( bExportContent ) { - Reference< drawing::XShape > xShape = rChartDoc->getSubTitle(); if( xShape.is()) addPosition( xShape ); @@ -1383,19 +1377,12 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > SvXMLElementExport aElSubTitle( mrExport, XML_NAMESPACE_CHART, XML_SUBTITLE, true, true ); // content (text:p) - Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY ); - if( xPropSet.is()) - { - // TODO: ODF import for formatted chart titles - Any aAny( xPropSet->getPropertyValue( "String" )); - OUString aText; - aAny >>= aText; - exportText( aText ); - } + exportFormattedText(xPropSet); } else // autostyles { CollectAutoStyle( std::move(aPropertyStates) ); + CollectAutoTextStyle(xPropSet); } // remove property states for autostyles aPropertyStates.clear(); @@ -2266,11 +2253,6 @@ void SchXMLExportHelper_Impl::exportAxisTitle( const Reference< beans::XProperty std::vector<XMLPropertyState> aPropertyStates = mxExpPropMapper->Filter(mrExport, rTitleProps); if( bExportContent ) { - // TODO: ODF import for formatted chart titles - OUString aText; - Any aAny( rTitleProps->getPropertyValue( "String" )); - aAny >>= aText; - Reference< drawing::XShape > xShape( rTitleProps, uno::UNO_QUERY ); if( xShape.is()) addPosition( xShape ); @@ -2279,11 +2261,12 @@ void SchXMLExportHelper_Impl::exportAxisTitle( const Reference< beans::XProperty SvXMLElementExport aTitle( mrExport, XML_NAMESPACE_CHART, XML_TITLE, true, true ); // paragraph containing title - exportText( aText ); + exportFormattedText( rTitleProps ); } else { CollectAutoStyle( std::move(aPropertyStates) ); + CollectAutoTextStyle( rTitleProps ); } aPropertyStates.clear(); } @@ -3827,6 +3810,27 @@ void SchXMLExportHelper_Impl::CollectAutoStyle( std::vector< XMLPropertyState >& maAutoStyleNameQueue.push( mrAutoStylePool.Add( XmlStyleFamily::SCH_CHART_ID, std::move(aStates) )); } +void SchXMLExportHelper_Impl::CollectAutoTextStyle( const css::uno::Reference< beans::XPropertySet >& xTitlePropSet ) +{ + if (xTitlePropSet.is()) + { + Sequence< uno::Reference< chart2::XFormattedString > > xFormattedTitle; + + OUString aTitle; + if ((xTitlePropSet->getPropertyValue("String") >>= aTitle) && !aTitle.isEmpty()) + xTitlePropSet->getPropertyValue("FormattedStrings") >>= xFormattedTitle; + + if (xFormattedTitle.hasElements()) + { + for (const uno::Reference<chart2::XFormattedString>& rxFS : xFormattedTitle) + { + Reference< beans::XPropertySet > xRunPropSet(rxFS, uno::UNO_QUERY); + mrExport.GetTextParagraphExport()->Add(XmlStyleFamily::TEXT_TEXT, xRunPropSet); + } + } + } +} + void SchXMLExportHelper_Impl::AddAutoStyleAttribute( const std::vector< XMLPropertyState >& aStates ) { if( !aStates.empty() ) @@ -3843,6 +3847,11 @@ void SchXMLExportHelper_Impl::exportText( const OUString& rText ) SchXMLTools::exportText( mrExport, rText, false/*bConvertTabsLFs*/ ); } +void SchXMLExportHelper_Impl::exportFormattedText( const css::uno::Reference< beans::XPropertySet >& xTitleProps ) +{ + SchXMLTools::exportFormattedText( mrExport, xTitleProps ); +} + SchXMLExport::SchXMLExport(const Reference<uno::XComponentContext>& xContext, OUString const& implementationName, SvXMLExportFlags nExportFlags) diff --git a/xmloff/source/chart/SchXMLParagraphContext.cxx b/xmloff/source/chart/SchXMLParagraphContext.cxx index 9ed285916188..6f9dc0ce72cb 100644 --- a/xmloff/source/chart/SchXMLParagraphContext.cxx +++ b/xmloff/source/chart/SchXMLParagraphContext.cxx @@ -101,4 +101,135 @@ void SchXMLParagraphContext::characters( const OUString& rChars ) maBuffer.append( rChars ); } +SchXMLTitleParaContext::SchXMLTitleParaContext( SvXMLImport& rImport, + std::vector<std::pair<OUString, OUString>>& rParaText, + OUString * pOutId /* = 0 */ ) : + SvXMLImportContext( rImport ), + mrParaText( rParaText ), + mpId( pOutId ) +{ +} + +SchXMLTitleParaContext::~SchXMLTitleParaContext() +{} + +void SchXMLTitleParaContext::startFastElement( + sal_Int32 /*nElement*/, + const uno::Reference< xml::sax::XFastAttributeList >& xAttrList ) +{ + // remember the id. It is used for storing the original cell range string in + // a local table (cached data) + if( !mpId ) + return; + + bool bHaveXmlId( false ); + + for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) + { + switch(aIter.getToken()) + { + case XML_ELEMENT(TEXT, XML_STYLE_NAME): + maStyleName = aIter.toString(); + break; + case XML_ELEMENT(XML, XML_ID): + (*mpId) = aIter.toString(); + bHaveXmlId = true; + break; + case XML_ELEMENT(TEXT, XML_ID): + { // text:id shall be ignored if xml:id exists + if (!bHaveXmlId) + { + (*mpId) = aIter.toString(); + } + break; + } + default: + XMLOFF_WARN_UNKNOWN("xmloff", aIter); + } + } +} + +void SchXMLTitleParaContext::endFastElement(sal_Int32 ) +{ + if (!maBuffer.isEmpty()) + mrParaText.push_back(std::make_pair(maStyleName, maBuffer.makeStringAndClear())); +} + +void SchXMLTitleParaContext::characters(const OUString& rChars) +{ + maBuffer.append(rChars); +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLTitleParaContext::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList) +{ + if( nElement == XML_ELEMENT(TEXT, XML_SPAN) ) + { + if (!maBuffer.isEmpty()) + mrParaText.push_back(std::make_pair(maStyleName, maBuffer.makeStringAndClear())); + + return new SchXMLTitleSpanContext(GetImport(), mrParaText, xAttrList); + } + else if( nElement == XML_ELEMENT(TEXT, XML_TAB_STOP) ) + { + maBuffer.append( u'\x0009'); // tabulator + } + else if( nElement == XML_ELEMENT(TEXT, XML_LINE_BREAK) ) + { + maBuffer.append( u'\x000A'); // linefeed + } + else + XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement); + + return nullptr; +} + +SchXMLTitleSpanContext::SchXMLTitleSpanContext(SvXMLImport& rImport, std::vector<std::pair<OUString, OUString>>& rSpanTexts, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList) : + SvXMLImportContext(rImport), + mrSpanTexts(rSpanTexts) +{ + for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) + { + if( aIter.getToken() == XML_ELEMENT(TEXT, XML_STYLE_NAME) ) + { + maStyleName = aIter.toString(); + break; + } + } +} + +SchXMLTitleSpanContext::~SchXMLTitleSpanContext() +{} + +void SchXMLTitleSpanContext::characters(const OUString& rChars) +{ + maCharBuffer.append(rChars); +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLTitleSpanContext::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/) +{ + if( nElement == XML_ELEMENT(TEXT, XML_TAB_STOP) ) + { + maCharBuffer.append( u'\x0009'); // tabulator + } + else if( nElement == XML_ELEMENT(TEXT, XML_LINE_BREAK) ) + { + maCharBuffer.append( u'\x000A'); // linefeed + } + else + XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement); + + return nullptr; +} + +void SchXMLTitleSpanContext::endFastElement(sal_Int32) +{ + if (!maCharBuffer.isEmpty()) + mrSpanTexts.push_back(std::make_pair(maStyleName, maCharBuffer.makeStringAndClear())); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/chart/SchXMLParagraphContext.hxx b/xmloff/source/chart/SchXMLParagraphContext.hxx index 65e90522e860..ba2231bd5d24 100644 --- a/xmloff/source/chart/SchXMLParagraphContext.hxx +++ b/xmloff/source/chart/SchXMLParagraphContext.hxx @@ -50,4 +50,48 @@ public: const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override; }; +class SchXMLTitleParaContext : public SvXMLImportContext +{ +private: + std::vector<std::pair<OUString, OUString>>& mrParaText; + OUString* mpId; + OUStringBuffer maBuffer; + OUString maStyleName; + +public: + SchXMLTitleParaContext( SvXMLImport& rImport, + std::vector<std::pair<OUString, OUString>>& rParaText, + OUString * pOutId = nullptr ); + virtual ~SchXMLTitleParaContext() override; + + virtual void SAL_CALL startFastElement( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + virtual void SAL_CALL characters( const OUString& rChars ) override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override; +}; + +class SchXMLTitleSpanContext : public SvXMLImportContext +{ +private: + std::vector<std::pair<OUString, OUString>>& mrSpanTexts; + OUStringBuffer maCharBuffer; + OUString maStyleName; +public: + SchXMLTitleSpanContext( SvXMLImport& rImport, std::vector<std::pair<OUString, OUString>>& rSpanTexts, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList); + virtual ~SchXMLTitleSpanContext() override; + + virtual void SAL_CALL characters( const OUString& rChars ) override; + virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*AttrList*/) override; +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/chart/SchXMLTools.cxx b/xmloff/source/chart/SchXMLTools.cxx index 4287b731a7fb..fb3dc9e29c56 100644 --- a/xmloff/source/chart/SchXMLTools.cxx +++ b/xmloff/source/chart/SchXMLTools.cxx @@ -26,6 +26,7 @@ #include <xmloff/prstylei.hxx> #include <xmloff/xmlprmap.hxx> #include <xmloff/xmlexp.hxx> +#include <xmloff/xmlimp.hxx> #include <xmloff/xmlnamespace.hxx> #include <xmloff/xmlmetai.hxx> #include <xmloff/maptype.hxx> @@ -37,6 +38,7 @@ #include <com/sun/star/chart2/data/XDataReceiver.hpp> #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp> #include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp> +#include <com/sun/star/chart2/FormattedString.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> #include <com/sun/star/container/XChild.hpp> @@ -47,6 +49,7 @@ #include <comphelper/processfactory.hxx> #include <comphelper/diagnose_ex.hxx> +#include <comphelper/sequence.hxx> #include <sal/log.hxx> #include <o3tl/string_view.hxx> #include <algorithm> @@ -605,6 +608,95 @@ void exportText( SvXMLExport& rExport, const OUString& rText, bool bConvertTabsL } } +void exportFormattedText( SvXMLExport& rExport, const uno::Reference< beans::XPropertySet >& xTitleProps ) +{ + Sequence< uno::Reference< chart2::XFormattedString > > xFormattedTitle; + if (xTitleProps.is()) + { + OUString aTitle; + if ((xTitleProps->getPropertyValue("String") >>= aTitle) && !aTitle.isEmpty()) + xTitleProps->getPropertyValue("FormattedStrings") >>= xFormattedTitle; + } + + if (xFormattedTitle.hasElements()) + { + SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, true, false); + for (const uno::Reference<chart2::XFormattedString>& rxFS : xFormattedTitle) + { + Reference< beans::XPropertySet > xRunPropSet(rxFS, uno::UNO_QUERY); + bool bIsUICharStyle, bHasAutoStyle = false; + OUString sStyle = rExport.GetTextParagraphExport()->FindTextStyle(xRunPropSet, bIsUICharStyle, bHasAutoStyle); + if (!sStyle.isEmpty()) + { + rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, + rExport.EncodeStyleName(sStyle)); + } + + SvXMLElementExport aSpan(rExport, !sStyle.isEmpty(), XML_NAMESPACE_TEXT, XML_SPAN, true, false); + rExport.GetDocHandler()->characters(rxFS->getString()); + } + } +} + +void importFormattedText( SvXMLImport& rImport, const std::vector<std::pair<OUString, OUString>>& rTitle, + const uno::Reference< beans::XPropertySet >& xTitleProp ) +{ + if (!xTitleProp.is()) + return; + + std::vector< Reference< chart2::XFormattedString > > aStringVec; + Sequence< uno::Reference< chart2::XFormattedString > > xFullTextTitle; + Reference < beans::XPropertySet > xFullTextTitleProps; + + try + { + if ((xTitleProp->getPropertyValue("FormattedStrings") >>= xFullTextTitle) && + xFullTextTitle.hasElements()) + { + // these are the properies from the textshape object - needs to apply them + // to all the string parts firstly - (necessarry for backward compatibility) + xFullTextTitleProps.set(xFullTextTitle.getArray()[0], uno::UNO_QUERY); + } + + for (auto aRIt = std::begin(rTitle); aRIt != std::end(rTitle); ++aRIt) + { + Reference< chart2::XFormattedString2 > xNewFmtStr; + xNewFmtStr = chart2::FormattedString::create(rImport.GetComponentContext()); + + if (xFullTextTitleProps.is()) + { + // these are the properies from the textshape object - needs to apply them + // to all the string parts firstly + uno::Reference< beans::XPropertySetInfo > xInfo = xNewFmtStr->getPropertySetInfo(); + for (const beans::Property& rProp : xFullTextTitleProps->getPropertySetInfo()->getProperties()) + { + if (xInfo.is() && xInfo->hasPropertyByName(rProp.Name)) + { + const uno::Any aValue = xFullTextTitleProps->getPropertyValue(rProp.Name); + xNewFmtStr->setPropertyValue(rProp.Name, aValue); + } + } + } + + if (auto pStyle = rImport.GetTextImport()->FindAutoCharStyle(aRIt->first)) + { + pStyle->FillPropertySet(xNewFmtStr); + } + + xNewFmtStr->setString(aRIt->second); + aStringVec.emplace_back(xNewFmtStr); + } + + uno::Sequence< Reference< chart2::XFormattedString > > aStringSeq = + comphelper::containerToSequence(aStringVec); + xTitleProp->setPropertyValue("FormattedStrings", uno::Any(aStringSeq)); + } + catch (const beans::UnknownPropertyException&) + { + SAL_WARN("xmloff.chart", "Property FormattedStrings for Title not available"); + } +} + void exportRangeToSomewhere( SvXMLExport& rExport, const OUString& rValue ) { //with issue #i366# and CWS chart20 ranges for error bars were introduced diff --git a/xmloff/source/chart/SchXMLTools.hxx b/xmloff/source/chart/SchXMLTools.hxx index 994308a19bc3..364c894c5634 100644 --- a/xmloff/source/chart/SchXMLTools.hxx +++ b/xmloff/source/chart/SchXMLTools.hxx @@ -38,6 +38,7 @@ namespace com::sun::star { class XMLPropStyleContext; class SvXMLStylesContext; class SvXMLExport; +class SvXMLImport; namespace SchXMLTools { @@ -98,6 +99,9 @@ namespace SchXMLTools css::uno::Any getPropertyFromContext( std::u16string_view rPropertyName, const XMLPropStyleContext * pPropStyleContext, const SvXMLStylesContext* pStylesCtxt ); void exportText( SvXMLExport& rExport, const OUString& rText, bool bConvertTabsLFs ); + void exportFormattedText( SvXMLExport& rExport, const css::uno::Reference< css::beans::XPropertySet >& xTitleProps ); + void importFormattedText( SvXMLImport& rImport, const std::vector<std::pair<OUString, OUString>>& rTitle, + const css::uno::Reference< css::beans::XPropertySet >& xTitleProp); void exportRangeToSomewhere( SvXMLExport& rExport, const OUString& rValue ); diff --git a/xmloff/source/chart/transporttypes.hxx b/xmloff/source/chart/transporttypes.hxx index 81d5de8cdb8a..b312af71cf38 100644 --- a/xmloff/source/chart/transporttypes.hxx +++ b/xmloff/source/chart/transporttypes.hxx @@ -103,7 +103,7 @@ struct SchXMLAxis enum SchXMLAxisDimension eDimension; sal_Int8 nAxisIndex;//0->primary axis; 1->secondary axis OUString aName; - OUString aTitle; + std::vector<std::pair<OUString, OUString>> maTitle; bool bHasCategories; SchXMLAxis() : eDimension( SCH_XML_AXIS_UNDEF ), nAxisIndex( 0 ), bHasCategories( false ) {} |