diff options
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/chart/chartspaceconverter.cxx | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/oox/source/drawingml/chart/chartspaceconverter.cxx b/oox/source/drawingml/chart/chartspaceconverter.cxx index 6ddbb2ab76bb..2e2c8bc3885b 100644 --- a/oox/source/drawingml/chart/chartspaceconverter.cxx +++ b/oox/source/drawingml/chart/chartspaceconverter.cxx @@ -22,6 +22,10 @@ #include <com/sun/star/chart/MissingValueTreatment.hpp> #include <com/sun/star/chart/XChartDocument.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/chart2/XChartType.hpp> +#include <com/sun/star/chart2/XChartTypeContainer.hpp> +#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> +#include <com/sun/star/chart2/XDataSeriesContainer.hpp> #include <com/sun/star/chart2/XTitled.hpp> #include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/drawing/FillStyle.hpp> @@ -67,6 +71,82 @@ ChartSpaceConverter::~ChartSpaceConverter() { } +// Formulas with no numeric values and strings are zeroes in OOXML line charts also in the mode DispBlanksAs=gap, +// unlike in OpenDocument LEAVE_GAP mode. As a workaround, we will use the OpenDocument mode USE_ZERO, if the OOXML +// line chart has got formulas with no numeric values and strings, but it doesn't have empty cells, showing the +// same chart as in MSO. (Empty cells need gaps, so in that case, we cannot use this workaround). +static bool lcl_useWorkaroundForNoGapInOOXML( Reference< chart2::XChartDocument > const & xChartDoc) +{ + Reference <chart2::XDiagram > xDiagram = xChartDoc->getFirstDiagram(); + if ( !xDiagram.is() ) + return false; + + Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, UNO_QUERY_THROW ); + + Sequence< Reference< chart2::XCoordinateSystem > > xCooSysSequence( xCooSysContainer->getCoordinateSystems()); + if ( xCooSysSequence.getLength() == 0 ) + return false; + + Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSysSequence[0], UNO_QUERY_THROW ); + + Sequence< Reference< chart2::XChartType > > xChartTypeSequence( xChartTypeContainer->getChartTypes() ); + if ( xChartTypeSequence.getLength() == 0 ) + return false; + + const Reference<chart2::XChartType>& xCT = xChartTypeSequence[0]; + + if ( xCT->getChartType() != "com.sun.star.chart2.LineChartType" ) + return false; + + Reference<chart2::XDataSeriesContainer> xDSCont(xCT, uno::UNO_QUERY); + + if (!xDSCont.is()) + return false; + + Sequence<uno::Reference<chart2::XDataSeries> > aDataSeriesSeq = xDSCont->getDataSeries(); + + bool bHasNoGapBlankValue = false; + bool bHasEmptyCell = false; + + for (sal_Int32 i = 0; i < aDataSeriesSeq.getLength(); ++i) + { + uno::Reference<chart2::data::XDataSource> xDSrc(aDataSeriesSeq[i], uno::UNO_QUERY); + if (!xDSrc.is()) + return false; + + uno::Sequence<Reference<chart2::data::XLabeledDataSequence> > aDataSeqs = xDSrc->getDataSequences(); + for (sal_Int32 j = 0; j < aDataSeqs.getLength(); ++j) + { + Reference<chart2::data::XDataSequence> xValues = aDataSeqs[j]->getValues(); + if(!xValues.is()) + return false; + Reference<beans::XPropertySet> xPropSet(xValues, uno::UNO_QUERY); + if (!xPropSet.is()) + continue; + + OUString aRoleName; + xPropSet->getPropertyValue("Role") >>= aRoleName; + if (aRoleName == "values-y") + { + uno::Sequence<uno::Any> aData = xValues->getData(); + for (sal_Int32 nVal = 0; nVal < aData.getLength(); ++nVal) + { + double fVal; + OUString sStr; + if (aData[nVal] >>= fVal) + continue; + else if (aData[nVal] >>= sStr) + bHasNoGapBlankValue = true; + else + bHasEmptyCell = true; + } + } + } + } + + return bHasNoGapBlankValue && !bHasEmptyCell; +} + void ChartSpaceConverter::convertFromModel( const Reference< XShapes >& rxExternalPage, const awt::Point& rChartPos ) { /* create data provider (virtual function in the ChartConverter class, @@ -132,6 +212,11 @@ void ChartSpaceConverter::convertFromModel( const Reference< XShapes >& rxExtern case XML_zero: nMissingValues = USE_ZERO; break; case XML_span: nMissingValues = CONTINUE; break; } + + // use a workaround, if it's possible for the difference of OOXML and OpenDocument + if ( nMissingValues == LEAVE_GAP && lcl_useWorkaroundForNoGapInOOXML(getChartDocument()) ) + nMissingValues = USE_ZERO; + PropertySet aDiaProp( xDiagram ); aDiaProp.setProperty( PROP_MissingValueTreatment, nMissingValues ); } |