summaryrefslogtreecommitdiff
path: root/xmloff/source/chart
diff options
context:
space:
mode:
authorBalazs Varga <balazs.varga.extern@allotropia.de>2024-04-15 13:39:03 +0200
committerBalazs Varga <balazs.varga.extern@allotropia.de>2024-04-18 18:07:57 +0200
commitd7214aba95bbdcbd40e87ef50fc66f2e2ec4f5ff (patch)
treea4a7b62270149e841b8510cb3e810de43ae9b8c5 /xmloff/source/chart
parent176406a07edc29f59a67464c7812358f46421f4d (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.cxx22
-rw-r--r--xmloff/source/chart/SchXMLChartContext.cxx39
-rw-r--r--xmloff/source/chart/SchXMLChartContext.hxx6
-rw-r--r--xmloff/source/chart/SchXMLExport.cxx77
-rw-r--r--xmloff/source/chart/SchXMLParagraphContext.cxx131
-rw-r--r--xmloff/source/chart/SchXMLParagraphContext.hxx44
-rw-r--r--xmloff/source/chart/SchXMLTools.cxx92
-rw-r--r--xmloff/source/chart/SchXMLTools.hxx4
-rw-r--r--xmloff/source/chart/transporttypes.hxx2
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 ) {}