diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-07-23 15:49:11 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-07-26 18:36:42 -0400 |
commit | 2d5f5b00dc0a7777fab2be89a4b2b12fed95efde (patch) | |
tree | 90f4e023b3fab8570fcab3ffbef0406bd2990e0a | |
parent | 4df875f9a68b699e3714f83915574af22b4ccd0e (diff) |
bnc#885825: OOXML import and export of data label borders.
(cherry picked from commit 48f31a924280a418046f0c816f8a7d20b672dac6)
Conflicts:
include/oox/export/chartexport.hxx
oox/source/drawingml/chart/seriesconverter.cxx
oox/source/export/chartexport.cxx
Change-Id: I0fd808145aaeb0aa36d3ec30d7b977890642dcff
-rw-r--r-- | include/oox/export/chartexport.hxx | 4 | ||||
-rw-r--r-- | include/oox/export/utils.hxx | 1 | ||||
-rw-r--r-- | oox/source/drawingml/chart/seriesconverter.cxx | 31 | ||||
-rw-r--r-- | oox/source/export/chartexport.cxx | 198 | ||||
-rw-r--r-- | oox/source/token/properties.txt | 3 |
5 files changed, 120 insertions, 117 deletions
diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx index 237b410c686d..524c61d19829 100644 --- a/include/oox/export/chartexport.hxx +++ b/include/oox/export/chartexport.hxx @@ -147,9 +147,7 @@ private: void exportDataPoints( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSeriesProperties, sal_Int32 nSeriesLength ); - void exportDataLabels( - const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSeriesProperties, - sal_Int32 nSeriesLength ); + void exportDataLabels( const css::uno::Reference<css::chart2::XDataSeries>& xSeries, sal_Int32 nSeriesLength ); void exportGrouping( sal_Bool isBar = sal_False ); void exportTrendlines( ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries > xSeries ); void exportMarker(); diff --git a/include/oox/export/utils.hxx b/include/oox/export/utils.hxx index 657ee4d38e98..f189daf3fdfa 100644 --- a/include/oox/export/utils.hxx +++ b/include/oox/export/utils.hxx @@ -23,6 +23,7 @@ #define I32S(x) OString::number( (sal_Int32) x ).getStr() #define I64S(x) OString::number( (sal_Int64) x ).getStr() #define IS(x) OString::number( x ).getStr() +#define BS(x) (x ? "1":"0") #define USS(x) OUStringToOString( x, RTL_TEXTENCODING_UTF8 ).getStr() #ifndef DBG diff --git a/oox/source/drawingml/chart/seriesconverter.cxx b/oox/source/drawingml/chart/seriesconverter.cxx index dbd3201a3c98..910a8006d41a 100644 --- a/oox/source/drawingml/chart/seriesconverter.cxx +++ b/oox/source/drawingml/chart/seriesconverter.cxx @@ -27,6 +27,7 @@ #include <com/sun/star/chart2/XRegressionCurveContainer.hpp> #include <com/sun/star/chart2/data/XDataSink.hpp> #include <com/sun/star/chart2/data/LabeledDataSequence.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> #include <basegfx/numeric/ftools.hxx> #include "oox/drawingml/chart/datasourceconverter.hxx" #include "oox/drawingml/chart/seriesmodel.hxx" @@ -34,13 +35,13 @@ #include "oox/drawingml/chart/typegroupconverter.hxx" #include "oox/drawingml/chart/typegroupmodel.hxx" #include "oox/helper/containerhelper.hxx" +#include <oox/drawingml/lineproperties.hxx> namespace oox { namespace drawingml { namespace chart { -// ============================================================================ - +using namespace com::sun::star; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::chart2; using namespace ::com::sun::star::chart2::data; @@ -166,6 +167,20 @@ void lclConvertLabelFormatting( PropertySet& rPropSet, ObjectFormatter& rFormatt } } +void importBorderProperties( PropertySet& rPropSet, Shape& rShape, const GraphicHelper& rGraphicHelper ) +{ + LineProperties& rLP = rShape.getLineProperties(); + if (rLP.moLineWidth.has()) + { + sal_Int32 nWidth = convertEmuToHmm(rLP.moLineWidth.get()); + rPropSet.setProperty(PROP_LabelBorderWidth, uno::makeAny(nWidth)); + rPropSet.setProperty(PROP_LabelBorderStyle, uno::makeAny(drawing::LineStyle_SOLID)); + } + const Color& aColor = rLP.maLineFill.maFillColor; + sal_Int32 nColor = aColor.getColor(rGraphicHelper); + rPropSet.setProperty(PROP_LabelBorderColor, uno::makeAny(nColor)); +} + } // namespace // ============================================================================ @@ -181,7 +196,10 @@ DataLabelConverter::~DataLabelConverter() void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries, const TypeGroupConverter& rTypeGroup ) { - if( rxDataSeries.is() ) try + if (!rxDataSeries.is()) + return; + + try { PropertySet aPropSet( rxDataSeries->getDataPointByIndex( mrModel.mnIndex ) ); lclConvertLabelFormatting( aPropSet, getFormatter(), mrModel, rTypeGroup, false ); @@ -206,6 +224,9 @@ void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDat aPropSet.setProperty( PROP_LabelPlacement, aPositionsLookupTable[ simplifiedX+1 + 3*(simplifiedY+1) ] ); } + + if (mrModel.mxShapeProp) + importBorderProperties(aPropSet, *mrModel.mxShapeProp, getFilter().getGraphicHelper()); } catch( Exception& ) { @@ -229,6 +250,10 @@ void DataLabelsConverter::convertFromModel( const Reference< XDataSeries >& rxDa { PropertySet aPropSet( rxDataSeries ); lclConvertLabelFormatting( aPropSet, getFormatter(), mrModel, rTypeGroup, true ); + + if (mrModel.mxShapeProp) + // Import baseline border properties for these data labels. + importBorderProperties(aPropSet, *mrModel.mxShapeProp, getFilter().getGraphicHelper()); } // data point label settings diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index b13867e9bd81..6be487f72387 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -1540,8 +1540,8 @@ void ChartExport::exportSeries( Reference< chart2::XChartType > xChartType, sal_ // export data labels // Excel does not like our current data label export // for scatter charts - if( eChartType != chart::TYPEID_SCATTER && eChartType != chart::TYPEID_BAR ) - exportDataLabels( uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ), nSeriesLength ); + if( eChartType != chart::TYPEID_SCATTER ) + exportDataLabels(aSeriesSeq[nSeriesIdx], nSeriesLength); exportTrendlines( aSeriesSeq[nSeriesIdx] ); @@ -2264,127 +2264,103 @@ void ChartExport::_exportAxis( pFS->endElement( FSNS( XML_c, nAxisType ) ); } -void ChartExport::exportDataLabels( - const uno::Reference< beans::XPropertySet > & xSeriesProperties, - sal_Int32 nSeriesLength ) +namespace { + +const char* toOOXMLPlacement( sal_Int32 nPlacement ) { - // TODO: export field separators, missing flag vs. showing series name or not - uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY ); + switch (nPlacement) + { + case css::chart::DataLabelPlacement::OUTSIDE: return "outEnd"; + case css::chart::DataLabelPlacement::INSIDE: return "inEnd"; + case css::chart::DataLabelPlacement::CENTER: return "ctr"; + case css::chart::DataLabelPlacement::NEAR_ORIGIN: return "inBase"; + case css::chart::DataLabelPlacement::TOP: return "t"; + case css::chart::DataLabelPlacement::BOTTOM: return "b"; + case css::chart::DataLabelPlacement::LEFT: return "l"; + case css::chart::DataLabelPlacement::RIGHT: return "r"; + case css::chart::DataLabelPlacement::AVOID_OVERLAP: return "bestFit"; + default: + ; + } - if( xSeriesProperties.is()) + return "outEnd"; +} + +void writeLabelProperties( FSHelperPtr pFS, const uno::Reference<beans::XPropertySet>& xPropSet ) +{ + if (!xPropSet.is()) + return; + + chart2::DataPointLabel aLabel; + sal_Int32 nLabelPlacement = css::chart::DataLabelPlacement::OUTSIDE; + sal_Int32 nLabelBorderWidth = 0; + sal_Int32 nLabelBorderColor = 0x00FFFFFF; + + xPropSet->getPropertyValue("Label") >>= aLabel; + xPropSet->getPropertyValue("LabelPlacement") >>= nLabelPlacement; + xPropSet->getPropertyValue("LabelBorderWidth") >>= nLabelBorderWidth; + xPropSet->getPropertyValue("LabelBorderColor") >>= nLabelBorderColor; + + if (nLabelBorderWidth > 0) { - FSHelperPtr pFS = GetFS(); - pFS->startElement( FSNS( XML_c, XML_dLbls ), - FSEND ); + pFS->startElement(FSNS(XML_c, XML_spPr), FSEND); + pFS->startElement(FSNS(XML_a, XML_ln), XML_w, IS(convertHmmToEmu(nLabelBorderWidth)), FSEND); + pFS->startElement(FSNS(XML_a, XML_solidFill), FSEND); - bool showLegendSymbol = false; - bool showNumber = false; - bool showCategoryName = false; - bool showNumberInPercent = false; + OString aStr = OString::number(nLabelBorderColor, 16).toAsciiUpperCase(); + pFS->singleElement(FSNS(XML_a, XML_srgbClr), XML_val, aStr.getStr(), FSEND); - sal_Int32 nElem; - for( nElem = 0; nElem < nSeriesLength; ++nElem) - { - uno::Reference< beans::XPropertySet > xPropSet; + pFS->endElement(FSNS(XML_a, XML_solidFill)); + pFS->endElement(FSNS(XML_a, XML_ln)); + pFS->endElement(FSNS(XML_c, XML_spPr)); + } - try - { - xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet( - xSeries, nElem, getModel() ); - } - catch( const uno::Exception & rEx ) - { - SAL_WARN("oox", "Exception caught during Export of data label: " << rEx.Message ); - } + pFS->singleElement(FSNS(XML_c, XML_dLblPos), XML_val, toOOXMLPlacement(nLabelPlacement), FSEND); + pFS->singleElement(FSNS(XML_c, XML_showLegendKey), XML_val, BS(aLabel.ShowLegendSymbol), FSEND); + pFS->singleElement(FSNS(XML_c, XML_showVal), XML_val, BS(aLabel.ShowNumber), FSEND); + pFS->singleElement(FSNS(XML_c, XML_showCatName), XML_val, BS(aLabel.ShowCategoryName), FSEND); + pFS->singleElement(FSNS(XML_c, XML_showSerName), XML_val, BS(false), FSEND); + pFS->singleElement(FSNS(XML_c, XML_showPercent), XML_val, BS(aLabel.ShowNumberInPercent), FSEND); +} - if( xPropSet.is() ) - { - namespace cssc2 = ::com::sun::star::chart2; - cssc2::DataPointLabel aLabel; - if (GetProperty( xPropSet, "Label")) - { - mAny >>= aLabel; - - namespace csscd = ::com::sun::star::chart::DataLabelPlacement; - sal_Int32 nPlacement(csscd::AVOID_OVERLAP); - const char *aPlacement = NULL; - OUString aSep; - - if (GetProperty( xPropSet, "LabelPlacement")) - mAny >>= nPlacement; - - switch( nPlacement ) - { - case csscd::OUTSIDE: aPlacement = "outEnd"; break; - case csscd::INSIDE: aPlacement = "inEnd"; break; - case csscd::CENTER: aPlacement = "ctr"; break; - case csscd::NEAR_ORIGIN: aPlacement = "inBase"; break; - case csscd::TOP: aPlacement = "t"; break; - case csscd::BOTTOM: aPlacement = "b"; break; - case csscd::LEFT: aPlacement = "l"; break; - case csscd::RIGHT: aPlacement = "r"; break; - case csscd::AVOID_OVERLAP: aPlacement = "bestFit"; break; - } - - if(aLabel.ShowLegendSymbol || aLabel.ShowNumber || aLabel.ShowCategoryName || aLabel.ShowNumberInPercent) - { - pFS->startElement( FSNS( XML_c, XML_dLbl ), FSEND); - pFS->singleElement( FSNS( XML_c, XML_idx), XML_val, I32S(nElem), FSEND); - pFS->singleElement( FSNS( XML_c, XML_dLblPos), XML_val, aPlacement, FSEND); - - pFS->singleElement( FSNS( XML_c, XML_showLegendKey), XML_val, aLabel.ShowLegendSymbol ? "1": "0", FSEND); - if (aLabel.ShowLegendSymbol) - { - showLegendSymbol = true; - } - - pFS->singleElement( FSNS( XML_c, XML_showVal), XML_val,aLabel.ShowNumber ? "1": "0", FSEND); - if(aLabel.ShowNumber) - { - showNumber = true; - } - - pFS->singleElement( FSNS( XML_c, XML_showCatName), XML_val, aLabel.ShowCategoryName ? "1": "0", FSEND); - if(aLabel.ShowCategoryName) - { - showCategoryName = true; - } - - // MSO somehow assumes series name to be on (=displayed) by default. - // Let's put false here and switch it off then, since we have no UI means - // in LibO to toggle it on anyway - pFS->singleElement( FSNS( XML_c, XML_showSerName), XML_val, "0", FSEND); - - pFS->singleElement( FSNS( XML_c, XML_showPercent), XML_val,aLabel.ShowNumberInPercent ? "1": "0", FSEND); - if(aLabel.ShowNumberInPercent) - { - showNumberInPercent = true; - } - - if (GetProperty( xPropSet, "LabelSeparator")) - { - mAny >>= aSep; - pFS->startElement( FSNS( XML_c, XML_separator), FSEND); - pFS->writeEscaped(aSep); - pFS->endElement( FSNS( XML_c, XML_separator) ); - } - pFS->endElement( FSNS( XML_c, XML_dLbl )); - } - - } - } - } +} + +void ChartExport::exportDataLabels( const uno::Reference<chart2::XDataSeries> & xSeries, + sal_Int32 nSeriesLength ) +{ + if (!xSeries.is() || nSeriesLength <= 0) + return; + + uno::Reference<beans::XPropertySet> xPropSet(xSeries, uno::UNO_QUERY); + if (!xPropSet.is()) + return; - pFS->singleElement( FSNS( XML_c, XML_showLegendKey), XML_val, showLegendSymbol ? "1": "0", FSEND); - pFS->singleElement( FSNS( XML_c, XML_showVal), XML_val, showNumber ? "1": "0", FSEND); - pFS->singleElement( FSNS( XML_c, XML_showCatName), XML_val, showCategoryName ? "1": "0", FSEND); + FSHelperPtr pFS = GetFS(); + pFS->startElement(FSNS(XML_c, XML_dLbls), FSEND); - pFS->singleElement( FSNS( XML_c, XML_showSerName), XML_val, "0", FSEND); + uno::Sequence<sal_Int32> aAttrLabelIndices; + xPropSet->getPropertyValue("AttributedDataPoints") >>= aAttrLabelIndices; - pFS->singleElement( FSNS( XML_c, XML_showPercent), XML_val, showNumberInPercent ? "1": "0", FSEND); + const sal_Int32* p = aAttrLabelIndices.getConstArray(); + const sal_Int32* pEnd = p + aAttrLabelIndices.getLength(); + for (; p != pEnd; ++p) + { + sal_Int32 nIdx = *p; + uno::Reference<beans::XPropertySet> xLabelPropSet = xSeries->getDataPointByIndex(nIdx); + if (!xLabelPropSet.is()) + continue; - pFS->endElement( FSNS( XML_c, XML_dLbls ) ); + // Individual label property thhat overwrites the baseline. + pFS->startElement(FSNS(XML_c, XML_dLbl), FSEND); + pFS->singleElement(FSNS(XML_c, XML_idx), XML_val, I32S(nIdx), FSEND); + writeLabelProperties(pFS, xLabelPropSet); + pFS->endElement(FSNS(XML_c, XML_dLbl)); } + + // Baseline label properties for all labels. + writeLabelProperties(pFS, xPropSet); + + pFS->endElement(FSNS(XML_c, XML_dLbls)); } void ChartExport::exportDataPoints( diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index 6d384b89c1cd..50571cbcec55 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -266,6 +266,9 @@ IterationCount IterationEpsilon Japanese Label +LabelBorderColor +LabelBorderStyle +LabelBorderWidth LabelPlacement LabelPosition LabelSeparator |