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

Generated by: LCOV version 1.10