summaryrefslogtreecommitdiff
path: root/chart2/source
diff options
context:
space:
mode:
authorMarco Cecchetti <marco.cecchetti@collabora.com>2015-07-19 18:18:00 +0200
committerAndras Timar <andras.timar@collabora.com>2015-09-09 07:41:51 +0000
commit9ed1dd01be8afa0961e388a79e9ff4c1235820c2 (patch)
tree366cad6bae91e791be462e4c03f499ab0ba3e2f2 /chart2/source
parent79bc956e7f44b762bfd6560e5a9c9812fa3dcf4d (diff)
tdf#90839: support for wrapped text in data labels and for centered data value
Now in a pie chart the text of a label can be wrapped, the wrapping is automatic and the maximum text width is fixed to almost half the pie radius. This feature is used to import correctly the relative text wrapping property provided by MSO. Moreover the data value and percent value of a label are now centered horizontally, respect with the label text. Conflicts: chart2/qa/extras/xshape/chart2xshape.cxx Change-Id: Ie10d6184365436f763cd9693a5bbefcfa9b3862b Reviewed-on: https://gerrit.libreoffice.org/17193 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'chart2/source')
-rw-r--r--chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx8
-rw-r--r--chart2/source/controller/dialogs/res_DataLabel.cxx8
-rw-r--r--chart2/source/controller/dialogs/res_DataLabel.hxx1
-rw-r--r--chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx46
-rw-r--r--chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx44
-rw-r--r--chart2/source/inc/chartview/ChartSfxItemIds.hxx13
-rw-r--r--chart2/source/model/main/DataPointProperties.cxx8
-rw-r--r--chart2/source/model/main/DataPointProperties.hxx1
-rw-r--r--chart2/source/view/charttypes/PieChart.cxx29
-rw-r--r--chart2/source/view/charttypes/VSeriesPlotter.cxx139
-rw-r--r--chart2/source/view/inc/AbstractShapeFactory.hxx9
-rw-r--r--chart2/source/view/inc/OpenglShapeFactory.hxx9
-rw-r--r--chart2/source/view/inc/ShapeFactory.hxx36
-rw-r--r--chart2/source/view/inc/VSeriesPlotter.hxx5
-rw-r--r--chart2/source/view/main/ChartItemPool.cxx1
-rw-r--r--chart2/source/view/main/OpenglShapeFactory.cxx15
-rw-r--r--chart2/source/view/main/ShapeFactory.cxx103
17 files changed, 436 insertions, 39 deletions
diff --git a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx
index 4c6c5b563d28..2b6c2da72882 100644
--- a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx
+++ b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx
@@ -81,6 +81,7 @@ enum
PROP_SERIES_NUMBERFORMAT,
PROP_SERIES_LINK_NUMBERFORMAT_TO_SOURCE,
PROP_SERIES_PERCENTAGE_NUMBERFORMAT,
+ PROP_SERIES_DATAPOINT_TEXT_WORD_WRAP,
PROP_SERIES_DATAPOINT_LABEL_PLACEMENT,
//other series properties
PROP_SERIES_ATTACHED_AXIS,
@@ -138,6 +139,13 @@ void lcl_AddPropertiesToVector_PointProperties(
| beans::PropertyAttribute::MAYBEVOID ));
rOutProperties.push_back(
+ Property( "TextWordWrap",
+ PROP_SERIES_DATAPOINT_TEXT_WORD_WRAP,
+ cppu::UnoType<bool>::get(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEVOID ));
+
+ rOutProperties.push_back(
Property( "LabelPlacement",
PROP_SERIES_DATAPOINT_LABEL_PLACEMENT,
cppu::UnoType<sal_Int32>::get(),
diff --git a/chart2/source/controller/dialogs/res_DataLabel.cxx b/chart2/source/controller/dialogs/res_DataLabel.cxx
index 0c532e081d9f..591b8fa3bf51 100644
--- a/chart2/source/controller/dialogs/res_DataLabel.cxx
+++ b/chart2/source/controller/dialogs/res_DataLabel.cxx
@@ -105,6 +105,7 @@ DataLabelResources::DataLabelResources(VclBuilderContainer* pWindow, vcl::Window
pWindow->get(m_pFT_NumberFormatForPercent,"STR_DLG_NUMBERFORMAT_FOR_PERCENTAGE_VALUE");
pWindow->get(m_pCBCategory, "CB_CATEGORY");
pWindow->get(m_pCBSymbol, "CB_SYMBOL");
+ pWindow->get(m_pCBWrapText, "CB_WRAP_TEXT");
pWindow->get(m_pBxLabelPlacement, "boxPLACEMENT");
pWindow->get(m_pLB_LabelPlacement, "LB_LABEL_PLACEMENT");
@@ -155,6 +156,7 @@ DataLabelResources::DataLabelResources(VclBuilderContainer* pWindow, vcl::Window
m_pCBPercent->SetClickHdl( LINK( this, DataLabelResources, CheckHdl ));
m_pCBCategory->SetClickHdl( LINK( this, DataLabelResources, CheckHdl ));
m_pCBSymbol->SetClickHdl( LINK( this, DataLabelResources, CheckHdl ));
+ m_pCBWrapText->SetClickHdl( LINK( this, DataLabelResources, CheckHdl ));
m_bNumberFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_SOURCE, m_nNumberFormatForValue, m_bSourceFormatForValue, m_bSourceFormatMixedState );
m_bPercentFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SCHATTR_PERCENT_NUMBERFORMAT_VALUE, SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, m_nNumberFormatForPercent, m_bSourceFormatForPercent , m_bPercentSourceMixedState);
@@ -238,6 +240,9 @@ void DataLabelResources::EnableControls()
m_pCBSymbol->Enable( m_pCBNumber->IsChecked() || (m_pCBPercent->IsChecked() && m_pCBPercent->IsEnabled())
|| m_pCBCategory->IsChecked() );
+ m_pCBWrapText->Enable( m_pCBNumber->IsChecked() || (m_pCBPercent->IsChecked() && m_pCBPercent->IsEnabled())
+ || m_pCBCategory->IsChecked() );
+
// Enable or disable separator, placement and direction based on the check
// box states. Note that the check boxes are tri-state.
{
@@ -289,6 +294,8 @@ bool DataLabelResources::FillItemSet( SfxItemSet* rOutAttrs ) const
rOutAttrs->Put( SfxBoolItem( SCHATTR_DATADESCR_SHOW_CATEGORY, m_pCBCategory->IsChecked() ) );
if( m_pCBSymbol->GetState()!= TRISTATE_INDET )
rOutAttrs->Put( SfxBoolItem( SCHATTR_DATADESCR_SHOW_SYMBOL, m_pCBSymbol->IsChecked()) );
+ if( m_pCBSymbol->GetState()!= TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_DATADESCR_WRAP_TEXT, m_pCBWrapText->IsChecked()) );
OUString aSep = m_aEntryMap[m_pLB_Separator->GetSelectEntryPos()];
rOutAttrs->Put( SfxStringItem( SCHATTR_DATADESCR_SEPARATOR, aSep) );
@@ -321,6 +328,7 @@ void DataLabelResources::Reset(const SfxItemSet& rInAttrs)
lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_SHOW_PERCENTAGE, *m_pCBPercent );
lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_SHOW_CATEGORY, *m_pCBCategory );
lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_SHOW_SYMBOL, *m_pCBSymbol );
+ lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_WRAP_TEXT, *m_pCBWrapText );
m_bNumberFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_SOURCE, m_nNumberFormatForValue, m_bSourceFormatForValue, m_bSourceFormatMixedState );
m_bPercentFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SCHATTR_PERCENT_NUMBERFORMAT_VALUE, SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, m_nNumberFormatForPercent, m_bSourceFormatForPercent , m_bPercentSourceMixedState);
diff --git a/chart2/source/controller/dialogs/res_DataLabel.hxx b/chart2/source/controller/dialogs/res_DataLabel.hxx
index acfc93a30dde..e716320072dc 100644
--- a/chart2/source/controller/dialogs/res_DataLabel.hxx
+++ b/chart2/source/controller/dialogs/res_DataLabel.hxx
@@ -52,6 +52,7 @@ private:
VclPtr<FixedText> m_pFT_NumberFormatForPercent;
VclPtr<CheckBox> m_pCBCategory;
VclPtr<CheckBox> m_pCBSymbol;
+ VclPtr<CheckBox> m_pCBWrapText;
VclPtr<VclHBox> m_pSeparatorResources;
VclPtr<ListBox> m_pLB_Separator;
diff --git a/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx
index 6c3e874afe64..b3e9bd271dcb 100644
--- a/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx
+++ b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx
@@ -376,6 +376,37 @@ bool DataPointItemConverter::ApplySpecialItem(
}
break;
+ case SCHATTR_DATADESCR_WRAP_TEXT:
+ {
+
+ try
+ {
+ bool bNew = static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )).GetValue();
+ bool bOld = false;
+ GetPropertySet()->getPropertyValue( "TextWordWrap" ) >>= bOld;
+ if( m_bOverwriteLabelsForAttributedDataPointsAlso )
+ {
+ Reference< chart2::XDataSeries > xSeries( GetPropertySet(), uno::UNO_QUERY);
+ if( bOld!=bNew ||
+ DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries, "TextWordWrap", uno::makeAny( bOld ) ) )
+ {
+ DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "TextWordWrap", uno::makeAny( bNew ) );
+ bChanged = true;
+ }
+ }
+ else if( bOld!=bNew )
+ {
+ GetPropertySet()->setPropertyValue( "TextWordWrap", uno::makeAny( bNew ));
+ bChanged = true;
+ }
+ }
+ catch( const uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ }
+ break;
+
case SCHATTR_DATADESCR_PLACEMENT:
{
@@ -596,6 +627,21 @@ void DataPointItemConverter::FillSpecialItem(
}
break;
+ case SCHATTR_DATADESCR_WRAP_TEXT:
+ {
+ bool bValue = false;
+ try
+ {
+ GetPropertySet()->getPropertyValue( "TextWordWrap" ) >>= bValue;
+ rOutItemSet.Put( SfxBoolItem( nWhichId, bValue ));
+ }
+ catch( const uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ }
+ break;
+
case SCHATTR_DATADESCR_PLACEMENT:
{
try
diff --git a/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx b/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx
index faee4a61d291..2731f709bbaf 100644
--- a/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx
+++ b/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx
@@ -335,6 +335,36 @@ bool TextLabelItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxIte
}
}
break;
+ case SCHATTR_DATADESCR_WRAP_TEXT:
+ {
+
+ try
+ {
+ bool bNew = static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )).GetValue();
+ bool bOld = false;
+ GetPropertySet()->getPropertyValue( "TextWordWrap" ) >>= bOld;
+ if( mbDataSeries )
+ {
+ Reference< chart2::XDataSeries > xSeries( GetPropertySet(), uno::UNO_QUERY);
+ if( bOld!=bNew ||
+ DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries, "TextWordWrap", uno::makeAny( bOld ) ) )
+ {
+ DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "TextWordWrap", uno::makeAny( bNew ) );
+ bChanged = true;
+ }
+ }
+ else if( bOld!=bNew )
+ {
+ GetPropertySet()->setPropertyValue( "TextWordWrap", uno::makeAny( bNew ));
+ bChanged = true;
+ }
+ }
+ catch( const uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ }
+ break;
case SCHATTR_DATADESCR_PLACEMENT:
{
try
@@ -544,6 +574,20 @@ void TextLabelItemConverter::FillSpecialItem( sal_uInt16 nWhichId, SfxItemSet& r
}
}
break;
+ case SCHATTR_DATADESCR_WRAP_TEXT:
+ {
+ bool bValue = false;
+ try
+ {
+ GetPropertySet()->getPropertyValue( "TextWordWrap" ) >>= bValue;
+ rOutItemSet.Put( SfxBoolItem( nWhichId, bValue ));
+ }
+ catch( const uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ }
+ break;
case SCHATTR_DATADESCR_PLACEMENT:
{
try
diff --git a/chart2/source/inc/chartview/ChartSfxItemIds.hxx b/chart2/source/inc/chartview/ChartSfxItemIds.hxx
index 7481cc88169a..3bce731ebdce 100644
--- a/chart2/source/inc/chartview/ChartSfxItemIds.hxx
+++ b/chart2/source/inc/chartview/ChartSfxItemIds.hxx
@@ -29,12 +29,13 @@
#define SCHATTR_DATADESCR_SHOW_PERCENTAGE (SCHATTR_DATADESCR_START + 1)
#define SCHATTR_DATADESCR_SHOW_CATEGORY (SCHATTR_DATADESCR_START + 2)
#define SCHATTR_DATADESCR_SHOW_SYMBOL (SCHATTR_DATADESCR_START + 3)
-#define SCHATTR_DATADESCR_SEPARATOR (SCHATTR_DATADESCR_START + 4)
-#define SCHATTR_DATADESCR_PLACEMENT (SCHATTR_DATADESCR_START + 5)
-#define SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS (SCHATTR_DATADESCR_START + 6)
-#define SCHATTR_DATADESCR_NO_PERCENTVALUE (SCHATTR_DATADESCR_START + 7) //percentage values should not be offered
-#define SCHATTR_PERCENT_NUMBERFORMAT_VALUE (SCHATTR_DATADESCR_START + 8)
-#define SCHATTR_PERCENT_NUMBERFORMAT_SOURCE (SCHATTR_DATADESCR_START + 9)
+#define SCHATTR_DATADESCR_WRAP_TEXT (SCHATTR_DATADESCR_START + 4)
+#define SCHATTR_DATADESCR_SEPARATOR (SCHATTR_DATADESCR_START + 5)
+#define SCHATTR_DATADESCR_PLACEMENT (SCHATTR_DATADESCR_START + 6)
+#define SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS (SCHATTR_DATADESCR_START + 7)
+#define SCHATTR_DATADESCR_NO_PERCENTVALUE (SCHATTR_DATADESCR_START + 8) //percentage values should not be offered
+#define SCHATTR_PERCENT_NUMBERFORMAT_VALUE (SCHATTR_DATADESCR_START + 9)
+#define SCHATTR_PERCENT_NUMBERFORMAT_SOURCE (SCHATTR_DATADESCR_START + 10)
#define SCHATTR_DATADESCR_END SCHATTR_PERCENT_NUMBERFORMAT_SOURCE
//legend
diff --git a/chart2/source/model/main/DataPointProperties.cxx b/chart2/source/model/main/DataPointProperties.cxx
index 8c131837f449..3d04e961ceb1 100644
--- a/chart2/source/model/main/DataPointProperties.cxx
+++ b/chart2/source/model/main/DataPointProperties.cxx
@@ -414,6 +414,13 @@ void DataPointProperties::AddPropertiesToVector(
| beans::PropertyAttribute::MAYBEDEFAULT ));
rOutProperties.push_back(
+ Property( "TextWordWrap",
+ PROP_DATAPOINT_TEXT_WORD_WRAP,
+ cppu::UnoType<bool>::get(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+ rOutProperties.push_back(
Property( CHART_UNONAME_LABEL_SEP,
PROP_DATAPOINT_LABEL_SEPARATOR,
cppu::UnoType<OUString>::get(),
@@ -529,6 +536,7 @@ void DataPointProperties::AddDefaultsToMap(
sal_False // ShowLegendSymbol
));
+ PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DATAPOINT_TEXT_WORD_WRAP, false );
PropertyHelper::setPropertyValueDefault< OUString >( rOutMap, PROP_DATAPOINT_LABEL_SEPARATOR, " " );
PropertyHelper::setPropertyValueDefault<sal_Int32>(rOutMap, PROP_DATAPOINT_LABEL_BORDER_STYLE, drawing::LineStyle_NONE);
PropertyHelper::setEmptyPropertyValueDefault(rOutMap, PROP_DATAPOINT_LABEL_BORDER_COLOR);
diff --git a/chart2/source/model/main/DataPointProperties.hxx b/chart2/source/model/main/DataPointProperties.hxx
index f4fbf0e2d00e..e87c1a9d16c3 100644
--- a/chart2/source/model/main/DataPointProperties.hxx
+++ b/chart2/source/model/main/DataPointProperties.hxx
@@ -74,6 +74,7 @@ namespace DataPointProperties
// label
PROP_DATAPOINT_LABEL,
PROP_DATAPOINT_LABEL_SEPARATOR,
+ PROP_DATAPOINT_TEXT_WORD_WRAP,
PROP_DATAPOINT_LABEL_BORDER_STYLE,
PROP_DATAPOINT_LABEL_BORDER_COLOR,
PROP_DATAPOINT_LABEL_BORDER_WIDTH,
diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx
index c6e9379c605a..73f103007dd2 100644
--- a/chart2/source/view/charttypes/PieChart.cxx
+++ b/chart2/source/view/charttypes/PieChart.cxx
@@ -336,10 +336,28 @@ void PieChart::createTextLabelShape(
aScreenPosition2D.Y += aDirection.getY();
}
+ // compute outer pie radius
+ awt::Point aOuterCirclePoint = PlottingPositionHelper::transformSceneToScreenPosition(
+ m_pPosHelper->transformUnitCircleToScene(
+ 0,
+ rParam.mfUnitCircleOuterRadius,
+ 0 ),
+ m_xLogicTarget, m_pShapeFactory, m_nDimension );
+ basegfx::B2IVector aRadiusVector(
+ aOuterCirclePoint.X - aPieLabelInfo.aOrigin.getX(),
+ aOuterCirclePoint.Y - aPieLabelInfo.aOrigin.getY() );
+ double fSquaredPieRadius = aRadiusVector.scalar(aRadiusVector);
+ double fPieRadius = sqrt( fSquaredPieRadius );
+
+ // set the maximum text width to be used when text wrapping is enabled
+ double fTextMaximumFrameWidth = 0.8 * fPieRadius;
+ sal_Int32 nTextMaximumFrameWidth = ceil(fTextMaximumFrameWidth);
+
///the text shape for the label is created
double nVal = rSeries.getYValue(nPointIndex);
aPieLabelInfo.xTextShape = createDataLabel(
- xTextTarget, rSeries, nPointIndex, nVal, rParam.mfLogicYSum, aScreenPosition2D, eAlignment);
+ xTextTarget, rSeries, nPointIndex, nVal, rParam.mfLogicYSum,
+ aScreenPosition2D, eAlignment, 0, nTextMaximumFrameWidth);
///a new `PieLabelInfo` instance is initialized with all the info related to
///the current label in order to simplify later label position rearrangement;
@@ -1544,9 +1562,10 @@ bool PieChart::performLabelBestFitInnerPlacement(ShapeParam& rShapeParam, PieLab
basegfx::B2IVector aTranslationVector = aNewAnchorPoint - rPieLabelInfo.aFirstPosition;
// compute the new screen position and move the label
- awt::Point aNewPos( rPieLabelInfo.xLabelGroupShape->getPosition() );
- aNewPos.X += aTranslationVector.getX();
- aNewPos.Y += aTranslationVector.getY();
+ // XShape::getPosition returns the top left vertex of the b.b. of the shape
+ awt::Point aOldPos( rPieLabelInfo.xLabelGroupShape->getPosition() );
+ awt::Point aNewPos( aOldPos.X + aTranslationVector.getX(),
+ aOldPos.Y + aTranslationVector.getY() );
rPieLabelInfo.xLabelGroupShape->setPosition(aNewPos);
SAL_INFO( "chart2.pie.label.bestfit.inside",
@@ -1556,6 +1575,8 @@ bool PieChart::performLabelBestFitInnerPlacement(ShapeParam& rShapeParam, PieLab
SAL_INFO( "chart2.pie.label.bestfit.inside",
" translation vector = " << aTranslationVector );
SAL_INFO( "chart2.pie.label.bestfit.inside",
+ " old position = (" << aOldPos.X << "," << aOldPos.Y << ")" );
+ SAL_INFO( "chart2.pie.label.bestfit.inside",
" new position = (" << aNewPos.X << "," << aNewPos.Y << ")" );
return true;
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index 2fa557f42c48..7a8f1d28f708 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -66,6 +66,17 @@
#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+#include <com/sun/star/drawing/TextFitToSizeType.hpp>
+
#include <svx/unoshape.hxx>
#include <functional>
@@ -415,7 +426,8 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
, double fSumValue
, const awt::Point& rScreenPosition2D
, LabelAlignment eAlignment
- , sal_Int32 nOffset )
+ , sal_Int32 nOffset
+ , sal_Int32 nTextWidth )
{
uno::Reference< drawing::XShape > xTextShape;
@@ -476,10 +488,10 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
xSymbol.set( VSeriesPlotter::createLegendSymbolForPoint( aMaxSymbolExtent, rDataSeries, nPointIndex, xTarget_, m_xShapeFactory ) );
else
xSymbol.set( VSeriesPlotter::createLegendSymbolForSeries( aMaxSymbolExtent, rDataSeries, xTarget_, m_xShapeFactory ) );
-
}
+
//prepare text
- OUStringBuffer aText;
+ bool bTextWrap = false;
OUString aSeparator(" ");
double fRotationDegrees = 0.0;
try
@@ -487,6 +499,7 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
uno::Reference< beans::XPropertySet > xPointProps( rDataSeries.getPropertiesOfPoint( nPointIndex ) );
if(xPointProps.is())
{
+ xPointProps->getPropertyValue( "TextWordWrap" ) >>= bTextWrap;
xPointProps->getPropertyValue( "LabelSeparator" ) >>= aSeparator;
// Extract the optional text rotation through the
// "TextRotation" property attached to the passed data point.
@@ -498,12 +511,8 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
ASSERT_EXCEPTION( e );
}
- // check if data series entry percent value and absolute value have to
- // be appended to the text label, and what should be the separator
- // character (comma, space, new line). In case it is a new line we get
- // a multi-line label.
- bool bMultiLineLabel = aSeparator == "\n";
sal_Int32 nLineCountForSymbolsize = 0;
+ Sequence< OUString > aTextList(3);
{
if(pLabel->ShowCategoryName)
{
@@ -512,22 +521,14 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
Sequence< OUString > aCategories( m_pExplicitCategoriesProvider->getSimpleCategories() );
if( nPointIndex >= 0 && nPointIndex < aCategories.getLength() )
{
- aText.append( aCategories[nPointIndex] );
- ++nLineCountForSymbolsize;
+ aTextList[0] = aCategories[nPointIndex];
}
}
}
if(pLabel->ShowNumber)
{
- OUString aNumber = getLabelTextForValue(rDataSeries, nPointIndex, fValue, false);
- if( !aNumber.isEmpty() )
- {
- if(!aText.isEmpty())
- aText.append(aSeparator);
- aText.append(aNumber);
- ++nLineCountForSymbolsize;
- }
+ aTextList[1] = getLabelTextForValue(rDataSeries, nPointIndex, fValue, false);
}
if(pLabel->ShowNumberInPercent)
@@ -538,16 +539,18 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
if( fValue < 0 )
fValue*=-1.0;
- OUString aPercentage = getLabelTextForValue(rDataSeries, nPointIndex, fValue, true);
- if( !aPercentage.isEmpty() )
+ aTextList[2] = getLabelTextForValue(rDataSeries, nPointIndex, fValue, true);
+ }
+
+ for( sal_Int32 nN = 0; nN < 3; ++nN)
+ {
+ if( !aTextList[nN].isEmpty() )
{
- if(!aText.isEmpty())
- aText.append(aSeparator);
- aText.append(aPercentage);
++nLineCountForSymbolsize;
}
}
}
+
//prepare properties for multipropertyset-interface of shape
tNameSequence* pPropNames;
tAnySequence* pPropValues;
@@ -557,14 +560,94 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
// set text alignment for the text shape to be created.
LabelPositionHelper::changeTextAdjustment( *pPropValues, *pPropNames, eAlignment );
- //create text shape
- xTextShape = AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory)->
- createText( xTarget_, aText.makeStringAndClear()
- , *pPropNames, *pPropValues, AbstractShapeFactory::makeTransformation( aScreenPosition2D ) );
+ // check if data series entry percent value and absolute value have to
+ // be appended to the text label, and what should be the separator
+ // character (comma, space, new line). In case it is a new line we get
+ // a multi-line label.
+ bool bMultiLineLabel = ( aSeparator == "\n" );
+
+ if( bMultiLineLabel )
+ {
+ // prepare properties for each paragraph
+ // we want to have the value and percent value centered respect
+ // with the category name
+ Sequence< tNameSequence > aParaPropNames(3);
+ aParaPropNames[1].realloc(1);
+ aParaPropNames[1][0] = OUString( "ParaAdjust" );
+ aParaPropNames[2].realloc(1);
+ aParaPropNames[2][0] = OUString( "ParaAdjust" );
+
+ Sequence< tAnySequence > aParaPropValues(3);
+ aParaPropValues[1].realloc(1);
+ aParaPropValues[1][0] = uno::makeAny( style::ParagraphAdjust_CENTER );
+ aParaPropValues[2].realloc(1);
+ aParaPropValues[2][0] = uno::makeAny( style::ParagraphAdjust_CENTER );
+
+ //create text shape
+ xTextShape = AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory)->
+ createText( xTarget_, aTextList, aParaPropNames, aParaPropValues
+ , *pPropNames, *pPropValues, AbstractShapeFactory::makeTransformation( aScreenPosition2D ) );
+ }
+ else
+ {
+ // join text list elements
+ OUStringBuffer aText;
+ for( sal_Int32 nN = 0; nN < 3; ++nN)
+ {
+ if( !aTextList[nN].isEmpty() )
+ {
+ if( !aText.isEmpty() )
+ {
+ aText.append(aSeparator);
+ }
+ aText.append( aTextList[nN] );
+ }
+ }
+
+ //create text shape
+ xTextShape = AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory)->
+ createText( xTarget_, aText.makeStringAndClear()
+ , *pPropNames, *pPropValues, AbstractShapeFactory::makeTransformation( aScreenPosition2D ) );
+ }
if( !xTextShape.is() )
return xTextShape;
+ // we need to use a default value for the maximum width property ?
+ if( nTextWidth == 0 && bTextWrap )
+ {
+ sal_Int32 nMinSize =
+ (m_aPageReferenceSize.Height < m_aPageReferenceSize.Width)
+ ? m_aPageReferenceSize.Height
+ : m_aPageReferenceSize.Width;
+ nTextWidth = nMinSize / 3;
+ }
+
+ // in case text must be wrapped set the maximum width property
+ // for the text shape
+ if( nTextWidth != 0 && bTextWrap )
+ {
+ uno::Reference< beans::XPropertySet > xProp( xTextShape, uno::UNO_QUERY );
+ if( xProp.is() )
+ {
+ // compute the height of a line of text
+ if( !bMultiLineLabel || nLineCountForSymbolsize <= 0 )
+ {
+ nLineCountForSymbolsize = 1;
+ }
+ awt::Size aTextSize = xTextShape->getSize();
+ sal_Int32 aTextLineHeight = aTextSize.Height / nLineCountForSymbolsize;
+
+ // set maximum text width
+ uno::Any aTextMaximumFrameWidth = uno::makeAny( nTextWidth );
+ xProp->setPropertyValue( "TextMaximumFrameWidth", aTextMaximumFrameWidth );
+
+ // compute the total lines of text
+ aTextSize = xTextShape->getSize();
+ nLineCountForSymbolsize = aTextSize.Height / aTextLineHeight;
+ }
+ }
+
// in case text is rotated, the transformation property of the text
// shape is modified.
const awt::Point aUnrotatedTextPos( xTextShape->getPosition() );
@@ -586,7 +669,7 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
awt::Point aSymbolPosition( aUnrotatedTextPos );
awt::Size aSymbolSize( xSymbol->getSize() );
- awt::Size aTextSize( xTextShape->getSize() );
+ awt::Size aTextSize = xTextShape->getSize();
sal_Int32 nXDiff = aSymbolSize.Width + static_cast< sal_Int32 >( std::max( 100.0, fViewFontSize * 0.22 ) );//minimum 1mm
if( !bMultiLineLabel || nLineCountForSymbolsize <= 0 )
diff --git a/chart2/source/view/inc/AbstractShapeFactory.hxx b/chart2/source/view/inc/AbstractShapeFactory.hxx
index 020777dbb2bb..533ecee4e88d 100644
--- a/chart2/source/view/inc/AbstractShapeFactory.hxx
+++ b/chart2/source/view/inc/AbstractShapeFactory.hxx
@@ -200,6 +200,15 @@ public:
) = 0;
virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ createText( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
+ , const ::com::sun::star::uno::Sequence< OUString >& rTextParagraphs
+ , const ::com::sun::star::uno::Sequence< tNameSequence >& rParaPropNames
+ , const ::com::sun::star::uno::Sequence< tAnySequence >& rParaPropValues
+ , const tNameSequence& rPropNames
+ , const tAnySequence& rPropValues
+ , const ::com::sun::star::uno::Any& rATransformation ) = 0;
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
createText( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget2D,
const com::sun::star::awt::Size& rSize,
const com::sun::star::awt::Point& rPosition,
diff --git a/chart2/source/view/inc/OpenglShapeFactory.hxx b/chart2/source/view/inc/OpenglShapeFactory.hxx
index 9f0a360595dd..bab5cb239d24 100644
--- a/chart2/source/view/inc/OpenglShapeFactory.hxx
+++ b/chart2/source/view/inc/OpenglShapeFactory.hxx
@@ -149,6 +149,15 @@ public:
) SAL_OVERRIDE;
virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ createText( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
+ , const ::com::sun::star::uno::Sequence< OUString >& rTextParagraphs
+ , const ::com::sun::star::uno::Sequence< tNameSequence >& rParaPropNames
+ , const ::com::sun::star::uno::Sequence< tAnySequence >& rParaPropValues
+ , const tNameSequence& rPropNames
+ , const tAnySequence& rPropValues
+ , const ::com::sun::star::uno::Any& rATransformation ) SAL_OVERRIDE;
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
createText( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget2D,
const com::sun::star::awt::Size& rSize,
const com::sun::star::awt::Point& rPosition,
diff --git a/chart2/source/view/inc/ShapeFactory.hxx b/chart2/source/view/inc/ShapeFactory.hxx
index d7973da941dd..362b4d4d5de8 100644
--- a/chart2/source/view/inc/ShapeFactory.hxx
+++ b/chart2/source/view/inc/ShapeFactory.hxx
@@ -158,6 +158,42 @@ public:
, const ::com::sun::star::uno::Any& rATransformation
) SAL_OVERRIDE;
+ /** This method creates a text shape made up by a set of paragraphs.
+ * For each paragraph the related text style is passed to the method.
+ *
+ * @param xTarget
+ * where to append the new created text shape.
+ *
+ * @param rTextParagraphs
+ * the set of paragraphs which made up the text shape.
+ *
+ * @param rParaPropNames
+ * a collection of lists of text property names:
+ * there must be a list of text property names for each paragraph.
+ *
+ * @param rParaPropValues
+ * a collection of lists of text property values:
+ * there must be a list of text property values for each paragraph.
+ *
+ * @param rPropNames
+ * a list of text property names to be applied to the whole text shape.
+ *
+ * @param rPropValues
+ * a list of text property values to be applied to the whole text shape.
+ *
+ * @param rATransformation
+ * a transformation to be applied to the text shape as final step.
+ *
+ */
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ createText( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
+ , const ::com::sun::star::uno::Sequence< OUString >& rTextParagraphs
+ , const ::com::sun::star::uno::Sequence< tNameSequence >& rParaPropNames
+ , const ::com::sun::star::uno::Sequence< tAnySequence >& rParaPropValues
+ , const tNameSequence& rPropNames
+ , const tAnySequence& rPropValues
+ , const ::com::sun::star::uno::Any& rATransformation ) SAL_OVERRIDE;
+
virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
createText( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget2D,
const com::sun::star::awt::Size& rSize,
diff --git a/chart2/source/view/inc/VSeriesPlotter.hxx b/chart2/source/view/inc/VSeriesPlotter.hxx
index f0c1157bc520..96f0e76b6464 100644
--- a/chart2/source/view/inc/VSeriesPlotter.hxx
+++ b/chart2/source/view/inc/VSeriesPlotter.hxx
@@ -325,6 +325,8 @@ protected:
* the required alignment of the label.
* @param offset
* an optional offset depending on the label alignment.
+ * @param nTextWidth
+ * the maximum width of a text label (used for text wrapping).
*
* @return
* a reference to the created text shape.
@@ -338,7 +340,8 @@ protected:
, double fSumValue
, const ::com::sun::star::awt::Point& rScreenPosition2D
, LabelAlignment eAlignment=LABEL_ALIGN_CENTER
- , sal_Int32 nOffset=0 );
+ , sal_Int32 nOffset=0
+ , sal_Int32 nTextWidth = 0 );
/// This method returns a text string representation of the passed numeric
/// value by exploiting a NumberFormatterWrapper object.
diff --git a/chart2/source/view/main/ChartItemPool.cxx b/chart2/source/view/main/ChartItemPool.cxx
index 9ad6981697b4..e6f68a99f8d8 100644
--- a/chart2/source/view/main/ChartItemPool.cxx
+++ b/chart2/source/view/main/ChartItemPool.cxx
@@ -48,6 +48,7 @@ ChartItemPool::ChartItemPool():
ppPoolDefaults[SCHATTR_DATADESCR_SHOW_PERCENTAGE- SCHATTR_START] = new SfxBoolItem(SCHATTR_DATADESCR_SHOW_PERCENTAGE);
ppPoolDefaults[SCHATTR_DATADESCR_SHOW_CATEGORY - SCHATTR_START] = new SfxBoolItem(SCHATTR_DATADESCR_SHOW_CATEGORY);
ppPoolDefaults[SCHATTR_DATADESCR_SHOW_SYMBOL - SCHATTR_START] = new SfxBoolItem(SCHATTR_DATADESCR_SHOW_SYMBOL);
+ ppPoolDefaults[SCHATTR_DATADESCR_WRAP_TEXT - SCHATTR_START] = new SfxBoolItem(SCHATTR_DATADESCR_WRAP_TEXT);
ppPoolDefaults[SCHATTR_DATADESCR_SEPARATOR - SCHATTR_START] = new SfxStringItem(SCHATTR_DATADESCR_SEPARATOR," ");
ppPoolDefaults[SCHATTR_DATADESCR_PLACEMENT - SCHATTR_START] = new SfxInt32Item(SCHATTR_DATADESCR_PLACEMENT,0);
ppPoolDefaults[SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS - SCHATTR_START] = new SfxIntegerListItem(SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS, ::std::vector < sal_Int32 >() );
diff --git a/chart2/source/view/main/OpenglShapeFactory.cxx b/chart2/source/view/main/OpenglShapeFactory.cxx
index 5c9f756edd59..666ab98a8124 100644
--- a/chart2/source/view/main/OpenglShapeFactory.cxx
+++ b/chart2/source/view/main/OpenglShapeFactory.cxx
@@ -41,6 +41,7 @@
#include <com/sun/star/drawing/TextFitToSizeType.hpp>
#include <com/sun/star/drawing/TextureProjectionMode.hpp>
#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <editeng/unoprnms.hxx>
@@ -399,6 +400,20 @@ uno::Reference< drawing::XShape >
}
uno::Reference< drawing::XShape >
+ OpenglShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget
+ , const uno::Sequence< OUString >& rTextParagraphs
+ , const uno::Sequence< tNameSequence >& /*rParaPropNames*/
+ , const uno::Sequence< tAnySequence >& /*rParaPropValues*/
+ , const tNameSequence& rPropNames
+ , const tAnySequence& rPropValues
+ , const uno::Any& rATransformation )
+{
+ dummy::DummyText* pText = new dummy::DummyText( rTextParagraphs[0], 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 798691129bf1..7117fdd7b89e 100644
--- a/chart2/source/view/main/ShapeFactory.cxx
+++ b/chart2/source/view/main/ShapeFactory.cxx
@@ -41,7 +41,9 @@
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
#include <com/sun/star/drawing/TextureProjectionMode.hpp>
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <editeng/unoprnms.hxx>
@@ -2138,6 +2140,107 @@ uno::Reference< drawing::XShape >
}
uno::Reference< drawing::XShape >
+ ShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget
+ , const uno::Sequence< OUString >& rTextParagraphs
+ , const uno::Sequence< tNameSequence >& rParaPropNames
+ , const uno::Sequence< tAnySequence >& rParaPropValues
+ , const tNameSequence& rPropNames
+ , const tAnySequence& rPropValues
+ , const uno::Any& rATransformation )
+{
+ if( !xTarget.is() )
+ return 0;
+
+ if( !rTextParagraphs.hasElements() )
+ return 0;
+
+ sal_Int32 nNumberOfParagraphs = rTextParagraphs.getLength();
+
+ if( rParaPropNames.getLength() != nNumberOfParagraphs )
+ return 0;
+
+ if( rParaPropValues.getLength() != nNumberOfParagraphs )
+ return 0;
+
+ bool bNotEmpty = false;
+ for( sal_Int32 nN = 0; nN < nNumberOfParagraphs; ++nN )
+ {
+ if( !rTextParagraphs[nN].isEmpty() )
+ {
+ bNotEmpty = true;
+ break;
+ }
+ }
+ if( !bNotEmpty )
+ return 0;
+
+ //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( !rTextParagraphs[nN].isEmpty() )
+ {
+ xInsertCursor->gotoEnd(false);
+ if( bNotEmpty )
+ {
+ xText->insertString( xInsertCursor, "\n", false );
+ }
+ xSelectionCursor->gotoEnd(false);
+ xText->insertString( xInsertCursor, rTextParagraphs[nN], false );
+ bNotEmpty = true;
+ xSelectionCursor->gotoEnd(true); // select current paragraph
+ PropertyMapper::setMultiProperties( rParaPropNames[nN], rParaPropValues[nN], xSelectionProp );
+ }
+ }
+ }
+ }
+ }
+
+ if( !bNotEmpty )
+ return 0;
+
+ uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
+ if( xProp.is() )
+ {
+ //set whole text shape properties
+ PropertyMapper::setMultiProperties( rPropNames, rPropValues, xProp );
+
+ //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 )
+ {
+ ASSERT_EXCEPTION( e );
+ }
+ }
+ return xShape;
+}
+
+uno::Reference< drawing::XShape >
ShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget,
const awt::Size& rSize,
const awt::Point& rPos,