summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/chart/chartspaceconverter.cxx85
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 );
}