LibreOffice Module xmloff (master)  1
SchXMLSeries2Context.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include "SchXMLSeries2Context.hxx"
24 #include "SchXMLTools.hxx"
25 
26 #include <com/sun/star/chart2/XChartDocument.hpp>
27 #include <com/sun/star/chart2/XRegressionCurve.hpp>
28 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
29 #include <com/sun/star/chart2/data/XDataSink.hpp>
30 #include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
31 #include <com/sun/star/chart2/RelativePosition.hpp>
32 
33 #include <com/sun/star/chart2/XDataPointCustomLabelField.hpp>
34 #include <com/sun/star/chart2/DataPointCustomLabelFieldType.hpp>
35 #include <com/sun/star/chart2/DataPointCustomLabelField.hpp>
36 
37 #include <com/sun/star/chart/ChartAxisAssign.hpp>
38 #include <com/sun/star/chart/ChartSymbolType.hpp>
39 #include <com/sun/star/chart/ChartDataCaption.hpp>
40 #include <com/sun/star/chart/ErrorBarStyle.hpp>
41 #include <com/sun/star/chart/XChartDocument.hpp>
42 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 #include <com/sun/star/chart/ChartLegendPosition.hpp>
44 #include <com/sun/star/embed/Aspects.hpp>
45 #include <com/sun/star/embed/XVisualObject.hpp>
46 
48 
49 #include <sal/log.hxx>
50 #include <xmloff/xmlnamespace.hxx>
51 #include <xmloff/xmlimp.hxx>
52 #include <xmloff/namespacemap.hxx>
54 #include <SchXMLImport.hxx>
55 #include <xmloff/prstylei.hxx>
56 #include <tools/diagnose_ex.h>
57 
58 #include <algorithm> // std::find_if
59 
60 using namespace ::com::sun::star;
61 using namespace ::xmloff::token;
62 
63 using ::com::sun::star::uno::Reference;
64 using ::com::sun::star::uno::Sequence;
65 
66 namespace
67 {
68 
69 class SchXMLDomain2Context : public SvXMLImportContext
70 {
71 private:
72  ::std::vector< OUString > & mrAddresses;
73 
74 public:
75  SchXMLDomain2Context( SvXMLImport& rImport,
76  ::std::vector< OUString > & rAddresses );
77  virtual void SAL_CALL startFastElement(
78  sal_Int32 nElement,
79  const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
80 };
81 
82 SchXMLDomain2Context::SchXMLDomain2Context(
83  SvXMLImport& rImport,
84  ::std::vector< OUString > & rAddresses ) :
85  SvXMLImportContext( rImport ),
86  mrAddresses( rAddresses )
87 {
88 }
89 
90 void SchXMLDomain2Context::startFastElement(
91  sal_Int32 /*nElement*/,
92  const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
93 {
94  for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
95  {
96  if (aIter.getToken() == XML_ELEMENT(TABLE, XML_CELL_RANGE_ADDRESS) )
97  mrAddresses.push_back( aIter.toString() );
98  else
99  XMLOFF_WARN_UNKNOWN("xmloff", aIter);
100  }
101 }
102 
103 void lcl_setAutomaticSymbolSize( const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp, const SvXMLImport& rImport )
104 {
105  awt::Size aSymbolSize(140,140);//old default for standard sized charts 7cm height
106 
107  uno::Reference< chart::XChartDocument > xChartDoc( rImport.GetModel(), uno::UNO_QUERY );
108  if( xChartDoc.is() )
109  {
110  double fScale = 1;
111  uno::Reference< beans::XPropertySet > xLegendProp( xChartDoc->getLegend(), uno::UNO_QUERY );
112  chart::ChartLegendPosition aLegendPosition = chart::ChartLegendPosition_NONE;
113  if( xLegendProp.is() && (xLegendProp->getPropertyValue("Alignment") >>= aLegendPosition)
114  && chart::ChartLegendPosition_NONE != aLegendPosition )
115  {
116 
117  double fFontHeight = 6.0;
118  if( xLegendProp->getPropertyValue("CharHeight") >>= fFontHeight )
119  fScale = 0.75*fFontHeight/6.0;
120  }
121  else
122  {
123  uno::Reference< embed::XVisualObject > xVisualObject( rImport.GetModel(), uno::UNO_QUERY );
124  if( xVisualObject.is() )
125  {
126  awt::Size aPageSize( xVisualObject->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) );
127  fScale = aPageSize.Height/7000.0;
128  }
129  }
130  if( fScale>0 )
131  {
132  aSymbolSize.Height = static_cast<sal_Int32>( fScale * aSymbolSize.Height );
133  aSymbolSize.Width = aSymbolSize.Height;
134  }
135  }
136  xSeriesOrPointProp->setPropertyValue("SymbolSize",uno::makeAny( aSymbolSize ));
137 }
138 
139 void lcl_setSymbolSizeIfNeeded( const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp, const SvXMLImport& rImport )
140 {
141  if( !xSeriesOrPointProp.is() )
142  return;
143 
144  sal_Int32 nSymbolType = chart::ChartSymbolType::NONE;
145  if( !(xSeriesOrPointProp.is() && ( xSeriesOrPointProp->getPropertyValue("SymbolType") >>= nSymbolType)) )
146  return;
147 
148  if(chart::ChartSymbolType::NONE!=nSymbolType)
149  {
150  if( chart::ChartSymbolType::BITMAPURL==nSymbolType )
151  {
152  //set special size for graphics to indicate to use the bitmap size itself
153  xSeriesOrPointProp->setPropertyValue("SymbolSize",uno::makeAny( awt::Size(-1,-1) ));
154  }
155  else
156  {
157  lcl_setAutomaticSymbolSize( xSeriesOrPointProp, rImport );
158  }
159  }
160 }
161 
162 void lcl_resetSymbolSizeForPointsIfNecessary( const uno::Reference< beans::XPropertySet >& xPointProp, const SvXMLImport& rImport
163  , const XMLPropStyleContext * pPropStyleContext, const SvXMLStylesContext* pStylesCtxt )
164 {
165  uno::Any aASymbolSize( SchXMLTools::getPropertyFromContext( u"SymbolSize", pPropStyleContext, pStylesCtxt ) );
166  if( !aASymbolSize.hasValue() )
167  lcl_setSymbolSizeIfNeeded( xPointProp, rImport );
168 }
169 
170 void lcl_setLinkNumberFormatToSourceIfNeeded( const uno::Reference< beans::XPropertySet >& xPointProp
171  , const XMLPropStyleContext* pPropStyleContext, const SvXMLStylesContext* pStylesCtxt )
172 {
173  uno::Any aAny( SchXMLTools::getPropertyFromContext(u"LinkNumberFormatToSource", pPropStyleContext, pStylesCtxt) );
174  if( aAny.hasValue() )
175  return;
176 
177  if( !xPointProp.is() )
178  return;
179 
180  bool bLinkToSource = false;
181  if( xPointProp.is() && (xPointProp->getPropertyValue("LinkNumberFormatToSource") >>= bLinkToSource) )
182  {
183  if( bLinkToSource )
184  {
185  xPointProp->setPropertyValue("LinkNumberFormatToSource", uno::makeAny(false));
186  }
187  }
188 }
189 
190 void lcl_insertErrorBarLSequencesToMap(
191  tSchXMLLSequencesPerIndex & rInOutMap,
192  const uno::Reference< beans::XPropertySet > & xSeriesProp )
193 {
194  Reference< chart2::data::XDataSource > xErrorBarSource;
195  if( ( xSeriesProp->getPropertyValue( "ErrorBarY" ) >>= xErrorBarSource ) &&
196  xErrorBarSource.is() )
197  {
198  const Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSequences(
199  xErrorBarSource->getDataSequences());
200  for( const auto& rLSequence : aLSequences )
201  {
202  // use "0" as data index. This is ok, as it is not used for error bars
203  rInOutMap.emplace(
204  tSchXMLIndexWithPart( 0, SCH_XML_PART_ERROR_BARS ), rLSequence );
205  }
206  }
207 }
208 
209 Reference< chart2::data::XLabeledDataSequence2 > lcl_createAndAddSequenceToSeries( const OUString& rRole
210  , const OUString& rRange
211  , const Reference< chart2::XChartDocument >& xChartDoc
212  , const Reference< chart2::XDataSeries >& xSeries )
213 {
214  Reference< chart2::data::XLabeledDataSequence2 > xLabeledSeq;
215 
216  Reference< chart2::data::XDataSource > xSeriesSource( xSeries,uno::UNO_QUERY );
217  Reference< chart2::data::XDataSink > xSeriesSink( xSeries, uno::UNO_QUERY );
218 
219  if( !(!rRange.isEmpty() && xChartDoc.is() && xSeriesSource.is() && xSeriesSink.is()) )
220  return xLabeledSeq;
221 
222  // create a new sequence
224 
225  // set values at the new sequence
226  Reference< chart2::data::XDataSequence > xSeq = SchXMLTools::CreateDataSequence( rRange, xChartDoc );
227  Reference< beans::XPropertySet > xSeqProp( xSeq, uno::UNO_QUERY );
228  if( xSeqProp.is())
229  xSeqProp->setPropertyValue("Role", uno::makeAny( rRole));
230  xLabeledSeq->setValues( xSeq );
231 
232  // add new sequence to data series / push to front to have the correct sequence order if charttype is changed afterwards
233  Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeq( xSeriesSource->getDataSequences());
234  sal_Int32 nOldCount = aOldSeq.getLength();
235  Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeq( nOldCount + 1 );
236  aNewSeq[0].set(xLabeledSeq, uno::UNO_QUERY_THROW);
237  std::copy(aOldSeq.begin(), aOldSeq.end(), std::next(aNewSeq.begin()));
238  xSeriesSink->setData( aNewSeq );
239 
240  return xLabeledSeq;
241 }
242 
243 XMLPropStyleContext* lcl_GetStylePropContext(
244  const SvXMLStylesContext* pStylesCtxt,
245  const SvXMLStyleContext*& rpStyle,
246  OUString const & rStyleName )
247 {
248  rpStyle = pStylesCtxt->FindStyleChildContext( SchXMLImportHelper::GetChartFamilyID(), rStyleName );
249  XMLPropStyleContext* pPropStyleContext =
250  const_cast< XMLPropStyleContext* >(dynamic_cast< const XMLPropStyleContext* >( rpStyle ));
251  return pPropStyleContext;
252 }
253 
254 } // anonymous namespace
255 
257  SchXMLImportHelper& rImpHelper,
258  SvXMLImport& rImport,
259  const Reference< chart2::XChartDocument > & xNewDoc,
260  std::vector< SchXMLAxis >& rAxes,
261  ::std::vector< DataRowPointStyle >& rStyleVector,
262  ::std::vector< RegressionStyle >& rRegressionStyleVector,
263  sal_Int32 nSeriesIndex,
264  bool bStockHasVolume,
265  GlobalSeriesImportInfo& rGlobalSeriesImportInfo,
266  const OUString & aGlobalChartTypeName,
267  tSchXMLLSequencesPerIndex & rLSequencesPerIndex,
268  bool& rGlobalChartTypeUsedBySeries,
269  const awt::Size & rChartSize ) :
270  SvXMLImportContext( rImport ),
271  mrImportHelper( rImpHelper ),
272  mxNewDoc( xNewDoc ),
273  mrAxes( rAxes ),
274  mrStyleVector( rStyleVector ),
275  mrRegressionStyleVector( rRegressionStyleVector ),
276  mnSeriesIndex( nSeriesIndex ),
277  mnDataPointIndex( 0 ),
278  m_bStockHasVolume( bStockHasVolume ),
279  m_rGlobalSeriesImportInfo(rGlobalSeriesImportInfo),
280  mpAttachedAxis( nullptr ),
281  mnAttachedAxis( 0 ),
282  maGlobalChartTypeName( aGlobalChartTypeName ),
283  maSeriesChartTypeName( aGlobalChartTypeName ),
284  m_bHasDomainContext(false),
285  mrLSequencesPerIndex( rLSequencesPerIndex ),
286  mrGlobalChartTypeUsedBySeries( rGlobalChartTypeUsedBySeries ),
287  mbSymbolSizeIsMissingInFile(false),
288  maChartSize( rChartSize ),
289  // A series manages the DataRowPointStyle-struct of a data-label child element.
290  mDataLabel(DataRowPointStyle::DATA_LABEL_SERIES, OUString{})
291 {
292  if( aGlobalChartTypeName == "com.sun.star.chart2.DonutChartType" )
293  {
294  maSeriesChartTypeName = "com.sun.star.chart2.PieChartType";
295  maGlobalChartTypeName = maSeriesChartTypeName;
296  }
297 }
298 
300 {
301  SAL_WARN_IF( !maPostponedSequences.empty(), "xmloff.chart", "maPostponedSequences is NULL");
302 }
303 
304 void SchXMLSeries2Context::startFastElement (sal_Int32 /*Element*/,
305  const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
306 {
307  // parse attributes
308  mnAttachedAxis = 1;
309 
310  bool bHasRange = false;
311  OUString aSeriesLabelRange;
312  OUString aSeriesLabelString;
313  bool bHideLegend = false;
314 
315  for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
316  {
317  OUString aValue = aIter.toString();
318  switch(aIter.getToken())
319  {
321  m_aSeriesRange = aValue;
322  bHasRange = true;
323  break;
325  aSeriesLabelRange = aValue;
326  break;
327  case XML_ELEMENT(LO_EXT, XML_LABEL_STRING):
328  aSeriesLabelString = aValue;
329  break;
331  {
332  sal_Int32 nNumOfAxes = mrAxes.size();
333  for( sal_Int32 nCurrent = 0; nCurrent < nNumOfAxes; nCurrent++ )
334  {
335  if( aValue == mrAxes[ nCurrent ].aName &&
336  mrAxes[ nCurrent ].eDimension == SCH_XML_AXIS_Y )
337  {
338  mpAttachedAxis = &( mrAxes[ nCurrent ] );
339  }
340  }
341  }
342  break;
344  msAutoStyleName = aValue;
345  break;
346  case XML_ELEMENT(CHART, XML_CLASS):
347  {
348  OUString aClassName;
349  sal_uInt16 nClassPrefix =
351  aValue, &aClassName );
352  if( XML_NAMESPACE_CHART == nClassPrefix )
353  maSeriesChartTypeName = SchXMLTools::GetChartTypeByClassName( aClassName, false /* bUseOldNames */ );
354 
355  if( maSeriesChartTypeName.isEmpty())
356  maSeriesChartTypeName = aClassName;
357  }
358  break;
359  case XML_ELEMENT(LO_EXT, XML_HIDE_LEGEND):
360  bHideLegend = aValue.toBoolean();
361  break;
362  default:
363  XMLOFF_WARN_UNKNOWN("xmloff", aIter);
364  }
365  }
366 
367  if( mpAttachedAxis )
368  {
369  if( mpAttachedAxis->nAxisIndex > 0 )
370  {
371  // secondary axis => property has to be set (primary is default)
372  mnAttachedAxis = 2;
373  }
374  }
375 
376  try
377  {
378  SAL_WARN_IF( !mxNewDoc.is(), "xmloff.chart", "mxNewDoc is NULL");
381 
382  bool bIsCandleStick = maGlobalChartTypeName == "com.sun.star.chart2.CandleStickChartType";
383  if( !maSeriesChartTypeName.isEmpty() )
384  {
385  bIsCandleStick = maSeriesChartTypeName == "com.sun.star.chart2.CandleStickChartType";
386  }
387  else
388  {
389  if( bIsCandleStick
391  && mnSeriesIndex == 0 )
392  {
393  maSeriesChartTypeName = "com.sun.star.chart2.ColumnChartType";
394  bIsCandleStick = false;
395  }
396  else
397  {
399  }
400  }
403  sal_Int32 const nCoordinateSystemIndex = 0;//so far we can only import one coordinate system
404  m_xSeries.set(
407 
408  Reference< beans::XPropertySet > xSeriesProp( m_xSeries, uno::UNO_QUERY );
409  if (xSeriesProp.is())
410  {
411  if (bHideLegend)
412  xSeriesProp->setPropertyValue("ShowLegendEntry", uno::makeAny(false));
413 
414  if( bIsCandleStick )
415  {
416  // set default color for range-line to black (before applying styles)
417  xSeriesProp->setPropertyValue("Color",
418  uno::makeAny( sal_Int32( 0x000000 ))); // black
419  }
420  else if ( maSeriesChartTypeName == "com.sun.star.chart2.PieChartType" )
421  {
422  //@todo: this property should be saved
423  xSeriesProp->setPropertyValue("VaryColorsByPoint",
424  uno::makeAny( true ));
425  }
426 
427  }
428 
429  Reference<chart2::data::XDataProvider> xDataProvider(mxNewDoc->getDataProvider());
430  Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xDataProvider, uno::UNO_QUERY);
431 
432  Reference<chart2::data::XDataSequence> xSequenceValues;
433 
434  // values
435  if (xPivotTableDataProvider.is()) // is pivot chart
436  {
437  xSequenceValues.set(xPivotTableDataProvider->createDataSequenceOfValuesByIndex(mnSeriesIndex));
438  }
439  else
440  {
441  if (bHasRange && !m_aSeriesRange.isEmpty())
443  }
444 
445  Reference<beans::XPropertySet> xSeqProp(xSequenceValues, uno::UNO_QUERY);
446  if (xSeqProp.is())
447  {
448  OUString aMainRole("values-y");
449  if (maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType")
450  aMainRole = "values-size";
451  xSeqProp->setPropertyValue("Role", uno::makeAny(aMainRole));
452  }
453  xLabeledSeq->setValues(xSequenceValues);
454 
455  // register for setting local data if external data provider is not present
456  maPostponedSequences.emplace(
458 
459  // label
460  Reference<chart2::data::XDataSequence> xSequenceLabel;
461 
462  if (xPivotTableDataProvider.is())
463  {
464  xSequenceLabel.set(xPivotTableDataProvider->createDataSequenceOfLabelsByIndex(mnSeriesIndex));
465  }
466  else
467  {
468  if (!aSeriesLabelRange.isEmpty())
469  {
470  xSequenceLabel.set(SchXMLTools::CreateDataSequence(aSeriesLabelRange, mxNewDoc));
471  }
472  else if (!aSeriesLabelString.isEmpty())
473  {
474  xSequenceLabel.set(SchXMLTools::CreateDataSequenceWithoutConvert(aSeriesLabelString, mxNewDoc));
475  }
476  }
477 
478  //Labels should always include hidden cells
479  Reference<beans::XPropertySet> xSeqLabelProp(xSequenceLabel, uno::UNO_QUERY);
480  if (xSeqLabelProp.is() && xSeqLabelProp->getPropertySetInfo()->hasPropertyByName("IncludeHiddenCells"))
481  {
482  xSeqLabelProp->setPropertyValue( "IncludeHiddenCells", uno::Any(true));
483  }
484 
485  xLabeledSeq->setLabel(xSequenceLabel);
486 
487  // Note: Even if we have no label, we have to register the label
488  // for creation, because internal data always has labels. If
489  // they don't exist in the original, auto-generated labels are
490  // used for the internal data.
491  maPostponedSequences.emplace(
493 
494  Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( &xLabeledSeq, 1 );
495  Reference< chart2::data::XDataSink > xSink( m_xSeries, uno::UNO_QUERY_THROW );
496  xSink->setData( aSeq );
497  }
498  catch( const uno::Exception &)
499  {
500  DBG_UNHANDLED_EXCEPTION("xmloff.chart");
501  }
502 
503  //init mbSymbolSizeIsMissingInFile:
504  try
505  {
506  if( !msAutoStyleName.isEmpty() )
507  {
509  if( pStylesCtxt )
510  {
511  const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
513 
514  const XMLPropStyleContext* pPropStyleContext = dynamic_cast< const XMLPropStyleContext * >( pStyle );
515 
516  uno::Any aASymbolSize( SchXMLTools::getPropertyFromContext( u"SymbolSize"
517  , pPropStyleContext, pStylesCtxt ) );
518  mbSymbolSizeIsMissingInFile = !aASymbolSize.hasValue();
519  }
520  }
521  }
522  catch( const uno::Exception & )
523  {
524  }
525 }
526 
527 namespace {
528 
529 struct DomainInfo
530 {
531  DomainInfo( const OUString& rRole, const OUString& rRange, sal_Int32 nIndex )
532  : aRole(rRole), aRange(rRange), nIndexForLocalData(nIndex)
533  {}
534 
535  OUString aRole;
536  OUString aRange;
537  sal_Int32 nIndexForLocalData;
538 };
539 
540 }
541 
543 {
544  // special handling for different chart types. This is necessary as the
545  // roles are not yet saved in the file format
546  sal_Int32 nDomainCount = maDomainAddresses.size();
547  bool bIsScatterChart = maSeriesChartTypeName == "com.sun.star.chart2.ScatterChartType";
548  bool bIsBubbleChart = maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType";
549  bool bDeleteSeries = false;
550  std::vector< DomainInfo > aDomainInfos;
551 
552  //different handling for different chart types necessary
553  if( bIsScatterChart || ( nDomainCount==1 && !bIsBubbleChart ) )
554  {
556  bool bCreateXValues = true;
557  if( !maDomainAddresses.empty() )
558  {
560  {
563  }
564  aDomainInfo.aRange = maDomainAddresses.front();
565  aDomainInfo.nIndexForLocalData = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
567  }
569  {
570  if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) ) //wrong old chart files:
571  {
572  //for xy charts the first series needs to have a domain
573  //if this by error iss not the case the first series is taken s x values
574  //needed for wrong files created while having an addin (e.g. BoxPlot)
577  bDeleteSeries = true;
578  bCreateXValues = false;//they will be created for the next series
579  }
580  }
581  if( bCreateXValues )
582  aDomainInfos.push_back( aDomainInfo );
583  }
584  else if( bIsBubbleChart )
585  {
586  if( nDomainCount>1 )
587  {
588  DomainInfo aDomainInfo( "values-x", maDomainAddresses[1], m_rGlobalSeriesImportInfo.nCurrentDataIndex ) ;
590  {
591  //for bubble chart the second domain contains the x values which should become an index smaller than y values for own data table
592  //->so second first
595  }
596  aDomainInfos.push_back( aDomainInfo );
598  }
600  {
602  aDomainInfos.push_back( aDomainInfo );
603  }
604  if( nDomainCount>0)
605  {
606  DomainInfo aDomainInfo( "values-y", maDomainAddresses.front(), m_rGlobalSeriesImportInfo.nCurrentDataIndex ) ;
608  {
611  }
612  aDomainInfos.push_back( aDomainInfo );
614  }
616  {
618  aDomainInfos.push_back( aDomainInfo );
619  }
620  }
621 
622  if( bDeleteSeries )
623  {
624  //delete created series
626  m_xSeries, Reference< chart2::XChartDocument >( GetImport().GetModel(), uno::UNO_QUERY ) );
627  }
628  else
629  {
630  //add style
631  if( !msAutoStyleName.isEmpty() || mnAttachedAxis != 1 )
632  {
633  DataRowPointStyle aStyle(
635  m_xSeries,
636  -1, 1,
639  mrStyleVector.push_back( aStyle );
640  }
641  // And styles for a data-label child element too. In contrast to data-labels as child of data points,
642  // an information about absolute position is useless here. We need only style information.
643  if (!mDataLabel.msStyleName.isEmpty())
644  {
647  mDataLabel.mnAttachedAxis = mnAttachedAxis; // not needed, but be consistent with its parent
648  mrStyleVector.push_back(mDataLabel);
649  }
650  }
651 
652  for( std::vector< DomainInfo >::reverse_iterator aIt( aDomainInfos.rbegin() ); aIt!= aDomainInfos.rend(); ++aIt )
653  {
654  DomainInfo aDomainInfo( *aIt );
655  Reference< chart2::data::XLabeledDataSequence2 > xLabeledSeq =
656  lcl_createAndAddSequenceToSeries( aDomainInfo.aRole, aDomainInfo.aRange, mxNewDoc, m_xSeries );
657  if( xLabeledSeq.is() )
658  {
659  // register for setting local data if external data provider is not present
660  mrLSequencesPerIndex.emplace(
661  tSchXMLIndexWithPart( aDomainInfo.nIndexForLocalData, SCH_XML_PART_VALUES ),
662  Reference< chart2::data::XLabeledDataSequence >(xLabeledSeq, uno::UNO_QUERY_THROW) );
663  }
664  }
665 
666  if( !bDeleteSeries )
667  {
668  for (auto const& postponedSequence : maPostponedSequences)
669  {
670  sal_Int32 nNewIndex = postponedSequence.first.first + nDomainCount;
671  mrLSequencesPerIndex.emplace( tSchXMLIndexWithPart( nNewIndex, postponedSequence.first.second ), postponedSequence.second );
672  }
674  }
675  maPostponedSequences.clear();
676 }
677 
678 css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLSeries2Context::createFastChildContext(
679  sal_Int32 nElement,
680  const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
681 {
682  SvXMLImportContext* pContext = nullptr;
683 
684  switch(nElement)
685  {
687  if( m_xSeries.is())
688  {
689  m_bHasDomainContext = true;
690  pContext = new SchXMLDomain2Context(
692  }
693  break;
694 
696  pContext = new SchXMLStatisticsObjectContext(
702  break;
704  pContext = new SchXMLRegressionCurveObjectContext(
708  break;
710  pContext = new SchXMLStatisticsObjectContext(
716  break;
717 
719  pContext = new SchXMLDataPointContext( GetImport(),
721  break;
723  // CustomLabels are useless for a data label element as child of a series, because it serves as default
724  // for all data labels. But the ctor expects it, so use that of the mDataLabel struct as ersatz.
726  mDataLabel);
727  break;
728 
729  case XML_ELEMENT(LO_EXT, XML_PROPERTY_MAPPING):
730  pContext = new SchXMLPropertyMappingContext(
731  GetImport(),
733  break;
734  default:
735  XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
736  }
737 
738  return pContext;
739 }
740 
741 //static
743  , const uno::Reference< frame::XModel >& xChartModel )
744 {
745  // iterate over series first and remind propertysets in map
746  // new api <-> old api wrapper
747  ::std::map< Reference< chart2::XDataSeries >, Reference< beans::XPropertySet > > aSeriesMap;
748  for (auto & seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
749  {
750  if( seriesStyle.meType != DataRowPointStyle::DATA_SERIES )
751  continue;
752 
753  if( !seriesStyle.m_xOldAPISeries.is() )
754  seriesStyle.m_xOldAPISeries = SchXMLSeriesHelper::createOldAPISeriesPropertySet( seriesStyle.m_xSeries, xChartModel );
755 
756  aSeriesMap[seriesStyle.m_xSeries] = seriesStyle.m_xOldAPISeries;
757 
758  }
759 
760  //initialize m_xOldAPISeries for all other styles also
761  for (auto & seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
762  {
763  if( seriesStyle.meType == DataRowPointStyle::DATA_SERIES )
764  continue;
765  seriesStyle.m_xOldAPISeries = aSeriesMap[seriesStyle.m_xSeries];
766  }
767 }
768 
769 //static
771 {
772  // iterate over series
773  // call initSeriesPropertySets first
774 
775  for (const auto & seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
776  {
777  if( seriesStyle.meType != DataRowPointStyle::DATA_SERIES )
778  continue;
779 
780  try
781  {
782  uno::Reference< beans::XPropertySet > xSeries( seriesStyle.m_xOldAPISeries );
783  if( !xSeries.is() )
784  continue;
785 
786  if( rSeriesDefaultsAndStyles.maSymbolTypeDefault.hasValue() )
787  xSeries->setPropertyValue("SymbolType",rSeriesDefaultsAndStyles.maSymbolTypeDefault);
788  if( rSeriesDefaultsAndStyles.maDataCaptionDefault.hasValue() )
789  xSeries->setPropertyValue("DataCaption",rSeriesDefaultsAndStyles.maDataCaptionDefault);
790 
791  if( rSeriesDefaultsAndStyles.maErrorIndicatorDefault.hasValue() )
792  xSeries->setPropertyValue("ErrorIndicator",rSeriesDefaultsAndStyles.maErrorIndicatorDefault);
793  if( rSeriesDefaultsAndStyles.maErrorCategoryDefault.hasValue() )
794  xSeries->setPropertyValue("ErrorCategory",rSeriesDefaultsAndStyles.maErrorCategoryDefault);
795  if( rSeriesDefaultsAndStyles.maConstantErrorLowDefault.hasValue() )
796  xSeries->setPropertyValue("ConstantErrorLow",rSeriesDefaultsAndStyles.maConstantErrorLowDefault);
797  if( rSeriesDefaultsAndStyles.maConstantErrorHighDefault.hasValue() )
798  xSeries->setPropertyValue("ConstantErrorHigh",rSeriesDefaultsAndStyles.maConstantErrorHighDefault);
799  if( rSeriesDefaultsAndStyles.maPercentageErrorDefault.hasValue() )
800  xSeries->setPropertyValue("PercentageError",rSeriesDefaultsAndStyles.maPercentageErrorDefault);
801  if( rSeriesDefaultsAndStyles.maErrorMarginDefault.hasValue() )
802  xSeries->setPropertyValue("ErrorMargin",rSeriesDefaultsAndStyles.maErrorMarginDefault);
803 
804  if( rSeriesDefaultsAndStyles.maMeanValueDefault.hasValue() )
805  xSeries->setPropertyValue("MeanValue",rSeriesDefaultsAndStyles.maMeanValueDefault);
806  if( rSeriesDefaultsAndStyles.maRegressionCurvesDefault.hasValue() )
807  xSeries->setPropertyValue("RegressionCurves",rSeriesDefaultsAndStyles.maRegressionCurvesDefault);
808  }
809  catch( uno::Exception & )
810  {
811  //end of series reached
812  }
813  }
814 }
815 
816 // ODF has the line and fill properties in a <style:style> element, which is referenced by the
817 // <chart:data-label> element. But LibreOffice has them as special label properties of the series
818 // or point respectively. The following array maps the API name of the ODF property to the name of
819 // the internal property. Those are of kind "LabelFoo".
820 // The array is used in methods setStylesToSeries and setStylesToDataPoints.
821 const std::pair<OUString, OUString> aApiToLabelFooPairs[]
822  = { { "LineStyle", "LabelBorderStyle" },
823  { "LineWidth", "LabelBorderWidth" },
824  { "LineColor", "LabelBorderColor" },
825  // The name "LabelBorderDash" is defined, but the associated API name "LineDash" belongs to
826  // the <draw:stroke-dash> element and is not used directly as line property.
827  //{"LineDash", "LabelBorderDash"},
828  { "LineDashName", "LabelBorderDashName" },
829  { "LineTransparence", "LabelBorderTransparency" },
830  { "FillStyle", "LabelFillStyle" },
831  { "FillBackground", "LabelFillBackground" },
832  { "FillHatchName", "LabelFillHatchName" },
833  { "FillColor", "LabelFillColor" } };
834 
835 
836 //static
838  , const SvXMLStylesContext* pStylesCtxt
839  , const SvXMLStyleContext*& rpStyle
840  , OUString& rCurrStyleName
841  , const SchXMLImportHelper& rImportHelper
842  , const SvXMLImport& rImport
843  , bool bIsStockChart
844  , tSchXMLLSequencesPerIndex & rInOutLSequencesPerIndex )
845 {
846  // iterate over series
847  for (const auto & seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
848  {
849  if (seriesStyle.meType != DataRowPointStyle::DATA_SERIES)
850  continue;
851  try
852  {
853  uno::Reference< beans::XPropertySet > xSeriesProp( seriesStyle.m_xOldAPISeries );
854  if( !xSeriesProp.is() )
855  continue;
856 
857  if( seriesStyle.mnAttachedAxis != 1 )
858  {
859  xSeriesProp->setPropertyValue("Axis"
860  , uno::makeAny(chart::ChartAxisAssign::SECONDARY_Y) );
861  }
862 
863  if( seriesStyle.msStyleName.isEmpty())
864  continue;
865 
866  if( rCurrStyleName != seriesStyle.msStyleName )
867  {
868  rCurrStyleName = seriesStyle.msStyleName;
869  rpStyle = pStylesCtxt->FindStyleChildContext(
870  SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
871  }
872 
873  //set style to series
874  // note: SvXMLStyleContext::FillPropertySet is not const
875  XMLPropStyleContext * pPropStyleContext =
876  const_cast< XMLPropStyleContext * >(
877  dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
878 
879  if (!pPropStyleContext)
880  continue;
881 
882  // error bar style must be set before the other error
883  // bar properties (which may be alphabetically before
884  // this property)
885  bool bHasErrorBarRangesFromData = false;
886  {
887  const OUString aErrorBarStylePropName( "ErrorBarStyle");
888  uno::Any aErrorBarStyle(
889  SchXMLTools::getPropertyFromContext( aErrorBarStylePropName, pPropStyleContext, pStylesCtxt ));
890  if( aErrorBarStyle.hasValue())
891  {
892  xSeriesProp->setPropertyValue( aErrorBarStylePropName, aErrorBarStyle );
893  sal_Int32 eEBStyle = chart::ErrorBarStyle::NONE;
894  bHasErrorBarRangesFromData =
895  ( ( aErrorBarStyle >>= eEBStyle ) &&
896  eEBStyle == chart::ErrorBarStyle::FROM_DATA );
897  }
898  }
899 
900  //don't set the style to the min max line series of a stock chart
901  //otherwise the min max line properties gets overwritten and the series becomes invisible typically
902  if (bIsStockChart)
903  {
905  seriesStyle.m_xSeries,
906  rImportHelper.GetChartDocument()))
907  continue;
908  }
909 
910  // Has the series a data-label child element?
911  auto pItLabel
912  = std::find_if(rSeriesDefaultsAndStyles.maSeriesStyleVector.begin(),
913  rSeriesDefaultsAndStyles.maSeriesStyleVector.end(),
914  [&seriesStyle](const DataRowPointStyle& rStyle) {
915  return rStyle.meType == DataRowPointStyle::DATA_LABEL_SERIES
916  && rStyle.msStyleNameOfParent == seriesStyle.msStyleName;
917  });
918  if (pItLabel != rSeriesDefaultsAndStyles.maSeriesStyleVector.end())
919  {
920  // Bring the information from the data-label to the series
921  const SvXMLStyleContext* pLabelStyleContext(pStylesCtxt->FindStyleChildContext(
922  SchXMLImportHelper::GetChartFamilyID(), (*pItLabel).msStyleName));
923  // note: SvXMLStyleContext::FillPropertySet is not const
924  XMLPropStyleContext* pLabelPropStyleContext = const_cast<XMLPropStyleContext*>(
925  dynamic_cast<const XMLPropStyleContext*>(pLabelStyleContext));
926  if (pLabelPropStyleContext)
927  {
928  // Test each to be mapped property whether the data-label has a value for it.
929  // If found, set it at series.
930  uno::Reference<beans::XPropertySetInfo> xSeriesPropInfo(
931  xSeriesProp->getPropertySetInfo());
932  for (const auto& rPropPair : aApiToLabelFooPairs)
933  {
935  rPropPair.first, pLabelPropStyleContext, pStylesCtxt));
936  if (aPropValue.hasValue()
937  && xSeriesPropInfo->hasPropertyByName(rPropPair.second))
938  xSeriesProp->setPropertyValue(rPropPair.second, aPropValue);
939  }
940  }
941  }
942 
943  pPropStyleContext->FillPropertySet( xSeriesProp );
944  if( seriesStyle.mbSymbolSizeForSeriesIsMissingInFile )
945  lcl_setSymbolSizeIfNeeded( xSeriesProp, rImport );
946  if( bHasErrorBarRangesFromData )
947  lcl_insertErrorBarLSequencesToMap( rInOutLSequencesPerIndex, xSeriesProp );
948 
949  }
950  catch( const uno::Exception & )
951  {
952  TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during setting styles to series" );
953  }
954  }
955 }
956 
957 // static
959  SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles,
960  const SvXMLStylesContext* pStylesCtxt,
961  const SvXMLStyleContext*& rpStyle,
962  OUString const & rCurrentStyleName )
963 {
964  // iterate over regression etc
965  for (auto const& regressionStyle : rSeriesDefaultsAndStyles.maRegressionStyleVector)
966  {
967  try
968  {
969  OUString aServiceName;
970  XMLPropStyleContext* pPropStyleContext = nullptr;
971 
972  if (!rCurrentStyleName.isEmpty())
973  {
974  XMLPropStyleContext* pCurrent = lcl_GetStylePropContext(pStylesCtxt, rpStyle, rCurrentStyleName);
975  if( pCurrent )
976  {
977  pPropStyleContext = pCurrent;
978  uno::Any aAny = SchXMLTools::getPropertyFromContext(u"RegressionType", pPropStyleContext, pStylesCtxt);
979  if ( aAny.hasValue() )
980  {
981  aAny >>= aServiceName;
982  }
983  }
984  }
985 
986  if (!regressionStyle.msStyleName.isEmpty())
987  {
988  XMLPropStyleContext* pCurrent = lcl_GetStylePropContext(pStylesCtxt, rpStyle, regressionStyle.msStyleName);
989  if( pCurrent )
990  {
991  pPropStyleContext = pCurrent;
992  uno::Any aAny = SchXMLTools::getPropertyFromContext(u"RegressionType", pPropStyleContext, pStylesCtxt);
993  if ( aAny.hasValue() )
994  {
995  aAny >>= aServiceName;
996  }
997  }
998  }
999 
1000  if( !aServiceName.isEmpty() )
1001  {
1002  Reference< lang::XMultiServiceFactory > xMSF = comphelper::getProcessServiceFactory();
1003  Reference< chart2::XRegressionCurve > xRegCurve( xMSF->createInstance( aServiceName ), uno::UNO_QUERY_THROW );
1004  Reference< chart2::XRegressionCurveContainer > xRegCurveCont( regressionStyle.m_xSeries, uno::UNO_QUERY_THROW );
1005 
1006  Reference< beans::XPropertySet > xCurveProperties( xRegCurve, uno::UNO_QUERY );
1007  if( pPropStyleContext != nullptr)
1008  pPropStyleContext->FillPropertySet( xCurveProperties );
1009 
1010  xRegCurve->setEquationProperties( regressionStyle.m_xEquationProperties );
1011 
1012  xRegCurveCont->addRegressionCurve( xRegCurve );
1013  }
1014  }
1015  catch( const uno::Exception& )
1016  {
1017  TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during setting styles to series" );
1018  }
1019 
1020  }
1021 }
1022 
1023 // static
1025  , const SvXMLStylesContext* pStylesCtxt
1026  , const SvXMLStyleContext*& rpStyle
1027  , OUString& rCurrStyleName )
1028 {
1029  // iterate over regression etc
1030  for (auto const& seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
1031  {
1032  if( seriesStyle.meType == DataRowPointStyle::ERROR_INDICATOR ||
1033  seriesStyle.meType == DataRowPointStyle::MEAN_VALUE )
1034  {
1035  if ( seriesStyle.meType == DataRowPointStyle::ERROR_INDICATOR )
1036  {
1037  uno::Reference< beans::XPropertySet > xNewSeriesProp(seriesStyle.m_xSeries,uno::UNO_QUERY);
1038 
1039  if (seriesStyle.m_xErrorXProperties.is())
1040  xNewSeriesProp->setPropertyValue("ErrorBarX",uno::makeAny(seriesStyle.m_xErrorXProperties));
1041 
1042  if (seriesStyle.m_xErrorYProperties.is())
1043  xNewSeriesProp->setPropertyValue("ErrorBarY",uno::makeAny(seriesStyle.m_xErrorYProperties));
1044  }
1045 
1046  try
1047  {
1048  uno::Reference< beans::XPropertySet > xSeriesProp( seriesStyle.m_xOldAPISeries );
1049  if( !xSeriesProp.is() )
1050  continue;
1051 
1052  if( !seriesStyle.msStyleName.isEmpty())
1053  {
1054  if( rCurrStyleName != seriesStyle.msStyleName )
1055  {
1056  rCurrStyleName = seriesStyle.msStyleName;
1057  rpStyle = pStylesCtxt->FindStyleChildContext(
1058  SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
1059  }
1060 
1061  // note: SvXMLStyleContext::FillPropertySet is not const
1062  XMLPropStyleContext * pPropStyleContext =
1063  const_cast< XMLPropStyleContext * >(
1064  dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1065  if( pPropStyleContext )
1066  {
1067  Reference< beans::XPropertySet > xStatPropSet;
1068  switch( seriesStyle.meType )
1069  {
1071  xSeriesProp->getPropertyValue("DataMeanValueProperties") >>= xStatPropSet;
1072  break;
1074  xSeriesProp->getPropertyValue("DataErrorProperties") >>= xStatPropSet;
1075  break;
1076  default:
1077  break;
1078  }
1079  if( xStatPropSet.is())
1080  pPropStyleContext->FillPropertySet( xStatPropSet );
1081  }
1082  }
1083  }
1084  catch( const uno::Exception & )
1085  {
1086  TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during setting styles to series" );
1087  }
1088  }
1089  }
1090 }
1091 
1092 //static
1094  , const SvXMLStylesContext* pStylesCtxt
1095  , const SvXMLStyleContext*& rpStyle
1096  , OUString& rCurrStyleName
1097  , const SchXMLImportHelper& rImportHelper
1098  , const SvXMLImport& rImport
1099  , bool bIsStockChart, bool bIsDonutChart, bool bSwitchOffLinesForScatter )
1100 {
1101  for (auto const& seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
1102  {
1103  if( seriesStyle.meType != DataRowPointStyle::DATA_POINT )
1104  continue;
1105 
1106  if( seriesStyle.m_nPointIndex == -1 )
1107  continue;
1108 
1109  uno::Reference< beans::XPropertySet > xSeriesProp( seriesStyle.m_xOldAPISeries );
1110  if(!xSeriesProp.is())
1111  continue;
1112 
1113  //ignore datapoint properties for stock charts
1114  //... todo ...
1115  if( bIsStockChart )
1116  {
1117  if( SchXMLSeriesHelper::isCandleStickSeries( seriesStyle.m_xSeries, rImportHelper.GetChartDocument() ) )
1118  continue;
1119  }
1120 
1121  // data point style
1122  for( sal_Int32 i = 0; i < seriesStyle.m_nPointRepeat; i++ )
1123  {
1124  try
1125  {
1126  uno::Reference< beans::XPropertySet > xPointProp(
1127  SchXMLSeriesHelper::createOldAPIDataPointPropertySet( seriesStyle.m_xSeries, seriesStyle.m_nPointIndex + i
1128  , rImportHelper.GetChartDocument() ) );
1129 
1130  if( !xPointProp.is() )
1131  continue;
1132 
1133  if( bIsDonutChart )
1134  {
1135  //set special series styles for donut charts first
1136  if( rCurrStyleName != seriesStyle.msSeriesStyleNameForDonuts )
1137  {
1138  rCurrStyleName = seriesStyle.msSeriesStyleNameForDonuts;
1139  rpStyle = pStylesCtxt->FindStyleChildContext(
1140  SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
1141  }
1142 
1143  // note: SvXMLStyleContext::FillPropertySet is not const
1144  XMLPropStyleContext * pPropStyleContext =
1145  const_cast< XMLPropStyleContext * >(
1146  dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1147  if( pPropStyleContext )
1148  pPropStyleContext->FillPropertySet( xPointProp );
1149  }
1150 
1151  try
1152  {
1153  //need to set this explicitly here for old files as the new api does not support this property fully anymore
1154  if( bSwitchOffLinesForScatter )
1155  xPointProp->setPropertyValue("Lines",uno::makeAny(false));
1156  }
1157  catch( const uno::Exception & )
1158  {
1159  }
1160 
1161  if( rCurrStyleName != seriesStyle.msStyleName )
1162  {
1163  rCurrStyleName = seriesStyle.msStyleName;
1164  rpStyle = pStylesCtxt->FindStyleChildContext(
1165  SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
1166  }
1167 
1168  // note: SvXMLStyleContext::FillPropertySet is not const
1169  XMLPropStyleContext * pPropStyleContext =
1170  const_cast< XMLPropStyleContext * >(
1171  dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1172  if (pPropStyleContext)
1173  {
1174  // Has the point a data-label child element?
1175  auto pItLabel = std::find_if(
1176  rSeriesDefaultsAndStyles.maSeriesStyleVector.begin(),
1177  rSeriesDefaultsAndStyles.maSeriesStyleVector.end(),
1178  [&seriesStyle](const DataRowPointStyle& rStyle) {
1179  return rStyle.meType == DataRowPointStyle::DATA_LABEL_POINT
1180  && rStyle.msStyleNameOfParent == seriesStyle.msStyleName;
1181  });
1182  if (pItLabel != rSeriesDefaultsAndStyles.maSeriesStyleVector.end())
1183  {
1184  // Bring the information from the data-label to the point
1185  const SvXMLStyleContext* pLabelStyleContext(
1186  pStylesCtxt->FindStyleChildContext(
1187  SchXMLImportHelper::GetChartFamilyID(), (*pItLabel).msStyleName));
1188  // note: SvXMLStyleContext::FillPropertySet is not const
1189  XMLPropStyleContext* pLabelPropStyleContext
1190  = const_cast<XMLPropStyleContext*>(
1191  dynamic_cast<const XMLPropStyleContext*>(pLabelStyleContext));
1192  if (pLabelPropStyleContext)
1193  {
1194  // Test each to be mapped property whether the data-label has a value for it.
1195  // If found, set it at the point.
1196  uno::Reference<beans::XPropertySetInfo> xPointPropInfo(
1197  xPointProp->getPropertySetInfo());
1198  for (const auto& rPropPair : aApiToLabelFooPairs)
1199  {
1201  rPropPair.first, pLabelPropStyleContext, pStylesCtxt));
1202  if (aPropValue.hasValue()
1203  && xPointPropInfo->hasPropertyByName(rPropPair.second))
1204  xPointProp->setPropertyValue(rPropPair.second, aPropValue);
1205  }
1206  }
1207  }
1208 
1209  pPropStyleContext->FillPropertySet( xPointProp );
1210  if( seriesStyle.mbSymbolSizeForSeriesIsMissingInFile )
1211  lcl_resetSymbolSizeForPointsIfNecessary( xPointProp, rImport, pPropStyleContext, pStylesCtxt );
1212  if( !pPropStyleContext->isEmptyDataStyleName() )
1213  lcl_setLinkNumberFormatToSourceIfNeeded( xPointProp, pPropStyleContext, pStylesCtxt );
1214  }
1215 
1216  // Custom labels might be passed as property
1217  if(auto nLabelCount = seriesStyle.mCustomLabels.size(); nLabelCount > 0)
1218  {
1219  Sequence< Reference<chart2::XDataPointCustomLabelField>> xLabels(nLabelCount);
1221  for( auto j = 0; j< xLabels.getLength(); ++j )
1222  {
1223  Reference< chart2::XDataPointCustomLabelField > xCustomLabel = chart2::DataPointCustomLabelField::create(xContext);
1224  xLabels[j] = xCustomLabel;
1225  xCustomLabel->setString(seriesStyle.mCustomLabels[j]);
1226  xCustomLabel->setFieldType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT);
1227 
1228  // Restore character properties on the text span manually, till
1229  // SchXMLExportHelper_Impl::exportCustomLabel() does not write the style.
1230  uno::Reference<beans::XPropertySetInfo> xPointPropInfo
1231  = xPointProp->getPropertySetInfo();
1232  if (xPointPropInfo.is())
1233  {
1234  uno::Sequence<beans::Property> aProperties = xPointPropInfo->getProperties();
1235  for (const auto& rProperty : std::as_const(aProperties))
1236  {
1237  if (!rProperty.Name.startsWith("Char")
1238  || rProperty.Name.startsWith("Chart"))
1239  {
1240  continue;
1241  }
1242 
1243  xCustomLabel->setPropertyValue(
1244  rProperty.Name, xPointProp->getPropertyValue(rProperty.Name));
1245  }
1246  }
1247  }
1248  xPointProp->setPropertyValue("CustomLabelFields", uno::Any(xLabels));
1249  xPointProp->setPropertyValue("DataCaption", uno::Any(chart::ChartDataCaption::CUSTOM));
1250  }
1251 
1252  if( seriesStyle.mCustomLabelPos[0] != 0.0 || seriesStyle.mCustomLabelPos[1] != 0.0 )
1253  {
1254  chart2::RelativePosition aCustomlabelPosition;
1255  aCustomlabelPosition.Primary = seriesStyle.mCustomLabelPos[0];
1256  aCustomlabelPosition.Secondary = seriesStyle.mCustomLabelPos[1];
1257  xPointProp->setPropertyValue("CustomLabelPosition", uno::Any(aCustomlabelPosition));
1258  }
1259  }
1260  catch( const uno::Exception & )
1261  {
1262  TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during setting styles to data points" );
1263  }
1264  }
1265  } // styles iterator
1266 }
1267 
1268 //static
1269 void SchXMLSeries2Context::switchSeriesLinesOff( ::std::vector< DataRowPointStyle >& rSeriesStyleVector )
1270 {
1271  // iterate over series
1272  for (auto const& seriesStyle : rSeriesStyleVector)
1273  {
1274  if( seriesStyle.meType != DataRowPointStyle::DATA_SERIES )
1275  continue;
1276 
1277  try
1278  {
1279  uno::Reference< beans::XPropertySet > xSeries( seriesStyle.m_xOldAPISeries );
1280  if( !xSeries.is() )
1281  continue;
1282 
1283  xSeries->setPropertyValue("Lines",uno::makeAny(false));
1284  }
1285  catch( uno::Exception & )
1286  {
1287  //end of series reached
1288  }
1289  }
1290 }
1291 
1292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
tools::SvRef< SvBaseLink > xSink
css::uno::Reference< css::chart2::XDataSeries > m_xSeries
bool hasValue()
constexpr sal_uInt16 XML_NAMESPACE_CHART
SchXMLSeries2Context(SchXMLImportHelper &rImpHelper, SvXMLImport &rImport, const css::uno::Reference< css::chart2::XChartDocument > &xNewDoc, std::vector< SchXMLAxis > &rAxes,::std::vector< DataRowPointStyle > &rStyleVector,::std::vector< RegressionStyle > &rRegressionStyleVector, sal_Int32 nSeriesIndex, bool bStockHasVolume, GlobalSeriesImportInfo &rGlobalSeriesImportInfo, const OUString &aGlobalChartTypeName, tSchXMLLSequencesPerIndex &rLSequencesPerIndex, bool &rGlobalChartTypeUsedBySeries, const css::awt::Size &rChartSize)
static void switchSeriesLinesOff(::std::vector< DataRowPointStyle > &rSeriesStyleVector)
tSchXMLLSequencesPerIndex maPostponedSequences
static css::uno::Reference< css::beans::XPropertySet > createOldAPISeriesPropertySet(const css::uno::Reference< css::chart2::XDataSeries > &xSeries, const css::uno::Reference< css::frame::XModel > &xChartModel)
virtual void SAL_CALL startFastElement(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
Definition: xmlictxt.cxx:45
SvXMLStylesContext * GetAutoStylesContext() const
uno::Any getPropertyFromContext(std::u16string_view rPropertyName, const XMLPropStyleContext *pPropStyleContext, const SvXMLStylesContext *pStylesCtxt)
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:56
sal_Int8 nAxisIndex
css::uno::Reference< css::chart2::XDataSeries > m_xSeries
SvXMLNamespaceMap & GetNamespaceMap()
Definition: xmlimp.hxx:393
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
static void setDefaultsToSeries(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles)
tSchXMLLSequencesPerIndex & mrLSequencesPerIndex
PropertiesInfo aProperties
static void setStylesToStatisticsObjects(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const SvXMLStylesContext *pStylesCtxt, const SvXMLStyleContext *&rpStyle, OUString &rCurrStyleName)
OUString GetChartTypeByClassName(std::u16string_view rClassName, bool bUseOldNames)
static void DeleteDataSeries(const css::uno::Reference< css::chart2::XDataSeries > &xSeries, const css::uno::Reference< css::chart2::XChartDocument > &xDoc)
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
#define XMLOFF_WARN_UNKNOWN(area, rIter)
Definition: xmlictxt.hxx:110
sal_uInt16 GetKeyByAttrValueQName(const OUString &rAttrName, OUString *pLocalName) const
::std::pair< tSchXMLIndex, SchXMLLabeledSequencePart > tSchXMLIndexWithPart
static bool isCandleStickSeries(const css::uno::Reference< css::chart2::XDataSeries > &xSeries, const css::uno::Reference< css::frame::XModel > &xChartModel)
virtual ~SchXMLSeries2Context() override
#define DBG_UNHANDLED_EXCEPTION(...)
::std::vector< OUString > maDomainAddresses
int i
virtual void FillPropertySet(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
Definition: prstylei.cxx:222
static css::uno::Reference< css::chart2::XDataSeries > GetNewDataSeries(const css::uno::Reference< css::chart2::XChartDocument > &xDoc, sal_Int32 nCoordinateSystemIndex, const OUString &rChartTypeName, bool bPushLastChartType)
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
Reference< chart2::data::XLabeledDataSequence2 > GetNewLabeledDataSequence()
static void initSeriesPropertySets(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const css::uno::Reference< css::frame::XModel > &xChartModel)
static css::uno::Reference< css::beans::XPropertySet > createOldAPIDataPointPropertySet(const css::uno::Reference< css::chart2::XDataSeries > &xSeries, sal_Int32 nPointIndex, const css::uno::Reference< css::frame::XModel > &xChartModel)
css::uno::Any maConstantErrorHighDefault
virtual bool isEmptyDataStyleName()
Definition: prstylei.hxx:100
virtual void SAL_CALL startFastElement(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
float u
::std::vector< RegressionStyle > & mrRegressionStyleVector
const std::pair< OUString, OUString > aApiToLabelFooPairs[]
static void setStylesToSeries(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const SvXMLStylesContext *pStylesCtxt, const SvXMLStyleContext *&rpStyle, OUString &rCurrStyleName, const SchXMLImportHelper &rImportHelper, const SvXMLImport &rImport, bool bIsStockChart, tSchXMLLSequencesPerIndex &rInOutLSequencesPerIndex)
static void setStylesToRegressionCurves(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const SvXMLStylesContext *pStylesCtxt, const SvXMLStyleContext *&rpStyle, OUString const &rCurrStyleName)
css::uno::Any maRegressionCurvesDefault
static XmlStyleFamily GetChartFamilyID()
DataRowPointStyle mDataLabel
static void setStylesToDataPoints(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const SvXMLStylesContext *pStylesCtxt, const SvXMLStyleContext *&rpStyle, OUString &rCurrStyleName, const SchXMLImportHelper &rImportHelper, const SvXMLImport &rImport, bool bIsStockChart, bool bIsDonutChart, bool bSwitchOffLinesForScatter)
::std::vector< RegressionStyle > maRegressionStyleVector
css::uno::Any maPercentageErrorDefault
With this class you can import a element containing its data as element o...
OUString msStyleNameOfParent
bool mbSymbolSizeForSeriesIsMissingInFile
This class deliberately does not support XWeak, to improve performance when loading large documents...
Definition: xmlictxt.hxx:45
GlobalSeriesImportInfo & m_rGlobalSeriesImportInfo
#define TOOLS_INFO_EXCEPTION(area, stream)
Reference< chart2::data::XDataSequence > CreateDataSequenceWithoutConvert(const OUString &rRange, const Reference< chart2::XChartDocument > &xChartDoc)
Reference< XMultiServiceFactory > getProcessServiceFactory()
const css::uno::Reference< css::chart::XChartDocument > & GetChartDocument() const
::std::vector< DataRowPointStyle > maSeriesStyleVector
#define SAL_WARN_IF(condition, area, stream)
::std::vector< SchXMLAxis > & mrAxes
Handling of tokens in XML:
OUString aName
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:96
css::uno::Reference< css::chart2::XChartDocument > mxNewDoc
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlimp.hxx:399
Reference< XComponentContext > getProcessComponentContext()
Sequence< sal_Int8 > aSeq
css::uno::Any maErrorCategoryDefault
::std::vector< DataRowPointStyle > & mrStyleVector
css::uno::Any maErrorIndicatorDefault
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
Definition: xmlstyle.cxx:788
Reference< chart2::data::XDataSequence > CreateDataSequence(const OUString &rRange, const Reference< chart2::XChartDocument > &xChartDoc)
::std::vector< OUString > mCustomLabels
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
Definition: xmlictxt.hxx:116
bool isDocumentGeneratedWithOpenOfficeOlderThan2_3(const uno::Reference< frame::XModel > &xChartModel)
::std::multimap< tSchXMLIndexWithPart, css::uno::Reference< css::chart2::data::XLabeledDataSequence > > tSchXMLLSequencesPerIndex
SchXMLImportHelper & mrImportHelper
css::uno::Any maConstantErrorLowDefault