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

Generated by: LCOV version 1.10