bump product version to 5.0.4.1
[LibreOffice.git] / xmloff / source / chart / SchXMLAxisContext.cxx
blob502ef083896507d0779c0535c2519c0d4848739f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sax/tools/converter.hxx>
22 #include "SchXMLAxisContext.hxx"
23 #include "SchXMLChartContext.hxx"
24 #include "SchXMLTools.hxx"
25 #include <xmloff/xmlnmspe.hxx>
26 #include <xmloff/xmlement.hxx>
27 #include <xmloff/xmlstyle.hxx>
28 #include <xmloff/prstylei.hxx>
29 #include <xmloff/nmspmap.hxx>
30 #include <xmloff/xmluconv.hxx>
32 #include <tools/color.hxx>
34 #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
35 #include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
36 #include <com/sun/star/chart/ChartAxisPosition.hpp>
37 #include <com/sun/star/chart/ChartAxisType.hpp>
38 #include <com/sun/star/chart/TimeIncrement.hpp>
39 #include <com/sun/star/chart/TimeInterval.hpp>
40 #include <com/sun/star/chart/TimeUnit.hpp>
41 #include <com/sun/star/chart/XAxis.hpp>
42 #include <com/sun/star/chart/XAxisSupplier.hpp>
43 #include <com/sun/star/chart2/AxisType.hpp>
44 #include <com/sun/star/chart2/XChartDocument.hpp>
45 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
47 #include <com/sun/star/drawing/LineStyle.hpp>
49 using namespace ::xmloff::token;
50 using namespace com::sun::star;
52 using com::sun::star::uno::Reference;
54 static const SvXMLEnumMapEntry aXMLAxisDimensionMap[] =
56 { XML_X, SCH_XML_AXIS_X },
57 { XML_Y, SCH_XML_AXIS_Y },
58 { XML_Z, SCH_XML_AXIS_Z },
59 { XML_TOKEN_INVALID, 0 }
62 static const SvXMLEnumMapEntry aXMLAxisTypeMap[] =
64 { XML_AUTO, ::com::sun::star::chart::ChartAxisType::AUTOMATIC },
65 { XML_TEXT, ::com::sun::star::chart::ChartAxisType::CATEGORY },
66 { XML_DATE, ::com::sun::star::chart::ChartAxisType::DATE },
67 { XML_TOKEN_INVALID, 0 }
70 class SchXMLCategoriesContext : public SvXMLImportContext
72 private:
73 OUString& mrAddress;
75 public:
76 SchXMLCategoriesContext( SvXMLImport& rImport,
77 sal_uInt16 nPrefix,
78 const OUString& rLocalName,
79 OUString& rAddress );
80 virtual ~SchXMLCategoriesContext();
81 virtual void StartElement( const Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList ) SAL_OVERRIDE;
84 class DateScaleContext : public SvXMLImportContext
86 public:
87 DateScaleContext( SvXMLImport& rImport,
88 sal_uInt16 nPrefix, const OUString& rLocalName,
89 const Reference< beans::XPropertySet >& rAxisProps );
91 virtual ~DateScaleContext();
92 virtual void StartElement( const Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList ) SAL_OVERRIDE;
94 private:
95 Reference< beans::XPropertySet > m_xAxisProps;
98 SchXMLAxisContext::SchXMLAxisContext( SchXMLImportHelper& rImpHelper,
99 SvXMLImport& rImport, const OUString& rLocalName,
100 Reference< chart::XDiagram > xDiagram,
101 std::vector< SchXMLAxis >& rAxes,
102 OUString & rCategoriesAddress,
103 bool bAddMissingXAxisForNetCharts,
104 bool bAdaptWrongPercentScaleValues,
105 bool bAdaptXAxisOrientationForOld2DBarCharts,
106 bool& rbAxisPositionAttributeImported ) :
107 SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
108 m_rImportHelper( rImpHelper ),
109 m_xDiagram( xDiagram ),
110 m_rAxes( rAxes ),
111 m_rCategoriesAddress( rCategoriesAddress ),
112 m_nAxisType(chart::ChartAxisType::AUTOMATIC),
113 m_bAxisTypeImported(false),
114 m_bDateScaleImported(false),
115 m_bAddMissingXAxisForNetCharts( bAddMissingXAxisForNetCharts ),
116 m_bAdaptWrongPercentScaleValues( bAdaptWrongPercentScaleValues ),
117 m_bAdaptXAxisOrientationForOld2DBarCharts( bAdaptXAxisOrientationForOld2DBarCharts ),
118 m_rbAxisPositionAttributeImported( rbAxisPositionAttributeImported )
122 SchXMLAxisContext::~SchXMLAxisContext()
125 static Reference< chart::XAxis > lcl_getChartAxis(const SchXMLAxis& rCurrentAxis, const Reference< chart::XDiagram >& rDiagram )
127 Reference< chart::XAxis > xAxis;
128 Reference< chart::XAxisSupplier > xAxisSuppl( rDiagram, uno::UNO_QUERY );
129 if( !xAxisSuppl.is() )
130 return xAxis;
131 if( rCurrentAxis.nAxisIndex == 0 )
132 xAxis = xAxisSuppl->getAxis(rCurrentAxis.eDimension);
133 else
134 xAxis = xAxisSuppl->getSecondaryAxis(rCurrentAxis.eDimension);
135 return xAxis;
138 /* returns a shape for the current axis's title. The property
139 "Has...AxisTitle" is set to "True" to get the shape
141 Reference< drawing::XShape > SchXMLAxisContext::getTitleShape()
143 Reference< drawing::XShape > xResult;
144 Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY );
145 Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) );
146 if( !xDiaProp.is() || !xAxis.is() )
147 return xResult;
149 OUString aPropName;
150 switch( m_aCurrentAxis.eDimension )
152 case SCH_XML_AXIS_X:
153 if( m_aCurrentAxis.nAxisIndex == 0 )
154 aPropName = "HasXAxisTitle";
155 else
156 aPropName = "HasSecondaryXAxisTitle";
157 break;
158 case SCH_XML_AXIS_Y:
159 if( m_aCurrentAxis.nAxisIndex == 0 )
160 aPropName = "HasYAxisTitle";
161 else
162 aPropName = "HasSecondaryYAxisTitle";
163 break;
164 case SCH_XML_AXIS_Z:
165 aPropName = "HasZAxisTitle";
166 break;
167 case SCH_XML_AXIS_UNDEF:
168 SAL_INFO("xmloff.chart", "Invalid axis" );
169 break;
171 xDiaProp->setPropertyValue( aPropName, uno::makeAny(sal_True) );
172 xResult = Reference< drawing::XShape >( xAxis->getAxisTitle(), uno::UNO_QUERY );
173 return xResult;
176 void SchXMLAxisContext::CreateGrid( const OUString& sAutoStyleName, bool bIsMajor )
178 Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY );
179 Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) );
180 if( !xDiaProp.is() || !xAxis.is() )
181 return;
183 OUString aPropName;
184 switch( m_aCurrentAxis.eDimension )
186 case SCH_XML_AXIS_X:
187 if( bIsMajor )
188 aPropName = "HasXAxisGrid";
189 else
190 aPropName = "HasXAxisHelpGrid";
191 break;
192 case SCH_XML_AXIS_Y:
193 if( bIsMajor )
194 aPropName = "HasYAxisGrid";
195 else
196 aPropName = "HasYAxisHelpGrid";
197 break;
198 case SCH_XML_AXIS_Z:
199 if( bIsMajor )
200 aPropName = "HasZAxisGrid";
201 else
202 aPropName = "HasZAxisHelpGrid";
203 break;
204 case SCH_XML_AXIS_UNDEF:
205 SAL_INFO("xmloff.chart", "Invalid axis" );
206 break;
208 xDiaProp->setPropertyValue( aPropName, uno::makeAny(sal_True) );
210 Reference< beans::XPropertySet > xGridProp;
211 if( bIsMajor )
212 xGridProp = xAxis->getMajorGrid();
213 else
214 xGridProp = xAxis->getMinorGrid();
216 // set properties
217 if( xGridProp.is())
219 // the line color is black as default, in the model it is a light gray
220 xGridProp->setPropertyValue("LineColor",
221 uno::makeAny( COL_BLACK ));
222 if( !sAutoStyleName.isEmpty())
224 const SvXMLStylesContext* pStylesCtxt = m_rImportHelper.GetAutoStylesContext();
225 if( pStylesCtxt )
227 const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
228 SchXMLImportHelper::GetChartFamilyID(), sAutoStyleName );
230 if( pStyle && pStyle->ISA( XMLPropStyleContext ))
231 const_cast<XMLPropStyleContext*>( static_cast< const XMLPropStyleContext* >( pStyle ))->FillPropertySet( xGridProp );
237 namespace
239 enum AxisAttributeTokens
241 XML_TOK_AXIS_DIMENSION,
242 XML_TOK_AXIS_NAME,
243 XML_TOK_AXIS_STYLE_NAME,
244 XML_TOK_AXIS_TYPE,
245 XML_TOK_AXIS_TYPE_EXT
248 const SvXMLTokenMapEntry aAxisAttributeTokenMap[] =
250 { XML_NAMESPACE_CHART, XML_DIMENSION, XML_TOK_AXIS_DIMENSION },
251 { XML_NAMESPACE_CHART, XML_NAME, XML_TOK_AXIS_NAME },
252 { XML_NAMESPACE_CHART, XML_STYLE_NAME, XML_TOK_AXIS_STYLE_NAME },
253 { XML_NAMESPACE_CHART, XML_AXIS_TYPE, XML_TOK_AXIS_TYPE },
254 { XML_NAMESPACE_CHART_EXT, XML_AXIS_TYPE, XML_TOK_AXIS_TYPE_EXT },
255 XML_TOKEN_MAP_END
258 class AxisAttributeTokenMap : public SvXMLTokenMap
260 public:
261 AxisAttributeTokenMap(): SvXMLTokenMap( aAxisAttributeTokenMap ) {}
262 virtual ~AxisAttributeTokenMap() {}
265 //a AxisAttributeTokenMap Singleton
266 struct theAxisAttributeTokenMap : public rtl::Static< AxisAttributeTokenMap, theAxisAttributeTokenMap > {};
269 void SchXMLAxisContext::StartElement( const Reference< xml::sax::XAttributeList >& xAttrList )
271 // parse attributes
272 sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
273 const SvXMLTokenMap& rAttrTokenMap = theAxisAttributeTokenMap::get();
275 for( sal_Int16 i = 0; i < nAttrCount; i++ )
277 OUString sAttrName = xAttrList->getNameByIndex( i );
278 OUString aLocalName;
279 OUString aValue = xAttrList->getValueByIndex( i );
280 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
282 switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
284 case XML_TOK_AXIS_DIMENSION:
286 sal_uInt16 nEnumVal;
287 if( SvXMLUnitConverter::convertEnum( nEnumVal, aValue, aXMLAxisDimensionMap ))
288 m_aCurrentAxis.eDimension = ( SchXMLAxisDimension )nEnumVal;
290 break;
291 case XML_TOK_AXIS_NAME:
292 m_aCurrentAxis.aName = aValue;
293 break;
294 case XML_TOK_AXIS_TYPE:
295 case XML_TOK_AXIS_TYPE_EXT:
296 sal_uInt16 nEnumVal;
297 if( SvXMLUnitConverter::convertEnum( nEnumVal, aValue, aXMLAxisTypeMap ))
299 m_nAxisType = nEnumVal;
300 m_bAxisTypeImported = true;
302 break;
303 case XML_TOK_AXIS_STYLE_NAME:
304 m_aAutoStyleName = aValue;
305 break;
309 // check for number of axes with same dimension
310 m_aCurrentAxis.nAxisIndex = 0;
311 sal_Int32 nNumOfAxes = m_rAxes.size();
312 for( sal_Int32 nCurrent = 0; nCurrent < nNumOfAxes; nCurrent++ )
314 if( m_rAxes[ nCurrent ].eDimension == m_aCurrentAxis.eDimension )
315 m_aCurrentAxis.nAxisIndex++;
317 CreateAxis();
319 namespace
322 Reference< chart2::XAxis > lcl_getAxis( const Reference< frame::XModel >& xChartModel,
323 sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
325 Reference< chart2::XAxis > xAxis;
329 Reference< chart2::XChartDocument > xChart2Document( xChartModel, uno::UNO_QUERY );
330 if( xChart2Document.is() )
332 Reference< chart2::XDiagram > xDiagram( xChart2Document->getFirstDiagram());
333 Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
334 uno::Sequence< Reference< chart2::XCoordinateSystem > >
335 aCooSysSeq( xCooSysCnt->getCoordinateSystems());
336 sal_Int32 nCooSysIndex = 0;
337 if( nCooSysIndex < aCooSysSeq.getLength() )
339 Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[nCooSysIndex] );
340 if( xCooSys.is() && nDimensionIndex < xCooSys->getDimension() )
342 const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
343 if( nAxisIndex <= nMaxAxisIndex )
344 xAxis = xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex );
349 catch( uno::Exception & )
351 SAL_INFO("xmloff.chart", "Couldn't get axis" );
354 return xAxis;
357 bool lcl_divideBy100( uno::Any& rDoubleAny )
359 bool bChanged = false;
360 double fValue=0.0;
361 if( (rDoubleAny>>=fValue) && (fValue!=0.0) )
363 fValue/=100.0;
364 rDoubleAny = uno::makeAny(fValue);
365 bChanged = true;
367 return bChanged;
370 bool lcl_AdaptWrongPercentScaleValues(chart2::ScaleData& rScaleData)
372 bool bChanged = lcl_divideBy100( rScaleData.Minimum );
373 bChanged = lcl_divideBy100( rScaleData.Maximum ) || bChanged;
374 bChanged = lcl_divideBy100( rScaleData.Origin ) || bChanged;
375 bChanged = lcl_divideBy100( rScaleData.IncrementData.Distance ) || bChanged;
376 return bChanged;
379 }//end anonymous namespace
381 void SchXMLAxisContext::CreateAxis()
383 m_rAxes.push_back( m_aCurrentAxis );
385 Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY );
386 if( !xDiaProp.is() )
387 return;
388 OUString aPropName;
389 switch( m_aCurrentAxis.eDimension )
391 case SCH_XML_AXIS_X:
392 if( m_aCurrentAxis.nAxisIndex == 0 )
393 aPropName = "HasXAxis";
394 else
395 aPropName = "HasSecondaryXAxis";
396 break;
397 case SCH_XML_AXIS_Y:
398 if( m_aCurrentAxis.nAxisIndex == 0 )
399 aPropName = "HasYAxis";
400 else
401 aPropName = "HasSecondaryYAxis";
402 break;
403 case SCH_XML_AXIS_Z:
404 if( m_aCurrentAxis.nAxisIndex == 0 )
405 aPropName = "HasXAxis";
406 else
407 aPropName = "HasSecondaryXAxis";
408 break;
409 case SCH_XML_AXIS_UNDEF:
410 SAL_INFO("xmloff.chart", "Invalid axis" );
411 break;
415 xDiaProp->setPropertyValue( aPropName, uno::makeAny(sal_True) );
417 catch( beans::UnknownPropertyException & )
419 SAL_INFO("xmloff.chart", "Couldn't turn on axis" );
421 if( m_aCurrentAxis.eDimension==SCH_XML_AXIS_Z )
423 bool bSettingZAxisSuccedded = false;
426 xDiaProp->getPropertyValue( aPropName ) >>= bSettingZAxisSuccedded;
428 catch( beans::UnknownPropertyException & )
430 SAL_INFO("xmloff.chart", "Couldn't turn on z axis" );
432 if( !bSettingZAxisSuccedded )
433 return;
436 m_xAxisProps = Reference<beans::XPropertySet>( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ), uno::UNO_QUERY );
438 if( m_bAddMissingXAxisForNetCharts && m_aCurrentAxis.eDimension==SCH_XML_AXIS_Y && m_aCurrentAxis.nAxisIndex==0 )
442 xDiaProp->setPropertyValue("HasXAxis", uno::makeAny(sal_True) );
444 catch( beans::UnknownPropertyException & )
446 SAL_INFO("xmloff.chart", "Couldn't turn on x axis" );
450 // set properties
451 if( m_xAxisProps.is())
453 uno::Any aTrueBool( uno::makeAny( sal_True ));
454 uno::Any aFalseBool( uno::makeAny( sal_False ));
456 // #i109879# the line color is black as default, in the model it is a light gray
457 m_xAxisProps->setPropertyValue("LineColor",
458 uno::makeAny( COL_BLACK ));
460 m_xAxisProps->setPropertyValue("DisplayLabels", aFalseBool );
462 // #88077# AutoOrigin 'on' is default
463 m_xAxisProps->setPropertyValue("AutoOrigin", aTrueBool );
465 if( m_bAxisTypeImported )
466 m_xAxisProps->setPropertyValue("AxisType", uno::makeAny(m_nAxisType) );
468 if( !m_aAutoStyleName.isEmpty())
470 const SvXMLStylesContext* pStylesCtxt = m_rImportHelper.GetAutoStylesContext();
471 if( pStylesCtxt )
473 const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
474 SchXMLImportHelper::GetChartFamilyID(), m_aAutoStyleName );
476 if( pStyle && pStyle->ISA( XMLPropStyleContext ))
478 // note: SvXMLStyleContext::FillPropertySet is not const
479 XMLPropStyleContext * pPropStyleContext = const_cast< XMLPropStyleContext * >( dynamic_cast< const XMLPropStyleContext * >( pStyle ));
480 if( pPropStyleContext )
481 pPropStyleContext->FillPropertySet( m_xAxisProps );
483 if( m_bAdaptWrongPercentScaleValues && m_aCurrentAxis.eDimension==SCH_XML_AXIS_Y )
485 //set scale data of added x axis back to default
486 Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(),
487 m_aCurrentAxis.eDimension, m_aCurrentAxis.nAxisIndex ) );
488 if( xAxis.is() )
490 chart2::ScaleData aScaleData( xAxis->getScaleData());
491 if( lcl_AdaptWrongPercentScaleValues(aScaleData) )
492 xAxis->setScaleData( aScaleData );
496 if( m_bAddMissingXAxisForNetCharts )
498 //copy style from y axis to added x axis:
500 Reference< chart::XAxisSupplier > xAxisSuppl( xDiaProp, uno::UNO_QUERY );
501 if( xAxisSuppl.is() )
503 Reference< beans::XPropertySet > xXAxisProp( xAxisSuppl->getAxis(0), uno::UNO_QUERY );
504 const_cast<XMLPropStyleContext*>( static_cast< const XMLPropStyleContext* >( pStyle ))->FillPropertySet( xXAxisProp );
507 //set scale data of added x axis back to default
508 Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(),
509 0 /*nDimensionIndex*/, 0 /*nAxisIndex*/ ) );
510 if( xAxis.is() )
512 chart2::ScaleData aScaleData;
513 aScaleData.AxisType = chart2::AxisType::CATEGORY;
514 aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
515 xAxis->setScaleData( aScaleData );
518 //set line style of added x axis to invisible
519 Reference< beans::XPropertySet > xNewAxisProp( xAxis, uno::UNO_QUERY );
520 if( xNewAxisProp.is() )
522 xNewAxisProp->setPropertyValue("LineStyle"
523 , uno::makeAny(drawing::LineStyle_NONE));
527 if( m_bAdaptXAxisOrientationForOld2DBarCharts && m_aCurrentAxis.eDimension == SCH_XML_AXIS_X )
529 bool bIs3DChart = false;
530 if( xDiaProp.is() && ( xDiaProp->getPropertyValue("Dim3D") >>= bIs3DChart )
531 && !bIs3DChart )
533 Reference< chart2::XChartDocument > xChart2Document( GetImport().GetModel(), uno::UNO_QUERY );
534 if( xChart2Document.is() )
536 Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xChart2Document->getFirstDiagram(), uno::UNO_QUERY );
537 if( xCooSysCnt.is() )
539 uno::Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems() );
540 if( aCooSysSeq.getLength() )
542 bool bSwapXandYAxis = false;
543 Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[0] );
544 Reference< beans::XPropertySet > xCooSysProp( xCooSys, uno::UNO_QUERY );
545 if( xCooSysProp.is() && ( xCooSysProp->getPropertyValue("SwapXAndYAxis") >>= bSwapXandYAxis )
546 && bSwapXandYAxis )
548 Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( 0, m_aCurrentAxis.nAxisIndex );
549 if( xAxis.is() )
551 chart2::ScaleData aScaleData = xAxis->getScaleData();
552 aScaleData.Orientation = chart2::AxisOrientation_REVERSE;
553 xAxis->setScaleData( aScaleData );
562 m_rbAxisPositionAttributeImported = m_rbAxisPositionAttributeImported || SchXMLTools::getPropertyFromContext(
563 OUString("CrossoverPosition"), pPropStyleContext, pStylesCtxt ).hasValue();
570 void SchXMLAxisContext::SetAxisTitle()
572 if( m_aCurrentAxis.aTitle.isEmpty() )
573 return;
575 Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) );
576 if( !xAxis.is() )
577 return;
579 Reference< beans::XPropertySet > xTitleProp( xAxis->getAxisTitle() );
580 if( xTitleProp.is() )
584 xTitleProp->setPropertyValue("String", uno::makeAny(m_aCurrentAxis.aTitle) );
586 catch( beans::UnknownPropertyException & )
588 SAL_INFO("xmloff.chart", "Property String for Title not available" );
593 namespace
595 enum AxisChildTokens
597 XML_TOK_AXIS_TITLE,
598 XML_TOK_AXIS_CATEGORIES,
599 XML_TOK_AXIS_GRID,
600 XML_TOK_AXIS_DATE_SCALE,
601 XML_TOK_AXIS_DATE_SCALE_EXT
604 const SvXMLTokenMapEntry aAxisChildTokenMap[] =
606 { XML_NAMESPACE_CHART, XML_TITLE, XML_TOK_AXIS_TITLE },
607 { XML_NAMESPACE_CHART, XML_CATEGORIES, XML_TOK_AXIS_CATEGORIES },
608 { XML_NAMESPACE_CHART, XML_GRID, XML_TOK_AXIS_GRID },
609 { XML_NAMESPACE_CHART, XML_DATE_SCALE, XML_TOK_AXIS_DATE_SCALE },
610 { XML_NAMESPACE_CHART_EXT, XML_DATE_SCALE, XML_TOK_AXIS_DATE_SCALE_EXT },
611 XML_TOKEN_MAP_END
614 class AxisChildTokenMap : public SvXMLTokenMap
616 public:
617 AxisChildTokenMap(): SvXMLTokenMap( aAxisChildTokenMap ) {}
618 virtual ~AxisChildTokenMap() {}
621 //a AxisChildTokenMap Singleton
622 struct theAxisChildTokenMap : public rtl::Static< AxisChildTokenMap, theAxisChildTokenMap > {};
625 SvXMLImportContext* SchXMLAxisContext::CreateChildContext(
626 sal_uInt16 p_nPrefix,
627 const OUString& rLocalName,
628 const Reference< xml::sax::XAttributeList >& xAttrList )
630 SvXMLImportContext* pContext = 0;
631 const SvXMLTokenMap& rTokenMap = theAxisChildTokenMap::get();
633 switch( rTokenMap.Get( p_nPrefix, rLocalName ))
635 case XML_TOK_AXIS_TITLE:
637 Reference< drawing::XShape > xTitleShape = getTitleShape();
638 pContext = new SchXMLTitleContext( m_rImportHelper, GetImport(), rLocalName,
639 m_aCurrentAxis.aTitle,
640 xTitleShape );
642 break;
644 case XML_TOK_AXIS_CATEGORIES:
645 pContext = new SchXMLCategoriesContext( GetImport(),
646 p_nPrefix, rLocalName,
647 m_rCategoriesAddress );
648 m_aCurrentAxis.bHasCategories = true;
649 break;
651 case XML_TOK_AXIS_DATE_SCALE:
652 case XML_TOK_AXIS_DATE_SCALE_EXT:
653 pContext = new DateScaleContext( GetImport(),
654 p_nPrefix, rLocalName, m_xAxisProps );
655 m_bDateScaleImported = true;
656 break;
658 case XML_TOK_AXIS_GRID:
660 sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
661 bool bIsMajor = true; // default value for class is "major"
662 OUString sAutoStyleName;
664 for( sal_Int16 i = 0; i < nAttrCount; i++ )
666 OUString sAttrName = xAttrList->getNameByIndex( i );
667 OUString aLocalName;
668 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
670 if( nPrefix == XML_NAMESPACE_CHART )
672 if( IsXMLToken( aLocalName, XML_CLASS ) )
674 if( IsXMLToken( xAttrList->getValueByIndex( i ), XML_MINOR ) )
675 bIsMajor = false;
677 else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
678 sAutoStyleName = xAttrList->getValueByIndex( i );
682 CreateGrid( sAutoStyleName, bIsMajor );
684 // don't create a context => use default context. grid elements are empty
685 pContext = new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName );
687 break;
689 default:
690 pContext = new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName );
691 break;
694 return pContext;
697 void SchXMLAxisContext::EndElement()
699 if( !m_bDateScaleImported && m_nAxisType==chart::ChartAxisType::AUTOMATIC )
701 Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(), m_aCurrentAxis.eDimension, m_aCurrentAxis.nAxisIndex ) );
702 if( xAxis.is() )
704 chart2::ScaleData aScaleData( xAxis->getScaleData());
705 aScaleData.AutoDateAxis = false;//different default for older documents
706 xAxis->setScaleData( aScaleData );
710 SetAxisTitle();
713 namespace
716 Reference< chart2::XAxis > lcl_getAxis( const Reference< chart2::XCoordinateSystem >& rCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
718 Reference< chart2::XAxis > xAxis;
721 xAxis = rCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex );
723 catch( uno::Exception & )
726 return xAxis;
729 } // anonymous namespace
731 void SchXMLAxisContext::CorrectAxisPositions( const Reference< chart2::XChartDocument >& xNewDoc,
732 const OUString& rChartTypeServiceName,
733 const OUString& rODFVersionOfFile,
734 bool bAxisPositionAttributeImported )
736 if( ( rODFVersionOfFile.isEmpty() || rODFVersionOfFile == "1.0" || rODFVersionOfFile == "1.1"
737 || ( rODFVersionOfFile == "1.2" && !bAxisPositionAttributeImported ) ) )
741 Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xNewDoc->getFirstDiagram(), uno::UNO_QUERY_THROW );
742 uno::Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
743 if( aCooSysSeq.getLength() )
745 Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[0] );
746 if( xCooSys.is() )
748 Reference< chart2::XAxis > xMainXAxis = lcl_getAxis( xCooSys, 0, 0 );
749 Reference< chart2::XAxis > xMainYAxis = lcl_getAxis( xCooSys, 1, 0 );
750 //Reference< chart2::XAxis > xMajorZAxis = lcl_getAxis( xCooSys, 2, 0 );
751 Reference< chart2::XAxis > xSecondaryXAxis = lcl_getAxis( xCooSys, 0, 1 );
752 Reference< chart2::XAxis > xSecondaryYAxis = lcl_getAxis( xCooSys, 1, 1 );
754 Reference< beans::XPropertySet > xMainXAxisProp( xMainXAxis, uno::UNO_QUERY );
755 Reference< beans::XPropertySet > xMainYAxisProp( xMainYAxis, uno::UNO_QUERY );
756 Reference< beans::XPropertySet > xSecondaryXAxisProp( xSecondaryXAxis, uno::UNO_QUERY );
757 Reference< beans::XPropertySet > xSecondaryYAxisProp( xSecondaryYAxis, uno::UNO_QUERY );
759 if( xMainXAxisProp.is() && xMainYAxisProp.is() )
761 chart2::ScaleData aMainXScale = xMainXAxis->getScaleData();
762 if( rChartTypeServiceName == "com.sun.star.chart2.ScatterChartType" )
764 xMainYAxisProp->setPropertyValue("CrossoverPosition"
765 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_VALUE) );
766 double fCrossoverValue = 0.0;
767 aMainXScale.Origin >>= fCrossoverValue;
768 xMainYAxisProp->setPropertyValue("CrossoverValue"
769 , uno::makeAny( fCrossoverValue ) );
771 if( aMainXScale.Orientation == chart2::AxisOrientation_REVERSE )
773 xMainYAxisProp->setPropertyValue("LabelPosition"
774 , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END) );
775 xMainYAxisProp->setPropertyValue("MarkPosition"
776 , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) );
777 if( xSecondaryYAxisProp.is() )
778 xSecondaryYAxisProp->setPropertyValue("CrossoverPosition"
779 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) );
781 else
783 xMainYAxisProp->setPropertyValue("LabelPosition"
784 , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START) );
785 xMainYAxisProp->setPropertyValue("MarkPosition"
786 , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) );
787 if( xSecondaryYAxisProp.is() )
788 xSecondaryYAxisProp->setPropertyValue("CrossoverPosition"
789 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) );
792 else
794 if( aMainXScale.Orientation == chart2::AxisOrientation_REVERSE )
796 xMainYAxisProp->setPropertyValue("CrossoverPosition"
797 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) );
798 if( xSecondaryYAxisProp.is() )
799 xSecondaryYAxisProp->setPropertyValue("CrossoverPosition"
800 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) );
802 else
804 xMainYAxisProp->setPropertyValue("CrossoverPosition"
805 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) );
806 if( xSecondaryYAxisProp.is() )
807 xSecondaryYAxisProp->setPropertyValue("CrossoverPosition"
808 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) );
812 chart2::ScaleData aMainYScale = xMainYAxis->getScaleData();
813 xMainXAxisProp->setPropertyValue("CrossoverPosition"
814 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_VALUE) );
815 double fCrossoverValue = 0.0;
816 aMainYScale.Origin >>= fCrossoverValue;
817 xMainXAxisProp->setPropertyValue("CrossoverValue"
818 , uno::makeAny( fCrossoverValue ) );
820 if( aMainYScale.Orientation == chart2::AxisOrientation_REVERSE )
822 xMainXAxisProp->setPropertyValue("LabelPosition"
823 , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END) );
824 xMainXAxisProp->setPropertyValue("MarkPosition"
825 , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) );
826 if( xSecondaryXAxisProp.is() )
827 xSecondaryXAxisProp->setPropertyValue("CrossoverPosition"
828 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) );
830 else
832 xMainXAxisProp->setPropertyValue("LabelPosition"
833 , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START) );
834 xMainXAxisProp->setPropertyValue("MarkPosition"
835 , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) );
836 if( xSecondaryXAxisProp.is() )
837 xSecondaryXAxisProp->setPropertyValue("CrossoverPosition"
838 , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) );
844 catch( uno::Exception & )
850 SchXMLCategoriesContext::SchXMLCategoriesContext(
851 SvXMLImport& rImport,
852 sal_uInt16 nPrefix,
853 const OUString& rLocalName,
854 OUString& rAddress ) :
855 SvXMLImportContext( rImport, nPrefix, rLocalName ),
856 mrAddress( rAddress )
860 SchXMLCategoriesContext::~SchXMLCategoriesContext()
864 void SchXMLCategoriesContext::StartElement( const Reference< xml::sax::XAttributeList >& xAttrList )
866 sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
868 for( sal_Int16 i = 0; i < nAttrCount; i++ )
870 OUString sAttrName = xAttrList->getNameByIndex( i );
871 OUString aLocalName;
872 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
874 if( nPrefix == XML_NAMESPACE_TABLE &&
875 IsXMLToken( aLocalName, XML_CELL_RANGE_ADDRESS ) )
877 Reference< chart2::XChartDocument > xNewDoc( GetImport().GetModel(), uno::UNO_QUERY );
878 mrAddress = xAttrList->getValueByIndex( i );
883 DateScaleContext::DateScaleContext(
884 SvXMLImport& rImport,
885 sal_uInt16 nPrefix,
886 const OUString& rLocalName,
887 const Reference< beans::XPropertySet >& rAxisProps ) :
888 SvXMLImportContext( rImport, nPrefix, rLocalName ),
889 m_xAxisProps( rAxisProps )
893 DateScaleContext::~DateScaleContext()
897 namespace
899 enum DateScaleAttributeTokens
901 XML_TOK_DATESCALE_BASE_TIME_UNIT,
902 XML_TOK_DATESCALE_MAJOR_INTERVAL_VALUE,
903 XML_TOK_DATESCALE_MAJOR_INTERVAL_UNIT,
904 XML_TOK_DATESCALE_MINOR_INTERVAL_VALUE,
905 XML_TOK_DATESCALE_MINOR_INTERVAL_UNIT
908 const SvXMLTokenMapEntry aDateScaleAttributeTokenMap[] =
910 { XML_NAMESPACE_CHART, XML_BASE_TIME_UNIT, XML_TOK_DATESCALE_BASE_TIME_UNIT },
911 { XML_NAMESPACE_CHART, XML_MAJOR_INTERVAL_VALUE, XML_TOK_DATESCALE_MAJOR_INTERVAL_VALUE },
912 { XML_NAMESPACE_CHART, XML_MAJOR_INTERVAL_UNIT, XML_TOK_DATESCALE_MAJOR_INTERVAL_UNIT },
913 { XML_NAMESPACE_CHART, XML_MINOR_INTERVAL_VALUE, XML_TOK_DATESCALE_MINOR_INTERVAL_VALUE },
914 { XML_NAMESPACE_CHART, XML_MINOR_INTERVAL_UNIT, XML_TOK_DATESCALE_MINOR_INTERVAL_UNIT },
915 XML_TOKEN_MAP_END
918 class DateScaleAttributeTokenMap : public SvXMLTokenMap
920 public:
921 DateScaleAttributeTokenMap(): SvXMLTokenMap( aDateScaleAttributeTokenMap ) {}
922 virtual ~DateScaleAttributeTokenMap() {}
925 struct theDateScaleAttributeTokenMap : public rtl::Static< DateScaleAttributeTokenMap, theDateScaleAttributeTokenMap > {};
927 sal_Int32 lcl_getTimeUnit( const OUString& rValue )
929 sal_Int32 nTimeUnit = ::com::sun::star::chart::TimeUnit::DAY;
930 if( IsXMLToken( rValue, XML_DAYS ) )
931 nTimeUnit = ::com::sun::star::chart::TimeUnit::DAY;
932 else if( IsXMLToken( rValue, XML_MONTHS ) )
933 nTimeUnit = ::com::sun::star::chart::TimeUnit::MONTH;
934 else if( IsXMLToken( rValue, XML_YEARS ) )
935 nTimeUnit = ::com::sun::star::chart::TimeUnit::YEAR;
936 return nTimeUnit;
941 void DateScaleContext::StartElement( const Reference< xml::sax::XAttributeList >& xAttrList )
943 if( !m_xAxisProps.is() )
944 return;
946 // parse attributes
947 sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
948 const SvXMLTokenMap& rAttrTokenMap = theDateScaleAttributeTokenMap::get();
950 bool bSetNewIncrement=false;
951 chart::TimeIncrement aIncrement;
952 m_xAxisProps->getPropertyValue("TimeIncrement") >>= aIncrement;
954 for( sal_Int16 i = 0; i < nAttrCount; i++ )
956 OUString sAttrName = xAttrList->getNameByIndex( i );
957 OUString aLocalName;
958 OUString aValue = xAttrList->getValueByIndex( i );
959 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
961 switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
963 case XML_TOK_DATESCALE_BASE_TIME_UNIT:
965 aIncrement.TimeResolution = uno::makeAny( lcl_getTimeUnit(aValue) );
966 bSetNewIncrement = true;
968 break;
969 case XML_TOK_DATESCALE_MAJOR_INTERVAL_VALUE:
971 chart::TimeInterval aInterval(1,0);
972 aIncrement.MajorTimeInterval >>= aInterval;
973 ::sax::Converter::convertNumber( aInterval.Number, aValue );
974 aIncrement.MajorTimeInterval = uno::makeAny(aInterval);
975 bSetNewIncrement = true;
977 break;
978 case XML_TOK_DATESCALE_MAJOR_INTERVAL_UNIT:
980 chart::TimeInterval aInterval(1,0);
981 aIncrement.MajorTimeInterval >>= aInterval;
982 aInterval.TimeUnit = lcl_getTimeUnit(aValue);
983 aIncrement.MajorTimeInterval = uno::makeAny(aInterval);
984 bSetNewIncrement = true;
986 break;
987 case XML_TOK_DATESCALE_MINOR_INTERVAL_VALUE:
989 chart::TimeInterval aInterval(1,0);
990 aIncrement.MinorTimeInterval >>= aInterval;
991 ::sax::Converter::convertNumber( aInterval.Number, aValue );
992 aIncrement.MinorTimeInterval = uno::makeAny(aInterval);
993 bSetNewIncrement = true;
995 break;
996 case XML_TOK_DATESCALE_MINOR_INTERVAL_UNIT:
998 chart::TimeInterval aInterval(1,0);
999 aIncrement.MinorTimeInterval >>= aInterval;
1000 aInterval.TimeUnit = lcl_getTimeUnit(aValue);
1001 aIncrement.MinorTimeInterval = uno::makeAny(aInterval);
1002 bSetNewIncrement = true;
1004 break;
1008 if( bSetNewIncrement )
1009 m_xAxisProps->setPropertyValue("TimeIncrement", uno::makeAny( aIncrement ) );
1012 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */