diff options
author | Philipp Lohmann [pl] <Philipp.Lohmann@Oracle.COM> | 2011-02-14 16:17:22 +0100 |
---|---|---|
committer | Philipp Lohmann [pl] <Philipp.Lohmann@Oracle.COM> | 2011-02-14 16:17:22 +0100 |
commit | 1fb042333fe6287756ff1fac11d18cd7c150730d (patch) | |
tree | 595de5d187177832ce656d7832af9dce9dce2d99 /xmloff/source/chart/SchXMLAxisContext.cxx | |
parent | 5b3e910e926c7dd1e8dcfe8e0a5c6cb5bd17480a (diff) | |
parent | cd0d6a5a6775f197fdb7e78b54c8133074a7a236 (diff) |
rebase to DEV300_m100
Diffstat (limited to 'xmloff/source/chart/SchXMLAxisContext.cxx')
-rwxr-xr-x | xmloff/source/chart/SchXMLAxisContext.cxx | 1053 |
1 files changed, 1053 insertions, 0 deletions
diff --git a/xmloff/source/chart/SchXMLAxisContext.cxx b/xmloff/source/chart/SchXMLAxisContext.cxx new file mode 100755 index 000000000000..f9828fa04931 --- /dev/null +++ b/xmloff/source/chart/SchXMLAxisContext.cxx @@ -0,0 +1,1053 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "SchXMLAxisContext.hxx" +#include "SchXMLChartContext.hxx" +#include "SchXMLTools.hxx" +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmlement.hxx> +#include <xmloff/xmlstyle.hxx> +#include <xmloff/prstylei.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> + +#include <tools/debug.hxx> + +#include <com/sun/star/chart/ChartAxisLabelPosition.hpp> +#include <com/sun/star/chart/ChartAxisMarkPosition.hpp> +#include <com/sun/star/chart/ChartAxisPosition.hpp> +#include <com/sun/star/chart/ChartAxisType.hpp> +#include <com/sun/star/chart/TimeIncrement.hpp> +#include <com/sun/star/chart/TimeInterval.hpp> +#include <com/sun/star/chart/TimeUnit.hpp> +#include <com/sun/star/chart/XAxis.hpp> +#include <com/sun/star/chart/XAxisSupplier.hpp> +#include <com/sun/star/chart2/AxisType.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> + +#include <com/sun/star/drawing/LineStyle.hpp> + +using namespace ::xmloff::token; +using namespace com::sun::star; + +using rtl::OUString; +using com::sun::star::uno::Reference; + +//---------------------------------------- +//---------------------------------------- + +static SvXMLEnumMapEntry aXMLAxisDimensionMap[] = +{ + { XML_X, SCH_XML_AXIS_X }, + { XML_Y, SCH_XML_AXIS_Y }, + { XML_Z, SCH_XML_AXIS_Z }, + { XML_TOKEN_INVALID, 0 } +}; + +static SvXMLEnumMapEntry aXMLAxisTypeMap[] = +{ + { XML_AUTO, ::com::sun::star::chart::ChartAxisType::AUTOMATIC }, + { XML_TEXT, ::com::sun::star::chart::ChartAxisType::CATEGORY }, + { XML_DATE, ::com::sun::star::chart::ChartAxisType::DATE }, + { XML_TOKEN_INVALID, 0 } +}; + +//---------------------------------------- +//---------------------------------------- + +class SchXMLCategoriesContext : public SvXMLImportContext +{ +private: + SchXMLImportHelper& m_rImportHelper; + OUString& mrAddress; + +public: + SchXMLCategoriesContext( SchXMLImportHelper& rImpHelper, + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + OUString& rAddress ); + virtual ~SchXMLCategoriesContext(); + virtual void StartElement( const Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList ); +}; + +//---------------------------------------- +//---------------------------------------- + + +class DateScaleContext : public SvXMLImportContext +{ +public: + DateScaleContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, + sal_uInt16 nPrefix, const OUString& rLocalName, + const Reference< beans::XPropertySet > xAxisProps ); + + virtual ~DateScaleContext(); + virtual void StartElement( const Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList ); + +private: + SchXMLImportHelper& m_rImportHelper; + Reference< beans::XPropertySet > m_xAxisProps; +}; + + +//---------------------------------------- +//---------------------------------------- + +SchXMLAxisContext::SchXMLAxisContext( SchXMLImportHelper& rImpHelper, + SvXMLImport& rImport, const OUString& rLocalName, + Reference< chart::XDiagram > xDiagram, + std::vector< SchXMLAxis >& rAxes, + OUString & rCategoriesAddress, + bool bAddMissingXAxisForNetCharts, + bool bAdaptWrongPercentScaleValues, + bool bAdaptXAxisOrientationForOld2DBarCharts, + bool& rbAxisPositionAttributeImported ) : + SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ), + m_rImportHelper( rImpHelper ), + m_xDiagram( xDiagram ), + m_rAxes( rAxes ), + m_rCategoriesAddress( rCategoriesAddress ), + m_nAxisType(chart::ChartAxisType::AUTOMATIC), + m_bAxisTypeImported(false), + m_bDateScaleImported(false), + m_bAddMissingXAxisForNetCharts( bAddMissingXAxisForNetCharts ), + m_bAdaptWrongPercentScaleValues( bAdaptWrongPercentScaleValues ), + m_bAdaptXAxisOrientationForOld2DBarCharts( bAdaptXAxisOrientationForOld2DBarCharts ), + m_rbAxisPositionAttributeImported( rbAxisPositionAttributeImported ) +{ +} + +SchXMLAxisContext::~SchXMLAxisContext() +{} + +Reference< chart::XAxis > lcl_getChartAxis( SchXMLAxis aCurrentAxis, const Reference< chart::XDiagram > xDiagram ) +{ + Reference< chart::XAxis > xAxis; + Reference< chart::XAxisSupplier > xAxisSuppl( xDiagram, uno::UNO_QUERY ); + if( !xAxisSuppl.is() ) + return xAxis; + if( aCurrentAxis.nAxisIndex == 0 ) + xAxis = xAxisSuppl->getAxis(aCurrentAxis.eDimension); + else + xAxis = xAxisSuppl->getSecondaryAxis(aCurrentAxis.eDimension); + return xAxis; +} + +/* returns a shape for the current axis's title. The property + "Has...AxisTitle" is set to "True" to get the shape + */ +Reference< drawing::XShape > SchXMLAxisContext::getTitleShape() +{ + Reference< drawing::XShape > xResult; + Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY ); + Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) ); + if( !xDiaProp.is() || !xAxis.is() ) + return xResult; + + rtl::OUString aPropName; + switch( m_aCurrentAxis.eDimension ) + { + case SCH_XML_AXIS_X: + if( m_aCurrentAxis.nAxisIndex == 0 ) + aPropName = OUString::createFromAscii( "HasXAxisTitle" ); + else + aPropName = OUString::createFromAscii( "HasSecondaryXAxisTitle" ); + break; + case SCH_XML_AXIS_Y: + if( m_aCurrentAxis.nAxisIndex == 0 ) + aPropName = OUString::createFromAscii( "HasYAxisTitle" ); + else + aPropName = OUString::createFromAscii( "HasSecondaryYAxisTitle" ); + break; + case SCH_XML_AXIS_Z: + aPropName = OUString::createFromAscii( "HasZAxisTitle" ); + break; + case SCH_XML_AXIS_UNDEF: + DBG_ERROR( "Invalid axis" ); + break; + } + xDiaProp->setPropertyValue( aPropName, uno::makeAny(sal_True) ); + xResult = Reference< drawing::XShape >( xAxis->getAxisTitle(), uno::UNO_QUERY ); + return xResult; +} + +void SchXMLAxisContext::CreateGrid( OUString sAutoStyleName, bool bIsMajor ) +{ + Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY ); + Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) ); + if( !xDiaProp.is() || !xAxis.is() ) + return; + + rtl::OUString aPropName; + switch( m_aCurrentAxis.eDimension ) + { + case SCH_XML_AXIS_X: + if( bIsMajor ) + aPropName = OUString::createFromAscii("HasXAxisGrid"); + else + aPropName = OUString::createFromAscii("HasXAxisHelpGrid"); + break; + case SCH_XML_AXIS_Y: + if( bIsMajor ) + aPropName = OUString::createFromAscii("HasYAxisGrid"); + else + aPropName = OUString::createFromAscii("HasYAxisHelpGrid"); + break; + case SCH_XML_AXIS_Z: + if( bIsMajor ) + aPropName = OUString::createFromAscii("HasZAxisGrid"); + else + aPropName = OUString::createFromAscii("HasZAxisHelpGrid"); + break; + case SCH_XML_AXIS_UNDEF: + DBG_ERROR( "Invalid axis" ); + break; + } + xDiaProp->setPropertyValue( aPropName, uno::makeAny(sal_True) ); + + Reference< beans::XPropertySet > xGridProp; + if( bIsMajor ) + xGridProp = xAxis->getMajorGrid(); + else + xGridProp = xAxis->getMinorGrid(); + + // set properties + if( xGridProp.is()) + { + // the line color is black as default, in the model it is a light gray + xGridProp->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "LineColor" )), + uno::makeAny( COL_BLACK )); + if( sAutoStyleName.getLength()) + { + const SvXMLStylesContext* pStylesCtxt = m_rImportHelper.GetAutoStylesContext(); + if( pStylesCtxt ) + { + const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext( + m_rImportHelper.GetChartFamilyID(), sAutoStyleName ); + + if( pStyle && pStyle->ISA( XMLPropStyleContext )) + (( XMLPropStyleContext* )pStyle )->FillPropertySet( xGridProp ); + } + } + } +} + +namespace +{ +enum AxisAttributeTokens +{ + XML_TOK_AXIS_DIMENSION, + XML_TOK_AXIS_NAME, + XML_TOK_AXIS_STYLE_NAME, + XML_TOK_AXIS_TYPE, + XML_TOK_AXIS_TYPE_EXT +}; + +SvXMLTokenMapEntry aAxisAttributeTokenMap[] = +{ + { XML_NAMESPACE_CHART, XML_DIMENSION, XML_TOK_AXIS_DIMENSION }, + { XML_NAMESPACE_CHART, XML_NAME, XML_TOK_AXIS_NAME }, + { XML_NAMESPACE_CHART, XML_STYLE_NAME, XML_TOK_AXIS_STYLE_NAME }, + { XML_NAMESPACE_CHART, XML_AXIS_TYPE, XML_TOK_AXIS_TYPE }, + { XML_NAMESPACE_CHART_EXT, XML_AXIS_TYPE, XML_TOK_AXIS_TYPE_EXT }, + XML_TOKEN_MAP_END +}; + +class AxisAttributeTokenMap : public SvXMLTokenMap +{ +public: + AxisAttributeTokenMap(): SvXMLTokenMap( aAxisAttributeTokenMap ) {} + virtual ~AxisAttributeTokenMap() {} +}; + +//a AxisAttributeTokenMap Singleton +struct theAxisAttributeTokenMap : public rtl::Static< AxisAttributeTokenMap, theAxisAttributeTokenMap > {}; +} + +void SchXMLAxisContext::StartElement( const Reference< xml::sax::XAttributeList >& xAttrList ) +{ + // parse attributes + sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; + SchXMLImport& rImport = ( SchXMLImport& )GetImport(); + const SvXMLTokenMap& rAttrTokenMap = theAxisAttributeTokenMap::get(); + + for( sal_Int16 i = 0; i < nAttrCount; i++ ) + { + OUString sAttrName = xAttrList->getNameByIndex( i ); + OUString aLocalName; + OUString aValue = xAttrList->getValueByIndex( i ); + sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName )) + { + case XML_TOK_AXIS_DIMENSION: + { + sal_uInt16 nEnumVal; + if( rImport.GetMM100UnitConverter().convertEnum( nEnumVal, aValue, aXMLAxisDimensionMap )) + m_aCurrentAxis.eDimension = ( SchXMLAxisDimension )nEnumVal; + } + break; + case XML_TOK_AXIS_NAME: + m_aCurrentAxis.aName = aValue; + break; + case XML_TOK_AXIS_TYPE: + case XML_TOK_AXIS_TYPE_EXT: + sal_uInt16 nEnumVal; + if( rImport.GetMM100UnitConverter().convertEnum( nEnumVal, aValue, aXMLAxisTypeMap )) + { + m_nAxisType = nEnumVal; + m_bAxisTypeImported = true; + } + break; + case XML_TOK_AXIS_STYLE_NAME: + m_aAutoStyleName = aValue; + break; + } + } + + // check for number of axes with same dimension + m_aCurrentAxis.nAxisIndex = 0; + sal_Int32 nNumOfAxes = m_rAxes.size(); + for( sal_Int32 nCurrent = 0; nCurrent < nNumOfAxes; nCurrent++ ) + { + if( m_rAxes[ nCurrent ].eDimension == m_aCurrentAxis.eDimension ) + m_aCurrentAxis.nAxisIndex++; + } + CreateAxis(); +} +namespace +{ + +Reference< chart2::XAxis > lcl_getAxis( const Reference< frame::XModel >& xChartModel, + sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) +{ + Reference< chart2::XAxis > xAxis; + + try + { + Reference< chart2::XChartDocument > xChart2Document( xChartModel, uno::UNO_QUERY ); + if( xChart2Document.is() ) + { + Reference< chart2::XDiagram > xDiagram( xChart2Document->getFirstDiagram()); + Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW ); + uno::Sequence< Reference< chart2::XCoordinateSystem > > + aCooSysSeq( xCooSysCnt->getCoordinateSystems()); + sal_Int32 nCooSysIndex = 0; + if( nCooSysIndex < aCooSysSeq.getLength() ) + { + Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[nCooSysIndex] ); + if( xCooSys.is() && nDimensionIndex < xCooSys->getDimension() ) + { + const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex); + if( nAxisIndex <= nMaxAxisIndex ) + xAxis = xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ); + } + } + } + } + catch( uno::Exception & ) + { + DBG_ERROR( "Couldn't get axis" ); + } + + return xAxis; +} + +bool lcl_divideBy100( uno::Any& rDoubleAny ) +{ + bool bChanged = false; + double fValue=0.0; + if( (rDoubleAny>>=fValue) && (fValue!=0.0) ) + { + fValue/=100.0; + rDoubleAny = uno::makeAny(fValue); + bChanged = true; + } + return bChanged; +} + +bool lcl_AdaptWrongPercentScaleValues(chart2::ScaleData& rScaleData) +{ + bool bChanged = lcl_divideBy100( rScaleData.Minimum ); + bChanged = lcl_divideBy100( rScaleData.Maximum ) || bChanged; + bChanged = lcl_divideBy100( rScaleData.Origin ) || bChanged; + bChanged = lcl_divideBy100( rScaleData.IncrementData.Distance ) || bChanged; + return bChanged; +} + +}//end anonymous namespace + +void SchXMLAxisContext::CreateAxis() +{ + m_rAxes.push_back( m_aCurrentAxis ); + + Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY ); + if( !xDiaProp.is() ) + return; + rtl::OUString aPropName; + switch( m_aCurrentAxis.eDimension ) + { + case SCH_XML_AXIS_X: + if( m_aCurrentAxis.nAxisIndex == 0 ) + aPropName = OUString::createFromAscii("HasXAxis"); + else + aPropName = OUString::createFromAscii("HasSecondaryXAxis"); + break; + case SCH_XML_AXIS_Y: + if( m_aCurrentAxis.nAxisIndex == 0 ) + aPropName = OUString::createFromAscii("HasYAxis"); + else + aPropName = OUString::createFromAscii("HasSecondaryYAxis"); + break; + case SCH_XML_AXIS_Z: + if( m_aCurrentAxis.nAxisIndex == 0 ) + aPropName = OUString::createFromAscii("HasXAxis"); + else + aPropName = OUString::createFromAscii("HasSecondaryXAxis"); + break; + case SCH_XML_AXIS_UNDEF: + DBG_ERROR( "Invalid axis" ); + break; + } + try + { + xDiaProp->setPropertyValue( aPropName, uno::makeAny(sal_True) ); + } + catch( beans::UnknownPropertyException & ) + { + DBG_ERROR( "Couldn't turn on axis" ); + } + if( m_aCurrentAxis.eDimension==SCH_XML_AXIS_Z ) + { + bool bSettingZAxisSuccedded = false; + try + { + xDiaProp->getPropertyValue( aPropName ) >>= bSettingZAxisSuccedded; + } + catch( beans::UnknownPropertyException & ) + { + DBG_ERROR( "Couldn't turn on z axis" ); + } + if( !bSettingZAxisSuccedded ) + return; + } + + + m_xAxisProps = Reference<beans::XPropertySet>( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ), uno::UNO_QUERY ); + + if( m_bAddMissingXAxisForNetCharts && m_aCurrentAxis.eDimension==SCH_XML_AXIS_Y && m_aCurrentAxis.nAxisIndex==0 ) + { + try + { + xDiaProp->setPropertyValue( OUString::createFromAscii( "HasXAxis" ), uno::makeAny(sal_True) ); + } + catch( beans::UnknownPropertyException & ) + { + DBG_ERROR( "Couldn't turn on x axis" ); + } + } + + // set properties + if( m_xAxisProps.is()) + { + uno::Any aTrueBool( uno::makeAny( sal_True )); + uno::Any aFalseBool( uno::makeAny( sal_False )); + + // #i109879# the line color is black as default, in the model it is a light gray + m_xAxisProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "LineColor" )), + uno::makeAny( COL_BLACK )); + + m_xAxisProps->setPropertyValue( OUString::createFromAscii( "DisplayLabels" ), aFalseBool ); + + // #88077# AutoOrigin 'on' is default + m_xAxisProps->setPropertyValue( OUString::createFromAscii( "AutoOrigin" ), aTrueBool ); + + if( m_bAxisTypeImported ) + m_xAxisProps->setPropertyValue( OUString::createFromAscii( "AxisType" ), uno::makeAny(m_nAxisType) ); + + if( m_aAutoStyleName.getLength()) + { + const SvXMLStylesContext* pStylesCtxt = m_rImportHelper.GetAutoStylesContext(); + if( pStylesCtxt ) + { + const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext( + m_rImportHelper.GetChartFamilyID(), m_aAutoStyleName ); + + if( pStyle && pStyle->ISA( XMLPropStyleContext )) + { + // note: SvXMLStyleContext::FillPropertySet is not const + XMLPropStyleContext * pPropStyleContext = const_cast< XMLPropStyleContext * >( dynamic_cast< const XMLPropStyleContext * >( pStyle )); + if( pPropStyleContext ) + pPropStyleContext->FillPropertySet( m_xAxisProps ); + + if( m_bAdaptWrongPercentScaleValues && m_aCurrentAxis.eDimension==SCH_XML_AXIS_Y ) + { + //set scale data of added x axis back to default + Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(), + m_aCurrentAxis.eDimension, m_aCurrentAxis.nAxisIndex ) ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData( xAxis->getScaleData()); + if( lcl_AdaptWrongPercentScaleValues(aScaleData) ) + xAxis->setScaleData( aScaleData ); + } + } + + if( m_bAddMissingXAxisForNetCharts ) + { + //copy style from y axis to added x axis: + + Reference< chart::XAxisSupplier > xAxisSuppl( xDiaProp, uno::UNO_QUERY ); + if( xAxisSuppl.is() ) + { + Reference< beans::XPropertySet > xXAxisProp( xAxisSuppl->getAxis(0), uno::UNO_QUERY ); + (( XMLPropStyleContext* )pStyle )->FillPropertySet( xXAxisProp ); + } + + //set scale data of added x axis back to default + Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(), + 0 /*nDimensionIndex*/, 0 /*nAxisIndex*/ ) ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData; + aScaleData.AxisType = chart2::AxisType::CATEGORY; + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + xAxis->setScaleData( aScaleData ); + } + + //set line style of added x axis to invisible + Reference< beans::XPropertySet > xNewAxisProp( xAxis, uno::UNO_QUERY ); + if( xNewAxisProp.is() ) + { + xNewAxisProp->setPropertyValue( OUString::createFromAscii("LineStyle") + , uno::makeAny(drawing::LineStyle_NONE)); + } + } + + if( m_bAdaptXAxisOrientationForOld2DBarCharts && m_aCurrentAxis.eDimension == SCH_XML_AXIS_X ) + { + bool bIs3DChart = false; + if( xDiaProp.is() && ( xDiaProp->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Dim3D"))) >>= bIs3DChart ) + && !bIs3DChart ) + { + Reference< chart2::XChartDocument > xChart2Document( GetImport().GetModel(), uno::UNO_QUERY ); + if( xChart2Document.is() ) + { + Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xChart2Document->getFirstDiagram(), uno::UNO_QUERY ); + if( xCooSysCnt.is() ) + { + uno::Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems() ); + if( aCooSysSeq.getLength() ) + { + bool bSwapXandYAxis = false; + Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[0] ); + Reference< beans::XPropertySet > xCooSysProp( xCooSys, uno::UNO_QUERY ); + if( xCooSysProp.is() && ( xCooSysProp->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("SwapXAndYAxis"))) >>= bSwapXandYAxis ) + && bSwapXandYAxis ) + { + Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( 0, m_aCurrentAxis.nAxisIndex ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData = xAxis->getScaleData(); + aScaleData.Orientation = chart2::AxisOrientation_REVERSE; + xAxis->setScaleData( aScaleData ); + } + } + } + } + } + } + } + + m_rbAxisPositionAttributeImported = m_rbAxisPositionAttributeImported || SchXMLTools::getPropertyFromContext( + OUString(RTL_CONSTASCII_USTRINGPARAM("CrossoverPosition")), pPropStyleContext, pStylesCtxt ).hasValue(); + } + } + } + } +} + +void SchXMLAxisContext::SetAxisTitle() +{ + if( !m_aCurrentAxis.aTitle.getLength() ) + return; + + Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) ); + if( !xAxis.is() ) + return; + + Reference< beans::XPropertySet > xTitleProp( xAxis->getAxisTitle() ); + if( xTitleProp.is() ) + { + try + { + xTitleProp->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "String" )), uno::makeAny(m_aCurrentAxis.aTitle) ); + } + catch( beans::UnknownPropertyException & ) + { + DBG_ERROR( "Property String for Title not available" ); + } + } +} + +//----------------------------------------------------------------------- +namespace +{ +enum AxisChildTokens +{ + XML_TOK_AXIS_TITLE, + XML_TOK_AXIS_CATEGORIES, + XML_TOK_AXIS_GRID, + XML_TOK_AXIS_DATE_SCALE, + XML_TOK_AXIS_DATE_SCALE_EXT +}; + +SvXMLTokenMapEntry aAxisChildTokenMap[] = +{ + { XML_NAMESPACE_CHART, XML_TITLE, XML_TOK_AXIS_TITLE }, + { XML_NAMESPACE_CHART, XML_CATEGORIES, XML_TOK_AXIS_CATEGORIES }, + { XML_NAMESPACE_CHART, XML_GRID, XML_TOK_AXIS_GRID }, + { XML_NAMESPACE_CHART, XML_DATE_SCALE, XML_TOK_AXIS_DATE_SCALE }, + { XML_NAMESPACE_CHART_EXT, XML_DATE_SCALE, XML_TOK_AXIS_DATE_SCALE_EXT }, + XML_TOKEN_MAP_END +}; + +class AxisChildTokenMap : public SvXMLTokenMap +{ +public: + AxisChildTokenMap(): SvXMLTokenMap( aAxisChildTokenMap ) {} + virtual ~AxisChildTokenMap() {} +}; + +//a AxisChildTokenMap Singleton +struct theAxisChildTokenMap : public rtl::Static< AxisChildTokenMap, theAxisChildTokenMap > {}; +} + +SvXMLImportContext* SchXMLAxisContext::CreateChildContext( + sal_uInt16 p_nPrefix, + const OUString& rLocalName, + const Reference< xml::sax::XAttributeList >& xAttrList ) +{ + SvXMLImportContext* pContext = 0; + const SvXMLTokenMap& rTokenMap = theAxisChildTokenMap::get(); + + switch( rTokenMap.Get( p_nPrefix, rLocalName )) + { + case XML_TOK_AXIS_TITLE: + { + Reference< drawing::XShape > xTitleShape = getTitleShape(); + pContext = new SchXMLTitleContext( m_rImportHelper, GetImport(), rLocalName, + m_aCurrentAxis.aTitle, + xTitleShape ); + } + break; + + case XML_TOK_AXIS_CATEGORIES: + pContext = new SchXMLCategoriesContext( m_rImportHelper, GetImport(), + p_nPrefix, rLocalName, + m_rCategoriesAddress ); + m_aCurrentAxis.bHasCategories = true; + break; + + case XML_TOK_AXIS_DATE_SCALE: + case XML_TOK_AXIS_DATE_SCALE_EXT: + pContext = new DateScaleContext( m_rImportHelper, GetImport(), + p_nPrefix, rLocalName, m_xAxisProps ); + m_bDateScaleImported = true; + break; + + case XML_TOK_AXIS_GRID: + { + sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; + bool bIsMajor = true; // default value for class is "major" + OUString sAutoStyleName; + + for( sal_Int16 i = 0; i < nAttrCount; i++ ) + { + OUString sAttrName = xAttrList->getNameByIndex( i ); + OUString aLocalName; + sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + if( nPrefix == XML_NAMESPACE_CHART ) + { + if( IsXMLToken( aLocalName, XML_CLASS ) ) + { + if( IsXMLToken( xAttrList->getValueByIndex( i ), XML_MINOR ) ) + bIsMajor = false; + } + else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) ) + sAutoStyleName = xAttrList->getValueByIndex( i ); + } + } + + CreateGrid( sAutoStyleName, bIsMajor ); + + // don't create a context => use default context. grid elements are empty + pContext = new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName ); + } + break; + + default: + pContext = new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName ); + break; + } + + return pContext; +} + +void SchXMLAxisContext::EndElement() +{ + if( !m_bDateScaleImported && m_nAxisType==chart::ChartAxisType::AUTOMATIC ) + { + Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(), m_aCurrentAxis.eDimension, m_aCurrentAxis.nAxisIndex ) ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData( xAxis->getScaleData()); + aScaleData.AutoDateAxis = false;//different default for older documents + xAxis->setScaleData( aScaleData ); + } + } + + SetAxisTitle(); +} + +// ======================================== + +namespace +{ + +Reference< chart2::XAxis > lcl_getAxis( const Reference< chart2::XCoordinateSystem > xCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) +{ + Reference< chart2::XAxis > xAxis; + try + { + xAxis = xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ); + } + catch( uno::Exception & ) + { + } + return xAxis; +} + +} // anonymous namespace + +void SchXMLAxisContext::CorrectAxisPositions( const Reference< chart2::XChartDocument >& xNewDoc, + const OUString& rChartTypeServiceName, + const OUString& rODFVersionOfFile, + bool bAxisPositionAttributeImported ) +{ + if( ( !rODFVersionOfFile.getLength() || rODFVersionOfFile.equalsAscii("1.0") + || rODFVersionOfFile.equalsAscii("1.1") + || ( rODFVersionOfFile.equalsAscii("1.2") && !bAxisPositionAttributeImported ) ) ) + { + try + { + Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xNewDoc->getFirstDiagram(), uno::UNO_QUERY_THROW ); + uno::Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems()); + if( aCooSysSeq.getLength() ) + { + Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[0] ); + if( xCooSys.is() ) + { + Reference< chart2::XAxis > xMainXAxis = lcl_getAxis( xCooSys, 0, 0 ); + Reference< chart2::XAxis > xMainYAxis = lcl_getAxis( xCooSys, 1, 0 ); + //Reference< chart2::XAxis > xMajorZAxis = lcl_getAxis( xCooSys, 2, 0 ); + Reference< chart2::XAxis > xSecondaryXAxis = lcl_getAxis( xCooSys, 0, 1 ); + Reference< chart2::XAxis > xSecondaryYAxis = lcl_getAxis( xCooSys, 1, 1 ); + + Reference< beans::XPropertySet > xMainXAxisProp( xMainXAxis, uno::UNO_QUERY ); + Reference< beans::XPropertySet > xMainYAxisProp( xMainYAxis, uno::UNO_QUERY ); + Reference< beans::XPropertySet > xSecondaryXAxisProp( xSecondaryXAxis, uno::UNO_QUERY ); + Reference< beans::XPropertySet > xSecondaryYAxisProp( xSecondaryYAxis, uno::UNO_QUERY ); + + if( xMainXAxisProp.is() && xMainYAxisProp.is() ) + { + chart2::ScaleData aMainXScale = xMainXAxis->getScaleData(); + if( 0 == rChartTypeServiceName.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ScatterChartType" ) ) ) + { + xMainYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_VALUE) ); + double fCrossoverValue = 0.0; + aMainXScale.Origin >>= fCrossoverValue; + xMainYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverValue") + , uno::makeAny( fCrossoverValue ) ); + + if( aMainXScale.Orientation == chart2::AxisOrientation_REVERSE ) + { + xMainYAxisProp->setPropertyValue( OUString::createFromAscii("LabelPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END) ); + xMainYAxisProp->setPropertyValue( OUString::createFromAscii("MarkPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) ); + if( xSecondaryYAxisProp.is() ) + xSecondaryYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) ); + } + else + { + xMainYAxisProp->setPropertyValue( OUString::createFromAscii("LabelPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START) ); + xMainYAxisProp->setPropertyValue( OUString::createFromAscii("MarkPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) ); + if( xSecondaryYAxisProp.is() ) + xSecondaryYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) ); + } + } + else + { + if( aMainXScale.Orientation == chart2::AxisOrientation_REVERSE ) + { + xMainYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) ); + if( xSecondaryYAxisProp.is() ) + xSecondaryYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) ); + } + else + { + xMainYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) ); + if( xSecondaryYAxisProp.is() ) + xSecondaryYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) ); + } + } + + chart2::ScaleData aMainYScale = xMainYAxis->getScaleData(); + xMainXAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_VALUE) ); + double fCrossoverValue = 0.0; + aMainYScale.Origin >>= fCrossoverValue; + xMainXAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverValue") + , uno::makeAny( fCrossoverValue ) ); + + if( aMainYScale.Orientation == chart2::AxisOrientation_REVERSE ) + { + xMainXAxisProp->setPropertyValue( OUString::createFromAscii("LabelPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END) ); + xMainXAxisProp->setPropertyValue( OUString::createFromAscii("MarkPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) ); + if( xSecondaryXAxisProp.is() ) + xSecondaryXAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) ); + } + else + { + xMainXAxisProp->setPropertyValue( OUString::createFromAscii("LabelPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START) ); + xMainXAxisProp->setPropertyValue( OUString::createFromAscii("MarkPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) ); + if( xSecondaryXAxisProp.is() ) + xSecondaryXAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition") + , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) ); + } + } + } + } + } + catch( uno::Exception & ) + { + } + } +} + +// ======================================== + +SchXMLCategoriesContext::SchXMLCategoriesContext( + SchXMLImportHelper& rImpHelper, + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + OUString& rAddress ) : + SvXMLImportContext( rImport, nPrefix, rLocalName ), + m_rImportHelper( rImpHelper ), + mrAddress( rAddress ) +{ +} + +SchXMLCategoriesContext::~SchXMLCategoriesContext() +{ +} + +void SchXMLCategoriesContext::StartElement( const Reference< xml::sax::XAttributeList >& xAttrList ) +{ + sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; + + for( sal_Int16 i = 0; i < nAttrCount; i++ ) + { + OUString sAttrName = xAttrList->getNameByIndex( i ); + OUString aLocalName; + sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + if( nPrefix == XML_NAMESPACE_TABLE && + IsXMLToken( aLocalName, XML_CELL_RANGE_ADDRESS ) ) + { + Reference< chart2::XChartDocument > xNewDoc( GetImport().GetModel(), uno::UNO_QUERY ); + mrAddress = xAttrList->getValueByIndex( i ); + } + } +} + +// ======================================== + +DateScaleContext::DateScaleContext( + SchXMLImportHelper& rImpHelper, + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference< beans::XPropertySet > xAxisProps ) : + SvXMLImportContext( rImport, nPrefix, rLocalName ), + m_rImportHelper( rImpHelper ), + m_xAxisProps( xAxisProps ) +{ +} + +DateScaleContext::~DateScaleContext() +{ +} + +namespace +{ +enum DateScaleAttributeTokens +{ + XML_TOK_DATESCALE_BASE_TIME_UNIT, + XML_TOK_DATESCALE_MAJOR_INTERVAL_VALUE, + XML_TOK_DATESCALE_MAJOR_INTERVAL_UNIT, + XML_TOK_DATESCALE_MINOR_INTERVAL_VALUE, + XML_TOK_DATESCALE_MINOR_INTERVAL_UNIT +}; + +SvXMLTokenMapEntry aDateScaleAttributeTokenMap[] = +{ + { XML_NAMESPACE_CHART, XML_BASE_TIME_UNIT, XML_TOK_DATESCALE_BASE_TIME_UNIT }, + { XML_NAMESPACE_CHART, XML_MAJOR_INTERVAL_VALUE, XML_TOK_DATESCALE_MAJOR_INTERVAL_VALUE }, + { XML_NAMESPACE_CHART, XML_MAJOR_INTERVAL_UNIT, XML_TOK_DATESCALE_MAJOR_INTERVAL_UNIT }, + { XML_NAMESPACE_CHART, XML_MINOR_INTERVAL_VALUE, XML_TOK_DATESCALE_MINOR_INTERVAL_VALUE }, + { XML_NAMESPACE_CHART, XML_MINOR_INTERVAL_UNIT, XML_TOK_DATESCALE_MINOR_INTERVAL_UNIT }, + XML_TOKEN_MAP_END +}; + +class DateScaleAttributeTokenMap : public SvXMLTokenMap +{ +public: + DateScaleAttributeTokenMap(): SvXMLTokenMap( aDateScaleAttributeTokenMap ) {} + virtual ~DateScaleAttributeTokenMap() {} +}; + +struct theDateScaleAttributeTokenMap : public rtl::Static< DateScaleAttributeTokenMap, theDateScaleAttributeTokenMap > {}; + +sal_Int32 lcl_getTimeUnit( const OUString& rValue ) +{ + sal_Int32 nTimeUnit = ::com::sun::star::chart::TimeUnit::DAY; + if( IsXMLToken( rValue, XML_DAYS ) ) + nTimeUnit = ::com::sun::star::chart::TimeUnit::DAY; + else if( IsXMLToken( rValue, XML_MONTHS ) ) + nTimeUnit = ::com::sun::star::chart::TimeUnit::MONTH; + else if( IsXMLToken( rValue, XML_YEARS ) ) + nTimeUnit = ::com::sun::star::chart::TimeUnit::YEAR; + return nTimeUnit; +} + +} + +void DateScaleContext::StartElement( const Reference< xml::sax::XAttributeList >& xAttrList ) +{ + if( !m_xAxisProps.is() ) + return; + + // parse attributes + sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; + const SvXMLTokenMap& rAttrTokenMap = theDateScaleAttributeTokenMap::get(); + + bool bSetNewIncrement=false; + chart::TimeIncrement aIncrement; + m_xAxisProps->getPropertyValue( OUString::createFromAscii( "TimeIncrement" )) >>= aIncrement; + + for( sal_Int16 i = 0; i < nAttrCount; i++ ) + { + OUString sAttrName = xAttrList->getNameByIndex( i ); + OUString aLocalName; + OUString aValue = xAttrList->getValueByIndex( i ); + sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); + + switch( rAttrTokenMap.Get( nPrefix, aLocalName )) + { + case XML_TOK_DATESCALE_BASE_TIME_UNIT: + { + aIncrement.TimeResolution = uno::makeAny( lcl_getTimeUnit(aValue) ); + bSetNewIncrement = true; + } + break; + case XML_TOK_DATESCALE_MAJOR_INTERVAL_VALUE: + { + chart::TimeInterval aInterval(1,0); + aIncrement.MajorTimeInterval >>= aInterval; + SvXMLUnitConverter::convertNumber( aInterval.Number, aValue ); + aIncrement.MajorTimeInterval = uno::makeAny(aInterval); + bSetNewIncrement = true; + } + break; + case XML_TOK_DATESCALE_MAJOR_INTERVAL_UNIT: + { + chart::TimeInterval aInterval(1,0); + aIncrement.MajorTimeInterval >>= aInterval; + aInterval.TimeUnit = lcl_getTimeUnit(aValue); + aIncrement.MajorTimeInterval = uno::makeAny(aInterval); + bSetNewIncrement = true; + } + break; + case XML_TOK_DATESCALE_MINOR_INTERVAL_VALUE: + { + chart::TimeInterval aInterval(1,0); + aIncrement.MinorTimeInterval >>= aInterval; + SvXMLUnitConverter::convertNumber( aInterval.Number, aValue ); + aIncrement.MinorTimeInterval = uno::makeAny(aInterval); + bSetNewIncrement = true; + } + break; + case XML_TOK_DATESCALE_MINOR_INTERVAL_UNIT: + { + chart::TimeInterval aInterval(1,0); + aIncrement.MinorTimeInterval >>= aInterval; + aInterval.TimeUnit = lcl_getTimeUnit(aValue); + aIncrement.MinorTimeInterval = uno::makeAny(aInterval); + bSetNewIncrement = true; + } + break; + } + } + + if( bSetNewIncrement ) + m_xAxisProps->setPropertyValue( OUString::createFromAscii( "TimeIncrement" ), uno::makeAny( aIncrement ) ); +} + +// ======================================== |