summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBalazs Varga <balazs.varga.extern@allotropia.de>2024-04-15 13:39:03 +0200
committerThorsten Behrens <thorsten.behrens@allotropia.de>2024-05-09 21:41:41 +0200
commitbb16f920b5e16ca7d2601190a7e2b534a2dfa1a5 (patch)
tree0c75844008791b8b94ce4e560fddc869c026960d
parent8af78dc0de96daab6a23a21e152d5c91b93ee74c (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>
-rw-r--r--chart2/qa/extras/chart2export3.cxx138
-rw-r--r--chart2/qa/extras/data/ods/tdf39052.odsbin0 -> 15941 bytes
-rw-r--r--chart2/source/controller/chartapiwrapper/TitleWrapper.cxx46
-rw-r--r--chart2/source/model/main/Title.cxx3
-rw-r--r--oox/source/export/chartexport.cxx12
-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
14 files changed, 491 insertions, 125 deletions
diff --git a/chart2/qa/extras/chart2export3.cxx b/chart2/qa/extras/chart2export3.cxx
index 13f41f56198f..fcc9a80954cc 100644
--- a/chart2/qa/extras/chart2export3.cxx
+++ b/chart2/qa/extras/chart2export3.cxx
@@ -18,6 +18,9 @@
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
using uno::Reference;
using beans::XPropertySet;
@@ -440,11 +443,17 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest3, testChartSubTitle)
xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart1.xml");
CPPUNIT_ASSERT(pXmlDoc);
// test properties of subtitle
+ // paragraph props
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:pPr/a:defRPr"_ostr, "sz"_ostr, "1100");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:pPr/a:defRPr"_ostr, "b"_ostr, "1");
- assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:pPr/a:defRPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "00a933");
+ // run props
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:rPr"_ostr, "sz"_ostr, "1100");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:rPr"_ostr, "b"_ostr, "1");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:rPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "00a933");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:rPr/a:latin"_ostr, "typeface"_ostr, "Times New Roman");
+ // text
assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:t"_ostr, "It is a Subtitle");
+ // shape props
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:spPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "b2b2b2");
}
@@ -455,13 +464,19 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest3, testChartMainWithSubTitle)
xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart1.xml");
CPPUNIT_ASSERT(pXmlDoc);
// test properties of title
+ // paragraph props
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:pPr/a:defRPr"_ostr, "sz"_ostr, "1300");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:pPr/a:defRPr"_ostr, "b"_ostr, "0");
- assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:pPr/a:defRPr"_ostr, "i"_ostr, "1");
- assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:pPr/a:defRPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "f10d0c");
+ // run props
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r/a:rPr"_ostr, "sz"_ostr, "1300");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r/a:rPr"_ostr, "b"_ostr, "0");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r/a:rPr"_ostr, "i"_ostr, "1");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r/a:rPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "f10d0c");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r/a:rPr/a:latin"_ostr, "typeface"_ostr, "Arial");
+ // text
assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r/a:t"_ostr, "It is a Maintitle");
assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r/a:t"_ostr, "It is a Subtitle");
+ // shape props
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:spPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "81d41a");
}
@@ -608,8 +623,8 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest3, testTitleCharacterPropertiesXLSX)
xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart1.xml");
CPPUNIT_ASSERT(pXmlDoc);
- assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:pPr/a:defRPr"_ostr, "sz"_ostr, "2400");
- assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:pPr/a:defRPr"_ostr, "b"_ostr, "1");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:pPr/a:defRPr"_ostr, "sz"_ostr, "1300");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:pPr/a:defRPr"_ostr, "b"_ostr, "0");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:rPr"_ostr, "sz"_ostr, "2400");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:rPr"_ostr, "b"_ostr, "1");
@@ -820,6 +835,119 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest3, testFormattedChartTitles)
assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[4]/a:t"_ostr, "title");
}
+namespace {
+
+void checkCharacterProps(Reference<beans::XPropertySet> const & xTitleProp)
+{
+ Sequence< uno::Reference< chart2::XFormattedString > > xFormattedSubTitle;
+ CPPUNIT_ASSERT(xTitleProp->getPropertyValue("FormattedStrings") >>= xFormattedSubTitle);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(10), xFormattedSubTitle.getLength());
+ // check texts
+ std::vector<OUString> aValues = { "This", " is", "3", " a ", "custom", " erte1\n", "2dfgd ch", "ar", "t ", "title" };
+ for (sal_Int32 i = 0; i < xFormattedSubTitle.getLength(); i++)
+ {
+ const OUString aText = xFormattedSubTitle.getConstArray()[i]->getString();
+ CPPUNIT_ASSERT_EQUAL(aValues[i], aText);
+ Reference< beans::XPropertySet > xRunPropSet(xFormattedSubTitle.getConstArray()[i], uno::UNO_QUERY);
+ // common props
+ uno::Any aAny = xRunPropSet->getPropertyValue("CharFontName");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("Aptos Narrow")), aAny);
+ // unique props
+ if (aText == aValues[0])
+ {
+ aAny = xRunPropSet->getPropertyValue("CharWeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontWeight::BOLD), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharHeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(14.0f), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharColor");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(Color(0xff0000)), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharEscapement");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(short(0)), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharEscapementHeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(short(100)), aAny);
+ }
+ else if (aText == aValues[1] || aText == aValues[3] || aText == aValues[5] ||
+ aText == aValues[6] || aText == aValues[8])
+ {
+ aAny = xRunPropSet->getPropertyValue("CharWeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontWeight::NORMAL), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharHeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(14.0f), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharColor");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(Color(0x595959)), aAny);
+ }
+ else if (aText == aValues[2])
+ {
+ aAny = xRunPropSet->getPropertyValue("CharWeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontWeight::NORMAL), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharHeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(14.0f), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharColor");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(Color(0x595959)), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharEscapement");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(short(30)), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharEscapementHeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(short(58)), aAny);
+ }
+ else if (aText == aValues[4])
+ {
+ aAny = xRunPropSet->getPropertyValue("CharWeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontWeight::NORMAL), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharHeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(20.0f), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharColor");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(Color(0x4ea72e)), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharPosture");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontSlant_ITALIC), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharUnderline");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontUnderline::SINGLE), aAny);
+ }
+ else if (aText == aValues[7])
+ {
+ aAny = xRunPropSet->getPropertyValue("CharWeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontWeight::BOLD), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharHeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(14.0f), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharColor");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(Color(0x595959)), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharPosture");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontSlant_NONE), aAny);
+ }
+ else // aText == aValues[9]
+ {
+ aAny = xRunPropSet->getPropertyValue("CharWeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontWeight::NORMAL), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharHeight");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(14.0f), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharColor");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(Color(0x595959)), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharPosture");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontSlant_ITALIC), aAny);
+ aAny = xRunPropSet->getPropertyValue("CharOverline");
+ CPPUNIT_ASSERT_EQUAL(uno::Any(awt::FontUnderline::NONE), aAny);
+ }
+ }
+}
+
+}
+
+CPPUNIT_TEST_FIXTURE(Chart2ExportTest3, testODSFormattedChartTitles)
+{
+ // The document contains a line chart with "Between tick marks" X axis position.
+ loadFromFile(u"ods/tdf39052.ods");
+ // Check formatted strings after export.
+ saveAndReload("calc8");
+
+ Reference<chart2::XChartDocument> xChart2Doc = getChartDocFromSheet(0, mxComponent);
+ CPPUNIT_ASSERT(xChart2Doc.is());
+ Reference< chart::XChartDocument > xChartDoc(xChart2Doc, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xChartDoc.is());
+ uno::Reference< beans::XPropertySet > xTitleProp(xChartDoc->getTitle(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xTitleProp.is());
+
+ checkCharacterProps(xTitleProp);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/qa/extras/data/ods/tdf39052.ods b/chart2/qa/extras/data/ods/tdf39052.ods
new file mode 100644
index 000000000000..68089195507e
--- /dev/null
+++ b/chart2/qa/extras/data/ods/tdf39052.ods
Binary files differ
diff --git a/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx b/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx
index b0367cb0f478..fb94a5d74c8a 100644
--- a/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx
+++ b/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx
@@ -143,16 +143,7 @@ Any WrappedTitleFormStringsProperty::getPropertyValue( const Reference< beans::X
if (xTitle.is())
{
const Sequence< Reference< chart2::XFormattedString > > aStrings(xTitle->getText());
-
- OUStringBuffer aBuf;
- for (Reference< chart2::XFormattedString > const& formattedStr : aStrings)
- {
- aBuf.append(formattedStr->getString());
- }
- if (!aBuf.makeStringAndClear().isEmpty())
- {
- aRet <<= aStrings;
- }
+ aRet <<= aStrings;
}
return aRet;
}
@@ -325,27 +316,12 @@ void SAL_CALL TitleWrapper::removeEventListener(
m_aEventListenerContainer.removeInterface( g, aListener );
}
-Reference< beans::XPropertySet > TitleWrapper::getFirstCharacterPropertySet()
-{
- Reference< beans::XPropertySet > xProp;
-
- Reference< chart2::XTitle > xTitle( getTitleObject() );
- if( xTitle.is())
- {
- Sequence< Reference< chart2::XFormattedString > > aStrings( xTitle->getText());
- if( aStrings.hasElements() )
- xProp.set( aStrings[0], uno::UNO_QUERY );
- }
-
- return xProp;
-}
-
void TitleWrapper::getFastCharacterPropertyValue( sal_Int32 nHandle, Any& rValue )
{
OSL_ASSERT( FAST_PROPERTY_ID_START_CHAR_PROP <= nHandle &&
nHandle < CharacterProperties::FAST_PROPERTY_ID_END_CHAR_PROP );
- Reference< beans::XPropertySet > xProp = getFirstCharacterPropertySet();
+ Reference< beans::XPropertySet > xProp = getInnerPropertySet();
Reference< beans::XFastPropertySet > xFastProp( xProp, uno::UNO_QUERY );
if(xProp.is())
{
@@ -385,6 +361,16 @@ void TitleWrapper::setFastCharacterPropertyValue(
else if( xFastPropertySet.is() )
xFastPropertySet->setFastPropertyValue( nHandle, rValue );
}
+
+ Reference< beans::XPropertySet > xInnerProp = getInnerPropertySet();
+ Reference< beans::XFastPropertySet > xFastInnerProp( xInnerProp, uno::UNO_QUERY );
+ if (xInnerProp.is())
+ {
+ if (pWrappedProperty)
+ pWrappedProperty->setPropertyValue(rValue, xInnerProp);
+ else if (xFastInnerProp.is())
+ xFastInnerProp->setFastPropertyValue(nHandle, rValue);
+ }
}
// WrappedPropertySet
@@ -418,7 +404,7 @@ beans::PropertyState SAL_CALL TitleWrapper::getPropertyState( const OUString& rP
sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName );
if( CharacterProperties::IsCharacterPropertyHandle( nHandle ) )
{
- Reference< beans::XPropertyState > xPropState( getFirstCharacterPropertySet(), uno::UNO_QUERY );
+ Reference< beans::XPropertyState > xPropState( getInnerPropertySet(), uno::UNO_QUERY);
if( xPropState.is() )
{
const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName );
@@ -451,7 +437,7 @@ Any SAL_CALL TitleWrapper::getPropertyDefault( const OUString& rPropertyName )
sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName );
if( CharacterProperties::IsCharacterPropertyHandle( nHandle ) )
{
- Reference< beans::XPropertyState > xPropState( getFirstCharacterPropertySet(), uno::UNO_QUERY );
+ Reference< beans::XPropertyState > xPropState( getInnerPropertySet(), uno::UNO_QUERY );
if( xPropState.is() )
{
const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName );
@@ -472,7 +458,7 @@ void SAL_CALL TitleWrapper::addPropertyChangeListener( const OUString& rProperty
sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName );
if( CharacterProperties::IsCharacterPropertyHandle( nHandle ) )
{
- Reference< beans::XPropertySet > xPropSet = getFirstCharacterPropertySet();
+ Reference< beans::XPropertySet > xPropSet = getInnerPropertySet();
if( xPropSet.is() )
xPropSet->addPropertyChangeListener( rPropertyName, xListener );
}
@@ -484,7 +470,7 @@ void SAL_CALL TitleWrapper::removePropertyChangeListener( const OUString& rPrope
sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName );
if( CharacterProperties::IsCharacterPropertyHandle( nHandle ) )
{
- Reference< beans::XPropertySet > xPropSet = getFirstCharacterPropertySet();
+ Reference< beans::XPropertySet > xPropSet = getInnerPropertySet();
if( xPropSet.is() )
xPropSet->removePropertyChangeListener( rPropertyName, xListener );
}
diff --git a/chart2/source/model/main/Title.cxx b/chart2/source/model/main/Title.cxx
index 6833684e9bf2..10551ce6e318 100644
--- a/chart2/source/model/main/Title.cxx
+++ b/chart2/source/model/main/Title.cxx
@@ -18,6 +18,7 @@
*/
#include <Title.hxx>
+#include <CharacterProperties.hxx>
#include <LinePropertiesHelper.hxx>
#include <FillProperties.hxx>
#include <CloneHelper.hxx>
@@ -145,6 +146,7 @@ const ::chart::tPropertyValueMap& StaticTitleDefaults()
{
::chart::tPropertyValueMap aTmp;
+ ::chart::CharacterProperties::AddDefaultsToMap( aTmp );
::chart::LinePropertiesHelper::AddDefaultsToMap( aTmp );
::chart::FillProperties::AddDefaultsToMap( aTmp );
@@ -178,6 +180,7 @@ const ::chart::tPropertyValueMap& StaticTitleDefaults()
{
std::vector< css::beans::Property > aProperties;
lcl_AddPropertiesToVector( aProperties );
+ ::chart::CharacterProperties::AddPropertiesToVector( aProperties );
::chart::LinePropertiesHelper::AddPropertiesToVector( aProperties );
::chart::FillProperties::AddPropertiesToVector( aProperties );
diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx
index 00161cde7e4a..6fb1ae804ee7 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -1154,13 +1154,9 @@ void ChartExport::exportChart( const Reference< css::chart::XChartDocument >& xC
Reference< beans::XPropertySet > xPropSubTitle( xChartDoc->getSubTitle(), UNO_QUERY );
if( xPropSubTitle.is())
{
- try
- {
+ OUString aSubTitle;
+ if ((xPropSubTitle->getPropertyValue("String") >>= aSubTitle) && !aSubTitle.isEmpty())
xPropSubTitle->getPropertyValue("FormattedStrings") >>= xFormattedSubTitle;
- }
- catch( beans::UnknownPropertyException & )
- {
- }
}
// chart element
@@ -1451,7 +1447,9 @@ void ChartExport::exportTitle( const Reference< XShape >& xShape,
Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
if( xPropSet.is())
{
- xPropSet->getPropertyValue("FormattedStrings") >>= xFormattedTitle;
+ OUString aTitle;
+ if ((xPropSet->getPropertyValue("String") >>= aTitle) && !aTitle.isEmpty())
+ xPropSet->getPropertyValue("FormattedStrings") >>= xFormattedTitle;
}
// tdf#101322: add subtitle to title
diff --git a/xmloff/source/chart/SchXMLAxisContext.cxx b/xmloff/source/chart/SchXMLAxisContext.cxx
index fd106f72fa69..c39d13f69100 100644
--- a/xmloff/source/chart/SchXMLAxisContext.cxx
+++ b/xmloff/source/chart/SchXMLAxisContext.cxx
@@ -553,26 +553,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(
@@ -585,7 +577,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLAxisContext::cre
{
Reference< drawing::XShape > xTitleShape = getTitleShape();
return new SchXMLTitleContext( m_rImportHelper, GetImport(),
- m_aCurrentAxis.aTitle,
+ m_aCurrentAxis.maTitle,
xTitleShape );
}
break;
diff --git a/xmloff/source/chart/SchXMLChartContext.cxx b/xmloff/source/chart/SchXMLChartContext.cxx
index 6d1350add627..ab800c5f5199 100644
--- a/xmloff/source/chart/SchXMLChartContext.cxx
+++ b/xmloff/source/chart/SchXMLChartContext.cxx
@@ -720,37 +720,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);
}
}
@@ -1165,7 +1144,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 ),
@@ -1231,7 +1210,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 40ba13e0177c..6b52b61b6d7c 100644
--- a/xmloff/source/chart/SchXMLChartContext.hxx
+++ b/xmloff/source/chart/SchXMLChartContext.hxx
@@ -89,7 +89,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;
@@ -127,14 +127,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 804891006faa..e3b1c3ebb1ef 100644
--- a/xmloff/source/chart/SchXMLExport.cxx
+++ b/xmloff/source/chart/SchXMLExport.cxx
@@ -207,6 +207,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 );
@@ -275,6 +277,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;
@@ -1314,15 +1317,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 );
@@ -1333,19 +1335,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();
@@ -1355,16 +1350,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 );
@@ -1375,19 +1369,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();
@@ -2258,11 +2245,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 );
@@ -2271,11 +2253,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();
}
@@ -3819,6 +3802,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() )
@@ -3835,6 +3839,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 84e22c5a5c71..32e2a9899789 100644
--- a/xmloff/source/chart/SchXMLParagraphContext.cxx
+++ b/xmloff/source/chart/SchXMLParagraphContext.cxx
@@ -104,4 +104,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 120e361f84f0..ad012dc9cffe 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>
@@ -600,6 +603,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 ) {}