summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBalazs Varga <balazs.varga991@gmail.com>2020-01-15 16:31:35 +0100
committerLászló Németh <nemeth@numbertext.org>2020-01-30 10:43:02 +0100
commit4223ff2be69f03e571464b0b09ad0d278918631b (patch)
tree7205f05cf9773f53f0ad4433703055794eb3f997
parente265037d6c655675416116b19882c3c29bb7bf40 (diff)
tdf#48436 Chart: add CustomLabelPosition UNO API property
and CUSTOM DataLabelPlacement to support custom data label positions, and its initial implementation: only UI support with OOXML import (tdf#130030), yet. Change-Id: I01d986071d78ae3e2a5f43d5711e9f60b8410c21 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86859 Tested-by: Jenkins Reviewed-by: László Németh <nemeth@numbertext.org> Tested-by: László Németh <nemeth@numbertext.org>
-rw-r--r--chart2/qa/extras/chart2import.cxx24
-rw-r--r--chart2/qa/extras/data/xlsx/testDataPointLabelCustomPos.xlsxbin0 -> 15069 bytes
-rw-r--r--chart2/source/controller/chartapiwrapper/LegendWrapper.cxx2
-rw-r--r--chart2/source/controller/inc/PositionAndSizeHelper.hxx2
-rw-r--r--chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx13
-rw-r--r--chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx11
-rw-r--r--chart2/source/controller/main/ChartController_Position.cxx2
-rw-r--r--chart2/source/controller/main/ChartController_Window.cxx2
-rw-r--r--chart2/source/controller/main/PositionAndSizeHelper.cxx30
-rw-r--r--chart2/source/model/main/DataPointProperties.cxx7
-rw-r--r--chart2/source/model/main/DataPointProperties.hxx3
-rw-r--r--chart2/source/tools/DataSeriesHelper.cxx2
-rw-r--r--chart2/source/tools/ObjectIdentifier.cxx1
-rw-r--r--chart2/source/view/charttypes/VSeriesPlotter.cxx10
-rw-r--r--chart2/source/view/inc/VDataSeries.hxx4
-rw-r--r--chart2/source/view/main/VDataSeries.cxx40
-rw-r--r--compilerplugins/clang/unusedenumconstants.writeonly.results2
-rw-r--r--offapi/com/sun/star/chart/DataLabelPlacement.idl1
-rw-r--r--offapi/com/sun/star/chart2/DataPointProperties.idl7
-rw-r--r--oox/source/drawingml/chart/seriesconverter.cxx31
-rw-r--r--oox/source/token/properties.txt1
-rw-r--r--sd/qa/unit/import-tests.cxx7
22 files changed, 177 insertions, 25 deletions
diff --git a/chart2/qa/extras/chart2import.cxx b/chart2/qa/extras/chart2import.cxx
index 223ca95b2b32..47b2e0354d51 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -12,6 +12,7 @@
#include <com/sun/star/chart2/DataPointLabel.hpp>
#include <com/sun/star/chart2/XDataPointCustomLabelField.hpp>
#include <com/sun/star/chart2/DataPointCustomLabelFieldType.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>
#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
@@ -151,6 +152,7 @@ public:
void testTdf122765();
void testTdf123206CustomLabelField();
void testTdf125444PercentageCustomLabel();
+ void testDataPointLabelCustomPos();
CPPUNIT_TEST_SUITE(Chart2ImportTest);
CPPUNIT_TEST(Fdo60083);
@@ -251,6 +253,7 @@ public:
CPPUNIT_TEST(testTdf122765);
CPPUNIT_TEST(testTdf123206CustomLabelField);
CPPUNIT_TEST(testTdf125444PercentageCustomLabel);
+ CPPUNIT_TEST(testDataPointLabelCustomPos);
CPPUNIT_TEST_SUITE_END();
@@ -2348,6 +2351,27 @@ void Chart2ImportTest::testTdf125444PercentageCustomLabel()
CPPUNIT_ASSERT_EQUAL(chart2::DataPointCustomLabelFieldType_PERCENTAGE, aLabelFields[2]->getFieldType());
}
+void Chart2ImportTest::testDataPointLabelCustomPos()
+{
+ load("/chart2/qa/extras/data/xlsx/", "testDataPointLabelCustomPos.xlsx");
+ uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet(0, mxComponent);
+ CPPUNIT_ASSERT(xChartDoc.is());
+ uno::Reference<chart2::XDataSeries> xDataSeries(getDataSeriesFromDoc(xChartDoc, 0));
+ CPPUNIT_ASSERT(xDataSeries.is());
+
+ uno::Reference<beans::XPropertySet> xPropertySet(xDataSeries->getDataPointByIndex(0), uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT(xPropertySet.is());
+
+ chart2::RelativePosition aCustomLabelPosition;
+ xPropertySet->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(aCustomLabelPosition.Primary, -0.14621409921671025, 1e-7);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(aCustomLabelPosition.Secondary, -5.2887961029923464E-2, 1e-7);
+
+ sal_Int32 aPlacement;
+ xPropertySet->getPropertyValue("LabelPlacement") >>= aPlacement;
+ CPPUNIT_ASSERT_EQUAL(chart::DataLabelPlacement::OUTSIDE, aPlacement);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ImportTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/chart2/qa/extras/data/xlsx/testDataPointLabelCustomPos.xlsx b/chart2/qa/extras/data/xlsx/testDataPointLabelCustomPos.xlsx
new file mode 100644
index 000000000000..69f89ec0e4c2
--- /dev/null
+++ b/chart2/qa/extras/data/xlsx/testDataPointLabelCustomPos.xlsx
Binary files differ
diff --git a/chart2/source/controller/chartapiwrapper/LegendWrapper.cxx b/chart2/source/controller/chartapiwrapper/LegendWrapper.cxx
index e4059c6d4b74..4dce225ba570 100644
--- a/chart2/source/controller/chartapiwrapper/LegendWrapper.cxx
+++ b/chart2/source/controller/chartapiwrapper/LegendWrapper.cxx
@@ -309,7 +309,7 @@ void SAL_CALL LegendWrapper::setSize( const awt::Size& aSize )
awt::Rectangle aNewPositionAndSize(aPos.X,aPos.Y,aSize.Width,aSize.Height);
PositionAndSizeHelper::moveObject( OBJECTTYPE_LEGEND
- , xProp, aNewPositionAndSize, aPageRectangle );
+ , xProp, aNewPositionAndSize, awt::Rectangle(), aPageRectangle );
}
}
diff --git a/chart2/source/controller/inc/PositionAndSizeHelper.hxx b/chart2/source/controller/inc/PositionAndSizeHelper.hxx
index f65b333c3407..964eebfb03cc 100644
--- a/chart2/source/controller/inc/PositionAndSizeHelper.hxx
+++ b/chart2/source/controller/inc/PositionAndSizeHelper.hxx
@@ -34,11 +34,13 @@ public:
static bool moveObject( ObjectType eObjectType
, const css::uno::Reference< css::beans::XPropertySet >& xObjectProp
, const css::awt::Rectangle& rNewPositionAndSize
+ , const css::awt::Rectangle& rOldPositionAndSize
, const css::awt::Rectangle& rPageRectangle );
static bool moveObject( const OUString& rObjectCID
, const css::uno::Reference< css::frame::XModel >& xChartModel
, const css::awt::Rectangle& rNewPositionAndSize
+ , const css::awt::Rectangle& rOldPositionAndSize
, const css::awt::Rectangle& rPageRectangle );
};
diff --git a/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx
index 43721c24502a..aab6be665814 100644
--- a/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx
+++ b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx
@@ -31,9 +31,11 @@
#include <ChartTypeHelper.hxx>
#include <unonames.hxx>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
#include <com/sun/star/chart2/AxisType.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
#include <com/sun/star/chart2/Symbol.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <svx/xflclit.hxx>
@@ -409,6 +411,7 @@ bool DataPointItemConverter::ApplySpecialItem(
{
sal_Int32 nNew = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue();
sal_Int32 nOld =0;
+ RelativePosition aCustomLabelPosition;
if( !(GetPropertySet()->getPropertyValue( "LabelPlacement" ) >>= nOld) )
{
if( m_aAvailableLabelPlacements.hasElements() )
@@ -424,9 +427,10 @@ bool DataPointItemConverter::ApplySpecialItem(
bChanged = true;
}
}
- else if( nOld!=nNew )
+ else if( nOld!=nNew || (GetPropertySet()->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition) )
{
- GetPropertySet()->setPropertyValue( "LabelPlacement" , uno::Any( nNew ));
+ GetPropertySet()->setPropertyValue("LabelPlacement", uno::Any(nNew));
+ GetPropertySet()->setPropertyValue("CustomLabelPosition", uno::Any());
bChanged = true;
}
}
@@ -641,7 +645,10 @@ void DataPointItemConverter::FillSpecialItem(
try
{
sal_Int32 nPlacement=0;
- if( GetPropertySet()->getPropertyValue( "LabelPlacement" ) >>= nPlacement )
+ RelativePosition aCustomLabelPosition;
+ if( !m_bOverwriteLabelsForAttributedDataPointsAlso && (GetPropertySet()->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition) )
+ rOutItemSet.Put(SfxInt32Item(nWhichId, css::chart::DataLabelPlacement::CUSTOM));
+ else if( GetPropertySet()->getPropertyValue( "LabelPlacement" ) >>= nPlacement )
rOutItemSet.Put( SfxInt32Item( nWhichId, nPlacement ));
else if( m_aAvailableLabelPlacements.hasElements() )
rOutItemSet.Put( SfxInt32Item( nWhichId, m_aAvailableLabelPlacements[0] ));
diff --git a/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx b/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx
index 70dc31a46b92..f5c9d8a0ce4d 100644
--- a/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx
+++ b/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx
@@ -37,9 +37,11 @@
#include <tools/diagnose_ex.h>
#include <vcl/graph.hxx>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
#include <com/sun/star/chart2/AxisType.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
#include <com/sun/star/chart2/Symbol.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
#include <memory>
using namespace com::sun::star;
@@ -370,6 +372,7 @@ bool TextLabelItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxIte
{
sal_Int32 nNew = static_cast<const SfxInt32Item&>(rItemSet.Get(nWhichId)).GetValue();
sal_Int32 nOld = 0;
+ RelativePosition aCustomLabelPosition;
if (!(GetPropertySet()->getPropertyValue("LabelPlacement") >>= nOld))
{
if (maAvailableLabelPlacements.hasElements())
@@ -385,9 +388,10 @@ bool TextLabelItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxIte
bChanged = true;
}
}
- else if (nOld != nNew)
+ else if (nOld != nNew || (GetPropertySet()->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition))
{
GetPropertySet()->setPropertyValue("LabelPlacement", uno::Any(nNew));
+ GetPropertySet()->setPropertyValue("CustomLabelPosition", uno::Any());
bChanged = true;
}
}
@@ -591,7 +595,10 @@ void TextLabelItemConverter::FillSpecialItem( sal_uInt16 nWhichId, SfxItemSet& r
try
{
sal_Int32 nPlacement = 0;
- if (GetPropertySet()->getPropertyValue("LabelPlacement") >>= nPlacement)
+ RelativePosition aCustomLabelPosition;
+ if (!mbDataSeries && (GetPropertySet()->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition))
+ rOutItemSet.Put(SfxInt32Item(nWhichId, css::chart::DataLabelPlacement::CUSTOM));
+ else if (GetPropertySet()->getPropertyValue("LabelPlacement") >>= nPlacement)
rOutItemSet.Put(SfxInt32Item(nWhichId, nPlacement));
else if (maAvailableLabelPlacements.hasElements())
rOutItemSet.Put(SfxInt32Item(nWhichId, maAvailableLabelPlacements[0]));
diff --git a/chart2/source/controller/main/ChartController_Position.cxx b/chart2/source/controller/main/ChartController_Position.cxx
index 184c37e108ed..32c4bd78522e 100644
--- a/chart2/source/controller/main/ChartController_Position.cxx
+++ b/chart2/source/controller/main/ChartController_Position.cxx
@@ -194,7 +194,7 @@ void ChartController::executeDispatch_PositionAndSize(const ::css::uno::Sequence
}
bool bMoved = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID(), getModel()
- , aObjectRect, aPageRect );
+ , aObjectRect, awt::Rectangle(), aPageRect );
if( bMoved || bChanged )
aUndoGuard.commit();
}
diff --git a/chart2/source/controller/main/ChartController_Window.cxx b/chart2/source/controller/main/ChartController_Window.cxx
index 9266e61005c7..c7b753dda1dc 100644
--- a/chart2/source/controller/main/ChartController_Window.cxx
+++ b/chart2/source/controller/main/ChartController_Window.cxx
@@ -836,6 +836,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
if( pObj )
{
tools::Rectangle aObjectRect = pObj->GetSnapRect();
+ tools::Rectangle aOldObjectRect = pObj->GetLastBoundRect();
awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) );
tools::Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height );
@@ -868,6 +869,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
bool bMoved = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
, getModel()
, awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight())
+ , awt::Rectangle(aOldObjectRect.getX(), aOldObjectRect.getY(), 0, 0)
, awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) );
if( bMoved || bChanged )
diff --git a/chart2/source/controller/main/PositionAndSizeHelper.cxx b/chart2/source/controller/main/PositionAndSizeHelper.cxx
index d9100c839a14..c1e0e14441bd 100644
--- a/chart2/source/controller/main/PositionAndSizeHelper.cxx
+++ b/chart2/source/controller/main/PositionAndSizeHelper.cxx
@@ -36,6 +36,7 @@ using namespace ::com::sun::star::chart2;
bool PositionAndSizeHelper::moveObject( ObjectType eObjectType
, const uno::Reference< beans::XPropertySet >& xObjectProp
, const awt::Rectangle& rNewPositionAndSize
+ , const awt::Rectangle& rOldPositionAndSize
, const awt::Rectangle& rPageRectangle
)
{
@@ -59,6 +60,32 @@ bool PositionAndSizeHelper::moveObject( ObjectType eObjectType
aRelativePosition.Secondary = (double(aPos.Y())+double(aObjectRect.getHeight())/2.0)/double(aPageRect.getHeight());
xObjectProp->setPropertyValue( "RelativePosition", uno::Any(aRelativePosition) );
}
+ else if( eObjectType == OBJECTTYPE_DATA_LABEL )
+ {
+ RelativePosition aAbsolutePosition;
+ RelativePosition aCustomLabelPosition;
+ aAbsolutePosition.Primary = double(rOldPositionAndSize.X) / double(aPageRect.getWidth());
+ aAbsolutePosition.Secondary = double(rOldPositionAndSize.Y) / double(aPageRect.getHeight());
+
+ if( xObjectProp->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition )
+ {
+ aAbsolutePosition.Primary -= aCustomLabelPosition.Primary;
+ aAbsolutePosition.Secondary -= aCustomLabelPosition.Secondary;
+ }
+
+ //the anchor point at the data label object is top/left
+ Point aPos = aObjectRect.TopLeft();
+ double fRotation = 0.0;
+ xObjectProp->getPropertyValue("TextRotation") >>= fRotation;
+ if( fRotation == 90.0 )
+ aPos = aObjectRect.BottomLeft();
+ else if( fRotation == 270.0 )
+ aPos = aObjectRect.TopRight();
+
+ aCustomLabelPosition.Primary = double(aPos.X()) / double(aPageRect.getWidth()) - aAbsolutePosition.Primary;
+ aCustomLabelPosition.Secondary = double(aPos.Y()) / double(aPageRect.getHeight()) - aAbsolutePosition.Secondary;
+ xObjectProp->setPropertyValue("CustomLabelPosition", uno::Any(aCustomLabelPosition));
+ }
else if( eObjectType==OBJECTTYPE_DATA_CURVE_EQUATION )
{
//@todo decide whether x is primary or secondary
@@ -128,6 +155,7 @@ bool PositionAndSizeHelper::moveObject( ObjectType eObjectType
bool PositionAndSizeHelper::moveObject( const OUString& rObjectCID
, const uno::Reference< frame::XModel >& xChartModel
, const awt::Rectangle& rNewPositionAndSize
+ , const awt::Rectangle& rOldPositionAndSize
, const awt::Rectangle& rPageRectangle
)
{
@@ -143,7 +171,7 @@ bool PositionAndSizeHelper::moveObject( const OUString& rObjectCID
if(!xObjectProp.is())
return false;
}
- return moveObject( eObjectType, xObjectProp, aNewPositionAndSize, rPageRectangle );
+ return moveObject( eObjectType, xObjectProp, aNewPositionAndSize, rOldPositionAndSize, rPageRectangle );
}
} //namespace chart
diff --git a/chart2/source/model/main/DataPointProperties.cxx b/chart2/source/model/main/DataPointProperties.cxx
index 1cb709d0559c..114fb4355069 100644
--- a/chart2/source/model/main/DataPointProperties.cxx
+++ b/chart2/source/model/main/DataPointProperties.cxx
@@ -28,6 +28,7 @@
#include <com/sun/star/drawing/LineDash.hpp>
#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/XDataPointCustomLabelField.hpp>
#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
@@ -410,6 +411,12 @@ void DataPointProperties::AddPropertiesToVector(
cppu::UnoType<uno::Sequence<uno::Reference<chart2::XDataPointCustomLabelField>>>::get(),
beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::MAYBEDEFAULT);
+
+ rOutProperties.emplace_back( "CustomLabelPosition",
+ PROP_DATAPOINT_LABEL_CUSTOM_POS,
+ cppu::UnoType<chart2::RelativePosition>::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 51f1d81a71b7..d591f13625f3 100644
--- a/chart2/source/model/main/DataPointProperties.hxx
+++ b/chart2/source/model/main/DataPointProperties.hxx
@@ -82,7 +82,8 @@ namespace DataPointProperties
PROP_DATAPOINT_LABEL_BORDER_DASH,
PROP_DATAPOINT_LABEL_BORDER_DASH_NAME,
PROP_DATAPOINT_LABEL_BORDER_TRANS,
- PROP_DATAPOINT_CUSTOM_LABEL_FIELDS
+ PROP_DATAPOINT_CUSTOM_LABEL_FIELDS,
+ PROP_DATAPOINT_LABEL_CUSTOM_POS
// additionally some properties from ::chart::LineProperties
};
diff --git a/chart2/source/tools/DataSeriesHelper.cxx b/chart2/source/tools/DataSeriesHelper.cxx
index 4b4c954b5e0e..d2b0b27e04fb 100644
--- a/chart2/source/tools/DataSeriesHelper.cxx
+++ b/chart2/source/tools/DataSeriesHelper.cxx
@@ -600,6 +600,8 @@ void setPropertyAlsoToAllAttributedDataPoints( const Reference< chart2::XDataSer
if(!xPointProp.is())
continue;
xPointProp->setPropertyValue( rPropertyName, rPropertyValue );
+ if( rPropertyName == "LabelPlacement" )
+ xPointProp->setPropertyValue("CustomLabelPosition", uno::Any());
}
}
}
diff --git a/chart2/source/tools/ObjectIdentifier.cxx b/chart2/source/tools/ObjectIdentifier.cxx
index 7b47967f1f9a..3c2c45a19e74 100644
--- a/chart2/source/tools/ObjectIdentifier.cxx
+++ b/chart2/source/tools/ObjectIdentifier.cxx
@@ -796,6 +796,7 @@ bool ObjectIdentifier::isDragableObject( const OUString& rClassifiedIdentifier )
case OBJECTTYPE_TITLE:
case OBJECTTYPE_LEGEND:
case OBJECTTYPE_DIAGRAM:
+ case OBJECTTYPE_DATA_LABEL:
case OBJECTTYPE_DATA_CURVE_EQUATION:
//case OBJECTTYPE_DIAGRAM_WALL:
bReturn = true;
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index f7e828425246..b6382943b418 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -707,7 +707,6 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
// in case text is rotated, the transformation property of the text
// shape is modified.
- const awt::Point aUnrotatedTextPos( xTextShape->getPosition() );
if( fRotationDegrees != 0.0 )
{
const double fDegreesPi( -basegfx::deg2rad(fRotationDegrees) );
@@ -717,8 +716,17 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
LabelPositionHelper::correctPositionForRotation( xTextShape, eAlignment, fRotationDegrees, true /*bRotateAroundCenter*/ );
}
+ awt::Point aTextShapePos(xTextShape->getPosition());
+ if( rDataSeries.isLabelCustomPos(nPointIndex) )
+ {
+ awt::Point aRelPos = rDataSeries.getLabelPosition(aTextShapePos, nPointIndex);
+ if( aRelPos.X != -1 )
+ xTextShape->setPosition(aRelPos);
+ }
+
// in case legend symbol has to be displayed, text shape position is
// slightly changed.
+ const awt::Point aUnrotatedTextPos(xTextShape->getPosition());
if( xSymbol.is() )
{
const awt::Point aOldTextPos( xTextShape->getPosition() );
diff --git a/chart2/source/view/inc/VDataSeries.hxx b/chart2/source/view/inc/VDataSeries.hxx
index b65ea66f1009..853b6757077b 100644
--- a/chart2/source/view/inc/VDataSeries.hxx
+++ b/chart2/source/view/inc/VDataSeries.hxx
@@ -24,6 +24,7 @@
#include <com/sun/star/chart2/StackingDirection.hpp>
#include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/Point.hpp>
#include <memory>
#include <map>
@@ -107,6 +108,9 @@ public:
sal_Int32 nPointIndex, const css::uno::Reference<css::chart2::XChartType>& xChartType,
bool bSwapXAndY ) const;
+ css::awt::Point getLabelPosition( css::awt::Point aTextShapePos, sal_Int32 nPointIndex ) const;
+ bool isLabelCustomPos( sal_Int32 nPointIndex ) const;
+
css::uno::Reference<css::beans::XPropertySet> getPropertiesOfPoint( sal_Int32 index ) const;
css::uno::Reference<css::beans::XPropertySet> getPropertiesOfSeries() const;
diff --git a/chart2/source/view/main/VDataSeries.cxx b/chart2/source/view/main/VDataSeries.cxx
index 867eb56dee11..33bf9bee481d 100644
--- a/chart2/source/view/main/VDataSeries.cxx
+++ b/chart2/source/view/main/VDataSeries.cxx
@@ -26,11 +26,13 @@
#include <RegressionCurveHelper.hxx>
#include <unonames.hxx>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
#include <com/sun/star/chart/MissingValueTreatment.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
#include <com/sun/star/chart2/Symbol.hpp>
#include <com/sun/star/chart2/XDataSeries.hpp>
#include <com/sun/star/chart2/XRegressionCurveCalculator.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
#include <rtl/math.hxx>
#include <osl/diagnose.h>
@@ -603,8 +605,6 @@ sal_Int32 VDataSeries::getLabelPlacement( sal_Int32 nPointIndex, const uno::Refe
if( xPointProps.is() )
xPointProps->getPropertyValue("LabelPlacement") >>= nLabelPlacement;
- //ensure that the set label placement is supported by this charttype
-
uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
xChartType, bSwapXAndY, m_xDataSeries ) );
@@ -628,6 +628,42 @@ sal_Int32 VDataSeries::getLabelPlacement( sal_Int32 nPointIndex, const uno::Refe
return nLabelPlacement;
}
+awt::Point VDataSeries::getLabelPosition( awt::Point aTextShapePos, sal_Int32 nPointIndex ) const
+{
+ awt::Point aPos(-1, -1);
+ try
+ {
+ RelativePosition aCustomLabelPosition;
+ uno::Reference< beans::XPropertySet > xPointProps(getPropertiesOfPoint(nPointIndex));
+ if( xPointProps.is() && (xPointProps->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition))
+ {
+ aPos.X = static_cast<sal_Int32>(aCustomLabelPosition.Primary * m_aReferenceSize.Width) + aTextShapePos.X;
+ aPos.Y = static_cast<sal_Int32>(aCustomLabelPosition.Secondary * m_aReferenceSize.Height) + aTextShapePos.Y;
+ }
+ }
+ catch (const uno::Exception&) {}
+
+ return aPos;
+}
+
+bool VDataSeries::isLabelCustomPos(sal_Int32 nPointIndex) const
+{
+ bool bCustom = false;
+ RelativePosition aCustomLabelPosition;
+ try
+ {
+ if( isAttributedDataPoint(nPointIndex) )
+ {
+ uno::Reference< beans::XPropertySet > xPointProps(m_xDataSeries->getDataPointByIndex(nPointIndex));
+ if( xPointProps.is() && (xPointProps->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition) )
+ bCustom = true;
+ }
+ }
+ catch (const uno::Exception&) {}
+
+ return bCustom;
+}
+
double VDataSeries::getMinimumofAllDifferentYValues( sal_Int32 index ) const
{
double fMin=0.0;
diff --git a/compilerplugins/clang/unusedenumconstants.writeonly.results b/compilerplugins/clang/unusedenumconstants.writeonly.results
index ff3da7eee610..313ef966c1a7 100644
--- a/compilerplugins/clang/unusedenumconstants.writeonly.results
+++ b/compilerplugins/clang/unusedenumconstants.writeonly.results
@@ -728,6 +728,8 @@ chart2/source/model/main/DataPointProperties.hxx:84
enum chart::DataPointProperties::(anonymous at /media/disk2/libo4/chart2/source/model/main/DataPointProperties.hxx:36:5) PROP_DATAPOINT_LABEL_BORDER_TRANS
chart2/source/model/main/DataPointProperties.hxx:85
enum chart::DataPointProperties::(anonymous at /media/disk2/libo4/chart2/source/model/main/DataPointProperties.hxx:36:5) PROP_DATAPOINT_CUSTOM_LABEL_FIELDS
+chart2/source/model/main/DataPointProperties.hxx:86
+ enum chart::DataPointProperties::(anonymous at /media/disk2/libo4/chart2/source/model/main/DataPointProperties.hxx:36:5) PROP_DATAPOINT_LABEL_CUSTOM_POS
chart2/source/model/main/DataSeriesProperties.hxx:37
enum chart::DataSeriesProperties::(anonymous at /media/disk2/libo4/chart2/source/model/main/DataSeriesProperties.hxx:34:5) PROP_DATASERIES_STACKING_DIRECTION
chart2/source/model/main/DataSeriesProperties.hxx:38
diff --git a/offapi/com/sun/star/chart/DataLabelPlacement.idl b/offapi/com/sun/star/chart/DataLabelPlacement.idl
index ca1cf02d6a25..fbdc19fcce8f 100644
--- a/offapi/com/sun/star/chart/DataLabelPlacement.idl
+++ b/offapi/com/sun/star/chart/DataLabelPlacement.idl
@@ -41,6 +41,7 @@ published constants DataLabelPlacement
const long INSIDE = 10;
const long OUTSIDE = 11;
const long NEAR_ORIGIN = 12;
+ const long CUSTOM = 13;
};
diff --git a/offapi/com/sun/star/chart2/DataPointProperties.idl b/offapi/com/sun/star/chart2/DataPointProperties.idl
index e2230a5f7630..a8725651c00a 100644
--- a/offapi/com/sun/star/chart2/DataPointProperties.idl
+++ b/offapi/com/sun/star/chart2/DataPointProperties.idl
@@ -32,6 +32,7 @@
#include <com/sun/star/chart2/DataPointLabel.idl>
#include <com/sun/star/chart2/Symbol.idl>
#include <com/sun/star/chart2/XFormattedString2.idl>
+#include <com/sun/star/chart2/RelativePosition.idl>
module com
{
@@ -327,6 +328,12 @@ service DataPointProperties
/** A value between 0 and 100 indicating the percentage how round an edge should be.
*/
[optional, maybevoid, property] short PercentDiagonal;
+
+ /** Custom position on the page associated to the CUSTOM label placement.
+
+ @since LibreOffice 6.5
+ */
+ [optional, maybevoid, property] ::com::sun::star::chart2::RelativePosition CustomLabelPosition;
};
} ; // chart2
diff --git a/oox/source/drawingml/chart/seriesconverter.cxx b/oox/source/drawingml/chart/seriesconverter.cxx
index 62f78a28e383..d47d897c5a91 100644
--- a/oox/source/drawingml/chart/seriesconverter.cxx
+++ b/oox/source/drawingml/chart/seriesconverter.cxx
@@ -20,6 +20,7 @@
#include <drawingml/chart/seriesconverter.hxx>
#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
#include <com/sun/star/chart2/XDataPointCustomLabelField.hpp>
@@ -273,22 +274,32 @@ void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDat
lclConvertLabelFormatting( aPropSet, getFormatter(), mrModel, rTypeGroup, false, bMSO2007Doc );
const TypeGroupInfo& rTypeInfo = rTypeGroup.getTypeInfo();
bool bIsPie = rTypeInfo.meTypeCategory == TYPECATEGORY_PIE;
- if( mrModel.mxLayout && !mrModel.mxLayout->mbAutoLayout && !bIsPie )
+
+ if( mrModel.mxLayout && !mrModel.mxLayout->mbAutoLayout )
{
- // bnc#694340 - nasty hack - chart2 cannot individually
- // place data labels, let's try to find a useful
- // compromise instead
- namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
- const sal_Int32 aPositionsLookupTable[] =
+ if( rTypeInfo.meTypeCategory == TYPECATEGORY_BAR )
+ {
+ // It is only works for BAR Chart, yet!!!
+ RelativePosition aPos(mrModel.mxLayout->mfX, mrModel.mxLayout->mfY, css::drawing::Alignment_TOP_LEFT);
+ aPropSet.setProperty(PROP_CustomLabelPosition, aPos);
+ }
+ else if( !bIsPie )
+ {
+ // bnc#694340 - nasty hack - chart2 cannot individually
+ // place data labels, let's try to find a useful
+ // compromise instead
+ namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
+ const sal_Int32 aPositionsLookupTable[] =
{
csscd::TOP_LEFT, csscd::TOP, csscd::TOP_RIGHT,
csscd::LEFT, csscd::CENTER, csscd::RIGHT,
csscd::BOTTOM_LEFT, csscd::BOTTOM, csscd::BOTTOM_RIGHT
};
- const int simplifiedX = lclGetPositionX(mrModel.mxLayout->mfX);
- const int simplifiedY = lclGetPositionY(mrModel.mxLayout->mfY);
- aPropSet.setProperty( PROP_LabelPlacement,
- aPositionsLookupTable[ simplifiedX+1 + 3*(simplifiedY+1) ] );
+ const int simplifiedX = lclGetPositionX(mrModel.mxLayout->mfX);
+ const int simplifiedY = lclGetPositionY(mrModel.mxLayout->mfY);
+ aPropSet.setProperty(PROP_LabelPlacement,
+ aPositionsLookupTable[simplifiedX + 1 + 3 * (simplifiedY + 1)]);
+ }
}
if (mrModel.mxShapeProp)
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index b7a76058d688..de9cd886643a 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -113,6 +113,7 @@ CursorPositionX
CursorPositionY
CurveName
CurveStyle
+CustomLabelPosition
CustomShapeGeometry
D3DSceneAmbientColor
D3DSceneLightColor2
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 61c74879a6db..9eff839c2865 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -2614,24 +2614,25 @@ void SdImportTest::testTdf114821()
uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Series count", static_cast<sal_Int32>( 1 ), aSeriesSeq.getLength() );
+ // These Labels have custom position, so the exported LabelPlacement (reference point) by MSO is OUTSIDE/OUTEND
// Check the first label
const css::uno::Reference< css::beans::XPropertySet >& rPropSet0( aSeriesSeq[0]->getDataPointByIndex( 0 ) );
CPPUNIT_ASSERT( rPropSet0.is() );
sal_Int32 aPlacement;
rPropSet0->getPropertyValue( "LabelPlacement" ) >>= aPlacement;
- CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::TOP, aPlacement );
+ CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::OUTSIDE, aPlacement );
// Check the second label
const css::uno::Reference< css::beans::XPropertySet >& rPropSet1( aSeriesSeq[0]->getDataPointByIndex( 1 ) );
CPPUNIT_ASSERT( rPropSet1.is() );
rPropSet1->getPropertyValue( "LabelPlacement" ) >>= aPlacement;
- CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::CENTER, aPlacement );
+ CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::OUTSIDE, aPlacement );
// Check the third label
const css::uno::Reference< css::beans::XPropertySet >& rPropSet2( aSeriesSeq[0]->getDataPointByIndex( 2 ) );
CPPUNIT_ASSERT( rPropSet2.is() );
rPropSet2->getPropertyValue( "LabelPlacement") >>= aPlacement;
- CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::TOP, aPlacement );
+ CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::OUTSIDE, aPlacement );
xDocShRef->DoClose();
}