1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
76 SchXMLCategoriesContext( SvXMLImport
& rImport
,
78 const OUString
& rLocalName
,
80 virtual ~SchXMLCategoriesContext();
81 virtual void StartElement( const Reference
< ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
) SAL_OVERRIDE
;
84 class DateScaleContext
: public SvXMLImportContext
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
;
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
),
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() )
131 if( rCurrentAxis
.nAxisIndex
== 0 )
132 xAxis
= xAxisSuppl
->getAxis(rCurrentAxis
.eDimension
);
134 xAxis
= xAxisSuppl
->getSecondaryAxis(rCurrentAxis
.eDimension
);
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() )
150 switch( m_aCurrentAxis
.eDimension
)
153 if( m_aCurrentAxis
.nAxisIndex
== 0 )
154 aPropName
= "HasXAxisTitle";
156 aPropName
= "HasSecondaryXAxisTitle";
159 if( m_aCurrentAxis
.nAxisIndex
== 0 )
160 aPropName
= "HasYAxisTitle";
162 aPropName
= "HasSecondaryYAxisTitle";
165 aPropName
= "HasZAxisTitle";
167 case SCH_XML_AXIS_UNDEF
:
168 SAL_INFO("xmloff.chart", "Invalid axis" );
171 xDiaProp
->setPropertyValue( aPropName
, uno::makeAny(sal_True
) );
172 xResult
= Reference
< drawing::XShape
>( xAxis
->getAxisTitle(), uno::UNO_QUERY
);
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() )
184 switch( m_aCurrentAxis
.eDimension
)
188 aPropName
= "HasXAxisGrid";
190 aPropName
= "HasXAxisHelpGrid";
194 aPropName
= "HasYAxisGrid";
196 aPropName
= "HasYAxisHelpGrid";
200 aPropName
= "HasZAxisGrid";
202 aPropName
= "HasZAxisHelpGrid";
204 case SCH_XML_AXIS_UNDEF
:
205 SAL_INFO("xmloff.chart", "Invalid axis" );
208 xDiaProp
->setPropertyValue( aPropName
, uno::makeAny(sal_True
) );
210 Reference
< beans::XPropertySet
> xGridProp
;
212 xGridProp
= xAxis
->getMajorGrid();
214 xGridProp
= xAxis
->getMinorGrid();
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();
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
);
239 enum AxisAttributeTokens
241 XML_TOK_AXIS_DIMENSION
,
243 XML_TOK_AXIS_STYLE_NAME
,
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
},
258 class AxisAttributeTokenMap
: public SvXMLTokenMap
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
)
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
);
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
:
287 if( SvXMLUnitConverter::convertEnum( nEnumVal
, aValue
, aXMLAxisDimensionMap
))
288 m_aCurrentAxis
.eDimension
= ( SchXMLAxisDimension
)nEnumVal
;
291 case XML_TOK_AXIS_NAME
:
292 m_aCurrentAxis
.aName
= aValue
;
294 case XML_TOK_AXIS_TYPE
:
295 case XML_TOK_AXIS_TYPE_EXT
:
297 if( SvXMLUnitConverter::convertEnum( nEnumVal
, aValue
, aXMLAxisTypeMap
))
299 m_nAxisType
= nEnumVal
;
300 m_bAxisTypeImported
= true;
303 case XML_TOK_AXIS_STYLE_NAME
:
304 m_aAutoStyleName
= aValue
;
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
++;
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" );
357 bool lcl_divideBy100( uno::Any
& rDoubleAny
)
359 bool bChanged
= false;
361 if( (rDoubleAny
>>=fValue
) && (fValue
!=0.0) )
364 rDoubleAny
= uno::makeAny(fValue
);
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
;
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
);
389 switch( m_aCurrentAxis
.eDimension
)
392 if( m_aCurrentAxis
.nAxisIndex
== 0 )
393 aPropName
= "HasXAxis";
395 aPropName
= "HasSecondaryXAxis";
398 if( m_aCurrentAxis
.nAxisIndex
== 0 )
399 aPropName
= "HasYAxis";
401 aPropName
= "HasSecondaryYAxis";
404 if( m_aCurrentAxis
.nAxisIndex
== 0 )
405 aPropName
= "HasXAxis";
407 aPropName
= "HasSecondaryXAxis";
409 case SCH_XML_AXIS_UNDEF
:
410 SAL_INFO("xmloff.chart", "Invalid axis" );
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
)
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" );
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();
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
) );
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*/ ) );
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
)
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
)
548 Reference
< chart2::XAxis
> xAxis
= xCooSys
->getAxisByDimension( 0, m_aCurrentAxis
.nAxisIndex
);
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() )
575 Reference
< chart::XAxis
> xAxis( lcl_getChartAxis( m_aCurrentAxis
, m_xDiagram
) );
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" );
598 XML_TOK_AXIS_CATEGORIES
,
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
},
614 class AxisChildTokenMap
: public SvXMLTokenMap
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
,
644 case XML_TOK_AXIS_CATEGORIES
:
645 pContext
= new SchXMLCategoriesContext( GetImport(),
646 p_nPrefix
, rLocalName
,
647 m_rCategoriesAddress
);
648 m_aCurrentAxis
.bHasCategories
= true;
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;
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
);
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
) )
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
);
690 pContext
= new SvXMLImportContext( GetImport(), p_nPrefix
, rLocalName
);
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
) );
704 chart2::ScaleData
aScaleData( xAxis
->getScaleData());
705 aScaleData
.AutoDateAxis
= false;//different default for older documents
706 xAxis
->setScaleData( aScaleData
);
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
& )
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] );
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
) );
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
) );
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
) );
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
) );
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
,
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
);
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
,
886 const OUString
& rLocalName
,
887 const Reference
< beans::XPropertySet
>& rAxisProps
) :
888 SvXMLImportContext( rImport
, nPrefix
, rLocalName
),
889 m_xAxisProps( rAxisProps
)
893 DateScaleContext::~DateScaleContext()
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
},
918 class DateScaleAttributeTokenMap
: public SvXMLTokenMap
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
;
941 void DateScaleContext::StartElement( const Reference
< xml::sax::XAttributeList
>& xAttrList
)
943 if( !m_xAxisProps
.is() )
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
);
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;
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;
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;
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;
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;
1008 if( bSetNewIncrement
)
1009 m_xAxisProps
->setPropertyValue("TimeIncrement", uno::makeAny( aIncrement
) );
1012 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */