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

Generated by: LCOV version 1.10