LCOV - code coverage report
Current view: top level - xmloff/source/chart - SchXMLTools.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 266 420 63.3 %
Date: 2015-06-13 12:38:46 Functions: 22 28 78.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 "SchXMLTools.hxx"
      21             : 
      22             : #include <rtl/ustrbuf.hxx>
      23             : #include <comphelper/InlineContainer.hxx>
      24             : #include <xmloff/xmluconv.hxx>
      25             : #include <xmloff/xmlement.hxx>
      26             : #include <xmloff/xmlimppr.hxx>
      27             : #include <xmloff/prstylei.hxx>
      28             : #include <xmloff/xmlprmap.hxx>
      29             : #include <xmloff/xmlexp.hxx>
      30             : #include <xmloff/xmlnmspe.hxx>
      31             : #include <xmloff/xmlmetai.hxx>
      32             : #include <xmloff/maptype.hxx>
      33             : 
      34             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      35             : #include <com/sun/star/uno/XComponentContext.hpp>
      36             : #include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
      37             : #include <com/sun/star/chart2/data/XDataProvider.hpp>
      38             : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
      39             : #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
      40             : #include <com/sun/star/chart2/XChartDocument.hpp>
      41             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      42             : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
      43             : #include <com/sun/star/container/XChild.hpp>
      44             : #include <com/sun/star/document/XDocumentProperties.hpp>
      45             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      46             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      47             : #include <com/sun/star/lang/XServiceName.hpp>
      48             : 
      49             : #include <comphelper/processfactory.hxx>
      50             : #include <algorithm>
      51             : 
      52             : using namespace com::sun::star;
      53             : using namespace ::xmloff::token;
      54             : 
      55             : using ::com::sun::star::uno::Reference;
      56             : using ::com::sun::star::uno::Sequence;
      57             : 
      58             : namespace
      59             : {
      60             : 
      61        1285 : OUString lcl_getGeneratorFromModel( const uno::Reference< frame::XModel >& xChartModel )
      62             : {
      63        1285 :     OUString aGenerator;
      64        2570 :     uno::Reference< document::XDocumentPropertiesSupplier> xChartDocumentPropertiesSupplier( xChartModel, uno::UNO_QUERY );
      65        1285 :     if( xChartDocumentPropertiesSupplier.is() )
      66             :     {
      67             :         uno::Reference< document::XDocumentProperties > xChartDocumentProperties(
      68        1222 :             xChartDocumentPropertiesSupplier->getDocumentProperties());
      69        1222 :         if( xChartDocumentProperties.is() )
      70        1222 :             aGenerator =  xChartDocumentProperties->getGenerator();
      71             :     }
      72        2570 :     return aGenerator;
      73             : }
      74             : 
      75         123 : OUString lcl_getGeneratorFromModelOrItsParent( const uno::Reference< frame::XModel >& xChartModel )
      76             : {
      77         123 :     OUString aGenerator( lcl_getGeneratorFromModel(xChartModel) );
      78         123 :     if( aGenerator.isEmpty() ) //try to get the missing info from the parent document
      79             :     {
      80          41 :         uno::Reference< container::XChild > xChild( xChartModel, uno::UNO_QUERY );
      81          41 :         if( xChild.is() )
      82          41 :             aGenerator = lcl_getGeneratorFromModel( uno::Reference< frame::XModel >( xChild->getParent(), uno::UNO_QUERY) );
      83             :     }
      84         123 :     return aGenerator;
      85             : }
      86             : 
      87           0 : sal_Int32 lcl_getBuildIDFromGenerator( const OUString& rGenerator )
      88             : {
      89             :     //returns -1 if nothing found
      90           0 :     sal_Int32 nBuildId = -1;
      91           0 :     const OUString sBuildCompare(  "$Build-"  );
      92           0 :     sal_Int32 nBegin = rGenerator.indexOf( sBuildCompare );
      93           0 :     if( nBegin >= 0 )
      94             :     {
      95           0 :         OUString sBuildId( rGenerator.copy( nBegin + sBuildCompare.getLength() ) );
      96           0 :         nBuildId = sBuildId.toInt32();
      97             :     }
      98           0 :     return nBuildId;
      99             : }
     100             : 
     101         340 : OUString lcl_ConvertRange( const OUString & rRange, const Reference< chart2::data::XDataProvider >& xDataProvider )
     102             : {
     103         340 :     OUString aResult = rRange;
     104         680 :     Reference< chart2::data::XRangeXMLConversion > xRangeConversion( xDataProvider, uno::UNO_QUERY );
     105         340 :     if( xRangeConversion.is())
     106         340 :         aResult = xRangeConversion->convertRangeFromXML( rRange );
     107         680 :     return aResult;
     108             : }
     109             : 
     110           0 : Reference< chart2::data::XDataSequence > lcl_createNewSequenceFromCachedXMLRange( const Reference< chart2::data::XDataSequence >& xSeq, const Reference< chart2::data::XDataProvider >& xDataProvider )
     111             : {
     112           0 :     Reference< chart2::data::XDataSequence > xRet;
     113           0 :     OUString aRange;
     114           0 :     if( xSeq.is() && SchXMLTools::getXMLRangePropertyFromDataSequence( xSeq, aRange, /* bClearProp = */ true ) )
     115             :     {
     116           0 :         xRet.set( xDataProvider->createDataSequenceByRangeRepresentation(
     117           0 :             lcl_ConvertRange( aRange, xDataProvider )) );
     118             :         SchXMLTools::copyProperties( Reference< beans::XPropertySet >( xSeq, uno::UNO_QUERY ),
     119           0 :             Reference< beans::XPropertySet >( xRet, uno::UNO_QUERY ));
     120             :     }
     121           0 :     return xRet;
     122             : }
     123             : 
     124             : } // anonymous namespace
     125             : 
     126             : namespace SchXMLTools
     127             : {
     128             : 
     129             : static const SvXMLEnumMapEntry aXMLChartClassMap[] =
     130             : {
     131             :     { XML_LINE,         XML_CHART_CLASS_LINE    },
     132             :     { XML_AREA,         XML_CHART_CLASS_AREA    },
     133             :     { XML_CIRCLE,       XML_CHART_CLASS_CIRCLE  },
     134             :     { XML_RING,         XML_CHART_CLASS_RING    },
     135             :     { XML_SCATTER,      XML_CHART_CLASS_SCATTER },
     136             :     { XML_RADAR,        XML_CHART_CLASS_RADAR   },
     137             :     { XML_FILLED_RADAR, XML_CHART_CLASS_FILLED_RADAR },
     138             :     { XML_BAR,          XML_CHART_CLASS_BAR     },
     139             :     { XML_STOCK,        XML_CHART_CLASS_STOCK   },
     140             :     { XML_BUBBLE,       XML_CHART_CLASS_BUBBLE  },
     141             :     { XML_GL3DBAR,      XML_CHART_CLASS_GL3DBAR },
     142             :     { XML_SURFACE,      XML_CHART_CLASS_BAR     }, //@todo change this if a surface chart is available
     143             :     { XML_ADD_IN,       XML_CHART_CLASS_ADDIN   },
     144             :     { XML_TOKEN_INVALID, XML_CHART_CLASS_UNKNOWN }
     145             : };
     146             : 
     147          86 : SchXMLChartTypeEnum GetChartTypeEnum( const OUString& rClassName )
     148             : {
     149          86 :     sal_uInt16 nEnumVal = XML_CHART_CLASS_UNKNOWN;
     150          86 :     if( !SvXMLUnitConverter::convertEnum(
     151          86 :                                     nEnumVal, rClassName, aXMLChartClassMap ) )
     152           0 :         nEnumVal = XML_CHART_CLASS_UNKNOWN;
     153          86 :     return SchXMLChartTypeEnum(nEnumVal);
     154             : }
     155             : 
     156             : typedef ::comphelper::MakeMap< OUString, OUString > tMakeStringStringMap;
     157             : //static
     158           0 : const tMakeStringStringMap& lcl_getChartTypeNameMap()
     159             : {
     160             :     //shape property -- chart model object property
     161             :     static const tMakeStringStringMap g_aChartTypeNameMap =
     162             :         tMakeStringStringMap
     163             :         ( OUString( "com.sun.star.chart.LineDiagram" )
     164             :         , OUString( "com.sun.star.chart2.LineChartType" ) )
     165             : 
     166             :         ( OUString( "com.sun.star.chart.AreaDiagram" )
     167           0 :         , OUString( "com.sun.star.chart2.AreaChartType" ) )
     168             : 
     169             :         ( OUString( "com.sun.star.chart.BarDiagram" )
     170           0 :         , OUString( "com.sun.star.chart2.ColumnChartType" ) )
     171             : 
     172             :         ( OUString( "com.sun.star.chart.PieDiagram" )
     173           0 :         , OUString( "com.sun.star.chart2.PieChartType" ) )
     174             : 
     175             :         ( OUString( "com.sun.star.chart.DonutDiagram" )
     176           0 :         , OUString( "com.sun.star.chart2.DonutChartType" ) )
     177             : 
     178             :         ( OUString( "com.sun.star.chart.XYDiagram" )
     179           0 :         , OUString( "com.sun.star.chart2.ScatterChartType" ) )
     180             : 
     181             :         ( OUString( "com.sun.star.chart.NetDiagram" )
     182           0 :         , OUString( "com.sun.star.chart2.NetChartType" ) )
     183             : 
     184             :         ( OUString( "com.sun.star.chart.FilledNetDiagram" )
     185           0 :         , OUString( "com.sun.star.chart2.FilledNetChartType" ) )
     186             : 
     187             :         ( OUString( "com.sun.star.chart.StockDiagram" )
     188           0 :         , OUString( "com.sun.star.chart2.CandleStickChartType" ) )
     189             : 
     190             :         ( OUString( "com.sun.star.chart.BubbleDiagram" )
     191           0 :         , OUString( "com.sun.star.chart2.BubbleChartType" ) )
     192             : 
     193             :         ( OUString( "com.sun.star.chart.GL3DBarDiagram" )
     194           0 :         , OUString( "com.sun.star.chart2.GL3DBarChartType" ) )
     195             : 
     196             :         ;
     197           0 :     return g_aChartTypeNameMap;
     198             : }
     199             : 
     200           0 : OUString GetNewChartTypeName( const OUString & rOldChartTypeName )
     201             : {
     202           0 :     OUString aNew(rOldChartTypeName);
     203             : 
     204           0 :     const tMakeStringStringMap& rMap = lcl_getChartTypeNameMap();
     205           0 :     tMakeStringStringMap::const_iterator aIt( rMap.find( rOldChartTypeName ));
     206           0 :     if( aIt != rMap.end())
     207             :     {
     208           0 :         aNew = aIt->second;
     209             :     }
     210           0 :     return aNew;
     211             : }
     212             : 
     213         321 : OUString GetChartTypeByClassName(
     214             :     const OUString & rClassName, bool bUseOldNames )
     215             : {
     216         321 :     OUStringBuffer aResultBuffer;
     217         321 :     bool bInternalType = false;
     218             : 
     219         321 :     if( bUseOldNames )
     220          86 :         aResultBuffer.append( "com.sun.star.chart.");
     221             :     else
     222         235 :         aResultBuffer.append( "com.sun.star.chart2.");
     223             : 
     224         321 :     bInternalType = true;
     225             : 
     226         321 :     if( IsXMLToken( rClassName, XML_LINE ))
     227          48 :         aResultBuffer.append("Line");
     228         273 :     else if( IsXMLToken( rClassName, XML_AREA ))
     229           7 :         aResultBuffer.append("Area");
     230         266 :     else if( IsXMLToken( rClassName, XML_BAR ))
     231             :     {
     232         157 :         if( bUseOldNames )
     233          37 :             aResultBuffer.append("Bar");
     234             :         else
     235             :         {
     236         120 :             aResultBuffer.append("Column");
     237             :             // @todo: might be Bar
     238             :         }
     239             :     }
     240         109 :     else if( IsXMLToken( rClassName, XML_CIRCLE ))
     241          14 :         aResultBuffer.append("Pie");
     242          95 :     else if( IsXMLToken( rClassName, XML_RING ))
     243           4 :         aResultBuffer.append("Donut");
     244          91 :     else if( IsXMLToken( rClassName, XML_SCATTER ))
     245             :     {
     246          85 :         if( bUseOldNames )
     247          26 :             aResultBuffer.append("XY");
     248             :         else
     249          59 :             aResultBuffer.append("Scatter");
     250             :     }
     251             : 
     252           6 :     else if( IsXMLToken( rClassName, XML_BUBBLE ))
     253           0 :         aResultBuffer.append("Bubble");
     254           6 :     else if( IsXMLToken( rClassName, XML_RADAR ))
     255           0 :         aResultBuffer.append("Net");
     256           6 :     else if( IsXMLToken( rClassName, XML_FILLED_RADAR ))
     257           4 :         aResultBuffer.append("FilledNet");
     258           2 :     else if( IsXMLToken( rClassName, XML_STOCK ))
     259             :     {
     260           2 :         if( bUseOldNames )
     261           1 :             aResultBuffer.append("Stock");
     262             :         else
     263           1 :             aResultBuffer.append("CandleStick");
     264             :     }
     265           0 :     else if( IsXMLToken( rClassName, XML_SURFACE ))
     266             :     {
     267             :         //@todo change this if a surface chart is available
     268           0 :         if( bUseOldNames )
     269           0 :             aResultBuffer.append("Bar");
     270             :         else
     271           0 :             aResultBuffer.append("Column");
     272             :     }
     273           0 :     else if (IsXMLToken(rClassName, XML_GL3DBAR))
     274           0 :         aResultBuffer.append("GL3DBar");
     275             :     else
     276           0 :         bInternalType = false;
     277             : 
     278         321 :     if( ! bInternalType )
     279           0 :         return OUString();
     280             : 
     281         321 :     if( bUseOldNames )
     282          86 :         aResultBuffer.append("Diagram");
     283             :     else
     284         235 :         aResultBuffer.append("ChartType");
     285             : 
     286         321 :     return aResultBuffer.makeStringAndClear();
     287             : 
     288             : }
     289             : 
     290         868 : XMLTokenEnum getTokenByChartType(
     291             :     const OUString & rChartTypeService, bool bUseOldNames )
     292             : {
     293         868 :     XMLTokenEnum eResult = XML_TOKEN_INVALID;
     294        1736 :     OUString aPrefix, aPostfix;
     295             : 
     296         868 :     if( bUseOldNames )
     297             :     {
     298         269 :         aPrefix = "com.sun.star.chart.";
     299         269 :         aPostfix = "Diagram";
     300             :     }
     301             :     else
     302             :     {
     303         599 :         aPrefix = "com.sun.star.chart2.";
     304         599 :         aPostfix = "ChartType";
     305             :     }
     306             : 
     307         868 :     if( rChartTypeService.match( aPrefix ))
     308             :     {
     309         868 :         sal_Int32 nSkip = aPrefix.getLength();
     310             :         SAL_WARN_IF( rChartTypeService.getLength() < nSkip, "xmloff.chart", "ChartTypeService.getLength() < nSkip" );
     311         868 :         sal_Int32 nTypeLength = rChartTypeService.getLength() - nSkip - aPostfix.getLength();
     312             :         // if postfix matches and leaves a non-empty type
     313         868 :         if( nTypeLength > 0 && rChartTypeService.match( aPostfix, nSkip + nTypeLength ))
     314             :         {
     315         868 :             OUString aServiceName( rChartTypeService.copy( nSkip, nTypeLength ));
     316             : 
     317         868 :             if ( aServiceName == "Line" )
     318          74 :                 eResult = XML_LINE;
     319         794 :             else if ( aServiceName == "Area" )
     320          30 :                 eResult = XML_AREA;
     321        1949 :             else if( aServiceName == "Bar" ||
     322        1125 :                      (!bUseOldNames && aServiceName == "Column"))
     323         580 :                 eResult = XML_BAR;
     324         184 :             else if ( aServiceName == "Pie" )
     325          90 :                 eResult = XML_CIRCLE;
     326          94 :             else if ( aServiceName == "Donut" )
     327          12 :                 eResult = XML_RING;
     328         200 :             else if( (bUseOldNames && aServiceName == "XY") ||
     329         108 :                      (!bUseOldNames && aServiceName == "Scatter"))
     330          58 :                 eResult = XML_SCATTER;
     331          24 :             else if ( aServiceName == "Bubble" )
     332           0 :                 eResult = XML_BUBBLE;
     333          24 :             else if ( aServiceName == "Net" )
     334           0 :                 eResult = XML_RADAR;
     335          24 :             else if ( aServiceName == "FilledNet" )
     336          18 :                 eResult = XML_FILLED_RADAR;
     337          12 :             else if( (bUseOldNames && aServiceName == "Stock") ||
     338           0 :                      (!bUseOldNames && aServiceName == "CandleStick"))
     339           6 :                 eResult = XML_STOCK;
     340           0 :             else if (aServiceName == "GL3DBar")
     341           0 :                 eResult = XML_GL3DBAR;
     342             :         }
     343             :     }
     344             : 
     345         868 :     if( eResult == XML_TOKEN_INVALID && !rChartTypeService.isEmpty() )
     346           0 :         eResult = XML_ADD_IN;
     347             : 
     348        1736 :     return eResult;
     349             : }
     350             : 
     351         251 : Reference< chart2::data::XLabeledDataSequence2 > GetNewLabeledDataSequence()
     352             : {
     353         251 :     Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
     354         251 :     Reference< chart2::data::XLabeledDataSequence2 > xResult = chart2::data::LabeledDataSequence::create(xContext);
     355         251 :     return xResult;
     356             : }
     357             : 
     358         340 : Reference< chart2::data::XDataSequence > CreateDataSequence(
     359             :         const OUString & rRange,
     360             :         const Reference< chart2::XChartDocument >& xChartDoc )
     361             : {
     362         340 :     Reference< chart2::data::XDataSequence > xRet;
     363             : 
     364         340 :     if( !xChartDoc.is() )
     365             :     {
     366             :         SAL_WARN("xmloff.chart", "need a chart document" );
     367           0 :         return xRet;
     368             :     }
     369             : 
     370         680 :     Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
     371         340 :     if( !xDataProvider.is() )
     372             :     {
     373             :         SAL_WARN("xmloff.chart", "need a data provider" );
     374           0 :         return xRet;
     375             :     }
     376             : 
     377         340 :     bool bUseInternal = false;
     378         680 :     uno::Reference<beans::XPropertySet> xPropSet(xDataProvider, uno::UNO_QUERY);
     379         340 :     if (xPropSet.is())
     380             :     {
     381             :         try
     382             :         {
     383          97 :             bool bVal = false;
     384          97 :             uno::Any any = xPropSet->getPropertyValue("UseInternalDataProvider");
     385          97 :             if (any >>= bVal)
     386          97 :                 bUseInternal = static_cast<bool>(bVal);
     387             :         }
     388           0 :         catch (const beans::UnknownPropertyException&)
     389             :         {
     390             :             // Do nothing
     391             :         }
     392             :     }
     393             : 
     394         340 :     if (!bUseInternal)
     395             :     {
     396             :         try
     397             :         {
     398         340 :             xRet.set( xDataProvider->createDataSequenceByRangeRepresentation( lcl_ConvertRange( rRange, xDataProvider )));
     399         340 :             SchXMLTools::setXMLRangePropertyAtDataSequence( xRet, rRange );
     400             :         }
     401           0 :         catch( const lang::IllegalArgumentException & )
     402             :         {
     403             :             SAL_WARN("xmloff.chart", "could not create data sequence" );
     404             :         }
     405             :     }
     406             : 
     407         340 :     if( !xRet.is() && !xChartDoc->hasInternalDataProvider() && !rRange.isEmpty() )
     408             :     {
     409             :         //#i103911# switch to internal data in case the parent cannot provide the requested data
     410           0 :         xChartDoc->createInternalDataProvider( sal_True /* bCloneExistingData */ );
     411           0 :         xDataProvider = xChartDoc->getDataProvider();
     412             :         try
     413             :         {
     414           0 :             xRet.set( xDataProvider->createDataSequenceByRangeRepresentation( lcl_ConvertRange( rRange, xDataProvider )));
     415           0 :             SchXMLTools::setXMLRangePropertyAtDataSequence( xRet, rRange );
     416             :         }
     417           0 :         catch( const lang::IllegalArgumentException & )
     418             :         {
     419             :             SAL_WARN("xmloff.chart", "could not create data sequence" );
     420             :         }
     421             :     }
     422         340 :     return xRet;
     423             : }
     424             : 
     425           2 : Reference< chart2::data::XDataSequence > CreateDataSequenceWithoutConvert(
     426             :         const OUString & rRange,
     427             :         const Reference< chart2::XChartDocument >& xChartDoc )
     428             : {
     429           2 :     Reference< chart2::data::XDataSequence > xRet;
     430             : 
     431           2 :     if( !xChartDoc.is() )
     432             :     {
     433             :         SAL_WARN("xmloff.chart", "need a chart document" );
     434           0 :         return xRet;
     435             :     }
     436             : 
     437           4 :     Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
     438           2 :     if( !xDataProvider.is() )
     439             :     {
     440             :         SAL_WARN("xmloff.chart", "need a data provider" );
     441           0 :         return xRet;
     442             :     }
     443             : 
     444             :     try
     445             :     {
     446           2 :         xRet.set( xDataProvider->createDataSequenceByRangeRepresentation( rRange ) );
     447           2 :         SchXMLTools::setXMLRangePropertyAtDataSequence( xRet, rRange );
     448             :     }
     449           0 :     catch( const lang::IllegalArgumentException & )
     450             :     {
     451             :         SAL_WARN("xmloff.chart", "could not create data sequence" );
     452             :     }
     453             : 
     454           2 :     return xRet;
     455             : }
     456             : 
     457          53 : void CreateCategories(
     458             :     const uno::Reference< chart2::data::XDataProvider > & xDataProvider,
     459             :     const uno::Reference< chart2::XChartDocument > & xNewDoc,
     460             :     const OUString & rRangeAddress,
     461             :     sal_Int32 nCooSysIndex,
     462             :     sal_Int32 nDimensionIndex,
     463             :     tSchXMLLSequencesPerIndex * pLSequencesPerIndex )
     464             : {
     465             :     try
     466             :     {
     467          53 :         if( xNewDoc.is() && !rRangeAddress.isEmpty())
     468             :         {
     469          53 :             if( xDataProvider.is())
     470             :             {
     471          53 :                 uno::Reference< chart2::XDiagram > xDia( xNewDoc->getFirstDiagram());
     472          53 :                 if( !xDia.is())
     473          53 :                     return;
     474             : 
     475         106 :                 uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDia, uno::UNO_QUERY_THROW );
     476             :                 uno::Sequence< uno::Reference< chart2::XCoordinateSystem > >
     477         106 :                     aCooSysSeq( xCooSysCnt->getCoordinateSystems());
     478          53 :                 if( nCooSysIndex < aCooSysSeq.getLength())
     479             :                 {
     480          53 :                     uno::Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[nCooSysIndex] );
     481             :                     SAL_WARN_IF( !xCooSys.is(), "xmloff.chart", "xCooSys is NULL");
     482          53 :                     if( nDimensionIndex < xCooSys->getDimension() )
     483             :                     {
     484          53 :                         const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
     485         109 :                         for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
     486             :                         {
     487          56 :                             uno::Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nI ));
     488          56 :                             if( xAxis.is() )
     489             :                             {
     490          56 :                                 chart2::ScaleData aData( xAxis->getScaleData());
     491             :                                 uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
     492         112 :                                     GetNewLabeledDataSequence(), uno::UNO_QUERY_THROW);
     493             :                                 try
     494             :                                 {
     495          56 :                                     OUString aConvertedRange( rRangeAddress );
     496          56 :                                     bool bRangeConverted = false;
     497          56 :                                     if( ! (xNewDoc->hasInternalDataProvider() && aConvertedRange == "categories"))
     498             :                                     {
     499          54 :                                         Reference< chart2::data::XRangeXMLConversion > xXMLConv( xDataProvider, uno::UNO_QUERY );
     500          54 :                                         if( xXMLConv.is())
     501             :                                         {
     502          54 :                                             aConvertedRange = xXMLConv->convertRangeFromXML( rRangeAddress );
     503          54 :                                             bRangeConverted = true;
     504          54 :                                         }
     505             :                                     }
     506             :                                     Reference< chart2::data::XDataSequence > xSeq(
     507         112 :                                         xDataProvider->createDataSequenceByRangeRepresentation( aConvertedRange ));
     508          56 :                                     xLabeledSeq->setValues( xSeq );
     509          56 :                                     if( bRangeConverted )
     510         110 :                                         setXMLRangePropertyAtDataSequence( xSeq, rRangeAddress );
     511             :                                 }
     512           0 :                                 catch( const lang::IllegalArgumentException & ex )
     513             :                                 {
     514             :                                     SAL_WARN("xmloff.chart", "IllegalArgumentException caught, Message: " << ex.Message );
     515             :                                 }
     516          56 :                                 aData.Categories.set( xLabeledSeq );
     517          56 :                                 if( pLSequencesPerIndex )
     518             :                                 {
     519             :                                     // register for setting local data if external data provider is not present
     520             :                                     pLSequencesPerIndex->insert(
     521             :                                         tSchXMLLSequencesPerIndex::value_type(
     522          54 :                                             tSchXMLIndexWithPart( SCH_XML_CATEGORIES_INDEX, SCH_XML_PART_VALUES ), xLabeledSeq ));
     523             :                                 }
     524         112 :                                 xAxis->setScaleData( aData );
     525             :                             }
     526          56 :                         }
     527          53 :                     }
     528          53 :                 }
     529             :             }
     530             :         }
     531             :     }
     532           0 :     catch( uno::Exception & )
     533             :     {
     534             :         SAL_WARN("xmloff.chart", "Exception caught while creating Categories" );
     535             :     }
     536             : }
     537             : 
     538         883 : uno::Any getPropertyFromContext( const OUString& rPropertyName, const XMLPropStyleContext* pPropStyleContext, const SvXMLStylesContext* pStylesCtxt )
     539             : {
     540         883 :     uno::Any aRet;
     541         883 :     if( !pPropStyleContext || !pStylesCtxt )
     542           0 :         return aRet;
     543         883 :     const ::std::vector< XMLPropertyState >& rProperties = pPropStyleContext->GetProperties();
     544         883 :     const rtl::Reference< XMLPropertySetMapper >& rMapper = pStylesCtxt->GetImportPropertyMapper( pPropStyleContext->GetFamily()/*XML_STYLE_FAMILY_SCH_CHART_ID*/ )->getPropertySetMapper();
     545         883 :     ::std::vector< XMLPropertyState >::const_iterator aEnd( rProperties.end() );
     546         883 :     ::std::vector< XMLPropertyState >::const_iterator aPropIter( rProperties.begin() );
     547        7062 :     for( aPropIter = rProperties.begin(); aPropIter != aEnd; ++aPropIter )
     548             :     {
     549        6548 :         sal_Int32 nIdx = aPropIter->mnIndex;
     550        6548 :         if( nIdx == -1 )
     551           0 :             continue;
     552        6548 :         OUString aPropName = rMapper->GetEntryAPIName( nIdx );
     553        6548 :         if(rPropertyName.equals(aPropName))
     554         369 :             return aPropIter->maValue;
     555        6179 :     }
     556         514 :     return aRet;
     557             : }
     558             : 
     559        5895 : void exportText( SvXMLExport& rExport, const OUString& rText, bool bConvertTabsLFs )
     560             : {
     561             :     SvXMLElementExport aPara( rExport, XML_NAMESPACE_TEXT,
     562        5895 :                               ::xmloff::token::GetXMLToken( ::xmloff::token::XML_P ),
     563        5895 :                               true, false );
     564             : 
     565        5895 :     if( bConvertTabsLFs )
     566             :     {
     567         522 :         sal_Int32 nStartPos = 0;
     568         522 :         sal_Int32 nEndPos = rText.getLength();
     569             :         sal_Unicode cChar;
     570             : 
     571        1566 :         for( sal_Int32 nPos = 0; nPos < nEndPos; nPos++ )
     572             :         {
     573        1044 :             cChar = rText[ nPos ];
     574        1044 :             switch( cChar )
     575             :             {
     576             :                 case 0x0009:        // tabulator
     577             :                     {
     578           0 :                         if( nPos > nStartPos )
     579           0 :                             rExport.GetDocHandler()->characters( rText.copy( nStartPos, (nPos - nStartPos)) );
     580           0 :                         nStartPos = nPos + 1;
     581             : 
     582             :                         SvXMLElementExport aElem( rExport, XML_NAMESPACE_TEXT,
     583           0 :                                                   ::xmloff::token::GetXMLToken( ::xmloff::token::XML_TAB_STOP ),
     584           0 :                                                   false, false );
     585             :                     }
     586           0 :                     break;
     587             : 
     588             :                 case 0x000A:        // linefeed
     589             :                     {
     590           0 :                         if( nPos > nStartPos )
     591           0 :                             rExport.GetDocHandler()->characters( rText.copy( nStartPos, (nPos - nStartPos)) );
     592           0 :                         nStartPos = nPos + 1;
     593             : 
     594             :                         SvXMLElementExport aElem( rExport, XML_NAMESPACE_TEXT,
     595           0 :                                                   ::xmloff::token::GetXMLToken( ::xmloff::token::XML_LINE_BREAK ),
     596           0 :                                                   false, false );
     597             :                     }
     598           0 :                     break;
     599             :             }
     600             :         }
     601         522 :         if( nEndPos > nStartPos )
     602             :         {
     603         522 :             if( nStartPos == 0 )
     604         522 :                 rExport.GetDocHandler()->characters( rText );
     605             :             else
     606           0 :                 rExport.GetDocHandler()->characters( rText.copy( nStartPos, (nEndPos - nStartPos)) );
     607             :         }
     608             :     }
     609             :     else // do not convert tabs and linefeeds (eg for numbers coming from unit converter)
     610             :     {
     611        5373 :         rExport.GetDocHandler()->characters( rText );
     612        5895 :     }
     613        5895 : }
     614             : 
     615          38 : void exportRangeToSomewhere( SvXMLExport& rExport, const OUString& rValue )
     616             : {
     617             :     //with issue #i366# and CWS chart20 ranges for error bars were introduced
     618             :     //to keep them during copy paste from calc to impress for example it
     619             :     //was necessary to introduce a mapping between the used ranges within calc and the data written to the local table
     620             :     //this is why we write this ranges here
     621             : 
     622             :     //#i113950# first the range was exported to attribute text:id, but that attribute does not allow arbitrary strings anymore within ODF 1.2
     623             :     //as an alternative the range info is now saved into the description at an empty group element (not very nice, but ODF conform)
     624             : 
     625          38 :     const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
     626          38 :     if( nCurrentODFVersion == SvtSaveOptions::ODFVER_010 || nCurrentODFVersion == SvtSaveOptions::ODFVER_011 )
     627          38 :         return;//svg:desc is not allowed at draw:g in ODF1.0; but as the ranges for error bars are anyhow not allowed within ODF1.0 nor ODF1.1 we do not need the information
     628             : 
     629             :     SvXMLElementExport aEmptyShapeGroup( rExport, XML_NAMESPACE_DRAW,
     630          38 :                               ::xmloff::token::GetXMLToken( ::xmloff::token::XML_G ),
     631          38 :                               true, false );
     632             :     SvXMLElementExport aDescription( rExport, XML_NAMESPACE_SVG,
     633          38 :                               ::xmloff::token::GetXMLToken( ::xmloff::token::XML_DESC ),
     634          76 :                               true, false );
     635          76 :     rExport.GetDocHandler()->characters( rValue );
     636             : }
     637             : 
     638         402 : void setXMLRangePropertyAtDataSequence(
     639             :     const Reference< chart2::data::XDataSequence > & xDataSequence,
     640             :     const OUString & rXMLRange )
     641             : {
     642         402 :     if( !xDataSequence.is())
     643         402 :         return;
     644             :     try
     645             :     {
     646         402 :         const OUString aXMLRangePropName(  "CachedXMLRange" );
     647         804 :         Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY_THROW );
     648         804 :         Reference< beans::XPropertySetInfo > xInfo( xProp->getPropertySetInfo());
     649         402 :         if( xInfo.is() && xInfo->hasPropertyByName( aXMLRangePropName ))
     650         696 :             xProp->setPropertyValue( aXMLRangePropName, uno::makeAny( rXMLRange ));
     651             :     }
     652           0 :     catch( const uno::Exception & ex )
     653             :     {
     654             :         SAL_WARN("xmloff.chart", "Exception caught, Message: " << ex.Message );
     655             :     }
     656             : }
     657             : 
     658         282 : bool getXMLRangePropertyFromDataSequence(
     659             :     const Reference< chart2::data::XDataSequence > & xDataSequence,
     660             :     OUString & rOutXMLRange,
     661             :     bool bClearProp /* = false */)
     662             : {
     663         282 :     bool bResult = false;
     664         282 :     if( xDataSequence.is())
     665             :     {
     666             :         try
     667             :         {
     668         282 :             const OUString aXMLRangePropName(  "CachedXMLRange" );
     669         564 :             Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY_THROW );
     670         564 :             Reference< beans::XPropertySetInfo > xInfo( xProp->getPropertySetInfo());
     671             :             bResult =
     672        1128 :                 ( xInfo.is() && xInfo->hasPropertyByName( aXMLRangePropName ) &&
     673        1974 :                   ( xProp->getPropertyValue( aXMLRangePropName ) >>= rOutXMLRange ) &&
     674         564 :                   !rOutXMLRange.isEmpty());
     675             :             // clear the property after usage
     676         282 :             if( bClearProp && bResult )
     677         564 :                 xProp->setPropertyValue( aXMLRangePropName, uno::Any( OUString()));
     678             :         }
     679           0 :         catch( const uno::Exception & ex )
     680             :         {
     681             :             SAL_WARN("xmloff.chart", "Exception caught, Message: " << ex.Message );
     682             :         }
     683             :     }
     684         282 :     return bResult;
     685             : }
     686             : 
     687           3 : void copyProperties(
     688             :     const Reference< beans::XPropertySet > & xSource,
     689             :     const Reference< beans::XPropertySet > & xDestination )
     690             : {
     691           3 :     if( ! (xSource.is() && xDestination.is()) )
     692           6 :         return;
     693             : 
     694             :     try
     695             :     {
     696           0 :         Reference< beans::XPropertySetInfo > xSrcInfo( xSource->getPropertySetInfo(), uno::UNO_QUERY_THROW );
     697           0 :         Reference< beans::XPropertySetInfo > xDestInfo( xDestination->getPropertySetInfo(), uno::UNO_QUERY_THROW );
     698           0 :         Sequence< beans::Property > aProperties( xSrcInfo->getProperties());
     699           0 :         const sal_Int32 nLength = aProperties.getLength();
     700           0 :         for( sal_Int32 i = 0; i < nLength; ++i )
     701             :         {
     702           0 :             OUString aName( aProperties[i].Name);
     703           0 :             if( xDestInfo->hasPropertyByName( aName ))
     704             :             {
     705           0 :                 beans::Property aProp( xDestInfo->getPropertyByName( aName ));
     706           0 :                 if( (aProp.Attributes & beans::PropertyAttribute::READONLY) == 0 )
     707           0 :                     xDestination->setPropertyValue(
     708           0 :                         aName, xSource->getPropertyValue( aName ));
     709             :             }
     710           0 :         }
     711             :     }
     712           0 :     catch( const uno::Exception & )
     713             :     {
     714             :         SAL_WARN("xmloff.chart", "Copying property sets failed!" );
     715             :     }
     716             : }
     717             : 
     718           0 : bool switchBackToDataProviderFromParent( const Reference< chart2::XChartDocument >& xChartDoc, const tSchXMLLSequencesPerIndex & rLSequencesPerIndex )
     719             : {
     720             :     //return whether the switch is successful
     721           0 :     if( !xChartDoc.is() || !xChartDoc->hasInternalDataProvider() )
     722           0 :         return false;
     723           0 :     Reference< chart2::data::XDataProvider > xDataProviderFromParent( SchXMLTools::getDataProviderFromParent( xChartDoc ) );
     724           0 :     if( !xDataProviderFromParent.is() )
     725           0 :         return false;
     726           0 :     uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartDoc, uno::UNO_QUERY );
     727           0 :     if( !xDataReceiver.is() )
     728           0 :         return false;
     729             : 
     730           0 :     xDataReceiver->attachDataProvider( xDataProviderFromParent );
     731             : 
     732           0 :     for( tSchXMLLSequencesPerIndex::const_iterator aLSeqIt( rLSequencesPerIndex.begin() );
     733           0 :          aLSeqIt != rLSequencesPerIndex.end(); ++aLSeqIt )
     734             :     {
     735           0 :         Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( aLSeqIt->second );
     736           0 :         if( !xLabeledSeq.is() )
     737           0 :             continue;
     738           0 :         Reference< chart2::data::XDataSequence > xNewSeq;
     739           0 :         xNewSeq = lcl_createNewSequenceFromCachedXMLRange( xLabeledSeq->getValues(), xDataProviderFromParent );
     740           0 :         if( xNewSeq.is() )
     741           0 :             xLabeledSeq->setValues( xNewSeq );
     742           0 :         xNewSeq = lcl_createNewSequenceFromCachedXMLRange( xLabeledSeq->getLabel(), xDataProviderFromParent );
     743           0 :         if( xNewSeq.is() )
     744           0 :             xLabeledSeq->setLabel( xNewSeq );
     745           0 :     }
     746           0 :     return true;
     747             : }
     748             : 
     749          86 : void setBuildIDAtImportInfo( uno::Reference< frame::XModel > xModel, Reference< beans::XPropertySet > xImportInfo )
     750             : {
     751          86 :     OUString aGenerator( lcl_getGeneratorFromModelOrItsParent(xModel) );
     752          86 :     if( !aGenerator.isEmpty() )
     753          82 :         SvXMLMetaDocumentContext::setBuildId( aGenerator, xImportInfo );
     754          86 : }
     755             : 
     756           3 : bool isDocumentGeneratedWithOpenOfficeOlderThan3_3( const uno::Reference< frame::XModel >& xChartModel )
     757             : {
     758           3 :     bool bResult = isDocumentGeneratedWithOpenOfficeOlderThan3_0( xChartModel );
     759           3 :     if( !bResult )
     760             :     {
     761           3 :         OUString aGenerator( lcl_getGeneratorFromModel(xChartModel) );
     762           3 :         if( aGenerator.indexOf( "OpenOffice.org_project/3" ) != -1 )
     763             :         {
     764           0 :             if( aGenerator.indexOf( "OpenOffice.org_project/300m" ) != -1 )
     765             :             {
     766           0 :                 sal_Int32 nBuilId = lcl_getBuildIDFromGenerator( lcl_getGeneratorFromModel(xChartModel) );
     767           0 :                 if( nBuilId>0 && nBuilId<9491 ) //9491 is build id of dev300m76
     768           0 :                     bResult= true;
     769             :             }
     770           0 :             else if( aGenerator.indexOf( "OpenOffice.org_project/310m" ) != -1 )
     771           0 :                 bResult= true;
     772           0 :             else if( aGenerator.indexOf( "OpenOffice.org_project/320m" ) != -1 )
     773           0 :                 bResult= true;
     774           3 :         }
     775             :     }
     776           3 :     return bResult;
     777             : }
     778             : 
     779         282 : bool isDocumentGeneratedWithOpenOfficeOlderThan3_0( const uno::Reference< frame::XModel >& xChartModel )
     780             : {
     781         282 :     bool bResult = isDocumentGeneratedWithOpenOfficeOlderThan2_3( xChartModel );
     782         282 :     if( !bResult )
     783             :     {
     784         282 :         OUString aGenerator( lcl_getGeneratorFromModel(xChartModel) );
     785         282 :         if( aGenerator.indexOf( "OpenOffice.org_project/680m" ) != -1 )
     786           0 :             bResult= true;
     787             :     }
     788         282 :     return bResult;
     789             : }
     790             : 
     791         193 : bool isDocumentGeneratedWithOpenOfficeOlderThan2_4( const uno::Reference< frame::XModel >& xChartModel )
     792             : {
     793         193 :     if( isDocumentGeneratedWithOpenOfficeOlderThan2_3( xChartModel ) )
     794           0 :         return true;
     795             : 
     796         193 :     if( isDocumentGeneratedWithOpenOfficeOlderThan3_0( xChartModel ) )
     797             :     {
     798           0 :         sal_Int32 nBuilId = lcl_getBuildIDFromGenerator( lcl_getGeneratorFromModel(xChartModel) );
     799           0 :         if( nBuilId>0 && nBuilId<=9238 ) //9238 is build id of OpenOffice.org 2.3.1
     800           0 :             return true;
     801             :     }
     802         193 :     return false;
     803             : }
     804             : 
     805         799 : bool isDocumentGeneratedWithOpenOfficeOlderThan2_3( const uno::Reference< frame::XModel >& xChartModel )
     806             : {
     807         799 :     bool bResult = false;
     808         799 :     OUString aGenerator( lcl_getGeneratorFromModel(xChartModel) );
     809             :     //if there is a meta stream at the chart object it was not written with an older OpenOffice version < 2.3
     810         799 :     if( aGenerator.isEmpty() )
     811             :     {
     812             :         //if there is no meta stream at the chart object we need to check whether the parent document is OpenOffice at all
     813          37 :         uno::Reference< container::XChild > xChild( xChartModel, uno::UNO_QUERY );
     814          37 :         if( xChild.is() )
     815             :         {
     816          37 :             aGenerator = lcl_getGeneratorFromModel( uno::Reference< frame::XModel >( xChild->getParent(), uno::UNO_QUERY) );
     817          37 :             if( aGenerator.indexOf( "OpenOffice.org_project" ) != -1 )
     818             :             {
     819             :                 //the chart application has not created files without a meta stream since OOo 2.3 (OOo 2.3 has written a metastream already)
     820             :                 //only the report builder extension has created some files with OOo 3.1 that do not have a meta stream
     821           0 :                 if( aGenerator.indexOf( "OpenOffice.org_project/31" ) != -1 )
     822           0 :                     bResult = false;//#i100102# probably generated with OOo 3.1 by the report designer
     823             :                 else
     824           0 :                     bResult= true; //in this case the OLE chart was created by an older version, as OLE objects are sometimes stream copied the version can differ from the parents version, so the parents version is not a reliable indicator
     825             :             }
     826          37 :             else if( isDocumentGeneratedWithOpenOfficeOlderThan2_0(xChartModel) )
     827           0 :                 bResult= true;
     828          37 :         }
     829             :     }
     830         799 :     return bResult;
     831             : }
     832             : 
     833          37 : bool isDocumentGeneratedWithOpenOfficeOlderThan2_0( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xChartModel)
     834             : {
     835          37 :     bool bResult = false;
     836          37 :     OUString aGenerator( lcl_getGeneratorFromModelOrItsParent(xChartModel) );
     837          74 :     if(    aGenerator.startsWith( "OpenOffice.org 1" )
     838          37 :         || aGenerator.startsWith( "StarOffice 6" )
     839          37 :         || aGenerator.startsWith( "StarOffice 7" )
     840          37 :         || aGenerator.startsWith( "StarSuite 6" )
     841          74 :         || aGenerator.startsWith( "StarSuite 7" )
     842             :         )
     843           0 :         bResult= true;
     844          37 :     return bResult;
     845             : }
     846             : 
     847           0 : Reference< chart2::data::XDataProvider > getDataProviderFromParent( const Reference< chart2::XChartDocument >& xChartDoc )
     848             : {
     849           0 :     Reference< chart2::data::XDataProvider > xRet;
     850           0 :     uno::Reference< container::XChild > xChild( xChartDoc, uno::UNO_QUERY );
     851           0 :     if( xChild.is() )
     852             :     {
     853           0 :         Reference< lang::XMultiServiceFactory > xFact( xChild->getParent(), uno::UNO_QUERY );
     854           0 :         if( xFact.is() )
     855             :         {
     856           0 :             const OUString aDataProviderServiceName( "com.sun.star.chart2.data.DataProvider");
     857           0 :             const uno::Sequence< OUString > aServiceNames( xFact->getAvailableServiceNames());
     858           0 :             const OUString * pBegin = aServiceNames.getConstArray();
     859           0 :             const OUString * pEnd = pBegin + aServiceNames.getLength();
     860           0 :             if( ::std::find( pBegin, pEnd, aDataProviderServiceName ) != pEnd )
     861             :             {
     862           0 :                 xRet = Reference< chart2::data::XDataProvider >(
     863           0 :                     xFact->createInstance( aDataProviderServiceName ), uno::UNO_QUERY );
     864           0 :             }
     865           0 :         }
     866             :     }
     867           0 :     return xRet;
     868             : }
     869             : 
     870             : } // namespace SchXMLTools
     871             : 
     872             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11