LCOV - code coverage report
Current view: top level - xmloff/source/chart - SchXMLChartContext.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 309 575 53.7 %
Date: 2015-06-13 12:38:46 Functions: 15 28 53.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include "SchXMLChartContext.hxx"
      21             : #include "SchXMLImport.hxx"
      22             : #include "SchXMLLegendContext.hxx"
      23             : #include "SchXMLPlotAreaContext.hxx"
      24             : #include "SchXMLParagraphContext.hxx"
      25             : #include "SchXMLTableContext.hxx"
      26             : #include "SchXMLSeries2Context.hxx"
      27             : #include "SchXMLTools.hxx"
      28             : #include <osl/diagnose.h>
      29             : #include <unotools/mediadescriptor.hxx>
      30             : #include <xmloff/xmlnmspe.hxx>
      31             : #include <xmloff/xmlement.hxx>
      32             : #include <xmloff/xmltoken.hxx>
      33             : #include <xmloff/nmspmap.hxx>
      34             : #include <xmloff/xmluconv.hxx>
      35             : #include <xmloff/xmlstyle.hxx>
      36             : #include <xmloff/prstylei.hxx>
      37             : #include <xmloff/SchXMLSeriesHelper.hxx>
      38             : 
      39             : #include "vector"
      40             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      41             : #include <com/sun/star/chart/XChartDocument.hpp>
      42             : #include <com/sun/star/chart/XDiagram.hpp>
      43             : #include <com/sun/star/xml/sax/XAttributeList.hpp>
      44             : #include <com/sun/star/util/XStringMapping.hpp>
      45             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      46             : #include <com/sun/star/drawing/XDrawPage.hpp>
      47             : #include <com/sun/star/chart/ChartDataRowSource.hpp>
      48             : #include <com/sun/star/chart/ChartSeriesAddress.hpp>
      49             : #include <com/sun/star/awt/PosSize.hpp>
      50             : #include <com/sun/star/embed/Aspects.hpp>
      51             : #include <com/sun/star/embed/XVisualObject.hpp>
      52             : 
      53             : #include <com/sun/star/chart2/XChartDocument.hpp>
      54             : #include <com/sun/star/chart2/data/XDataSink.hpp>
      55             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      56             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      57             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      58             : #include <com/sun/star/chart2/XTitled.hpp>
      59             : 
      60             : using namespace com::sun::star;
      61             : using namespace ::xmloff::token;
      62             : using com::sun::star::uno::Reference;
      63             : using namespace ::SchXMLTools;
      64             : 
      65             : namespace
      66             : {
      67             : 
      68           0 : void lcl_setRoleAtLabeledSequence(
      69             :     const uno::Reference< chart2::data::XLabeledDataSequence > & xLSeq,
      70             :     const OUString &rRole )
      71             : {
      72             :     // set role of sequence
      73           0 :     uno::Reference< chart2::data::XDataSequence > xValues( xLSeq->getValues());
      74           0 :     if( xValues.is())
      75             :     {
      76           0 :         uno::Reference< beans::XPropertySet > xProp( xValues, uno::UNO_QUERY );
      77           0 :         if( xProp.is())
      78           0 :             xProp->setPropertyValue("Role", uno::makeAny( rRole ));
      79           0 :     }
      80           0 : }
      81             : 
      82           0 : void lcl_MoveDataToCandleStickSeries(
      83             :     const uno::Reference< chart2::data::XDataSource > & xDataSource,
      84             :     const uno::Reference< chart2::XDataSeries > & xDestination,
      85             :     const OUString & rRole )
      86             : {
      87             :     try
      88             :     {
      89             :         uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledSeq(
      90           0 :             xDataSource->getDataSequences());
      91           0 :         if( aLabeledSeq.getLength())
      92             :         {
      93           0 :             lcl_setRoleAtLabeledSequence( aLabeledSeq[0], rRole );
      94             : 
      95             :             // add to data series
      96           0 :             uno::Reference< chart2::data::XDataSource > xSource( xDestination, uno::UNO_QUERY_THROW );
      97             :             // @todo: realloc only once outside this function
      98           0 :             uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aData( xSource->getDataSequences());
      99           0 :             aData.realloc( aData.getLength() + 1);
     100           0 :             aData[ aData.getLength() - 1 ] = aLabeledSeq[0];
     101           0 :             uno::Reference< chart2::data::XDataSink > xSink( xDestination, uno::UNO_QUERY_THROW );
     102           0 :             xSink->setData( aData );
     103           0 :         }
     104             :     }
     105           0 :     catch(const uno::Exception&)
     106             :     {
     107             :         SAL_WARN("xmloff.chart", "Exception caught while moving data to candlestick series" );
     108             :     }
     109           0 : }
     110             : 
     111           0 : void lcl_setRoleAtFirstSequence(
     112             :     const uno::Reference< chart2::XDataSeries > & xSeries,
     113             :     const OUString & rRole )
     114             : {
     115           0 :     uno::Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
     116           0 :     if( xSource.is())
     117             :     {
     118           0 :         uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
     119           0 :         if( aSeq.getLength())
     120           0 :             lcl_setRoleAtLabeledSequence( aSeq[0], rRole );
     121           0 :     }
     122           0 : }
     123             : 
     124          86 : void lcl_removeEmptyChartTypeGroups( const uno::Reference< chart2::XChartDocument > & xDoc )
     125             : {
     126          86 :     if( ! xDoc.is())
     127           0 :         return;
     128             : 
     129          86 :     uno::Reference< chart2::XDiagram > xDia( xDoc->getFirstDiagram());
     130          86 :     if( ! xDia.is())
     131           0 :         return;
     132             : 
     133             :     try
     134             :     {
     135             :         // count all charttype groups to be able to leave at least one
     136          86 :         sal_Int32 nRemainingGroups = 0;
     137          86 :         uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDia, uno::UNO_QUERY_THROW );
     138             :         uno::Sequence< uno::Reference< chart2::XCoordinateSystem > >
     139         172 :             aCooSysSeq( xCooSysCnt->getCoordinateSystems());
     140         258 :         for( sal_Int32 nI = aCooSysSeq.getLength(); nI--; )
     141             :         {
     142          86 :             uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nI], uno::UNO_QUERY_THROW );
     143          86 :             nRemainingGroups += xCTCnt->getChartTypes().getLength();
     144          86 :         }
     145             : 
     146             :         // delete all empty groups, but leave at least  group (empty or not)
     147         176 :         for( sal_Int32 nI = aCooSysSeq.getLength(); nI-- && (nRemainingGroups > 1); )
     148             :         {
     149           4 :             uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nI], uno::UNO_QUERY_THROW );
     150           8 :             uno::Sequence< uno::Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
     151          16 :             for( sal_Int32 nJ=aCTSeq.getLength(); nJ-- && (nRemainingGroups > 1); )
     152             :             {
     153           8 :                 uno::Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nJ], uno::UNO_QUERY_THROW );
     154           8 :                 if( xDSCnt->getDataSeries().getLength() == 0 )
     155             :                 {
     156             :                     // note: iterator stays valid as we have a local sequence
     157           0 :                     xCTCnt->removeChartType( aCTSeq[nJ] );
     158           0 :                     --nRemainingGroups;
     159             :                 }
     160           8 :             }
     161          90 :         }
     162             :     }
     163           0 :     catch(const uno::Exception& ex)
     164             :     {
     165           0 :         OString aBStr(OUStringToOString(ex.Message, RTL_TEXTENCODING_ASCII_US));
     166           0 :         SAL_INFO("xmloff.chart", "Exception caught while removing empty chart types: " << aBStr);
     167          86 :     }
     168             : }
     169             : 
     170           0 : uno::Sequence< sal_Int32 > lcl_getNumberSequenceFromString( const OUString& rStr, bool bAddOneToEachOldIndex )
     171             : {
     172           0 :     const sal_Unicode aSpace( ' ' );
     173             : 
     174             :     // count number of entries
     175           0 :     ::std::vector< sal_Int32 > aVec;
     176           0 :     sal_Int32 nLastPos = 0;
     177           0 :     sal_Int32 nPos = 0;
     178           0 :     while( nPos != -1 )
     179             :     {
     180           0 :         nPos = rStr.indexOf( aSpace, nLastPos );
     181           0 :         if( nPos > nLastPos )
     182             :         {
     183           0 :             aVec.push_back( rStr.copy( nLastPos, (nPos - nLastPos) ).toInt32() );
     184             :         }
     185           0 :         if( nPos != -1 )
     186           0 :             nLastPos = nPos + 1;
     187             :     }
     188             :     // last entry
     189           0 :     if( nLastPos != 0 &&
     190           0 :         rStr.getLength() > nLastPos )
     191             :     {
     192           0 :         aVec.push_back( rStr.copy( nLastPos, (rStr.getLength() - nLastPos) ).toInt32() );
     193             :     }
     194             : 
     195           0 :     const sal_Int32 nVecSize = aVec.size();
     196           0 :     uno::Sequence< sal_Int32 > aSeq( nVecSize );
     197             : 
     198           0 :     if(!bAddOneToEachOldIndex)
     199             :     {
     200           0 :         sal_Int32* pSeqArr = aSeq.getArray();
     201           0 :         for( nPos = 0; nPos < nVecSize; ++nPos )
     202             :         {
     203           0 :             pSeqArr[ nPos ] = aVec[ nPos ];
     204             :         }
     205             :     }
     206           0 :     else if( bAddOneToEachOldIndex )
     207             :     {
     208           0 :         aSeq.realloc( nVecSize+1 );
     209           0 :         aSeq[0]=0;
     210             : 
     211           0 :         sal_Int32* pSeqArr = aSeq.getArray();
     212           0 :         for( nPos = 0; nPos < nVecSize; ++nPos )
     213             :         {
     214           0 :             pSeqArr[ nPos+1 ] = aVec[ nPos ]+1;
     215             :         }
     216             :     }
     217             : 
     218           0 :     return aSeq;
     219             : }
     220             : 
     221             : } // anonymous namespace
     222             : 
     223          86 : SchXMLChartContext::SchXMLChartContext( SchXMLImportHelper& rImpHelper,
     224             :                                         SvXMLImport& rImport, const OUString& rLocalName ) :
     225             :         SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
     226             :         mrImportHelper( rImpHelper ),
     227             :         m_bHasRangeAtPlotArea( false ),
     228             :         m_bHasTableElement( false ),
     229             :         mbAllRangeAddressesAvailable( true ),
     230             :         mbColHasLabels( false ),
     231             :         mbRowHasLabels( false ),
     232             :         meDataRowSource( chart::ChartDataRowSource_COLUMNS ),
     233          86 :         mbIsStockChart( false )
     234             : {
     235          86 : }
     236             : 
     237         172 : SchXMLChartContext::~SchXMLChartContext()
     238         172 : {}
     239             : 
     240          86 : void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
     241             : {
     242             :     // parse attributes
     243          86 :     sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
     244          86 :     const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetChartAttrTokenMap();
     245             : 
     246          86 :     uno::Reference< embed::XVisualObject > xVisualObject( mrImportHelper.GetChartDocument(), uno::UNO_QUERY);
     247             :     SAL_WARN_IF(!xVisualObject.is(), "xmloff.chart", "need xVisualObject for page size");
     248          86 :     if( xVisualObject.is() )
     249          86 :         maChartSize = xVisualObject->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ); //#i103460# take the size given from the parent frame as default
     250             : 
     251             :     // this flag is necessarry for pie charts in the core
     252          86 :     bool bSetSwitchData = false;
     253             : 
     254         172 :     OUString sAutoStyleName;
     255         172 :     OUString aOldChartTypeName;
     256          86 :     bool bHasAddin = false;
     257             : 
     258         595 :     for( sal_Int16 i = 0; i < nAttrCount; i++ )
     259             :     {
     260         509 :         OUString sAttrName = xAttrList->getNameByIndex( i );
     261        1018 :         OUString aLocalName;
     262        1018 :         OUString aValue = xAttrList->getValueByIndex( i );
     263         509 :         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
     264             : 
     265         509 :         switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
     266             :         {
     267             :             case XML_TOK_CHART_HREF:
     268          83 :                 m_aXLinkHRefAttributeToIndicateDataProvider = aValue;
     269          83 :                 break;
     270             : 
     271             :             case XML_TOK_CHART_CLASS:
     272             :                 {
     273          86 :                     OUString sClassName;
     274             :                     sal_uInt16 nClassPrefix =
     275          86 :                         GetImport().GetNamespaceMap().GetKeyByAttrName(
     276          86 :                                 aValue, &sClassName );
     277          86 :                     if( XML_NAMESPACE_CHART == nClassPrefix )
     278             :                     {
     279          86 :                         SchXMLChartTypeEnum eChartTypeEnum = SchXMLTools::GetChartTypeEnum( sClassName );
     280          86 :                         if( eChartTypeEnum != XML_CHART_CLASS_UNKNOWN )
     281             :                         {
     282          86 :                             aOldChartTypeName = SchXMLTools::GetChartTypeByClassName( sClassName, true /* bUseOldNames */ );
     283          86 :                             maChartTypeServiceName = SchXMLTools::GetChartTypeByClassName( sClassName, false /* bUseOldNames */ );
     284          86 :                             switch( eChartTypeEnum )
     285             :                             {
     286             :                             case XML_CHART_CLASS_CIRCLE:
     287           4 :                                 bSetSwitchData = true;
     288           4 :                                 break;
     289             :                             case XML_CHART_CLASS_STOCK:
     290           1 :                                 mbIsStockChart = true;
     291           1 :                                 break;
     292             :                             default:
     293          81 :                                 break;
     294             :                             }
     295             :                         }
     296             :                     }
     297           0 :                     else if( XML_NAMESPACE_OOO == nClassPrefix )
     298             :                     {
     299             :                         // service is taken from add-in-name attribute
     300           0 :                         bHasAddin = true;
     301             : 
     302           0 :                         aOldChartTypeName = sClassName;
     303           0 :                         maChartTypeServiceName = sClassName;
     304          86 :                     }
     305             :                 }
     306          86 :                 break;
     307             : 
     308             :             case XML_TOK_CHART_WIDTH:
     309          86 :                 GetImport().GetMM100UnitConverter().convertMeasureToCore(
     310         172 :                         maChartSize.Width, aValue );
     311          86 :                 break;
     312             : 
     313             :             case XML_TOK_CHART_HEIGHT:
     314          86 :                 GetImport().GetMM100UnitConverter().convertMeasureToCore(
     315         172 :                         maChartSize.Height, aValue );
     316          86 :                 break;
     317             : 
     318             :             case XML_TOK_CHART_STYLE_NAME:
     319          86 :                 sAutoStyleName = aValue;
     320          86 :                 break;
     321             : 
     322             :             case XML_TOK_CHART_COL_MAPPING:
     323           0 :                 msColTrans = aValue;
     324           0 :                 break;
     325             :             case XML_TOK_CHART_ROW_MAPPING:
     326           0 :                 msRowTrans = aValue;
     327           0 :                 break;
     328             :         }
     329         509 :     }
     330             : 
     331          86 :     if( aOldChartTypeName.isEmpty() )
     332             :     {
     333             :         SAL_WARN("xmloff.chart", "need a charttype to create a diagram" );
     334             :         //set a fallback value:
     335           0 :         OUString aChartClass_Bar( GetXMLToken(XML_BAR ) );
     336           0 :         aOldChartTypeName = SchXMLTools::GetChartTypeByClassName( aChartClass_Bar, true /* bUseOldNames */ );
     337           0 :         maChartTypeServiceName = SchXMLTools::GetChartTypeByClassName( aChartClass_Bar, false /* bUseOldNames */ );
     338             :     }
     339             : 
     340             :     //  Set the size of the draw page.
     341          86 :     if( xVisualObject.is() )
     342          86 :         xVisualObject->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, maChartSize );
     343             : 
     344          86 :     InitChart( aOldChartTypeName, bSetSwitchData);
     345             : 
     346          86 :     if( bHasAddin )
     347             :     {
     348             :         //correct charttype serveice name when having an addin
     349             :         //and don't refresh addin during load
     350           0 :         uno::Reference< beans::XPropertySet > xDocProp( mrImportHelper.GetChartDocument(), uno::UNO_QUERY );
     351           0 :         if( xDocProp.is() )
     352             :         {
     353             :             try
     354             :             {
     355           0 :                 xDocProp->getPropertyValue("BaseDiagram") >>= aOldChartTypeName;
     356           0 :                 maChartTypeServiceName =  SchXMLTools::GetNewChartTypeName( aOldChartTypeName );
     357           0 :                 xDocProp->setPropertyValue("RefreshAddInAllowed", uno::makeAny( sal_False) );
     358             :             }
     359           0 :             catch(const uno::Exception&)
     360             :             {
     361             :                 SAL_WARN("xmloff.chart", "Exception during import SchXMLChartContext::StartElement" );
     362             :             }
     363           0 :         }
     364             :     }
     365             : 
     366             :     // set auto-styles for Area
     367          86 :     uno::Reference< beans::XPropertySet > xProp( mrImportHelper.GetChartDocument()->getArea(), uno::UNO_QUERY );
     368          86 :     if( xProp.is())
     369             :     {
     370          86 :         const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
     371          86 :         if( pStylesCtxt )
     372             :         {
     373             :             const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
     374          86 :                 SchXMLImportHelper::GetChartFamilyID(), sAutoStyleName );
     375             : 
     376          86 :             if( pStyle && pStyle->ISA( XMLPropStyleContext ))
     377          86 :                 const_cast<XMLPropStyleContext*>( static_cast< const XMLPropStyleContext* >( pStyle ) )->FillPropertySet( xProp );
     378             :         }
     379         172 :     }
     380          86 : }
     381             : 
     382             : namespace
     383             : {
     384             : 
     385           0 : struct NewDonutSeries
     386             : {
     387             :     ::com::sun::star::uno::Reference<
     388             :                 ::com::sun::star::chart2::XDataSeries > m_xSeries;
     389             :     OUString msStyleName;
     390             :     sal_Int32 mnAttachedAxis;
     391             : 
     392             :     ::std::vector< OUString > m_aSeriesStyles;
     393             :     ::std::vector< OUString > m_aPointStyles;
     394             : 
     395           0 :     NewDonutSeries( const ::com::sun::star::uno::Reference<
     396             :                 ::com::sun::star::chart2::XDataSeries >& xSeries, sal_Int32 nPointCount )
     397             :                     : m_xSeries( xSeries )
     398           0 :                     , mnAttachedAxis( 1 )
     399             :     {
     400           0 :         m_aPointStyles.resize(nPointCount);
     401           0 :         m_aSeriesStyles.resize(nPointCount);
     402           0 :     }
     403             : 
     404           0 :     void setSeriesStyleNameToPoint( const OUString& rStyleName, sal_Int32 nPointIndex )
     405             :     {
     406             :         SAL_WARN_IF(nPointIndex >= static_cast<sal_Int32>(m_aSeriesStyles.size()), "xmloff.chart", "donut point <-> series count mismatch");
     407           0 :         if( nPointIndex < static_cast<sal_Int32>(m_aSeriesStyles.size()) )
     408           0 :             m_aSeriesStyles[nPointIndex]=rStyleName;
     409           0 :     }
     410             : 
     411           0 :     void setPointStyleNameToPoint( const OUString& rStyleName, sal_Int32 nPointIndex )
     412             :     {
     413             :         SAL_WARN_IF(nPointIndex >= static_cast<sal_Int32>(m_aPointStyles.size()), "xmloff.chart", "donut point <-> series count mismatch");
     414           0 :         if( nPointIndex < static_cast<sal_Int32>(m_aPointStyles.size()) )
     415           0 :             m_aPointStyles[nPointIndex]=rStyleName;
     416           0 :     }
     417             : 
     418           0 :     ::std::list< DataRowPointStyle > creatStyleList()
     419             :     {
     420           0 :         ::std::list< DataRowPointStyle > aRet;
     421             : 
     422             :         DataRowPointStyle aSeriesStyle( DataRowPointStyle::DATA_SERIES
     423           0 :             , m_xSeries, -1, 1, msStyleName, mnAttachedAxis );
     424           0 :         aRet.push_back( aSeriesStyle );
     425             : 
     426           0 :         sal_Int32 nPointIndex=0;
     427           0 :         ::std::vector< OUString >::iterator aPointIt( m_aPointStyles.begin() );
     428           0 :         ::std::vector< OUString >::iterator aPointEnd( m_aPointStyles.end() );
     429           0 :         while( aPointIt != aPointEnd )
     430             :         {
     431             :             DataRowPointStyle aPointStyle( DataRowPointStyle::DATA_POINT
     432           0 :                 , m_xSeries, nPointIndex, 1, *aPointIt, mnAttachedAxis );
     433           0 :             if( nPointIndex < static_cast<sal_Int32>(m_aSeriesStyles.size()) )
     434             :             {
     435           0 :                 aPointStyle.msSeriesStyleNameForDonuts = m_aSeriesStyles[nPointIndex];
     436             :             }
     437           0 :             if( !aPointStyle.msSeriesStyleNameForDonuts.isEmpty()
     438           0 :                 || !aPointStyle.msStyleName.isEmpty() )
     439           0 :                 aRet.push_back( aPointStyle );
     440           0 :             ++aPointIt;
     441           0 :             ++nPointIndex;
     442           0 :         }
     443             : 
     444           0 :         return aRet;
     445             :     }
     446             : };
     447             : 
     448           0 : void lcl_swapPointAndSeriesStylesForDonutCharts( ::std::list< DataRowPointStyle >& rStyleList
     449             :         , const ::std::map< ::com::sun::star::uno::Reference<
     450             :                 ::com::sun::star::chart2::XDataSeries> , sal_Int32 >& rSeriesMap )
     451             : {
     452           0 :     ::std::list< DataRowPointStyle >::iterator aIt(rStyleList.begin());
     453           0 :     ::std::list< DataRowPointStyle >::iterator aEnd(rStyleList.end());
     454             : 
     455             :     //detect old series count
     456             :     //and add old series to aSeriesMap
     457             :     ::std::map< ::com::sun::star::uno::Reference<
     458           0 :                 ::com::sun::star::chart2::XDataSeries >, sal_Int32 > aSeriesMap(rSeriesMap);
     459           0 :     sal_Int32 nOldSeriesCount = 0;
     460             :     {
     461           0 :         sal_Int32 nMaxOldSeriesIndex = 0;
     462           0 :         sal_Int32 nOldSeriesIndex = 0;
     463           0 :         for( aIt = rStyleList.begin(); aIt != aEnd; ++aIt )
     464             :         {
     465           0 :             DataRowPointStyle aStyle(*aIt);
     466           0 :             if(aStyle.meType == DataRowPointStyle::DATA_SERIES &&
     467           0 :                     aStyle.m_xSeries.is() )
     468             :             {
     469           0 :                 nMaxOldSeriesIndex = nOldSeriesIndex;
     470             : 
     471           0 :                 if( aSeriesMap.end() == aSeriesMap.find(aStyle.m_xSeries) )
     472           0 :                     aSeriesMap[aStyle.m_xSeries] = nOldSeriesIndex;
     473             : 
     474           0 :                 nOldSeriesIndex++;
     475             :             }
     476           0 :         }
     477           0 :         nOldSeriesCount = nMaxOldSeriesIndex+1;
     478             :     }
     479             : 
     480             :     //initialize new series styles
     481           0 :     ::std::map< Reference< chart2::XDataSeries >, sal_Int32 >::const_iterator aSeriesMapIt( aSeriesMap.begin() );
     482           0 :     ::std::map< Reference< chart2::XDataSeries >, sal_Int32 >::const_iterator aSeriesMapEnd( aSeriesMap.end() );
     483             : 
     484             :     //sort by index
     485           0 :     ::std::vector< NewDonutSeries > aNewSeriesVector;
     486             :     {
     487           0 :         ::std::map< sal_Int32, Reference< chart2::XDataSeries > > aIndexSeriesMap;
     488           0 :         for( ; aSeriesMapIt != aSeriesMapEnd; ++aSeriesMapIt )
     489           0 :             aIndexSeriesMap[aSeriesMapIt->second] = aSeriesMapIt->first;
     490             : 
     491           0 :         ::std::map< sal_Int32, Reference< chart2::XDataSeries > >::const_iterator aIndexIt( aIndexSeriesMap.begin() );
     492           0 :         ::std::map< sal_Int32, Reference< chart2::XDataSeries > >::const_iterator aIndexEnd( aIndexSeriesMap.end() );
     493             : 
     494           0 :         for( ; aIndexIt != aIndexEnd; ++aIndexIt )
     495           0 :             aNewSeriesVector.push_back( NewDonutSeries(aIndexIt->second,nOldSeriesCount) );
     496             :     }
     497             : 
     498             :     //overwrite attached axis information according to old series styles
     499           0 :     for( aIt = rStyleList.begin(); aIt != aEnd; ++aIt )
     500             :     {
     501           0 :         DataRowPointStyle aStyle(*aIt);
     502           0 :         if(aStyle.meType == DataRowPointStyle::DATA_SERIES )
     503             :         {
     504           0 :             aSeriesMapIt = aSeriesMap.find( aStyle.m_xSeries );
     505           0 :             if( aSeriesMapIt != aSeriesMapEnd && aSeriesMapIt->second < static_cast<sal_Int32>(aNewSeriesVector.size()) )
     506           0 :                 aNewSeriesVector[aSeriesMapIt->second].mnAttachedAxis = aStyle.mnAttachedAxis;
     507             :         }
     508           0 :     }
     509             : 
     510             :     //overwrite new series style names with old series style name information
     511           0 :     for( aIt = rStyleList.begin(); aIt != aEnd; ++aIt )
     512             :     {
     513           0 :         DataRowPointStyle aStyle(*aIt);
     514           0 :         if( aStyle.meType == DataRowPointStyle::DATA_SERIES )
     515             :         {
     516           0 :             aSeriesMapIt = aSeriesMap.find(aStyle.m_xSeries);
     517           0 :             if( aSeriesMapEnd != aSeriesMapIt )
     518             :             {
     519           0 :                 sal_Int32 nNewPointIndex = aSeriesMapIt->second;
     520             : 
     521           0 :                 ::std::vector< NewDonutSeries >::iterator aNewSeriesIt( aNewSeriesVector.begin() );
     522           0 :                 ::std::vector< NewDonutSeries >::iterator aNewSeriesEnd( aNewSeriesVector.end() );
     523             : 
     524           0 :                 for( ;aNewSeriesIt!=aNewSeriesEnd; ++aNewSeriesIt)
     525           0 :                     aNewSeriesIt->setSeriesStyleNameToPoint( aStyle.msStyleName, nNewPointIndex );
     526             :             }
     527             :         }
     528           0 :     }
     529             : 
     530             :     //overwrite new series style names with point style name information
     531           0 :     for( aIt = rStyleList.begin(); aIt != aEnd; ++aIt )
     532             :     {
     533           0 :         DataRowPointStyle aStyle(*aIt);
     534           0 :         if( aStyle.meType == DataRowPointStyle::DATA_POINT )
     535             :         {
     536           0 :             aSeriesMapIt = aSeriesMap.find(aStyle.m_xSeries);
     537           0 :             if( aSeriesMapEnd != aSeriesMapIt )
     538             :             {
     539           0 :                 sal_Int32 nNewPointIndex = aSeriesMapIt->second;
     540           0 :                 sal_Int32 nNewSeriesIndex = aStyle.m_nPointIndex;
     541           0 :                 sal_Int32 nRepeatCount = aStyle.m_nPointRepeat;
     542             : 
     543           0 :                 while( nRepeatCount && (nNewSeriesIndex>=0) && (nNewSeriesIndex< static_cast<sal_Int32>(aNewSeriesVector.size()) ) )
     544             :                 {
     545           0 :                     NewDonutSeries& rNewSeries( aNewSeriesVector[nNewSeriesIndex] );
     546           0 :                     rNewSeries.setPointStyleNameToPoint( aStyle.msStyleName, nNewPointIndex );
     547             : 
     548           0 :                     nRepeatCount--;
     549           0 :                     nNewSeriesIndex++;
     550             :                 }
     551             :             }
     552             :         }
     553           0 :     }
     554             : 
     555             :     //put information from aNewSeriesVector to output parameter rStyleList
     556           0 :     rStyleList.clear();
     557             : 
     558           0 :     ::std::vector< NewDonutSeries >::iterator aNewSeriesIt( aNewSeriesVector.begin() );
     559           0 :     ::std::vector< NewDonutSeries >::iterator aNewSeriesEnd( aNewSeriesVector.end() );
     560           0 :     for( ;aNewSeriesIt!=aNewSeriesEnd; ++aNewSeriesIt)
     561             :     {
     562           0 :         ::std::list< DataRowPointStyle > aList( aNewSeriesIt->creatStyleList() );
     563           0 :         rStyleList.insert(rStyleList.end(),aList.begin(),aList.end());
     564           0 :     }
     565           0 : }
     566             : 
     567         135 : bool lcl_SpecialHandlingForDonutChartNeeded(
     568             :     const OUString & rServiceName,
     569             :     const SvXMLImport & rImport )
     570             : {
     571         135 :     bool bResult = false;
     572         135 :     if( rServiceName == "com.sun.star.chart2.DonutChartType" )
     573             :     {
     574           4 :         bResult = SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( rImport.GetModel() );
     575             :     }
     576         135 :     return bResult;
     577             : }
     578             : 
     579             : } // anonymous namespace
     580             : 
     581           1 : static void lcl_ApplyDataFromRectangularRangeToDiagram(
     582             :         const uno::Reference< chart2::XChartDocument >& xNewDoc
     583             :         , const OUString& rRectangularRange
     584             :         , ::com::sun::star::chart::ChartDataRowSource eDataRowSource
     585             :         , bool bRowHasLabels, bool bColHasLabels
     586             :         , bool bSwitchOnLabelsAndCategoriesForOwnData
     587             :         , const OUString& sColTrans
     588             :         , const OUString& sRowTrans )
     589             : {
     590           1 :     if( !xNewDoc.is() )
     591           0 :         return;
     592             : 
     593           1 :     uno::Reference< chart2::XDiagram > xNewDia( xNewDoc->getFirstDiagram());
     594           2 :     uno::Reference< chart2::data::XDataProvider > xDataProvider( xNewDoc->getDataProvider() );
     595           1 :     if( !xNewDia.is() || !xDataProvider.is() )
     596           0 :         return;
     597             : 
     598             :     bool bFirstCellAsLabel =
     599           1 :         (eDataRowSource==chart::ChartDataRowSource_COLUMNS)? bRowHasLabels : bColHasLabels;
     600             :     bool bHasCateories =
     601           1 :         (eDataRowSource==chart::ChartDataRowSource_COLUMNS)? bColHasLabels : bRowHasLabels;
     602             : 
     603           1 :     if( bSwitchOnLabelsAndCategoriesForOwnData )
     604             :     {
     605           1 :         bFirstCellAsLabel = true;
     606           1 :         bHasCateories = true;
     607             :     }
     608             : 
     609           2 :     uno::Sequence< beans::PropertyValue > aArgs( 3 );
     610           2 :     aArgs[0] = beans::PropertyValue(
     611             :         OUString( "CellRangeRepresentation" ),
     612             :         -1, uno::makeAny( rRectangularRange ),
     613           1 :         beans::PropertyState_DIRECT_VALUE );
     614           2 :     aArgs[1] = beans::PropertyValue(
     615             :         OUString( "DataRowSource" ),
     616             :         -1, uno::makeAny( eDataRowSource ),
     617           1 :         beans::PropertyState_DIRECT_VALUE );
     618           2 :     aArgs[2] = beans::PropertyValue(
     619             :         OUString( "FirstCellAsLabel" ),
     620             :         -1, uno::makeAny( bFirstCellAsLabel ),
     621           1 :         beans::PropertyState_DIRECT_VALUE );
     622             : 
     623           1 :     if( !sColTrans.isEmpty() || !sRowTrans.isEmpty() )
     624             :     {
     625           0 :         aArgs.realloc( aArgs.getLength() + 1 );
     626           0 :         aArgs[ sal::static_int_cast<sal_uInt32>(aArgs.getLength()) - 1 ] = beans::PropertyValue(
     627             :             OUString( "SequenceMapping" ),
     628           0 :             -1, uno::makeAny( !sColTrans.isEmpty()
     629           0 :                 ? lcl_getNumberSequenceFromString( sColTrans, bHasCateories && !xNewDoc->hasInternalDataProvider() )
     630           0 :                 : lcl_getNumberSequenceFromString( sRowTrans, bHasCateories && !xNewDoc->hasInternalDataProvider() ) ),
     631           0 :         beans::PropertyState_DIRECT_VALUE );
     632             :     }
     633             : 
     634             :     //work around wrong writer ranges ( see Issue 58464 )
     635             :     {
     636           1 :         OUString aChartOleObjectName;
     637           2 :         uno::Reference< frame::XModel > xModel(xNewDoc, uno::UNO_QUERY );
     638           1 :         if( xModel.is() )
     639             :         {
     640           1 :             utl::MediaDescriptor aMediaDescriptor( xModel->getArgs() );
     641             : 
     642             :             utl::MediaDescriptor::const_iterator aIt(
     643           1 :                 aMediaDescriptor.find( OUString(  "HierarchicalDocumentName" )));
     644           1 :             if( aIt != aMediaDescriptor.end() )
     645             :             {
     646           1 :                 aChartOleObjectName = (*aIt).second.get< OUString >();
     647           1 :             }
     648             :         }
     649           1 :         if( !aChartOleObjectName.isEmpty() )
     650             :         {
     651           1 :             aArgs.realloc( aArgs.getLength() + 1 );
     652           2 :             aArgs[ sal::static_int_cast<sal_uInt32>(aArgs.getLength()) - 1 ] = beans::PropertyValue(
     653             :                 OUString( "ChartOleObjectName" ),
     654             :                 -1, uno::makeAny( aChartOleObjectName ),
     655           1 :                 beans::PropertyState_DIRECT_VALUE );
     656           1 :         }
     657             :     }
     658             : 
     659             :     uno::Reference< chart2::data::XDataSource > xDataSource(
     660           2 :         xDataProvider->createDataSource( aArgs ));
     661             : 
     662           1 :     aArgs.realloc( aArgs.getLength() + 2 );
     663           2 :     aArgs[ sal::static_int_cast<sal_uInt32>(aArgs.getLength()) - 2 ] = beans::PropertyValue(
     664             :         OUString( "HasCategories" ),
     665             :         -1, uno::makeAny( bHasCateories ),
     666           1 :         beans::PropertyState_DIRECT_VALUE );
     667           2 :     aArgs[ sal::static_int_cast<sal_uInt32>(aArgs.getLength()) - 1 ] = beans::PropertyValue(
     668             :         OUString("UseCategoriesAsX"),
     669             :         -1, uno::makeAny( sal_False ),//categories in ODF files are not to be used as x values (independent from what is offered in our ui)
     670           1 :         beans::PropertyState_DIRECT_VALUE );
     671             : 
     672           2 :     xNewDia->setDiagramData( xDataSource, aArgs );
     673             : }
     674             : 
     675          86 : void SchXMLChartContext::EndElement()
     676             : {
     677          86 :     uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
     678         172 :     uno::Reference< beans::XPropertySet > xProp( xDoc, uno::UNO_QUERY );
     679         172 :     uno::Reference< chart2::XChartDocument > xNewDoc( xDoc, uno::UNO_QUERY );
     680             : 
     681          86 :     if( xProp.is())
     682             :     {
     683          86 :         if( !maMainTitle.isEmpty())
     684             :         {
     685          33 :             uno::Reference< beans::XPropertySet > xTitleProp( xDoc->getTitle(), uno::UNO_QUERY );
     686          33 :             if( xTitleProp.is())
     687             :             {
     688             :                 try
     689             :                 {
     690          33 :                     uno::Any aAny;
     691          33 :                     aAny <<= maMainTitle;
     692          33 :                     xTitleProp->setPropertyValue("String", aAny );
     693             :                 }
     694           0 :                 catch(const beans::UnknownPropertyException&)
     695             :                 {
     696             :                     SAL_WARN("xmloff.chart", "Property String for Title not available" );
     697             :                 }
     698          33 :             }
     699             :         }
     700          86 :         if( !maSubTitle.isEmpty())
     701             :         {
     702           3 :             uno::Reference< beans::XPropertySet > xTitleProp( xDoc->getSubTitle(), uno::UNO_QUERY );
     703           3 :             if( xTitleProp.is())
     704             :             {
     705             :                 try
     706             :                 {
     707           3 :                     uno::Any aAny;
     708           3 :                     aAny <<= maSubTitle;
     709           3 :                     xTitleProp->setPropertyValue("String", aAny );
     710             :                 }
     711           0 :                 catch(const beans::UnknownPropertyException&)
     712             :                 {
     713             :                     SAL_WARN("xmloff.chart", "Property String for Title not available" );
     714             :                 }
     715           3 :             }
     716             :         }
     717             :     }
     718             : 
     719             :     // cleanup: remove empty chart type groups
     720          86 :     lcl_removeEmptyChartTypeGroups( xNewDoc );
     721             : 
     722             :     // set stack mode before a potential chart type detection (in case we have a rectangular range)
     723         172 :     uno::Reference< chart::XDiagram > xDiagram( xDoc->getDiagram() );
     724         172 :     uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
     725          86 :     if( xDiaProp.is())
     726             :     {
     727          86 :         if( maSeriesDefaultsAndStyles.maStackedDefault.hasValue())
     728           5 :             xDiaProp->setPropertyValue("Stacked",maSeriesDefaultsAndStyles.maStackedDefault);
     729          86 :         if( maSeriesDefaultsAndStyles.maPercentDefault.hasValue())
     730           4 :             xDiaProp->setPropertyValue("Percent",maSeriesDefaultsAndStyles.maPercentDefault);
     731          86 :         if( maSeriesDefaultsAndStyles.maDeepDefault.hasValue())
     732           3 :             xDiaProp->setPropertyValue("Deep",maSeriesDefaultsAndStyles.maDeepDefault);
     733          86 :         if( maSeriesDefaultsAndStyles.maStackedBarsConnectedDefault.hasValue())
     734          86 :             xDiaProp->setPropertyValue("StackedBarsConnected",maSeriesDefaultsAndStyles.maStackedBarsConnectedDefault);
     735             :     }
     736             : 
     737             :     //the OOo 2.0 implementation and older has a bug with donuts
     738             :     bool bSpecialHandlingForDonutChart = lcl_SpecialHandlingForDonutChartNeeded(
     739          86 :         maChartTypeServiceName, GetImport());
     740             : 
     741             :     // apply data
     742          86 :     if(!xNewDoc.is())
     743          86 :         return;
     744             : 
     745          86 :     bool bHasOwnData = false;
     746          86 :     if( m_aXLinkHRefAttributeToIndicateDataProvider == "." ) //data comes from the chart itself
     747          47 :         bHasOwnData = true;
     748          39 :     else if( m_aXLinkHRefAttributeToIndicateDataProvider == ".." ) //data comes from the parent application
     749          36 :         bHasOwnData = false;
     750           3 :     else if( !m_aXLinkHRefAttributeToIndicateDataProvider.isEmpty() ) //not supported so far to get the data by sibling objects -> fall back to chart itself if data are available
     751           0 :         bHasOwnData = m_bHasTableElement;
     752             :     else
     753           3 :         bHasOwnData = !m_bHasRangeAtPlotArea;
     754             : 
     755          86 :     if( xNewDoc->hasInternalDataProvider())
     756             :     {
     757          50 :         if( !m_bHasTableElement && m_aXLinkHRefAttributeToIndicateDataProvider != "." )
     758             :         {
     759             :             //#i103147# ODF, workaround broken files with a missing table:cell-range-address at the plot-area
     760           0 :             bool bSwitchSuccessful = SchXMLTools::switchBackToDataProviderFromParent( xNewDoc, maLSequencesPerIndex );
     761           0 :             bHasOwnData = !bSwitchSuccessful;
     762             :         }
     763             :         else
     764          50 :             bHasOwnData = true;//e.g. in case of copy->paste from calc to impress
     765             :     }
     766          36 :     else if( bHasOwnData )
     767             :     {
     768           0 :         xNewDoc->createInternalDataProvider( sal_False /* bCloneExistingData */ );
     769             :     }
     770          86 :     if( bHasOwnData )
     771          50 :         msChartAddress = "all";
     772             : 
     773          86 :     bool bSwitchRangesFromOuterToInternalIfNecessary = false;
     774          86 :     if( !bHasOwnData && mbAllRangeAddressesAvailable )
     775             :     {
     776             :         // special handling for stock chart (merge series together)
     777          72 :         if( mbIsStockChart )
     778           0 :             MergeSeriesForStockChart();
     779             :     }
     780          50 :     else if( !msChartAddress.isEmpty() )
     781             :     {
     782             :         //own data or only rectangular range available
     783             : 
     784          50 :         if( xNewDoc->hasInternalDataProvider() )
     785          50 :             SchXMLTableHelper::applyTableToInternalDataProvider( maTable, xNewDoc );
     786             : 
     787          50 :         bool bOlderThan2_3 = SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( Reference< frame::XModel >( xNewDoc, uno::UNO_QUERY ));
     788          50 :         bool bOldFileWithOwnDataFromRows = (bOlderThan2_3 && bHasOwnData && (meDataRowSource==chart::ChartDataRowSource_ROWS)); // in this case there are range addresses that are simply wrong.
     789             : 
     790          99 :         if( mbAllRangeAddressesAvailable && !bSpecialHandlingForDonutChart && !mbIsStockChart &&
     791          49 :             !bOldFileWithOwnDataFromRows )
     792             :         {
     793             :             //bHasOwnData is true in this case!
     794             :             //e.g. for normal files with own data or also in case of copy paste scenario (e.g. calc to impress)
     795          49 :             bSwitchRangesFromOuterToInternalIfNecessary = true;
     796             :         }
     797             :         else
     798             :         {
     799             :             //apply data from rectangular range
     800             : 
     801             :             // create datasource from data provider with rectangular range parameters and change the diagram setDiagramData
     802             :             try
     803             :             {
     804           1 :                 if( bOlderThan2_3 && xDiaProp.is() )//for older charts the hidden cells were removed by calc on the fly
     805           0 :                     xDiaProp->setPropertyValue("IncludeHiddenCells",uno::makeAny(false));
     806             : 
     807             :                 // note: mbRowHasLabels means the first row contains labels, that means we have "column-descriptions",
     808             :                 // (analogously mbColHasLabels means we have "row-descriptions")
     809           1 :                 lcl_ApplyDataFromRectangularRangeToDiagram( xNewDoc, msChartAddress, meDataRowSource, mbRowHasLabels, mbColHasLabels, bHasOwnData, msColTrans, msRowTrans );
     810             :             }
     811           0 :             catch(const uno::Exception&)
     812             :             {
     813             :                 //try to fallback to internal data
     814             :                 SAL_WARN("xmloff.chart", "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram try to fallback to internal data" );
     815           0 :                 if(!bHasOwnData)
     816             :                 {
     817           0 :                     bHasOwnData = true;
     818           0 :                     msChartAddress = "all";
     819           0 :                     if( !xNewDoc->hasInternalDataProvider() )
     820             :                     {
     821           0 :                         xNewDoc->createInternalDataProvider( sal_False /* bCloneExistingData */ );
     822           0 :                         SchXMLTableHelper::applyTableToInternalDataProvider( maTable, xNewDoc );
     823             :                         try
     824             :                         {
     825           0 :                             lcl_ApplyDataFromRectangularRangeToDiagram( xNewDoc, msChartAddress, meDataRowSource, mbRowHasLabels, mbColHasLabels, bHasOwnData, msColTrans, msRowTrans );
     826             :                         }
     827           0 :                         catch(const uno::Exception&)
     828             :                         {
     829             :                             SAL_WARN("xmloff.chart", "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram fallback to internal data failed also" );
     830             :                         }
     831             :                     }
     832             :                 }
     833             :             }
     834             :         }
     835             :     }
     836             :     else
     837             :     {
     838             :         SAL_WARN("xmloff.chart", "Must not get here" );
     839             :     }
     840             : 
     841             :     // now all series and data point properties are available and can be set
     842             :     {
     843          86 :         if( bSpecialHandlingForDonutChart )
     844             :         {
     845           0 :             uno::Reference< chart2::XDiagram > xNewDiagram( xNewDoc->getFirstDiagram() );
     846             :             lcl_swapPointAndSeriesStylesForDonutCharts( maSeriesDefaultsAndStyles.maSeriesStyleList
     847           0 :                 , SchXMLSeriesHelper::getDataSeriesIndexMapFromDiagram(xNewDiagram) );
     848             :         }
     849             : 
     850          86 :         SchXMLSeries2Context::initSeriesPropertySets( maSeriesDefaultsAndStyles, uno::Reference< frame::XModel >(xDoc, uno::UNO_QUERY ) );
     851             : 
     852             :         //set defaults from diagram to the new series:
     853             :         //check whether we need to remove lines from symbol only charts
     854          86 :         bool bSwitchOffLinesForScatter = false;
     855             :         {
     856          86 :             bool bLinesOn = true;
     857          86 :             if( (maSeriesDefaultsAndStyles.maLinesOnProperty >>= bLinesOn) && !bLinesOn )
     858             :             {
     859           3 :                 if( maChartTypeServiceName == "com.sun.star.chart2.ScatterChartType" )
     860             :                 {
     861           0 :                     bSwitchOffLinesForScatter = true;
     862           0 :                     SchXMLSeries2Context::switchSeriesLinesOff( maSeriesDefaultsAndStyles.maSeriesStyleList );
     863             :                 }
     864             :             }
     865             :         }
     866          86 :         SchXMLSeries2Context::setDefaultsToSeries( maSeriesDefaultsAndStyles );
     867             : 
     868             :         // set autostyles for series and data points
     869          86 :         const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
     870          86 :         const SvXMLStyleContext* pStyle = NULL;
     871          86 :         OUString sCurrStyleName;
     872             : 
     873          86 :         if( pStylesCtxt )
     874             :         {
     875             :             //iterate over data-series first
     876             :             //don't set series styles for donut charts
     877          86 :             if( !bSpecialHandlingForDonutChart )
     878             :             {
     879             :                 SchXMLSeries2Context::setStylesToSeries(
     880             :                                         maSeriesDefaultsAndStyles, pStylesCtxt, pStyle,
     881          86 :                                         sCurrStyleName, mrImportHelper, GetImport(),
     882         172 :                                         mbIsStockChart, maLSequencesPerIndex );
     883             :                 // ... then set attributes for statistics (after their existence was set in the series)
     884             :                 SchXMLSeries2Context::setStylesToStatisticsObjects(
     885             :                                         maSeriesDefaultsAndStyles, pStylesCtxt,
     886          86 :                                         pStyle, sCurrStyleName );
     887             : 
     888             :                 SchXMLSeries2Context::setStylesToRegressionCurves(
     889             :                                         maSeriesDefaultsAndStyles, pStylesCtxt,
     890          86 :                                         pStyle, sCurrStyleName );
     891             :             }
     892             :         }
     893             : 
     894             :         //#i98319# call switchRangesFromOuterToInternalIfNecessary before the data point styles are applied, otherwise in copy->paste scenario the data point styles do get lost
     895          86 :         if( bSwitchRangesFromOuterToInternalIfNecessary )
     896             :         {
     897          49 :             if( xNewDoc->hasInternalDataProvider() )
     898          49 :                 SchXMLTableHelper::switchRangesFromOuterToInternalIfNecessary( maTable, maLSequencesPerIndex, xNewDoc, meDataRowSource );
     899             :         }
     900             : 
     901          86 :         if( pStylesCtxt )
     902             :         {
     903             :             // ... then iterate over data-point attributes, so the latter are not overwritten
     904             :             SchXMLSeries2Context::setStylesToDataPoints( maSeriesDefaultsAndStyles
     905          86 :                             , pStylesCtxt, pStyle, sCurrStyleName, mrImportHelper, GetImport(), mbIsStockChart, bSpecialHandlingForDonutChart, bSwitchOffLinesForScatter );
     906          86 :         }
     907             :     }
     908             : 
     909          86 :     if( xProp.is())
     910         172 :         xProp->setPropertyValue("RefreshAddInAllowed", uno::makeAny( sal_True) );
     911             : }
     912             : 
     913           0 : void SchXMLChartContext::MergeSeriesForStockChart()
     914             : {
     915             :     OSL_ASSERT( mbIsStockChart );
     916             :     try
     917             :     {
     918           0 :         uno::Reference< chart::XChartDocument > xOldDoc( mrImportHelper.GetChartDocument());
     919           0 :         uno::Reference< chart2::XChartDocument > xDoc( xOldDoc, uno::UNO_QUERY_THROW );
     920           0 :         uno::Reference< chart2::XDiagram > xDiagram( xDoc->getFirstDiagram());
     921           0 :         if( ! xDiagram.is())
     922           0 :             return;
     923             : 
     924           0 :         bool bHasJapaneseCandlestick = true;
     925           0 :         uno::Reference< chart2::XDataSeriesContainer > xDSContainer;
     926           0 :         uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
     927           0 :         uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
     928           0 :         for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
     929             :         {
     930           0 :             uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
     931           0 :             uno::Sequence< uno::Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
     932           0 :             for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
     933             :             {
     934           0 :                 if( aChartTypes[nCTIdx]->getChartType() == "com.sun.star.chart2.CandleStickChartType" )
     935             :                 {
     936           0 :                     xDSContainer.set( aChartTypes[nCTIdx], uno::UNO_QUERY_THROW );
     937           0 :                     uno::Reference< beans::XPropertySet > xCTProp( aChartTypes[nCTIdx], uno::UNO_QUERY_THROW );
     938           0 :                     xCTProp->getPropertyValue("Japanese") >>= bHasJapaneseCandlestick;
     939           0 :                     break;
     940             :                 }
     941             :             }
     942           0 :         }
     943             : 
     944           0 :         if( xDSContainer.is())
     945             :         {
     946             :             // with japanese candlesticks: open, low, high, close
     947             :             // otherwise: low, high, close
     948           0 :             uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDSContainer->getDataSeries());
     949           0 :             const sal_Int32 nSeriesCount( aSeriesSeq.getLength());
     950           0 :             const sal_Int32 nSeriesPerCandleStick = bHasJapaneseCandlestick ? 4: 3;
     951           0 :             sal_Int32 nCandleStickCount = nSeriesCount / nSeriesPerCandleStick;
     952             :             OSL_ASSERT( nSeriesPerCandleStick * nCandleStickCount == nSeriesCount );
     953           0 :             uno::Sequence< uno::Reference< chart2::XDataSeries > > aNewSeries( nCandleStickCount );
     954           0 :             for( sal_Int32 i=0; i<nCandleStickCount; ++i )
     955             :             {
     956           0 :                 sal_Int32 nSeriesIndex = i*nSeriesPerCandleStick;
     957           0 :                 if( bHasJapaneseCandlestick )
     958             :                 {
     959             :                     // open values
     960           0 :                     lcl_setRoleAtFirstSequence( aSeriesSeq[ nSeriesIndex ], OUString( "values-first" ));
     961           0 :                     aNewSeries[i] = aSeriesSeq[ nSeriesIndex ];
     962             :                     // low values
     963             :                     lcl_MoveDataToCandleStickSeries(
     964           0 :                         uno::Reference< chart2::data::XDataSource >( aSeriesSeq[ ++nSeriesIndex ], uno::UNO_QUERY_THROW ),
     965           0 :                         aNewSeries[i], OUString( "values-min" ));
     966             :                 }
     967             :                 else
     968             :                 {
     969             :                     // low values
     970           0 :                     lcl_setRoleAtFirstSequence( aSeriesSeq[ nSeriesIndex ], OUString( "values-min" ));
     971           0 :                     aNewSeries[i] = aSeriesSeq[ nSeriesIndex ];
     972             :                 }
     973             :                 // high values
     974             :                 lcl_MoveDataToCandleStickSeries(
     975           0 :                     uno::Reference< chart2::data::XDataSource >( aSeriesSeq[ ++nSeriesIndex ], uno::UNO_QUERY_THROW ),
     976           0 :                     aNewSeries[i], OUString( "values-max" ));
     977             :                 // close values
     978             :                 lcl_MoveDataToCandleStickSeries(
     979           0 :                     uno::Reference< chart2::data::XDataSource >( aSeriesSeq[ ++nSeriesIndex ], uno::UNO_QUERY_THROW ),
     980           0 :                     aNewSeries[i], OUString( "values-last" ));
     981             :             }
     982           0 :             xDSContainer->setDataSeries( aNewSeries );
     983           0 :         }
     984             :     }
     985           0 :     catch(const uno::Exception&)
     986             :     {
     987             :         SAL_WARN("xmloff.chart", "Exception while merging series for stock chart" );
     988             :     }
     989             : }
     990             : 
     991         269 : SvXMLImportContext* SchXMLChartContext::CreateChildContext(
     992             :     sal_uInt16 nPrefix,
     993             :     const OUString& rLocalName,
     994             :     const uno::Reference< xml::sax::XAttributeList >& xAttrList )
     995             : {
     996         269 :     SvXMLImportContext* pContext = 0;
     997         269 :     const SvXMLTokenMap& rTokenMap = mrImportHelper.GetChartElemTokenMap();
     998         269 :     uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
     999         538 :     uno::Reference< beans::XPropertySet > xProp( xDoc, uno::UNO_QUERY );
    1000             : 
    1001         269 :     switch( rTokenMap.Get( nPrefix, rLocalName ))
    1002             :     {
    1003             :         case XML_TOK_CHART_PLOT_AREA:
    1004          86 :             pContext = new SchXMLPlotAreaContext( mrImportHelper, GetImport(), rLocalName,
    1005             :                                                   m_aXLinkHRefAttributeToIndicateDataProvider,
    1006             :                                                   msCategoriesAddress,
    1007             :                                                   msChartAddress, m_bHasRangeAtPlotArea, mbAllRangeAddressesAvailable,
    1008             :                                                   mbColHasLabels, mbRowHasLabels,
    1009             :                                                   meDataRowSource,
    1010             :                                                   maSeriesDefaultsAndStyles,
    1011             :                                                   maChartTypeServiceName,
    1012          86 :                                                   maLSequencesPerIndex, maChartSize );
    1013          86 :             break;
    1014             : 
    1015             :         case XML_TOK_CHART_TITLE:
    1016          33 :             if( xDoc.is())
    1017             :             {
    1018          33 :                 if( xProp.is())
    1019             :                 {
    1020          33 :                     xProp->setPropertyValue("HasMainTitle", uno::makeAny(true) );
    1021             :                 }
    1022          33 :                 uno::Reference< drawing::XShape > xTitleShape( xDoc->getTitle(), uno::UNO_QUERY );
    1023          33 :                 pContext = new SchXMLTitleContext( mrImportHelper, GetImport(),
    1024          33 :                                                    rLocalName, maMainTitle, xTitleShape );
    1025             :             }
    1026          33 :             break;
    1027             : 
    1028             :         case XML_TOK_CHART_SUBTITLE:
    1029           3 :             if( xDoc.is())
    1030             :             {
    1031           3 :                 if( xProp.is())
    1032             :                 {
    1033           3 :                     xProp->setPropertyValue("HasSubTitle", uno::makeAny(true) );
    1034             :                 }
    1035           3 :                 uno::Reference< drawing::XShape > xTitleShape( xDoc->getSubTitle(), uno::UNO_QUERY );
    1036           3 :                 pContext = new SchXMLTitleContext( mrImportHelper, GetImport(),
    1037           3 :                                                    rLocalName, maSubTitle, xTitleShape );
    1038             :             }
    1039           3 :             break;
    1040             : 
    1041             :         case XML_TOK_CHART_LEGEND:
    1042          61 :             pContext = new SchXMLLegendContext( mrImportHelper, GetImport(), rLocalName );
    1043          61 :             break;
    1044             : 
    1045             :         case XML_TOK_CHART_TABLE:
    1046             :             {
    1047             :                 SchXMLTableContext * pTableContext =
    1048          86 :                     new SchXMLTableContext( mrImportHelper, GetImport(), rLocalName, maTable );
    1049          86 :                 m_bHasTableElement = true;
    1050             :                 // #i85913# take into account column- and row- mapping for
    1051             :                 // charts with own data only for those which were not copied
    1052             :                 // from a place where they got data from the container.  Note,
    1053             :                 // that this requires the plot-area been read before the table
    1054             :                 // (which is required in the ODF spec)
    1055             :                 // Note: For stock charts and donut charts with special handling
    1056             :                 // the mapping must not be applied!
    1057         135 :                 if( msChartAddress.isEmpty() && !mbIsStockChart &&
    1058             :                     !lcl_SpecialHandlingForDonutChartNeeded(
    1059          49 :                         maChartTypeServiceName, GetImport()))
    1060             :                 {
    1061          49 :                     if( !msColTrans.isEmpty() )
    1062             :                     {
    1063             :                         OSL_ASSERT( msRowTrans.isEmpty() );
    1064           0 :                         pTableContext->setColumnPermutation( lcl_getNumberSequenceFromString( msColTrans, true ));
    1065           0 :                         msColTrans.clear();
    1066             :                     }
    1067          49 :                     else if( !msRowTrans.isEmpty() )
    1068             :                     {
    1069           0 :                         pTableContext->setRowPermutation( lcl_getNumberSequenceFromString( msRowTrans, true ));
    1070           0 :                         msRowTrans.clear();
    1071             :                     }
    1072             :                 }
    1073          86 :                 pContext = pTableContext;
    1074             :             }
    1075          86 :             break;
    1076             : 
    1077             :         default:
    1078             :             // try importing as an additional shape
    1079           0 :             if( ! mxDrawPage.is())
    1080             :             {
    1081           0 :                 uno::Reference< drawing::XDrawPageSupplier  > xSupp( xDoc, uno::UNO_QUERY );
    1082           0 :                 if( xSupp.is())
    1083           0 :                     mxDrawPage = uno::Reference< drawing::XShapes >( xSupp->getDrawPage(), uno::UNO_QUERY );
    1084             : 
    1085           0 :                 SAL_WARN_IF( !mxDrawPage.is(), "xmloff.chart", "Invalid Chart Page" );
    1086             :             }
    1087           0 :             if( mxDrawPage.is())
    1088           0 :                 pContext = GetImport().GetShapeImport()->CreateGroupChildContext(
    1089           0 :                     GetImport(), nPrefix, rLocalName, xAttrList, mxDrawPage );
    1090           0 :             break;
    1091             :     }
    1092             : 
    1093         269 :     if( ! pContext )
    1094           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
    1095             : 
    1096         538 :     return pContext;
    1097             : }
    1098             : 
    1099             : /*
    1100             :     With a locked controller the following is done here:
    1101             :         1.  Hide title, subtitle, and legend.
    1102             :         2.  Set the size of the draw page.
    1103             :         3.  Set a (logically) empty data set.
    1104             :         4.  Set the chart type.
    1105             : */
    1106          86 : void SchXMLChartContext::InitChart(
    1107             :     const OUString & rChartTypeServiceName, // currently the old service name
    1108             :     bool /* bSetSwitchData */ )
    1109             : {
    1110          86 :     uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
    1111             :     SAL_WARN_IF( !xDoc.is(), "xmloff.chart", "No valid document!" );
    1112         172 :     uno::Reference< frame::XModel > xModel (xDoc, uno::UNO_QUERY );
    1113             : 
    1114             :     // Remove Title and Diagram ("De-InitNew")
    1115         172 :     uno::Reference< chart2::XChartDocument > xNewDoc( mrImportHelper.GetChartDocument(), uno::UNO_QUERY );
    1116          86 :     if( xNewDoc.is())
    1117             :     {
    1118          86 :         xNewDoc->setFirstDiagram( 0 );
    1119          86 :         uno::Reference< chart2::XTitled > xTitled( xNewDoc, uno::UNO_QUERY );
    1120          86 :         if( xTitled.is())
    1121          86 :             xTitled->setTitleObject( 0 );
    1122             :     }
    1123             : 
    1124             :     //  Set the chart type via setting the diagram.
    1125          86 :     if( !rChartTypeServiceName.isEmpty() && xDoc.is())
    1126             :     {
    1127          86 :         uno::Reference< lang::XMultiServiceFactory > xFact( xDoc, uno::UNO_QUERY );
    1128          86 :         if( xFact.is())
    1129             :         {
    1130          86 :             uno::Reference< chart::XDiagram > xDia( xFact->createInstance( rChartTypeServiceName ), uno::UNO_QUERY );
    1131          86 :             if( xDia.is())
    1132          86 :                 xDoc->setDiagram( xDia );
    1133          86 :         }
    1134          86 :     }
    1135          86 : }
    1136             : 
    1137          50 : SchXMLTitleContext::SchXMLTitleContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport,
    1138             :                                         const OUString& rLocalName,
    1139             :                                         OUString& rTitle,
    1140             :                                         uno::Reference< drawing::XShape >& xTitleShape ) :
    1141             :         SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
    1142             :         mrImportHelper( rImpHelper ),
    1143             :         mrTitle( rTitle ),
    1144          50 :         mxTitleShape( xTitleShape )
    1145             : {
    1146          50 : }
    1147             : 
    1148         100 : SchXMLTitleContext::~SchXMLTitleContext()
    1149         100 : {}
    1150             : 
    1151          50 : void SchXMLTitleContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
    1152             : {
    1153          50 :     sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
    1154             : 
    1155          50 :     com::sun::star::awt::Point maPosition;
    1156          50 :     bool bHasXPosition=false;
    1157          50 :     bool bHasYPosition=false;
    1158             : 
    1159         200 :     for( sal_Int16 i = 0; i < nAttrCount; i++ )
    1160             :     {
    1161         150 :         OUString sAttrName = xAttrList->getNameByIndex( i );
    1162         300 :         OUString aLocalName;
    1163         300 :         OUString aValue = xAttrList->getValueByIndex( i );
    1164         150 :         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
    1165             : 
    1166         150 :         if( nPrefix == XML_NAMESPACE_SVG )
    1167             :         {
    1168         100 :             if( IsXMLToken( aLocalName, XML_X ) )
    1169             :             {
    1170          50 :                 GetImport().GetMM100UnitConverter().convertMeasureToCore(
    1171          50 :                         maPosition.X, aValue );
    1172          50 :                 bHasXPosition = true;
    1173             :             }
    1174          50 :             else if( IsXMLToken( aLocalName, XML_Y ) )
    1175             :             {
    1176          50 :                 GetImport().GetMM100UnitConverter().convertMeasureToCore(
    1177          50 :                         maPosition.Y, aValue );
    1178          50 :                 bHasYPosition = true;
    1179             :             }
    1180             :         }
    1181          50 :         else if( nPrefix == XML_NAMESPACE_CHART )
    1182             :         {
    1183          50 :             if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
    1184          50 :                 msAutoStyleName = aValue;
    1185             :         }
    1186         150 :     }
    1187             : 
    1188          50 :     if( mxTitleShape.is())
    1189             :     {
    1190          50 :         if( bHasXPosition && bHasYPosition )
    1191          50 :             mxTitleShape->setPosition( maPosition );
    1192             : 
    1193          50 :         uno::Reference< beans::XPropertySet > xProp( mxTitleShape, uno::UNO_QUERY );
    1194          50 :         if( xProp.is())
    1195             :         {
    1196          50 :             const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
    1197          50 :             if( pStylesCtxt )
    1198             :             {
    1199             :                 const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
    1200          50 :                     SchXMLImportHelper::GetChartFamilyID(), msAutoStyleName );
    1201             : 
    1202          50 :                 if( pStyle && pStyle->ISA( XMLPropStyleContext ))
    1203          50 :                     const_cast<XMLPropStyleContext*>( static_cast< const XMLPropStyleContext* >( pStyle ) )->FillPropertySet( xProp );
    1204             :             }
    1205          50 :         }
    1206             :     }
    1207          50 : }
    1208             : 
    1209          50 : SvXMLImportContext* SchXMLTitleContext::CreateChildContext(
    1210             :     sal_uInt16 nPrefix,
    1211             :     const OUString& rLocalName,
    1212             :     const uno::Reference< xml::sax::XAttributeList >& )
    1213             : {
    1214          50 :     SvXMLImportContext* pContext = 0;
    1215             : 
    1216          50 :     if( (nPrefix == XML_NAMESPACE_TEXT ||
    1217         100 :                 nPrefix == XML_NAMESPACE_LO_EXT) &&
    1218          50 :         IsXMLToken( rLocalName, XML_P ) )
    1219             :     {
    1220          50 :         pContext = new SchXMLParagraphContext( GetImport(), rLocalName, mrTitle );
    1221             :     }
    1222             :     else
    1223           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
    1224             : 
    1225          50 :     return pContext;
    1226             : }
    1227             : 
    1228             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11