summaryrefslogtreecommitdiff
path: root/chart2/source/view/main/VLegend.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'chart2/source/view/main/VLegend.cxx')
-rw-r--r--chart2/source/view/main/VLegend.cxx207
1 files changed, 154 insertions, 53 deletions
diff --git a/chart2/source/view/main/VLegend.cxx b/chart2/source/view/main/VLegend.cxx
index 9a011498991b..59444ad05894 100644
--- a/chart2/source/view/main/VLegend.cxx
+++ b/chart2/source/view/main/VLegend.cxx
@@ -42,7 +42,7 @@
#include <com/sun/star/beans/XPropertyState.hpp>
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
#include <com/sun/star/drawing/LineJoint.hpp>
-#include <com/sun/star/chart2/LegendExpansion.hpp>
+#include <com/sun/star/chart/ChartLegendExpansion.hpp>
#include <com/sun/star/chart2/LegendPosition.hpp>
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <rtl/ustrbuf.hxx>
@@ -123,7 +123,6 @@ void lcl_getProperties(
const Reference< beans::XPropertySet > & xLegendProp,
tPropertyValues & rOutLineFillProperties,
tPropertyValues & rOutTextProperties,
- sal_Int32 nMaxLabelWidth,
const awt::Size & rReferenceSize )
{
// Get Line- and FillProperties from model legend
@@ -146,7 +145,7 @@ void lcl_getProperties(
aTextValueMap[ C2U("TextAutoGrowHeight") ] = uno::makeAny( sal_True );
aTextValueMap[ C2U("TextAutoGrowWidth") ] = uno::makeAny( sal_True );
aTextValueMap[ C2U("TextHorizontalAdjust") ] = uno::makeAny( eHorizAdjust );
- aTextValueMap[ C2U("TextMaximumFrameWidth") ] = uno::makeAny( nMaxLabelWidth );
+ aTextValueMap[ C2U("TextMaximumFrameWidth") ] = uno::makeAny( rReferenceSize.Width ); //needs to be overwritten by actual available space in the legend
// recalculate font size
awt::Size aPropRefSize;
@@ -241,20 +240,23 @@ awt::Size lcl_createTextShapes(
return aResult;
}
-
-void lcl_placeLegendEntries(
+//returns resulting legend size
+awt::Size lcl_placeLegendEntries(
const tViewLegendEntryContainer & rEntries,
- LegendExpansion eExpansion,
+ ::com::sun::star::chart::ChartLegendExpansion eExpansion,
bool bSymbolsLeftSide,
const Reference< beans::XPropertySet > & xProperties,
tPropertyValues & rTextProperties,
const Reference< drawing::XShapes > & xTarget,
const Reference< lang::XMultiServiceFactory > & xShapeFactory,
- const Reference< uno::XComponentContext > & /* xContext */,
const awt::Size & rAvailableSpace,
- const awt::Size & rPageSize,
- awt::Size & rOutLegendSize )
+ const awt::Size & rPageSize )
{
+ bool bIsCustomSize = (eExpansion == ::com::sun::star::chart::ChartLegendExpansion_CUSTOM);
+ awt::Size aResultingLegendSize(0,0);
+ if( bIsCustomSize )
+ aResultingLegendSize = rAvailableSpace;
+ //todo
double fViewFontSize = lcl_CalcViewFontSize( xProperties, rPageSize );
// padding as percentage of the font height
@@ -269,16 +271,29 @@ void lcl_placeLegendEntries(
const sal_Int32 nXOffset = static_cast< sal_Int32 >( fViewFontSize * fXOffset );
const sal_Int32 nYOffset = static_cast< sal_Int32 >( fViewFontSize * fYOffset );
- ::std::vector< Reference< drawing::XShape > > aTextShapes;
- awt::Size aMaxEntryExtent = lcl_createTextShapes(
- rEntries, xShapeFactory, xTarget, aTextShapes, rTextProperties );
- OSL_ASSERT( aTextShapes.size() == rEntries.size());
-
// #i109336# Improve auto positioning in chart
double fSymbolSizeFraction = 0.8;
awt::Size aMaxSymbolExtent( static_cast< sal_Int32 >( fViewFontSize * fSymbolSizeFraction * 3.0 / 2.0 ),
static_cast< sal_Int32 >( fViewFontSize * fSymbolSizeFraction ) );
+ sal_Int32 nMaxTextWidth = rAvailableSpace.Width - (2 * nXOffset) - aMaxSymbolExtent.Width;
+ rtl::OUString aPropNameTextMaximumFrameWidth( C2U("TextMaximumFrameWidth") );
+ uno::Any* pFrameWidthAny = PropertyMapper::getValuePointer( rTextProperties.second, rTextProperties.first, aPropNameTextMaximumFrameWidth);
+ if(pFrameWidthAny)
+ {
+ if( eExpansion == ::com::sun::star::chart::ChartLegendExpansion_HIGH )
+ {
+ // limit the width of texts to 30% of the total available width
+ // #i109336# Improve auto positioning in chart
+ nMaxTextWidth = rAvailableSpace.Width * 3 / 10;
+ }
+ *pFrameWidthAny = uno::makeAny(nMaxTextWidth);
+ }
+
+ ::std::vector< Reference< drawing::XShape > > aTextShapes;
+ awt::Size aMaxEntryExtent = lcl_createTextShapes( rEntries, xShapeFactory, xTarget, aTextShapes, rTextProperties );
+ OSL_ASSERT( aTextShapes.size() == rEntries.size());
+
sal_Int32 nCurrentXPos = nXPadding;
sal_Int32 nCurrentYPos = nYPadding;
sal_Int32 nMaxEntryWidth = 2 * nXOffset + aMaxSymbolExtent.Width + aMaxEntryExtent.Width;
@@ -289,9 +304,80 @@ void lcl_placeLegendEntries(
nCurrentXPos = -nXPadding;
sal_Int32 nNumberOfColumns = 0, nNumberOfRows = 0;
+ std::vector< sal_Int32 > aColumnWidths;
// determine layout depending on LegendExpansion
- if( eExpansion == LegendExpansion_HIGH )
+ if( eExpansion == ::com::sun::star::chart::ChartLegendExpansion_CUSTOM )
+ {
+ sal_Int32 nCurrentRow=0;
+ sal_Int32 nCurrentColumn=-1;
+ sal_Int32 nColumnCount=0;
+ sal_Int32 nMaxColumnCount=-1;
+ for( sal_Int32 nN=0; nN<aTextShapes.size(); nN++)
+ {
+ Reference< drawing::XShape > xShape( aTextShapes[nN] );
+ if( !xShape.is() )
+ continue;
+ awt::Size aSize( xShape->getSize() );
+ sal_Int32 nNewWidth = aSize.Width + aMaxSymbolExtent.Width + nXOffset;
+ sal_Int32 nCurrentColumnCount = aColumnWidths.size();
+
+ //are we allowed to add a new column?
+ if( nMaxColumnCount==-1 || (nCurrentColumn+1) < nMaxColumnCount )
+ {
+ //try add a new column
+ nCurrentColumn++;
+ if( nCurrentColumn < nCurrentColumnCount )
+ {
+ //check wether the current column width is sufficient for the new entry
+ if( aColumnWidths[nCurrentColumn]>=nNewWidth )
+ {
+ //all good proceed with next entry
+ continue;
+ }
+ }
+ if( nCurrentColumn < nCurrentColumnCount )
+ aColumnWidths[nCurrentColumn] = std::max( nNewWidth, aColumnWidths[nCurrentColumn] );
+ else
+ aColumnWidths.push_back(nNewWidth);
+
+ //do the columns still fit into the given size?
+ nCurrentColumnCount = aColumnWidths.size();//update count
+ sal_Int32 nSumWidth = 0;
+ for( sal_Int32 nC=0; nC<nCurrentColumnCount; nC++ )
+ nSumWidth += aColumnWidths[nC];
+ if( nCurrentColumnCount > 1)
+ nSumWidth += nXOffset*(nCurrentColumnCount-1);
+
+ if( nSumWidth <= rAvailableSpace.Width || nCurrentColumnCount==1 )
+ {
+ //all good proceed with next entry
+ continue;
+ }
+ else
+ {
+ //not enough space for the current amount of columns
+ //try again with less columns
+ nMaxColumnCount = nCurrentColumnCount-1;
+ nN=-1;
+ nCurrentRow=0;
+ nCurrentColumn=-1;
+ nColumnCount=0;
+ aColumnWidths.clear();
+ }
+ }
+ else
+ {
+ //add a new row and try the same entry again
+ nCurrentRow++;
+ nCurrentColumn=-1;
+ nN--;
+ }
+ }
+ nNumberOfColumns = aColumnWidths.size();
+ nNumberOfRows = nCurrentRow+1;
+ }
+ else if( eExpansion == ::com::sun::star::chart::ChartLegendExpansion_HIGH )
{
sal_Int32 nMaxNumberOfRows = nMaxEntryHeight
? (rAvailableSpace.Height - 2*nYPadding ) / nMaxEntryHeight
@@ -308,7 +394,7 @@ void lcl_placeLegendEntries(
static_cast< double >( nNumberOfColumns ) ))
: 0;
}
- else if( eExpansion == LegendExpansion_WIDE )
+ else if( eExpansion == ::com::sun::star::chart::ChartLegendExpansion_WIDE )
{
sal_Int32 nMaxNumberOfColumns = nMaxEntryWidth
? (rAvailableSpace.Width - 2*nXPadding ) / nMaxEntryWidth
@@ -325,7 +411,7 @@ void lcl_placeLegendEntries(
static_cast< double >( nNumberOfRows ) ))
: 0;
}
- else // LegendExpansion_BALANCED
+ else // ::com::sun::star::chart::ChartLegendExpansion_BALANCED
{
double fAspect = nMaxEntryHeight
? static_cast< double >( nMaxEntryWidth ) / static_cast< double >( nMaxEntryHeight )
@@ -341,7 +427,7 @@ void lcl_placeLegendEntries(
}
if(nNumberOfRows<=0)
- return;
+ return aResultingLegendSize;
// calculate maximum height for current row
std::vector< sal_Int32 > nMaxHeights( nNumberOfRows );
@@ -352,13 +438,23 @@ void lcl_placeLegendEntries(
sal_Int32 nMaxHeight = 0;
for( nColumn = 0; nColumn < nNumberOfColumns; ++nColumn )
{
- sal_Int32 nEntry = ( eExpansion == LegendExpansion_WIDE )
- ? (nColumn + nRow * nNumberOfColumns)
- // HIGH or BALANCED
- : (nRow + nColumn * nNumberOfRows);
+ sal_Int32 nEntry = (nColumn + nRow * nNumberOfColumns);
if( nEntry < nNumberOfEntries )
+ {
+ awt::Size aTextSize( aTextShapes[ nEntry ]->getSize() );
nMaxHeight = ::std::max(
- nMaxHeight, nYOffset + aTextShapes[ nEntry ]->getSize().Height );
+ nMaxHeight, nYOffset + aTextSize.Height );
+ if( eExpansion != ::com::sun::star::chart::ChartLegendExpansion_CUSTOM )
+ {
+ sal_Int32 nWidth = nXOffset + aMaxSymbolExtent.Width + aTextSize.Width;
+ if( nColumn>0 )
+ nWidth += nXOffset;
+ if( nRow==0 )
+ aColumnWidths.push_back( nWidth );
+ else
+ aColumnWidths[nColumn] = ::std::max( nWidth, aColumnWidths[nColumn] );
+ }
+ }
}
nMaxHeights[ nRow ] = nMaxHeight;
}
@@ -367,15 +463,11 @@ void lcl_placeLegendEntries(
sal_Int32 nMaxYPos = 0;
for( nColumn = 0; nColumn < nNumberOfColumns; ++nColumn )
{
- sal_Int32 nMaxWidth = 0;
nCurrentYPos = nYPadding;
for( nRow = 0; nRow < nNumberOfRows; ++nRow )
{
- sal_Int32 nEntry = ( eExpansion == LegendExpansion_WIDE )
- ? (nColumn + nRow * nNumberOfColumns)
- // HIGH or BALANCED
- : (nRow + nColumn * nNumberOfRows);
+ sal_Int32 nEntry = (nColumn + nRow * nNumberOfColumns);
if( nEntry >= nNumberOfEntries )
break;
@@ -406,7 +498,6 @@ void lcl_placeLegendEntries(
// position text shape
awt::Size aTextSize( aTextShapes[ nEntry ]->getSize());
- nMaxWidth = ::std::max( nMaxWidth, 2 * nXOffset + aMaxSymbolExtent.Width + aTextSize.Width );
sal_Int32 nTextXPos = nCurrentXPos + aMaxSymbolExtent.Width;
if( !bSymbolsLeftSide )
nTextXPos = nCurrentXPos - aMaxSymbolExtent.Width - aTextSize.Width;
@@ -416,18 +507,26 @@ void lcl_placeLegendEntries(
nMaxYPos = ::std::max( nMaxYPos, nCurrentYPos );
}
if( bSymbolsLeftSide )
- nCurrentXPos += nMaxWidth;
+ nCurrentXPos += aColumnWidths[nColumn];
else
- nCurrentXPos -= nMaxWidth;
+ nCurrentXPos -= aColumnWidths[nColumn];
}
- if( bSymbolsLeftSide )
- rOutLegendSize.Width = nCurrentXPos + nXPadding;
- else
+ if( !bIsCustomSize )
{
- sal_Int32 nLegendWidth = -(nCurrentXPos-nXPadding);
- rOutLegendSize.Width = nLegendWidth;
+ if( bSymbolsLeftSide )
+ aResultingLegendSize.Width = nCurrentXPos + nXPadding;
+ else
+ {
+ sal_Int32 nLegendWidth = -(nCurrentXPos-nXPadding);
+ aResultingLegendSize.Width = nLegendWidth;
+ }
+ aResultingLegendSize.Height = nMaxYPos + nYPadding;
+ }
+ if( !bSymbolsLeftSide )
+ {
+ sal_Int32 nLegendWidth = aResultingLegendSize.Width;
awt::Point aPos(0,0);
for( sal_Int32 nEntry=0; nEntry<nNumberOfEntries; nEntry++ )
{
@@ -441,7 +540,8 @@ void lcl_placeLegendEntries(
xText->setPosition( aPos );
}
}
- rOutLegendSize.Height = nMaxYPos + nYPadding;
+
+ return aResultingLegendSize;
}
// #i109336# Improve auto positioning in chart
@@ -706,23 +806,26 @@ void VLegend::createShapes(
tPropertyValues aLineFillProperties;
tPropertyValues aTextProperties;
- // limit the width of texts to 30% of the total available width
- // #i109336# Improve auto positioning in chart
- sal_Int32 nMaxLabelWidth = rAvailableSpace.Width * 3 / 10;
Reference< beans::XPropertySet > xLegendProp( m_xLegend, uno::UNO_QUERY );
- LegendExpansion eExpansion = LegendExpansion_HIGH;
+ ::com::sun::star::chart::ChartLegendExpansion eExpansion = ::com::sun::star::chart::ChartLegendExpansion_HIGH;
+ awt::Size aLegendSize( rAvailableSpace );
+
if( xLegendProp.is())
{
// get Expansion property
xLegendProp->getPropertyValue( C2U( "Expansion" )) >>= eExpansion;
- if( eExpansion == LegendExpansion_WIDE )
+ if( eExpansion == ::com::sun::star::chart::ChartLegendExpansion_CUSTOM )
{
- //#i80377#
- nMaxLabelWidth = (rAvailableSpace.Width * 5) / 6;//completely correct would be available width minus symbol size minus distances to page ...
+ RelativeSize aRelativeSize;
+ if ((xLegendProp->getPropertyValue( C2U( "RelativeSize" )) >>= aRelativeSize))
+ {
+ aLegendSize.Width = aRelativeSize.Primary * rPageSize.Width;
+ aLegendSize.Height = aRelativeSize.Secondary * rPageSize.Height;
+ }
+ else
+ eExpansion = ::com::sun::star::chart::ChartLegendExpansion_HIGH;
}
-
- lcl_getProperties( xLegendProp, aLineFillProperties, aTextProperties, nMaxLabelWidth,
- rPageSize );
+ lcl_getProperties( xLegendProp, aLineFillProperties, aTextProperties, rPageSize );
}
if( xBorder.is())
@@ -758,13 +861,11 @@ void VLegend::createShapes(
bool bSymbolsLeftSide = lcl_shouldSymbolsBePlacedOnTheLeftSide( xLegendProp, m_nDefaultWritingMode );
// place entries
- awt::Size aLegendSize;
- lcl_placeLegendEntries( aViewEntries, eExpansion, bSymbolsLeftSide
- , xLegendProp, aTextProperties
- , xLegendContainer, m_xShapeFactory, m_xContext
- , rAvailableSpace, rPageSize, aLegendSize );
+ aLegendSize = lcl_placeLegendEntries( aViewEntries, eExpansion, bSymbolsLeftSide
+ , xLegendProp, aTextProperties, xLegendContainer, m_xShapeFactory
+ , aLegendSize, rPageSize );
- if( xBorder.is())
+ if( xBorder.is() )
xBorder->setSize( aLegendSize );
}
}