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 #include "oox/drawingml/chart/seriescontext.hxx"
29 
30 #include "oox/drawingml/shapepropertiescontext.hxx"
31 #include "oox/drawingml/textbodycontext.hxx"
32 #include "oox/drawingml/chart/datasourcecontext.hxx"
33 #include "oox/drawingml/chart/seriesmodel.hxx"
34 #include "oox/drawingml/chart/titlecontext.hxx"
35 
36 namespace oox {
37 namespace drawingml {
38 namespace chart {
39 
40 // ============================================================================
41 
42 using ::oox::core::ContextHandler2;
43 using ::oox::core::ContextHandler2Helper;
44 using ::oox::core::ContextHandlerRef;
45 using ::rtl::OUString;
46 
47 // ============================================================================
48 
49 namespace {
50 
51 ContextHandlerRef lclDataLabelSharedCreateContext( ContextHandler2& rContext,
52         sal_Int32 nElement, const AttributeList& rAttribs, DataLabelModelBase& orModel )
53 {
54     if( rContext.isRootElement() ) switch( nElement )
55     {
56         case C_TOKEN( delete ):
57             // default is 'false', not 'true' as specified
58             orModel.mbDeleted = rAttribs.getBool( XML_val, false );
59             return 0;
60         case C_TOKEN( dLblPos ):
61             orModel.monLabelPos = rAttribs.getToken( XML_val, XML_TOKEN_INVALID );
62             return 0;
63         case C_TOKEN( numFmt ):
64             orModel.maNumberFormat.setAttributes( rAttribs );
65             return 0;
66         case C_TOKEN( showBubbleSize ):
67             orModel.mobShowBubbleSize = rAttribs.getBool( XML_val );
68             return 0;
69         case C_TOKEN( showCatName ):
70             orModel.mobShowCatName = rAttribs.getBool( XML_val );
71             return 0;
72         case C_TOKEN( showLegendKey ):
73             orModel.mobShowLegendKey = rAttribs.getBool( XML_val );
74             return 0;
75         case C_TOKEN( showPercent ):
76             orModel.mobShowPercent = rAttribs.getBool( XML_val );
77             return 0;
78         case C_TOKEN( showSerName ):
79             orModel.mobShowSerName = rAttribs.getBool( XML_val );
80             return 0;
81         case C_TOKEN( showVal ):
82             orModel.mobShowVal = rAttribs.getBool( XML_val );
83             return 0;
84         case C_TOKEN( separator ):
85             // collect separator text in onCharacters()
86             return &rContext;
87         case C_TOKEN( spPr ):
88             return new ShapePropertiesContext( rContext, orModel.mxShapeProp.create() );
89         case C_TOKEN( txPr ):
90             return new TextBodyContext( rContext, orModel.mxTextProp.create() );
91     }
92     return 0;
93 }
94 
95 void lclDataLabelSharedCharacters( ContextHandler2& rContext, const OUString& rChars, DataLabelModelBase& orModel )
96 {
97     if( rContext.isCurrentElement( C_TOKEN( separator ) ) )
98         orModel.moaSeparator = rChars;
99 }
100 
101 } // namespace
102 
103 // ============================================================================
104 
105 DataLabelContext::DataLabelContext( ContextHandler2Helper& rParent, DataLabelModel& rModel ) :
106     ContextBase< DataLabelModel >( rParent, rModel )
107 {
108 }
109 
110 DataLabelContext::~DataLabelContext()
111 {
112 }
113 
114 ContextHandlerRef DataLabelContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
115 {
116     if( isRootElement() ) switch( nElement )
117     {
118         case C_TOKEN( idx ):
119             mrModel.mnIndex = rAttribs.getInteger( XML_val, -1 );
120             return 0;
121         case C_TOKEN( layout ):
122             return new LayoutContext( *this, mrModel.mxLayout.create() );
123         case C_TOKEN( tx ):
124             return new TextContext( *this, mrModel.mxText.create() );
125     }
126     return lclDataLabelSharedCreateContext( *this, nElement, rAttribs, mrModel );
127 }
128 
129 void DataLabelContext::onCharacters( const OUString& rChars )
130 {
131     lclDataLabelSharedCharacters( *this, rChars, mrModel );
132 }
133 
134 // ============================================================================
135 
136 DataLabelsContext::DataLabelsContext( ContextHandler2Helper& rParent, DataLabelsModel& rModel ) :
137     ContextBase< DataLabelsModel >( rParent, rModel )
138 {
139 }
140 
141 DataLabelsContext::~DataLabelsContext()
142 {
143 }
144 
145 ContextHandlerRef DataLabelsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
146 {
147     if( isRootElement() ) switch( nElement )
148     {
149         case C_TOKEN( dLbl ):
150             return new DataLabelContext( *this, mrModel.maPointLabels.create() );
151         case C_TOKEN( leaderLines ):
152             return new ShapePrWrapperContext( *this, mrModel.mxLeaderLines.create() );
153         case C_TOKEN( showLeaderLines ):
154             // default is 'false', not 'true' as specified
155             mrModel.mbShowLeaderLines = rAttribs.getBool( XML_val, false );
156             return 0;
157     }
158     return lclDataLabelSharedCreateContext( *this, nElement, rAttribs, mrModel );
159 }
160 
161 void DataLabelsContext::onCharacters( const OUString& rChars )
162 {
163     lclDataLabelSharedCharacters( *this, rChars, mrModel );
164 }
165 
166 // ============================================================================
167 
168 PictureOptionsContext::PictureOptionsContext( ContextHandler2Helper& rParent, PictureOptionsModel& rModel ) :
169     ContextBase< PictureOptionsModel >( rParent, rModel )
170 {
171 }
172 
173 PictureOptionsContext::~PictureOptionsContext()
174 {
175 }
176 
177 ContextHandlerRef PictureOptionsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
178 {
179     if( isRootElement() ) switch( nElement )
180     {
181         case C_TOKEN( applyToEnd ):
182             // default is 'false', not 'true' as specified
183             mrModel.mbApplyToEnd = rAttribs.getBool( XML_val, false );
184             return 0;
185         case C_TOKEN( applyToFront ):
186             // default is 'false', not 'true' as specified
187             mrModel.mbApplyToFront = rAttribs.getBool( XML_val, false );
188             return 0;
189         case C_TOKEN( applyToSides ):
190             // default is 'false', not 'true' as specified
191             mrModel.mbApplyToSides = rAttribs.getBool( XML_val, false );
192             return 0;
193         case C_TOKEN( pictureFormat ):
194             mrModel.mnPictureFormat = rAttribs.getToken( XML_val, XML_stretch );
195             return 0;
196         case C_TOKEN( pictureStackUnit ):
197             mrModel.mfStackUnit = rAttribs.getDouble( XML_val, 1.0 );
198             return 0;
199     }
200     return 0;
201 }
202 
203 // ============================================================================
204 
205 ErrorBarContext::ErrorBarContext( ContextHandler2Helper& rParent, ErrorBarModel& rModel ) :
206     ContextBase< ErrorBarModel >( rParent, rModel )
207 {
208 }
209 
210 ErrorBarContext::~ErrorBarContext()
211 {
212 }
213 
214 ContextHandlerRef ErrorBarContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
215 {
216     if( isRootElement() ) switch( nElement )
217     {
218         case C_TOKEN( errBarType ):
219             mrModel.mnTypeId = rAttribs.getToken( XML_val, XML_both );
220             return 0;
221         case C_TOKEN( errDir ):
222             mrModel.mnDirection = rAttribs.getToken( XML_val, XML_TOKEN_INVALID );
223             return 0;
224         case C_TOKEN( errValType ):
225             mrModel.mnValueType = rAttribs.getToken( XML_val, XML_fixedVal );
226             return 0;
227         case C_TOKEN( minus ):
228             return new DataSourceContext( *this, mrModel.maSources.create( ErrorBarModel::MINUS ) );
229         case C_TOKEN( noEndCap ):
230             // default is 'false', not 'true' as specified
231             mrModel.mbNoEndCap = rAttribs.getBool( XML_val, false );
232             return 0;
233         case C_TOKEN( plus ):
234             return new DataSourceContext( *this, mrModel.maSources.create( ErrorBarModel::PLUS ) );
235         case C_TOKEN( spPr ):
236             return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
237         case C_TOKEN( val ):
238             mrModel.mfValue = rAttribs.getDouble( XML_val, 0.0 );
239             return 0;
240     }
241     return 0;
242 }
243 
244 // ============================================================================
245 
246 TrendlineLabelContext::TrendlineLabelContext( ContextHandler2Helper& rParent, TrendlineLabelModel& rModel ) :
247     ContextBase< TrendlineLabelModel >( rParent, rModel )
248 {
249 }
250 
251 TrendlineLabelContext::~TrendlineLabelContext()
252 {
253 }
254 
255 ContextHandlerRef TrendlineLabelContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
256 {
257     if( isRootElement() ) switch( nElement )
258     {
259         case C_TOKEN( layout ):
260             return new LayoutContext( *this, mrModel.mxLayout.create() );
261         case C_TOKEN( numFmt ):
262             mrModel.maNumberFormat.setAttributes( rAttribs );
263             return 0;
264         case C_TOKEN( spPr ):
265             return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
266         case C_TOKEN( tx ):
267             return new TextContext( *this, mrModel.mxText.create() );
268         case C_TOKEN( txPr ):
269             return new TextBodyContext( *this, mrModel.mxTextProp.create() );
270     }
271     return 0;
272 }
273 
274 // ============================================================================
275 
276 TrendlineContext::TrendlineContext( ContextHandler2Helper& rParent, TrendlineModel& rModel ) :
277     ContextBase< TrendlineModel >( rParent, rModel )
278 {
279 }
280 
281 TrendlineContext::~TrendlineContext()
282 {
283 }
284 
285 ContextHandlerRef TrendlineContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
286 {
287     if( isRootElement() ) switch( nElement )
288     {
289         case C_TOKEN( backward ):
290             mrModel.mfBackward = rAttribs.getDouble( XML_val, 0.0 );
291             return 0;
292         case C_TOKEN( dispEq ):
293             // default is 'false', not 'true' as specified
294             mrModel.mbDispEquation = rAttribs.getBool( XML_val, false );
295             return 0;
296         case C_TOKEN( dispRSqr ):
297             // default is 'false', not 'true' as specified
298             mrModel.mbDispRSquared = rAttribs.getBool( XML_val, false );
299             return 0;
300         case C_TOKEN( forward ):
301             mrModel.mfForward = rAttribs.getDouble( XML_val, 0.0 );
302             return 0;
303         case C_TOKEN( intercept ):
304             mrModel.mfIntercept = rAttribs.getDouble( XML_val, 0.0 );
305             return 0;
306         case C_TOKEN( name ):
307             return this;    // collect name in onCharacters()
308         case C_TOKEN( order ):
309             mrModel.mnOrder = rAttribs.getInteger( XML_val, 2 );
310             return 0;
311         case C_TOKEN( period ):
312             mrModel.mnPeriod = rAttribs.getInteger( XML_val, 2 );
313             return 0;
314         case C_TOKEN( spPr ):
315             return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
316         case C_TOKEN( trendlineLbl ):
317             return new TrendlineLabelContext( *this, mrModel.mxLabel.create() );
318         case C_TOKEN( trendlineType ):
319             mrModel.mnTypeId = rAttribs.getToken( XML_val, XML_linear );
320             return 0;
321     }
322     return 0;
323 }
324 
325 void TrendlineContext::onCharacters( const OUString& rChars )
326 {
327     if( isCurrentElement( C_TOKEN( name ) ) )
328         mrModel.maName = rChars;
329 }
330 
331 // ============================================================================
332 
333 DataPointContext::DataPointContext( ContextHandler2Helper& rParent, DataPointModel& rModel ) :
334     ContextBase< DataPointModel >( rParent, rModel )
335 {
336 }
337 
338 DataPointContext::~DataPointContext()
339 {
340 }
341 
342 ContextHandlerRef DataPointContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
343 {
344     switch( getCurrentElement() )
345     {
346         case C_TOKEN( dPt ):
347             switch( nElement )
348             {
349                 case C_TOKEN( bubble3D ):
350                     mrModel.mobBubble3d = rAttribs.getBool( XML_val );
351                     return 0;
352                 case C_TOKEN( explosion ):
353                     // if the 'val' attribute is missing, series explosion remains unchanged
354                     mrModel.monExplosion = rAttribs.getInteger( XML_val );
355                     return 0;
356                 case C_TOKEN( idx ):
357                     mrModel.mnIndex = rAttribs.getInteger( XML_val, -1 );
358                     return 0;
359                 case C_TOKEN( invertIfNegative ):
360                     // default is 'false', not 'true' as specified (value not derived from series!)
361                     mrModel.mbInvertNeg = rAttribs.getBool( XML_val, false );
362                     return 0;
363                 case C_TOKEN( marker ):
364                     return this;
365                 case C_TOKEN( pictureOptions ):
366                     return new PictureOptionsContext( *this, mrModel.mxPicOptions.create() );
367                 case C_TOKEN( spPr ):
368                     return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
369             }
370         break;
371 
372         case C_TOKEN( marker ):
373             switch( nElement )
374             {
375                 case C_TOKEN( size ):
376                     mrModel.monMarkerSize = rAttribs.getInteger( XML_val, 5 );
377                     return 0;
378                 case C_TOKEN( spPr ):
379                     return new ShapePropertiesContext( *this, mrModel.mxMarkerProp.create() );
380                 case C_TOKEN( symbol ):
381                     mrModel.monMarkerSymbol = rAttribs.getToken( XML_val, XML_none );
382                     return 0;
383             }
384         break;
385     }
386     return 0;
387 }
388 
389 // ============================================================================
390 
391 SeriesContextBase::SeriesContextBase( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
392     ContextBase< SeriesModel >( rParent, rModel )
393 {
394 }
395 
396 SeriesContextBase::~SeriesContextBase()
397 {
398 }
399 
400 ContextHandlerRef SeriesContextBase::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
401 {
402     switch( getCurrentElement() )
403     {
404         case C_TOKEN( ser ):
405             switch( nElement )
406             {
407                 case C_TOKEN( idx ):
408                     mrModel.mnIndex = rAttribs.getInteger( XML_val, -1 );
409                     return 0;
410                 case C_TOKEN( order ):
411                     mrModel.mnOrder = rAttribs.getInteger( XML_val, -1 );
412                     return 0;
413                 case C_TOKEN( spPr ):
414                     return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
415                 case C_TOKEN( tx ):
416                     return new TextContext( *this, mrModel.mxText.create() );
417             }
418         break;
419 
420         case C_TOKEN( marker ):
421             switch( nElement )
422             {
423                 case C_TOKEN( size ):
424                     mrModel.mnMarkerSize = rAttribs.getInteger( XML_val, 5 );
425                     return 0;
426                 case C_TOKEN( spPr ):
427                     return new ShapePropertiesContext( *this, mrModel.mxMarkerProp.create() );
428                 case C_TOKEN( symbol ):
429                     mrModel.mnMarkerSymbol = rAttribs.getToken( XML_val, XML_none );
430                     return 0;
431             }
432         break;
433     }
434     return 0;
435 }
436 
437 // ============================================================================
438 
439 AreaSeriesContext::AreaSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
440     SeriesContextBase( rParent, rModel )
441 {
442 }
443 
444 AreaSeriesContext::~AreaSeriesContext()
445 {
446 }
447 
448 ContextHandlerRef AreaSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
449 {
450     switch( getCurrentElement() )
451     {
452         case C_TOKEN( ser ):
453             switch( nElement )
454             {
455                 case C_TOKEN( cat ):
456                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
457                 case C_TOKEN( errBars ):
458                     return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
459                 case C_TOKEN( dLbls ):
460                     return new DataLabelsContext( *this, mrModel.mxLabels.create() );
461                 case C_TOKEN( dPt ):
462                     return new DataPointContext( *this, mrModel.maPoints.create() );
463                 case C_TOKEN( trendline ):
464                     return new TrendlineContext( *this, mrModel.maTrendlines.create() );
465                 case C_TOKEN( val ):
466                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
467             }
468         break;
469     }
470     return SeriesContextBase::onCreateContext( nElement, rAttribs );
471 }
472 
473 // ============================================================================
474 
475 BarSeriesContext::BarSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
476     SeriesContextBase( rParent, rModel )
477 {
478 }
479 
480 BarSeriesContext::~BarSeriesContext()
481 {
482 }
483 
484 ContextHandlerRef BarSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
485 {
486     switch( getCurrentElement() )
487     {
488         case C_TOKEN( ser ):
489             switch( nElement )
490             {
491                 case C_TOKEN( cat ):
492                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
493                 case C_TOKEN( dLbls ):
494                     return new DataLabelsContext( *this, mrModel.mxLabels.create() );
495                 case C_TOKEN( dPt ):
496                     return new DataPointContext( *this, mrModel.maPoints.create() );
497                 case C_TOKEN( errBars ):
498                     return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
499                 case C_TOKEN( invertIfNegative ):
500                     // default is 'false', not 'true' as specified
501                     mrModel.mbInvertNeg = rAttribs.getBool( XML_val, false );
502                     return 0;
503                 case C_TOKEN( pictureOptions ):
504                     return new PictureOptionsContext( *this, mrModel.mxPicOptions.create() );
505                 case C_TOKEN( shape ):
506                     // missing attribute does not change shape type to 'box' as specified
507                     mrModel.monShape = rAttribs.getToken( XML_val );
508                     return 0;
509                 case C_TOKEN( trendline ):
510                     return new TrendlineContext( *this, mrModel.maTrendlines.create() );
511                 case C_TOKEN( val ):
512                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
513             }
514         break;
515     }
516     return SeriesContextBase::onCreateContext( nElement, rAttribs );
517 }
518 
519 // ============================================================================
520 
521 BubbleSeriesContext::BubbleSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
522     SeriesContextBase( rParent, rModel )
523 {
524 }
525 
526 BubbleSeriesContext::~BubbleSeriesContext()
527 {
528 }
529 
530 ContextHandlerRef BubbleSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
531 {
532     switch( getCurrentElement() )
533     {
534         case C_TOKEN( ser ):
535             switch( nElement )
536             {
537                 case C_TOKEN( bubble3D ):
538                     // default is 'false', not 'true' as specified
539                     mrModel.mbBubble3d = rAttribs.getBool( XML_val, false );
540                     return 0;
541                 case C_TOKEN( bubbleSize ):
542                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::POINTS ) );
543                 case C_TOKEN( dLbls ):
544                     return new DataLabelsContext( *this, mrModel.mxLabels.create() );
545                 case C_TOKEN( dPt ):
546                     return new DataPointContext( *this, mrModel.maPoints.create() );
547                 case C_TOKEN( errBars ):
548                     return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
549                 case C_TOKEN( invertIfNegative ):
550                     // default is 'false', not 'true' as specified
551                     mrModel.mbInvertNeg = rAttribs.getBool( XML_val, false );
552                     return 0;
553                 case C_TOKEN( trendline ):
554                     return new TrendlineContext( *this, mrModel.maTrendlines.create() );
555                 case C_TOKEN( xVal ):
556                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
557                 case C_TOKEN( yVal ):
558                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
559             }
560         break;
561     }
562     return SeriesContextBase::onCreateContext( nElement, rAttribs );
563 }
564 
565 // ============================================================================
566 
567 LineSeriesContext::LineSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
568     SeriesContextBase( rParent, rModel )
569 {
570 }
571 
572 LineSeriesContext::~LineSeriesContext()
573 {
574 }
575 
576 ContextHandlerRef LineSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
577 {
578     switch( getCurrentElement() )
579     {
580         case C_TOKEN( ser ):
581             switch( nElement )
582             {
583                 case C_TOKEN( cat ):
584                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
585                 case C_TOKEN( dLbls ):
586                     return new DataLabelsContext( *this, mrModel.mxLabels.create() );
587                 case C_TOKEN( dPt ):
588                     return new DataPointContext( *this, mrModel.maPoints.create() );
589                 case C_TOKEN( errBars ):
590                     return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
591                 case C_TOKEN( marker ):
592                     return this;
593                 case C_TOKEN( smooth ):
594                     // default is 'false', not 'true' as specified
595                     mrModel.mbSmooth = rAttribs.getBool( XML_val, false );
596                     return 0;
597                 case C_TOKEN( trendline ):
598                     return new TrendlineContext( *this, mrModel.maTrendlines.create() );
599                 case C_TOKEN( val ):
600                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
601             }
602         break;
603     }
604     return SeriesContextBase::onCreateContext( nElement, rAttribs );
605 }
606 
607 // ============================================================================
608 
609 PieSeriesContext::PieSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
610     SeriesContextBase( rParent, rModel )
611 {
612 }
613 
614 PieSeriesContext::~PieSeriesContext()
615 {
616 }
617 
618 ContextHandlerRef PieSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
619 {
620     switch( getCurrentElement() )
621     {
622         case C_TOKEN( ser ):
623             switch( nElement )
624             {
625                 case C_TOKEN( cat ):
626                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
627                 case C_TOKEN( dLbls ):
628                     return new DataLabelsContext( *this, mrModel.mxLabels.create() );
629                 case C_TOKEN( dPt ):
630                     return new DataPointContext( *this, mrModel.maPoints.create() );
631                 case C_TOKEN( explosion ):
632                     mrModel.mnExplosion = rAttribs.getInteger( XML_val, 0 );
633                     return 0;
634                 case C_TOKEN( val ):
635                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
636             }
637         break;
638     }
639     return SeriesContextBase::onCreateContext( nElement, rAttribs );
640 }
641 
642 // ============================================================================
643 
644 RadarSeriesContext::RadarSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
645     SeriesContextBase( rParent, rModel )
646 {
647 }
648 
649 RadarSeriesContext::~RadarSeriesContext()
650 {
651 }
652 
653 ContextHandlerRef RadarSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
654 {
655     switch( getCurrentElement() )
656     {
657         case C_TOKEN( ser ):
658             switch( nElement )
659             {
660                 case C_TOKEN( cat ):
661                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
662                 case C_TOKEN( dLbls ):
663                     return new DataLabelsContext( *this, mrModel.mxLabels.create() );
664                 case C_TOKEN( dPt ):
665                     return new DataPointContext( *this, mrModel.maPoints.create() );
666                 case C_TOKEN( marker ):
667                     return this;
668                 case C_TOKEN( smooth ):
669                     // default is 'false', not 'true' as specified
670                     mrModel.mbSmooth = rAttribs.getBool( XML_val, false );
671                     return 0;
672                 case C_TOKEN( val ):
673                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
674             }
675         break;
676     }
677     return SeriesContextBase::onCreateContext( nElement, rAttribs );
678 }
679 
680 // ============================================================================
681 
682 ScatterSeriesContext::ScatterSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
683     SeriesContextBase( rParent, rModel )
684 {
685 }
686 
687 ScatterSeriesContext::~ScatterSeriesContext()
688 {
689 }
690 
691 ContextHandlerRef ScatterSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
692 {
693     switch( getCurrentElement() )
694     {
695         case C_TOKEN( ser ):
696             switch( nElement )
697             {
698                 case C_TOKEN( dLbls ):
699                     return new DataLabelsContext( *this, mrModel.mxLabels.create() );
700                 case C_TOKEN( dPt ):
701                     return new DataPointContext( *this, mrModel.maPoints.create() );
702                 case C_TOKEN( errBars ):
703                     return new ErrorBarContext( *this, mrModel.maErrorBars.create() );
704                 case C_TOKEN( marker ):
705                     return this;
706                 case C_TOKEN( smooth ):
707                     // default is 'false', not 'true' as specified
708                     mrModel.mbSmooth = rAttribs.getBool( XML_val, false );
709                     return 0;
710                 case C_TOKEN( trendline ):
711                     return new TrendlineContext( *this, mrModel.maTrendlines.create() );
712                 case C_TOKEN( xVal ):
713                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
714                 case C_TOKEN( yVal ):
715                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
716             }
717         break;
718     }
719     return SeriesContextBase::onCreateContext( nElement, rAttribs );
720 }
721 
722 // ============================================================================
723 
724 SurfaceSeriesContext::SurfaceSeriesContext( ContextHandler2Helper& rParent, SeriesModel& rModel ) :
725     SeriesContextBase( rParent, rModel )
726 {
727 }
728 
729 SurfaceSeriesContext::~SurfaceSeriesContext()
730 {
731 }
732 
733 ContextHandlerRef SurfaceSeriesContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
734 {
735     switch( getCurrentElement() )
736     {
737         case C_TOKEN( ser ):
738             switch( nElement )
739             {
740                 case C_TOKEN( cat ):
741                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) );
742                 case C_TOKEN( val ):
743                     return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) );
744             }
745         break;
746     }
747     return SeriesContextBase::onCreateContext( nElement, rAttribs );
748 }
749 
750 // ============================================================================
751 
752 } // namespace chart
753 } // namespace drawingml
754 } // namespace oox
755