diff options
Diffstat (limited to 'chart2/source')
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, |