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  const Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeq( xSeriesSource->getDataSequences());
234  sal_Int32 nOldCount = aOldSeq.getLength();
235  Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeq( nOldCount + 1 );
236  auto pNewSeq = aNewSeq.getArray();
237  pNewSeq[0].set(xLabeledSeq, uno::UNO_QUERY_THROW);
238  std::copy(aOldSeq.begin(), aOldSeq.end(), std::next(pNewSeq));
239  xSeriesSink->setData( aNewSeq );
240 
241  return xLabeledSeq;
242 }
243 
244 XMLPropStyleContext* lcl_GetStylePropContext(
245  const SvXMLStylesContext* pStylesCtxt,
246  const SvXMLStyleContext*& rpStyle,
247  OUString const & rStyleName )
248 {
249  rpStyle = pStylesCtxt->FindStyleChildContext( SchXMLImportHelper::GetChartFamilyID(), rStyleName );
250  XMLPropStyleContext* pPropStyleContext =
251  const_cast< XMLPropStyleContext* >(dynamic_cast< const XMLPropStyleContext* >( rpStyle ));
252  return pPropStyleContext;
253 }
254 
255 } // anonymous namespace
256 
258  SchXMLImportHelper& rImpHelper,
259  SvXMLImport& rImport,
260  const Reference< chart2::XChartDocument > & xNewDoc,
261  std::vector< SchXMLAxis >& rAxes,
262  ::std::vector< DataRowPointStyle >& rStyleVector,
263  ::std::vector< RegressionStyle >& rRegressionStyleVector,
264  sal_Int32 nSeriesIndex,
265  bool bStockHasVolume,
266  GlobalSeriesImportInfo& rGlobalSeriesImportInfo,
267  const OUString & aGlobalChartTypeName,
268  tSchXMLLSequencesPerIndex & rLSequencesPerIndex,
269  bool& rGlobalChartTypeUsedBySeries,
270  const awt::Size & rChartSize ) :
271  SvXMLImportContext( rImport ),
272  mrImportHelper( rImpHelper ),
273  mxNewDoc( xNewDoc ),
274  mrAxes( rAxes ),
275  mrStyleVector( rStyleVector ),
276  mrRegressionStyleVector( rRegressionStyleVector ),
277  mnSeriesIndex( nSeriesIndex ),
278  mnDataPointIndex( 0 ),
279  m_bStockHasVolume( bStockHasVolume ),
280  m_rGlobalSeriesImportInfo(rGlobalSeriesImportInfo),
281  mpAttachedAxis( nullptr ),
282  mnAttachedAxis( 0 ),
283  maGlobalChartTypeName( aGlobalChartTypeName ),
284  maSeriesChartTypeName( aGlobalChartTypeName ),
285  m_bHasDomainContext(false),
286  mrLSequencesPerIndex( rLSequencesPerIndex ),
287  mrGlobalChartTypeUsedBySeries( rGlobalChartTypeUsedBySeries ),
288  mbSymbolSizeIsMissingInFile(false),
289  maChartSize( rChartSize ),
290  // A series manages the DataRowPointStyle-struct of a data-label child element.
291  mDataLabel(DataRowPointStyle::DATA_LABEL_SERIES, OUString{})
292 {
293  if( aGlobalChartTypeName == "com.sun.star.chart2.DonutChartType" )
294  {
295  maSeriesChartTypeName = "com.sun.star.chart2.PieChartType";
296  maGlobalChartTypeName = maSeriesChartTypeName;
297  }
298 }
299 
301 {
302  SAL_WARN_IF( !maPostponedSequences.empty(), "xmloff.chart", "maPostponedSequences is NULL");
303 }
304 
305 void SchXMLSeries2Context::startFastElement (sal_Int32 /*Element*/,
306  const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
307 {
308  // parse attributes
309  mnAttachedAxis = 1;
310 
311  bool bHasRange = false;
312  OUString aSeriesLabelRange;
313  OUString aSeriesLabelString;
314  bool bHideLegend = false;
315 
316  for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
317  {
318  OUString aValue = aIter.toString();
319  switch(aIter.getToken())
320  {
322  m_aSeriesRange = aValue;
323  bHasRange = true;
324  break;
326  aSeriesLabelRange = aValue;
327  break;
328  case XML_ELEMENT(LO_EXT, XML_LABEL_STRING):
329  aSeriesLabelString = aValue;
330  break;
332  {
333  sal_Int32 nNumOfAxes = mrAxes.size();
334  for( sal_Int32 nCurrent = 0; nCurrent < nNumOfAxes; nCurrent++ )
335  {
336  if( aValue == mrAxes[ nCurrent ].aName &&
337  mrAxes[ nCurrent ].eDimension == SCH_XML_AXIS_Y )
338  {
339  mpAttachedAxis = &( mrAxes[ nCurrent ] );
340  }
341  }
342  }
343  break;
345  msAutoStyleName = aValue;
346  break;
347  case XML_ELEMENT(CHART, XML_CLASS):
348  {
349  OUString aClassName;
350  sal_uInt16 nClassPrefix =
352  aValue, &aClassName );
353  if( XML_NAMESPACE_CHART == nClassPrefix )
354  maSeriesChartTypeName = SchXMLTools::GetChartTypeByClassName( aClassName, false /* bUseOldNames */ );
355 
356  if( maSeriesChartTypeName.isEmpty())
357  maSeriesChartTypeName = aClassName;
358  }
359  break;
360  case XML_ELEMENT(LO_EXT, XML_HIDE_LEGEND):
361  bHideLegend = aValue.toBoolean();
362  break;
363  default:
364  XMLOFF_WARN_UNKNOWN("xmloff", aIter);
365  }
366  }
367 
368  if( mpAttachedAxis )
369  {
370  if( mpAttachedAxis->nAxisIndex > 0 )
371  {
372  // secondary axis => property has to be set (primary is default)
373  mnAttachedAxis = 2;
374  }
375  }
376 
377  try
378  {
379  SAL_WARN_IF( !mxNewDoc.is(), "xmloff.chart", "mxNewDoc is NULL");
382 
383  bool bIsCandleStick = maGlobalChartTypeName == "com.sun.star.chart2.CandleStickChartType";
384  if( !maSeriesChartTypeName.isEmpty() )
385  {
386  bIsCandleStick = maSeriesChartTypeName == "com.sun.star.chart2.CandleStickChartType";
387  }
388  else
389  {
390  if( bIsCandleStick
392  && mnSeriesIndex == 0 )
393  {
394  maSeriesChartTypeName = "com.sun.star.chart2.ColumnChartType";
395  bIsCandleStick = false;
396  }
397  else
398  {
400  }
401  }
404  sal_Int32 const nCoordinateSystemIndex = 0;//so far we can only import one coordinate system
405  m_xSeries.set(
408 
409  Reference< beans::XPropertySet > xSeriesProp( m_xSeries, uno::UNO_QUERY );
410  if (xSeriesProp.is())
411  {
412  if (bHideLegend)
413  xSeriesProp->setPropertyValue("ShowLegendEntry", uno::makeAny(false));
414 
415  if( bIsCandleStick )
416  {
417  // set default color for range-line to black (before applying styles)
418  xSeriesProp->setPropertyValue("Color",
419  uno::makeAny( sal_Int32( 0x000000 ))); // black
420  }
421  else if ( maSeriesChartTypeName == "com.sun.star.chart2.PieChartType" )
422  {
423  //@todo: this property should be saved
424  xSeriesProp->setPropertyValue("VaryColorsByPoint",
425  uno::makeAny( true ));
426  }
427 
428  }
429 
430  Reference<chart2::data::XDataProvider> xDataProvider(mxNewDoc->getDataProvider());
431  Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xDataProvider, uno::UNO_QUERY);
432 
433  Reference<chart2::data::XDataSequence> xSequenceValues;
434 
435  // values
436  if (xPivotTableDataProvider.is()) // is pivot chart
437  {
438  xSequenceValues.set(xPivotTableDataProvider->createDataSequenceOfValuesByIndex(mnSeriesIndex));
439  }
440  else
441  {
442  if (bHasRange && !m_aSeriesRange.isEmpty())
444  }
445 
446  Reference<beans::XPropertySet> xSeqProp(xSequenceValues, uno::UNO_QUERY);
447  if (xSeqProp.is())
448  {
449  OUString aMainRole("values-y");
450  if (maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType")
451  aMainRole = "values-size";
452  xSeqProp->setPropertyValue("Role", uno::makeAny(aMainRole));
453  }
454  xLabeledSeq->setValues(xSequenceValues);
455 
456  // register for setting local data if external data provider is not present
457  maPostponedSequences.emplace(
459 
460  // label
461  Reference<chart2::data::XDataSequence> xSequenceLabel;
462 
463  if (xPivotTableDataProvider.is())
464  {
465  xSequenceLabel.set(xPivotTableDataProvider->createDataSequenceOfLabelsByIndex(mnSeriesIndex));
466  }
467  else
468  {
469  if (!aSeriesLabelRange.isEmpty())
470  {
471  xSequenceLabel.set(SchXMLTools::CreateDataSequence(aSeriesLabelRange, mxNewDoc));
472  }
473  else if (!aSeriesLabelString.isEmpty())
474  {
475  xSequenceLabel.set(SchXMLTools::CreateDataSequenceWithoutConvert(aSeriesLabelString, mxNewDoc));
476  }
477  }
478 
479  //Labels should always include hidden cells
480  Reference<beans::XPropertySet> xSeqLabelProp(xSequenceLabel, uno::UNO_QUERY);
481  if (xSeqLabelProp.is() && xSeqLabelProp->getPropertySetInfo()->hasPropertyByName("IncludeHiddenCells"))
482  {
483  xSeqLabelProp->setPropertyValue( "IncludeHiddenCells", uno::Any(true));
484  }
485 
486  xLabeledSeq->setLabel(xSequenceLabel);
487 
488  // Note: Even if we have no label, we have to register the label
489  // for creation, because internal data always has labels. If
490  // they don't exist in the original, auto-generated labels are
491  // used for the internal data.
492  maPostponedSequences.emplace(
494 
495  Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( &xLabeledSeq, 1 );
496  Reference< chart2::data::XDataSink > xSink( m_xSeries, uno::UNO_QUERY_THROW );
497  xSink->setData( aSeq );
498  }
499  catch( const uno::Exception &)
500  {
501  DBG_UNHANDLED_EXCEPTION("xmloff.chart");
502  }
503 
504  //init mbSymbolSizeIsMissingInFile:
505  try
506  {
507  if( !msAutoStyleName.isEmpty() )
508  {
510  if( pStylesCtxt )
511  {
512  const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
514 
515  const XMLPropStyleContext* pPropStyleContext = dynamic_cast< const XMLPropStyleContext * >( pStyle );
516 
517  uno::Any aASymbolSize( SchXMLTools::getPropertyFromContext( u"SymbolSize"
518  , pPropStyleContext, pStylesCtxt ) );
519  mbSymbolSizeIsMissingInFile = !aASymbolSize.hasValue();
520  }
521  }
522  }
523  catch( const uno::Exception & )
524  {
525  }
526 }
527 
528 namespace {
529 
530 struct DomainInfo
531 {
532  DomainInfo( const OUString& rRole, const OUString& rRange, sal_Int32 nIndex )
533  : aRole(rRole), aRange(rRange), nIndexForLocalData(nIndex)
534  {}
535 
536  OUString aRole;
537  OUString aRange;
538  sal_Int32 nIndexForLocalData;
539 };
540 
541 }
542 
544 {
545  // special handling for different chart types. This is necessary as the
546  // roles are not yet saved in the file format
547  sal_Int32 nDomainCount = maDomainAddresses.size();
548  bool bIsScatterChart = maSeriesChartTypeName == "com.sun.star.chart2.ScatterChartType";
549  bool bIsBubbleChart = maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType";
550  bool bDeleteSeries = false;
551  std::vector< DomainInfo > aDomainInfos;
552 
553  //different handling for different chart types necessary
554  if( bIsScatterChart || ( nDomainCount==1 && !bIsBubbleChart ) )
555  {
557  bool bCreateXValues = true;
558  if( !maDomainAddresses.empty() )
559  {
561  {
564  }
565  aDomainInfo.aRange = maDomainAddresses.front();
566  aDomainInfo.nIndexForLocalData = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
568  }
570  {
571  if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) ) //wrong old chart files:
572  {
573  //for xy charts the first series needs to have a domain
574  //if this by error iss not the case the first series is taken s x values
575  //needed for wrong files created while having an addin (e.g. BoxPlot)
578  bDeleteSeries = true;
579  bCreateXValues = false;//they will be created for the next series
580  }
581  }
582  if( bCreateXValues )
583  aDomainInfos.push_back( aDomainInfo );
584  }
585  else if( bIsBubbleChart )
586  {
587  if( nDomainCount>1 )
588  {
589  DomainInfo aDomainInfo( "values-x", maDomainAddresses[1], m_rGlobalSeriesImportInfo.nCurrentDataIndex ) ;
591  {
592  //for bubble chart the second domain contains the x values which should become an index smaller than y values for own data table
593  //->so second first
596  }
597  aDomainInfos.push_back( aDomainInfo );
599  }
601  {
603  aDomainInfos.push_back( aDomainInfo );
604  }
605  if( nDomainCount>0)
606  {
607  DomainInfo aDomainInfo( "values-y", maDomainAddresses.front(), m_rGlobalSeriesImportInfo.nCurrentDataIndex ) ;
609  {
612  }
613  aDomainInfos.push_back( aDomainInfo );
615  }
617  {
619  aDomainInfos.push_back( aDomainInfo );
620  }
621  }
622 
623  if( bDeleteSeries )
624  {
625  //delete created series
627  m_xSeries, Reference< chart2::XChartDocument >( GetImport().GetModel(), uno::UNO_QUERY ) );
628  }
629  else
630  {
631  //add style
632  if( !msAutoStyleName.isEmpty() || mnAttachedAxis != 1 )
633  {
634  DataRowPointStyle aStyle(
636  m_xSeries,
637  -1, 1,
640  mrStyleVector.push_back( aStyle );
641  }
642  // And styles for a data-label child element too. In contrast to data-labels as child of data points,
643  // an information about absolute position is useless here. We need only style information.
644  if (!mDataLabel.msStyleName.isEmpty())
645  {
648  mDataLabel.mnAttachedAxis = mnAttachedAxis; // not needed, but be consistent with its parent
649  mrStyleVector.push_back(mDataLabel);
650  }
651  }
652 
653  for( std::vector< DomainInfo >::reverse_iterator aIt( aDomainInfos.rbegin() ); aIt!= aDomainInfos.rend(); ++aIt )
654  {
655  DomainInfo aDomainInfo( *aIt );
656  Reference< chart2::data::XLabeledDataSequence2 > xLabeledSeq =
657  lcl_createAndAddSequenceToSeries( aDomainInfo.aRole, aDomainInfo.aRange, mxNewDoc, m_xSeries );
658  if( xLabeledSeq.is() )
659  {
660  // register for setting local data if external data provider is not present
661  mrLSequencesPerIndex.emplace(
662  tSchXMLIndexWithPart( aDomainInfo.nIndexForLocalData, SCH_XML_PART_VALUES ),
663  Reference< chart2::data::XLabeledDataSequence >(xLabeledSeq, uno::UNO_QUERY_THROW) );
664  }
665  }
666 
667  if( !bDeleteSeries )
668  {
669  for (auto const& postponedSequence : maPostponedSequences)
670  {
671  sal_Int32 nNewIndex = postponedSequence.first.first + nDomainCount;
672  mrLSequencesPerIndex.emplace( tSchXMLIndexWithPart( nNewIndex, postponedSequence.first.second ), postponedSequence.second );
673  }
675  }
676  maPostponedSequences.clear();
677 }
678 
679 css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLSeries2Context::createFastChildContext(
680  sal_Int32 nElement,
681  const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
682 {
683  SvXMLImportContext* pContext = nullptr;
684 
685  switch(nElement)
686  {
688  if( m_xSeries.is())
689  {
690  m_bHasDomainContext = true;
691  pContext = new SchXMLDomain2Context(
693  }
694  break;
695 
697  pContext = new SchXMLStatisticsObjectContext(
703  break;
705  pContext = new SchXMLRegressionCurveObjectContext(
709  break;
711  pContext = new SchXMLStatisticsObjectContext(
717  break;
718 
720  pContext = new SchXMLDataPointContext( GetImport(),
722  break;
724  // CustomLabels are useless for a data label element as child of a series, because it serves as default
725  // for all data labels. But the ctor expects it, so use that of the mDataLabel struct as ersatz.
727  mDataLabel);
728  break;
729 
730  case XML_ELEMENT(LO_EXT, XML_PROPERTY_MAPPING):
731  pContext = new SchXMLPropertyMappingContext(
732  GetImport(),
734  break;
735  default:
736  XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
737  }
738 
739  return pContext;
740 }
741 
742 //static
744  , const uno::Reference< frame::XModel >& xChartModel )
745 {
746  // iterate over series first and remind propertysets in map
747  // new api <-> old api wrapper
748  ::std::map< Reference< chart2::XDataSeries >, Reference< beans::XPropertySet > > aSeriesMap;
749  for (auto & seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
750  {
751  if( seriesStyle.meType != DataRowPointStyle::DATA_SERIES )
752  continue;
753 
754  if( !seriesStyle.m_xOldAPISeries.is() )
755  seriesStyle.m_xOldAPISeries = SchXMLSeriesHelper::createOldAPISeriesPropertySet( seriesStyle.m_xSeries, xChartModel );
756 
757  aSeriesMap[seriesStyle.m_xSeries] = seriesStyle.m_xOldAPISeries;
758 
759  }
760 
761  //initialize m_xOldAPISeries for all other styles also
762  for (auto & seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
763  {
764  if( seriesStyle.meType == DataRowPointStyle::DATA_SERIES )
765  continue;
766  seriesStyle.m_xOldAPISeries = aSeriesMap[seriesStyle.m_xSeries];
767  }
768 }
769 
770 //static
772 {
773  // iterate over series
774  // call initSeriesPropertySets first
775 
776  for (const auto & seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
777  {
778  if( seriesStyle.meType != DataRowPointStyle::DATA_SERIES )
779  continue;
780 
781  try
782  {
783  uno::Reference< beans::XPropertySet > xSeries( seriesStyle.m_xOldAPISeries );
784  if( !xSeries.is() )
785  continue;
786 
787  if( rSeriesDefaultsAndStyles.maSymbolTypeDefault.hasValue() )
788  xSeries->setPropertyValue("SymbolType",rSeriesDefaultsAndStyles.maSymbolTypeDefault);
789  if( rSeriesDefaultsAndStyles.maDataCaptionDefault.hasValue() )
790  xSeries->setPropertyValue("DataCaption",rSeriesDefaultsAndStyles.maDataCaptionDefault);
791 
792  if( rSeriesDefaultsAndStyles.maErrorIndicatorDefault.hasValue() )
793  xSeries->setPropertyValue("ErrorIndicator",rSeriesDefaultsAndStyles.maErrorIndicatorDefault);
794  if( rSeriesDefaultsAndStyles.maErrorCategoryDefault.hasValue() )
795  xSeries->setPropertyValue("ErrorCategory",rSeriesDefaultsAndStyles.maErrorCategoryDefault);
796  if( rSeriesDefaultsAndStyles.maConstantErrorLowDefault.hasValue() )
797  xSeries->setPropertyValue("ConstantErrorLow",rSeriesDefaultsAndStyles.maConstantErrorLowDefault);
798  if( rSeriesDefaultsAndStyles.maConstantErrorHighDefault.hasValue() )
799  xSeries->setPropertyValue("ConstantErrorHigh",rSeriesDefaultsAndStyles.maConstantErrorHighDefault);
800  if( rSeriesDefaultsAndStyles.maPercentageErrorDefault.hasValue() )
801  xSeries->setPropertyValue("PercentageError",rSeriesDefaultsAndStyles.maPercentageErrorDefault);
802  if( rSeriesDefaultsAndStyles.maErrorMarginDefault.hasValue() )
803  xSeries->setPropertyValue("ErrorMargin",rSeriesDefaultsAndStyles.maErrorMarginDefault);
804 
805  if( rSeriesDefaultsAndStyles.maMeanValueDefault.hasValue() )
806  xSeries->setPropertyValue("MeanValue",rSeriesDefaultsAndStyles.maMeanValueDefault);
807  if( rSeriesDefaultsAndStyles.maRegressionCurvesDefault.hasValue() )
808  xSeries->setPropertyValue("RegressionCurves",rSeriesDefaultsAndStyles.maRegressionCurvesDefault);
809  }
810  catch( uno::Exception & )
811  {
812  //end of series reached
813  }
814  }
815 }
816 
817 // ODF has the line and fill properties in a <style:style> element, which is referenced by the
818 // <chart:data-label> element. But LibreOffice has them as special label properties of the series
819 // or point respectively. The following array maps the API name of the ODF property to the name of
820 // the internal property. Those are of kind "LabelFoo".
821 // The array is used in methods setStylesToSeries and setStylesToDataPoints.
822 const std::pair<OUString, OUString> aApiToLabelFooPairs[]
823  = { { "LineStyle", "LabelBorderStyle" },
824  { "LineWidth", "LabelBorderWidth" },
825  { "LineColor", "LabelBorderColor" },
826  // The name "LabelBorderDash" is defined, but the associated API name "LineDash" belongs to
827  // the <draw:stroke-dash> element and is not used directly as line property.
828  //{"LineDash", "LabelBorderDash"},
829  { "LineDashName", "LabelBorderDashName" },
830  { "LineTransparence", "LabelBorderTransparency" },
831  { "FillStyle", "LabelFillStyle" },
832  { "FillBackground", "LabelFillBackground" },
833  { "FillHatchName", "LabelFillHatchName" },
834  { "FillColor", "LabelFillColor" } };
835 
836 
837 //static
839  , const SvXMLStylesContext* pStylesCtxt
840  , const SvXMLStyleContext*& rpStyle
841  , OUString& rCurrStyleName
842  , const SchXMLImportHelper& rImportHelper
843  , const SvXMLImport& rImport
844  , bool bIsStockChart
845  , tSchXMLLSequencesPerIndex & rInOutLSequencesPerIndex )
846 {
847  // iterate over series
848  for (const auto & seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
849  {
850  if (seriesStyle.meType != DataRowPointStyle::DATA_SERIES)
851  continue;
852  try
853  {
854  uno::Reference< beans::XPropertySet > xSeriesProp( seriesStyle.m_xOldAPISeries );
855  if( !xSeriesProp.is() )
856  continue;
857 
858  if( seriesStyle.mnAttachedAxis != 1 )
859  {
860  xSeriesProp->setPropertyValue("Axis"
861  , uno::makeAny(chart::ChartAxisAssign::SECONDARY_Y) );
862  }
863 
864  if( seriesStyle.msStyleName.isEmpty())
865  continue;
866 
867  if( rCurrStyleName != seriesStyle.msStyleName )
868  {
869  rCurrStyleName = seriesStyle.msStyleName;
870  rpStyle = pStylesCtxt->FindStyleChildContext(
871  SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
872  }
873 
874  //set style to series
875  // note: SvXMLStyleContext::FillPropertySet is not const
876  XMLPropStyleContext * pPropStyleContext =
877  const_cast< XMLPropStyleContext * >(
878  dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
879 
880  if (!pPropStyleContext)
881  continue;
882 
883  // error bar style must be set before the other error
884  // bar properties (which may be alphabetically before
885  // this property)
886  bool bHasErrorBarRangesFromData = false;
887  {
888  static const OUStringLiteral aErrorBarStylePropName( u"ErrorBarStyle");
889  uno::Any aErrorBarStyle(
890  SchXMLTools::getPropertyFromContext( aErrorBarStylePropName, pPropStyleContext, pStylesCtxt ));
891  if( aErrorBarStyle.hasValue())
892  {
893  xSeriesProp->setPropertyValue( aErrorBarStylePropName, aErrorBarStyle );
894  sal_Int32 eEBStyle = chart::ErrorBarStyle::NONE;
895  bHasErrorBarRangesFromData =
896  ( ( aErrorBarStyle >>= eEBStyle ) &&
897  eEBStyle == chart::ErrorBarStyle::FROM_DATA );
898  }
899  }
900 
901  //don't set the style to the min max line series of a stock chart
902  //otherwise the min max line properties gets overwritten and the series becomes invisible typically
903  if (bIsStockChart)
904  {
906  seriesStyle.m_xSeries,
907  rImportHelper.GetChartDocument()))
908  continue;
909  }
910 
911  // Has the series a data-label child element?
912  auto pItLabel
913  = std::find_if(rSeriesDefaultsAndStyles.maSeriesStyleVector.begin(),
914  rSeriesDefaultsAndStyles.maSeriesStyleVector.end(),
915  [&seriesStyle](const DataRowPointStyle& rStyle) {
916  return rStyle.meType == DataRowPointStyle::DATA_LABEL_SERIES
917  && rStyle.msStyleNameOfParent == seriesStyle.msStyleName;
918  });
919  if (pItLabel != rSeriesDefaultsAndStyles.maSeriesStyleVector.end())
920  {
921  // Bring the information from the data-label to the series
922  const SvXMLStyleContext* pLabelStyleContext(pStylesCtxt->FindStyleChildContext(
923  SchXMLImportHelper::GetChartFamilyID(), (*pItLabel).msStyleName));
924  // note: SvXMLStyleContext::FillPropertySet is not const
925  XMLPropStyleContext* pLabelPropStyleContext = const_cast<XMLPropStyleContext*>(
926  dynamic_cast<const XMLPropStyleContext*>(pLabelStyleContext));
927  if (pLabelPropStyleContext)
928  {
929  // Test each to be mapped property whether the data-label has a value for it.
930  // If found, set it at series.
931  uno::Reference<beans::XPropertySetInfo> xSeriesPropInfo(
932  xSeriesProp->getPropertySetInfo());
933  for (const auto& rPropPair : aApiToLabelFooPairs)
934  {
936  rPropPair.first, pLabelPropStyleContext, pStylesCtxt));
937  if (aPropValue.hasValue()
938  && xSeriesPropInfo->hasPropertyByName(rPropPair.second))
939  xSeriesProp->setPropertyValue(rPropPair.second, aPropValue);
940  }
941  }
942  }
943 
944  pPropStyleContext->FillPropertySet( xSeriesProp );
945  if( seriesStyle.mbSymbolSizeForSeriesIsMissingInFile )
946  lcl_setSymbolSizeIfNeeded( xSeriesProp, rImport );
947  if( bHasErrorBarRangesFromData )
948  lcl_insertErrorBarLSequencesToMap( rInOutLSequencesPerIndex, xSeriesProp );
949 
950  }
951  catch( const uno::Exception & )
952  {
953  TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during setting styles to series" );
954  }
955  }
956 }
957 
958 // static
960  SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles,
961  const SvXMLStylesContext* pStylesCtxt,
962  const SvXMLStyleContext*& rpStyle,
963  OUString const & rCurrentStyleName )
964 {
965  // iterate over regression etc
966  for (auto const& regressionStyle : rSeriesDefaultsAndStyles.maRegressionStyleVector)
967  {
968  try
969  {
970  OUString aServiceName;
971  XMLPropStyleContext* pPropStyleContext = nullptr;
972 
973  if (!rCurrentStyleName.isEmpty())
974  {
975  XMLPropStyleContext* pCurrent = lcl_GetStylePropContext(pStylesCtxt, rpStyle, rCurrentStyleName);
976  if( pCurrent )
977  {
978  pPropStyleContext = pCurrent;
979  uno::Any aAny = SchXMLTools::getPropertyFromContext(u"RegressionType", pPropStyleContext, pStylesCtxt);
980  if ( aAny.hasValue() )
981  {
982  aAny >>= aServiceName;
983  }
984  }
985  }
986 
987  if (!regressionStyle.msStyleName.isEmpty())
988  {
989  XMLPropStyleContext* pCurrent = lcl_GetStylePropContext(pStylesCtxt, rpStyle, regressionStyle.msStyleName);
990  if( pCurrent )
991  {
992  pPropStyleContext = pCurrent;
993  uno::Any aAny = SchXMLTools::getPropertyFromContext(u"RegressionType", pPropStyleContext, pStylesCtxt);
994  if ( aAny.hasValue() )
995  {
996  aAny >>= aServiceName;
997  }
998  }
999  }
1000 
1001  if( !aServiceName.isEmpty() )
1002  {
1003  Reference< lang::XMultiServiceFactory > xMSF = comphelper::getProcessServiceFactory();
1004  Reference< chart2::XRegressionCurve > xRegCurve( xMSF->createInstance( aServiceName ), uno::UNO_QUERY_THROW );
1005  Reference< chart2::XRegressionCurveContainer > xRegCurveCont( regressionStyle.m_xSeries, uno::UNO_QUERY_THROW );
1006 
1007  Reference< beans::XPropertySet > xCurveProperties( xRegCurve, uno::UNO_QUERY );
1008  if( pPropStyleContext != nullptr)
1009  pPropStyleContext->FillPropertySet( xCurveProperties );
1010 
1011  xRegCurve->setEquationProperties( regressionStyle.m_xEquationProperties );
1012 
1013  xRegCurveCont->addRegressionCurve( xRegCurve );
1014  }
1015  }
1016  catch( const uno::Exception& )
1017  {
1018  TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during setting styles to series" );
1019  }
1020 
1021  }
1022 }
1023 
1024 // static
1026  , const SvXMLStylesContext* pStylesCtxt
1027  , const SvXMLStyleContext*& rpStyle
1028  , OUString& rCurrStyleName )
1029 {
1030  // iterate over regression etc
1031  for (auto const& seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
1032  {
1033  if( seriesStyle.meType == DataRowPointStyle::ERROR_INDICATOR ||
1034  seriesStyle.meType == DataRowPointStyle::MEAN_VALUE )
1035  {
1036  if ( seriesStyle.meType == DataRowPointStyle::ERROR_INDICATOR )
1037  {
1038  uno::Reference< beans::XPropertySet > xNewSeriesProp(seriesStyle.m_xSeries,uno::UNO_QUERY);
1039 
1040  if (seriesStyle.m_xErrorXProperties.is())
1041  xNewSeriesProp->setPropertyValue("ErrorBarX",uno::makeAny(seriesStyle.m_xErrorXProperties));
1042 
1043  if (seriesStyle.m_xErrorYProperties.is())
1044  xNewSeriesProp->setPropertyValue("ErrorBarY",uno::makeAny(seriesStyle.m_xErrorYProperties));
1045  }
1046 
1047  try
1048  {
1049  uno::Reference< beans::XPropertySet > xSeriesProp( seriesStyle.m_xOldAPISeries );
1050  if( !xSeriesProp.is() )
1051  continue;
1052 
1053  if( !seriesStyle.msStyleName.isEmpty())
1054  {
1055  if( rCurrStyleName != seriesStyle.msStyleName )
1056  {
1057  rCurrStyleName = seriesStyle.msStyleName;
1058  rpStyle = pStylesCtxt->FindStyleChildContext(
1059  SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
1060  }
1061 
1062  // note: SvXMLStyleContext::FillPropertySet is not const
1063  XMLPropStyleContext * pPropStyleContext =
1064  const_cast< XMLPropStyleContext * >(
1065  dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1066  if( pPropStyleContext )
1067  {
1068  Reference< beans::XPropertySet > xStatPropSet;
1069  switch( seriesStyle.meType )
1070  {
1072  xSeriesProp->getPropertyValue("DataMeanValueProperties") >>= xStatPropSet;
1073  break;
1075  xSeriesProp->getPropertyValue("DataErrorProperties") >>= xStatPropSet;
1076  break;
1077  default:
1078  break;
1079  }
1080  if( xStatPropSet.is())
1081  pPropStyleContext->FillPropertySet( xStatPropSet );
1082  }
1083  }
1084  }
1085  catch( const uno::Exception & )
1086  {
1087  TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during setting styles to series" );
1088  }
1089  }
1090  }
1091 }
1092 
1093 //static
1095  , const SvXMLStylesContext* pStylesCtxt
1096  , const SvXMLStyleContext*& rpStyle
1097  , OUString& rCurrStyleName
1098  , const SchXMLImportHelper& rImportHelper
1099  , const SvXMLImport& rImport
1100  , bool bIsStockChart, bool bIsDonutChart, bool bSwitchOffLinesForScatter )
1101 {
1102  for (auto const& seriesStyle : rSeriesDefaultsAndStyles.maSeriesStyleVector)
1103  {
1104  if( seriesStyle.meType != DataRowPointStyle::DATA_POINT )
1105  continue;
1106 
1107  if( seriesStyle.m_nPointIndex == -1 )
1108  continue;
1109 
1110  uno::Reference< beans::XPropertySet > xSeriesProp( seriesStyle.m_xOldAPISeries );
1111  if(!xSeriesProp.is())
1112  continue;
1113 
1114  //ignore datapoint properties for stock charts
1115  //... todo ...
1116  if( bIsStockChart )
1117  {
1118  if( SchXMLSeriesHelper::isCandleStickSeries( seriesStyle.m_xSeries, rImportHelper.GetChartDocument() ) )
1119  continue;
1120  }
1121 
1122  // data point style
1123  for( sal_Int32 i = 0; i < seriesStyle.m_nPointRepeat; i++ )
1124  {
1125  try
1126  {
1127  uno::Reference< beans::XPropertySet > xPointProp(
1128  SchXMLSeriesHelper::createOldAPIDataPointPropertySet( seriesStyle.m_xSeries, seriesStyle.m_nPointIndex + i
1129  , rImportHelper.GetChartDocument() ) );
1130 
1131  if( !xPointProp.is() )
1132  continue;
1133 
1134  if( bIsDonutChart )
1135  {
1136  //set special series styles for donut charts first
1137  if( rCurrStyleName != seriesStyle.msSeriesStyleNameForDonuts )
1138  {
1139  rCurrStyleName = seriesStyle.msSeriesStyleNameForDonuts;
1140  rpStyle = pStylesCtxt->FindStyleChildContext(
1141  SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
1142  }
1143 
1144  // note: SvXMLStyleContext::FillPropertySet is not const
1145  XMLPropStyleContext * pPropStyleContext =
1146  const_cast< XMLPropStyleContext * >(
1147  dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1148  if( pPropStyleContext )
1149  pPropStyleContext->FillPropertySet( xPointProp );
1150  }
1151 
1152  try
1153  {
1154  //need to set this explicitly here for old files as the new api does not support this property fully anymore
1155  if( bSwitchOffLinesForScatter )
1156  xPointProp->setPropertyValue("Lines",uno::makeAny(false));
1157  }
1158  catch( const uno::Exception & )
1159  {
1160  }
1161 
1162  if( rCurrStyleName != seriesStyle.msStyleName )
1163  {
1164  rCurrStyleName = seriesStyle.msStyleName;
1165  rpStyle = pStylesCtxt->FindStyleChildContext(
1166  SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
1167  }
1168 
1169  // note: SvXMLStyleContext::FillPropertySet is not const
1170  XMLPropStyleContext * pPropStyleContext =
1171  const_cast< XMLPropStyleContext * >(
1172  dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1173  if (pPropStyleContext)
1174  {
1175  // Has the point a data-label child element?
1176  auto pItLabel = std::find_if(
1177  rSeriesDefaultsAndStyles.maSeriesStyleVector.begin(),
1178  rSeriesDefaultsAndStyles.maSeriesStyleVector.end(),
1179  [&seriesStyle](const DataRowPointStyle& rStyle) {
1180  return rStyle.meType == DataRowPointStyle::DATA_LABEL_POINT
1181  && rStyle.msStyleNameOfParent == seriesStyle.msStyleName;
1182  });
1183  if (pItLabel != rSeriesDefaultsAndStyles.maSeriesStyleVector.end())
1184  {
1185  // Bring the information from the data-label to the point
1186  const SvXMLStyleContext* pLabelStyleContext(
1187  pStylesCtxt->FindStyleChildContext(
1188  SchXMLImportHelper::GetChartFamilyID(), (*pItLabel).msStyleName));
1189  // note: SvXMLStyleContext::FillPropertySet is not const
1190  XMLPropStyleContext* pLabelPropStyleContext
1191  = const_cast<XMLPropStyleContext*>(
1192  dynamic_cast<const XMLPropStyleContext*>(pLabelStyleContext));
1193  if (pLabelPropStyleContext)
1194  {
1195  // Test each to be mapped property whether the data-label has a value for it.
1196  // If found, set it at the point.
1197  uno::Reference<beans::XPropertySetInfo> xPointPropInfo(
1198  xPointProp->getPropertySetInfo());
1199  for (const auto& rPropPair : aApiToLabelFooPairs)
1200  {
1202  rPropPair.first, pLabelPropStyleContext, pStylesCtxt));
1203  if (aPropValue.hasValue()
1204  && xPointPropInfo->hasPropertyByName(rPropPair.second))
1205  xPointProp->setPropertyValue(rPropPair.second, aPropValue);
1206  }
1207  }
1208  }
1209 
1210  pPropStyleContext->FillPropertySet( xPointProp );
1211  if( seriesStyle.mbSymbolSizeForSeriesIsMissingInFile )
1212  lcl_resetSymbolSizeForPointsIfNecessary( xPointProp, rImport, pPropStyleContext, pStylesCtxt );
1213  if( !pPropStyleContext->isEmptyDataStyleName() )
1214  lcl_setLinkNumberFormatToSourceIfNeeded( xPointProp, pPropStyleContext, pStylesCtxt );
1215  }
1216 
1217  // Custom labels might be passed as property
1218  if(const size_t nLabelCount = seriesStyle.mCustomLabels.mLabels.size(); nLabelCount > 0)
1219  {
1220  auto& rCustomLabels = seriesStyle.mCustomLabels;
1221 
1222  Sequence< Reference<chart2::XDataPointCustomLabelField>> xLabels(nLabelCount);
1223  auto pxLabels = xLabels.getArray();
1225  for( size_t j = 0; j < nLabelCount; ++j )
1226  {
1227  Reference< chart2::XDataPointCustomLabelField > xCustomLabel = chart2::DataPointCustomLabelField::create(xContext);
1228  pxLabels[j] = xCustomLabel;
1229  xCustomLabel->setString(rCustomLabels.mLabels[j]);
1230  if ( j == 0 && rCustomLabels.mbDataLabelsRange)
1231  {
1232  xCustomLabel->setFieldType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLRANGE);
1233  xCustomLabel->setGuid(rCustomLabels.msLabelGuid);
1234  xCustomLabel->setCellRange(rCustomLabels.msLabelsCellRange);
1235  xCustomLabel->setDataLabelsRange(true);
1236  }
1237  else
1238  {
1239  xCustomLabel->setFieldType(chart2::DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT);
1240  }
1241 
1242  // Restore character properties on the text span manually, till
1243  // SchXMLExportHelper_Impl::exportCustomLabel() does not write the style.
1244  uno::Reference<beans::XPropertySetInfo> xPointPropInfo
1245  = xPointProp->getPropertySetInfo();
1246  if (xPointPropInfo.is())
1247  {
1248  uno::Sequence<beans::Property> aProperties = xPointPropInfo->getProperties();
1249  for (const auto& rProperty : std::as_const(aProperties))
1250  {
1251  if (!rProperty.Name.startsWith("Char")
1252  || rProperty.Name.startsWith("Chart"))
1253  {
1254  continue;
1255  }
1256 
1257  xCustomLabel->setPropertyValue(
1258  rProperty.Name, xPointProp->getPropertyValue(rProperty.Name));
1259  }
1260  }
1261  }
1262 
1263  xPointProp->setPropertyValue("CustomLabelFields", uno::Any(xLabels));
1264  xPointProp->setPropertyValue("DataCaption", uno::Any(chart::ChartDataCaption::CUSTOM));
1265  }
1266 
1267  if( seriesStyle.mCustomLabelPos[0] != 0.0 || seriesStyle.mCustomLabelPos[1] != 0.0 )
1268  {
1269  chart2::RelativePosition aCustomlabelPosition;
1270  aCustomlabelPosition.Primary = seriesStyle.mCustomLabelPos[0];
1271  aCustomlabelPosition.Secondary = seriesStyle.mCustomLabelPos[1];
1272  xPointProp->setPropertyValue("CustomLabelPosition", uno::Any(aCustomlabelPosition));
1273  }
1274  }
1275  catch( const uno::Exception & )
1276  {
1277  TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught during setting styles to data points" );
1278  }
1279  }
1280  } // styles iterator
1281 }
1282 
1283 //static
1284 void SchXMLSeries2Context::switchSeriesLinesOff( ::std::vector< DataRowPointStyle >& rSeriesStyleVector )
1285 {
1286  // iterate over series
1287  for (auto const& seriesStyle : rSeriesStyleVector)
1288  {
1289  if( seriesStyle.meType != DataRowPointStyle::DATA_SERIES )
1290  continue;
1291 
1292  try
1293  {
1294  uno::Reference< beans::XPropertySet > xSeries( seriesStyle.m_xOldAPISeries );
1295  if( !xSeries.is() )
1296  continue;
1297 
1298  xSeries->setPropertyValue("Lines",uno::makeAny(false));
1299  }
1300  catch( uno::Exception & )
1301  {
1302  //end of series reached
1303  }
1304  }
1305 }
1306 
1307 /* 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:60
sal_Int8 nAxisIndex
css::uno::Reference< css::chart2::XDataSeries > m_xSeries
SvXMLNamespaceMap & GetNamespaceMap()
Definition: xmlimp.hxx:398
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
CustomLabelsInfo mCustomLabels
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:114
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:97
css::uno::Reference< css::chart2::XChartDocument > mxNewDoc
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlimp.hxx:404
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:798
Reference< chart2::data::XDataSequence > CreateDataSequence(const OUString &rRange, const Reference< chart2::XChartDocument > &xChartDoc)
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
Definition: xmlictxt.hxx:120
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