diff options
author | Justin Luth <justin.luth@collabora.com> | 2024-01-25 11:57:40 -0500 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2024-01-30 10:40:43 +0100 |
commit | a77403d11a60ebe6aeb33d9b6ae611412d9ab1cc (patch) | |
tree | eccb24a43aad7df75620a7b49b2d7e2a4b3a2db7 | |
parent | 2048db4dc8ee6edb231a9109257846975a6f7834 (diff) |
tdf#146756 pie chart2 import: use manualLayout Width for pie chart labels
... and use a compatible 1/5 width if not specified.
This patch depends on the previous oox patch
(commit 301e27cbebf7d6e4c9b82290d7cd555c43f0c999)
which actually reads the width into the model.
Fixes a 7.2 regression from
commit b0068342398786ca50304260434a18880dddf74d
author Tünde Tóth on Wed Dec 16 18:26:26 2020 +0100
tdf#138777 pie chart: improve long data label width
and is basically a re-write of 7.1's
commit 20da1a5dd37c7edac620566c992d5a53b23a5f12
author Tünde Tóth <toth.tunde@nisz.hu> on Fri Oct 09 09:24:18 2020 +0200
tdf#134978 Chart OOXML Import: fix pie chart label custom position
This is very risky, but then ANYTHING changing chart2 is risky.
There were a lot of changes made in 7.1,
and they all invited regressions.
However, our chart implementation is not in a good state,
and certainly is not very interoperable,
so it is worth taking the risk.
Anything dealing with manualLayout at this point
should have originated as a pptx,
so forcing a compatible max width should be fairly safe.
It probably isn't actually all that risky after all.
largely copied code from
commit 4223ff2be69f03e571464b0b09ad0d278918631b
Author: Balazs Varga on Wed Jan 15 16:31:35 2020 +0100
tdf#48436 Chart: add CustomLabelPosition UNO API property
Fortunately this all goes away after a round-trip
since custom label placement is lost on export to OOXML,
and that really helps to reduce the risk.
make CppunitTest_chart2_import CPPUNIT_TEST_NAME=testTdf146487
Change-Id: I9722fc6c759c15ac3924780e6fc124f02fba07e1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162590
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r-- | chart2/qa/extras/chart2import.cxx | 22 | ||||
-rw-r--r-- | chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx | 1 | ||||
-rw-r--r-- | chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx | 1 | ||||
-rw-r--r-- | chart2/source/model/main/DataPointProperties.cxx | 6 | ||||
-rw-r--r-- | chart2/source/model/main/DataPointProperties.hxx | 3 | ||||
-rw-r--r-- | chart2/source/tools/DataSeriesHelper.cxx | 3 | ||||
-rw-r--r-- | chart2/source/view/charttypes/PieChart.cxx | 38 | ||||
-rw-r--r-- | chart2/source/view/inc/VDataSeries.hxx | 1 | ||||
-rw-r--r-- | chart2/source/view/main/VDataSeries.cxx | 21 | ||||
-rw-r--r-- | offapi/com/sun/star/chart2/DataPointProperties.idl | 6 | ||||
-rw-r--r-- | oox/source/drawingml/chart/seriesconverter.cxx | 3 | ||||
-rw-r--r-- | oox/source/token/properties.txt | 1 |
12 files changed, 92 insertions, 14 deletions
diff --git a/chart2/qa/extras/chart2import.cxx b/chart2/qa/extras/chart2import.cxx index fc8042a38393..b23e048c6949 100644 --- a/chart2/qa/extras/chart2import.cxx +++ b/chart2/qa/extras/chart2import.cxx @@ -29,6 +29,7 @@ #include <com/sun/star/chart2/data/XTextualDataSequence.hpp> #include <com/sun/star/chart/DataLabelPlacement.hpp> #include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/qa/XDumper.hpp> #include <iterator> #include <com/sun/star/util/Color.hpp> @@ -37,6 +38,8 @@ #include <basegfx/utils/gradienttools.hxx> #include <docmodel/uno/UnoGradientTools.hxx> +namespace +{ class Chart2ImportTest : public ChartTest { public: @@ -46,6 +49,11 @@ protected: void testTransparentBackground(std::u16string_view filename); }; +OUString getShapeDump(css::uno::Reference<css::chart::XChartDocument> const& doc) +{ + return css::uno::Reference<css::qa::XDumper>(doc, css::uno::UNO_QUERY_THROW)->dump("shapes"); +} + // error bar import // split method up into smaller chunks for more detailed tests CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testFdo60083) @@ -187,7 +195,7 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testSteppedLines) } } -static uno::Sequence < OUString > getChartColumnDescriptions( uno::Reference< chart::XChartDocument > const & xChart1Doc) +uno::Sequence < OUString > getChartColumnDescriptions( uno::Reference< chart::XChartDocument > const & xChart1Doc) { CPPUNIT_ASSERT(xChart1Doc.is()); uno::Reference< chart::XChartDataArray > xChartData ( xChart1Doc->getData(), UNO_QUERY_THROW); @@ -1988,6 +1996,17 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testTdf146487) Reference<chart2::XTitled> xTitled(xChartDoc, uno::UNO_QUERY_THROW); uno::Reference<chart2::XTitle> xTitle = xTitled->getTitleObject(); CPPUNIT_ASSERT_MESSAGE("chart doc should not have a title", !xTitle.is()); + + // tdf#146756 use manualLayout Width that was provided (so Green; $7,654,321 is not wrapped + if (!IsDefaultDPI()) + return; + uno::Reference<chart::XChartDocument> xDoc = getChartDocFromDrawImpress(0, 0); + OString aXmlDump = OUStringToOString(getShapeDump(xDoc), RTL_TEXTENCODING_UTF8); + xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast<const xmlChar*>(aXmlDump.getStr()))); + OString aPath("//XShape[@text='Green; $7,654,321 ']"_ostr); + assertXPath(pXmlDoc, aPath, 1); + // Expected - 1 line tall(371), not 4 lines(1481). + CPPUNIT_ASSERT_EQUAL(OUString("371"), getXPath(pXmlDoc, aPath, "sizeY"_ostr)); } CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testFixedSizeBarChartVeryLongLabel) @@ -2248,6 +2267,7 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testPieChartPlotAreaMarginWithAutomaticLa } } +} // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx index 2b194051a1f2..93490438d753 100644 --- a/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx +++ b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx @@ -460,6 +460,7 @@ bool DataPointItemConverter::ApplySpecialItem( { GetPropertySet()->setPropertyValue("LabelPlacement", uno::Any(nNew)); GetPropertySet()->setPropertyValue("CustomLabelPosition", uno::Any()); + GetPropertySet()->setPropertyValue("CustomLabelSize", uno::Any()); bChanged = true; } } diff --git a/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx b/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx index 0f4019546592..10c1f9373547 100644 --- a/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx +++ b/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx @@ -401,6 +401,7 @@ bool TextLabelItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxIte { GetPropertySet()->setPropertyValue("LabelPlacement", uno::Any(nNew)); GetPropertySet()->setPropertyValue("CustomLabelPosition", uno::Any()); + GetPropertySet()->setPropertyValue("CustomLabelSize", uno::Any()); bChanged = true; } } diff --git a/chart2/source/model/main/DataPointProperties.cxx b/chart2/source/model/main/DataPointProperties.cxx index 819336edd9c4..c27407c98fca 100644 --- a/chart2/source/model/main/DataPointProperties.cxx +++ b/chart2/source/model/main/DataPointProperties.cxx @@ -30,6 +30,7 @@ #include <com/sun/star/drawing/BitmapMode.hpp> #include <com/sun/star/drawing/RectanglePoint.hpp> #include <com/sun/star/chart2/RelativePosition.hpp> +#include <com/sun/star/chart2/RelativeSize.hpp> #include <com/sun/star/chart2/XDataPointCustomLabelField.hpp> #include <com/sun/star/chart2/DataPointGeometry3D.hpp> #include <com/sun/star/chart2/DataPointLabel.hpp> @@ -447,6 +448,11 @@ void DataPointProperties::AddPropertiesToVector( cppu::UnoType<chart2::RelativePosition>::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEVOID ); + + rOutProperties.emplace_back("CustomLabelSize", PROP_DATAPOINT_LABEL_CUSTOM_SIZE, + cppu::UnoType<chart2::RelativeSize>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEVOID); } void DataPointProperties::AddDefaultsToMap( diff --git a/chart2/source/model/main/DataPointProperties.hxx b/chart2/source/model/main/DataPointProperties.hxx index ada7907b888f..1689322148d8 100644 --- a/chart2/source/model/main/DataPointProperties.hxx +++ b/chart2/source/model/main/DataPointProperties.hxx @@ -87,7 +87,8 @@ namespace DataPointProperties PROP_DATAPOINT_LABEL_BORDER_DASH_NAME, PROP_DATAPOINT_LABEL_BORDER_TRANS, PROP_DATAPOINT_CUSTOM_LABEL_FIELDS, - PROP_DATAPOINT_LABEL_CUSTOM_POS + PROP_DATAPOINT_LABEL_CUSTOM_POS, + PROP_DATAPOINT_LABEL_CUSTOM_SIZE // additionally some properties from ::chart::LineProperties }; diff --git a/chart2/source/tools/DataSeriesHelper.cxx b/chart2/source/tools/DataSeriesHelper.cxx index dba33728b5aa..a6efbda3a1e9 100644 --- a/chart2/source/tools/DataSeriesHelper.cxx +++ b/chart2/source/tools/DataSeriesHelper.cxx @@ -467,7 +467,10 @@ void setPropertyAlsoToAllAttributedDataPoints( const rtl::Reference< ::chart::Da continue; xPointProp->setPropertyValue( rPropertyName, rPropertyValue ); if( rPropertyName == "LabelPlacement" ) + { xPointProp->setPropertyValue("CustomLabelPosition", uno::Any()); + xPointProp->setPropertyValue("CustomLabelSize", uno::Any()); + } } } } diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx index 5e3a6dcaad17..93221b468473 100644 --- a/chart2/source/view/charttypes/PieChart.cxx +++ b/chart2/source/view/charttypes/PieChart.cxx @@ -324,14 +324,18 @@ void PieChart::createTextLabelShape( sal_Int32 nLabelPlacement = rSeries.getLabelPlacement( nPointIndex, m_xChartTypeModel, m_aPosHelper.isSwapXAndY()); + // has an X/Y offset (relative to the OUTSIDE label default position) been provided? + const bool bHasCustomLabelPlacement = nLabelPlacement == css::chart::DataLabelPlacement::CUSTOM; + if (bHasCustomLabelPlacement) + nLabelPlacement = css::chart::DataLabelPlacement::OUTSIDE; + ///when the placement is of `AVOID_OVERLAP` type a later rearrangement of ///the label position is allowed; the `createTextLabelShape` treats the ///`AVOID_OVERLAP` as if it was of `CENTER` type; double nVal = rSeries.getYValue(nPointIndex); //AVOID_OVERLAP is in fact "Best fit" in the UI. - bool bMovementAllowed = nLabelPlacement == css::chart::DataLabelPlacement::AVOID_OVERLAP - || nLabelPlacement == css::chart::DataLabelPlacement::CUSTOM; + bool bMovementAllowed = nLabelPlacement == css::chart::DataLabelPlacement::AVOID_OVERLAP; if( bMovementAllowed ) nLabelPlacement = css::chart::DataLabelPlacement::CENTER; @@ -398,14 +402,26 @@ void PieChart::createTextLabelShape( // set the maximum text width to be used when text wrapping is enabled double fTextMaximumFrameWidth = 0.8 * fPieRadius; - if (nLabelPlacement == css::chart::DataLabelPlacement::OUTSIDE - && m_aAvailableOuterRect.getWidth()) + if (m_aAvailableOuterRect.getWidth()) { - if ((fAngleDegree >= 67.5 && fAngleDegree <= 112.5) - || (fAngleDegree >= 247.5 && fAngleDegree <= 292.5)) - fTextMaximumFrameWidth = m_aAvailableOuterRect.getWidth() / 3.0; - else - fTextMaximumFrameWidth = 0.85 * (m_aAvailableOuterRect.getWidth() / 2.0 - fPieRadius); + if (bHasCustomLabelPlacement) + { + // if a custom width has been provided, then use that of course, + // otherwise use the interoperability-compliant 1/5 of the chart space as max width + const awt::Size aCustomSize = rSeries.getLabelCustomSize(nPointIndex); + if (aCustomSize.Width > 0) + fTextMaximumFrameWidth = aCustomSize.Width; + else + fTextMaximumFrameWidth = m_aAvailableOuterRect.getWidth() / 5.0; + } + else if (nLabelPlacement == css::chart::DataLabelPlacement::OUTSIDE) + { + if ((fAngleDegree >= 67.5 && fAngleDegree <= 112.5) + || (fAngleDegree >= 247.5 && fAngleDegree <= 292.5)) + fTextMaximumFrameWidth = m_aAvailableOuterRect.getWidth() / 3.0; + else + fTextMaximumFrameWidth = 0.85 * (m_aAvailableOuterRect.getWidth() / 2.0 - fPieRadius); + } } sal_Int32 nTextMaximumFrameWidth = ceil(fTextMaximumFrameWidth); @@ -430,9 +446,7 @@ void PieChart::createTextLabelShape( * First off the routine try to place the label inside the related pie slice, * if this is not possible the label is placed outside. */ - if (rSeries.getLabelPlacement(nPointIndex, m_xChartTypeModel, m_aPosHelper.isSwapXAndY()) - == css::chart::DataLabelPlacement::CUSTOM - || !performLabelBestFitInnerPlacement(rParam, aPieLabelInfo)) + if (!performLabelBestFitInnerPlacement(rParam, aPieLabelInfo)) { if (m_aAvailableOuterRect.getWidth()) { diff --git a/chart2/source/view/inc/VDataSeries.hxx b/chart2/source/view/inc/VDataSeries.hxx index 65f7247bc197..72f5fca80089 100644 --- a/chart2/source/view/inc/VDataSeries.hxx +++ b/chart2/source/view/inc/VDataSeries.hxx @@ -112,6 +112,7 @@ public: css::awt::Point getLabelPosition( css::awt::Point aTextShapePos, sal_Int32 nPointIndex ) const; bool isLabelCustomPos( sal_Int32 nPointIndex ) const; + css::awt::Size getLabelCustomSize(sal_Int32 nPointIndex) const; css::uno::Reference<css::beans::XPropertySet> getPropertiesOfPoint( sal_Int32 index ) const; diff --git a/chart2/source/view/main/VDataSeries.cxx b/chart2/source/view/main/VDataSeries.cxx index 845e6d6ef0db..455c991b9f89 100644 --- a/chart2/source/view/main/VDataSeries.cxx +++ b/chart2/source/view/main/VDataSeries.cxx @@ -36,6 +36,7 @@ #include <com/sun/star/chart2/Symbol.hpp> #include <com/sun/star/chart2/XRegressionCurveCalculator.hpp> #include <com/sun/star/chart2/RelativePosition.hpp> +#include <com/sun/star/chart2/RelativeSize.hpp> #include <osl/diagnose.h> #include <tools/color.hxx> @@ -645,6 +646,26 @@ bool VDataSeries::isLabelCustomPos(sal_Int32 nPointIndex) const return bCustom; } +awt::Size VDataSeries::getLabelCustomSize(sal_Int32 nPointIndex) const +{ + awt::Size aSize(-1, -1); + try + { + RelativeSize aCustomLabelSize; + const uno::Reference<beans::XPropertySet> xPointProps(getPropertiesOfPoint(nPointIndex)); + if (xPointProps.is() && (xPointProps->getPropertyValue("CustomLabelSize") >>= aCustomLabelSize)) + { + aSize.Width = static_cast<sal_Int32>(aCustomLabelSize.Primary * m_aReferenceSize.Width); + aSize.Height = static_cast<sal_Int32>(aCustomLabelSize.Secondary * m_aReferenceSize.Height); + } + } + catch (const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + return aSize; +} + double VDataSeries::getMinimumofAllDifferentYValues( sal_Int32 index ) const { double fMin = std::numeric_limits<double>::infinity(); diff --git a/offapi/com/sun/star/chart2/DataPointProperties.idl b/offapi/com/sun/star/chart2/DataPointProperties.idl index b2dd1163967a..7fe64e77ad9d 100644 --- a/offapi/com/sun/star/chart2/DataPointProperties.idl +++ b/offapi/com/sun/star/chart2/DataPointProperties.idl @@ -317,6 +317,12 @@ service DataPointProperties @since LibreOffice 7.0 */ [optional, maybevoid, property] ::com::sun::star::chart2::RelativePosition CustomLabelPosition; + + /** Custom size associated with the CUSTOM label placement. + + @since LibreOffice 24.8 + */ + [optional, maybevoid, property] ::com::sun::star::chart2::RelativeSize CustomLabelSize; }; } ; // chart2 diff --git a/oox/source/drawingml/chart/seriesconverter.cxx b/oox/source/drawingml/chart/seriesconverter.cxx index db3916b74f63..2d07f26493ef 100644 --- a/oox/source/drawingml/chart/seriesconverter.cxx +++ b/oox/source/drawingml/chart/seriesconverter.cxx @@ -21,6 +21,7 @@ #include <com/sun/star/chart/DataLabelPlacement.hpp> #include <com/sun/star/chart2/RelativePosition.hpp> +#include <com/sun/star/chart2/RelativeSize.hpp> #include <com/sun/star/chart/ErrorBarStyle.hpp> #include <com/sun/star/chart2/DataPointLabel.hpp> #include <com/sun/star/drawing/Hatch.hpp> @@ -291,6 +292,8 @@ void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDat { RelativePosition aPos(mrModel.mxLayout->mfX, mrModel.mxLayout->mfY, css::drawing::Alignment_TOP_LEFT); aPropSet.setProperty(PROP_CustomLabelPosition, aPos); + const RelativeSize aSize(mrModel.mxLayout->mfW, mrModel.mxLayout->mfH); + aPropSet.setProperty(PROP_CustomLabelSize, aSize); sal_Int32 nPlacement = -1; if (bIsPie && aPropSet.getProperty(nPlacement, PROP_LabelPlacement) && nPlacement == css::chart::DataLabelPlacement::AVOID_OVERLAP) diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index b6fa29c090fe..a8764a432b5d 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -123,6 +123,7 @@ CursorPositionY CurveName CurveStyle CustomLabelPosition +CustomLabelSize CustomShapeGeometry D3DSceneAmbientColor D3DSceneLightColor2 |