Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE
libreoffice.8650
bnc1060128.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bnc1060128.patch of Package libreoffice.8650
From 85753e0f2759960dd87f6ecf9245e764a9f9bf11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20K=C5=82os?= <szymon.klos@collabora.com> Date: Thu, 4 Jan 2018 22:15:32 +0100 Subject: [PATCH 1/2] tdf#114821 import complex data labels in bar chart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * import static text & fields: VALUE, SERIESNAME, COLUMNNAME * text is formatted * DataPointCustomLabelField with field type (DataPointCustomLabelFieldType) was introduced. * text can have many portions & multiple lines * unit tests for import data labels with formatting Not implemented: CELLREF field support which needs importing some additional data from extLst Shows custom text as a label for data points. Change-Id: Iba8fd508eb16356b05586b93d7b8da32240d2b91 Reviewed-on: https://gerrit.libreoffice.org/48243 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Szymon Kłos <szymon.klos@collabora.com> --- chart2/inc/unonames.hxx | 1 + chart2/qa/extras/chart2import.cxx | 154 +++++++++++++++++++++ chart2/qa/extras/data/pptx/tdf115107-2.pptx | Bin 0 -> 50519 bytes chart2/qa/extras/data/pptx/tdf115107.pptx | Bin 0 -> 50726 bytes chart2/source/chartcore.component | 1 + chart2/source/model/main/DataPointProperties.cxx | 11 +- chart2/source/model/main/DataPointProperties.hxx | 3 +- chart2/source/model/main/FormattedString.cxx | 40 ++++++ chart2/source/model/main/FormattedString.hxx | 16 ++- chart2/source/view/charttypes/VSeriesPlotter.cxx | 126 +++++++++++++++-- chart2/source/view/inc/AbstractShapeFactory.hxx | 7 + chart2/source/view/inc/OpenglShapeFactory.hxx | 7 + chart2/source/view/inc/ShapeFactory.hxx | 7 + chart2/source/view/inc/VSeriesPlotter.hxx | 2 + chart2/source/view/main/OpenglShapeFactory.cxx | 12 ++ chart2/source/view/main/ShapeFactory.cxx | 94 +++++++++++++ offapi/UnoApi_offapi.mk | 3 + .../sun/star/chart2/DataPointCustomLabelField.idl | 26 ++++ .../star/chart2/DataPointCustomLabelFieldType.idl | 33 +++++ offapi/com/sun/star/chart2/DataPointProperties.idl | 8 ++ .../sun/star/chart2/XDataPointCustomLabelField.idl | 43 ++++++ oox/inc/drawingml/textfield.hxx | 2 + oox/source/drawingml/chart/seriesconverter.cxx | 78 +++++++++++ oox/source/token/properties.txt | 1 + 24 files changed, 657 insertions(+), 18 deletions(-) create mode 100644 chart2/qa/extras/data/pptx/tdf115107-2.pptx create mode 100644 chart2/qa/extras/data/pptx/tdf115107.pptx create mode 100644 offapi/com/sun/star/chart2/DataPointCustomLabelField.idl create mode 100644 offapi/com/sun/star/chart2/DataPointCustomLabelFieldType.idl create mode 100644 offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl diff --git a/chart2/inc/unonames.hxx b/chart2/inc/unonames.hxx index 867a155e14aa..44c3bf67d3cb 100644 --- a/chart2/inc/unonames.hxx +++ b/chart2/inc/unonames.hxx @@ -29,6 +29,7 @@ #define CHART_UNONAME_LABEL_BORDER_DASH "LabelBorderDash" #define CHART_UNONAME_LABEL_BORDER_DASHNAME "LabelBorderDashName" #define CHART_UNONAME_LABEL_BORDER_TRANS "LabelBorderTransparency" +#define CHART_UNONAME_CUSTOM_LABEL_FIELDS "CustomLabelFields" #endif diff --git a/chart2/source/chartcore.component b/chart2/source/chartcore.component index f7a1783eda68..45c87f93d633 100644 --- a/chart2/source/chartcore.component +++ b/chart2/source/chartcore.component @@ -158,6 +158,7 @@ constructor="com_sun_star_comp_chart_FormattedString_get_implementation"> <service name="com.sun.star.beans.PropertySet"/> <service name="com.sun.star.chart2.FormattedString"/> + <service name="com.sun.star.chart2.DataPointCustomLabelField"/> </implementation> <implementation name="com.sun.star.comp.chart.LineChartType" constructor="com_sun_star_comp_chart_LineChartType_get_implementation"> diff --git a/chart2/source/model/main/DataPointProperties.cxx b/chart2/source/model/main/DataPointProperties.cxx index 66e0b88d1f5a..dbc950c2195b 100644 --- a/chart2/source/model/main/DataPointProperties.cxx +++ b/chart2/source/model/main/DataPointProperties.cxx @@ -30,7 +30,7 @@ #include <com/sun/star/style/XStyle.hpp> #include <com/sun/star/drawing/BitmapMode.hpp> #include <com/sun/star/drawing/RectanglePoint.hpp> - +#include <com/sun/star/chart2/XDataPointCustomLabelField.hpp> #include <com/sun/star/chart2/DataPointGeometry3D.hpp> #include <com/sun/star/chart2/DataPointLabel.hpp> #include <com/sun/star/chart2/Symbol.hpp> @@ -406,6 +406,12 @@ void DataPointProperties::AddPropertiesToVector( cppu::UnoType<sal_Int16>::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT ); + + rOutProperties.emplace_back( CHART_UNONAME_CUSTOM_LABEL_FIELDS, + PROP_DATAPOINT_CUSTOM_LABEL_FIELDS, + cppu::UnoType<uno::Sequence<uno::Reference<chart2::XDataPointCustomLabelField>>>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT); } void DataPointProperties::AddDefaultsToMap( @@ -486,6 +492,9 @@ void DataPointProperties::AddDefaultsToMap( PropertyHelper::setPropertyValueDefault(rOutMap, PROP_DATAPOINT_LABEL_BORDER_DASH, drawing::LineDash()); PropertyHelper::setEmptyPropertyValueDefault(rOutMap, PROP_DATAPOINT_LABEL_BORDER_DASH_NAME); PropertyHelper::setPropertyValueDefault<sal_Int16>(rOutMap, PROP_DATAPOINT_LABEL_BORDER_TRANS, 0); + + uno::Sequence<uno::Reference<chart2::XDataPointCustomLabelField>> aFields(0); + PropertyHelper::setPropertyValueDefault(rOutMap, PROP_DATAPOINT_CUSTOM_LABEL_FIELDS, aFields); } } // namespace chart diff --git a/chart2/source/model/main/DataPointProperties.hxx b/chart2/source/model/main/DataPointProperties.hxx index 3daf838e5da5..6490b5c8cfe5 100644 --- a/chart2/source/model/main/DataPointProperties.hxx +++ b/chart2/source/model/main/DataPointProperties.hxx @@ -80,7 +80,8 @@ namespace DataPointProperties PROP_DATAPOINT_LABEL_BORDER_WIDTH, PROP_DATAPOINT_LABEL_BORDER_DASH, PROP_DATAPOINT_LABEL_BORDER_DASH_NAME, - PROP_DATAPOINT_LABEL_BORDER_TRANS + PROP_DATAPOINT_LABEL_BORDER_TRANS, + PROP_DATAPOINT_CUSTOM_LABEL_FIELDS // additionally some properites from ::chart::LineProperties }; diff --git a/chart2/source/model/main/FormattedString.cxx b/chart2/source/model/main/FormattedString.cxx index 4f26acc95e3f..2dfcca2d35c5 100644 --- a/chart2/source/model/main/FormattedString.cxx +++ b/chart2/source/model/main/FormattedString.cxx @@ -95,6 +95,8 @@ namespace chart FormattedString::FormattedString() : ::property::OPropertySet( m_aMutex ), m_aString(), + m_aType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT), + m_aGuid(), m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()) {} @@ -103,6 +105,8 @@ FormattedString::FormattedString( const FormattedString & rOther ) : impl::FormattedString_Base(), ::property::OPropertySet( rOther, m_aMutex ), m_aString( rOther.m_aString ), + m_aType(rOther.m_aType), + m_aGuid(rOther.m_aGuid), m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()) {} @@ -133,6 +137,41 @@ void SAL_CALL FormattedString::setString( const OUString& String ) } +// ____ XDataPointCustomLabelField ____ +css::chart2::DataPointCustomLabelFieldType SAL_CALL FormattedString::getFieldType() +{ + MutexGuard aGuard(GetMutex()); + return m_aType; +} + +void SAL_CALL +FormattedString::setFieldType(const css::chart2::DataPointCustomLabelFieldType Type) +{ + { + MutexGuard aGuard(GetMutex()); + m_aType = Type; + } + //don't keep the mutex locked while calling out + fireModifyEvent(); +} + +OUString SAL_CALL FormattedString::getGuid() +{ + MutexGuard aGuard( GetMutex()); + return m_aGuid; +} + +void SAL_CALL FormattedString::setGuid( const OUString& guid ) +{ + { + MutexGuard aGuard( GetMutex()); + m_aGuid= guid; + } + //don't keep the mutex locked while calling out + fireModifyEvent(); + +} + // ____ XModifyBroadcaster ____ void SAL_CALL FormattedString::addModifyListener( const uno::Reference< util::XModifyListener >& aListener ) { @@ -226,6 +265,7 @@ sal_Bool SAL_CALL FormattedString::supportsService( const OUString& rServiceName css::uno::Sequence< OUString > SAL_CALL FormattedString::getSupportedServiceNames() { return { + "com.sun.star.chart2.DataPointCustomLabelField", "com.sun.star.chart2.FormattedString", "com.sun.star.beans.PropertySet" }; } diff --git a/chart2/source/model/main/FormattedString.hxx b/chart2/source/model/main/FormattedString.hxx index 16c73372ebcc..aee7674081be 100644 --- a/chart2/source/model/main/FormattedString.hxx +++ b/chart2/source/model/main/FormattedString.hxx @@ -26,6 +26,8 @@ #include <ModifyListenerHelper.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/chart2/XFormattedString2.hpp> +#include <com/sun/star/chart2/DataPointCustomLabelFieldType.hpp> +#include <com/sun/star/chart2/XDataPointCustomLabelField.hpp> #include <com/sun/star/util/XCloneable.hpp> #include <com/sun/star/uno/XComponentContext.hpp> @@ -35,7 +37,7 @@ namespace chart namespace impl { typedef ::cppu::WeakImplHelper< - css::chart2::XFormattedString2, + css::chart2::XDataPointCustomLabelField, // inherits from XFormattedString2 css::lang::XServiceInfo, css::util::XCloneable, css::util::XModifyBroadcaster, @@ -82,6 +84,13 @@ private: virtual OUString SAL_CALL getString() override; virtual void SAL_CALL setString( const OUString& String ) override; + // ____ XDataPointCustomLabelField ____ + virtual css::chart2::DataPointCustomLabelFieldType SAL_CALL getFieldType() override; + virtual void SAL_CALL + setFieldType( const css::chart2::DataPointCustomLabelFieldType FieldType ) override; + virtual OUString SAL_CALL getGuid() override; + void SAL_CALL setGuid( const OUString& guid ) override; + // ____ OPropertySet ____ virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; @@ -115,8 +124,13 @@ private: void fireModifyEvent(); + // ____ XFormattedString ____ OUString m_aString; + // ____ XDataPointCustomLabelField ____ + css::chart2::DataPointCustomLabelFieldType m_aType; + OUString m_aGuid; + css::uno::Reference< css::util::XModifyListener > m_xModifyEventForwarder; }; diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx index af1544b22815..23cad6ada542 100644 --- a/chart2/source/view/charttypes/VSeriesPlotter.cxx +++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx @@ -56,6 +56,7 @@ #include <com/sun/star/chart/ErrorBarStyle.hpp> #include <com/sun/star/chart/TimeUnit.hpp> +#include <com/sun/star/chart2/XDataPointCustomLabelField.hpp> #include <com/sun/star/chart2/XRegressionCurveContainer.hpp> #include <com/sun/star/container/XChild.hpp> #include <com/sun/star/chart2/RelativePosition.hpp> @@ -413,9 +414,21 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re , sal_Int32 nTextWidth ) { uno::Reference< drawing::XShape > xTextShape; + Sequence<uno::Reference<XDataPointCustomLabelField>> aCustomLabels; try { + const uno::Reference< css::beans::XPropertySet >& xPropertySet( + rDataSeries.getPropertiesOfPoint( nPointIndex ) ); + if( xPropertySet.is() ) + { + uno::Any aAny = xPropertySet->getPropertyValue( CHART_UNONAME_CUSTOM_LABEL_FIELDS ); + if( aAny.hasValue() ) + { + aAny >>= aCustomLabels; + } + } + awt::Point aScreenPosition2D(rScreenPosition2D); if(eAlignment==LABEL_ALIGN_LEFT) aScreenPosition2D.X -= nOffset; @@ -495,26 +508,75 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re } sal_Int32 nLineCountForSymbolsize = 0; - Sequence< OUString > aTextList(3); + sal_uInt32 nTextListLength = 3; + sal_uInt32 nCustomLabelsCount = aCustomLabels.getLength(); + bool bUseCustomLabel = false; + Sequence< OUString > aTextList( nTextListLength ); + + bUseCustomLabel = nCustomLabelsCount > 0; + if( bUseCustomLabel ) { - if(pLabel->ShowCategoryName) + nTextListLength = ( nCustomLabelsCount > 3 ) ? nCustomLabelsCount : 3; + aSeparator = ""; + aTextList = Sequence< OUString >( nTextListLength ); + for( sal_uInt32 i = 0; i < nCustomLabelsCount; ++i ) { - if( m_pExplicitCategoriesProvider ) + switch( aCustomLabels[i]->getFieldType() ) { - Sequence< OUString > aCategories( m_pExplicitCategoriesProvider->getSimpleCategories() ); - if( nPointIndex >= 0 && nPointIndex < aCategories.getLength() ) + case DataPointCustomLabelFieldType_VALUE: + { + aTextList[i] = getLabelTextForValue( rDataSeries, nPointIndex, fValue, false ); + break; + } + case DataPointCustomLabelFieldType_CATEGORYNAME: + { + aTextList[i] = getCategoryName( nPointIndex ); + break; + } + case DataPointCustomLabelFieldType_SERIESNAME: { - aTextList[0] = aCategories[nPointIndex]; + OUString aRole; + if ( m_xChartTypeModel ) + aRole = m_xChartTypeModel->getRoleOfSequenceForSeriesLabel(); + uno::Reference< XDataSeries > xSeries( rDataSeries.getModel() ); + aTextList[i] = DataSeriesHelper::getDataSeriesLabel( xSeries, aRole ); + break; } + case DataPointCustomLabelFieldType_CELLREF: + { + // TODO: for now doesn't show placeholder + aTextList[i] = OUString(); + break; + } + case DataPointCustomLabelFieldType_TEXT: + { + aTextList[i] = aCustomLabels[i]->getString(); + break; + } + case DataPointCustomLabelFieldType_NEWLINE: + { + aTextList[i] = "\n"; + break; + } + default: + break; } + aCustomLabels[i]->setString( aTextList[i] ); + } + } + else + { + if( pLabel->ShowCategoryName ) + { + aTextList[0] = getCategoryName( nPointIndex ); } - if(pLabel->ShowNumber) + if( pLabel->ShowNumber ) { aTextList[1] = getLabelTextForValue(rDataSeries, nPointIndex, fValue, false); } - if(pLabel->ShowNumberInPercent) + if( pLabel->ShowNumberInPercent ) { if(fSumValue==0.0) fSumValue=1.0; @@ -524,13 +586,13 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re aTextList[2] = getLabelTextForValue(rDataSeries, nPointIndex, fValue, true); } + } - for( sal_Int32 nN = 0; nN < 3; ++nN) + for( sal_Int32 nN = 0; nN < aTextList.getLength(); ++nN ) + { + if( !aTextList[nN].isEmpty() ) { - if( !aTextList[nN].isEmpty() ) - { - ++nLineCountForSymbolsize; - } + ++nLineCountForSymbolsize; } } @@ -549,7 +611,28 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re // a multi-line label. bool bMultiLineLabel = ( aSeparator == "\n" ); - if( bMultiLineLabel ) + if( bUseCustomLabel ) + { + Sequence< uno::Reference< XFormattedString > > aFormattedLabels( aCustomLabels.getLength() ); + for( int i = 0; i < aFormattedLabels.getLength(); i++ ) + { + uno::Reference< XFormattedString > xString( aCustomLabels[i], uno::UNO_QUERY ); + aFormattedLabels[i] = xString; + } + + // center the text + sal_uInt32 nProperties = pPropNames->getLength(); + pPropNames->realloc( nProperties + 1 ); + pPropValues->realloc( nProperties + 1 ); + (*pPropNames)[ nProperties ] = UNO_NAME_EDIT_PARA_ADJUST; + (*pPropValues)[ nProperties ] <<= style::ParagraphAdjust_CENTER; + + // create text shape + xTextShape = AbstractShapeFactory::getOrCreateShapeFactory( m_xShapeFactory )-> + createText( xTarget_, aFormattedLabels, *pPropNames, *pPropValues, + AbstractShapeFactory::makeTransformation( aScreenPosition2D ) ); + } + else if( bMultiLineLabel ) { // prepare properties for each paragraph // we want to have the value and percent value centered respect @@ -575,7 +658,7 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re { // join text list elements OUStringBuffer aText; - for( sal_Int32 nN = 0; nN < 3; ++nN) + for( sal_uInt32 nN = 0; nN < nTextListLength; ++nN) { if( !aTextList[nN].isEmpty() ) { @@ -2050,6 +2133,19 @@ VDataSeries* VSeriesPlotter::getFirstSeries() const return nullptr; } +OUString VSeriesPlotter::getCategoryName( sal_Int32 nPointIndex ) const +{ + if (m_pExplicitCategoriesProvider) + { + Sequence< OUString > aCategories(m_pExplicitCategoriesProvider->getSimpleCategories()); + if (nPointIndex >= 0 && nPointIndex < aCategories.getLength()) + { + return aCategories[nPointIndex]; + } + } + return OUString(); +} + uno::Sequence< OUString > VSeriesPlotter::getSeriesNames() const { std::vector<OUString> aRetVector; diff --git a/chart2/source/view/inc/AbstractShapeFactory.hxx b/chart2/source/view/inc/AbstractShapeFactory.hxx index 26512214341d..e281e6291ebf 100644 --- a/chart2/source/view/inc/AbstractShapeFactory.hxx +++ b/chart2/source/view/inc/AbstractShapeFactory.hxx @@ -200,6 +200,13 @@ public: , const css::uno::Any& rATransformation ) = 0; virtual css::uno::Reference< css::drawing::XShape > + createText(const css::uno::Reference< css::drawing::XShapes >& xTarget + , css::uno::Sequence< css::uno::Reference< css::chart2::XFormattedString > >& xFormattedString + , const tNameSequence& rPropNames + , const tAnySequence& rPropValues + , const css::uno::Any& rATransformation) = 0; + + virtual css::uno::Reference< css::drawing::XShape > createText( const css::uno::Reference< css::drawing::XShapes >& xTarget2D, const css::awt::Size& rSize, const css::awt::Point& rPosition, diff --git a/chart2/source/view/inc/OpenglShapeFactory.hxx b/chart2/source/view/inc/OpenglShapeFactory.hxx index 01b2223cf59c..7963068ce79e 100644 --- a/chart2/source/view/inc/OpenglShapeFactory.hxx +++ b/chart2/source/view/inc/OpenglShapeFactory.hxx @@ -151,6 +151,13 @@ public: , const css::uno::Any& rATransformation ) override; virtual css::uno::Reference< css::drawing::XShape > + createText( const css::uno::Reference< css::drawing::XShapes >& xTarget + , css::uno::Sequence< css::uno::Reference< css::chart2::XFormattedString > >& xFormattedString + , const tNameSequence& rPropNames + , const tAnySequence& rPropValues + , const css::uno::Any& rATransformation ) override; + + virtual css::uno::Reference< css::drawing::XShape > createText( const css::uno::Reference< css::drawing::XShapes >& xTarget2D, const css::awt::Size& rSize, const css::awt::Point& rPosition, diff --git a/chart2/source/view/inc/ShapeFactory.hxx b/chart2/source/view/inc/ShapeFactory.hxx index 02a75d3a0764..ec1080732142 100644 --- a/chart2/source/view/inc/ShapeFactory.hxx +++ b/chart2/source/view/inc/ShapeFactory.hxx @@ -189,6 +189,13 @@ public: , const css::uno::Any& rATransformation ) override; virtual css::uno::Reference< css::drawing::XShape > + createText(const css::uno::Reference< css::drawing::XShapes >& xTarget + , css::uno::Sequence< css::uno::Reference< css::chart2::XFormattedString > >& xFormattedString + , const tNameSequence& rPropNames + , const tAnySequence& rPropValues + , const css::uno::Any& rATransformation) override; + + virtual css::uno::Reference< css::drawing::XShape > createText( const css::uno::Reference< css::drawing::XShapes >& xTarget2D, const css::awt::Size& rSize, const css::awt::Point& rPosition, diff --git a/chart2/source/view/inc/VSeriesPlotter.hxx b/chart2/source/view/inc/VSeriesPlotter.hxx index 54f3f7733d63..d8b1cf05eb2b 100644 --- a/chart2/source/view/inc/VSeriesPlotter.hxx +++ b/chart2/source/view/inc/VSeriesPlotter.hxx @@ -389,6 +389,8 @@ protected: VDataSeries* getFirstSeries() const; + OUString getCategoryName( sal_Int32 nPointIndex ) const; + protected: PlottingPositionHelper* m_pMainPosHelper; diff --git a/chart2/source/view/main/OpenglShapeFactory.cxx b/chart2/source/view/main/OpenglShapeFactory.cxx index 9cb3318f7fa2..e6c4980b8017 100644 --- a/chart2/source/view/main/OpenglShapeFactory.cxx +++ b/chart2/source/view/main/OpenglShapeFactory.cxx @@ -408,6 +408,18 @@ uno::Reference< drawing::XShape > } uno::Reference< drawing::XShape > + OpenglShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget + , uno::Sequence< uno::Reference< chart2::XFormattedString > >& rFormattedString + , const tNameSequence& rPropNames + , const tAnySequence& rPropValues + , const uno::Any& rATransformation ) +{ + dummy::DummyText* pText = new dummy::DummyText( rFormattedString[0]->getString(), rPropNames, rPropValues, + rATransformation, xTarget, 0 ); + return pText; +} + +uno::Reference< drawing::XShape > OpenglShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget, const awt::Size& , const awt::Point& rPos, uno::Sequence< uno::Reference< chart2::XFormattedString > >& rFormattedString, diff --git a/chart2/source/view/main/ShapeFactory.cxx b/chart2/source/view/main/ShapeFactory.cxx index 3ed37f316225..2a72f969fa10 100644 --- a/chart2/source/view/main/ShapeFactory.cxx +++ b/chart2/source/view/main/ShapeFactory.cxx @@ -2237,6 +2237,100 @@ uno::Reference< drawing::XShape > } uno::Reference< drawing::XShape > + ShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget + , uno::Sequence< uno::Reference< chart2::XFormattedString > >& xFormattedString + , const tNameSequence& rPropNames + , const tAnySequence& rPropValues + , const uno::Any& rATransformation ) +{ + if( !xTarget.is() ) + return nullptr; + + if( !xFormattedString.hasElements() ) + return nullptr; + + sal_Int32 nNumberOfParagraphs = xFormattedString.getLength(); + + bool bNotEmpty = false; + for( sal_Int32 nN = 0; nN < nNumberOfParagraphs; ++nN ) + { + if( !xFormattedString[nN]->getString().isEmpty() ) + { + bNotEmpty = true; + break; + } + } + if( !bNotEmpty ) + return nullptr; + + //create shape and add to page + uno::Reference< drawing::XShape > xShape( + m_xShapeFactory->createInstance( + "com.sun.star.drawing.TextShape" ), uno::UNO_QUERY ); + xTarget->add(xShape); + + //set paragraph properties + bNotEmpty = false; + Reference< text::XText > xText( xShape, uno::UNO_QUERY ); + if( xText.is() ) + { + // the first cursor is used for appending the next paragraph, + // after a new string has been inserted the cursor is moved at the end + // of the inserted string + // the second cursor is used for selecting the paragraph and apply the + // passed text properties + Reference< text::XTextCursor > xInsertCursor = xText->createTextCursor(); + Reference< text::XTextCursor > xSelectionCursor = xText->createTextCursor(); + if( xInsertCursor.is() && xSelectionCursor.is() ) + { + uno::Reference< beans::XPropertySet > xSelectionProp( xSelectionCursor, uno::UNO_QUERY ); + if( xSelectionProp.is() ) + { + for( sal_Int32 nN = 0; nN < nNumberOfParagraphs; ++nN ) + { + if( !xFormattedString[nN]->getString().isEmpty() ) + { + xInsertCursor->gotoEnd( false ); + xSelectionCursor->gotoEnd( false ); + xText->insertString( xInsertCursor, xFormattedString[nN]->getString(), false ); + bNotEmpty = true; + xSelectionCursor->gotoEnd( true ); // select current paragraph + uno::Reference< beans::XPropertySet > xStringProperties( xFormattedString[nN], uno::UNO_QUERY ); + PropertyMapper::setMappedProperties( xSelectionProp, xStringProperties, + PropertyMapper::getPropertyNameMapForTextShapeProperties() ); + } + } + } + } + } + + if( !bNotEmpty ) + return nullptr; + + uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY ); + if( xProp.is() ) + { + //set whole text shape properties + PropertyMapper::setMultiProperties( rPropNames, rPropValues, xProp ); + + if( rATransformation.hasValue() ) + { + //set position matrix + //the matrix needs to be set at the end behind autogrow and such position influencing properties + try + { + xProp->setPropertyValue( "Transformation", rATransformation ); + } + catch( const uno::Exception& e ) + { + SAL_WARN("chart2", "Exception caught. " << e ); + } + } + } + return xShape; +} + +uno::Reference< drawing::XShape > ShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget, const awt::Size& rSize, const awt::Point& rPos, diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 472771a5c15d..b50864a25880 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -69,6 +69,8 @@ $(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/awt/tree,\ $(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/chart2,\ CartesianCoordinateSystem2d \ CartesianCoordinateSystem3d \ + DataPointCustomLabelField \ + DataPointCustomLabelFieldType \ ExponentialRegressionCurve \ ExponentialScaling \ FormattedString \ @@ -2024,6 +2026,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/chart2,\ XCoordinateSystem \ XCoordinateSystemContainer \ XDataInterpreter \ + XDataPointCustomLabelField \ XDataSeries \ XDataSeriesContainer \ XDefaultSizeTransmitter \ diff --git a/offapi/com/sun/star/chart2/DataPointCustomLabelField.idl b/offapi/com/sun/star/chart2/DataPointCustomLabelField.idl new file mode 100644 index 000000000000..cebe1c3273f3 --- /dev/null +++ b/offapi/com/sun/star/chart2/DataPointCustomLabelField.idl @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef com_sun_star_chart2_DataPointCustomLabelField_idl +#define com_sun_star_chart2_DataPointCustomLabelField_idl + +#include <com/sun/star/chart2/XDataPointCustomLabelField.idl> + +module com { module sun { module star { module chart2 { + +/** + @since LibreOffice 6.1 +*/ +service DataPointCustomLabelField : XDataPointCustomLabelField; + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ \ No newline at end of file diff --git a/offapi/com/sun/star/chart2/DataPointCustomLabelFieldType.idl b/offapi/com/sun/star/chart2/DataPointCustomLabelFieldType.idl new file mode 100644 index 000000000000..0b7f925342a6 --- /dev/null +++ b/offapi/com/sun/star/chart2/DataPointCustomLabelFieldType.idl @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef com_sun_star_chart2_DataPointCustomLabelFieldType_idl +#define com_sun_star_chart2_DataPointCustomLabelFieldType_idl + +module com { module sun { module star { module chart2 { + +/** The Field type enumeration for custom data point labels. + + @since LibreOffice 6.1 + */ +enum DataPointCustomLabelFieldType +{ + TEXT, + VALUE, + SERIESNAME, + CATEGORYNAME, + CELLREF, + NEWLINE +}; + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ \ No newline at end of file diff --git a/offapi/com/sun/star/chart2/DataPointProperties.idl b/offapi/com/sun/star/chart2/DataPointProperties.idl index 31bd0a42696c..df5cf071ee90 100644 --- a/offapi/com/sun/star/chart2/DataPointProperties.idl +++ b/offapi/com/sun/star/chart2/DataPointProperties.idl @@ -31,6 +31,7 @@ #include <com/sun/star/drawing/RectanglePoint.idl> #include <com/sun/star/chart2/DataPointLabel.idl> #include <com/sun/star/chart2/Symbol.idl> +#include <com/sun/star/chart2/XFormattedString2.idl> module com { @@ -258,6 +259,13 @@ service DataPointProperties [property] DataPointLabel Label; + /** specifies a text with possible fields that is used as a data point label, + if set then Label property is ignored + + @since LibreOffice 6.1 + */ + [optional, property] sequence<XDataPointCustomLabelField> CustomLabelFields; + /** specifies a string that is used to separate the parts of a data label (caption) */ [optional, property] string LabelSeparator; diff --git a/offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl b/offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl new file mode 100644 index 000000000000..a6a1b0151c94 --- /dev/null +++ b/offapi/com/sun/star/chart2/XDataPointCustomLabelField.idl @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#ifndef com_sun_star_chart2_DataPointCustomLabelField_idl +#define com_sun_star_chart2_DataPointCustomLabelField_idl + +#include <com/sun/star/chart2/XFormattedString2.idl> +#include <com/sun/star/chart2/DataPointCustomLabelFieldType.idl> + +module com { module sun { module star { module chart2 { + +/** + Provides interface for DataPointCustomLabelField service. + + @since LibreOffice 6.1 +*/ +interface XDataPointCustomLabelField : XFormattedString2 +{ + DataPointCustomLabelFieldType getFieldType(); + + void setFieldType( [in] DataPointCustomLabelFieldType fieldType ); + + string getGuid(); + + void setGuid( [in] string guid ); + +}; + + + +} ; // chart2 +} ; // com +} ; // sun +} ; // star + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/oox/inc/drawingml/textfield.hxx b/oox/inc/drawingml/textfield.hxx index 9f5bf9cf27af..7cc15a04fce4 100644 --- a/oox/inc/drawingml/textfield.hxx +++ b/oox/inc/drawingml/textfield.hxx @@ -38,7 +38,9 @@ public: const TextParagraphProperties& getTextParagraphProperties() const { return maTextParagraphProperties; } void setType( const OUString& sType ) { msType = sType; } + const OUString& getType() const { return msType; } void setUuid( const OUString & sUuid ) { msUuid = sUuid; } + const OUString& getUuid() const { return msUuid; } virtual sal_Int32 insertAt( const ::oox::core::XmlFilterBase& rFilterBase, diff --git a/oox/source/drawingml/chart/seriesconverter.cxx b/oox/source/drawingml/chart/seriesconverter.cxx index 6eceb213ea04..1a5c2ba8d96d 100644 --- a/oox/source/drawingml/chart/seriesconverter.cxx +++ b/oox/source/drawingml/chart/seriesconverter.cxx @@ -22,11 +22,16 @@ #include <com/sun/star/chart/DataLabelPlacement.hpp> #include <com/sun/star/chart/ErrorBarStyle.hpp> #include <com/sun/star/chart2/DataPointLabel.hpp> +#include <com/sun/star/chart2/XDataPointCustomLabelField.hpp> +#include <com/sun/star/chart2/DataPointCustomLabelField.hpp> +#include <com/sun/star/chart2/DataPointCustomLabelFieldType.hpp> #include <com/sun/star/chart2/XDataSeries.hpp> #include <com/sun/star/chart2/XRegressionCurve.hpp> #include <com/sun/star/chart2/XRegressionCurveContainer.hpp> #include <com/sun/star/chart2/data/XDataSink.hpp> #include <com/sun/star/chart2/data/LabeledDataSequence.hpp> +#include <com/sun/star/chart2/XFormattedString2.hpp> +#include <com/sun/star/chart2/FormattedString.hpp> #include <osl/diagnose.h> #include <basegfx/numeric/ftools.hxx> #include <drawingml/chart/datasourceconverter.hxx> @@ -41,6 +46,10 @@ #include <oox/token/properties.hxx> #include <oox/token/tokens.hxx> #include <drawingml/lineproperties.hxx> +#include <drawingml/textparagraph.hxx> +#include <drawingml/textrun.hxx> +#include <drawingml/textfield.hxx> +#include <drawingml/textbody.hxx> namespace oox { namespace drawingml { @@ -200,6 +209,20 @@ void importBorderProperties( PropertySet& rPropSet, Shape& rShape, const Graphic rPropSet.setProperty(PROP_LabelBorderColor, uno::makeAny(nColor)); } +DataPointCustomLabelFieldType lcl_ConvertFieldNameToFieldEnum( const OUString& rField ) +{ + if (rField == "VALUE") + return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_VALUE; + else if (rField == "SERIESNAME") + return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_SERIESNAME; + else if (rField == "CATEGORYNAME") + return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CATEGORYNAME; + else if (rField == "CELLREF") + return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLREF; + else + return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT; +} + } // namespace DataLabelConverter::DataLabelConverter( const ConverterRoot& rParent, DataLabelModel& rModel ) : @@ -247,6 +270,61 @@ void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDat if (mrModel.mxShapeProp) importBorderProperties(aPropSet, *mrModel.mxShapeProp, getFilter().getGraphicHelper()); + + if( mrModel.mxText && mrModel.mxText->mxTextBody && mrModel.mxText->mxTextBody->getParagraphs().size() ) + { + css::uno::Reference< XComponentContext > xContext = getComponentContext(); + uno::Sequence< css::uno::Reference< XDataPointCustomLabelField > > aSequence; + + auto& rParagraphs = mrModel.mxText->mxTextBody->getParagraphs(); + + int nSequenceSize = 0; + for( auto& pParagraph : rParagraphs ) + nSequenceSize += pParagraph->getRuns().size(); + + int nParagraphs = rParagraphs.size(); + if( nParagraphs > 1 ) + nSequenceSize += nParagraphs - 1; + + aSequence.realloc( nSequenceSize ); + + int nPos = 0; + for( auto& pParagraph : rParagraphs ) + { + for( auto& pRun : pParagraph->getRuns() ) + { + css::uno::Reference< XDataPointCustomLabelField > xCustomLabel = DataPointCustomLabelField::create( xContext ); + + // Store properties + oox::PropertySet aPropertySet( xCustomLabel ); + pRun->getTextCharacterProperties().pushToPropSet( aPropertySet, getFilter() ); + + TextField* pField = nullptr; + if( ( pField = dynamic_cast< TextField* >( pRun.get() ) ) ) + { + xCustomLabel->setString( pField->getText() ); + xCustomLabel->setFieldType( lcl_ConvertFieldNameToFieldEnum( pField->getType() ) ); + xCustomLabel->setGuid( pField->getUuid() ); + } + else if( pRun.get() ) + { + xCustomLabel->setString( pRun->getText() ); + xCustomLabel->setFieldType( DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT ); + } + aSequence[ nPos++ ] = xCustomLabel; + } + + if( nParagraphs > 1 && nPos < nSequenceSize ) + { + css::uno::Reference< XDataPointCustomLabelField > xCustomLabel = DataPointCustomLabelField::create( xContext ); + xCustomLabel->setFieldType( DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_NEWLINE ); + xCustomLabel->setString("\n"); + aSequence[ nPos++ ] = xCustomLabel; + } + } + + aPropSet.setProperty( PROP_CustomLabelFields, makeAny( aSequence ) ); + } } catch( Exception& ) { diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index e6bc79ff3d08..1c700894a112 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -278,6 +278,7 @@ LabelBorderWidth LabelPlacement LabelPosition LabelSeparator +CustomLabelFields LayoutInfo LeftBorder LeftBorderDistance -- 2.13.6 From 12415c5d82817b4d056d205b6afc940872b83682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20K=C5=82os?= <szymon.klos@collabora.com> Date: Sat, 27 Jan 2018 20:29:38 +0100 Subject: [PATCH 2/2] tdf#114821 export complex data labels in charts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I9b0893dfde4efc10bb05e6e17b7128b016efeb71 Reviewed-on: https://gerrit.libreoffice.org/48788 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Szymon Kłos <szymon.klos@collabora.com> --- chart2/qa/extras/chart2export.cxx | 159 ++++++++++++++++++++++++++++++++++++++ oox/source/export/chartexport.cxx | 107 ++++++++++++++++++++++++- 2 files changed, 262 insertions(+), 4 deletions(-) diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index 128a166c6c4a..63375d6c2fca 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -60,6 +60,8 @@ #include <com/sun/star/chart2/XDataSeriesContainer.hpp> #include <com/sun/star/chart2/DataPointGeometry3D.hpp> #include <com/sun/star/chart2/DataPointLabel.hpp> +#include <com/sun/star/chart2/DataPointCustomLabelField.hpp> +#include <com/sun/star/chart2/DataPointCustomLabelFieldType.hpp> #include <com/sun/star/chart2/Symbol.hpp> #include <com/sun/star/chart2/data/XDataSource.hpp> #include <com/sun/star/chart2/data/XDataSink.hpp> @@ -2866,17 +2868,111 @@ const char* toOOXMLPlacement( sal_Int32 nPlacement ) return "outEnd"; } -void writeLabelProperties( - const FSHelperPtr& pFS, const uno::Reference<beans::XPropertySet>& xPropSet, const LabelPlacementParam& rLabelParam ) +OUString getFieldTypeString( const chart2::DataPointCustomLabelFieldType aType ) +{ + switch (aType) + { + case chart2::DataPointCustomLabelFieldType_CATEGORYNAME: + return OUString("CATEGORYNAME"); + + case chart2::DataPointCustomLabelFieldType_SERIESNAME: + return OUString("SERIESNAME"); + + case chart2::DataPointCustomLabelFieldType_VALUE: + return OUString("VALUE"); + + case chart2::DataPointCustomLabelFieldType_CELLREF: + return OUString("CELLREF"); + + default: + break; + } + return OUString(); +} + +void writeRunProperties( ChartExport* pChartExport, Reference<XPropertySet>& xPropertySet ) +{ + bool bDummy = false; + sal_Int32 nDummy; + pChartExport->WriteRunProperties(xPropertySet, false, XML_rPr, true, bDummy, nDummy); +} + +void writeCustomLabel( const FSHelperPtr& pFS, ChartExport* pChartExport, + const Sequence<Reference<chart2::XDataPointCustomLabelField>>& rCustomLabelFields ) +{ + pFS->startElement(FSNS(XML_c, XML_tx), FSEND); + pFS->startElement(FSNS(XML_c, XML_rich), FSEND); + + // TODO: body properties? + pFS->singleElement(FSNS(XML_a, XML_bodyPr), FSEND); + + OUString sFieldType; + bool bNewParagraph; + pFS->startElement(FSNS(XML_a, XML_p), FSEND); + + for (auto& rField : rCustomLabelFields) + { + Reference<XPropertySet> xPropertySet(rField, UNO_QUERY); + chart2::DataPointCustomLabelFieldType aType = rField->getFieldType(); + sFieldType.clear(); + bNewParagraph = false; + + if (aType == chart2::DataPointCustomLabelFieldType_NEWLINE) + bNewParagraph = true; + else if (aType != chart2::DataPointCustomLabelFieldType_TEXT) + sFieldType = getFieldTypeString(aType); + + if (bNewParagraph) + { + pFS->endElement(FSNS(XML_a, XML_p)); + pFS->startElement(FSNS(XML_a, XML_p), FSEND); + continue; + } + + if (sFieldType.isEmpty()) + { + // Normal text run + pFS->startElement(FSNS(XML_a, XML_r), FSEND); + writeRunProperties(pChartExport, xPropertySet); + + pFS->startElement(FSNS(XML_a, XML_t), FSEND); + pFS->writeEscaped(rField->getString()); + pFS->endElement(FSNS(XML_a, XML_t)); + + pFS->endElement(FSNS(XML_a, XML_r)); + } + else + { + // Field + pFS->startElement(FSNS(XML_a, XML_fld), XML_id, USS(rField->getGuid()), XML_type, USS(sFieldType), FSEND); + writeRunProperties(pChartExport, xPropertySet); + + pFS->startElement(FSNS(XML_a, XML_t), FSEND); + pFS->writeEscaped(rField->getString()); + pFS->endElement(FSNS(XML_a, XML_t)); + + pFS->endElement(FSNS(XML_a, XML_fld)); + } + } + + pFS->endElement(FSNS(XML_a, XML_p)); + pFS->endElement(FSNS(XML_c, XML_rich)); + pFS->endElement(FSNS(XML_c, XML_tx)); +} + +void writeLabelProperties( const FSHelperPtr& pFS, ChartExport* pChartExport, + const uno::Reference<beans::XPropertySet>& xPropSet, const LabelPlacementParam& rLabelParam ) { if (!xPropSet.is()) return; chart2::DataPointLabel aLabel; + Sequence<Reference<chart2::XDataPointCustomLabelField>> aCustomLabelFields; sal_Int32 nLabelBorderWidth = 0; sal_Int32 nLabelBorderColor = 0x00FFFFFF; xPropSet->getPropertyValue("Label") >>= aLabel; + xPropSet->getPropertyValue("CustomLabelFields") >>= aCustomLabelFields; xPropSet->getPropertyValue("LabelBorderWidth") >>= nLabelBorderWidth; xPropSet->getPropertyValue("LabelBorderColor") >>= nLabelBorderColor; @@ -2897,6 +2993,9 @@ void writeLabelProperties( pFS->endElement(FSNS(XML_c, XML_spPr)); } + if (aCustomLabelFields.getLength() > 0) + writeCustomLabel(pFS, pChartExport, aCustomLabelFields); + if (rLabelParam.mbExport) { sal_Int32 nLabelPlacement = rLabelParam.meDefault; @@ -2992,12 +3091,12 @@ void ChartExport::exportDataLabels( // Individual label property that overwrites the baseline. pFS->startElement(FSNS(XML_c, XML_dLbl), FSEND); pFS->singleElement(FSNS(XML_c, XML_idx), XML_val, I32S(nIdx), FSEND); - writeLabelProperties(pFS, xLabelPropSet, aParam); + writeLabelProperties(pFS, this, xLabelPropSet, aParam); pFS->endElement(FSNS(XML_c, XML_dLbl)); } // Baseline label properties for all labels. - writeLabelProperties(pFS, xPropSet, aParam); + writeLabelProperties(pFS, this, xPropSet, aParam); pFS->singleElement(FSNS(XML_c, XML_showLeaderLines), XML_val, "0", -- 2.13.6
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor