/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmloff.hxx" #include "SchXMLPlotAreaContext.hxx" #include "SchXMLImport.hxx" #include "SchXMLAxisContext.hxx" #include "SchXMLSeries2Context.hxx" #include "SchXMLTools.hxx" #include #ifdef DBG_UTIL #include #endif #include #include "xmloff/xmlnmspe.hxx" #include #include #include #include #include #include "xexptran.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star; using namespace ::xmloff::token; using ::rtl::OUString; using com::sun::star::uno::Reference; namespace { struct lcl_AxisHasCategories : public ::std::unary_function< SchXMLAxis, bool > { bool operator() ( const SchXMLAxis & rAxis ) { return rAxis.bHasCategories; } }; OUString lcl_ConvertRange( const ::rtl::OUString & rRange, const uno::Reference< chart2::XChartDocument > & xDoc ) { OUString aResult = rRange; if(!xDoc.is()) return aResult; uno::Reference< chart2::data::XRangeXMLConversion > xConversion( xDoc->getDataProvider(), uno::UNO_QUERY ); if( xConversion.is()) aResult = xConversion->convertRangeFromXML( rRange ); return aResult; } } // anonymous namespace SchXML3DSceneAttributesHelper::SchXML3DSceneAttributesHelper( SvXMLImport& rImporter ) : SdXML3DSceneAttributesHelper( rImporter ) { } void SchXML3DSceneAttributesHelper::getCameraDefaultFromDiagram( const uno::Reference< chart::XDiagram >& xDiagram ) { //different defaults for camera geometry necessary to workaround wrong behaviour in old chart //in future make this version dependent if we have versioning (metastream) for ole objects try { uno::Reference< beans::XPropertySet > xProp( xDiagram, uno::UNO_QUERY ); if( xProp.is() ) { drawing::CameraGeometry aCamGeo; xProp->getPropertyValue( ::rtl::OUString::createFromAscii("D3DCameraGeometry")) >>= aCamGeo; maVRP.setX( aCamGeo.vrp.PositionX ); maVRP.setY( aCamGeo.vrp.PositionY ); maVRP.setZ( aCamGeo.vrp.PositionZ ); maVPN.setX( aCamGeo.vpn.DirectionX ); maVPN.setY( aCamGeo.vpn.DirectionY ); maVPN.setZ( aCamGeo.vpn.DirectionZ ); maVUP.setX( aCamGeo.vup.DirectionX ); maVUP.setY( aCamGeo.vup.DirectionY ); maVUP.setZ( aCamGeo.vup.DirectionZ ); } } catch( uno::Exception & rEx ) { #ifdef DBG_UTIL String aStr( rEx.Message ); ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US ); DBG_ERROR1( "Exception caught for property NumberOfLines: %s", aBStr.GetBuffer()); #else (void)rEx; // avoid warning for pro build #endif } } SchXML3DSceneAttributesHelper::~SchXML3DSceneAttributesHelper() { } SchXMLPlotAreaContext::SchXMLPlotAreaContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, const rtl::OUString& rLocalName, const rtl::OUString& rXLinkHRefAttributeToIndicateDataProvider, uno::Sequence< chart::ChartSeriesAddress >& rSeriesAddresses, ::rtl::OUString& rCategoriesAddress, ::rtl::OUString& rChartAddress, bool& rbHasRangeAtPlotArea, sal_Bool & rAllRangeAddressesAvailable, sal_Bool & rColHasLabels, sal_Bool & rRowHasLabels, chart::ChartDataRowSource & rDataRowSource, SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles, const ::rtl::OUString& aChartTypeServiceName, tSchXMLLSequencesPerIndex & rLSequencesPerIndex, const awt::Size & rChartSize ) : SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ), mrImportHelper( rImpHelper ), mrSeriesAddresses( rSeriesAddresses ), mrCategoriesAddress( rCategoriesAddress ), mrSeriesDefaultsAndStyles( rSeriesDefaultsAndStyles ), mnNumOfLinesProp( 0 ), mbStockHasVolume( sal_False ), mnSeries( 0 ), m_aGlobalSeriesImportInfo( rAllRangeAddressesAvailable ), maSceneImportHelper( rImport ), m_aOuterPositioning( rImport ), m_aInnerPositioning( rImport ), mbPercentStacked(false), m_bAxisPositionAttributeImported(false), m_rXLinkHRefAttributeToIndicateDataProvider(rXLinkHRefAttributeToIndicateDataProvider), mrChartAddress( rChartAddress ), m_rbHasRangeAtPlotArea( rbHasRangeAtPlotArea ), mrColHasLabels( rColHasLabels ), mrRowHasLabels( rRowHasLabels ), mrDataRowSource( rDataRowSource ), maChartTypeServiceName( aChartTypeServiceName ), mrLSequencesPerIndex( rLSequencesPerIndex ), mbGlobalChartTypeUsedBySeries( false ), maChartSize( rChartSize ) { m_rbHasRangeAtPlotArea = false; // get Diagram uno::Reference< chart::XChartDocument > xDoc( rImpHelper.GetChartDocument(), uno::UNO_QUERY ); if( xDoc.is()) { mxDiagram = xDoc->getDiagram(); mxNewDoc.set( xDoc, uno::UNO_QUERY ); maSceneImportHelper.getCameraDefaultFromDiagram( mxDiagram ); } DBG_ASSERT( mxDiagram.is(), "Couldn't get XDiagram" ); // turn off all axes initially uno::Any aFalseBool; aFalseBool <<= (sal_Bool)(sal_False); uno::Reference< lang::XServiceInfo > xInfo( mxDiagram, uno::UNO_QUERY ); uno::Reference< beans::XPropertySet > xProp( mxDiagram, uno::UNO_QUERY ); if( xInfo.is() && xProp.is()) { try { xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasXAxis" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasXAxisGrid" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasXAxisDescription" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasSecondaryXAxis" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasSecondaryXAxisDescription" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasYAxis" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasYAxisGrid" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasYAxisDescription" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasSecondaryYAxis" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasSecondaryYAxisDescription" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasZAxis" ), aFalseBool ); xProp->setPropertyValue( rtl::OUString::createFromAscii( "HasZAxisDescription" ), aFalseBool ); uno::Any aAny; chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS; aAny <<= eSource; xProp->setPropertyValue( rtl::OUString::createFromAscii( "DataRowSource" ), aAny ); } catch( beans::UnknownPropertyException & ) { DBG_ERROR( "Property required by service not supported" ); } } } SchXMLPlotAreaContext::~SchXMLPlotAreaContext() {} void SchXMLPlotAreaContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { // parse attributes sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetPlotAreaAttrTokenMap(); uno::Reference< chart2::XChartDocument > xNewDoc( GetImport().GetModel(), uno::UNO_QUERY ); for( sal_Int16 i = 0; i < nAttrCount; i++ ) { rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); rtl::OUString aLocalName; rtl::OUString aValue = xAttrList->getValueByIndex( i ); sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); switch( rAttrTokenMap.Get( nPrefix, aLocalName )) { case XML_TOK_PA_X: case XML_TOK_PA_Y: case XML_TOK_PA_WIDTH: case XML_TOK_PA_HEIGHT: m_aOuterPositioning.readPositioningAttribute( nPrefix, aLocalName, aValue ); break; case XML_TOK_PA_STYLE_NAME: msAutoStyleName = aValue; break; case XML_TOK_PA_CHART_ADDRESS: mrChartAddress = lcl_ConvertRange( aValue, xNewDoc ); // indicator for getting data from the outside m_rbHasRangeAtPlotArea = true; break; case XML_TOK_PA_DS_HAS_LABELS: { if( aValue.equals( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_BOTH ))) mrColHasLabels = mrRowHasLabels = sal_True; else if( aValue.equals( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_ROW ))) mrRowHasLabels = sal_True; else if( aValue.equals( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_COLUMN ))) mrColHasLabels = sal_True; } break; case XML_TOK_PA_TRANSFORM: case XML_TOK_PA_VRP: case XML_TOK_PA_VPN: case XML_TOK_PA_VUP: case XML_TOK_PA_PROJECTION: case XML_TOK_PA_DISTANCE: case XML_TOK_PA_FOCAL_LENGTH: case XML_TOK_PA_SHADOW_SLANT: case XML_TOK_PA_SHADE_MODE: case XML_TOK_PA_AMBIENT_COLOR: case XML_TOK_PA_LIGHTING_MODE: maSceneImportHelper.processSceneAttribute( nPrefix, aLocalName, aValue ); break; } } if( ! mxNewDoc.is()) { uno::Reference< beans::XPropertySet > xDocProp( mrImportHelper.GetChartDocument(), uno::UNO_QUERY ); if( xDocProp.is()) { try { uno::Any aAny; aAny <<= (sal_Bool)(mrColHasLabels); xDocProp->setPropertyValue( ::rtl::OUString::createFromAscii( "DataSourceLabelsInFirstColumn" ), aAny ); aAny <<= (sal_Bool)(mrRowHasLabels); xDocProp->setPropertyValue( ::rtl::OUString::createFromAscii( "DataSourceLabelsInFirstRow" ), aAny ); } catch( beans::UnknownPropertyException & ) { DBG_ERRORFILE( "Properties missing" ); } } } // set properties uno::Reference< beans::XPropertySet > xProp( mxDiagram, uno::UNO_QUERY ); if( msAutoStyleName.getLength()) { if( xProp.is()) { const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext(); if( pStylesCtxt ) { const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext( mrImportHelper.GetChartFamilyID(), msAutoStyleName ); XMLPropStyleContext* pPropStyleContext = const_cast< XMLPropStyleContext * >( dynamic_cast< const XMLPropStyleContext * >( pStyle ) ); if( pPropStyleContext ) { pPropStyleContext->FillPropertySet( xProp ); // get the data row source that was set without having data xProp->getPropertyValue( ::rtl::OUString::createFromAscii("DataRowSource")) >>= mrDataRowSource; //lines on/off //this old property is not supported fully anymore with the new chart, so we need to get the information a little bit different from similar properties mrSeriesDefaultsAndStyles.maLinesOnProperty = SchXMLTools::getPropertyFromContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Lines")), pPropStyleContext, pStylesCtxt ); //handle automatic position and size m_aOuterPositioning.readAutomaticPositioningProperties( pPropStyleContext, pStylesCtxt ); //correct default starting angle for old 3D pies if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan3_0( GetImport().GetModel() ) ) { bool bIs3d = false; if( xProp.is() && ( xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Dim3D"))) >>= bIs3d ) && bIs3d ) { if( maChartTypeServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.PieChartType" )) || maChartTypeServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.DonutChartType" )) ) { ::rtl::OUString aPropName( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartingAngle")) ); uno::Any aAStartingAngle( SchXMLTools::getPropertyFromContext( aPropName, pPropStyleContext, pStylesCtxt ) ); if( !aAStartingAngle.hasValue() ) xProp->setPropertyValue( aPropName, uno::makeAny(sal_Int32(0)) ) ; } } } } } } } //remember default values for dataseries if(xProp.is()) try { mrSeriesDefaultsAndStyles.maSymbolTypeDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolType"))); mrSeriesDefaultsAndStyles.maDataCaptionDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataCaption"))); mrSeriesDefaultsAndStyles.maErrorIndicatorDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ErrorIndicator"))); mrSeriesDefaultsAndStyles.maErrorCategoryDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ErrorCategory"))); mrSeriesDefaultsAndStyles.maConstantErrorLowDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ConstantErrorLow"))); mrSeriesDefaultsAndStyles.maConstantErrorHighDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ConstantErrorHigh"))); mrSeriesDefaultsAndStyles.maPercentageErrorDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PercentageError"))); mrSeriesDefaultsAndStyles.maErrorMarginDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ErrorMargin"))); mrSeriesDefaultsAndStyles.maMeanValueDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MeanValue"))); mrSeriesDefaultsAndStyles.maRegressionCurvesDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RegressionCurves"))); bool bStacked = false; mrSeriesDefaultsAndStyles.maStackedDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Stacked"))); mrSeriesDefaultsAndStyles.maStackedDefault >>= bStacked; mrSeriesDefaultsAndStyles.maPercentDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Percent"))); mrSeriesDefaultsAndStyles.maPercentDefault >>= mbPercentStacked; mrSeriesDefaultsAndStyles.maStackedBarsConnectedDefault = xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StackedBarsConnected"))); // deep uno::Any aDeepProperty( xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Deep")))); // #124488# old versions store a 3d area and 3D line deep chart with Deep==false => workaround for this if( ! (bStacked || mbPercentStacked )) { if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) ) { bool bIs3d = false; if( ( xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Dim3D"))) >>= bIs3d ) && bIs3d ) { if( maChartTypeServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.AreaChartType" )) || maChartTypeServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.LineChartType" )) ) { aDeepProperty <<= uno::makeAny( true ); } } } } mrSeriesDefaultsAndStyles.maDeepDefault = aDeepProperty; xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberOfLines"))) >>= mnNumOfLinesProp; xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Volume"))) >>= mbStockHasVolume; } catch( uno::Exception & rEx ) { #ifdef DBG_UTIL String aStr( rEx.Message ); ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US ); DBG_ERROR1( "PlotAreaContext:EndElement(): Exception caught: %s", aBStr.GetBuffer()); #else (void)rEx; // avoid warning for pro build #endif } // bool bCreateInternalDataProvider = false; if( m_rXLinkHRefAttributeToIndicateDataProvider.equalsAscii( "." ) ) //data comes from the chart itself bCreateInternalDataProvider = true; else if( m_rXLinkHRefAttributeToIndicateDataProvider.equalsAscii( ".." ) ) //data comes from the parent application bCreateInternalDataProvider = false; else if( m_rXLinkHRefAttributeToIndicateDataProvider.getLength() ) //not supported so far to get the data by sibling objects -> fall back to chart itself bCreateInternalDataProvider = true; else if( !m_rbHasRangeAtPlotArea ) bCreateInternalDataProvider = true; if( bCreateInternalDataProvider && mxNewDoc.is() ) { // we have no complete range => we have own data, so switch the data // provider to internal. Clone is not necessary, as we don't have any // data yet. mxNewDoc->createInternalDataProvider( false /* bCloneExistingData */ ); if( xProp.is() && mrDataRowSource!=chart::ChartDataRowSource_COLUMNS ) xProp->setPropertyValue( rtl::OUString::createFromAscii( "DataRowSource" ), uno::makeAny(mrDataRowSource) ); } } SvXMLImportContext* SchXMLPlotAreaContext::CreateChildContext( sal_uInt16 nPrefix, const rtl::OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { SvXMLImportContext* pContext = 0; const SvXMLTokenMap& rTokenMap = mrImportHelper.GetPlotAreaElemTokenMap(); switch( rTokenMap.Get( nPrefix, rLocalName )) { case XML_TOK_PA_COORDINATE_REGION_EXT: case XML_TOK_PA_COORDINATE_REGION: { pContext = new SchXMLCoordinateRegionContext( GetImport(), nPrefix, rLocalName, m_aInnerPositioning ); } break; case XML_TOK_PA_AXIS: { bool bAddMissingXAxisForNetCharts = false; bool bAdaptWrongPercentScaleValues = false; if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) ) { //correct errors from older versions // for NetCharts there were no xAxis exported to older files // so we need to add the x axis here for those old NetChart files if( maChartTypeServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.NetChartType" )) ) bAddMissingXAxisForNetCharts = true; //Issue 59288 if( mbPercentStacked ) bAdaptWrongPercentScaleValues = true; } bool bAdaptXAxisOrientationForOld2DBarCharts = false; if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_4( GetImport().GetModel() ) ) { //issue74660 if( maChartTypeServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ColumnChartType" )) ) bAdaptXAxisOrientationForOld2DBarCharts = true; } pContext = new SchXMLAxisContext( mrImportHelper, GetImport(), rLocalName, mxDiagram, maAxes, mrCategoriesAddress, bAddMissingXAxisForNetCharts, bAdaptWrongPercentScaleValues, bAdaptXAxisOrientationForOld2DBarCharts, m_bAxisPositionAttributeImported ); } break; case XML_TOK_PA_SERIES: { if( mxNewDoc.is()) { pContext = new SchXMLSeries2Context( mrImportHelper, GetImport(), rLocalName, mxNewDoc, maAxes, mrSeriesDefaultsAndStyles.maSeriesStyleList, mnSeries, mbStockHasVolume, m_aGlobalSeriesImportInfo, maChartTypeServiceName, mrLSequencesPerIndex, mbGlobalChartTypeUsedBySeries, maChartSize ); } mnSeries++; } break; case XML_TOK_PA_WALL: pContext = new SchXMLWallFloorContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram, SchXMLWallFloorContext::CONTEXT_TYPE_WALL ); break; case XML_TOK_PA_FLOOR: pContext = new SchXMLWallFloorContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram, SchXMLWallFloorContext::CONTEXT_TYPE_FLOOR ); break; case XML_TOK_PA_LIGHT_SOURCE: pContext = maSceneImportHelper.create3DLightContext( nPrefix, rLocalName, xAttrList ); break; // elements for stock charts case XML_TOK_PA_STOCK_GAIN: pContext = new SchXMLStockContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram, SchXMLStockContext::CONTEXT_TYPE_GAIN ); break; case XML_TOK_PA_STOCK_LOSS: pContext = new SchXMLStockContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram, SchXMLStockContext::CONTEXT_TYPE_LOSS ); break; case XML_TOK_PA_STOCK_RANGE: pContext = new SchXMLStockContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram, SchXMLStockContext::CONTEXT_TYPE_RANGE ); break; default: pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); } return pContext; } void SchXMLPlotAreaContext::EndElement() { // set categories if( mrCategoriesAddress.getLength() && mxNewDoc.is()) { uno::Reference< chart2::data::XDataProvider > xDataProvider( mxNewDoc->getDataProvider() ); // @todo: correct coordinate system index sal_Int32 nDimension( 0 ); ::std::vector< SchXMLAxis >::const_iterator aIt( ::std::find_if( maAxes.begin(), maAxes.end(), lcl_AxisHasCategories())); if( aIt != maAxes.end()) nDimension = static_cast< sal_Int32 >( (*aIt).eDimension ); SchXMLTools::CreateCategories( xDataProvider, mxNewDoc, mrCategoriesAddress, 0 /* nCooSysIndex */, nDimension, &mrLSequencesPerIndex ); } uno::Reference< beans::XPropertySet > xDiaProp( mxDiagram, uno::UNO_QUERY ); if( xDiaProp.is()) { sal_Bool bIsThreeDim = sal_False; uno::Any aAny = xDiaProp->getPropertyValue( ::rtl::OUString::createFromAscii( "Dim3D" )); aAny >>= bIsThreeDim; // set 3d scene attributes if( bIsThreeDim ) { // set scene attributes at diagram maSceneImportHelper.setSceneAttributes( xDiaProp ); } // set correct number of lines at series if( ! m_aGlobalSeriesImportInfo.rbAllRangeAddressesAvailable && mnNumOfLinesProp > 0 && maChartTypeServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ColumnChartType" ))) { try { xDiaProp->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NumberOfLines" )), uno::makeAny( mnNumOfLinesProp )); } catch( uno::Exception & rEx ) { #ifdef DBG_UTIL String aStr( rEx.Message ); ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US ); DBG_ERROR1( "Exception caught for property NumberOfLines: %s", aBStr.GetBuffer()); #else (void)rEx; // avoid warning for pro build #endif } } // #i32366# stock has volume if( ( 0 == mxDiagram->getDiagramType().reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.StockDiagram" ))) && mbStockHasVolume ) { try { xDiaProp->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Volume" )), uno::makeAny( true )); } catch( uno::Exception & rEx ) { #ifdef DBG_UTIL String aStr( rEx.Message ); ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US ); DBG_ERROR1( "Exception caught for property Volume: %s", aBStr.GetBuffer()); #else (void)rEx; // avoid warning for pro build #endif } } } // set changed size and position after properties (esp. 3d) uno::Reference< chart::XDiagramPositioning > xDiaPos( mxDiagram, uno::UNO_QUERY ); if( xDiaPos.is()) { if( !m_aOuterPositioning.isAutomatic() ) { if( m_aInnerPositioning.hasPosSize() ) xDiaPos->setDiagramPositionExcludingAxes( m_aInnerPositioning.getRectangle() ); else if( m_aOuterPositioning.hasPosSize() ) { if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan3_3( GetImport().GetModel() ) ) //old version of OOo did write a wrong rectangle for the diagram size xDiaPos->setDiagramPositionIncludingAxesAndAxisTitles( m_aOuterPositioning.getRectangle() ); else xDiaPos->setDiagramPositionIncludingAxes( m_aOuterPositioning.getRectangle() ); } } } SchXMLAxisContext::CorrectAxisPositions( uno::Reference< chart2::XChartDocument >( mrImportHelper.GetChartDocument(), uno::UNO_QUERY ), maChartTypeServiceName, GetImport().GetODFVersion(), m_bAxisPositionAttributeImported ); } // ======================================== SchXMLDataPointContext::SchXMLDataPointContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, const rtl::OUString& rLocalName, ::std::list< DataRowPointStyle >& rStyleList, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& xSeries, sal_Int32& rIndex, bool bSymbolSizeForSeriesIsMissingInFile ) : SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ), mrImportHelper( rImpHelper ), mrStyleList( rStyleList ), m_xSeries( xSeries ), mrIndex( rIndex ), mbSymbolSizeForSeriesIsMissingInFile( bSymbolSizeForSeriesIsMissingInFile ) { } SchXMLDataPointContext::~SchXMLDataPointContext() { } void SchXMLDataPointContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; ::rtl::OUString aValue; ::rtl::OUString sAutoStyleName; sal_Int32 nRepeat = 1; for( sal_Int16 i = 0; i < nAttrCount; i++ ) { rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); rtl::OUString aLocalName; sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); if( nPrefix == XML_NAMESPACE_CHART ) { if( IsXMLToken( aLocalName, XML_STYLE_NAME ) ) sAutoStyleName = xAttrList->getValueByIndex( i ); else if( IsXMLToken( aLocalName, XML_REPEATED ) ) nRepeat = xAttrList->getValueByIndex( i ).toInt32(); } } if( sAutoStyleName.getLength()) { DataRowPointStyle aStyle( DataRowPointStyle::DATA_POINT, m_xSeries, mrIndex, nRepeat, sAutoStyleName ); aStyle.mbSymbolSizeForSeriesIsMissingInFile = mbSymbolSizeForSeriesIsMissingInFile; mrStyleList.push_back( aStyle ); } mrIndex += nRepeat; } // ======================================== SchXMLPositonAttributesHelper::SchXMLPositonAttributesHelper( SvXMLImport& rImporter ) : m_rImport( rImporter ) , m_aPosition(0,0) , m_aSize(0,0) , m_bHasSizeWidth( false ) , m_bHasSizeHeight( false ) , m_bHasPositionX( false ) , m_bHasPositionY( false ) , m_bAutoSize( false ) , m_bAutoPosition( false ) { } SchXMLPositonAttributesHelper::~SchXMLPositonAttributesHelper() { } bool SchXMLPositonAttributesHelper::hasSize() const { return m_bHasSizeWidth && m_bHasSizeHeight; } bool SchXMLPositonAttributesHelper::hasPosition() const { return m_bHasPositionX && m_bHasPositionY; } bool SchXMLPositonAttributesHelper::hasPosSize() const { return hasPosition() && hasSize(); } bool SchXMLPositonAttributesHelper::isAutomatic() const { return m_bAutoSize || m_bAutoPosition; } awt::Point SchXMLPositonAttributesHelper::getPosition() const { return m_aPosition; } awt::Size SchXMLPositonAttributesHelper::getSize() const { return m_aSize; } awt::Rectangle SchXMLPositonAttributesHelper::getRectangle() const { return awt::Rectangle( m_aPosition.X, m_aPosition.Y, m_aSize.Width, m_aSize.Height ); } bool SchXMLPositonAttributesHelper::readPositioningAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue ) { //returns true if the attribute was proccessed bool bReturn = true; if( XML_NAMESPACE_SVG == nPrefix ) { if( IsXMLToken( rLocalName, XML_X ) ) { m_rImport.GetMM100UnitConverter().convertMeasure( m_aPosition.X, rValue ); m_bHasPositionX = true; } else if( IsXMLToken( rLocalName, XML_Y ) ) { m_rImport.GetMM100UnitConverter().convertMeasure( m_aPosition.Y, rValue ); m_bHasPositionY = true; } else if( IsXMLToken( rLocalName, XML_WIDTH ) ) { m_rImport.GetMM100UnitConverter().convertMeasure( m_aSize.Width, rValue ); m_bHasSizeWidth = true; } else if( IsXMLToken( rLocalName, XML_HEIGHT ) ) { m_rImport.GetMM100UnitConverter().convertMeasure( m_aSize.Height, rValue ); m_bHasSizeHeight = true; } else bReturn = false; } else bReturn = false; return bReturn; } void SchXMLPositonAttributesHelper::readAutomaticPositioningProperties( XMLPropStyleContext* pPropStyleContext, const SvXMLStylesContext* pStylesCtxt ) { if( pPropStyleContext && pStylesCtxt ) { //handle automatic position and size SchXMLTools::getPropertyFromContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutomaticSize")), pPropStyleContext, pStylesCtxt ) >>= m_bAutoSize; SchXMLTools::getPropertyFromContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutomaticPosition")), pPropStyleContext, pStylesCtxt ) >>= m_bAutoPosition; } } // ======================================== SchXMLCoordinateRegionContext::SchXMLCoordinateRegionContext( SvXMLImport& rImport , sal_uInt16 nPrefix , const rtl::OUString& rLocalName , SchXMLPositonAttributesHelper& rPositioning ) : SvXMLImportContext( rImport, nPrefix, rLocalName ) , m_rPositioning( rPositioning ) { } SchXMLCoordinateRegionContext::~SchXMLCoordinateRegionContext() { } void SchXMLCoordinateRegionContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { // parse attributes sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; for( sal_Int16 i = 0; i < nAttrCount; i++ ) { rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); rtl::OUString aLocalName; rtl::OUString aValue = xAttrList->getValueByIndex( i ); sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); m_rPositioning.readPositioningAttribute( nPrefix, aLocalName, aValue ); } } // ======================================== SchXMLWallFloorContext::SchXMLWallFloorContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, sal_uInt16 nPrefix, const rtl::OUString& rLocalName, uno::Reference< chart::XDiagram >& xDiagram, ContextType eContextType ) : SvXMLImportContext( rImport, nPrefix, rLocalName ), mrImportHelper( rImpHelper ), mxWallFloorSupplier( xDiagram, uno::UNO_QUERY ), meContextType( eContextType ) { } SchXMLWallFloorContext::~SchXMLWallFloorContext() { } void SchXMLWallFloorContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { if( mxWallFloorSupplier.is()) { sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; rtl::OUString sAutoStyleName; for( sal_Int16 i = 0; i < nAttrCount; i++ ) { rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); rtl::OUString aLocalName; sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); if( nPrefix == XML_NAMESPACE_CHART && IsXMLToken( aLocalName, XML_STYLE_NAME ) ) { sAutoStyleName = xAttrList->getValueByIndex( i ); } } // set properties uno::Reference< beans::XPropertySet > xProp( ( meContextType == CONTEXT_TYPE_WALL ) ? mxWallFloorSupplier->getWall() : mxWallFloorSupplier->getFloor(), uno::UNO_QUERY ); if( xProp.is()) { if( sAutoStyleName.getLength()) { const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext(); if( pStylesCtxt ) { const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext( mrImportHelper.GetChartFamilyID(), sAutoStyleName ); if( pStyle && pStyle->ISA( XMLPropStyleContext )) (( XMLPropStyleContext* )pStyle )->FillPropertySet( xProp ); } } } } } // ======================================== SchXMLStockContext::SchXMLStockContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, sal_uInt16 nPrefix, const rtl::OUString& rLocalName, uno::Reference< chart::XDiagram >& xDiagram, ContextType eContextType ) : SvXMLImportContext( rImport, nPrefix, rLocalName ), mrImportHelper( rImpHelper ), mxStockPropProvider( xDiagram, uno::UNO_QUERY ), meContextType( eContextType ) { } SchXMLStockContext::~SchXMLStockContext() { } void SchXMLStockContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { if( mxStockPropProvider.is()) { sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; rtl::OUString sAutoStyleName; for( sal_Int16 i = 0; i < nAttrCount; i++ ) { rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); rtl::OUString aLocalName; sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); if( nPrefix == XML_NAMESPACE_CHART && IsXMLToken( aLocalName, XML_STYLE_NAME ) ) { sAutoStyleName = xAttrList->getValueByIndex( i ); } } if( sAutoStyleName.getLength()) { // set properties uno::Reference< beans::XPropertySet > xProp; switch( meContextType ) { case CONTEXT_TYPE_GAIN: xProp = mxStockPropProvider->getUpBar(); break; case CONTEXT_TYPE_LOSS: xProp = mxStockPropProvider->getDownBar(); break; case CONTEXT_TYPE_RANGE: xProp = mxStockPropProvider->getMinMaxLine(); break; } if( xProp.is()) { const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext(); if( pStylesCtxt ) { const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext( mrImportHelper.GetChartFamilyID(), sAutoStyleName ); if( pStyle && pStyle->ISA( XMLPropStyleContext )) (( XMLPropStyleContext* )pStyle )->FillPropertySet( xProp ); } } } } } // ======================================== SchXMLStatisticsObjectContext::SchXMLStatisticsObjectContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, sal_uInt16 nPrefix, const rtl::OUString& rLocalName, ::std::list< DataRowPointStyle >& rStyleList, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& xSeries, ContextType eContextType, const awt::Size & rChartSize ) : SvXMLImportContext( rImport, nPrefix, rLocalName ), mrImportHelper( rImpHelper ), mrStyleList( rStyleList ), m_xSeries( xSeries ), meContextType( eContextType ), maChartSize( rChartSize ) {} SchXMLStatisticsObjectContext::~SchXMLStatisticsObjectContext() { } void SchXMLStatisticsObjectContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; ::rtl::OUString aValue; ::rtl::OUString sAutoStyleName; for( sal_Int16 i = 0; i < nAttrCount; i++ ) { rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); rtl::OUString aLocalName; sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); if( nPrefix == XML_NAMESPACE_CHART ) { if( IsXMLToken( aLocalName, XML_STYLE_NAME ) ) sAutoStyleName = xAttrList->getValueByIndex( i ); } } // note: regression-curves must get a style-object even if there is no // auto-style set, because they can contain an equation if( sAutoStyleName.getLength() || meContextType == CONTEXT_TYPE_REGRESSION_CURVE ) { DataRowPointStyle::StyleType eType = DataRowPointStyle::MEAN_VALUE; switch( meContextType ) { case CONTEXT_TYPE_MEAN_VALUE_LINE: eType = DataRowPointStyle::MEAN_VALUE; break; case CONTEXT_TYPE_REGRESSION_CURVE: eType = DataRowPointStyle::REGRESSION; break; case CONTEXT_TYPE_ERROR_INDICATOR: eType = DataRowPointStyle::ERROR_INDICATOR; break; } DataRowPointStyle aStyle( eType, m_xSeries, -1, 1, sAutoStyleName ); mrStyleList.push_back( aStyle ); } } SvXMLImportContext* SchXMLStatisticsObjectContext::CreateChildContext( sal_uInt16 nPrefix, const rtl::OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { SvXMLImportContext* pContext = 0; if( nPrefix == XML_NAMESPACE_CHART && IsXMLToken( rLocalName, XML_EQUATION ) ) { pContext = new SchXMLEquationContext( mrImportHelper, GetImport(), nPrefix, rLocalName, m_xSeries, maChartSize, mrStyleList.back()); } else { pContext = SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList ); } return pContext; } // ======================================== SchXMLEquationContext::SchXMLEquationContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport, sal_uInt16 nPrefix, const rtl::OUString& rLocalName, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& xSeries, const awt::Size & rChartSize, DataRowPointStyle & rRegressionStyle ) : SvXMLImportContext( rImport, nPrefix, rLocalName ), mrImportHelper( rImpHelper ), mrRegressionStyle( rRegressionStyle ), m_xSeries( xSeries ), maChartSize( rChartSize ) {} SchXMLEquationContext::~SchXMLEquationContext() {} void SchXMLEquationContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { // parse attributes sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; SchXMLImport& rImport = ( SchXMLImport& )GetImport(); const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetRegEquationAttrTokenMap(); OUString sAutoStyleName; sal_Bool bShowEquation = sal_True; sal_Bool bShowRSquare = sal_False; awt::Point aPosition; bool bHasXPos = false; bool bHasYPos = false; for( sal_Int16 i = 0; i < nAttrCount; i++ ) { rtl::OUString sAttrName = xAttrList->getNameByIndex( i ); rtl::OUString aLocalName; rtl::OUString aValue = xAttrList->getValueByIndex( i ); sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); switch( rAttrTokenMap.Get( nPrefix, aLocalName )) { case XML_TOK_REGEQ_POS_X: rImport.GetMM100UnitConverter().convertMeasure( aPosition.X, aValue ); bHasXPos = true; break; case XML_TOK_REGEQ_POS_Y: rImport.GetMM100UnitConverter().convertMeasure( aPosition.Y, aValue ); bHasYPos = true; break; case XML_TOK_REGEQ_DISPLAY_EQUATION: rImport.GetMM100UnitConverter().convertBool( bShowEquation, aValue ); break; case XML_TOK_REGEQ_DISPLAY_R_SQUARE: rImport.GetMM100UnitConverter().convertBool( bShowRSquare, aValue ); break; case XML_TOK_REGEQ_STYLE_NAME: sAutoStyleName = aValue; break; } } if( sAutoStyleName.getLength() || bShowEquation || bShowRSquare ) { uno::Reference< beans::XPropertySet > xEqProp; uno::Reference< lang::XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory(), uno::UNO_QUERY ); if( xFact.is()) xEqProp.set( xFact->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.RegressionEquation" ))), uno::UNO_QUERY ); if( xEqProp.is()) { if( sAutoStyleName.getLength() ) { const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext(); if( pStylesCtxt ) { const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext( mrImportHelper.GetChartFamilyID(), sAutoStyleName ); // note: SvXMLStyleContext::FillPropertySet is not const XMLPropStyleContext * pPropStyleContext = const_cast< XMLPropStyleContext * >( dynamic_cast< const XMLPropStyleContext * >( pStyle )); if( pPropStyleContext ) pPropStyleContext->FillPropertySet( xEqProp ); } } xEqProp->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("ShowEquation")), uno::makeAny( bShowEquation )); xEqProp->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("ShowCorrelationCoefficient")), uno::makeAny( bShowRSquare )); if( bHasXPos && bHasYPos ) { chart2::RelativePosition aRelPos; aRelPos.Primary = static_cast< double >( aPosition.X ) / static_cast< double >( maChartSize.Width ); aRelPos.Secondary = static_cast< double >( aPosition.Y ) / static_cast< double >( maChartSize.Height ); xEqProp->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "RelativePosition" )), uno::makeAny( aRelPos )); } OSL_ASSERT( mrRegressionStyle.meType == DataRowPointStyle::REGRESSION ); mrRegressionStyle.m_xEquationProperties.set( xEqProp ); } } }