Avoid potential negative array index access to cached text.
[LibreOffice.git] / xmloff / source / chart / SchXMLPlotAreaContext.cxx
blob93f18d4b1efa4ed3408956e1dbb6470d1b8b6f6a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "SchXMLPlotAreaContext.hxx"
21 #include <SchXMLImport.hxx>
22 #include "SchXMLAxisContext.hxx"
23 #include "SchXMLSeries2Context.hxx"
24 #include "SchXMLTools.hxx"
26 #include <comphelper/processfactory.hxx>
27 #include <comphelper/sequence.hxx>
28 #include <sal/log.hxx>
29 #include <comphelper/diagnose_ex.hxx>
30 #include <utility>
31 #include <xmloff/xmlnamespace.hxx>
32 #include <xmloff/namespacemap.hxx>
33 #include <xmloff/xmluconv.hxx>
34 #include <xmloff/prstylei.hxx>
35 #include <xmloff/xmlstyle.hxx>
36 #include <oox/helper/containerhelper.hxx>
38 #include <com/sun/star/awt/Point.hpp>
39 #include <com/sun/star/awt/Size.hpp>
40 #include <com/sun/star/chart/ErrorBarStyle.hpp>
41 #include <com/sun/star/chart/X3DDisplay.hpp>
42 #include <com/sun/star/chart/XStatisticDisplay.hpp>
43 #include <com/sun/star/chart/XDiagramPositioning.hpp>
44 #include <com/sun/star/chart/XChartDocument.hpp>
45 #include <com/sun/star/chart2/XChartDocument.hpp>
46 #include <com/sun/star/chart2/data/XDataSink.hpp>
47 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
48 #include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
49 #include <com/sun/star/drawing/CameraGeometry.hpp>
50 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
51 #include <com/sun/star/lang/XServiceInfo.hpp>
52 #include <com/sun/star/xml/sax/XAttributeList.hpp>
54 using namespace com::sun::star;
55 using namespace ::xmloff::token;
57 using com::sun::star::uno::Reference;
59 namespace
62 struct lcl_AxisHasCategories
64 bool operator() ( const SchXMLAxis & rAxis )
66 return rAxis.bHasCategories;
70 OUString lcl_ConvertRange( const OUString & rRange, const uno::Reference< chart2::XChartDocument > & xDoc )
72 OUString aResult = rRange;
73 if(!xDoc.is())
74 return aResult;
75 uno::Reference< chart2::data::XRangeXMLConversion > xConversion(
76 xDoc->getDataProvider(), uno::UNO_QUERY );
77 if( xConversion.is())
78 aResult = xConversion->convertRangeFromXML( rRange );
79 return aResult;
82 } // anonymous namespace
84 SchXML3DSceneAttributesHelper::SchXML3DSceneAttributesHelper( SvXMLImport& rImporter )
85 : SdXML3DSceneAttributesHelper( rImporter )
89 void SchXML3DSceneAttributesHelper::getCameraDefaultFromDiagram( const uno::Reference< chart::XDiagram >& xDiagram )
91 //different defaults for camera geometry necessary to workaround wrong behaviour in old chart
92 //in future make this version dependent if we have versioning (metastream) for ole objects
94 try
96 uno::Reference< beans::XPropertySet > xProp( xDiagram, uno::UNO_QUERY );
97 if( xProp.is() )
99 drawing::CameraGeometry aCamGeo;
100 xProp->getPropertyValue("D3DCameraGeometry") >>= aCamGeo;
101 maVRP.setX( aCamGeo.vrp.PositionX );
102 maVRP.setY( aCamGeo.vrp.PositionY );
103 maVRP.setZ( aCamGeo.vrp.PositionZ );
104 maVPN.setX( aCamGeo.vpn.DirectionX );
105 maVPN.setY( aCamGeo.vpn.DirectionY );
106 maVPN.setZ( aCamGeo.vpn.DirectionZ );
107 maVUP.setX( aCamGeo.vup.DirectionX );
108 maVUP.setY( aCamGeo.vup.DirectionY );
109 maVUP.setZ( aCamGeo.vup.DirectionZ );
112 catch( const uno::Exception & )
114 TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught for property NumberOfLines");
118 SchXML3DSceneAttributesHelper::~SchXML3DSceneAttributesHelper()
122 SchXMLPlotAreaContext::SchXMLPlotAreaContext(
123 SchXMLImportHelper& rImpHelper,
124 SvXMLImport& rImport,
125 const OUString& rXLinkHRefAttributeToIndicateDataProvider,
126 OUString& rCategoriesAddress,
127 OUString& rChartAddress,
128 bool & rbHasRangeAtPlotArea,
129 bool & rAllRangeAddressesAvailable,
130 bool & rColHasLabels,
131 bool & rRowHasLabels,
132 chart::ChartDataRowSource & rDataRowSource,
133 SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles,
134 OUString aChartTypeServiceName,
135 tSchXMLLSequencesPerIndex & rLSequencesPerIndex,
136 const awt::Size & rChartSize ) :
137 SvXMLImportContext( rImport ),
138 mrImportHelper( rImpHelper ),
139 mrCategoriesAddress( rCategoriesAddress ),
140 mrSeriesDefaultsAndStyles( rSeriesDefaultsAndStyles ),
141 mnNumOfLinesProp( 0 ),
142 mbStockHasVolume( false ),
143 mnSeries( 0 ),
144 m_aGlobalSeriesImportInfo( rAllRangeAddressesAvailable ),
145 maSceneImportHelper( rImport ),
146 m_aOuterPositioning( rImport ),
147 m_aInnerPositioning( rImport ),
148 mbPercentStacked(false),
149 m_bAxisPositionAttributeImported(false),
150 m_rXLinkHRefAttributeToIndicateDataProvider(rXLinkHRefAttributeToIndicateDataProvider),
151 mrChartAddress( rChartAddress ),
152 m_rbHasRangeAtPlotArea( rbHasRangeAtPlotArea ),
153 mrColHasLabels( rColHasLabels ),
154 mrRowHasLabels( rRowHasLabels ),
155 mrDataRowSource( rDataRowSource ),
156 maChartTypeServiceName(std::move( aChartTypeServiceName )),
157 mrLSequencesPerIndex( rLSequencesPerIndex ),
158 mbGlobalChartTypeUsedBySeries( false ),
159 maChartSize( rChartSize )
161 m_rbHasRangeAtPlotArea = false;
163 // get Diagram
164 uno::Reference< chart::XChartDocument > xDoc = rImpHelper.GetChartDocument();
165 if( xDoc.is())
167 mxDiagram = xDoc->getDiagram();
168 mxNewDoc.set( xDoc, uno::UNO_QUERY );
170 maSceneImportHelper.getCameraDefaultFromDiagram( mxDiagram );
172 SAL_WARN_IF( !mxDiagram.is(),"xmloff.chart", "Couldn't get XDiagram" );
174 // turn off all axes initially
175 uno::Any aFalseBool;
176 aFalseBool <<= false;
178 uno::Reference< lang::XServiceInfo > xInfo( mxDiagram, uno::UNO_QUERY );
179 uno::Reference< beans::XPropertySet > xProp( mxDiagram, uno::UNO_QUERY );
180 if( !xInfo.is() || !xProp.is() )
181 return;
185 xProp->setPropertyValue("HasXAxis", aFalseBool );
186 xProp->setPropertyValue("HasXAxisGrid", aFalseBool );
187 xProp->setPropertyValue("HasXAxisDescription", aFalseBool );
188 xProp->setPropertyValue("HasSecondaryXAxis", aFalseBool );
189 xProp->setPropertyValue("HasSecondaryXAxisDescription", aFalseBool );
191 xProp->setPropertyValue("HasYAxis", aFalseBool );
192 xProp->setPropertyValue("HasYAxisGrid", aFalseBool );
193 xProp->setPropertyValue("HasYAxisDescription", aFalseBool );
194 xProp->setPropertyValue("HasSecondaryYAxis", aFalseBool );
195 xProp->setPropertyValue("HasSecondaryYAxisDescription", aFalseBool );
197 xProp->setPropertyValue("HasZAxis", aFalseBool );
198 xProp->setPropertyValue("HasZAxisDescription", aFalseBool );
200 xProp->setPropertyValue("DataRowSource", uno::Any(chart::ChartDataRowSource_COLUMNS) );
202 catch( const beans::UnknownPropertyException & )
204 SAL_WARN("xmloff.chart", "Property required by service not supported" );
208 SchXMLPlotAreaContext::~SchXMLPlotAreaContext()
211 void SchXMLPlotAreaContext::startFastElement (sal_Int32 /*nElement*/,
212 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
214 // parse attributes
215 uno::Reference< chart2::XChartDocument > xNewDoc( GetImport().GetModel(), uno::UNO_QUERY );
217 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
219 switch( aIter.getToken() )
221 case XML_ELEMENT(SVG, XML_X):
222 case XML_ELEMENT(SVG_COMPAT, XML_X):
223 case XML_ELEMENT(SVG, XML_Y):
224 case XML_ELEMENT(SVG_COMPAT, XML_Y):
225 case XML_ELEMENT(SVG, XML_WIDTH):
226 case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
227 case XML_ELEMENT(SVG, XML_HEIGHT):
228 case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
229 m_aOuterPositioning.readPositioningAttribute( aIter.getToken(), aIter.toView() );
230 break;
231 case XML_ELEMENT(CHART, XML_STYLE_NAME):
232 msAutoStyleName = aIter.toString();
233 break;
234 case XML_ELEMENT(TABLE, XML_CELL_RANGE_ADDRESS):
235 mrChartAddress = lcl_ConvertRange( aIter.toString(), xNewDoc );
236 // indicator for getting data from the outside
237 m_rbHasRangeAtPlotArea = true;
238 break;
239 case XML_ELEMENT(CHART, XML_DATA_SOURCE_HAS_LABELS):
241 if( IsXMLToken(aIter, XML_BOTH) )
242 mrColHasLabels = mrRowHasLabels = true;
243 else if( IsXMLToken(aIter, XML_ROW) )
244 mrRowHasLabels = true;
245 else if( IsXMLToken(aIter, XML_COLUMN) )
246 mrColHasLabels = true;
248 break;
249 case XML_ELEMENT(DR3D, XML_TRANSFORM):
250 case XML_ELEMENT(DR3D, XML_VRP):
251 case XML_ELEMENT(DR3D, XML_VPN):
252 case XML_ELEMENT(DR3D, XML_VUP):
253 case XML_ELEMENT(DR3D, XML_PROJECTION):
254 case XML_ELEMENT(DR3D, XML_DISTANCE):
255 case XML_ELEMENT(DR3D, XML_FOCAL_LENGTH):
256 case XML_ELEMENT(DR3D, XML_SHADOW_SLANT):
257 case XML_ELEMENT(DR3D, XML_SHADE_MODE):
258 case XML_ELEMENT(DR3D, XML_AMBIENT_COLOR):
259 case XML_ELEMENT(DR3D, XML_LIGHTING_MODE):
260 maSceneImportHelper.processSceneAttribute( aIter );
261 break;
262 default:
263 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
267 if( ! mxNewDoc.is())
269 uno::Reference< beans::XPropertySet > xDocProp( mrImportHelper.GetChartDocument(), uno::UNO_QUERY );
270 if( xDocProp.is())
274 xDocProp->setPropertyValue("DataSourceLabelsInFirstColumn", uno::Any(mrColHasLabels) );
275 xDocProp->setPropertyValue("DataSourceLabelsInFirstRow", uno::Any(mrRowHasLabels) );
277 catch( const beans::UnknownPropertyException & )
279 SAL_WARN("xmloff.chart", "Properties missing" );
284 // set properties
285 uno::Reference< beans::XPropertySet > xProp( mxDiagram, uno::UNO_QUERY );
286 if( !msAutoStyleName.isEmpty())
288 if( xProp.is())
290 const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
291 if( pStylesCtxt )
293 const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
294 SchXMLImportHelper::GetChartFamilyID(), msAutoStyleName );
296 XMLPropStyleContext* pPropStyleContext =
297 const_cast< XMLPropStyleContext * >(
298 dynamic_cast< const XMLPropStyleContext * >( pStyle ) );
299 if( pPropStyleContext )
301 pPropStyleContext->FillPropertySet( xProp );
303 // get the data row source that was set without having data
304 xProp->getPropertyValue("DataRowSource")
305 >>= mrDataRowSource;
307 //lines on/off
308 //this old property is not supported fully anymore with the new chart, so we need to get the information a little bit different from similar properties
309 mrSeriesDefaultsAndStyles.maLinesOnProperty = SchXMLTools::getPropertyFromContext(
310 u"Lines", pPropStyleContext, pStylesCtxt );
312 //handle automatic position and size
313 m_aOuterPositioning.readAutomaticPositioningProperties( pPropStyleContext, pStylesCtxt );
315 //correct default starting angle for old 3D pies
316 if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan3_0( GetImport().GetModel() ) )
318 bool bIs3d = false;
319 if( xProp.is() && ( xProp->getPropertyValue("Dim3D") >>= bIs3d ) &&
320 bIs3d )
322 if( maChartTypeServiceName == "com.sun.star.chart2.PieChartType" || maChartTypeServiceName == "com.sun.star.chart2.DonutChartType" )
324 OUString aPropName( "StartingAngle" );
325 uno::Any aAStartingAngle( SchXMLTools::getPropertyFromContext( aPropName, pPropStyleContext, pStylesCtxt ) );
326 if( !aAStartingAngle.hasValue() )
327 xProp->setPropertyValue( aPropName, uno::Any(sal_Int32(0)) ) ;
336 //remember default values for dataseries
337 if(xProp.is())
341 mrSeriesDefaultsAndStyles.maSymbolTypeDefault = xProp->getPropertyValue("SymbolType");
342 mrSeriesDefaultsAndStyles.maDataCaptionDefault = xProp->getPropertyValue("DataCaption");
344 mrSeriesDefaultsAndStyles.maMeanValueDefault = xProp->getPropertyValue("MeanValue");
345 mrSeriesDefaultsAndStyles.maRegressionCurvesDefault = xProp->getPropertyValue("RegressionCurves");
347 bool bStacked = false;
348 mrSeriesDefaultsAndStyles.maStackedDefault = xProp->getPropertyValue("Stacked");
349 mrSeriesDefaultsAndStyles.maStackedDefault >>= bStacked;
350 mrSeriesDefaultsAndStyles.maPercentDefault = xProp->getPropertyValue("Percent");
351 mrSeriesDefaultsAndStyles.maPercentDefault >>= mbPercentStacked;
352 mrSeriesDefaultsAndStyles.maStackedBarsConnectedDefault = xProp->getPropertyValue("StackedBarsConnected");
354 // deep
355 uno::Any aDeepProperty( xProp->getPropertyValue("Deep"));
356 // #124488# old versions store a 3d area and 3D line deep chart with Deep==false => workaround for this
357 if( ! (bStacked || mbPercentStacked ))
359 if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) )
361 bool bIs3d = false;
362 if( ( xProp->getPropertyValue("Dim3D") >>= bIs3d ) &&
363 bIs3d )
365 if( maChartTypeServiceName == "com.sun.star.chart2.AreaChartType" || maChartTypeServiceName == "com.sun.star.chart2.LineChartType" )
367 aDeepProperty <<= true;
372 mrSeriesDefaultsAndStyles.maDeepDefault = aDeepProperty;
374 xProp->getPropertyValue("NumberOfLines") >>= mnNumOfLinesProp;
375 xProp->getPropertyValue("Volume") >>= mbStockHasVolume;
377 catch( const uno::Exception & )
379 TOOLS_INFO_EXCEPTION("xmloff.chart", "PlotAreaContext:EndElement(): Exception caught");
381 } // if
383 bool bCreateInternalDataProvider = false;
384 if( m_rXLinkHRefAttributeToIndicateDataProvider == "." ) //data comes from the chart itself
385 bCreateInternalDataProvider = true;
386 else if( m_rXLinkHRefAttributeToIndicateDataProvider == ".." ) //data comes from the parent application
387 bCreateInternalDataProvider = false;
388 else if( !m_rXLinkHRefAttributeToIndicateDataProvider.isEmpty() ) //not supported so far to get the data by sibling objects -> fall back to chart itself
389 bCreateInternalDataProvider = true;
390 else if( !m_rbHasRangeAtPlotArea )
391 bCreateInternalDataProvider = true;
393 if( bCreateInternalDataProvider && mxNewDoc.is() )
395 // we have no complete range => we have own data, so switch the data
396 // provider to internal. Clone is not necessary, as we don't have any
397 // data yet.
398 mxNewDoc->createInternalDataProvider( false /* bCloneExistingData */ );
399 if( xProp.is() && mrDataRowSource!=chart::ChartDataRowSource_COLUMNS )
400 xProp->setPropertyValue("DataRowSource", uno::Any(mrDataRowSource) );
404 css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLPlotAreaContext::createFastChildContext(
405 sal_Int32 nElement,
406 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
408 SvXMLImportContext* pContext = nullptr;
410 switch(nElement)
412 case XML_ELEMENT(CHART_EXT, XML_COORDINATE_REGION):
413 case XML_ELEMENT(CHART, XML_COORDINATE_REGION):
415 pContext = new SchXMLCoordinateRegionContext( GetImport(), m_aInnerPositioning );
417 break;
419 case XML_ELEMENT(CHART, XML_AXIS):
421 bool bAddMissingXAxisForNetCharts = false;
422 bool bAdaptWrongPercentScaleValues = false;
423 if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) )
425 //correct errors from older versions
427 // for NetCharts there were no xAxis exported to older files
428 // so we need to add the x axis here for those old NetChart files
429 if ( maChartTypeServiceName == "com.sun.star.chart2.NetChartType" )
430 bAddMissingXAxisForNetCharts = true;
432 //Issue 59288
433 if( mbPercentStacked )
434 bAdaptWrongPercentScaleValues = true;
437 bool bAdaptXAxisOrientationForOld2DBarCharts = false;
438 if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_4( GetImport().GetModel() ) )
440 //issue74660
441 if ( maChartTypeServiceName == "com.sun.star.chart2.ColumnChartType" )
442 bAdaptXAxisOrientationForOld2DBarCharts = true;
445 pContext = new SchXMLAxisContext( mrImportHelper, GetImport(), mxDiagram, maAxes, mrCategoriesAddress,
446 bAddMissingXAxisForNetCharts, bAdaptWrongPercentScaleValues, bAdaptXAxisOrientationForOld2DBarCharts, m_bAxisPositionAttributeImported );
448 break;
450 case XML_ELEMENT(CHART, XML_SERIES):
452 if( mxNewDoc.is())
454 pContext = new SchXMLSeries2Context(
455 mrImportHelper, GetImport(),
456 mxNewDoc, maAxes,
457 mrSeriesDefaultsAndStyles.maSeriesStyleVector,
458 mrSeriesDefaultsAndStyles.maRegressionStyleVector,
459 mnSeries,
460 mbStockHasVolume,
461 m_aGlobalSeriesImportInfo,
462 maChartTypeServiceName,
463 mrLSequencesPerIndex,
464 mbGlobalChartTypeUsedBySeries, maChartSize );
466 mnSeries++;
468 break;
470 case XML_ELEMENT(CHART, XML_WALL):
471 pContext = new SchXMLWallFloorContext( mrImportHelper, GetImport(), mxDiagram,
472 SchXMLWallFloorContext::CONTEXT_TYPE_WALL );
473 break;
474 case XML_ELEMENT(CHART, XML_FLOOR):
475 pContext = new SchXMLWallFloorContext( mrImportHelper, GetImport(), mxDiagram,
476 SchXMLWallFloorContext::CONTEXT_TYPE_FLOOR );
477 break;
479 case XML_ELEMENT(DR3D, XML_LIGHT):
480 pContext = maSceneImportHelper.create3DLightContext( xAttrList );
481 break;
483 // elements for stock charts
484 case XML_ELEMENT(CHART, XML_STOCK_GAIN_MARKER):
485 pContext = new SchXMLStockContext( mrImportHelper, GetImport(), mxDiagram,
486 SchXMLStockContext::CONTEXT_TYPE_GAIN );
487 break;
488 case XML_ELEMENT(CHART, XML_STOCK_LOSS_MARKER):
489 pContext = new SchXMLStockContext( mrImportHelper, GetImport(), mxDiagram,
490 SchXMLStockContext::CONTEXT_TYPE_LOSS );
491 break;
492 case XML_ELEMENT(CHART, XML_STOCK_RANGE_LINE):
493 pContext = new SchXMLStockContext( mrImportHelper, GetImport(), mxDiagram,
494 SchXMLStockContext::CONTEXT_TYPE_RANGE );
495 break;
496 default:
497 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
500 return pContext;
503 void SchXMLPlotAreaContext::endFastElement(sal_Int32 )
505 // set categories
506 if( !mrCategoriesAddress.isEmpty() && mxNewDoc.is())
508 uno::Reference< chart2::data::XDataProvider > xDataProvider(
509 mxNewDoc->getDataProvider() );
510 // @todo: correct coordinate system index
511 sal_Int32 nDimension( 0 );
512 ::std::vector< SchXMLAxis >::const_iterator aIt(
513 ::std::find_if( maAxes.begin(), maAxes.end(), lcl_AxisHasCategories()));
514 if( aIt != maAxes.end())
515 nDimension = static_cast< sal_Int32 >( (*aIt).eDimension );
516 SchXMLTools::CreateCategories(
517 xDataProvider, mxNewDoc, mrCategoriesAddress,
518 0 /* nCooSysIndex */,
519 nDimension, &mrLSequencesPerIndex );
522 uno::Reference< beans::XPropertySet > xDiaProp( mxDiagram, uno::UNO_QUERY );
523 if( xDiaProp.is())
525 bool bIsThreeDim = false;
526 uno::Any aAny = xDiaProp->getPropertyValue("Dim3D");
527 aAny >>= bIsThreeDim;
529 // set 3d scene attributes
530 if( bIsThreeDim )
532 // set scene attributes at diagram
533 maSceneImportHelper.setSceneAttributes( xDiaProp );
536 // set correct number of lines at series
537 if( ! m_aGlobalSeriesImportInfo.rbAllRangeAddressesAvailable && mnNumOfLinesProp > 0 && maChartTypeServiceName == "com.sun.star.chart2.ColumnChartType" )
541 xDiaProp->setPropertyValue("NumberOfLines",
542 uno::Any( mnNumOfLinesProp ));
544 catch( const uno::Exception & )
546 TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught for property NumberOfLines");
550 // #i32366# stock has volume
551 if( mxDiagram->getDiagramType() == "com.sun.star.chart.StockDiagram" &&
552 mbStockHasVolume )
556 xDiaProp->setPropertyValue("Volume",
557 uno::Any( true ));
559 catch( const uno::Exception & )
561 TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught for property Volume");
566 // set changed size and position after properties (esp. 3d)
568 uno::Reference< chart::XDiagramPositioning > xDiaPos( mxDiagram, uno::UNO_QUERY );
569 if( xDiaPos.is())
571 if( !m_aOuterPositioning.isAutomatic() )
573 if( m_aInnerPositioning.hasPosSize() )
574 xDiaPos->setDiagramPositionExcludingAxes( m_aInnerPositioning.getRectangle() );
575 else if( m_aOuterPositioning.hasPosSize() )
577 if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan3_3( GetImport().GetModel() ) ) //old version of OOo did write a wrong rectangle for the diagram size
578 xDiaPos->setDiagramPositionIncludingAxesAndAxisTitles( m_aOuterPositioning.getRectangle() );
579 else
580 xDiaPos->setDiagramPositionIncludingAxes( m_aOuterPositioning.getRectangle() );
585 SchXMLAxisContext::CorrectAxisPositions( uno::Reference< chart2::XChartDocument >( mrImportHelper.GetChartDocument(), uno::UNO_QUERY ), maChartTypeServiceName, GetImport().GetODFVersion(), m_bAxisPositionAttributeImported );
588 SchXMLDataLabelSpanContext::SchXMLDataLabelSpanContext( SvXMLImport& rImport, ::std::vector<OUString>& rLabels):
589 SvXMLImportContext( rImport ),
590 mrLabels(rLabels)
594 void SchXMLDataLabelSpanContext::characters(const OUString& rChars)
596 maCharBuffer.append(rChars);
599 void SchXMLDataLabelSpanContext::endFastElement(sal_Int32 )
601 mrLabels.push_back(maCharBuffer.makeStringAndClear());
604 SchXMLDataLabelParaContext::SchXMLDataLabelParaContext( SvXMLImport& rImport, ::std::vector<OUString>& rLabels):
605 SvXMLImportContext( rImport ),
606 mrLabels(rLabels)
610 css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLDataLabelParaContext::createFastChildContext(
611 sal_Int32 nElement,
612 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
614 if ( nElement == XML_ELEMENT(TEXT, XML_SPAN) )
615 return new SchXMLDataLabelSpanContext(GetImport(), mrLabels);
616 else
617 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
618 return nullptr;
621 SchXMLDataLabelContext::SchXMLDataLabelContext(SvXMLImport& rImport,
622 CustomLabelsInfo& rLabels,
623 DataRowPointStyle& rDataLabelStyle)
624 : SvXMLImportContext(rImport)
625 , mrLabels(rLabels)
626 , mrDataLabelStyle(rDataLabelStyle)
630 css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLDataLabelContext::createFastChildContext(
631 sal_Int32 nElement,
632 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
634 if ( nElement == XML_ELEMENT(TEXT, XML_P) )
635 return new SchXMLDataLabelParaContext(GetImport(), mrLabels.mLabels);
636 else
637 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
638 return nullptr;
641 void SchXMLDataLabelContext::startFastElement(
642 sal_Int32 /*nElement*/,
643 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
645 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
647 switch(aIter.getToken())
649 case XML_ELEMENT(SVG, XML_X):
650 case XML_ELEMENT(SVG_COMPAT, XML_X):
652 sal_Int32 nResultValue;
653 GetImport().GetMM100UnitConverter().convertMeasureToCore(nResultValue, aIter.toView());
654 mrDataLabelStyle.mo_nLabelAbsolutePosX = nResultValue;
655 break;
657 case XML_ELEMENT(SVG, XML_Y):
658 case XML_ELEMENT(SVG_COMPAT, XML_Y):
660 sal_Int32 nResultValue;
661 GetImport().GetMM100UnitConverter().convertMeasureToCore(nResultValue, aIter.toView());
662 mrDataLabelStyle.mo_nLabelAbsolutePosY = nResultValue;
663 break;
665 case XML_ELEMENT(CHART, XML_STYLE_NAME):
666 mrDataLabelStyle.msStyleName = aIter.toString();
667 break;
668 case XML_ELEMENT(LO_EXT, XML_DATA_LABEL_GUID):
669 mrLabels.msLabelGuid = aIter.toString();
670 mrLabels.mbDataLabelsRange = true;
671 break;
672 case XML_ELEMENT(LO_EXT, XML_DATA_LABELS_CELL_RANGE):
673 mrLabels.msLabelsCellRange = aIter.toString();
674 mrLabels.mbDataLabelsRange = true;
675 break;
676 default:
677 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
683 SchXMLDataPointContext::SchXMLDataPointContext( SvXMLImport& rImport,
684 ::std::vector< DataRowPointStyle >& rStyleVector,
685 const css::uno::Reference< css::chart2::XDataSeries >& xSeries,
686 sal_Int32& rIndex,
687 bool bSymbolSizeForSeriesIsMissingInFile ) :
688 SvXMLImportContext( rImport ),
689 mrStyleVector( rStyleVector ),
690 mrIndex( rIndex ),
691 mDataPoint(DataRowPointStyle::DATA_POINT, xSeries, rIndex, 1, OUString{}),
692 mDataLabel(DataRowPointStyle::DATA_LABEL_POINT, xSeries, rIndex, 1, OUString{})
694 mDataPoint.mbSymbolSizeForSeriesIsMissingInFile = bSymbolSizeForSeriesIsMissingInFile;
697 css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLDataPointContext::createFastChildContext(
698 sal_Int32 nElement,
699 const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
701 SvXMLImportContext* pContext = nullptr;
702 switch(nElement)
704 case XML_ELEMENT(CHART, XML_DATA_LABEL):
705 mbHasLabelParagraph = true;
706 pContext = new SchXMLDataLabelContext(GetImport(), mDataPoint.mCustomLabels,
707 mDataLabel);
708 break;
709 default:
710 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
712 return pContext;
715 SchXMLDataPointContext::~SchXMLDataPointContext()
719 void SchXMLDataPointContext::startFastElement (sal_Int32 /*Element*/,
720 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
722 OUString sAutoStyleName;
723 sal_Int32 nRepeat = 1;
724 OUString sCustomLabelField;
726 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
728 switch (aIter.getToken())
730 case XML_ELEMENT(CHART, XML_STYLE_NAME):
732 sAutoStyleName = aIter.toString();
733 mDataPoint.msStyleName = sAutoStyleName;
734 mDataLabel.msStyleNameOfParent = sAutoStyleName;
735 break;
737 case XML_ELEMENT(CHART, XML_REPEATED):
739 nRepeat = aIter.toInt32();
740 mDataPoint.m_nPointRepeat = nRepeat;
741 mDataLabel.m_nPointRepeat = nRepeat;
742 break;
744 // Deprecated. New documents use the chart:data-label element
745 // instead in order to store custom label text.
746 case XML_ELEMENT(LO_EXT, XML_CUSTOM_LABEL_FIELD):
747 if (!mbHasLabelParagraph)
749 sCustomLabelField = aIter.toString();
750 mDataPoint.mCustomLabels.mLabels.push_back(sCustomLabelField);
752 break;
753 case XML_ELEMENT(LO_EXT, XML_HIDE_LEGEND):
755 bool bHideLegend = aIter.toBoolean();
756 if (bHideLegend)
758 uno::Sequence<sal_Int32> deletedLegendEntriesSeq;
759 Reference<beans::XPropertySet> xSeriesProp(mDataPoint.m_xSeries, uno::UNO_QUERY);
760 xSeriesProp->getPropertyValue("DeletedLegendEntries") >>= deletedLegendEntriesSeq;
761 std::vector<sal_Int32> deletedLegendEntries;
762 for (const auto& deletedLegendEntry : std::as_const(deletedLegendEntriesSeq))
764 deletedLegendEntries.push_back(deletedLegendEntry);
766 deletedLegendEntries.push_back(mDataPoint.m_nPointIndex);
767 xSeriesProp->setPropertyValue("DeletedLegendEntries", uno::Any(comphelper::containerToSequence(deletedLegendEntries)));
769 break;
771 case XML_ELEMENT(LO_EXT, XML_CUSTOM_LABEL_POS_X):
773 mDataPoint.mCustomLabelPos[0] = aIter.toDouble();
774 break;
776 case XML_ELEMENT(LO_EXT, XML_CUSTOM_LABEL_POS_Y):
778 mDataPoint.mCustomLabelPos[1] = aIter.toDouble();
779 break;
781 default:
782 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
786 mrIndex += nRepeat;
789 void SchXMLDataPointContext::endFastElement(sal_Int32 )
791 if(!mDataPoint.msStyleName.isEmpty() || mDataPoint.mCustomLabels.mLabels.size() > 0)
793 mrStyleVector.push_back(mDataPoint);
795 if (!mDataLabel.msStyleName.isEmpty() || mDataLabel.mo_nLabelAbsolutePosX.has_value()
796 || mDataLabel.mo_nLabelAbsolutePosY.has_value())
798 mrStyleVector.push_back(mDataLabel);
802 SchXMLPositionAttributesHelper::SchXMLPositionAttributesHelper( SvXMLImport& rImporter )
803 : m_rImport( rImporter )
804 , m_aPosition(0,0)
805 , m_aSize(0,0)
806 , m_bHasSizeWidth( false )
807 , m_bHasSizeHeight( false )
808 , m_bHasPositionX( false )
809 , m_bHasPositionY( false )
810 , m_bAutoSize( false )
811 , m_bAutoPosition( false )
815 bool SchXMLPositionAttributesHelper::hasPosSize() const
817 return (m_bHasPositionX && m_bHasPositionY) && (m_bHasSizeWidth && m_bHasSizeHeight);
820 bool SchXMLPositionAttributesHelper::isAutomatic() const
822 return m_bAutoSize || m_bAutoPosition;
825 void SchXMLPositionAttributesHelper::readPositioningAttribute( sal_Int32 nAttributeToken, std::string_view rValue )
827 if( !IsTokenInNamespace(nAttributeToken, XML_NAMESPACE_SVG) && !IsTokenInNamespace(nAttributeToken, XML_NAMESPACE_SVG_COMPAT) )
828 return;
830 switch (nAttributeToken & TOKEN_MASK)
832 case XML_X:
834 m_rImport.GetMM100UnitConverter().convertMeasureToCore(
835 m_aPosition.X, rValue );
836 m_bHasPositionX = true;
837 break;
839 case XML_Y:
841 m_rImport.GetMM100UnitConverter().convertMeasureToCore(
842 m_aPosition.Y, rValue );
843 m_bHasPositionY = true;
844 break;
846 case XML_WIDTH:
848 m_rImport.GetMM100UnitConverter().convertMeasureToCore(
849 m_aSize.Width, rValue );
850 m_bHasSizeWidth = true;
851 break;
853 case XML_HEIGHT:
855 m_rImport.GetMM100UnitConverter().convertMeasureToCore(
856 m_aSize.Height, rValue );
857 m_bHasSizeHeight = true;
858 break;
860 default:
861 XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttributeToken, OUString::fromUtf8(rValue));
865 void SchXMLPositionAttributesHelper::readAutomaticPositioningProperties( XMLPropStyleContext const * pPropStyleContext, const SvXMLStylesContext* pStylesCtxt )
867 if( pPropStyleContext && pStylesCtxt )
869 //handle automatic position and size
870 SchXMLTools::getPropertyFromContext(
871 u"AutomaticSize", pPropStyleContext, pStylesCtxt ) >>= m_bAutoSize;
872 SchXMLTools::getPropertyFromContext(
873 u"AutomaticPosition", pPropStyleContext, pStylesCtxt ) >>= m_bAutoPosition;
877 SchXMLCoordinateRegionContext::SchXMLCoordinateRegionContext(
878 SvXMLImport& rImport
879 , SchXMLPositionAttributesHelper& rPositioning )
880 : SvXMLImportContext( rImport )
881 , m_rPositioning( rPositioning )
885 SchXMLCoordinateRegionContext::~SchXMLCoordinateRegionContext()
889 void SchXMLCoordinateRegionContext::startFastElement (sal_Int32 /*Element*/,
890 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
892 // parse attributes
893 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
894 m_rPositioning.readPositioningAttribute( aIter.getToken(), aIter.toView() );
897 SchXMLWallFloorContext::SchXMLWallFloorContext(
898 SchXMLImportHelper& rImpHelper,
899 SvXMLImport& rImport,
900 uno::Reference< chart::XDiagram > const & xDiagram,
901 ContextType eContextType ) :
902 SvXMLImportContext( rImport ),
903 mrImportHelper( rImpHelper ),
904 mxWallFloorSupplier( xDiagram, uno::UNO_QUERY ),
905 meContextType( eContextType )
909 SchXMLWallFloorContext::~SchXMLWallFloorContext()
913 void SchXMLWallFloorContext::startFastElement (sal_Int32 /*Element*/,
914 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
916 if( !mxWallFloorSupplier.is())
917 return;
919 OUString sAutoStyleName;
921 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
923 if( aIter.getToken() == XML_ELEMENT(CHART, XML_STYLE_NAME) )
924 sAutoStyleName = aIter.toString();
925 else
926 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
929 // set properties
930 uno::Reference< beans::XPropertySet > xProp = ( meContextType == CONTEXT_TYPE_WALL )
931 ? mxWallFloorSupplier->getWall()
932 : mxWallFloorSupplier->getFloor();
934 if (!sAutoStyleName.isEmpty())
935 mrImportHelper.FillAutoStyle(sAutoStyleName, xProp);
938 SchXMLStockContext::SchXMLStockContext(
939 SchXMLImportHelper& rImpHelper,
940 SvXMLImport& rImport,
941 uno::Reference< chart::XDiagram > const & xDiagram,
942 ContextType eContextType ) :
943 SvXMLImportContext( rImport ),
944 mrImportHelper( rImpHelper ),
945 mxStockPropProvider( xDiagram, uno::UNO_QUERY ),
946 meContextType( eContextType )
950 SchXMLStockContext::~SchXMLStockContext()
954 void SchXMLStockContext::startFastElement (sal_Int32 /*Element*/,
955 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
957 if( !mxStockPropProvider.is())
958 return;
960 OUString sAutoStyleName;
962 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
964 if( aIter.getToken() == XML_ELEMENT(CHART, XML_STYLE_NAME) )
965 sAutoStyleName = aIter.toString();
966 else
967 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
970 if( sAutoStyleName.isEmpty())
971 return;
973 // set properties
974 uno::Reference< beans::XPropertySet > xProp;
975 switch( meContextType )
977 case CONTEXT_TYPE_GAIN:
978 xProp = mxStockPropProvider->getUpBar();
979 break;
980 case CONTEXT_TYPE_LOSS:
981 xProp = mxStockPropProvider->getDownBar();
982 break;
983 case CONTEXT_TYPE_RANGE:
984 xProp = mxStockPropProvider->getMinMaxLine();
985 break;
988 mrImportHelper.FillAutoStyle(sAutoStyleName, xProp);
991 static void lcl_setErrorBarSequence ( const uno::Reference< chart2::XChartDocument > &xDoc,
992 const uno::Reference< beans::XPropertySet > &xBarProp,
993 const OUString &aXMLRange,
994 bool bPositiveValue, bool bYError,
995 tSchXMLLSequencesPerIndex& rSequences)
997 uno::Reference< css::chart2::data::XDataProvider > xDataProvider(xDoc->getDataProvider());
998 uno::Reference< css::chart2::data::XDataSource > xDataSource( xBarProp, uno::UNO_QUERY );
999 uno::Reference< css::chart2::data::XDataSink > xDataSink( xDataSource, uno::UNO_QUERY );
1001 assert( xDataSink.is() && xDataSource.is() && xDataProvider.is() );
1003 OUString aRange(lcl_ConvertRange(aXMLRange,xDoc));
1005 uno::Reference< chart2::data::XDataSequence > xNewSequence(
1006 xDataProvider->createDataSequenceByRangeRepresentation( aRange ));
1008 if( !xNewSequence.is())
1009 return;
1011 SchXMLTools::setXMLRangePropertyAtDataSequence(xNewSequence,aXMLRange);
1013 OUStringBuffer aRoleBuffer("error-bars-");
1014 if( bYError )
1015 aRoleBuffer.append( 'y' );
1016 else
1017 aRoleBuffer.append( 'x');
1019 aRoleBuffer.append( '-' );
1021 if( bPositiveValue )
1022 aRoleBuffer = aRoleBuffer.append( "positive" );
1023 else
1024 aRoleBuffer = aRoleBuffer.append( "negative" );
1026 OUString aRole = aRoleBuffer.makeStringAndClear();
1028 Reference< beans::XPropertySet > xSeqProp( xNewSequence, uno::UNO_QUERY );
1030 xSeqProp->setPropertyValue("Role", uno::Any( aRole ));
1032 Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
1034 Reference< chart2::data::XLabeledDataSequence > xLabelSeq( chart2::data::LabeledDataSequence::create(xContext),
1035 uno::UNO_QUERY_THROW );
1037 rSequences.emplace( tSchXMLIndexWithPart( -2, SCH_XML_PART_ERROR_BARS ), xLabelSeq );
1039 xLabelSeq->setValues( xNewSequence );
1041 uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences(
1042 xDataSource->getDataSequences());
1044 aSequences.realloc( aSequences.getLength() + 1 );
1045 aSequences.getArray()[ aSequences.getLength() - 1 ] = xLabelSeq;
1046 xDataSink->setData( aSequences );
1050 SchXMLStatisticsObjectContext::SchXMLStatisticsObjectContext(
1051 SchXMLImportHelper& rImpHelper,
1052 SvXMLImport& rImport,
1053 OUString sSeriesStyleName,
1054 ::std::vector< DataRowPointStyle >& rStyleVector,
1055 css::uno::Reference< css::chart2::XDataSeries > xSeries,
1056 ContextType eContextType,
1057 tSchXMLLSequencesPerIndex & rLSequencesPerIndex) :
1059 SvXMLImportContext( rImport ),
1060 mrImportHelper( rImpHelper ),
1061 mrStyleVector( rStyleVector ),
1062 m_xSeries(std::move( xSeries )),
1063 meContextType( eContextType ),
1064 maSeriesStyleName(std::move( sSeriesStyleName)),
1065 mrLSequencesPerIndex(rLSequencesPerIndex)
1068 SchXMLStatisticsObjectContext::~SchXMLStatisticsObjectContext()
1072 namespace {
1074 void SetErrorBarStyleProperties( const OUString& rStyleName, const uno::Reference< beans::XPropertySet >& xBarProp,
1075 SchXMLImportHelper const & rImportHelper )
1077 const SvXMLStylesContext* pStylesCtxt = rImportHelper.GetAutoStylesContext();
1078 const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(SchXMLImportHelper::GetChartFamilyID(),
1079 rStyleName);
1081 XMLPropStyleContext &rSeriesStyleContext =
1082 const_cast< XMLPropStyleContext& >( dynamic_cast< const XMLPropStyleContext& >( *pStyle ));
1084 rSeriesStyleContext.FillPropertySet( xBarProp );
1087 void SetErrorBarPropertiesFromStyleName( const OUString& aStyleName, const uno::Reference< beans::XPropertySet>& xBarProp,
1088 SchXMLImportHelper const & rImportHelper, OUString& aPosRange, OUString& aNegRange)
1090 const SvXMLStylesContext* pStylesCtxt = rImportHelper.GetAutoStylesContext();
1091 const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(SchXMLImportHelper::GetChartFamilyID(),
1092 aStyleName);
1094 XMLPropStyleContext * pSeriesStyleContext =
1095 const_cast< XMLPropStyleContext * >( dynamic_cast< const XMLPropStyleContext * >( pStyle ));
1097 uno::Any aAny = SchXMLTools::getPropertyFromContext(u"ErrorBarStyle",
1098 pSeriesStyleContext,pStylesCtxt);
1100 if ( !aAny.hasValue() )
1101 return;
1103 sal_Int32 aBarStyle = css::chart::ErrorBarStyle::NONE;
1104 aAny >>= aBarStyle;
1105 xBarProp->setPropertyValue("ErrorBarStyle", aAny);
1107 aAny = SchXMLTools::getPropertyFromContext(u"ShowPositiveError",
1108 pSeriesStyleContext,pStylesCtxt);
1110 if(aAny.hasValue())
1111 xBarProp->setPropertyValue("ShowPositiveError",aAny);
1113 aAny = SchXMLTools::getPropertyFromContext(u"ShowNegativeError",
1114 pSeriesStyleContext,pStylesCtxt);
1116 if(aAny.hasValue())
1117 xBarProp->setPropertyValue("ShowNegativeError",aAny);
1119 aAny = SchXMLTools::getPropertyFromContext(u"PositiveError",
1120 pSeriesStyleContext, pStylesCtxt);
1122 if(aAny.hasValue())
1123 xBarProp->setPropertyValue("PositiveError", aAny);
1124 else
1126 aAny = SchXMLTools::getPropertyFromContext(u"ConstantErrorHigh",
1127 pSeriesStyleContext, pStylesCtxt);
1129 if(aAny.hasValue())
1130 xBarProp->setPropertyValue("PositiveError", aAny);
1133 aAny = SchXMLTools::getPropertyFromContext(u"NegativeError",
1134 pSeriesStyleContext, pStylesCtxt);
1136 if(aAny.hasValue())
1137 xBarProp->setPropertyValue("NegativeError", aAny);
1138 else
1140 aAny = SchXMLTools::getPropertyFromContext(u"ConstantErrorLow",
1141 pSeriesStyleContext, pStylesCtxt);
1143 if(aAny.hasValue())
1144 xBarProp->setPropertyValue("NegativeError", aAny);
1147 aAny = SchXMLTools::getPropertyFromContext(u"ErrorBarRangePositive",
1148 pSeriesStyleContext, pStylesCtxt);
1149 if( aAny.hasValue() )
1151 aAny >>= aPosRange;
1154 aAny = SchXMLTools::getPropertyFromContext(u"ErrorBarRangeNegative",
1155 pSeriesStyleContext, pStylesCtxt);
1156 if( aAny.hasValue() )
1158 aAny >>= aNegRange;
1161 aAny = SchXMLTools::getPropertyFromContext(u"Weight",
1162 pSeriesStyleContext, pStylesCtxt);
1163 if( aAny.hasValue() )
1165 xBarProp->setPropertyValue("Weight", aAny);
1168 aAny = SchXMLTools::getPropertyFromContext(u"PercentageError",
1169 pSeriesStyleContext, pStylesCtxt);
1170 if( aAny.hasValue() && aBarStyle == css::chart::ErrorBarStyle::RELATIVE )
1172 xBarProp->setPropertyValue("PositiveError", aAny);
1173 xBarProp->setPropertyValue("NegativeError", aAny);
1176 switch(aBarStyle)
1178 case css::chart::ErrorBarStyle::ERROR_MARGIN:
1180 aAny = SchXMLTools::getPropertyFromContext(u"NegativeError",
1181 pSeriesStyleContext,pStylesCtxt);
1183 xBarProp->setPropertyValue("NegativeError",aAny);
1185 aAny = SchXMLTools::getPropertyFromContext(u"PositiveError",
1186 pSeriesStyleContext,pStylesCtxt);
1188 xBarProp->setPropertyValue("PositiveError",aAny);
1190 break;
1191 default:
1192 break;
1199 void SchXMLStatisticsObjectContext::startFastElement (sal_Int32 /*Element*/,
1200 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1202 OUString sAutoStyleName;
1203 OUString aPosRange;
1204 OUString aNegRange;
1205 bool bYError = true; /// Default errorbar, to be backward compatible with older files!
1207 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
1209 switch (aIter.getToken())
1211 case XML_ELEMENT(CHART, XML_STYLE_NAME):
1212 sAutoStyleName = aIter.toString();
1213 break;
1214 case XML_ELEMENT(CHART, XML_DIMENSION):
1215 bYError = aIter.toView() == "y";
1216 break;
1217 case XML_ELEMENT(CHART, XML_ERROR_UPPER_RANGE):
1218 aPosRange = aIter.toString();
1219 break;
1220 case XML_ELEMENT(CHART, XML_ERROR_LOWER_RANGE):
1221 aNegRange = aIter.toString();
1222 break;
1226 if( sAutoStyleName.isEmpty() )
1227 return;
1229 DataRowPointStyle aStyle( DataRowPointStyle::MEAN_VALUE, m_xSeries, -1, 1, sAutoStyleName );
1231 switch( meContextType )
1233 case CONTEXT_TYPE_MEAN_VALUE_LINE:
1234 aStyle.meType = DataRowPointStyle::MEAN_VALUE;
1235 break;
1236 case CONTEXT_TYPE_ERROR_INDICATOR:
1238 aStyle.meType = DataRowPointStyle::ERROR_INDICATOR;
1240 uno::Reference< lang::XMultiServiceFactory > xFact = comphelper::getProcessServiceFactory();
1242 uno::Reference< beans::XPropertySet > xBarProp( xFact->createInstance("com.sun.star.chart2.ErrorBar" ),
1243 uno::UNO_QUERY );
1245 xBarProp->setPropertyValue("ErrorBarStyle",uno::Any(css::chart::ErrorBarStyle::NONE));
1246 xBarProp->setPropertyValue("PositiveError",uno::Any(0.0));
1247 xBarProp->setPropertyValue("NegativeError",uno::Any(0.0));
1248 xBarProp->setPropertyValue("Weight",uno::Any(1.0));
1249 xBarProp->setPropertyValue("ShowPositiveError",uno::Any(true));
1250 xBarProp->setPropertyValue("ShowNegativeError",uno::Any(true));
1252 // first import defaults from parent style
1253 SetErrorBarStyleProperties( maSeriesStyleName, xBarProp, mrImportHelper );
1254 SetErrorBarStyleProperties( sAutoStyleName, xBarProp, mrImportHelper );
1255 SetErrorBarPropertiesFromStyleName( maSeriesStyleName, xBarProp, mrImportHelper, aPosRange, aNegRange );
1256 SetErrorBarPropertiesFromStyleName( sAutoStyleName, xBarProp, mrImportHelper, aPosRange, aNegRange );
1258 uno::Reference< chart2::XChartDocument > xDoc(GetImport().GetModel(),uno::UNO_QUERY);
1260 if (!aPosRange.isEmpty())
1261 lcl_setErrorBarSequence(xDoc,xBarProp,aPosRange,true,bYError, mrLSequencesPerIndex);
1263 if (!aNegRange.isEmpty())
1264 lcl_setErrorBarSequence(xDoc,xBarProp,aNegRange,false,bYError, mrLSequencesPerIndex);
1266 if ( !bYError )
1268 aStyle.m_xErrorXProperties.set( xBarProp );
1270 else
1272 aStyle.m_xErrorYProperties.set( xBarProp );
1275 break;
1278 mrStyleVector.push_back( aStyle );
1281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */