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/xmlimp.hxx>
26 #include <xmloff/xmlnamespace.hxx>
27 #include <xmloff/xmlement.hxx>
28 #include <xmloff/xmlstyle.hxx>
29 #include <xmloff/prstylei.hxx>
30 #include <xmloff/namespacemap.hxx>
31 #include <xmloff/xmluconv.hxx>
33 #include <rtl/math.hxx>
34 #include <tools/color.hxx>
35 #include <sal/log.hxx>
37 #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
38 #include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
39 #include <com/sun/star/chart/ChartAxisPosition.hpp>
40 #include <com/sun/star/chart/ChartAxisType.hpp>
41 #include <com/sun/star/chart/TimeIncrement.hpp>
42 #include <com/sun/star/chart/TimeInterval.hpp>
43 #include <com/sun/star/chart/TimeUnit.hpp>
44 #include <com/sun/star/chart/XAxis.hpp>
45 #include <com/sun/star/chart/XAxisSupplier.hpp>
46 #include <com/sun/star/chart/XChartDocument.hpp>
47 #include <com/sun/star/chart2/AxisType.hpp>
48 #include <com/sun/star/chart2/XChartDocument.hpp>
49 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
51 #include <com/sun/star/drawing/LineStyle.hpp>
53 using namespace ::xmloff::token
;
54 using namespace com::sun::star
;
56 using com::sun::star::uno::Reference
;
58 const SvXMLEnumMapEntry
<SchXMLAxisDimension
> aXMLAxisDimensionMap
[] =
60 { XML_X
, SCH_XML_AXIS_X
},
61 { XML_Y
, SCH_XML_AXIS_Y
},
62 { XML_Z
, SCH_XML_AXIS_Z
},
63 { XML_TOKEN_INVALID
, SchXMLAxisDimension(0) }
66 const SvXMLEnumMapEntry
<sal_uInt16
> aXMLAxisTypeMap
[] =
68 { XML_AUTO
, css::chart::ChartAxisType::AUTOMATIC
},
69 { XML_TEXT
, css::chart::ChartAxisType::CATEGORY
},
70 { XML_DATE
, css::chart::ChartAxisType::DATE
},
71 { XML_TOKEN_INVALID
, 0 }
76 class SchXMLCategoriesContext
: public SvXMLImportContext
82 SchXMLCategoriesContext( SvXMLImport
& rImport
,
84 virtual void SAL_CALL
startFastElement( sal_Int32 nElement
,
85 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
88 class DateScaleContext
: public SvXMLImportContext
91 DateScaleContext( SvXMLImport
& rImport
,
92 const Reference
< beans::XPropertySet
>& rAxisProps
);
94 virtual void SAL_CALL
startFastElement( sal_Int32 nElement
,
95 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
98 Reference
< beans::XPropertySet
> m_xAxisProps
;
103 SchXMLAxisContext::SchXMLAxisContext( SchXMLImportHelper
& rImpHelper
,
104 SvXMLImport
& rImport
,
105 Reference
< chart::XDiagram
> const & xDiagram
,
106 std::vector
< SchXMLAxis
>& rAxes
,
107 OUString
& rCategoriesAddress
,
108 bool bAddMissingXAxisForNetCharts
,
109 bool bAdaptWrongPercentScaleValues
,
110 bool bAdaptXAxisOrientationForOld2DBarCharts
,
111 bool& rbAxisPositionAttributeImported
) :
112 SvXMLImportContext( rImport
),
113 m_rImportHelper( rImpHelper
),
114 m_xDiagram( xDiagram
),
116 m_rCategoriesAddress( rCategoriesAddress
),
117 m_nAxisType(chart::ChartAxisType::AUTOMATIC
),
118 m_bAxisTypeImported(false),
119 m_bDateScaleImported(false),
120 m_bAddMissingXAxisForNetCharts( bAddMissingXAxisForNetCharts
),
121 m_bAdaptWrongPercentScaleValues( bAdaptWrongPercentScaleValues
),
122 m_bAdaptXAxisOrientationForOld2DBarCharts( bAdaptXAxisOrientationForOld2DBarCharts
),
123 m_rbAxisPositionAttributeImported( rbAxisPositionAttributeImported
)
127 SchXMLAxisContext::~SchXMLAxisContext()
130 static Reference
< chart::XAxis
> lcl_getChartAxis(const SchXMLAxis
& rCurrentAxis
, const Reference
< chart::XDiagram
>& rDiagram
)
132 Reference
< chart::XAxis
> xAxis
;
133 Reference
< chart::XAxisSupplier
> xAxisSuppl( rDiagram
, uno::UNO_QUERY
);
134 if( !xAxisSuppl
.is() )
136 if( rCurrentAxis
.nAxisIndex
== 0 )
137 xAxis
= xAxisSuppl
->getAxis(rCurrentAxis
.eDimension
);
139 xAxis
= xAxisSuppl
->getSecondaryAxis(rCurrentAxis
.eDimension
);
143 /* returns a shape for the current axis's title. The property
144 "Has...AxisTitle" is set to "True" to get the shape
146 Reference
< drawing::XShape
> SchXMLAxisContext::getTitleShape() const
148 Reference
< drawing::XShape
> xResult
;
149 Reference
< beans::XPropertySet
> xDiaProp( m_rImportHelper
.GetChartDocument()->getDiagram(), uno::UNO_QUERY
);
150 Reference
< chart::XAxis
> xAxis( lcl_getChartAxis( m_aCurrentAxis
, m_xDiagram
) );
151 if( !xDiaProp
.is() || !xAxis
.is() )
155 switch( m_aCurrentAxis
.eDimension
)
158 if( m_aCurrentAxis
.nAxisIndex
== 0 )
159 aPropName
= "HasXAxisTitle";
161 aPropName
= "HasSecondaryXAxisTitle";
164 if( m_aCurrentAxis
.nAxisIndex
== 0 )
165 aPropName
= "HasYAxisTitle";
167 aPropName
= "HasSecondaryYAxisTitle";
170 aPropName
= "HasZAxisTitle";
172 case SCH_XML_AXIS_UNDEF
:
173 SAL_INFO("xmloff.chart", "Invalid axis" );
176 xDiaProp
->setPropertyValue( aPropName
, uno::Any(true) );
177 xResult
.set( xAxis
->getAxisTitle(), uno::UNO_QUERY
);
181 void SchXMLAxisContext::CreateGrid( const OUString
& sAutoStyleName
, bool bIsMajor
)
183 Reference
< beans::XPropertySet
> xDiaProp( m_rImportHelper
.GetChartDocument()->getDiagram(), uno::UNO_QUERY
);
184 Reference
< chart::XAxis
> xAxis( lcl_getChartAxis( m_aCurrentAxis
, m_xDiagram
) );
185 if( !xDiaProp
.is() || !xAxis
.is() )
189 switch( m_aCurrentAxis
.eDimension
)
193 aPropName
= "HasXAxisGrid";
195 aPropName
= "HasXAxisHelpGrid";
199 aPropName
= "HasYAxisGrid";
201 aPropName
= "HasYAxisHelpGrid";
205 aPropName
= "HasZAxisGrid";
207 aPropName
= "HasZAxisHelpGrid";
209 case SCH_XML_AXIS_UNDEF
:
210 SAL_INFO("xmloff.chart", "Invalid axis" );
213 xDiaProp
->setPropertyValue( aPropName
, uno::Any(true) );
215 Reference
< beans::XPropertySet
> xGridProp
;
217 xGridProp
= xAxis
->getMajorGrid();
219 xGridProp
= xAxis
->getMinorGrid();
224 // the line color is black as default, in the model it is a light gray
225 xGridProp
->setPropertyValue("LineColor",
226 uno::Any( COL_BLACK
));
227 if (!sAutoStyleName
.isEmpty())
228 m_rImportHelper
.FillAutoStyle(sAutoStyleName
, xGridProp
);
232 void SchXMLAxisContext::startFastElement( sal_Int32
/*nElement*/,
233 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
236 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
238 switch(aIter
.getToken())
240 case XML_ELEMENT(CHART
, XML_DIMENSION
):
242 SchXMLAxisDimension nEnumVal
;
243 if( SvXMLUnitConverter::convertEnum( nEnumVal
, aIter
.toView(), aXMLAxisDimensionMap
))
244 m_aCurrentAxis
.eDimension
= nEnumVal
;
247 case XML_ELEMENT(CHART
, XML_NAME
):
248 m_aCurrentAxis
.aName
= aIter
.toString();
250 case XML_ELEMENT(CHART
, XML_AXIS_TYPE
):
251 case XML_ELEMENT(CHART_EXT
, XML_AXIS_TYPE
):
253 if( SvXMLUnitConverter::convertEnum( nEnumVal
, aIter
.toView(), aXMLAxisTypeMap
))
255 m_nAxisType
= nEnumVal
;
256 m_bAxisTypeImported
= true;
259 case XML_ELEMENT(CHART
, XML_STYLE_NAME
):
260 m_aAutoStyleName
= aIter
.toString();
263 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
267 // check for number of axes with same dimension
268 m_aCurrentAxis
.nAxisIndex
= 0;
269 sal_Int32 nNumOfAxes
= m_rAxes
.size();
270 for( sal_Int32 nCurrent
= 0; nCurrent
< nNumOfAxes
; nCurrent
++ )
272 if( m_rAxes
[ nCurrent
].eDimension
== m_aCurrentAxis
.eDimension
)
273 m_aCurrentAxis
.nAxisIndex
++;
280 Reference
< chart2::XAxis
> lcl_getAxis( const Reference
< frame::XModel
>& xChartModel
,
281 sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
)
283 Reference
< chart2::XAxis
> xAxis
;
287 Reference
< chart2::XChartDocument
> xChart2Document( xChartModel
, uno::UNO_QUERY
);
288 if( xChart2Document
.is() )
290 Reference
< chart2::XDiagram
> xDiagram( xChart2Document
->getFirstDiagram());
291 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
292 uno::Sequence
< Reference
< chart2::XCoordinateSystem
> >
293 aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
294 sal_Int32 nCooSysIndex
= 0;
295 if( nCooSysIndex
< aCooSysSeq
.getLength() )
297 Reference
< chart2::XCoordinateSystem
> xCooSys( aCooSysSeq
[nCooSysIndex
] );
298 if( xCooSys
.is() && nDimensionIndex
< xCooSys
->getDimension() )
300 const sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
301 if( nAxisIndex
<= nMaxAxisIndex
)
302 xAxis
= xCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
);
307 catch( uno::Exception
& )
309 SAL_INFO("xmloff.chart", "Couldn't get axis" );
315 bool lcl_divideBy100( uno::Any
& rDoubleAny
)
317 bool bChanged
= false;
319 if( (rDoubleAny
>>=fValue
) && (fValue
!=0.0) )
322 rDoubleAny
<<= fValue
;
328 bool lcl_AdaptWrongPercentScaleValues(chart2::ScaleData
& rScaleData
)
330 bool bChanged
= lcl_divideBy100( rScaleData
.Minimum
);
331 bChanged
= lcl_divideBy100( rScaleData
.Maximum
) || bChanged
;
332 bChanged
= lcl_divideBy100( rScaleData
.Origin
) || bChanged
;
333 bChanged
= lcl_divideBy100( rScaleData
.IncrementData
.Distance
) || bChanged
;
337 }//end anonymous namespace
339 void SchXMLAxisContext::CreateAxis()
341 m_rAxes
.push_back( m_aCurrentAxis
);
343 Reference
< beans::XPropertySet
> xDiaProp( m_rImportHelper
.GetChartDocument()->getDiagram(), uno::UNO_QUERY
);
347 switch( m_aCurrentAxis
.eDimension
)
350 if( m_aCurrentAxis
.nAxisIndex
== 0 )
351 aPropName
= "HasXAxis";
353 aPropName
= "HasSecondaryXAxis";
356 if( m_aCurrentAxis
.nAxisIndex
== 0 )
357 aPropName
= "HasYAxis";
359 aPropName
= "HasSecondaryYAxis";
362 if( m_aCurrentAxis
.nAxisIndex
== 0 )
363 aPropName
= "HasZAxis";
365 case SCH_XML_AXIS_UNDEF
:
366 SAL_INFO("xmloff.chart", "Invalid axis" );
371 xDiaProp
->setPropertyValue( aPropName
, uno::Any(true) );
373 catch( beans::UnknownPropertyException
& )
375 SAL_INFO("xmloff.chart", "Couldn't turn on axis" );
377 if( m_aCurrentAxis
.eDimension
==SCH_XML_AXIS_Z
)
379 bool bSettingZAxisSucceeded
= false;
382 xDiaProp
->getPropertyValue( aPropName
) >>= bSettingZAxisSucceeded
;
384 catch( beans::UnknownPropertyException
& )
386 SAL_INFO("xmloff.chart", "Couldn't turn on z axis" );
388 if( !bSettingZAxisSucceeded
)
392 m_xAxisProps
.set( lcl_getChartAxis( m_aCurrentAxis
, m_xDiagram
), uno::UNO_QUERY
);
394 if( m_bAddMissingXAxisForNetCharts
&& m_aCurrentAxis
.eDimension
==SCH_XML_AXIS_Y
&& m_aCurrentAxis
.nAxisIndex
==0 )
398 xDiaProp
->setPropertyValue("HasXAxis", uno::Any(true) );
400 catch( beans::UnknownPropertyException
& )
402 SAL_INFO("xmloff.chart", "Couldn't turn on x axis" );
407 if( !m_xAxisProps
.is())
410 uno::Any
aTrueBool( uno::Any( true ));
411 uno::Any
aFalseBool( uno::Any( false ));
413 // #i109879# the line color is black as default, in the model it is a light gray
414 m_xAxisProps
->setPropertyValue("LineColor",
415 uno::Any( COL_BLACK
));
417 m_xAxisProps
->setPropertyValue("DisplayLabels", aFalseBool
);
419 // Compatibility option: starting from LibreOffice 5.1 the rotated
420 // layout is preferred to staggering for axis labels.
421 // So the import default value for having compatibility with ODF
422 // documents created with earlier LibreOffice versions is `true`.
423 if( GetImport().getGeneratorVersion() != SvXMLImport::ProductVersionUnknown
)
424 m_xAxisProps
->setPropertyValue("TryStaggeringFirst", aTrueBool
);
426 // #88077# AutoOrigin 'on' is default
427 m_xAxisProps
->setPropertyValue("AutoOrigin", aTrueBool
);
429 if( m_bAxisTypeImported
)
430 m_xAxisProps
->setPropertyValue("AxisType", uno::Any(m_nAxisType
) );
432 if( !m_aAutoStyleName
.isEmpty())
434 const SvXMLStylesContext
* pStylesCtxt
= m_rImportHelper
.GetAutoStylesContext();
437 SvXMLStyleContext
* pStyle
= const_cast<SvXMLStyleContext
*>(pStylesCtxt
->FindStyleChildContext(SchXMLImportHelper::GetChartFamilyID(), m_aAutoStyleName
));
439 if (XMLPropStyleContext
* pPropStyleContext
= dynamic_cast<XMLPropStyleContext
*>(pStyle
))
441 pPropStyleContext
->FillPropertySet(m_xAxisProps
);
443 if( m_bAdaptWrongPercentScaleValues
&& m_aCurrentAxis
.eDimension
==SCH_XML_AXIS_Y
)
445 //set scale data of added x axis back to default
446 Reference
< chart2::XAxis
> xAxis( lcl_getAxis( GetImport().GetModel(),
447 m_aCurrentAxis
.eDimension
, m_aCurrentAxis
.nAxisIndex
) );
450 chart2::ScaleData
aScaleData( xAxis
->getScaleData());
451 if( lcl_AdaptWrongPercentScaleValues(aScaleData
) )
452 xAxis
->setScaleData( aScaleData
);
456 if( m_bAddMissingXAxisForNetCharts
)
458 //copy style from y axis to added x axis:
460 Reference
< chart::XAxisSupplier
> xAxisSuppl( xDiaProp
, uno::UNO_QUERY
);
461 if( xAxisSuppl
.is() )
463 Reference
< beans::XPropertySet
> xXAxisProp( xAxisSuppl
->getAxis(0), uno::UNO_QUERY
);
464 pPropStyleContext
->FillPropertySet(xXAxisProp
);
467 //set scale data of added x axis back to default
468 Reference
< chart2::XAxis
> xAxis( lcl_getAxis( GetImport().GetModel(),
469 0 /*nDimensionIndex*/, 0 /*nAxisIndex*/ ) );
472 chart2::ScaleData aScaleData
;
473 aScaleData
.AxisType
= chart2::AxisType::CATEGORY
;
474 aScaleData
.Orientation
= chart2::AxisOrientation_MATHEMATICAL
;
475 xAxis
->setScaleData( aScaleData
);
478 //set line style of added x axis to invisible
479 Reference
< beans::XPropertySet
> xNewAxisProp( xAxis
, uno::UNO_QUERY
);
480 if( xNewAxisProp
.is() )
482 xNewAxisProp
->setPropertyValue("LineStyle"
483 , uno::Any(drawing::LineStyle_NONE
));
487 if( m_bAdaptXAxisOrientationForOld2DBarCharts
&& m_aCurrentAxis
.eDimension
== SCH_XML_AXIS_X
)
489 bool bIs3DChart
= false;
490 if( xDiaProp
.is() && ( xDiaProp
->getPropertyValue("Dim3D") >>= bIs3DChart
)
493 Reference
< chart2::XChartDocument
> xChart2Document( GetImport().GetModel(), uno::UNO_QUERY
);
494 if( xChart2Document
.is() )
496 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xChart2Document
->getFirstDiagram(), uno::UNO_QUERY
);
497 if( xCooSysCnt
.is() )
499 uno::Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems() );
500 if( aCooSysSeq
.hasElements() )
502 bool bSwapXandYAxis
= false;
503 Reference
< chart2::XCoordinateSystem
> xCooSys( aCooSysSeq
[0] );
504 Reference
< beans::XPropertySet
> xCooSysProp( xCooSys
, uno::UNO_QUERY
);
505 if( xCooSysProp
.is() && ( xCooSysProp
->getPropertyValue("SwapXAndYAxis") >>= bSwapXandYAxis
)
508 Reference
< chart2::XAxis
> xAxis
= xCooSys
->getAxisByDimension( 0, m_aCurrentAxis
.nAxisIndex
);
511 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
512 aScaleData
.Orientation
= chart2::AxisOrientation_REVERSE
;
513 xAxis
->setScaleData( aScaleData
);
522 m_rbAxisPositionAttributeImported
= m_rbAxisPositionAttributeImported
|| SchXMLTools::getPropertyFromContext(
523 u
"CrossoverPosition", pPropStyleContext
, pStylesCtxt
).hasValue();
528 if (m_aCurrentAxis
.eDimension
!= SCH_XML_AXIS_X
)
531 Reference
<chart2::XAxis
> xAxis(lcl_getAxis(GetImport().GetModel(), m_aCurrentAxis
.eDimension
, m_aCurrentAxis
.nAxisIndex
));
535 chart2::ScaleData
aScaleData(xAxis
->getScaleData());
536 bool bIs3DChart
= false;
537 double fMajorOrigin
= -1;
538 OUString sChartType
= m_xDiagram
->getDiagramType();
539 if ((xDiaProp
->getPropertyValue("Dim3D") >>= bIs3DChart
) && bIs3DChart
540 && (sChartType
== "com.sun.star.chart.BarDiagram" || sChartType
== "com.sun.star.chart.StockDiagram"))
542 aScaleData
.ShiftedCategoryPosition
= true;
543 xAxis
->setScaleData(aScaleData
);
545 else if ((m_xAxisProps
->getPropertyValue("MajorOrigin") >>= fMajorOrigin
)
546 && (rtl::math::approxEqual(fMajorOrigin
, 0.0) || rtl::math::approxEqual(fMajorOrigin
, 0.5)))
548 aScaleData
.ShiftedCategoryPosition
= rtl::math::approxEqual(fMajorOrigin
, 0.5);
549 xAxis
->setScaleData(aScaleData
);
553 void SchXMLAxisContext::SetAxisTitle()
555 if( m_aCurrentAxis
.aTitle
.isEmpty() )
558 Reference
< chart::XAxis
> xAxis( lcl_getChartAxis( m_aCurrentAxis
, m_xDiagram
) );
562 Reference
< beans::XPropertySet
> xTitleProp( xAxis
->getAxisTitle() );
563 if( xTitleProp
.is() )
567 xTitleProp
->setPropertyValue("String", uno::Any(m_aCurrentAxis
.aTitle
) );
569 catch( beans::UnknownPropertyException
& )
571 SAL_INFO("xmloff.chart", "Property String for Title not available" );
576 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SchXMLAxisContext::createFastChildContext(
578 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
582 case XML_ELEMENT(CHART
, XML_TITLE
):
584 Reference
< drawing::XShape
> xTitleShape
= getTitleShape();
585 return new SchXMLTitleContext( m_rImportHelper
, GetImport(),
586 m_aCurrentAxis
.aTitle
,
591 case XML_ELEMENT(CHART
, XML_CATEGORIES
):
592 m_aCurrentAxis
.bHasCategories
= true;
593 return new SchXMLCategoriesContext( GetImport(),
594 m_rCategoriesAddress
);
597 case XML_ELEMENT(CHART
, XML_DATE_SCALE
):
598 case XML_ELEMENT(CHART_EXT
, XML_DATE_SCALE
):
599 m_bDateScaleImported
= true;
600 return new DateScaleContext( GetImport(), m_xAxisProps
);
602 case XML_ELEMENT(CHART
, XML_GRID
):
604 bool bIsMajor
= true; // default value for class is "major"
605 OUString sAutoStyleName
;
607 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
609 switch (aIter
.getToken())
611 case XML_ELEMENT(CHART
, XML_CLASS
):
612 if( IsXMLToken( aIter
, XML_MINOR
) )
615 case XML_ELEMENT(CHART
, XML_STYLE_NAME
):
616 sAutoStyleName
= aIter
.toString();
619 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
623 CreateGrid( sAutoStyleName
, bIsMajor
);
625 // don't create a context => use default context. grid elements are empty
630 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
637 void SchXMLAxisContext::endFastElement(sal_Int32
)
639 if( !m_bDateScaleImported
&& m_nAxisType
==chart::ChartAxisType::AUTOMATIC
)
641 Reference
< chart2::XAxis
> xAxis( lcl_getAxis( GetImport().GetModel(), m_aCurrentAxis
.eDimension
, m_aCurrentAxis
.nAxisIndex
) );
644 chart2::ScaleData
aScaleData( xAxis
->getScaleData());
645 aScaleData
.AutoDateAxis
= false;//different default for older documents
646 xAxis
->setScaleData( aScaleData
);
656 Reference
< chart2::XAxis
> lcl_getAxis( const Reference
< chart2::XCoordinateSystem
>& rCooSys
, sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
)
658 Reference
< chart2::XAxis
> xAxis
;
661 xAxis
= rCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
);
663 catch( uno::Exception
& )
669 } // anonymous namespace
671 void SchXMLAxisContext::CorrectAxisPositions( const Reference
< chart2::XChartDocument
>& xNewDoc
,
672 std::u16string_view rChartTypeServiceName
,
673 std::u16string_view rODFVersionOfFile
,
674 bool bAxisPositionAttributeImported
)
676 if( !(rODFVersionOfFile
.empty() || rODFVersionOfFile
== u
"1.0" || rODFVersionOfFile
== u
"1.1"
677 || ( rODFVersionOfFile
== u
"1.2" && !bAxisPositionAttributeImported
)) )
682 Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xNewDoc
->getFirstDiagram(), uno::UNO_QUERY_THROW
);
683 uno::Sequence
< Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
684 if( aCooSysSeq
.hasElements() )
686 Reference
< chart2::XCoordinateSystem
> xCooSys( aCooSysSeq
[0] );
689 Reference
< chart2::XAxis
> xMainXAxis
= lcl_getAxis( xCooSys
, 0, 0 );
690 Reference
< chart2::XAxis
> xMainYAxis
= lcl_getAxis( xCooSys
, 1, 0 );
691 //Reference< chart2::XAxis > xMajorZAxis = lcl_getAxis( xCooSys, 2, 0 );
692 Reference
< chart2::XAxis
> xSecondaryXAxis
= lcl_getAxis( xCooSys
, 0, 1 );
693 Reference
< chart2::XAxis
> xSecondaryYAxis
= lcl_getAxis( xCooSys
, 1, 1 );
695 Reference
< beans::XPropertySet
> xMainXAxisProp( xMainXAxis
, uno::UNO_QUERY
);
696 Reference
< beans::XPropertySet
> xMainYAxisProp( xMainYAxis
, uno::UNO_QUERY
);
697 Reference
< beans::XPropertySet
> xSecondaryXAxisProp( xSecondaryXAxis
, uno::UNO_QUERY
);
698 Reference
< beans::XPropertySet
> xSecondaryYAxisProp( xSecondaryYAxis
, uno::UNO_QUERY
);
700 if( xMainXAxisProp
.is() && xMainYAxisProp
.is() )
702 chart2::ScaleData aMainXScale
= xMainXAxis
->getScaleData();
703 if( rChartTypeServiceName
== u
"com.sun.star.chart2.ScatterChartType" )
705 xMainYAxisProp
->setPropertyValue("CrossoverPosition"
706 , uno::Any( css::chart::ChartAxisPosition_VALUE
) );
707 double fCrossoverValue
= 0.0;
708 aMainXScale
.Origin
>>= fCrossoverValue
;
709 xMainYAxisProp
->setPropertyValue("CrossoverValue"
710 , uno::Any( fCrossoverValue
) );
712 if( aMainXScale
.Orientation
== chart2::AxisOrientation_REVERSE
)
714 xMainYAxisProp
->setPropertyValue("LabelPosition"
715 , uno::Any( css::chart::ChartAxisLabelPosition_OUTSIDE_END
) );
716 xMainYAxisProp
->setPropertyValue("MarkPosition"
717 , uno::Any( css::chart::ChartAxisMarkPosition_AT_LABELS
) );
718 if( xSecondaryYAxisProp
.is() )
719 xSecondaryYAxisProp
->setPropertyValue("CrossoverPosition"
720 , uno::Any( css::chart::ChartAxisPosition_START
) );
724 xMainYAxisProp
->setPropertyValue("LabelPosition"
725 , uno::Any( css::chart::ChartAxisLabelPosition_OUTSIDE_START
) );
726 xMainYAxisProp
->setPropertyValue("MarkPosition"
727 , uno::Any( css::chart::ChartAxisMarkPosition_AT_LABELS
) );
728 if( xSecondaryYAxisProp
.is() )
729 xSecondaryYAxisProp
->setPropertyValue("CrossoverPosition"
730 , uno::Any( css::chart::ChartAxisPosition_END
) );
735 if( aMainXScale
.Orientation
== chart2::AxisOrientation_REVERSE
)
737 xMainYAxisProp
->setPropertyValue("CrossoverPosition"
738 , uno::Any( css::chart::ChartAxisPosition_END
) );
739 if( xSecondaryYAxisProp
.is() )
740 xSecondaryYAxisProp
->setPropertyValue("CrossoverPosition"
741 , uno::Any( css::chart::ChartAxisPosition_START
) );
745 xMainYAxisProp
->setPropertyValue("CrossoverPosition"
746 , uno::Any( css::chart::ChartAxisPosition_START
) );
747 if( xSecondaryYAxisProp
.is() )
748 xSecondaryYAxisProp
->setPropertyValue("CrossoverPosition"
749 , uno::Any( css::chart::ChartAxisPosition_END
) );
753 chart2::ScaleData aMainYScale
= xMainYAxis
->getScaleData();
754 xMainXAxisProp
->setPropertyValue("CrossoverPosition"
755 , uno::Any( css::chart::ChartAxisPosition_VALUE
) );
756 double fCrossoverValue
= 0.0;
757 aMainYScale
.Origin
>>= fCrossoverValue
;
758 xMainXAxisProp
->setPropertyValue("CrossoverValue"
759 , uno::Any( fCrossoverValue
) );
761 if( aMainYScale
.Orientation
== chart2::AxisOrientation_REVERSE
)
763 xMainXAxisProp
->setPropertyValue("LabelPosition"
764 , uno::Any( css::chart::ChartAxisLabelPosition_OUTSIDE_END
) );
765 xMainXAxisProp
->setPropertyValue("MarkPosition"
766 , uno::Any( css::chart::ChartAxisMarkPosition_AT_LABELS
) );
767 if( xSecondaryXAxisProp
.is() )
768 xSecondaryXAxisProp
->setPropertyValue("CrossoverPosition"
769 , uno::Any( css::chart::ChartAxisPosition_START
) );
773 xMainXAxisProp
->setPropertyValue("LabelPosition"
774 , uno::Any( css::chart::ChartAxisLabelPosition_OUTSIDE_START
) );
775 xMainXAxisProp
->setPropertyValue("MarkPosition"
776 , uno::Any( css::chart::ChartAxisMarkPosition_AT_LABELS
) );
777 if( xSecondaryXAxisProp
.is() )
778 xSecondaryXAxisProp
->setPropertyValue("CrossoverPosition"
779 , uno::Any( css::chart::ChartAxisPosition_END
) );
785 catch( uno::Exception
& )
790 SchXMLCategoriesContext::SchXMLCategoriesContext(
791 SvXMLImport
& rImport
,
792 OUString
& rAddress
) :
793 SvXMLImportContext( rImport
),
794 mrAddress( rAddress
)
798 void SchXMLCategoriesContext::startFastElement( sal_Int32
/*nElement*/,
799 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
801 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
803 if( aIter
.getToken() == XML_ELEMENT(TABLE
, XML_CELL_RANGE_ADDRESS
) )
804 mrAddress
= aIter
.toString();
806 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
810 DateScaleContext::DateScaleContext(
811 SvXMLImport
& rImport
,
812 const Reference
< beans::XPropertySet
>& rAxisProps
) :
813 SvXMLImportContext( rImport
),
814 m_xAxisProps( rAxisProps
)
820 sal_Int32
lcl_getTimeUnit( const sax_fastparser::FastAttributeList::FastAttributeIter
& rValue
)
822 sal_Int32 nTimeUnit
= css::chart::TimeUnit::DAY
;
823 if( IsXMLToken( rValue
, XML_DAYS
) )
824 nTimeUnit
= css::chart::TimeUnit::DAY
;
825 else if( IsXMLToken( rValue
, XML_MONTHS
) )
826 nTimeUnit
= css::chart::TimeUnit::MONTH
;
827 else if( IsXMLToken( rValue
, XML_YEARS
) )
828 nTimeUnit
= css::chart::TimeUnit::YEAR
;
834 void DateScaleContext::startFastElement( sal_Int32
/*nElement*/,
835 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
837 if( !m_xAxisProps
.is() )
841 bool bSetNewIncrement
=false;
842 chart::TimeIncrement aIncrement
;
843 m_xAxisProps
->getPropertyValue("TimeIncrement") >>= aIncrement
;
845 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
847 switch( aIter
.getToken() )
849 case XML_ELEMENT(CHART
, XML_BASE_TIME_UNIT
):
851 aIncrement
.TimeResolution
<<= lcl_getTimeUnit(aIter
);
852 bSetNewIncrement
= true;
855 case XML_ELEMENT(CHART
, XML_MAJOR_INTERVAL_VALUE
):
857 chart::TimeInterval
aInterval(1,0);
858 aIncrement
.MajorTimeInterval
>>= aInterval
;
859 ::sax::Converter::convertNumber( aInterval
.Number
, aIter
.toView() );
860 aIncrement
.MajorTimeInterval
<<= aInterval
;
861 bSetNewIncrement
= true;
864 case XML_ELEMENT(CHART
, XML_MAJOR_INTERVAL_UNIT
):
866 chart::TimeInterval
aInterval(1,0);
867 aIncrement
.MajorTimeInterval
>>= aInterval
;
868 aInterval
.TimeUnit
= lcl_getTimeUnit(aIter
);
869 aIncrement
.MajorTimeInterval
<<= aInterval
;
870 bSetNewIncrement
= true;
873 case XML_ELEMENT(CHART
, XML_MINOR_INTERVAL_VALUE
):
875 chart::TimeInterval
aInterval(1,0);
876 aIncrement
.MinorTimeInterval
>>= aInterval
;
877 ::sax::Converter::convertNumber( aInterval
.Number
, aIter
.toView() );
878 aIncrement
.MinorTimeInterval
<<= aInterval
;
879 bSetNewIncrement
= true;
882 case XML_ELEMENT(CHART
, XML_MINOR_INTERVAL_UNIT
):
884 chart::TimeInterval
aInterval(1,0);
885 aIncrement
.MinorTimeInterval
>>= aInterval
;
886 aInterval
.TimeUnit
= lcl_getTimeUnit(aIter
);
887 aIncrement
.MinorTimeInterval
<<= aInterval
;
888 bSetNewIncrement
= true;
892 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
896 if( bSetNewIncrement
)
897 m_xAxisProps
->setPropertyValue("TimeIncrement", uno::Any( aIncrement
) );
900 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */