1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #include "SchXMLSeries2Context.hxx"
32 #include "SchXMLPlotAreaContext.hxx"
33 #include "SchXMLSeriesHelper.hxx"
34 #include "SchXMLTools.hxx"
35 #include "PropertyMap.hxx"
36 
37 #include <com/sun/star/chart2/XChartDocument.hpp>
38 #include <com/sun/star/chart2/XDataSeries.hpp>
39 #include <com/sun/star/chart2/XRegressionCurve.hpp>
40 #include <com/sun/star/chart2/data/XDataSink.hpp>
41 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
42 
43 #include <com/sun/star/chart/ChartAxisAssign.hpp>
44 #include <com/sun/star/chart/ChartSymbolType.hpp>
45 #include <com/sun/star/container/XChild.hpp>
46 #include <com/sun/star/chart/ChartLegendPosition.hpp>
47 #include <com/sun/star/drawing/LineStyle.hpp>
48 #include <com/sun/star/embed/Aspects.hpp>
49 #include <com/sun/star/embed/XVisualObject.hpp>
50 #include <com/sun/star/uno/XComponentContext.hpp>
51 
52 // header for define DBG_ERROR1
53 #include <tools/debug.hxx>
54 #include <rtl/ustrbuf.hxx>
55 #include "xmloff/xmlnmspe.hxx"
56 #include <xmloff/xmlimp.hxx>
57 #ifndef _XMLOFF_NMSPMAP_HX
58 #include <xmloff/nmspmap.hxx>
59 #endif
60 #include "SchXMLImport.hxx"
61 // header for class XMLPropStyleContext
62 #include <xmloff/prstylei.hxx>
63 #include <xmloff/xmlprmap.hxx>
64 
65 #include <typeinfo>
66 
67 using namespace ::com::sun::star;
68 using namespace ::xmloff::token;
69 
70 using ::com::sun::star::uno::Reference;
71 using ::com::sun::star::uno::Sequence;
72 using ::rtl::OUString;
73 using ::rtl::OUStringBuffer;
74 
75 // ================================================================================
76 
77 namespace
78 {
79 
80 class SchXMLDomain2Context : public SvXMLImportContext
81 {
82 private:
83 	SchXMLImportHelper& mrImportHelper;
84 	::std::vector< OUString > & mrAddresses;
85 
86 public:
87 	SchXMLDomain2Context( SchXMLImportHelper& rImpHelper,
88                           SvXMLImport& rImport,
89                           sal_uInt16 nPrefix,
90                           const rtl::OUString& rLocalName,
91                           ::std::vector< OUString > & rAddresses );
92 	virtual ~SchXMLDomain2Context();
93 	virtual void StartElement( const Reference< xml::sax::XAttributeList >& xAttrList );
94 };
95 
96 SchXMLDomain2Context::SchXMLDomain2Context(
97 	SchXMLImportHelper& rImpHelper,
98 	SvXMLImport& rImport,
99 	sal_uInt16 nPrefix,
100 	const rtl::OUString& rLocalName,
101 	::std::vector< ::rtl::OUString > & rAddresses ) :
102 		SvXMLImportContext( rImport, nPrefix, rLocalName ),
103 		mrImportHelper( rImpHelper ),
104 		mrAddresses( rAddresses )
105 {
106 }
107 
108 SchXMLDomain2Context::~SchXMLDomain2Context()
109 {
110 }
111 
112 void SchXMLDomain2Context::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
113 {
114 	sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
115 
116 	for( sal_Int16 i = 0; i < nAttrCount; i++ )
117 	{
118 		rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
119 		rtl::OUString aLocalName;
120 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
121 
122 		if( nPrefix == XML_NAMESPACE_TABLE &&
123 			IsXMLToken( aLocalName, XML_CELL_RANGE_ADDRESS ) )
124 		{
125             Reference< chart2::XChartDocument > xNewDoc( GetImport().GetModel(), uno::UNO_QUERY );
126             mrAddresses.push_back( xAttrList->getValueByIndex( i ));
127 		}
128 	}
129 }
130 
131 void lcl_setAutomaticSymbolSize( const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp, const SvXMLImport& rImport )
132 {
133     awt::Size aSymbolSize(140,140);//old default for standard sized charts 7cm height
134 
135     double fScale = 1;
136     uno::Reference< chart::XChartDocument > xChartDoc( rImport.GetModel(), uno::UNO_QUERY );
137     if( xChartDoc.is() )
138     {
139         uno::Reference< beans::XPropertySet > xLegendProp( xChartDoc->getLegend(), uno::UNO_QUERY );
140         chart::ChartLegendPosition aLegendPosition = chart::ChartLegendPosition_NONE;
141         if( xLegendProp.is() && (xLegendProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Alignment" ))) >>= aLegendPosition)
142             && chart::ChartLegendPosition_NONE != aLegendPosition )
143         {
144 
145             double fFontHeight = 6.0;
146             if( xLegendProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ))) >>= fFontHeight )
147                 fScale = 0.75*fFontHeight/6.0;
148         }
149         else
150         {
151             uno::Reference< embed::XVisualObject > xVisualObject( rImport.GetModel(), uno::UNO_QUERY );
152             if( xVisualObject.is() )
153             {
154                 awt::Size aPageSize( xVisualObject->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) );
155                 fScale = aPageSize.Height/7000.0;
156             }
157         }
158         if( fScale>0 )
159         {
160             aSymbolSize.Height = static_cast<sal_Int32>( fScale * aSymbolSize.Height );
161             aSymbolSize.Width = aSymbolSize.Height;
162         }
163     }
164     xSeriesOrPointProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolSize")),uno::makeAny( aSymbolSize ));
165 }
166 
167 void lcl_setSymbolSizeIfNeeded( const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp, const SvXMLImport& rImport )
168 {
169     if( !xSeriesOrPointProp.is() )
170         return;
171 
172     sal_Int32 nSymbolType = chart::ChartSymbolType::NONE;
173     if( xSeriesOrPointProp.is() && ( xSeriesOrPointProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolType"))) >>= nSymbolType) )
174     {
175         if(chart::ChartSymbolType::NONE!=nSymbolType)
176         {
177             if( chart::ChartSymbolType::BITMAPURL==nSymbolType )
178             {
179                 //set special size for graphics to indicate to use the bitmap size itself
180                 xSeriesOrPointProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolSize")),uno::makeAny( awt::Size(-1,-1) ));
181             }
182             else
183             {
184                 lcl_setAutomaticSymbolSize( xSeriesOrPointProp, rImport );
185             }
186         }
187     }
188 }
189 
190 void lcl_resetSymbolSizeForPointsIfNecessary( const uno::Reference< beans::XPropertySet >& xPointProp, const SvXMLImport& rImport
191     , const XMLPropStyleContext * pPropStyleContext, const SvXMLStylesContext* pStylesCtxt )
192 {
193     uno::Any aASymbolSize( SchXMLTools::getPropertyFromContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolSize")), pPropStyleContext, pStylesCtxt ) );
194     if( !aASymbolSize.hasValue() )
195         lcl_setSymbolSizeIfNeeded( xPointProp, rImport );
196 }
197 
198 void lcl_insertErrorBarLSequencesToMap(
199     tSchXMLLSequencesPerIndex & rInOutMap,
200     const uno::Reference< beans::XPropertySet > & xSeriesProp,
201     bool bYError = true )
202 {
203     Reference< chart2::data::XDataSource > xErrorBarSource;
204     const OUString aPropName(
205         bYError
206         ? ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorBarY" ))
207         : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorBarX" )));
208     if( ( xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBarSource ) &&
209         xErrorBarSource.is() )
210     {
211         Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSequences(
212             xErrorBarSource->getDataSequences());
213         for( sal_Int32 nIndex = 0; nIndex < aLSequences.getLength(); ++nIndex )
214         {
215             // use "0" as data index. This is ok, as it is not used for error bars
216             rInOutMap.insert(
217                 tSchXMLLSequencesPerIndex::value_type(
218                     tSchXMLIndexWithPart( 0, SCH_XML_PART_ERROR_BARS ), aLSequences[ nIndex ] ));
219         }
220     }
221 }
222 
223 Reference< chart2::data::XLabeledDataSequence > lcl_createAndAddSequenceToSeries( const rtl::OUString& rRole
224         , const rtl::OUString& rRange
225         , const Reference< chart2::XChartDocument >& xChartDoc
226         , const Reference< chart2::XDataSeries >& xSeries )
227 {
228     Reference< chart2::data::XLabeledDataSequence > xLabeledSeq;
229 
230     Reference< chart2::data::XDataSource > xSeriesSource( xSeries,uno::UNO_QUERY );
231     Reference< chart2::data::XDataSink > xSeriesSink( xSeries, uno::UNO_QUERY );
232 
233     if( !(rRange.getLength() && xChartDoc.is() && xSeriesSource.is() && xSeriesSink.is()) )
234         return xLabeledSeq;
235 
236     // create a new sequence
237     xLabeledSeq = SchXMLTools::GetNewLabeledDataSequence();
238 
239     // set values at the new sequence
240     Reference< chart2::data::XDataSequence > xSeq = SchXMLTools::CreateDataSequence( rRange, xChartDoc );
241     Reference< beans::XPropertySet > xSeqProp( xSeq, uno::UNO_QUERY );
242     if( xSeqProp.is())
243         xSeqProp->setPropertyValue(OUString::createFromAscii("Role"), uno::makeAny( rRole));
244     xLabeledSeq->setValues( xSeq );
245 
246     // add new sequence to data series / push to front to have the correct sequence order if charttype is changed afterwards
247     Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeq( xSeriesSource->getDataSequences());
248     sal_Int32 nOldCount = aOldSeq.getLength();
249     Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeq( nOldCount + 1 );
250     aNewSeq[0]=xLabeledSeq;
251     for( sal_Int32 nN=0; nN<nOldCount; nN++ )
252         aNewSeq[nN+1] = aOldSeq[nN];
253     xSeriesSink->setData( aNewSeq );
254 
255     return xLabeledSeq;
256 }
257 
258 } // anonymous namespace
259 
260 // ================================================================================
261 
262 SchXMLSeries2Context::SchXMLSeries2Context(
263 	SchXMLImportHelper& rImpHelper,
264 	SvXMLImport& rImport, const rtl::OUString& rLocalName,
265     const Reference< chart2::XChartDocument > & xNewDoc,
266 	std::vector< SchXMLAxis >& rAxes,
267 	::std::list< DataRowPointStyle >& rStyleList,
268 	sal_Int32 nSeriesIndex,
269 	sal_Bool bStockHasVolume,
270     GlobalSeriesImportInfo& rGlobalSeriesImportInfo,
271     const OUString & aGlobalChartTypeName,
272     tSchXMLLSequencesPerIndex & rLSequencesPerIndex,
273     bool& rGlobalChartTypeUsedBySeries,
274     const awt::Size & rChartSize ) :
275 		SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
276         mrImportHelper( rImpHelper ),
277         mxNewDoc( xNewDoc ),
278 		mrAxes( rAxes ),
279         mrStyleList( rStyleList ),
280 		m_xSeries(0),
281 		mnSeriesIndex( nSeriesIndex ),
282 		mnDataPointIndex( 0 ),
283         m_bStockHasVolume( bStockHasVolume ),
284         m_rGlobalSeriesImportInfo(rGlobalSeriesImportInfo),
285         mpAttachedAxis( NULL ),
286 		maGlobalChartTypeName( aGlobalChartTypeName ),
287         maSeriesChartTypeName( aGlobalChartTypeName ),
288         m_bHasDomainContext(false),
289         mrLSequencesPerIndex( rLSequencesPerIndex ),
290         mrGlobalChartTypeUsedBySeries( rGlobalChartTypeUsedBySeries ),
291         mbSymbolSizeIsMissingInFile(false),
292         maChartSize( rChartSize )
293 {
294     if( 0 == aGlobalChartTypeName.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.DonutChartType" ) ) )
295     {
296         maSeriesChartTypeName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2.PieChartType" ));
297         maGlobalChartTypeName = maSeriesChartTypeName;
298     }
299 }
300 
301 SchXMLSeries2Context::~SchXMLSeries2Context()
302 {
303     OSL_ASSERT( maPostponedSequences.empty());
304 }
305 
306 void SchXMLSeries2Context::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
307 {
308 	// parse attributes
309 	sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
310 	const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetSeriesAttrTokenMap();
311 	mnAttachedAxis = 1;
312 
313     bool bHasRange = false;
314     bool bHasLabelRange = false;
315 
316 	for( sal_Int16 i = 0; i < nAttrCount; i++ )
317 	{
318 		rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
319 		rtl::OUString aLocalName;
320 		rtl::OUString aValue = xAttrList->getValueByIndex( i );
321 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
322 
323 		switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
324 		{
325 			case XML_TOK_SERIES_CELL_RANGE:
326                 m_aSeriesRange = aValue;
327                 bHasRange = true;
328 				break;
329 			case XML_TOK_SERIES_LABEL_ADDRESS:
330                 m_aSeriesLabelRange = aValue;
331                 bHasLabelRange = true;
332 				break;
333 			case XML_TOK_SERIES_ATTACHED_AXIS:
334 				{
335 					sal_Int32 nNumOfAxes = mrAxes.size();
336 					for( sal_Int32 nCurrent = 0; nCurrent < nNumOfAxes; nCurrent++ )
337 					{
338 						if( aValue.equals( mrAxes[ nCurrent ].aName ) &&
339 							mrAxes[ nCurrent ].eDimension == SCH_XML_AXIS_Y )
340 						{
341 							mpAttachedAxis = &( mrAxes[ nCurrent ] );
342 						}
343 					}
344 				}
345 				break;
346 			case XML_TOK_SERIES_STYLE_NAME:
347 				msAutoStyleName = aValue;
348 				break;
349 			case XML_TOK_SERIES_CHART_CLASS:
350                 {
351                     OUString aClassName;
352 					sal_uInt16 nClassPrefix =
353 						GetImport().GetNamespaceMap().GetKeyByAttrName(
354                             aValue, &aClassName );
355 					if( XML_NAMESPACE_CHART == nClassPrefix )
356                         maSeriesChartTypeName = SchXMLTools::GetChartTypeByClassName( aClassName, false /* bUseOldNames */ );
357 
358                     if( ! maSeriesChartTypeName.getLength())
359                         maSeriesChartTypeName = aClassName;
360                 }
361 				break;
362 		}
363 	}
364 
365     if( mpAttachedAxis )
366 	{
367 		if( mpAttachedAxis->nAxisIndex > 0 )
368 		{
369 			// secondary axis => property has to be set (primary is default)
370 			mnAttachedAxis = 2;
371 		}
372 	}
373 
374     try
375     {
376         OSL_ASSERT( mxNewDoc.is());
377         if( m_rGlobalSeriesImportInfo.rbAllRangeAddressesAvailable && ! bHasRange )
378             m_rGlobalSeriesImportInfo.rbAllRangeAddressesAvailable = sal_False;
379 
380         bool bIsCandleStick = maGlobalChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.CandleStickChartType"));
381         if( maSeriesChartTypeName.getLength() )
382         {
383             bIsCandleStick = maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.CandleStickChartType"));
384         }
385         else
386         {
387             if( bIsCandleStick
388                 && m_bStockHasVolume
389                 && mnSeriesIndex == 0 )
390             {
391                 maSeriesChartTypeName = OUString::createFromAscii( "com.sun.star.chart2.ColumnChartType" );
392                 bIsCandleStick = false;
393             }
394             else
395             {
396                 maSeriesChartTypeName = maGlobalChartTypeName;
397             }
398         }
399         if( ! mrGlobalChartTypeUsedBySeries )
400             mrGlobalChartTypeUsedBySeries = (maSeriesChartTypeName.equals( maGlobalChartTypeName ));
401         sal_Int32 nCoordinateSystemIndex = 0;//so far we can only import one coordinate system
402         m_xSeries.set(
403             mrImportHelper.GetNewDataSeries( mxNewDoc, nCoordinateSystemIndex, maSeriesChartTypeName, ! mrGlobalChartTypeUsedBySeries ));
404         Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
405             SchXMLTools::GetNewLabeledDataSequence());
406 
407         if( bIsCandleStick )
408         {
409             // set default color for range-line to black (before applying styles)
410             Reference< beans::XPropertySet > xSeriesProp( m_xSeries, uno::UNO_QUERY );
411             if( xSeriesProp.is())
412                 xSeriesProp->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Color")),
413                                                uno::makeAny( sal_Int32( 0x000000 ))); // black
414         }
415         else if( maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.PieChartType")))
416         {
417             //@todo: this property should be saved
418             Reference< beans::XPropertySet > xSeriesProp( m_xSeries, uno::UNO_QUERY );
419             if( xSeriesProp.is())
420                 xSeriesProp->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VaryColorsByPoint")),
421                                                uno::makeAny( true ));
422         }
423 
424         // values
425         Reference< chart2::data::XDataSequence > xSeq;
426         if( bHasRange && m_aSeriesRange.getLength() )
427             xSeq = SchXMLTools::CreateDataSequence( m_aSeriesRange, mxNewDoc );
428 
429         Reference< beans::XPropertySet > xSeqProp( xSeq, uno::UNO_QUERY );
430         if( xSeqProp.is())
431         {
432             OUString aMainRole( OUString::createFromAscii("values-y") );
433             if( maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.BubbleChartType") ) )
434                 aMainRole = OUString::createFromAscii("values-size");
435             xSeqProp->setPropertyValue(OUString::createFromAscii("Role"), uno::makeAny( aMainRole ));
436         }
437         xLabeledSeq->setValues( xSeq );
438 
439         // register for setting local data if external data provider is not present
440         maPostponedSequences.insert(
441             tSchXMLLSequencesPerIndex::value_type(
442                 tSchXMLIndexWithPart( m_rGlobalSeriesImportInfo.nCurrentDataIndex, SCH_XML_PART_VALUES ), xLabeledSeq ));
443 
444         // label
445         if( bHasLabelRange && m_aSeriesLabelRange.getLength() )
446         {
447             Reference< chart2::data::XDataSequence > xLabelSequence =
448                 SchXMLTools::CreateDataSequence( m_aSeriesLabelRange, mxNewDoc );
449             xLabeledSeq->setLabel( xLabelSequence );
450         }
451 
452         // Note: Even if we have no label, we have to register the label
453         // for creation, because internal data always has labels. If
454         // they don't exist in the original, auto-generated labels are
455         // used for the internal data.
456         maPostponedSequences.insert(
457             tSchXMLLSequencesPerIndex::value_type(
458                 tSchXMLIndexWithPart( m_rGlobalSeriesImportInfo.nCurrentDataIndex, SCH_XML_PART_LABEL ), xLabeledSeq ));
459 
460 
461         Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( &xLabeledSeq, 1 );
462         Reference< chart2::data::XDataSink > xSink( m_xSeries, uno::UNO_QUERY_THROW );
463         xSink->setData( aSeq );
464     }
465     catch( uno::Exception & ex )
466     {
467         (void)ex; // avoid warning for pro build
468         OSL_ENSURE( false, ::rtl::OUStringToOString(
469                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
470                         ::rtl::OUString::createFromAscii( typeid( ex ).name()) +
471                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
472                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
473     }
474 
475     //init mbSymbolSizeIsMissingInFile:
476     try
477     {
478         if( msAutoStyleName.getLength() )
479         {
480             const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
481 	        if( pStylesCtxt )
482 	        {
483 		        const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
484 			        mrImportHelper.GetChartFamilyID(), msAutoStyleName );
485 
486                 const XMLPropStyleContext* pPropStyleContext = dynamic_cast< const XMLPropStyleContext * >( pStyle );
487 
488                 uno::Any aASymbolSize( SchXMLTools::getPropertyFromContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolSize"))
489                     , pPropStyleContext, pStylesCtxt ) );
490                 mbSymbolSizeIsMissingInFile = !aASymbolSize.hasValue();
491 	        }
492         }
493     }
494     catch( uno::Exception & ex )
495     {
496         (void)ex; // avoid warning for pro build
497     }
498 }
499 
500 struct DomainInfo
501 {
502     DomainInfo( const rtl::OUString& rRole, const rtl::OUString& rRange, sal_Int32 nIndex )
503         : aRole(rRole), aRange(rRange), nIndexForLocalData(nIndex)
504     {}
505 
506     rtl::OUString aRole;
507     rtl::OUString aRange;
508     sal_Int32 nIndexForLocalData;
509 };
510 
511 void SchXMLSeries2Context::EndElement()
512 {
513     // special handling for different chart types.  This is necessary as the
514     // roles are not yet saved in the file format
515     sal_Int32 nDomainCount = maDomainAddresses.size();
516     bool bIsScatterChart = maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.ScatterChartType"));
517     bool bIsBubbleChart = maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.BubbleChartType"));
518     bool bDeleteSeries = false;
519     std::vector< DomainInfo > aDomainInfos;
520 
521     //different handling for different chart types necessary
522     if( bIsScatterChart || ( nDomainCount==1 && !bIsBubbleChart ) )
523     {
524         DomainInfo aDomainInfo( OUString::createFromAscii("values-x"), m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress, m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex ) ;
525         bool bCreateXValues = true;
526         if( !maDomainAddresses.empty() )
527         {
528             if( !m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress.getLength() )
529             {
530                 m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress = maDomainAddresses.front();
531                 m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
532             }
533             aDomainInfo.aRange = maDomainAddresses.front();
534             aDomainInfo.nIndexForLocalData = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
535             m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
536         }
537         else if( !m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress.getLength() && !m_bHasDomainContext && mnSeriesIndex==0 )
538         {
539             if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) ) //wrong old chart files:
540             {
541                 //for xy charts the first series needs to have a domain
542                 //if this by error iss not the case the first series is taken s x values
543                 //needed for wrong files created while having an addin (e.g. BoxPlot)
544                 m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress = m_aSeriesRange;
545                 m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex = m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
546                 bDeleteSeries = true;
547                 bCreateXValues = false;//they will be created for the next series
548             }
549         }
550         if( bCreateXValues )
551             aDomainInfos.push_back( aDomainInfo );
552     }
553     else if( bIsBubbleChart )
554     {
555         if( nDomainCount>1 )
556         {
557             DomainInfo aDomainInfo( OUString::createFromAscii("values-x"), maDomainAddresses[1], m_rGlobalSeriesImportInfo.nCurrentDataIndex ) ;
558             if( !m_rGlobalSeriesImportInfo.aFirstSecondDomainAddress.getLength() )
559             {
560                 //for bubble chart the second domain contains the x values which should become an index smaller than y values for own data table
561                 //->so second first
562                 m_rGlobalSeriesImportInfo.aFirstSecondDomainAddress = maDomainAddresses[1];
563                 m_rGlobalSeriesImportInfo.nFirstSecondDomainIndex = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
564             }
565             aDomainInfos.push_back( aDomainInfo );
566             m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
567         }
568         else if( m_rGlobalSeriesImportInfo.aFirstSecondDomainAddress.getLength() )
569         {
570             DomainInfo aDomainInfo( OUString::createFromAscii("values-x"), m_rGlobalSeriesImportInfo.aFirstSecondDomainAddress, m_rGlobalSeriesImportInfo.nFirstSecondDomainIndex ) ;
571             aDomainInfos.push_back( aDomainInfo );
572         }
573         if( nDomainCount>0)
574         {
575             DomainInfo aDomainInfo( OUString::createFromAscii("values-y"), maDomainAddresses.front(), m_rGlobalSeriesImportInfo.nCurrentDataIndex ) ;
576             if( !m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress.getLength() )
577             {
578                 m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress = maDomainAddresses.front();
579                 m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
580             }
581             aDomainInfos.push_back( aDomainInfo );
582             m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
583         }
584         else if( m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress.getLength() )
585         {
586             DomainInfo aDomainInfo( OUString::createFromAscii("values-y"), m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress, m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex ) ;
587             aDomainInfos.push_back( aDomainInfo );
588         }
589     }
590 
591     if( bDeleteSeries )
592     {
593         //delete created series
594         SchXMLImportHelper::DeleteDataSeries(
595             m_xSeries, Reference< chart2::XChartDocument >( GetImport().GetModel(), uno::UNO_QUERY ) );
596     }
597     else
598     {
599         //add style
600 	    if( msAutoStyleName.getLength() ||
601 		    mnAttachedAxis != 1 )
602 	    {
603 		    DataRowPointStyle aStyle(
604                 DataRowPointStyle::DATA_SERIES,
605                 m_xSeries,
606                 -1, 1,
607                 msAutoStyleName, mnAttachedAxis );
608             aStyle.mbSymbolSizeForSeriesIsMissingInFile=mbSymbolSizeIsMissingInFile;
609 		    mrStyleList.push_back( aStyle );
610 	    }
611     }
612 
613     for( std::vector< DomainInfo >::reverse_iterator aIt( aDomainInfos.rbegin() ); aIt!= aDomainInfos.rend(); ++aIt )
614     {
615         DomainInfo aDomainInfo( *aIt );
616         Reference< chart2::data::XLabeledDataSequence > xLabeledSeq =
617             lcl_createAndAddSequenceToSeries( aDomainInfo.aRole, aDomainInfo.aRange, mxNewDoc, m_xSeries );
618         if( xLabeledSeq.is() )
619         {
620             // register for setting local data if external data provider is not present
621             mrLSequencesPerIndex.insert(
622                 tSchXMLLSequencesPerIndex::value_type(
623                     tSchXMLIndexWithPart( aDomainInfo.nIndexForLocalData, SCH_XML_PART_VALUES ), xLabeledSeq ));
624         }
625     }
626 
627     if( !bDeleteSeries )
628     {
629         for( tSchXMLLSequencesPerIndex::const_iterator aIt( maPostponedSequences.begin());
630             aIt != maPostponedSequences.end(); ++aIt )
631         {
632             sal_Int32 nNewIndex = aIt->first.first + nDomainCount;
633             mrLSequencesPerIndex.insert(
634                 tSchXMLLSequencesPerIndex::value_type(
635                     tSchXMLIndexWithPart( nNewIndex, aIt->first.second ), aIt->second ));
636         }
637         m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
638     }
639     maPostponedSequences.clear();
640 }
641 
642 SvXMLImportContext* SchXMLSeries2Context::CreateChildContext(
643 	sal_uInt16 nPrefix,
644 	const rtl::OUString& rLocalName,
645 	const uno::Reference< xml::sax::XAttributeList >&  )
646 {
647 	SvXMLImportContext* pContext = 0;
648 	const SvXMLTokenMap& rTokenMap = mrImportHelper.GetSeriesElemTokenMap();
649 
650 	switch( rTokenMap.Get( nPrefix, rLocalName ))
651 	{
652 		case XML_TOK_SERIES_DOMAIN:
653             if( m_xSeries.is())
654             {
655                 m_bHasDomainContext = true;
656 				pContext = new SchXMLDomain2Context(
657 					mrImportHelper, GetImport(),
658 					nPrefix, rLocalName,
659                     maDomainAddresses );
660 			}
661 			break;
662 
663         case XML_TOK_SERIES_MEAN_VALUE_LINE:
664             pContext = new SchXMLStatisticsObjectContext(
665                 mrImportHelper, GetImport(),
666                 nPrefix, rLocalName,
667                 mrStyleList, m_xSeries,
668                 SchXMLStatisticsObjectContext::CONTEXT_TYPE_MEAN_VALUE_LINE,
669                 maChartSize );
670             break;
671         case XML_TOK_SERIES_REGRESSION_CURVE:
672             pContext = new SchXMLStatisticsObjectContext(
673                 mrImportHelper, GetImport(),
674                 nPrefix, rLocalName,
675                 mrStyleList, m_xSeries,
676                 SchXMLStatisticsObjectContext::CONTEXT_TYPE_REGRESSION_CURVE,
677                 maChartSize );
678             break;
679         case XML_TOK_SERIES_ERROR_INDICATOR:
680             pContext = new SchXMLStatisticsObjectContext(
681                 mrImportHelper, GetImport(),
682                 nPrefix, rLocalName,
683                 mrStyleList, m_xSeries,
684                 SchXMLStatisticsObjectContext::CONTEXT_TYPE_ERROR_INDICATOR,
685                 maChartSize );
686             break;
687 
688 		case XML_TOK_SERIES_DATA_POINT:
689 			pContext = new SchXMLDataPointContext( mrImportHelper, GetImport(), rLocalName,
690 												   mrStyleList, m_xSeries, mnDataPointIndex, mbSymbolSizeIsMissingInFile );
691 			break;
692 
693 		default:
694 			pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
695 	}
696 
697 	return pContext;
698 }
699 
700 //static
701 void SchXMLSeries2Context::initSeriesPropertySets( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles
702         , const uno::Reference< frame::XModel >& xChartModel )
703 {
704     ::std::list< DataRowPointStyle >::iterator iStyle;
705 
706     // iterate over series first and remind propertysets in map
707     // new api <-> old api wrapper
708     ::std::map< Reference< chart2::XDataSeries >, Reference< beans::XPropertySet > > aSeriesMap;
709 	for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
710 	{
711 		if( iStyle->meType != DataRowPointStyle::DATA_SERIES )
712             continue;
713 
714         if( !iStyle->m_xOldAPISeries.is() )
715             iStyle->m_xOldAPISeries = SchXMLSeriesHelper::createOldAPISeriesPropertySet( iStyle->m_xSeries, xChartModel );
716 
717         aSeriesMap[iStyle->m_xSeries] = iStyle->m_xOldAPISeries;
718 
719     }
720 
721     //initialize m_xOldAPISeries for all other styles also
722     for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
723 	{
724 		if( iStyle->meType == DataRowPointStyle::DATA_SERIES )
725             continue;
726         iStyle->m_xOldAPISeries = aSeriesMap[iStyle->m_xSeries];
727     }
728 }
729 
730 //static
731 void SchXMLSeries2Context::setDefaultsToSeries( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles )
732 {
733     ::std::list< DataRowPointStyle >::iterator iStyle;
734     // iterate over series
735     // call initSeriesPropertySets first
736 
737 	for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
738 	{
739 		if( iStyle->meType != DataRowPointStyle::DATA_SERIES )
740             continue;
741 
742         try
743         {
744             uno::Reference< beans::XPropertySet > xSeries( iStyle->m_xOldAPISeries );
745             if( !xSeries.is() )
746                 continue;
747 
748             if( rSeriesDefaultsAndStyles.maSymbolTypeDefault.hasValue() )
749                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolType")),rSeriesDefaultsAndStyles.maSymbolTypeDefault);
750             if( rSeriesDefaultsAndStyles.maDataCaptionDefault.hasValue() )
751                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataCaption")),rSeriesDefaultsAndStyles.maDataCaptionDefault);
752 
753             if( rSeriesDefaultsAndStyles.maErrorIndicatorDefault.hasValue() )
754                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ErrorIndicator")),rSeriesDefaultsAndStyles.maErrorIndicatorDefault);
755             if( rSeriesDefaultsAndStyles.maErrorCategoryDefault.hasValue() )
756                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ErrorCategory")),rSeriesDefaultsAndStyles.maErrorCategoryDefault);
757             if( rSeriesDefaultsAndStyles.maConstantErrorLowDefault.hasValue() )
758                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ConstantErrorLow")),rSeriesDefaultsAndStyles.maConstantErrorLowDefault);
759             if( rSeriesDefaultsAndStyles.maConstantErrorHighDefault.hasValue() )
760                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ConstantErrorHigh")),rSeriesDefaultsAndStyles.maConstantErrorHighDefault);
761             if( rSeriesDefaultsAndStyles.maPercentageErrorDefault.hasValue() )
762                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PercentageError")),rSeriesDefaultsAndStyles.maPercentageErrorDefault);
763             if( rSeriesDefaultsAndStyles.maErrorMarginDefault.hasValue() )
764                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ErrorMargin")),rSeriesDefaultsAndStyles.maErrorMarginDefault);
765 
766             if( rSeriesDefaultsAndStyles.maMeanValueDefault.hasValue() )
767                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MeanValue")),rSeriesDefaultsAndStyles.maMeanValueDefault);
768             if( rSeriesDefaultsAndStyles.maRegressionCurvesDefault.hasValue() )
769                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RegressionCurves")),rSeriesDefaultsAndStyles.maRegressionCurvesDefault);
770         }
771         catch( uno::Exception &  )
772         {
773             //end of series reached
774         }
775     }
776 }
777 
778 //static
779 void SchXMLSeries2Context::setStylesToSeries( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles
780         , const SvXMLStylesContext* pStylesCtxt
781         , const SvXMLStyleContext*& rpStyle
782         , ::rtl::OUString& rCurrStyleName
783         , SchXMLImportHelper& rImportHelper
784         , const SvXMLImport& rImport
785         , bool bIsStockChart
786         , tSchXMLLSequencesPerIndex & rInOutLSequencesPerIndex )
787 {
788     ::std::list< DataRowPointStyle >::iterator iStyle;
789 
790     // iterate over series
791 	for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
792 	{
793 		if( iStyle->meType == DataRowPointStyle::DATA_SERIES )
794 		{
795             try
796 			{
797                 uno::Reference< beans::XPropertySet > xSeriesProp( iStyle->m_xOldAPISeries );
798                 if( !xSeriesProp.is() )
799                     continue;
800 
801                 if( iStyle->mnAttachedAxis != 1 )
802 				{
803 					xSeriesProp->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Axis" ))
804                         , uno::makeAny(chart::ChartAxisAssign::SECONDARY_Y) );
805 				}
806 
807 				if( (iStyle->msStyleName).getLength())
808 				{
809 					if( ! rCurrStyleName.equals( iStyle->msStyleName ))
810 					{
811 						rCurrStyleName = iStyle->msStyleName;
812 						rpStyle = pStylesCtxt->FindStyleChildContext(
813 							rImportHelper.GetChartFamilyID(), rCurrStyleName );
814 					}
815 
816                     //set style to series
817                     // note: SvXMLStyleContext::FillPropertySet is not const
818                     XMLPropStyleContext * pPropStyleContext =
819                         const_cast< XMLPropStyleContext * >(
820                             dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
821                     if( pPropStyleContext )
822                     {
823                         // error bar style must be set before the other error
824                         // bar properties (which may be alphabetically before
825                         // this property)
826                         bool bHasErrorBarRangesFromData = false;
827                         {
828                             const ::rtl::OUString aErrorBarStylePropName( RTL_CONSTASCII_USTRINGPARAM("ErrorBarStyle"));
829                             uno::Any aErrorBarStyle(
830                                 SchXMLTools::getPropertyFromContext( aErrorBarStylePropName, pPropStyleContext, pStylesCtxt ));
831                             if( aErrorBarStyle.hasValue())
832                             {
833                                 xSeriesProp->setPropertyValue( aErrorBarStylePropName, aErrorBarStyle );
834                                 sal_Int32 eEBStyle = chart::ErrorBarStyle::NONE;
835                                 bHasErrorBarRangesFromData =
836                                     ( ( aErrorBarStyle >>= eEBStyle ) &&
837                                       eEBStyle == chart::ErrorBarStyle::FROM_DATA );
838                             }
839                         }
840 
841                         //don't set the style to the min max line series of a stock chart
842                         //otherwise the min max line properties gets overwritten and the series becomes invisible typically
843                         bool bIsMinMaxSeries = false;
844                         if( bIsStockChart )
845                         {
846                             if( SchXMLSeriesHelper::isCandleStickSeries( iStyle->m_xSeries
847                                     , uno::Reference< frame::XModel >( rImportHelper.GetChartDocument(), uno::UNO_QUERY ) ) )
848                                 bIsMinMaxSeries = true;
849                         }
850                         if( !bIsMinMaxSeries )
851                         {
852                             pPropStyleContext->FillPropertySet( xSeriesProp );
853                             if( iStyle->mbSymbolSizeForSeriesIsMissingInFile )
854                                 lcl_setSymbolSizeIfNeeded( xSeriesProp, rImport );
855                             if( bHasErrorBarRangesFromData )
856                                 lcl_insertErrorBarLSequencesToMap( rInOutLSequencesPerIndex, xSeriesProp );
857                         }
858                     }
859 				}
860 			}
861 			catch( uno::Exception & rEx )
862 			{
863                 (void)rEx; // avoid warning for pro build
864                 DBG_ERROR1( "Exception caught during setting styles to series: %s",
865                                 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
866 			}
867 		}
868     }
869 }
870 
871 // static
872 void SchXMLSeries2Context::setStylesToStatisticsObjects( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles
873         , const SvXMLStylesContext* pStylesCtxt
874         , const SvXMLStyleContext*& rpStyle
875         , ::rtl::OUString& rCurrStyleName )
876 {
877     ::std::list< DataRowPointStyle >::iterator iStyle;
878 
879     // iterate over regession etc
880 	for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
881     {
882         if( iStyle->meType == DataRowPointStyle::REGRESSION ||
883             iStyle->meType == DataRowPointStyle::ERROR_INDICATOR ||
884             iStyle->meType == DataRowPointStyle::MEAN_VALUE )
885         {
886             try
887             {
888                 uno::Reference< beans::XPropertySet > xSeriesProp( iStyle->m_xOldAPISeries );
889                 if( !xSeriesProp.is() )
890                     continue;
891 
892 				if( (iStyle->msStyleName).getLength())
893 				{
894 					if( ! rCurrStyleName.equals( iStyle->msStyleName ))
895 					{
896 						rCurrStyleName = iStyle->msStyleName;
897 						rpStyle = pStylesCtxt->FindStyleChildContext(
898 							SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
899 					}
900 
901                     // note: SvXMLStyleContext::FillPropertySet is not const
902                     XMLPropStyleContext * pPropStyleContext =
903                         const_cast< XMLPropStyleContext * >(
904                             dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
905                     if( pPropStyleContext )
906                     {
907                         Reference< beans::XPropertySet > xStatPropSet;
908                         switch( iStyle->meType )
909                         {
910                             case DataRowPointStyle::MEAN_VALUE:
911                                 xSeriesProp->getPropertyValue(
912                                     OUString( RTL_CONSTASCII_USTRINGPARAM(
913                                                   "DataMeanValueProperties" ))) >>= xStatPropSet;
914                                 break;
915                             case DataRowPointStyle::REGRESSION:
916                                 xSeriesProp->getPropertyValue(
917                                     OUString( RTL_CONSTASCII_USTRINGPARAM(
918                                                   "DataRegressionProperties" ))) >>= xStatPropSet;
919                                 break;
920                             case DataRowPointStyle::ERROR_INDICATOR:
921                                 xSeriesProp->getPropertyValue(
922                                     OUString( RTL_CONSTASCII_USTRINGPARAM(
923                                                   "DataErrorProperties" )))  >>= xStatPropSet;
924                                 break;
925                             default:
926                                 break;
927                         }
928                         if( xStatPropSet.is())
929                             pPropStyleContext->FillPropertySet( xStatPropSet );
930                     }
931                 }
932 
933                 // set equation properties at a regression curve
934                 // note: this must be done after setting the regression
935                 // properties at the old API, otherwise the curve itself does
936                 // not exist here
937                 if( iStyle->meType == DataRowPointStyle::REGRESSION && iStyle->m_xEquationProperties.is())
938                 {
939                     OSL_ASSERT( iStyle->m_xSeries.is());
940                     Reference< chart2::XRegressionCurve > xRegCurve( SchXMLTools::getRegressionCurve( iStyle->m_xSeries ));
941                     if( xRegCurve.is())
942                         xRegCurve->setEquationProperties( iStyle->m_xEquationProperties );
943                 }
944             }
945 			catch( uno::Exception & rEx )
946 			{
947                 (void)rEx; // avoid warning for pro build
948                 DBG_ERROR1( "Exception caught during setting styles to series: %s",
949                                 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
950 			}
951 		}
952     }
953 }
954 
955 //static
956 void SchXMLSeries2Context::setStylesToDataPoints( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles
957         , const SvXMLStylesContext* pStylesCtxt
958         , const SvXMLStyleContext*& rpStyle
959         , ::rtl::OUString& rCurrStyleName
960         , SchXMLImportHelper& rImportHelper
961         , const SvXMLImport& rImport
962         , bool bIsStockChart, bool bIsDonutChart, bool bSwitchOffLinesForScatter )
963 {
964     ::std::list< DataRowPointStyle >::iterator iStyle;
965     for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
966 	{
967         if( iStyle->meType != DataRowPointStyle::DATA_POINT )
968             continue;
969 
970 		if( iStyle->m_nPointIndex == -1 )
971             continue;
972 
973 		//ignore datapoint properties for stock charts
974         //... todo ...
975         if( bIsStockChart )
976         {
977             if( SchXMLSeriesHelper::isCandleStickSeries( iStyle->m_xSeries, uno::Reference< frame::XModel >( rImportHelper.GetChartDocument(), uno::UNO_QUERY ) ) )
978                 continue;
979         }
980 
981         // data point style
982 		for( sal_Int32 i = 0; i < iStyle->m_nPointRepeat; i++ )
983 		{
984 			try
985 			{
986                 uno::Reference< beans::XPropertySet > xSeriesProp( iStyle->m_xOldAPISeries );
987                 if(!xSeriesProp.is())
988                     continue;
989 
990                 uno::Reference< beans::XPropertySet > xPointProp(
991                     SchXMLSeriesHelper::createOldAPIDataPointPropertySet( iStyle->m_xSeries, iStyle->m_nPointIndex + i
992                         , uno::Reference< frame::XModel >( rImportHelper.GetChartDocument(), uno::UNO_QUERY ) ) );
993 
994                 if( !xPointProp.is() )
995                     continue;
996 
997                 if( bIsDonutChart )
998                 {
999                     //set special series styles for donut charts first
1000                     if( !rCurrStyleName.equals( iStyle->msSeriesStyleNameForDonuts ) )
1001 					{
1002 						rCurrStyleName = iStyle->msSeriesStyleNameForDonuts;
1003 						rpStyle = pStylesCtxt->FindStyleChildContext(
1004 							rImportHelper.GetChartFamilyID(), rCurrStyleName );
1005 					}
1006 
1007                     // note: SvXMLStyleContext::FillPropertySet is not const
1008                     XMLPropStyleContext * pPropStyleContext =
1009                         const_cast< XMLPropStyleContext * >(
1010                             dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1011                     if( pPropStyleContext )
1012 						pPropStyleContext->FillPropertySet( xPointProp );
1013                 }
1014 
1015                 try
1016                 {
1017                     //need to set this explicitely here for old files as the new api does not support this property fully anymore
1018                     if( bSwitchOffLinesForScatter )
1019                         xPointProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Lines")),uno::makeAny(sal_False));
1020                 }
1021                 catch( uno::Exception & rEx )
1022                 {
1023                     (void)rEx; // avoid warning for pro build
1024                 }
1025 
1026 				if( !rCurrStyleName.equals( iStyle->msStyleName ) )
1027 				{
1028 					rCurrStyleName = iStyle->msStyleName;
1029 					rpStyle = pStylesCtxt->FindStyleChildContext(
1030 						rImportHelper.GetChartFamilyID(), rCurrStyleName );
1031 				}
1032 
1033                 // note: SvXMLStyleContext::FillPropertySet is not const
1034                 XMLPropStyleContext * pPropStyleContext =
1035                     const_cast< XMLPropStyleContext * >(
1036                         dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1037                 if( pPropStyleContext )
1038                 {
1039                     pPropStyleContext->FillPropertySet( xPointProp );
1040                     if( iStyle->mbSymbolSizeForSeriesIsMissingInFile )
1041                         lcl_resetSymbolSizeForPointsIfNecessary( xPointProp, rImport, pPropStyleContext, pStylesCtxt );
1042                 }
1043 			}
1044 			catch( uno::Exception & rEx )
1045 			{
1046                 (void)rEx; // avoid warning for pro build
1047 				DBG_ERROR1( "Exception caught during setting styles to data points: %s",
1048                                     OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
1049 			}
1050 		}
1051 	}	// styles iterator
1052 }
1053 
1054 //static
1055 void SchXMLSeries2Context::switchSeriesLinesOff( ::std::list< DataRowPointStyle >& rSeriesStyleList )
1056 {
1057     ::std::list< DataRowPointStyle >::iterator iStyle;
1058     // iterate over series
1059 
1060 	for( iStyle = rSeriesStyleList.begin(); iStyle != rSeriesStyleList.end(); iStyle++ )
1061 	{
1062 		if( iStyle->meType != DataRowPointStyle::DATA_SERIES )
1063             continue;
1064 
1065         try
1066         {
1067             uno::Reference< beans::XPropertySet > xSeries( iStyle->m_xOldAPISeries );
1068             if( !xSeries.is() )
1069                 continue;
1070 
1071             xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Lines")),uno::makeAny(sal_False));
1072         }
1073         catch( uno::Exception &  )
1074         {
1075             //end of series reached
1076         }
1077     }
1078 }
1079