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