summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBalazs Varga <balazs.varga.extern@allotropia.de>2024-03-29 23:00:50 +0100
committerThorsten Behrens <thorsten.behrens@allotropia.de>2024-04-30 15:10:43 +0200
commitab1f35836946d5bfde293d164db438d8091cc438 (patch)
treea081373b822b65aef9f00bd78a673b3a615bcefd
parenttdf#39052 - Chart: make characters formatable in editable chart textshapes (diff)
downloadcore-ab1f35836946d5bfde293d164db438d8091cc438.tar.gz
core-ab1f35836946d5bfde293d164db438d8091cc438.zip
Related: tdf#39052 - chart ooxml: export formatted chart titles
texts properly to ooxml. Also adding "FormattedStrings" property for title objects to simplify the working of character formattings in editable chart shapes. TODO: odf import/export Change-Id: Ie27b4dee72c24fa6a2a4e2a7db8da7fa50eb8937 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165583 Tested-by: Jenkins Tested-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de> Reviewed-by: Balazs Varga <balazs.varga.extern@allotropia.de>
-rw-r--r--chart2/qa/extras/chart2export3.cxx70
-rw-r--r--chart2/qa/extras/data/xlsx/tdf39052.xlsxbin0 -> 9210 bytes
-rw-r--r--chart2/source/controller/chartapiwrapper/TitleWrapper.cxx65
-rw-r--r--chart2/source/controller/main/ChartController_TextEdit.cxx30
-rw-r--r--chart2/source/inc/TitleHelper.hxx2
-rw-r--r--chart2/source/tools/TitleHelper.cxx31
-rw-r--r--include/oox/export/chartexport.hxx4
-rw-r--r--oox/source/export/chartexport.cxx81
-rw-r--r--oox/source/export/drawingml.cxx3
-rw-r--r--xmloff/source/chart/SchXMLAxisContext.cxx1
-rw-r--r--xmloff/source/chart/SchXMLChartContext.cxx2
-rw-r--r--xmloff/source/chart/SchXMLExport.cxx3
12 files changed, 230 insertions, 62 deletions
diff --git a/chart2/qa/extras/chart2export3.cxx b/chart2/qa/extras/chart2export3.cxx
index 838da77191b7..13f41f56198f 100644
--- a/chart2/qa/extras/chart2export3.cxx
+++ b/chart2/qa/extras/chart2export3.cxx
@@ -455,12 +455,13 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest3, testChartMainWithSubTitle)
xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart1.xml");
CPPUNIT_ASSERT(pXmlDoc);
// test properties of title
- 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:pPr/a:defRPr"_ostr, "i"_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, "f10d0c");
- assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:rPr/a:latin"_ostr, "typeface"_ostr, "Arial");
- assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:t"_ostr, "It is a Maintitle\nIt is a Subtitle");
+ 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");
+ 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");
+ 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");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:spPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "81d41a");
}
@@ -762,6 +763,63 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest3, testTdf148142)
CPPUNIT_ASSERT(!aScaleData2.ShiftedCategoryPosition);
}
+CPPUNIT_TEST_FIXTURE(Chart2ExportTest3, testFormattedChartTitles)
+{
+ loadFromFile(u"xlsx/tdf39052.xlsx");
+ save("Calc Office Open XML");
+ xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart1.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ // Check run level properties [1] - first paragraph
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[1]/a:rPr"_ostr, "b"_ostr, "1");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[1]/a:rPr"_ostr, "sz"_ostr, "1400");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[1]/a:rPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "ff0000");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[1]/a:rPr/a:latin"_ostr, "typeface"_ostr, "Aptos Narrow");
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[1]/a:t"_ostr, "This");
+ // Check run level properties [2]
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[2]/a:rPr"_ostr, "b"_ostr, "0");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[2]/a:rPr"_ostr, "sz"_ostr, "1400");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[2]/a:rPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "595959");
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[2]/a:t"_ostr, " is");
+ // Check run level properties [3]
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[3]/a:rPr"_ostr, "b"_ostr, "0");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[3]/a:rPr"_ostr, "sz"_ostr, "1400");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[3]/a:rPr"_ostr, "baseline"_ostr, "30000");
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[3]/a:t"_ostr, "3");
+ // Check run level properties [4]
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[4]/a:rPr"_ostr, "b"_ostr, "0");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[4]/a:rPr"_ostr, "sz"_ostr, "1400");
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[4]/a:t"_ostr, " a ");
+ // Check run level properties [5]
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[5]/a:rPr"_ostr, "b"_ostr, "0");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[5]/a:rPr"_ostr, "i"_ostr, "1");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[5]/a:rPr"_ostr, "sz"_ostr, "2000");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[5]/a:rPr"_ostr, "u"_ostr, "sng");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[5]/a:rPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "4ea72e");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[5]/a:rPr/a:uFillTx"_ostr, 1);
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[5]/a:t"_ostr, "custom");
+ // Check run level properties [6]
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[6]/a:rPr"_ostr, "b"_ostr, "0");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[6]/a:rPr"_ostr, "sz"_ostr, "1400");
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[1]/a:r[6]/a:t"_ostr, " erte1");
+ // Check run level properties [1] - second paragraph
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[1]/a:rPr"_ostr, "b"_ostr, "0");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[1]/a:rPr"_ostr, "sz"_ostr, "1400");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[1]/a:rPr/a:solidFill/a:srgbClr"_ostr, "val"_ostr, "595959");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[1]/a:rPr/a:latin"_ostr, "typeface"_ostr, "Aptos Narrow");
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[1]/a:t"_ostr, "2dfgd ch");
+ // Check run level properties [2]
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[2]/a:rPr"_ostr, "b"_ostr, "1");
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[2]/a:t"_ostr, "ar");
+ // Check run level properties [3]
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[3]/a:rPr"_ostr, "b"_ostr, "0");;
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[3]/a:t"_ostr, "t ");
+ // Check run level properties [4]
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[4]/a:rPr"_ostr, "b"_ostr, "0");
+ assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[4]/a:rPr"_ostr, "strike"_ostr, "sngStrike");
+ assertXPathContent(pXmlDoc, "/c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p[2]/a:r[4]/a:t"_ostr, "title");
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/qa/extras/data/xlsx/tdf39052.xlsx b/chart2/qa/extras/data/xlsx/tdf39052.xlsx
new file mode 100644
index 000000000000..5b0285bab292
--- /dev/null
+++ b/chart2/qa/extras/data/xlsx/tdf39052.xlsx
Binary files differ
diff --git a/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx b/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx
index 9c802462ff09..b0367cb0f478 100644
--- a/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx
+++ b/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx
@@ -106,6 +106,63 @@ Any WrappedTitleStringProperty::getPropertyDefault( const Reference< beans::XPro
namespace {
+ class WrappedTitleFormStringsProperty : public WrappedProperty
+ {
+ public:
+ explicit WrappedTitleFormStringsProperty();
+
+ virtual void setPropertyValue( const Any& rOuterValue, const Reference< beans::XPropertySet >& xInnerPropertySet ) const override;
+ virtual Any getPropertyValue( const Reference< beans::XPropertySet >& xInnerPropertySet ) const override;
+ virtual Any getPropertyDefault( const Reference< beans::XPropertyState >& xInnerPropertyState ) const override;
+
+ protected:
+ Reference< uno::XComponentContext > m_xContext;
+ };
+
+}
+
+WrappedTitleFormStringsProperty::WrappedTitleFormStringsProperty()
+ : ::chart::WrappedProperty( "FormattedStrings", OUString() )
+{
+}
+
+void WrappedTitleFormStringsProperty::setPropertyValue( const Any& rOuterValue, const Reference< beans::XPropertySet >& xInnerPropertySet ) const
+{
+ Title* pTitle = dynamic_cast<Title*>(xInnerPropertySet.get());
+ if (pTitle)
+ {
+ Sequence< Reference< chart2::XFormattedString >> xFormattedStrings;
+ rOuterValue >>= xFormattedStrings;
+ TitleHelper::setFormattedString(pTitle, xFormattedStrings);
+ }
+}
+Any WrappedTitleFormStringsProperty::getPropertyValue( const Reference< beans::XPropertySet >& xInnerPropertySet ) const
+{
+ Any aRet(getPropertyDefault(Reference< beans::XPropertyState >(xInnerPropertySet, uno::UNO_QUERY)));
+ Reference< chart2::XTitle > xTitle(xInnerPropertySet, uno::UNO_QUERY);
+ 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;
+ }
+ }
+ return aRet;
+}
+Any WrappedTitleFormStringsProperty::getPropertyDefault( const Reference< beans::XPropertyState >& /*xInnerPropertyState*/ ) const
+{
+ return uno::Any(Sequence< Reference< chart2::XFormattedString > >()); //default title is an empty Sequence of XFormattedStrings
+}
+
+namespace {
+
class WrappedStackedTextProperty : public WrappedProperty
{
public:
@@ -127,6 +184,7 @@ namespace
enum
{
PROP_TITLE_STRING,
+ PROP_TITLE_FORMATTED_STRINGS,
PROP_TITLE_VISIBLE,
PROP_TITLE_TEXT_ROTATION,
PROP_TITLE_TEXT_STACKED
@@ -141,6 +199,12 @@ void lcl_AddPropertiesToVector(
beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::MAYBEVOID );
+ rOutProperties.emplace_back( "FormattedStrings",
+ PROP_TITLE_FORMATTED_STRINGS,
+ cppu::UnoType< Sequence< Reference< chart2::XFormattedString >>>::get(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID );
+
rOutProperties.emplace_back( "Visible",
PROP_TITLE_VISIBLE,
cppu::UnoType<OUString>::get(),
@@ -475,6 +539,7 @@ std::vector< std::unique_ptr<WrappedProperty> > TitleWrapper::createWrappedPrope
std::vector< std::unique_ptr<WrappedProperty> > aWrappedProperties;
aWrappedProperties.emplace_back( new WrappedTitleStringProperty( m_spChart2ModelContact->m_xContext ) );
+ aWrappedProperties.emplace_back( new WrappedTitleFormStringsProperty() );
aWrappedProperties.emplace_back( new WrappedTextRotationProperty( true ) );
aWrappedProperties.emplace_back( new WrappedStackedTextProperty() );
WrappedCharacterHeightProperty::addWrappedProperties( aWrappedProperties, this );
diff --git a/chart2/source/controller/main/ChartController_TextEdit.cxx b/chart2/source/controller/main/ChartController_TextEdit.cxx
index f6f85108108f..22d358a62fff 100644
--- a/chart2/source/controller/main/ChartController_TextEdit.cxx
+++ b/chart2/source/controller/main/ChartController_TextEdit.cxx
@@ -125,17 +125,10 @@ bool ChartController::EndTextEdit()
if(!pTextObject)
return false;
- SdrOutliner* pOutliner = m_pDrawViewWrapper->getOutliner();
OutlinerParaObject* pParaObj = pTextObject->GetOutlinerParaObject();
- if( !pParaObj || !pOutliner )
+ if( !pParaObj )
return true;
- pOutliner->SetText( *pParaObj );
-
- OUString aString = pOutliner->GetText(
- pOutliner->GetParagraph( 0 ),
- pOutliner->GetParagraphCount() );
-
OUString aObjectCID = m_aSelection.getSelectedCID();
if ( !aObjectCID.isEmpty() )
{
@@ -149,26 +142,7 @@ bool ChartController::EndTextEdit()
GetFormattedTitle(pParaObj->GetTextObject(), pTextObject->getUnoShape());
Title* pTitle = dynamic_cast<Title*>(xPropSet.get());
- if (pTitle && aNewFormattedTitle.hasElements())
- {
- bool bStacked = false;
- if (xPropSet.is())
- xPropSet->getPropertyValue("StackCharacters") >>= bStacked;
-
- if (bStacked)
- {
- for (uno::Reference< chart2::XFormattedString >const& formattedStr : aNewFormattedTitle)
- {
- formattedStr->setString(TitleHelper::getUnstackedStr(formattedStr->getString()));
- }
- }
-
- pTitle->setText(aNewFormattedTitle);
- }
- else
- {
- TitleHelper::setCompleteString(aString, pTitle, m_xCC);
- }
+ TitleHelper::setFormattedString(pTitle, aNewFormattedTitle);
OSL_ENSURE(m_pTextActionUndoGuard, "ChartController::EndTextEdit: no TextUndoGuard!");
if (m_pTextActionUndoGuard)
diff --git a/chart2/source/inc/TitleHelper.hxx b/chart2/source/inc/TitleHelper.hxx
index a0940d7b4166..ba14ac36fdfb 100644
--- a/chart2/source/inc/TitleHelper.hxx
+++ b/chart2/source/inc/TitleHelper.hxx
@@ -78,6 +78,8 @@ public:
static OUString getCompleteString( const rtl::Reference< ::chart::Title >& xTitle );
static OUString getUnstackedStr( const OUString& rNewText );
+ static void setFormattedString( const rtl::Reference< ::chart::Title >& xTitle,
+ const css::uno::Sequence< css::uno::Reference< css::chart2::XFormattedString > >& aNewFormattedTitle );
static void setCompleteString( const OUString& rNewText
, const rtl::Reference< ::chart::Title >& xTitle
, const css::uno::Reference< css::uno::XComponentContext > & xContext
diff --git a/chart2/source/tools/TitleHelper.cxx b/chart2/source/tools/TitleHelper.cxx
index a3831d332c30..5700d6e00449 100644
--- a/chart2/source/tools/TitleHelper.cxx
+++ b/chart2/source/tools/TitleHelper.cxx
@@ -329,32 +329,47 @@ OUString TitleHelper::getUnstackedStr(const OUString& rNewText)
return aUnstackedStr.makeStringAndClear();
}
+void TitleHelper::setFormattedString( const rtl::Reference< Title >& xTitle,
+ const css::uno::Sequence< css::uno::Reference< css::chart2::XFormattedString > >& aNewFormattedTitle )
+{
+ if (!xTitle.is() || !aNewFormattedTitle.hasElements())
+ return;
+
+ bool bStacked = false;
+ xTitle->getPropertyValue("StackCharacters") >>= bStacked;
+
+ if (bStacked)
+ {
+ for (uno::Reference< chart2::XFormattedString >const& formattedStr : aNewFormattedTitle)
+ {
+ formattedStr->setString(TitleHelper::getUnstackedStr(formattedStr->getString()));
+ }
+ }
+
+ xTitle->setText(aNewFormattedTitle);
+}
+
void TitleHelper::setCompleteString( const OUString& rNewText
, const rtl::Reference< Title >& xTitle
, const uno::Reference< uno::XComponentContext > & xContext
, const float * pDefaultCharHeight /* = 0 */
, bool bDialogTitle /*= false*/ )
{
- if(!xTitle.is())
+ if (!xTitle.is())
return;
- OUString aNewText = rNewText;
-
bool bStacked = false;
if( xTitle.is() )
xTitle->getPropertyValue( "StackCharacters" ) >>= bStacked;
- uno::Sequence< uno::Reference< XFormattedString > > aOldStringList = xTitle->getText();
+ OUString aNewText = rNewText;
if( bStacked )
{
aNewText = getUnstackedStr(rNewText);
- for (uno::Reference< XFormattedString >const & formattedStr : aOldStringList)
- {
- formattedStr->setString(getUnstackedStr(formattedStr->getString()));
- }
}
uno::Sequence< uno::Reference< XFormattedString > > aNewStringList;
+ uno::Sequence< uno::Reference< XFormattedString > > aOldStringList = xTitle->getText();
if( aOldStringList.hasElements())
{
const OUString aFullString = getCompleteString(xTitle);
diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx
index 6a40254f6491..4108aec96806 100644
--- a/include/oox/export/chartexport.hxx
+++ b/include/oox/export/chartexport.hxx
@@ -25,6 +25,7 @@
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/chart2/FormattedString.hpp>
#include <oox/dllapi.h>
#include <oox/export/drawingml.hxx>
#include <oox/export/shapes.hxx>
@@ -176,7 +177,8 @@ private:
void exportLegend( const css::uno::Reference<
css::chart::XChartDocument >& rChartDoc );
void exportTitle( const css::uno::Reference< css::drawing::XShape >& xShape,
- const OUString* pSubText = nullptr );
+ const css::uno::Sequence< css::uno::Reference< css::chart2::XFormattedString > >& xFormattedSubTitle =
+ css::uno::Sequence< css::uno::Reference< css::chart2::XFormattedString > >() );
void exportPlotArea( const css::uno::Reference<
css::chart::XChartDocument >& rChartDoc );
void exportAdditionalShapes( const css::uno::Reference<css::chart::XChartDocument >& rChartDoc );
diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx
index c80e8c1ba688..00161cde7e4a 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -1133,7 +1133,6 @@ void ChartExport::exportChart( const Reference< css::chart::XChartDocument >& xC
// get Properties of ChartDocument
bool bHasMainTitle = false;
- OUString aSubTitle;
bool bHasLegend = false;
Reference< beans::XPropertySet > xDocPropSet( xChartDoc, uno::UNO_QUERY );
if( xDocPropSet.is())
@@ -1151,12 +1150,13 @@ void ChartExport::exportChart( const Reference< css::chart::XChartDocument >& xC
}
} // if( xDocPropSet.is())
+ Sequence< uno::Reference< chart2::XFormattedString > > xFormattedSubTitle;
Reference< beans::XPropertySet > xPropSubTitle( xChartDoc->getSubTitle(), UNO_QUERY );
if( xPropSubTitle.is())
{
try
{
- xPropSubTitle->getPropertyValue("String") >>= aSubTitle;
+ xPropSubTitle->getPropertyValue("FormattedStrings") >>= xFormattedSubTitle;
}
catch( beans::UnknownPropertyException & )
{
@@ -1170,12 +1170,12 @@ void ChartExport::exportChart( const Reference< css::chart::XChartDocument >& xC
// titles
if( bHasMainTitle )
{
- exportTitle( xChartDoc->getTitle(), !aSubTitle.isEmpty() ? &aSubTitle : nullptr );
+ exportTitle( xChartDoc->getTitle(), xFormattedSubTitle);
pFS->singleElement(FSNS(XML_c, XML_autoTitleDeleted), XML_val, "0");
}
- else if( !aSubTitle.isEmpty() )
+ else if( xFormattedSubTitle.hasElements() )
{
- exportTitle( xChartDoc->getSubTitle(), nullptr );
+ exportTitle( xChartDoc->getSubTitle() );
pFS->singleElement(FSNS(XML_c, XML_autoTitleDeleted), XML_val, "0");
}
else
@@ -1444,20 +1444,40 @@ void ChartExport::exportLegend( const Reference< css::chart::XChartDocument >& x
pFS->endElement( FSNS( XML_c, XML_legend ) );
}
-void ChartExport::exportTitle( const Reference< XShape >& xShape, const OUString* pSubText)
+void ChartExport::exportTitle( const Reference< XShape >& xShape,
+ const css::uno::Sequence< uno::Reference< css::chart2::XFormattedString > >& xFormattedSubTitle )
{
- OUString sText;
+ Sequence< uno::Reference< chart2::XFormattedString > > xFormattedTitle;
Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
if( xPropSet.is())
{
- xPropSet->getPropertyValue("String") >>= sText;
+ xPropSet->getPropertyValue("FormattedStrings") >>= xFormattedTitle;
}
// tdf#101322: add subtitle to title
- if( pSubText )
- sText = sText.isEmpty() ? *pSubText : sText + "\n" + *pSubText;
+ if (xFormattedSubTitle.hasElements())
+ {
+ if (!xFormattedTitle.hasElements())
+ {
+ xFormattedTitle = xFormattedSubTitle;
+ }
+ else
+ {
+ sal_uInt32 nLength = xFormattedTitle.size();
+ const OUString aLastString = xFormattedTitle.getArray()[nLength - 1]->getString();
+ xFormattedTitle.getArray()[nLength - 1]->setString(aLastString + OUStringChar('\n'));
+ for (const uno::Reference<chart2::XFormattedString>& rxFS : xFormattedSubTitle)
+ {
+ if (!rxFS->getString().isEmpty())
+ {
+ xFormattedTitle.realloc(nLength + 1);
+ xFormattedTitle.getArray()[nLength++] = rxFS;
+ }
+ }
+ }
+ }
- if( sText.isEmpty() )
+ if (!xFormattedTitle.hasElements())
return;
FSHelperPtr pFS = GetFS();
@@ -1481,7 +1501,6 @@ void ChartExport::exportTitle( const Reference< XShape >& xShape, const OUString
XML_rot, oox::drawingml::calcRotationValue(nRotation) );
// TODO: lstStyle
pFS->singleElement(FSNS(XML_a, XML_lstStyle));
- // FIXME: handle multiple paragraphs to parse aText
pFS->startElement(FSNS(XML_a, XML_p));
pFS->startElement(FSNS(XML_a, XML_pPr));
@@ -1492,13 +1511,37 @@ void ChartExport::exportTitle( const Reference< XShape >& xShape, const OUString
pFS->endElement( FSNS( XML_a, XML_pPr ) );
- pFS->startElement(FSNS(XML_a, XML_r));
- bDummy = false;
- WriteRunProperties( xPropSet, false, XML_rPr, true, bDummy, nDummy );
- pFS->startElement(FSNS(XML_a, XML_t));
- pFS->writeEscaped( sText );
- pFS->endElement( FSNS( XML_a, XML_t ) );
- pFS->endElement( FSNS( XML_a, XML_r ) );
+ for (const uno::Reference<chart2::XFormattedString>& rxFS : xFormattedTitle)
+ {
+ pFS->startElement(FSNS(XML_a, XML_r));
+ bDummy = false;
+ Reference< beans::XPropertySet > xRunPropSet(rxFS, uno::UNO_QUERY);
+ WriteRunProperties(xRunPropSet, false, XML_rPr, true, bDummy, nDummy);
+ pFS->startElement(FSNS(XML_a, XML_t));
+
+ // the linebreak should always be at the end of the XFormattedString text
+ bool bNextPara = rxFS->getString().endsWith(u"\n");
+ if (!bNextPara)
+ pFS->writeEscaped(rxFS->getString());
+ else
+ {
+ sal_Int32 nEnd = rxFS->getString().lastIndexOf('\n');
+ pFS->writeEscaped(rxFS->getString().replaceAt(nEnd, 1, u""));
+ }
+ pFS->endElement(FSNS(XML_a, XML_t));
+ pFS->endElement(FSNS(XML_a, XML_r));
+
+ if (bNextPara)
+ {
+ pFS->endElement(FSNS(XML_a, XML_p));
+
+ pFS->startElement(FSNS(XML_a, XML_p));
+ pFS->startElement(FSNS(XML_a, XML_pPr));
+ bDummy = false;
+ WriteRunProperties(xPropSet, false, XML_defRPr, true, bDummy, nDummy);
+ pFS->endElement(FSNS(XML_a, XML_pPr));
+ }
+ }
pFS->endElement( FSNS( XML_a, XML_p ) );
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index a3e5356c0523..9a8e338d2957 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2491,6 +2491,9 @@ void DrawingML::WriteRunProperties( const Reference< XPropertySet >& rRun, bool
{
switch ( *o3tl::doAccess<sal_Int16>(mAny) )
{
+ case awt::FontUnderline::NONE :
+ underline = "none";
+ break;
case awt::FontUnderline::SINGLE :
underline = "sng";
break;
diff --git a/xmloff/source/chart/SchXMLAxisContext.cxx b/xmloff/source/chart/SchXMLAxisContext.cxx
index ae55da90f8b5..fd106f72fa69 100644
--- a/xmloff/source/chart/SchXMLAxisContext.cxx
+++ b/xmloff/source/chart/SchXMLAxisContext.cxx
@@ -565,6 +565,7 @@ void SchXMLAxisContext::SetAxisTitle()
{
try
{
+ // TODO: ODF import for formatted chart titles
xTitleProp->setPropertyValue("String", uno::Any(m_aCurrentAxis.aTitle) );
}
catch( beans::UnknownPropertyException & )
diff --git a/xmloff/source/chart/SchXMLChartContext.cxx b/xmloff/source/chart/SchXMLChartContext.cxx
index 7a8ac46c40a9..6d1350add627 100644
--- a/xmloff/source/chart/SchXMLChartContext.cxx
+++ b/xmloff/source/chart/SchXMLChartContext.cxx
@@ -727,6 +727,7 @@ void SchXMLChartContext::endFastElement(sal_Int32 )
{
try
{
+ // TODO: ODF import for formatted chart titles
xTitleProp->setPropertyValue("String", uno::Any(maMainTitle) );
}
catch(const beans::UnknownPropertyException&)
@@ -742,6 +743,7 @@ void SchXMLChartContext::endFastElement(sal_Int32 )
{
try
{
+ // TODO: ODF import for formatted chart titles
xTitleProp->setPropertyValue("String", uno::Any(maSubTitle) );
}
catch(const beans::UnknownPropertyException&)
diff --git a/xmloff/source/chart/SchXMLExport.cxx b/xmloff/source/chart/SchXMLExport.cxx
index 4566941f4fca..804891006faa 100644
--- a/xmloff/source/chart/SchXMLExport.cxx
+++ b/xmloff/source/chart/SchXMLExport.cxx
@@ -1336,6 +1336,7 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument >
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;
@@ -1377,6 +1378,7 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument >
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;
@@ -2256,6 +2258,7 @@ 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;