LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/filter/excel - xichart.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1622 2283 71.0 %
Date: 2013-07-09 Functions: 221 270 81.9 %
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 "xichart.hxx"
      21             : 
      22             : #include <algorithm>
      23             : #include <memory>
      24             : 
      25             : #include <com/sun/star/frame/XModel.hpp>
      26             : #include <com/sun/star/drawing/Direction3D.hpp>
      27             : #include <com/sun/star/drawing/ProjectionMode.hpp>
      28             : #include <com/sun/star/drawing/ShadeMode.hpp>
      29             : #include <com/sun/star/drawing/XShape.hpp>
      30             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      31             : #include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
      32             : #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
      33             : #include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
      34             : #include <com/sun/star/chart/ChartAxisPosition.hpp>
      35             : #include <com/sun/star/chart/ChartLegendExpansion.hpp>
      36             : #include <com/sun/star/chart/TimeInterval.hpp>
      37             : #include <com/sun/star/chart/TimeUnit.hpp>
      38             : #include <com/sun/star/chart/XChartDocument.hpp>
      39             : #include <com/sun/star/chart/XDiagramPositioning.hpp>
      40             : #include <com/sun/star/chart/DataLabelPlacement.hpp>
      41             : #include <com/sun/star/chart/ErrorBarStyle.hpp>
      42             : #include <com/sun/star/chart/MissingValueTreatment.hpp>
      43             : #include <com/sun/star/chart2/LinearRegressionCurve.hpp>
      44             : #include <com/sun/star/chart2/ExponentialRegressionCurve.hpp>
      45             : #include <com/sun/star/chart2/LogarithmicRegressionCurve.hpp>
      46             : #include <com/sun/star/chart2/PotentialRegressionCurve.hpp>
      47             : #include <com/sun/star/chart2/PolynomialRegressionCurve.hpp>
      48             : #include <com/sun/star/chart2/MovingAverageRegressionCurve.hpp>
      49             : #include <com/sun/star/chart2/CartesianCoordinateSystem2d.hpp>
      50             : #include <com/sun/star/chart2/CartesianCoordinateSystem3d.hpp>
      51             : #include <com/sun/star/chart2/FormattedString.hpp>
      52             : #include <com/sun/star/chart2/LogarithmicScaling.hpp>
      53             : #include <com/sun/star/chart2/LinearScaling.hpp>
      54             : #include <com/sun/star/chart2/PolarCoordinateSystem2d.hpp>
      55             : #include <com/sun/star/chart2/PolarCoordinateSystem3d.hpp>
      56             : #include <com/sun/star/chart2/XChartDocument.hpp>
      57             : #include <com/sun/star/chart2/XDiagram.hpp>
      58             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      59             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      60             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      61             : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
      62             : #include <com/sun/star/chart2/XTitled.hpp>
      63             : #include <com/sun/star/chart2/AxisType.hpp>
      64             : #include <com/sun/star/chart2/CurveStyle.hpp>
      65             : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
      66             : #include <com/sun/star/chart2/DataPointLabel.hpp>
      67             : #include <com/sun/star/chart2/LegendPosition.hpp>
      68             : #include <com/sun/star/chart2/StackingDirection.hpp>
      69             : #include <com/sun/star/chart2/TickmarkStyle.hpp>
      70             : #include <com/sun/star/chart2/RelativePosition.hpp>
      71             : #include <com/sun/star/chart2/RelativeSize.hpp>
      72             : #include <com/sun/star/chart2/data/XDataProvider.hpp>
      73             : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
      74             : #include <com/sun/star/chart2/data/XDataSink.hpp>
      75             : #include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
      76             : 
      77             : #include <sfx2/objsh.hxx>
      78             : #include <svx/svdpage.hxx>
      79             : #include <svx/unoapi.hxx>
      80             : 
      81             : #include "document.hxx"
      82             : #include "drwlayer.hxx"
      83             : #include "rangeutl.hxx"
      84             : #include "tokenarray.hxx"
      85             : #include "token.hxx"
      86             : #include "compiler.hxx"
      87             : #include "reftokenhelper.hxx"
      88             : #include "chartlis.hxx"
      89             : #include "fprogressbar.hxx"
      90             : #include "xltracer.hxx"
      91             : #include "xistream.hxx"
      92             : #include "xiformula.hxx"
      93             : #include "xistyle.hxx"
      94             : #include "xipage.hxx"
      95             : #include "xiview.hxx"
      96             : 
      97             : using ::com::sun::star::uno::Any;
      98             : using ::com::sun::star::uno::Reference;
      99             : using ::com::sun::star::uno::Sequence;
     100             : using ::com::sun::star::uno::UNO_QUERY;
     101             : using ::com::sun::star::uno::UNO_QUERY_THROW;
     102             : using ::com::sun::star::uno::UNO_SET_THROW;
     103             : using ::com::sun::star::uno::Exception;
     104             : using ::com::sun::star::beans::XPropertySet;
     105             : using ::com::sun::star::lang::XMultiServiceFactory;
     106             : using ::com::sun::star::frame::XModel;
     107             : using ::com::sun::star::util::XNumberFormatsSupplier;
     108             : using ::com::sun::star::drawing::XDrawPage;
     109             : using ::com::sun::star::drawing::XDrawPageSupplier;
     110             : using ::com::sun::star::drawing::XShape;
     111             : 
     112             : using namespace ::com::sun::star::chart2;
     113             : 
     114             : using ::com::sun::star::chart2::data::XDataProvider;
     115             : using ::com::sun::star::chart2::data::XDataReceiver;
     116             : using ::com::sun::star::chart2::data::XDataSequence;
     117             : using ::com::sun::star::chart2::data::XDataSink;
     118             : using ::com::sun::star::chart2::data::XLabeledDataSequence;
     119             : using ::com::sun::star::chart2::data::LabeledDataSequence;
     120             : 
     121             : using ::formula::FormulaToken;
     122             : using ::formula::StackVar;
     123             : using ::boost::shared_ptr;
     124             : using ::std::pair;
     125             : using ::std::auto_ptr;
     126             : 
     127             : namespace cssc = ::com::sun::star::chart;
     128             : namespace cssc2 = ::com::sun::star::chart2;
     129             : 
     130             : // Helpers ====================================================================
     131             : 
     132             : namespace {
     133             : 
     134         288 : XclImpStream& operator>>( XclImpStream& rStrm, XclChRectangle& rRect )
     135             : {
     136         288 :     return rStrm >> rRect.mnX >> rRect.mnY >> rRect.mnWidth >> rRect.mnHeight;
     137             : }
     138             : 
     139         120 : inline void lclSetValueOrClearAny( Any& rAny, double fValue, bool bClear )
     140             : {
     141         120 :     if( bClear )
     142         120 :         rAny.clear();
     143             :     else
     144           0 :         rAny <<= fValue;
     145         120 : }
     146             : 
     147          80 : void lclSetExpValueOrClearAny( Any& rAny, double fValue, bool bLogScale, bool bClear )
     148             : {
     149          80 :     if( !bClear && bLogScale )
     150           0 :         fValue = pow( 10.0, fValue );
     151          80 :     lclSetValueOrClearAny( rAny, fValue, bClear );
     152          80 : }
     153             : 
     154           0 : double lclGetSerialDay( const XclImpRoot& rRoot, sal_uInt16 nValue, sal_uInt16 nTimeUnit )
     155             : {
     156           0 :     switch( nTimeUnit )
     157             :     {
     158             :         case EXC_CHDATERANGE_DAYS:
     159           0 :             return nValue;
     160             :         case EXC_CHDATERANGE_MONTHS:
     161           0 :             return rRoot.GetDoubleFromDateTime( Date( 1, static_cast< sal_uInt16 >( 1 + nValue % 12 ), static_cast< sal_uInt16 >( rRoot.GetBaseYear() + nValue / 12 ) ) );
     162             :         case EXC_CHDATERANGE_YEARS:
     163           0 :             return rRoot.GetDoubleFromDateTime( Date( 1, 1, static_cast< sal_uInt16 >( rRoot.GetBaseYear() + nValue ) ) );
     164             :         default:
     165             :             OSL_ENSURE( false, "lclGetSerialDay - unexpected time unit" );
     166             :     }
     167           0 :     return nValue;
     168             : }
     169             : 
     170           0 : void lclConvertTimeValue( const XclImpRoot& rRoot, Any& rAny, sal_uInt16 nValue, bool bAuto, sal_uInt16 nTimeUnit )
     171             : {
     172           0 :     if( bAuto )
     173           0 :         rAny.clear();
     174             :     else
     175           0 :         rAny <<= lclGetSerialDay( rRoot, nValue, nTimeUnit );
     176           0 : }
     177             : 
     178           0 : sal_Int32 lclGetApiTimeUnit( sal_uInt16 nTimeUnit )
     179             : {
     180           0 :     switch( nTimeUnit )
     181             :     {
     182           0 :         case EXC_CHDATERANGE_DAYS:      return cssc::TimeUnit::DAY;
     183           0 :         case EXC_CHDATERANGE_MONTHS:    return cssc::TimeUnit::MONTH;
     184           0 :         case EXC_CHDATERANGE_YEARS:     return cssc::TimeUnit::YEAR;
     185             :         default:                        OSL_ENSURE( false, "lclGetApiTimeUnit - unexpected time unit" );
     186             :     }
     187           0 :     return cssc::TimeUnit::DAY;
     188             : }
     189             : 
     190           0 : void lclConvertTimeInterval( Any& rInterval, sal_uInt16 nValue, bool bAuto, sal_uInt16 nTimeUnit )
     191             : {
     192           0 :     if( bAuto || (nValue == 0) )
     193           0 :         rInterval.clear();
     194             :     else
     195           0 :         rInterval <<= cssc::TimeInterval( nValue, lclGetApiTimeUnit( nTimeUnit ) );
     196           0 : }
     197             : 
     198           0 : bool lcl_IsForceIntercept(double intercept)
     199             : {
     200           0 :     sal_math_Double* pIntercept = reinterpret_cast<sal_math_Double*>(&intercept);
     201           0 :     return (pIntercept->w32_parts.msw != 0xFFFFFFFF ||
     202           0 :             pIntercept->w32_parts.lsw != 0xFFFFFFFF);
     203             : }
     204             : 
     205             : } // namespace
     206             : 
     207             : // Common =====================================================================
     208             : 
     209             : /** Stores global data needed in various classes of the Chart import filter. */
     210          80 : struct XclImpChRootData : public XclChRootData
     211             : {
     212             :     XclImpChChart&      mrChartData;            /// The chart data object.
     213             : 
     214          40 :     inline explicit     XclImpChRootData( XclImpChChart& rChartData ) : mrChartData( rChartData ) {}
     215             : };
     216             : 
     217             : // ----------------------------------------------------------------------------
     218             : 
     219          40 : XclImpChRoot::XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData ) :
     220             :     XclImpRoot( rRoot ),
     221          40 :     mxChData( new XclImpChRootData( rChartData ) )
     222             : {
     223          40 : }
     224             : 
     225        1562 : XclImpChRoot::~XclImpChRoot()
     226             : {
     227        1562 : }
     228             : 
     229         417 : XclImpChChart& XclImpChRoot::GetChartData() const
     230             : {
     231         417 :     return mxChData->mrChartData;
     232             : }
     233             : 
     234          79 : const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
     235             : {
     236          79 :     return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
     237             : }
     238             : 
     239           1 : const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( sal_uInt16 nRecId ) const
     240             : {
     241           1 :     return mxChData->mxTypeInfoProv->GetTypeInfoFromRecId( nRecId );
     242             : }
     243             : 
     244        1101 : const XclChFormatInfo& XclImpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
     245             : {
     246        1101 :     return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
     247             : }
     248             : 
     249          84 : Color XclImpChRoot::GetFontAutoColor() const
     250             : {
     251          84 :     return GetPalette().GetColor( EXC_COLOR_CHWINDOWTEXT );
     252             : }
     253             : 
     254           2 : Color XclImpChRoot::GetSeriesLineAutoColor( sal_uInt16 nFormatIdx ) const
     255             : {
     256           2 :     return GetPalette().GetColor( XclChartHelper::GetSeriesLineAutoColorIdx( nFormatIdx ) );
     257             : }
     258             : 
     259           1 : Color XclImpChRoot::GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const
     260             : {
     261           1 :     const XclImpPalette& rPal = GetPalette();
     262           1 :     Color aColor = rPal.GetColor( XclChartHelper::GetSeriesFillAutoColorIdx( nFormatIdx ) );
     263           1 :     sal_uInt8 nTrans = XclChartHelper::GetSeriesFillAutoTransp( nFormatIdx );
     264           1 :     return ScfTools::GetMixedColor( aColor, rPal.GetColor( EXC_COLOR_CHWINDOWBACK ), nTrans );
     265             : }
     266             : 
     267          40 : void XclImpChRoot::InitConversion( const Reference<XChartDocument>& xChartDoc, const Rectangle& rChartRect ) const
     268             : {
     269             :     // create formatting object tables
     270          40 :     mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
     271             : 
     272             :     // lock the model to suppress any internal updates
     273          40 :     if( xChartDoc.is() )
     274          40 :         xChartDoc->lockControllers();
     275             : 
     276          40 :     SfxObjectShell* pDocShell = GetDocShell();
     277          40 :     Reference< XDataReceiver > xDataRec( xChartDoc, UNO_QUERY );
     278          40 :     if( pDocShell && xDataRec.is() )
     279             :     {
     280             :         // create and register a data provider
     281             :         Reference< XDataProvider > xDataProv(
     282          40 :             ScfApiHelper::CreateInstance( pDocShell, SERVICE_CHART2_DATAPROVIDER ), UNO_QUERY );
     283          40 :         if( xDataProv.is() )
     284          40 :             xDataRec->attachDataProvider( xDataProv );
     285             :         // attach the number formatter
     286          80 :         Reference< XNumberFormatsSupplier > xNumFmtSupp( pDocShell->GetModel(), UNO_QUERY );
     287          40 :         if( xNumFmtSupp.is() )
     288          80 :             xDataRec->attachNumberFormatsSupplier( xNumFmtSupp );
     289          40 :     }
     290          40 : }
     291             : 
     292          40 : void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const
     293             : {
     294          40 :     rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
     295             :     // unlock the model
     296          40 :     Reference< XModel > xModel( mxChData->mxChartDoc, UNO_QUERY );
     297          40 :     if( xModel.is() )
     298          40 :         xModel->unlockControllers();
     299          40 :     rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
     300             : 
     301          40 :     mxChData->FinishConversion();
     302          40 : }
     303             : 
     304         120 : Reference< XDataProvider > XclImpChRoot::GetDataProvider() const
     305             : {
     306         120 :     return mxChData->mxChartDoc->getDataProvider();
     307             : }
     308             : 
     309          20 : Reference< XShape > XclImpChRoot::GetTitleShape( const XclChTextKey& rTitleKey ) const
     310             : {
     311          20 :     return mxChData->GetTitleShape( rTitleKey );
     312             : }
     313             : 
     314         118 : sal_Int32 XclImpChRoot::CalcHmmFromChartX( sal_Int32 nPosX ) const
     315             : {
     316         118 :     return static_cast< sal_Int32 >( mxChData->mfUnitSizeX * nPosX + mxChData->mnBorderGapX + 0.5 );
     317             : }
     318             : 
     319         118 : sal_Int32 XclImpChRoot::CalcHmmFromChartY( sal_Int32 nPosY ) const
     320             : {
     321         118 :     return static_cast< sal_Int32 >( mxChData->mfUnitSizeY * nPosY + mxChData->mnBorderGapY + 0.5 );
     322             : }
     323             : 
     324          39 : ::com::sun::star::awt::Rectangle XclImpChRoot::CalcHmmFromChartRect( const XclChRectangle& rRect ) const
     325             : {
     326             :     return ::com::sun::star::awt::Rectangle(
     327          39 :         CalcHmmFromChartX( rRect.mnX ),
     328          39 :         CalcHmmFromChartY( rRect.mnY ),
     329          39 :         CalcHmmFromChartX( rRect.mnWidth ),
     330         156 :         CalcHmmFromChartY( rRect.mnHeight ) );
     331             : }
     332             : 
     333          39 : double XclImpChRoot::CalcRelativeFromHmmX( sal_Int32 nPosX ) const
     334             : {
     335          39 :     return static_cast< double >( nPosX ) / mxChData->maChartRect.GetWidth();
     336             : }
     337             : 
     338          39 : double XclImpChRoot::CalcRelativeFromHmmY( sal_Int32 nPosY ) const
     339             : {
     340          39 :     return static_cast< double >( nPosY ) / mxChData->maChartRect.GetHeight();
     341             : }
     342             : 
     343          20 : double XclImpChRoot::CalcRelativeFromChartX( sal_Int32 nPosX ) const
     344             : {
     345          20 :     return CalcRelativeFromHmmX( CalcHmmFromChartX( nPosX ) );
     346             : }
     347             : 
     348          20 : double XclImpChRoot::CalcRelativeFromChartY( sal_Int32 nPosY ) const
     349             : {
     350          20 :     return CalcRelativeFromHmmY( CalcHmmFromChartY( nPosY ) );
     351             : }
     352             : 
     353         299 : void XclImpChRoot::ConvertLineFormat( ScfPropertySet& rPropSet,
     354             :         const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode ) const
     355             : {
     356         299 :     GetChartPropSetHelper().WriteLineProperties(
     357         598 :         rPropSet, *mxChData->mxLineDashTable, rLineFmt, ePropMode );
     358         299 : }
     359             : 
     360         121 : void XclImpChRoot::ConvertAreaFormat( ScfPropertySet& rPropSet,
     361             :         const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode ) const
     362             : {
     363         121 :     GetChartPropSetHelper().WriteAreaProperties( rPropSet, rAreaFmt, ePropMode );
     364         121 : }
     365             : 
     366         150 : void XclImpChRoot::ConvertEscherFormat( ScfPropertySet& rPropSet,
     367             :         const XclChEscherFormat& rEscherFmt, const XclChPicFormat* pPicFmt,
     368             :         sal_uInt32 nDffFillType, XclChPropertyMode ePropMode ) const
     369             : {
     370         150 :     GetChartPropSetHelper().WriteEscherProperties( rPropSet,
     371         150 :         *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable,
     372         150 :         rEscherFmt, pPicFmt, nDffFillType, ePropMode );
     373         150 : }
     374             : 
     375         181 : void XclImpChRoot::ConvertFont( ScfPropertySet& rPropSet,
     376             :         sal_uInt16 nFontIdx, const Color* pFontColor ) const
     377             : {
     378         181 :     GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CHART, nFontIdx, pFontColor );
     379         181 : }
     380             : 
     381          37 : void XclImpChRoot::ConvertPieRotation( ScfPropertySet& rPropSet, sal_uInt16 nAngle )
     382             : {
     383          37 :     sal_Int32 nApiRot = (450 - (nAngle % 360)) % 360;
     384          37 :     rPropSet.SetProperty( EXC_CHPROP_STARTINGANGLE, nApiRot );
     385          37 : }
     386             : 
     387             : // ----------------------------------------------------------------------------
     388             : 
     389         998 : XclImpChGroupBase::~XclImpChGroupBase()
     390             : {
     391         998 : }
     392             : 
     393         722 : void XclImpChGroupBase::ReadRecordGroup( XclImpStream& rStrm )
     394             : {
     395             :     // read contents of the header record
     396         722 :     ReadHeaderRecord( rStrm );
     397             : 
     398             :     // only read sub records, if the next record is a CHBEGIN
     399         722 :     if( rStrm.GetNextRecId() == EXC_ID_CHBEGIN )
     400             :     {
     401             :         // read the CHBEGIN record, may be used for special initial processing
     402         627 :         rStrm.StartNextRecord();
     403         627 :         ReadSubRecord( rStrm );
     404             : 
     405             :         // read the nested records
     406         627 :         bool bLoop = true;
     407        6191 :         while( bLoop && rStrm.StartNextRecord() )
     408             :         {
     409        4937 :             sal_uInt16 nRecId = rStrm.GetRecId();
     410        4937 :             bLoop = nRecId != EXC_ID_CHEND;
     411             :             // skip unsupported nested blocks
     412        4937 :             if( nRecId == EXC_ID_CHBEGIN )
     413          30 :                 SkipBlock( rStrm );
     414             :             else
     415        4907 :                 ReadSubRecord( rStrm );
     416             :         }
     417             :     }
     418             :     /*  Returns with current CHEND record or unchanged stream, if no record
     419             :         group present. In every case another call to StartNextRecord() will go
     420             :         to next record of interest. */
     421         722 : }
     422             : 
     423          60 : void XclImpChGroupBase::SkipBlock( XclImpStream& rStrm )
     424             : {
     425             :     OSL_ENSURE( rStrm.GetRecId() == EXC_ID_CHBEGIN, "XclImpChGroupBase::SkipBlock - no CHBEGIN record" );
     426             :     // do nothing if current record is not CHBEGIN
     427          60 :     bool bLoop = rStrm.GetRecId() == EXC_ID_CHBEGIN;
     428         420 :     while( bLoop && rStrm.StartNextRecord() )
     429             :     {
     430         300 :         sal_uInt16 nRecId = rStrm.GetRecId();
     431         300 :         bLoop = nRecId != EXC_ID_CHEND;
     432             :         // skip nested record groups
     433         300 :         if( nRecId == EXC_ID_CHBEGIN )
     434          30 :             SkipBlock( rStrm );
     435             :     }
     436          60 : }
     437             : 
     438             : // Frame formatting ===========================================================
     439             : 
     440         248 : void XclImpChFramePos::ReadChFramePos( XclImpStream& rStrm )
     441             : {
     442         248 :     rStrm >> maData.mnTLMode >> maData.mnBRMode;
     443             :     /*  According to the spec, the upper 16 bits of all members in the
     444             :         rectangle are unused and may contain garbage. */
     445         248 :     maData.maRect.mnX = rStrm.ReadInt16(); rStrm.Ignore( 2 );
     446         248 :     maData.maRect.mnY = rStrm.ReadInt16(); rStrm.Ignore( 2 );
     447         248 :     maData.maRect.mnWidth = rStrm.ReadInt16(); rStrm.Ignore( 2 );
     448         248 :     maData.maRect.mnHeight = rStrm.ReadInt16(); rStrm.Ignore( 2 );
     449         248 : }
     450             : 
     451             : // ----------------------------------------------------------------------------
     452             : 
     453         255 : void XclImpChLineFormat::ReadChLineFormat( XclImpStream& rStrm )
     454             : {
     455         255 :     rStrm >> maData.maColor >> maData.mnPattern >> maData.mnWeight >> maData.mnFlags;
     456             : 
     457         255 :     const XclImpRoot& rRoot = rStrm.GetRoot();
     458         255 :     if( rRoot.GetBiff() == EXC_BIFF8 )
     459             :         // BIFF8: index into palette used instead of RGB data
     460         255 :         maData.maColor = rRoot.GetPalette().GetColor( rStrm.ReaduInt16() );
     461         255 : }
     462             : 
     463         299 : void XclImpChLineFormat::Convert( const XclImpChRoot& rRoot,
     464             :         ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
     465             : {
     466         299 :     const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
     467         299 :     if( IsAuto() )
     468             :     {
     469          88 :         XclChLineFormat aLineFmt;
     470             :         aLineFmt.maColor = (eObjType == EXC_CHOBJTYPE_LINEARSERIES) ?
     471           1 :             rRoot.GetSeriesLineAutoColor( nFormatIdx ) :
     472          89 :             rRoot.GetPalette().GetColor( rFmtInfo.mnAutoLineColorIdx );
     473          88 :         aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
     474          88 :         aLineFmt.mnWeight = rFmtInfo.mnAutoLineWeight;
     475          88 :         rRoot.ConvertLineFormat( rPropSet, aLineFmt, rFmtInfo.mePropMode );
     476             :     }
     477             :     else
     478             :     {
     479         211 :         rRoot.ConvertLineFormat( rPropSet, maData, rFmtInfo.mePropMode );
     480             :     }
     481         299 : }
     482             : 
     483             : // ----------------------------------------------------------------------------
     484             : 
     485         253 : void XclImpChAreaFormat::ReadChAreaFormat( XclImpStream& rStrm )
     486             : {
     487         253 :     rStrm >> maData.maPattColor >> maData.maBackColor >> maData.mnPattern >> maData.mnFlags;
     488             : 
     489         253 :     const XclImpRoot& rRoot = rStrm.GetRoot();
     490         253 :     if( rRoot.GetBiff() == EXC_BIFF8 )
     491             :     {
     492             :         // BIFF8: index into palette used instead of RGB data
     493         253 :         const XclImpPalette& rPal = rRoot.GetPalette();
     494         253 :         maData.maPattColor = rPal.GetColor( rStrm.ReaduInt16() );
     495         253 :         maData.maBackColor = rPal.GetColor( rStrm.ReaduInt16());
     496             :     }
     497         253 : }
     498             : 
     499         121 : void XclImpChAreaFormat::Convert( const XclImpChRoot& rRoot,
     500             :         ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
     501             : {
     502         121 :     const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
     503         121 :     if( IsAuto() )
     504             :     {
     505           5 :         XclChAreaFormat aAreaFmt;
     506             :         aAreaFmt.maPattColor = (eObjType == EXC_CHOBJTYPE_FILLEDSERIES) ?
     507           1 :             rRoot.GetSeriesFillAutoColor( nFormatIdx ) :
     508           6 :             rRoot.GetPalette().GetColor( rFmtInfo.mnAutoPattColorIdx );
     509           5 :         aAreaFmt.mnPattern = EXC_PATT_SOLID;
     510           5 :         rRoot.ConvertAreaFormat( rPropSet, aAreaFmt, rFmtInfo.mePropMode );
     511             :     }
     512             :     else
     513             :     {
     514         116 :         rRoot.ConvertAreaFormat( rPropSet, maData, rFmtInfo.mePropMode );
     515             :     }
     516         121 : }
     517             : 
     518             : // ----------------------------------------------------------------------------
     519             : 
     520          95 : XclImpChEscherFormat::XclImpChEscherFormat( const XclImpRoot& rRoot ) :
     521          95 :     mnDffFillType( mso_fillSolid )
     522             : {
     523             :     maData.mxItemSet.reset(
     524          95 :         new SfxItemSet( rRoot.GetDoc().GetDrawLayer()->GetItemPool() ) );
     525          95 : }
     526             : 
     527          95 : void XclImpChEscherFormat::ReadHeaderRecord( XclImpStream& rStrm )
     528             : {
     529             :     // read from stream - CHESCHERFORMAT uses own ID for record continuation
     530          95 :     XclImpDffPropSet aPropSet( rStrm.GetRoot() );
     531          95 :     rStrm.ResetRecord( true, rStrm.GetRecId() );
     532          95 :     rStrm >> aPropSet;
     533             :     // get the data
     534          95 :     aPropSet.FillToItemSet( *maData.mxItemSet );
     535             :     // get fill type from DFF property set
     536          95 :     mnDffFillType = aPropSet.GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
     537          95 : }
     538             : 
     539           0 : void XclImpChEscherFormat::ReadSubRecord( XclImpStream& rStrm )
     540             : {
     541           0 :     switch( rStrm.GetRecId() )
     542             :     {
     543             :         case EXC_ID_CHPICFORMAT:
     544           0 :             rStrm >> maPicFmt.mnBmpMode;
     545           0 :             rStrm.Ignore( 2 );
     546           0 :             rStrm >> maPicFmt.mnFlags >> maPicFmt.mfScale;
     547           0 :         break;
     548             :     }
     549           0 : }
     550             : 
     551         150 : void XclImpChEscherFormat::Convert( const XclImpChRoot& rRoot,
     552             :         ScfPropertySet& rPropSet, XclChObjectType eObjType, bool bUsePicFmt ) const
     553             : {
     554         150 :     const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
     555         150 :     rRoot.ConvertEscherFormat( rPropSet, maData, bUsePicFmt ? &maPicFmt : 0, mnDffFillType, rFmtInfo.mePropMode );
     556         150 : }
     557             : 
     558             : // ----------------------------------------------------------------------------
     559             : 
     560         259 : XclImpChFrameBase::XclImpChFrameBase( const XclChFormatInfo& rFmtInfo )
     561             : {
     562         259 :     if( rFmtInfo.mbCreateDefFrame ) switch( rFmtInfo.meDefFrameType )
     563             :     {
     564             :         case EXC_CHFRAMETYPE_AUTO:
     565         101 :             mxLineFmt.reset( new XclImpChLineFormat );
     566         101 :             if( rFmtInfo.mbIsFrame )
     567         101 :                 mxAreaFmt.reset( new XclImpChAreaFormat );
     568         101 :         break;
     569             :         case EXC_CHFRAMETYPE_INVISIBLE:
     570             :         {
     571          80 :             XclChLineFormat aLineFmt;
     572          80 :             ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
     573          80 :             aLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
     574          80 :             mxLineFmt.reset( new XclImpChLineFormat( aLineFmt ) );
     575          80 :             if( rFmtInfo.mbIsFrame )
     576             :             {
     577          80 :                 XclChAreaFormat aAreaFmt;
     578          80 :                 ::set_flag( aAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
     579          80 :                 aAreaFmt.mnPattern = EXC_PATT_NONE;
     580          80 :                 mxAreaFmt.reset( new XclImpChAreaFormat( aAreaFmt ) );
     581             :             }
     582             :         }
     583          80 :         break;
     584             :         default:
     585             :             OSL_FAIL( "XclImpChFrameBase::XclImpChFrameBase - unknown frame type" );
     586             :     }
     587         259 : }
     588             : 
     589        2012 : void XclImpChFrameBase::ReadSubRecord( XclImpStream& rStrm )
     590             : {
     591        2012 :     switch( rStrm.GetRecId() )
     592             :     {
     593             :         case EXC_ID_CHLINEFORMAT:
     594         253 :             mxLineFmt.reset( new XclImpChLineFormat );
     595         253 :             mxLineFmt->ReadChLineFormat( rStrm );
     596         253 :         break;
     597             :         case EXC_ID_CHAREAFORMAT:
     598         253 :             mxAreaFmt.reset( new XclImpChAreaFormat );
     599         253 :             mxAreaFmt->ReadChAreaFormat( rStrm );
     600         253 :         break;
     601             :         case EXC_ID_CHESCHERFORMAT:
     602          95 :             mxEscherFmt.reset( new XclImpChEscherFormat( rStrm.GetRoot() ) );
     603          95 :             mxEscherFmt->ReadRecordGroup( rStrm );
     604          95 :         break;
     605             :     }
     606        2012 : }
     607             : 
     608         217 : void XclImpChFrameBase::ConvertLineBase( const XclImpChRoot& rRoot,
     609             :         ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const
     610             : {
     611         217 :     if( mxLineFmt )
     612         217 :         mxLineFmt->Convert( rRoot, rPropSet, eObjType, nFormatIdx );
     613         217 : }
     614             : 
     615         272 : void XclImpChFrameBase::ConvertAreaBase( const XclImpChRoot& rRoot,
     616             :         ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const
     617             : {
     618         272 :     if( rRoot.GetFormatInfo( eObjType ).mbIsFrame )
     619             :     {
     620             :         // CHESCHERFORMAT overrides CHAREAFORMAT (even if it is auto)
     621         271 :         if( mxEscherFmt )
     622         150 :             mxEscherFmt->Convert( rRoot, rPropSet, eObjType, bUsePicFmt );
     623         121 :         else if( mxAreaFmt )
     624         121 :             mxAreaFmt->Convert( rRoot, rPropSet, eObjType, nFormatIdx );
     625             :     }
     626         272 : }
     627             : 
     628         217 : void XclImpChFrameBase::ConvertFrameBase( const XclImpChRoot& rRoot,
     629             :         ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const
     630             : {
     631         217 :     ConvertLineBase( rRoot, rPropSet, eObjType, nFormatIdx );
     632         217 :     ConvertAreaBase( rRoot, rPropSet, eObjType, nFormatIdx, bUsePicFmt );
     633         217 : }
     634             : 
     635             : // ----------------------------------------------------------------------------
     636             : 
     637         259 : XclImpChFrame::XclImpChFrame( const XclImpChRoot& rRoot, XclChObjectType eObjType ) :
     638         259 :     XclImpChFrameBase( rRoot.GetFormatInfo( eObjType ) ),
     639             :     XclImpChRoot( rRoot ),
     640         259 :     meObjType( eObjType )
     641             : {
     642         259 : }
     643             : 
     644         139 : void XclImpChFrame::ReadHeaderRecord( XclImpStream& rStrm )
     645             : {
     646         139 :     rStrm >> maData.mnFormat >> maData.mnFlags;
     647         139 : }
     648             : 
     649           0 : void XclImpChFrame::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
     650             : {
     651           0 :     const XclImpPalette& rPal = GetPalette();
     652             : 
     653           0 :     if( rLineData.IsVisible() && (!mxLineFmt || !mxLineFmt->HasLine()) )
     654             :     {
     655             :         // line formatting
     656           0 :         XclChLineFormat aLineFmt;
     657           0 :         aLineFmt.maColor = rPal.GetColor( rLineData.mnColorIdx );
     658           0 :         switch( rLineData.mnStyle )
     659             :         {
     660           0 :             case EXC_OBJ_LINE_SOLID:        aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;        break;
     661           0 :             case EXC_OBJ_LINE_DASH:         aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASH;         break;
     662           0 :             case EXC_OBJ_LINE_DOT:          aLineFmt.mnPattern = EXC_CHLINEFORMAT_DOT;          break;
     663           0 :             case EXC_OBJ_LINE_DASHDOT:      aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASHDOT;      break;
     664           0 :             case EXC_OBJ_LINE_DASHDOTDOT:   aLineFmt.mnPattern = EXC_CHLINEFORMAT_DASHDOTDOT;   break;
     665           0 :             case EXC_OBJ_LINE_MEDTRANS:     aLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS;     break;
     666           0 :             case EXC_OBJ_LINE_DARKTRANS:    aLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS;    break;
     667           0 :             case EXC_OBJ_LINE_LIGHTTRANS:   aLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS;   break;
     668           0 :             case EXC_OBJ_LINE_NONE:         aLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;         break;
     669           0 :             default:                        aLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
     670             :         }
     671           0 :         switch( rLineData.mnWidth )
     672             :         {
     673           0 :             case EXC_OBJ_LINE_HAIR:     aLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;      break;
     674           0 :             case EXC_OBJ_LINE_THIN:     aLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE;    break;
     675           0 :             case EXC_OBJ_LINE_MEDIUM:   aLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE;    break;
     676           0 :             case EXC_OBJ_LINE_THICK:    aLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE;    break;
     677           0 :             default:                    aLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
     678             :         }
     679           0 :         ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, rLineData.IsAuto() );
     680           0 :         mxLineFmt.reset( new XclImpChLineFormat( aLineFmt ) );
     681             :     }
     682             : 
     683           0 :     if( rFillData.IsFilled() && (!mxAreaFmt || !mxAreaFmt->HasArea()) && !mxEscherFmt )
     684             :     {
     685             :         // area formatting
     686           0 :         XclChAreaFormat aAreaFmt;
     687           0 :         aAreaFmt.maPattColor = rPal.GetColor( rFillData.mnPattColorIdx );
     688           0 :         aAreaFmt.maBackColor = rPal.GetColor( rFillData.mnBackColorIdx );
     689           0 :         aAreaFmt.mnPattern = rFillData.mnPattern;
     690           0 :         ::set_flag( aAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, rFillData.IsAuto() );
     691           0 :         mxAreaFmt.reset( new XclImpChAreaFormat( aAreaFmt ) );
     692             :     }
     693           0 : }
     694             : 
     695         120 : void XclImpChFrame::Convert( ScfPropertySet& rPropSet, bool bUsePicFmt ) const
     696             : {
     697         120 :     ConvertFrameBase( GetChRoot(), rPropSet, meObjType, EXC_CHDATAFORMAT_UNKNOWN, bUsePicFmt );
     698         120 : }
     699             : 
     700             : // Source links ===============================================================
     701             : 
     702             : namespace {
     703             : 
     704             : /** Creates a labeled data sequence object, adds link for series title if present. */
     705          80 : Reference< XLabeledDataSequence > lclCreateLabeledDataSequence(
     706             :         const XclImpChSourceLinkRef& xValueLink, const OUString& rValueRole,
     707             :         const XclImpChSourceLink* pTitleLink = 0 )
     708             : {
     709             :     // create data sequence for values and title
     710          80 :     Reference< XDataSequence > xValueSeq;
     711          80 :     if( xValueLink )
     712          80 :         xValueSeq = xValueLink->CreateDataSequence( rValueRole );
     713         160 :     Reference< XDataSequence > xTitleSeq;
     714          80 :     if( pTitleLink )
     715          40 :         xTitleSeq = pTitleLink->CreateDataSequence( EXC_CHPROP_ROLE_LABEL );
     716             : 
     717             :     // create the labeled data sequence, if values or title are present
     718          80 :     Reference< XLabeledDataSequence > xLabeledSeq;
     719          80 :     if( xValueSeq.is() || xTitleSeq.is() )
     720          61 :         xLabeledSeq.set( LabeledDataSequence::create(comphelper::getProcessComponentContext()), UNO_QUERY );
     721          80 :     if( xLabeledSeq.is() )
     722             :     {
     723          61 :         if( xValueSeq.is() )
     724          61 :             xLabeledSeq->setValues( xValueSeq );
     725          61 :         if( xTitleSeq.is() )
     726          21 :             xLabeledSeq->setLabel( xTitleSeq );
     727             :     }
     728         160 :     return xLabeledSeq;
     729             : }
     730             : 
     731             : } // namespace
     732             : 
     733             : // ----------------------------------------------------------------------------
     734             : 
     735         347 : XclImpChSourceLink::XclImpChSourceLink( const XclImpChRoot& rRoot ) :
     736         347 :     XclImpChRoot( rRoot )
     737             : {
     738         347 : }
     739             : 
     740         694 : XclImpChSourceLink::~XclImpChSourceLink()
     741             : {
     742         694 : }
     743             : 
     744         347 : void XclImpChSourceLink::ReadChSourceLink( XclImpStream& rStrm )
     745             : {
     746         347 :     rStrm   >> maData.mnDestType
     747         694 :             >> maData.mnLinkType
     748         694 :             >> maData.mnFlags
     749         694 :             >> maData.mnNumFmtIdx;
     750             : 
     751         347 :     mxTokenArray.reset();
     752         347 :     if( GetLinkType() == EXC_CHSRCLINK_WORKSHEET )
     753             :     {
     754             :         // read token array
     755          82 :         XclTokenArray aXclTokArr;
     756          82 :         rStrm >> aXclTokArr;
     757             : 
     758             :         // convert BIFF formula tokens to Calc token array
     759          82 :         if( const ScTokenArray* pTokens = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CHART, aXclTokArr ) )
     760          82 :             mxTokenArray.reset( pTokens->Clone() );
     761             :     }
     762             : 
     763             :     // try to read a following CHSTRING record
     764         347 :     if( (rStrm.GetNextRecId() == EXC_ID_CHSTRING) && rStrm.StartNextRecord() )
     765             :     {
     766          36 :         mxString.reset( new XclImpString );
     767          36 :         rStrm.Ignore( 2 );
     768          36 :         mxString->Read( rStrm, EXC_STR_8BITLENGTH | EXC_STR_SEPARATEFORMATS );
     769             :     }
     770         347 : }
     771             : 
     772          19 : void XclImpChSourceLink::SetString( const String& rString )
     773             : {
     774          19 :     if( !mxString )
     775          19 :         mxString.reset( new XclImpString );
     776          19 :     mxString->SetText( rString );
     777          19 : }
     778             : 
     779           0 : void XclImpChSourceLink::SetTextFormats( const XclFormatRunVec& rFormats )
     780             : {
     781           0 :     if( mxString )
     782           0 :         mxString->SetFormats( rFormats );
     783           0 : }
     784             : 
     785          37 : sal_uInt16 XclImpChSourceLink::GetCellCount() const
     786             : {
     787          37 :     sal_uInt32 nCellCount = 0;
     788          37 :     if( mxTokenArray )
     789             :     {
     790          37 :         mxTokenArray->Reset();
     791          74 :         for( const FormulaToken* pToken = mxTokenArray->First(); pToken; pToken = mxTokenArray->Next() )
     792             :         {
     793          37 :             switch( pToken->GetType() )
     794             :             {
     795             :                 case ::formula::svSingleRef:
     796             :                 case ::formula::svExternalSingleRef:
     797             :                     // single cell
     798          19 :                     ++nCellCount;
     799          19 :                 break;
     800             :                 case ::formula::svDoubleRef:
     801             :                 case ::formula::svExternalDoubleRef:
     802             :                 {
     803             :                     // cell range
     804          18 :                     const ScComplexRefData& rComplexRef = static_cast< const ScToken* >( pToken )->GetDoubleRef();
     805          18 :                     const ScSingleRefData& rRef1 = rComplexRef.Ref1;
     806          18 :                     const ScSingleRefData& rRef2 = rComplexRef.Ref2;
     807          18 :                     sal_uInt32 nTabs = static_cast< sal_uInt32 >( rRef2.nTab - rRef1.nTab + 1 );
     808          18 :                     sal_uInt32 nCols = static_cast< sal_uInt32 >( rRef2.nCol - rRef1.nCol + 1 );
     809          18 :                     sal_uInt32 nRows = static_cast< sal_uInt32 >( rRef2.nRow - rRef1.nRow + 1 );
     810          18 :                     nCellCount += nCols * nRows * nTabs;
     811             :                 }
     812          18 :                 break;
     813             :                 default: ;
     814             :             }
     815             :         }
     816             :     }
     817          37 :     return limit_cast< sal_uInt16 >( nCellCount );
     818             : }
     819             : 
     820          46 : void XclImpChSourceLink::ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const
     821             : {
     822          46 :     bool bLinkToSource = ::get_flag( maData.mnFlags, EXC_CHSRCLINK_NUMFMT );
     823          46 :     sal_uInt32 nScNumFmt = bLinkToSource ? GetNumFmtBuffer().GetScFormat( maData.mnNumFmtIdx ) : NUMBERFORMAT_ENTRY_NOT_FOUND;
     824          46 :     OUString aPropName = bPercent ? OUString( EXC_CHPROP_PERCENTAGENUMFMT ) : OUString( EXC_CHPROP_NUMBERFORMAT );
     825          46 :     if( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
     826           0 :         rPropSet.SetProperty( aPropName, static_cast< sal_Int32 >( nScNumFmt ) );
     827             :     else
     828             :         // restore 'link to source' at data point (series may contain manual number format)
     829          46 :         rPropSet.SetAnyProperty( aPropName, Any() );
     830          46 : }
     831             : 
     832         120 : Reference< XDataSequence > XclImpChSourceLink::CreateDataSequence( const OUString& rRole ) const
     833             : {
     834         120 :     Reference< XDataSequence > xDataSeq;
     835         240 :     Reference< XDataProvider > xDataProv = GetDataProvider();
     836         120 :     if( xDataProv.is() && mxTokenArray )
     837             :     {
     838          82 :         ScCompiler aComp( GetDocPtr(), ScAddress(), *mxTokenArray );
     839          82 :         aComp.SetGrammar(GetDoc().GetGrammar());
     840         164 :         OUStringBuffer aRangeRep;
     841          82 :         aComp.CreateStringFromTokenArray( aRangeRep );
     842             :         try
     843             :         {
     844          82 :             xDataSeq = xDataProv->createDataSequenceByRangeRepresentation( aRangeRep.makeStringAndClear() );
     845             :             // set sequence role
     846          82 :             ScfPropertySet aSeqProp( xDataSeq );
     847          82 :             aSeqProp.SetProperty( EXC_CHPROP_ROLE, rRole );
     848             :         }
     849           0 :         catch( Exception& )
     850             :         {
     851             : //            OSL_FAIL( "XclImpChSourceLink::CreateDataSequence - cannot create data sequence" );
     852          82 :         }
     853             :     }
     854          38 :     else if( rRole == EXC_CHPROP_ROLE_LABEL && mxString && mxString->GetText().Len() )
     855             :     {
     856             :         try
     857             :         {
     858           0 :             OUString aString("\"");
     859           0 :             xDataSeq = xDataProv->createDataSequenceByRangeRepresentation( aString + mxString->GetText() + aString );
     860             :             // set sequence role
     861           0 :             ScfPropertySet aSeqProp( xDataSeq );
     862           0 :             aSeqProp.SetProperty( EXC_CHPROP_ROLE, rRole );
     863             :         }
     864           0 :         catch( Exception& ) { }
     865             :     }
     866         240 :     return xDataSeq;
     867             : }
     868             : 
     869          21 : Sequence< Reference< XFormattedString > > XclImpChSourceLink::CreateStringSequence(
     870             :         const XclImpChRoot& rRoot, sal_uInt16 nLeadFontIdx, const Color& rLeadFontColor ) const
     871             : {
     872          21 :     ::std::vector< Reference< XFormattedString > > aStringVec;
     873          21 :     if( mxString )
     874             :     {
     875          42 :         for( XclImpStringIterator aIt( *mxString ); aIt.Is(); ++aIt )
     876             :         {
     877          21 :             Reference< css::chart2::XFormattedString2 > xFmtStr = css::chart2::FormattedString::create( comphelper::getProcessComponentContext() );
     878             :             // set text data
     879          21 :             xFmtStr->setString( aIt.GetPortionText() );
     880             : 
     881             :             // set font formatting and font color
     882          42 :             ScfPropertySet aStringProp( xFmtStr );
     883          21 :             sal_uInt16 nFontIdx = aIt.GetPortionFont();
     884          21 :             if( (nFontIdx == EXC_FONT_NOTFOUND) && (aIt.GetPortionIndex() == 0) )
     885             :                 // leading unformatted portion - use passed font settings
     886          21 :                 rRoot.ConvertFont( aStringProp, nLeadFontIdx, &rLeadFontColor );
     887             :             else
     888           0 :                 rRoot.ConvertFont( aStringProp, nFontIdx );
     889             : 
     890             :             // add string to vector of strings
     891          21 :             aStringVec.push_back( xFmtStr );
     892          21 :         }
     893             :     }
     894          21 :     return ScfApiHelper::VectorToSequence( aStringVec );
     895             : }
     896             : 
     897         160 : void XclImpChSourceLink::FillSourceLink( ::std::vector< ScTokenRef >& rTokens ) const
     898             : {
     899         160 :     if( !mxTokenArray )
     900             :         // no links to fill.
     901         238 :         return;
     902             : 
     903          82 :     mxTokenArray->Reset();
     904         164 :     for (FormulaToken* p = mxTokenArray->First(); p; p = mxTokenArray->Next())
     905             :     {
     906          82 :         ScTokenRef pToken(static_cast<ScToken*>(p->Clone()));
     907          82 :         if (ScRefTokenHelper::isRef(pToken))
     908             :             // This is a reference token.  Store it.
     909          82 :             ScRefTokenHelper::join(rTokens, pToken);
     910          82 :     }
     911             : }
     912             : 
     913             : // Text =======================================================================
     914             : 
     915         267 : XclImpChFontBase::~XclImpChFontBase()
     916             : {
     917         267 : }
     918             : 
     919         160 : void XclImpChFontBase::ConvertFontBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const
     920             : {
     921         160 :     Color aFontColor = GetFontColor();
     922         160 :     rRoot.ConvertFont( rPropSet, GetFontIndex(), &aFontColor );
     923         160 : }
     924             : 
     925         160 : void XclImpChFontBase::ConvertRotationBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, bool bSupportsStacked ) const
     926             : {
     927         160 :     rRoot.GetChartPropSetHelper().WriteRotationProperties( rPropSet, GetRotation(), bSupportsStacked );
     928         160 : }
     929             : 
     930             : // ----------------------------------------------------------------------------
     931             : 
     932         181 : XclImpChFont::XclImpChFont() :
     933         181 :     mnFontIdx( EXC_FONT_NOTFOUND )
     934             : {
     935         181 : }
     936             : 
     937         181 : void XclImpChFont::ReadChFont( XclImpStream& rStrm )
     938             : {
     939         181 :     rStrm >> mnFontIdx;
     940         181 : }
     941             : 
     942             : // ----------------------------------------------------------------------------
     943             : 
     944         187 : XclImpChText::XclImpChText( const XclImpChRoot& rRoot ) :
     945         187 :     XclImpChRoot( rRoot )
     946             : {
     947         187 : }
     948             : 
     949         187 : void XclImpChText::ReadHeaderRecord( XclImpStream& rStrm )
     950             : {
     951         187 :     rStrm   >> maData.mnHAlign
     952         374 :             >> maData.mnVAlign
     953         374 :             >> maData.mnBackMode
     954         374 :             >> maData.maTextColor
     955         374 :             >> maData.maRect
     956         374 :             >> maData.mnFlags;
     957             : 
     958         187 :     if( GetBiff() == EXC_BIFF8 )
     959             :     {
     960             :         // BIFF8: index into palette used instead of RGB data
     961         187 :         maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() );
     962             :         // placement and rotation
     963         187 :         rStrm >> maData.mnFlags2 >> maData.mnRotation;
     964             :     }
     965             :     else
     966             :     {
     967             :         // BIFF2-BIFF7: get rotation from text orientation
     968           0 :         sal_uInt8 nOrient = ::extract_value< sal_uInt8 >( maData.mnFlags, 8, 3 );
     969           0 :         maData.mnRotation = XclTools::GetXclRotFromOrient( nOrient );
     970             :     }
     971         187 : }
     972             : 
     973        1418 : void XclImpChText::ReadSubRecord( XclImpStream& rStrm )
     974             : {
     975        1418 :     switch( rStrm.GetRecId() )
     976             :     {
     977             :         case EXC_ID_CHFRAMEPOS:
     978         187 :             mxFramePos.reset( new XclImpChFramePos );
     979         187 :             mxFramePos->ReadChFramePos( rStrm );
     980         187 :         break;
     981             :         case EXC_ID_CHFONT:
     982         179 :             mxFont.reset( new XclImpChFont );
     983         179 :             mxFont->ReadChFont( rStrm );
     984         179 :         break;
     985             :         case EXC_ID_CHFORMATRUNS:
     986           0 :             if( GetBiff() == EXC_BIFF8 )
     987           0 :                 XclImpString::ReadFormats( rStrm, maFormats );
     988           0 :         break;
     989             :         case EXC_ID_CHSOURCELINK:
     990         187 :             mxSrcLink.reset( new XclImpChSourceLink( GetChRoot() ) );
     991         187 :             mxSrcLink->ReadChSourceLink( rStrm );
     992         187 :         break;
     993             :         case EXC_ID_CHFRAME:
     994          78 :             mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_TEXT ) );
     995          78 :             mxFrame->ReadRecordGroup( rStrm );
     996          78 :         break;
     997             :         case EXC_ID_CHOBJECTLINK:
     998          86 :             rStrm >> maObjLink.mnTarget >> maObjLink.maPointPos.mnSeriesIdx >> maObjLink.maPointPos.mnPointIdx;
     999          86 :         break;
    1000             :         case EXC_ID_CHFRLABELPROPS:
    1001           0 :             ReadChFrLabelProps( rStrm );
    1002           0 :         break;
    1003             :         case EXC_ID_CHEND:
    1004         187 :             if( mxSrcLink && !maFormats.empty() )
    1005           0 :                 mxSrcLink->SetTextFormats( maFormats );
    1006         187 :         break;
    1007             :     }
    1008        1418 : }
    1009             : 
    1010         179 : sal_uInt16 XclImpChText::GetFontIndex() const
    1011             : {
    1012         179 :     return mxFont ? mxFont->GetFontIndex() : EXC_FONT_NOTFOUND;
    1013             : }
    1014             : 
    1015         179 : Color XclImpChText::GetFontColor() const
    1016             : {
    1017         179 :     return ::get_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR ) ? GetFontAutoColor() : maData.maTextColor;
    1018             : }
    1019             : 
    1020         100 : sal_uInt16 XclImpChText::GetRotation() const
    1021             : {
    1022         100 :     return maData.mnRotation;
    1023             : }
    1024             : 
    1025          19 : void XclImpChText::SetString( const String& rString )
    1026             : {
    1027          19 :     if( !mxSrcLink )
    1028           0 :         mxSrcLink.reset( new XclImpChSourceLink( GetChRoot() ) );
    1029          19 :     mxSrcLink->SetString( rString );
    1030          19 : }
    1031             : 
    1032         107 : void XclImpChText::UpdateText( const XclImpChText* pParentText )
    1033             : {
    1034         107 :     if( pParentText )
    1035             :     {
    1036             :         // update missing members
    1037         107 :         if( !mxFrame )
    1038          29 :             mxFrame = pParentText->mxFrame;
    1039         107 :         if( !mxFont )
    1040             :         {
    1041           8 :             mxFont = pParentText->mxFont;
    1042             :             // text color is taken from CHTEXT record, not from font in CHFONT
    1043           8 :             ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR, ::get_flag( pParentText->maData.mnFlags, EXC_CHTEXT_AUTOCOLOR ) );
    1044           8 :             maData.maTextColor = pParentText->maData.maTextColor;
    1045             :         }
    1046             :     }
    1047         107 : }
    1048             : 
    1049           0 : void XclImpChText::UpdateDataLabel( bool bCateg, bool bValue, bool bPercent )
    1050             : {
    1051           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG,     bCateg );
    1052           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE,     bValue );
    1053           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT,   bPercent );
    1054           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC, bCateg && bPercent );
    1055           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED,       !bCateg && !bValue && !bPercent );
    1056           0 : }
    1057             : 
    1058         158 : void XclImpChText::ConvertFont( ScfPropertySet& rPropSet ) const
    1059             : {
    1060         158 :     ConvertFontBase( GetChRoot(), rPropSet );
    1061         158 : }
    1062             : 
    1063          80 : void XclImpChText::ConvertRotation( ScfPropertySet& rPropSet, bool bSupportsStacked ) const
    1064             : {
    1065          80 :     ConvertRotationBase( GetChRoot(), rPropSet, bSupportsStacked );
    1066          80 : }
    1067             : 
    1068          21 : void XclImpChText::ConvertFrame( ScfPropertySet& rPropSet ) const
    1069             : {
    1070          21 :     if( mxFrame )
    1071          19 :         mxFrame->Convert( rPropSet );
    1072          21 : }
    1073             : 
    1074          46 : void XclImpChText::ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const
    1075             : {
    1076          46 :     if( mxSrcLink )
    1077          46 :         mxSrcLink->ConvertNumFmt( rPropSet, bPercent );
    1078          46 : }
    1079             : 
    1080          65 : void XclImpChText::ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeInfo& rTypeInfo ) const
    1081             : {
    1082             :     // existing CHFRLABELPROPS record wins over flags from CHTEXT
    1083          65 :     sal_uInt16 nShowFlags = mxLabelProps ? mxLabelProps->mnFlags : maData.mnFlags;
    1084          65 :     sal_uInt16 SHOWANYCATEG   = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWCATEG : (EXC_CHTEXT_SHOWCATEGPERC | EXC_CHTEXT_SHOWCATEG);
    1085          65 :     sal_uInt16 SHOWANYVALUE   = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWVALUE : EXC_CHTEXT_SHOWVALUE;
    1086          65 :     sal_uInt16 SHOWANYPERCENT = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWPERCENT : (EXC_CHTEXT_SHOWPERCENT | EXC_CHTEXT_SHOWCATEGPERC);
    1087          65 :     sal_uInt16 SHOWANYBUBBLE  = mxLabelProps ? EXC_CHFRLABELPROPS_SHOWBUBBLE : EXC_CHTEXT_SHOWBUBBLE;
    1088             : 
    1089             :     // get raw flags for label values
    1090          65 :     bool bShowNone    = IsDeleted();
    1091          65 :     bool bShowCateg   = !bShowNone && ::get_flag( nShowFlags, SHOWANYCATEG );
    1092          65 :     bool bShowPercent = !bShowNone && ::get_flag( nShowFlags, SHOWANYPERCENT );
    1093          65 :     bool bShowValue   = !bShowNone && ::get_flag( nShowFlags, SHOWANYVALUE );
    1094          65 :     bool bShowBubble  = !bShowNone && ::get_flag( nShowFlags, SHOWANYBUBBLE );
    1095             : 
    1096             :     // adjust to Chart2 behaviour
    1097          65 :     if( rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES )
    1098           0 :          bShowValue = bShowBubble;  // Chart2 bubble charts show bubble size if 'ShowValue' is set
    1099             : 
    1100             :     // other flags
    1101          65 :     bool bShowAny = bShowValue || bShowPercent || bShowCateg;
    1102          65 :     bool bShowSymbol = bShowAny && ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL );
    1103             : 
    1104             :     // create API struct for label values, set API label separator
    1105          65 :     cssc2::DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol );
    1106          65 :     rPropSet.SetProperty( EXC_CHPROP_LABEL, aPointLabel );
    1107          65 :     String aSep = mxLabelProps ? mxLabelProps->maSeparator : OUString('\n');
    1108          65 :     if( aSep.Len() == 0 )
    1109           0 :         aSep = "; ";
    1110          65 :     rPropSet.SetStringProperty( EXC_CHPROP_LABELSEPARATOR, aSep );
    1111             : 
    1112             :     // text properties of attached label
    1113          65 :     if( bShowAny )
    1114             :     {
    1115          59 :         ConvertFont( rPropSet );
    1116          59 :         ConvertRotation( rPropSet, false );
    1117             :         // label placement
    1118             :         using namespace cssc::DataLabelPlacement;
    1119          59 :         sal_Int32 nPlacement = rTypeInfo.mnDefaultLabelPos;
    1120          59 :         switch( ::extract_value< sal_uInt16 >( maData.mnFlags2, 0, 4 ) )
    1121             :         {
    1122          38 :             case EXC_CHTEXT_POS_DEFAULT:    nPlacement = rTypeInfo.mnDefaultLabelPos;   break;
    1123           0 :             case EXC_CHTEXT_POS_OUTSIDE:    nPlacement = OUTSIDE;                       break;
    1124           0 :             case EXC_CHTEXT_POS_INSIDE:     nPlacement = INSIDE;                        break;
    1125           2 :             case EXC_CHTEXT_POS_CENTER:     nPlacement = CENTER;                        break;
    1126           0 :             case EXC_CHTEXT_POS_AXIS:       nPlacement = NEAR_ORIGIN;                   break;
    1127           0 :             case EXC_CHTEXT_POS_ABOVE:      nPlacement = TOP;                           break;
    1128           0 :             case EXC_CHTEXT_POS_BELOW:      nPlacement = BOTTOM;                        break;
    1129           0 :             case EXC_CHTEXT_POS_LEFT:       nPlacement = LEFT;                          break;
    1130           0 :             case EXC_CHTEXT_POS_RIGHT:      nPlacement = RIGHT;                         break;
    1131           0 :             case EXC_CHTEXT_POS_AUTO:       nPlacement = AVOID_OVERLAP;                 break;
    1132             :         }
    1133          59 :         rPropSet.SetProperty( EXC_CHPROP_LABELPLACEMENT, nPlacement );
    1134             :         // label number format (percentage format wins over value format)
    1135          59 :         if( bShowPercent || bShowValue )
    1136          46 :             ConvertNumFmt( rPropSet, bShowPercent );
    1137          65 :     }
    1138          65 : }
    1139             : 
    1140          21 : Reference< XTitle > XclImpChText::CreateTitle() const
    1141             : {
    1142          21 :     Reference< XTitle > xTitle;
    1143          21 :     if( mxSrcLink && mxSrcLink->HasString() )
    1144             :     {
    1145             :         // create the formatted strings
    1146             :         Sequence< Reference< XFormattedString > > aStringSeq(
    1147          21 :             mxSrcLink->CreateStringSequence( GetChRoot(), GetFontIndex(), GetFontColor() ) );
    1148          21 :         if( aStringSeq.hasElements() )
    1149             :         {
    1150             :             // create the title object
    1151          21 :             xTitle.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_TITLE ), UNO_QUERY );
    1152          21 :             if( xTitle.is() )
    1153             :             {
    1154             :                 // set the formatted strings
    1155          21 :                 xTitle->setText( aStringSeq );
    1156             :                 // more title formatting properties
    1157          21 :                 ScfPropertySet aTitleProp( xTitle );
    1158          21 :                 ConvertFrame( aTitleProp );
    1159          21 :                 ConvertRotation( aTitleProp, true );
    1160             :             }
    1161          21 :         }
    1162             :     }
    1163          21 :     return xTitle;
    1164             : }
    1165             : 
    1166          21 : void XclImpChText::ConvertTitlePosition( const XclChTextKey& rTitleKey ) const
    1167             : {
    1168          42 :     if( !mxFramePos ) return;
    1169             : 
    1170          21 :     const XclChFramePos& rPosData = mxFramePos->GetFramePosData();
    1171             :     OSL_ENSURE( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rPosData.mnBRMode == EXC_CHFRAMEPOS_PARENT),
    1172             :         "XclImpChText::ConvertTitlePosition - unexpected frame position mode" );
    1173             : 
    1174             :     /*  Check if title is moved manually. To get the actual position of the
    1175             :         title, we do some kind of hack and use the values from the CHTEXT
    1176             :         record, effectively ignoring the contents of the CHFRAMEPOS record
    1177             :         which contains the position relative to the default title position
    1178             :         (according to the spec, the CHFRAMEPOS supersedes the CHTEXT record).
    1179             :         Especially when it comes to axis titles, things would become very
    1180             :         complicated here, because the relative title position is stored in a
    1181             :         measurement unit that is dependent on the size of the inner plot area,
    1182             :         the interpretation of the X and Y coordinate is dependent on the
    1183             :         direction of the axis, and in 3D charts, and the title default
    1184             :         positions are dependent on the 3D view settings (rotation, elevation,
    1185             :         and perspective). Thus, it is easier to assume that the creator has
    1186             :         written out the correct absolute position and size of the title in the
    1187             :         CHTEXT record. This is assured by checking that the shape size stored
    1188             :         in the CHTEXT record is non-zero. */
    1189          42 :     if( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) &&
    1190          42 :         ((rPosData.maRect.mnX != 0) || (rPosData.maRect.mnY != 0)) &&
    1191          40 :         (maData.maRect.mnWidth > 0) && (maData.maRect.mnHeight > 0) ) try
    1192             :     {
    1193          20 :         Reference< XShape > xTitleShape( GetTitleShape( rTitleKey ), UNO_SET_THROW );
    1194             :         // the call to XShape.getSize() may recalc the chart view
    1195          20 :         ::com::sun::star::awt::Size aTitleSize = xTitleShape->getSize();
    1196             :         // rotated titles need special handling...
    1197          20 :         sal_Int32 nScRot = XclTools::GetScRotation( GetRotation(), 0 );
    1198          20 :         double fRad = nScRot * F_PI18000;
    1199          20 :         double fSin = fabs( sin( fRad ) );
    1200          20 :         double fCos = fabs( cos( fRad ) );
    1201             :         ::com::sun::star::awt::Size aBoundSize(
    1202          20 :             static_cast< sal_Int32 >( fCos * aTitleSize.Width + fSin * aTitleSize.Height + 0.5 ),
    1203          40 :             static_cast< sal_Int32 >( fSin * aTitleSize.Width + fCos * aTitleSize.Height + 0.5 ) );
    1204             :         // calculate the title position from the values in the CHTEXT record
    1205             :         ::com::sun::star::awt::Point aTitlePos(
    1206          20 :             CalcHmmFromChartX( maData.maRect.mnX ),
    1207          40 :             CalcHmmFromChartY( maData.maRect.mnY ) );
    1208             :         // add part of height to X direction, if title is rotated down (clockwise)
    1209          20 :         if( nScRot > 18000 )
    1210           0 :             aTitlePos.X += static_cast< sal_Int32 >( fSin * aTitleSize.Height + 0.5 );
    1211             :         // add part of width to Y direction, if title is rotated up (counterclockwise)
    1212          20 :         else if( nScRot > 0 )
    1213           0 :             aTitlePos.Y += static_cast< sal_Int32 >( fSin * aTitleSize.Width + 0.5 );
    1214             :         // set the resulting position at the title shape
    1215          20 :         xTitleShape->setPosition( aTitlePos );
    1216             :     }
    1217           0 :     catch( Exception& )
    1218             :     {
    1219             :     }
    1220             : }
    1221             : 
    1222           0 : void XclImpChText::ReadChFrLabelProps( XclImpStream& rStrm )
    1223             : {
    1224           0 :     if( GetBiff() == EXC_BIFF8 )
    1225             :     {
    1226           0 :         mxLabelProps.reset( new XclChFrLabelProps );
    1227             :         sal_uInt16 nSepLen;
    1228           0 :         rStrm.Ignore( 12 );
    1229           0 :         rStrm >> mxLabelProps->mnFlags >> nSepLen;
    1230           0 :         if( nSepLen > 0 )
    1231           0 :             mxLabelProps->maSeparator = rStrm.ReadUniString( nSepLen );
    1232             :     }
    1233           0 : }
    1234             : 
    1235             : namespace {
    1236             : 
    1237          21 : void lclUpdateText( XclImpChTextRef& rxText, const XclImpChText* xDefText )
    1238             : {
    1239          21 :     if( rxText )
    1240          21 :         rxText->UpdateText( xDefText );
    1241             :     else
    1242             :     {
    1243           0 :         XclImpChTextRef xNew(new XclImpChText(*xDefText));
    1244           0 :         rxText = xNew;
    1245             :     }
    1246          21 : }
    1247             : 
    1248         160 : void lclFinalizeTitle( XclImpChTextRef& rxTitle, const XclImpChText* pDefText, const String& rAutoTitle )
    1249             : {
    1250             :     /*  Do not update a title, if it is not visible (if rxTitle is null).
    1251             :         Existing reference indicates enabled title. */
    1252         160 :     if( rxTitle )
    1253             :     {
    1254          21 :         if( !rxTitle->HasString() )
    1255          19 :             rxTitle->SetString( rAutoTitle );
    1256          21 :         if( rxTitle->HasString() )
    1257          21 :             rxTitle->UpdateText(pDefText);
    1258             :         else
    1259           0 :             rxTitle.reset();
    1260             :     }
    1261         160 : }
    1262             : 
    1263             : } // namespace
    1264             : 
    1265             : // Data series ================================================================
    1266             : 
    1267         114 : void XclImpChMarkerFormat::ReadChMarkerFormat( XclImpStream& rStrm )
    1268             : {
    1269         114 :     rStrm >> maData.maLineColor >> maData.maFillColor >> maData.mnMarkerType >> maData.mnFlags;
    1270             : 
    1271         114 :     const XclImpRoot& rRoot = rStrm.GetRoot();
    1272         114 :     if( rRoot.GetBiff() == EXC_BIFF8 )
    1273             :     {
    1274             :         // BIFF8: index into palette used instead of RGB data
    1275         114 :         const XclImpPalette& rPal = rRoot.GetPalette();
    1276         114 :         maData.maLineColor = rPal.GetColor( rStrm.ReaduInt16() );
    1277         114 :         maData.maFillColor = rPal.GetColor( rStrm.ReaduInt16() );
    1278             :         // marker size
    1279         114 :         rStrm >> maData.mnMarkerSize;
    1280             :     }
    1281         114 : }
    1282             : 
    1283           1 : void XclImpChMarkerFormat::Convert( const XclImpChRoot& rRoot,
    1284             :         ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx, sal_Int16 nLineWeight ) const
    1285             : {
    1286           1 :     if( IsAuto() )
    1287             :     {
    1288           1 :         XclChMarkerFormat aMarkerFmt;
    1289             :         // line and fill color of the symbol are equal to series line color
    1290             :         //! TODO: Excel sets no fill color for specific symbols (e.g. cross)
    1291           1 :         aMarkerFmt.maLineColor = aMarkerFmt.maFillColor = rRoot.GetSeriesLineAutoColor( nFormatIdx );
    1292           1 :         switch( nLineWeight )
    1293             :         {
    1294           0 :             case EXC_CHLINEFORMAT_HAIR:     aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_HAIRSIZE;      break;
    1295           1 :             case EXC_CHLINEFORMAT_SINGLE:   aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_SINGLESIZE;    break;
    1296           0 :             case EXC_CHLINEFORMAT_DOUBLE:   aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_DOUBLESIZE;    break;
    1297           0 :             case EXC_CHLINEFORMAT_TRIPLE:   aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_TRIPLESIZE;    break;
    1298           0 :             default:                        aMarkerFmt.mnMarkerSize = EXC_CHMARKERFORMAT_SINGLESIZE;
    1299             :         }
    1300           1 :         aMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
    1301           1 :         rRoot.GetChartPropSetHelper().WriteMarkerProperties( rPropSet, aMarkerFmt );
    1302             :     }
    1303             :     else
    1304             :     {
    1305           0 :         rRoot.GetChartPropSetHelper().WriteMarkerProperties( rPropSet, maData );
    1306             :     }
    1307           1 : }
    1308             : 
    1309           0 : void XclImpChMarkerFormat::ConvertColor( const XclImpChRoot& rRoot,
    1310             :         ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const
    1311             : {
    1312           0 :     Color aLineColor = IsAuto() ? rRoot.GetSeriesLineAutoColor( nFormatIdx ) : maData.maFillColor;
    1313           0 :     rPropSet.SetColorProperty( EXC_CHPROP_COLOR, aLineColor );
    1314           0 : }
    1315             : 
    1316             : // ----------------------------------------------------------------------------
    1317             : 
    1318         114 : XclImpChPieFormat::XclImpChPieFormat() :
    1319         114 :     mnPieDist( 0 )
    1320             : {
    1321         114 : }
    1322             : 
    1323         114 : void XclImpChPieFormat::ReadChPieFormat( XclImpStream& rStrm )
    1324             : {
    1325         114 :     rStrm >> mnPieDist;
    1326         114 : }
    1327             : 
    1328          92 : void XclImpChPieFormat::Convert( ScfPropertySet& rPropSet ) const
    1329             : {
    1330          92 :     double fApiDist = ::std::min< double >( mnPieDist / 100.0, 1.0 );
    1331          92 :     rPropSet.SetProperty( EXC_CHPROP_OFFSET, fApiDist );
    1332          92 : }
    1333             : 
    1334             : // ----------------------------------------------------------------------------
    1335             : 
    1336           0 : XclImpChSeriesFormat::XclImpChSeriesFormat() :
    1337           0 :     mnFlags( 0 )
    1338             : {
    1339           0 : }
    1340             : 
    1341           0 : void XclImpChSeriesFormat::ReadChSeriesFormat( XclImpStream& rStrm )
    1342             : {
    1343           0 :     rStrm >> mnFlags;
    1344           0 : }
    1345             : 
    1346             : // ----------------------------------------------------------------------------
    1347             : 
    1348         116 : void XclImpCh3dDataFormat::ReadCh3dDataFormat( XclImpStream& rStrm )
    1349             : {
    1350         116 :     rStrm >> maData.mnBase >> maData.mnTop;
    1351         116 : }
    1352             : 
    1353           0 : void XclImpCh3dDataFormat::Convert( ScfPropertySet& rPropSet ) const
    1354             : {
    1355             :     using namespace ::com::sun::star::chart2::DataPointGeometry3D;
    1356           0 :     sal_Int32 nApiType = (maData.mnBase == EXC_CH3DDATAFORMAT_RECT) ?
    1357           0 :         ((maData.mnTop == EXC_CH3DDATAFORMAT_STRAIGHT) ? CUBOID : PYRAMID) :
    1358           0 :         ((maData.mnTop == EXC_CH3DDATAFORMAT_STRAIGHT) ? CYLINDER : CONE);
    1359           0 :     rPropSet.SetProperty( EXC_CHPROP_GEOMETRY3D, nApiType );
    1360           0 : }
    1361             : 
    1362             : // ----------------------------------------------------------------------------
    1363             : 
    1364          32 : XclImpChAttachedLabel::XclImpChAttachedLabel( const XclImpChRoot& rRoot ) :
    1365             :     XclImpChRoot( rRoot ),
    1366          32 :     mnFlags( 0 )
    1367             : {
    1368          32 : }
    1369             : 
    1370          32 : void XclImpChAttachedLabel::ReadChAttachedLabel( XclImpStream& rStrm )
    1371             : {
    1372          32 :     rStrm >> mnFlags;
    1373          32 : }
    1374             : 
    1375           0 : XclImpChTextRef XclImpChAttachedLabel::CreateDataLabel( const XclImpChText* pParent ) const
    1376             : {
    1377           0 :     const sal_uInt16 EXC_CHATTLABEL_SHOWANYVALUE = EXC_CHATTLABEL_SHOWVALUE;
    1378           0 :     const sal_uInt16 EXC_CHATTLABEL_SHOWANYPERCENT = EXC_CHATTLABEL_SHOWPERCENT | EXC_CHATTLABEL_SHOWCATEGPERC;
    1379           0 :     const sal_uInt16 EXC_CHATTLABEL_SHOWANYCATEG = EXC_CHATTLABEL_SHOWCATEG | EXC_CHATTLABEL_SHOWCATEGPERC;
    1380             : 
    1381           0 :     XclImpChTextRef xLabel( pParent ? new XclImpChText( *pParent ) : new XclImpChText( GetChRoot() ) );
    1382             :     xLabel->UpdateDataLabel(
    1383           0 :         ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYCATEG ),
    1384           0 :         ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYVALUE ),
    1385           0 :         ::get_flag( mnFlags, EXC_CHATTLABEL_SHOWANYPERCENT ) );
    1386           0 :     return xLabel;
    1387             : }
    1388             : 
    1389             : // ----------------------------------------------------------------------------
    1390             : 
    1391         116 : XclImpChDataFormat::XclImpChDataFormat( const XclImpChRoot& rRoot ) :
    1392         116 :     XclImpChRoot( rRoot )
    1393             : {
    1394         116 : }
    1395             : 
    1396         116 : void XclImpChDataFormat::ReadHeaderRecord( XclImpStream& rStrm )
    1397             : {
    1398         116 :     rStrm   >> maData.maPointPos.mnPointIdx
    1399         232 :             >> maData.maPointPos.mnSeriesIdx
    1400         232 :             >> maData.mnFormatIdx
    1401         232 :             >> maData.mnFlags;
    1402         116 : }
    1403             : 
    1404        1254 : void XclImpChDataFormat::ReadSubRecord( XclImpStream& rStrm )
    1405             : {
    1406        1254 :     switch( rStrm.GetRecId() )
    1407             :     {
    1408             :         case EXC_ID_CHMARKERFORMAT:
    1409         114 :             mxMarkerFmt.reset( new XclImpChMarkerFormat );
    1410         114 :             mxMarkerFmt->ReadChMarkerFormat( rStrm );
    1411         114 :         break;
    1412             :         case EXC_ID_CHPIEFORMAT:
    1413         114 :             mxPieFmt.reset( new XclImpChPieFormat );
    1414         114 :             mxPieFmt->ReadChPieFormat( rStrm );
    1415         114 :         break;
    1416             :         case EXC_ID_CHSERIESFORMAT:
    1417           0 :             mxSeriesFmt.reset( new XclImpChSeriesFormat );
    1418           0 :             mxSeriesFmt->ReadChSeriesFormat( rStrm );
    1419           0 :         break;
    1420             :         case EXC_ID_CH3DDATAFORMAT:
    1421         116 :             mx3dDataFmt.reset( new XclImpCh3dDataFormat );
    1422         116 :             mx3dDataFmt->ReadCh3dDataFormat( rStrm );
    1423         116 :         break;
    1424             :         case EXC_ID_CHATTACHEDLABEL:
    1425          32 :             mxAttLabel.reset( new XclImpChAttachedLabel( GetChRoot() ) );
    1426          32 :             mxAttLabel->ReadChAttachedLabel( rStrm );
    1427          32 :         break;
    1428             :         default:
    1429         878 :             XclImpChFrameBase::ReadSubRecord( rStrm );
    1430             :     }
    1431        1254 : }
    1432             : 
    1433           0 : void XclImpChDataFormat::SetPointPos( const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx )
    1434             : {
    1435           0 :     maData.maPointPos = rPointPos;
    1436           0 :     maData.mnFormatIdx = nFormatIdx;
    1437           0 : }
    1438             : 
    1439          19 : void XclImpChDataFormat::UpdateGroupFormat( const XclChExtTypeInfo& rTypeInfo )
    1440             : {
    1441             :     // remove formats not used for the current chart type
    1442          19 :     RemoveUnusedFormats( rTypeInfo );
    1443          19 : }
    1444             : 
    1445          40 : void XclImpChDataFormat::UpdateSeriesFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pGroupFmt )
    1446             : {
    1447             :     // update missing formats from passed chart type group format
    1448          40 :     if( pGroupFmt )
    1449             :     {
    1450          19 :         if( !mxLineFmt )
    1451           0 :             mxLineFmt = pGroupFmt->mxLineFmt;
    1452          19 :         if( !mxAreaFmt && !mxEscherFmt )
    1453             :         {
    1454           0 :             mxAreaFmt = pGroupFmt->mxAreaFmt;
    1455           0 :             mxEscherFmt = pGroupFmt->mxEscherFmt;
    1456             :         }
    1457          19 :         if( !mxMarkerFmt )
    1458           0 :             mxMarkerFmt = pGroupFmt->mxMarkerFmt;
    1459          19 :         if( !mxPieFmt )
    1460           0 :             mxPieFmt = pGroupFmt->mxPieFmt;
    1461          19 :         if( !mxSeriesFmt )
    1462          19 :             mxSeriesFmt = pGroupFmt->mxSeriesFmt;
    1463          19 :         if( !mx3dDataFmt )
    1464           0 :             mx3dDataFmt = pGroupFmt->mx3dDataFmt;
    1465          19 :         if( !mxAttLabel )
    1466           4 :             mxAttLabel = pGroupFmt->mxAttLabel;
    1467             :     }
    1468             : 
    1469             :     /*  Create missing but required formats. Existing line, area, and marker
    1470             :         format objects are needed to create automatic series formatting. */
    1471          40 :     if( !mxLineFmt )
    1472           2 :         mxLineFmt.reset( new XclImpChLineFormat );
    1473          40 :     if( !mxAreaFmt && !mxEscherFmt )
    1474           2 :         mxAreaFmt.reset( new XclImpChAreaFormat );
    1475          40 :     if( !mxMarkerFmt )
    1476           2 :         mxMarkerFmt.reset( new XclImpChMarkerFormat );
    1477             : 
    1478             :     // remove formats not used for the current chart type
    1479          40 :     RemoveUnusedFormats( rTypeInfo );
    1480             :     // update data label
    1481          40 :     UpdateDataLabel( pGroupFmt );
    1482          40 : }
    1483             : 
    1484          57 : void XclImpChDataFormat::UpdatePointFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pSeriesFmt )
    1485             : {
    1486             :     // remove formats if they are automatic in this and in the passed series format
    1487          57 :     if( pSeriesFmt )
    1488             :     {
    1489          57 :         if( IsAutoLine() && pSeriesFmt->IsAutoLine() )
    1490           0 :             mxLineFmt.reset();
    1491          57 :         if( IsAutoArea() && pSeriesFmt->IsAutoArea() )
    1492           0 :             mxAreaFmt.reset();
    1493          57 :         if( IsAutoMarker() && pSeriesFmt->IsAutoMarker() )
    1494          57 :             mxMarkerFmt.reset();
    1495          57 :         mxSeriesFmt.reset();
    1496             :     }
    1497             : 
    1498             :     // Excel ignores 3D bar format for single data points
    1499          57 :     mx3dDataFmt.reset();
    1500             :     // remove point line formats for linear chart types, TODO: implement in OOChart
    1501          57 :     if( !rTypeInfo.IsSeriesFrameFormat() )
    1502           0 :         mxLineFmt.reset();
    1503             : 
    1504             :     // remove formats not used for the current chart type
    1505          57 :     RemoveUnusedFormats( rTypeInfo );
    1506             :     // update data label
    1507          57 :     UpdateDataLabel( pSeriesFmt );
    1508          57 : }
    1509             : 
    1510           0 : void XclImpChDataFormat::UpdateTrendLineFormat()
    1511             : {
    1512           0 :     if( !mxLineFmt )
    1513           0 :         mxLineFmt.reset( new XclImpChLineFormat );
    1514           0 :     mxAreaFmt.reset();
    1515           0 :     mxEscherFmt.reset();
    1516           0 :     mxMarkerFmt.reset();
    1517           0 :     mxPieFmt.reset();
    1518           0 :     mxSeriesFmt.reset();
    1519           0 :     mx3dDataFmt.reset();
    1520           0 :     mxAttLabel.reset();
    1521             :     // update data label
    1522           0 :     UpdateDataLabel( 0 );
    1523           0 : }
    1524             : 
    1525          97 : void XclImpChDataFormat::Convert( ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo ) const
    1526             : {
    1527             :     /*  Line and area format.
    1528             :         #i71810# If the data points are filled with bitmaps, textures, or
    1529             :         patterns, then only bar charts will use the CHPICFORMAT record to
    1530             :         determine stacking/streching mode. All other chart types ignore this
    1531             :         record and always use the property 'fill-type' from the DFF property
    1532             :         set (streched for bitmaps, and stacked for textures and patterns). */
    1533          97 :     bool bUsePicFmt = rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR;
    1534          97 :     ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType(), maData.mnFormatIdx, bUsePicFmt );
    1535             : 
    1536             : #if EXC_CHART2_3DBAR_HAIRLINES_ONLY
    1537             :     // #i83151# only hair lines in 3D charts with filled data points
    1538          97 :     if( rTypeInfo.mb3dChart && rTypeInfo.IsSeriesFrameFormat() && mxLineFmt && mxLineFmt->HasLine() )
    1539           0 :         rPropSet.SetProperty< sal_Int32 >( "BorderWidth", 0 );
    1540             : #endif
    1541             : 
    1542             :     // other formatting
    1543          97 :     if( mxMarkerFmt )
    1544           1 :         mxMarkerFmt->Convert( GetChRoot(), rPropSet, maData.mnFormatIdx, GetLineWeight() );
    1545          97 :     if( mxPieFmt )
    1546          92 :         mxPieFmt->Convert( rPropSet );
    1547          97 :     if( mx3dDataFmt )
    1548           0 :         mx3dDataFmt->Convert( rPropSet );
    1549          97 :     if( mxLabel )
    1550          65 :         mxLabel->ConvertDataLabel( rPropSet, rTypeInfo );
    1551             : 
    1552             :     // 3D settings
    1553          97 :     rPropSet.SetProperty< sal_Int16 >( EXC_CHPROP_PERCENTDIAGONAL, 0 );
    1554             : 
    1555             :     /*  Special case: set marker color as line color, if series line is not
    1556             :         visible. This makes the color visible in the marker area.
    1557             :         TODO: remove this if OOChart supports own colors in markers. */
    1558          97 :     if( !rTypeInfo.IsSeriesFrameFormat() && !HasLine() && mxMarkerFmt )
    1559           0 :         mxMarkerFmt->ConvertColor( GetChRoot(), rPropSet, maData.mnFormatIdx );
    1560          97 : }
    1561             : 
    1562           0 : void XclImpChDataFormat::ConvertLine( ScfPropertySet& rPropSet, XclChObjectType eObjType ) const
    1563             : {
    1564           0 :     ConvertLineBase( GetChRoot(), rPropSet, eObjType );
    1565           0 : }
    1566             : 
    1567          55 : void XclImpChDataFormat::ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const
    1568             : {
    1569          55 :     ConvertAreaBase( GetChRoot(), rPropSet, EXC_CHOBJTYPE_FILLEDSERIES, nFormatIdx, bUsePicFmt );
    1570          55 : }
    1571             : 
    1572         116 : void XclImpChDataFormat::RemoveUnusedFormats( const XclChExtTypeInfo& rTypeInfo )
    1573             : {
    1574             :     // data point marker only in linear 2D charts
    1575         116 :     if( rTypeInfo.IsSeriesFrameFormat() )
    1576         115 :         mxMarkerFmt.reset();
    1577             :     // pie format only in pie/donut charts
    1578         116 :     if( rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE )
    1579           6 :         mxPieFmt.reset();
    1580             :     // 3D format only in 3D bar charts
    1581         116 :     if( !rTypeInfo.mb3dChart || (rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_BAR) )
    1582         116 :         mx3dDataFmt.reset();
    1583         116 : }
    1584             : 
    1585          97 : void XclImpChDataFormat::UpdateDataLabel( const XclImpChDataFormat* pParentFmt )
    1586             : {
    1587             :     /*  CHTEXT groups linked to data labels override existing CHATTACHEDLABEL
    1588             :         records. Only if there is a CHATTACHEDLABEL record without a CHTEXT
    1589             :         group, the contents of the CHATTACHEDLABEL record are used. In this
    1590             :         case a new CHTEXT group is created and filled with the settings from
    1591             :         the CHATTACHEDLABEL record. */
    1592          97 :     const XclImpChText* pDefText = NULL;
    1593          97 :     if (pParentFmt)
    1594          76 :         pDefText = pParentFmt->GetDataLabel();
    1595          97 :     if (!pDefText)
    1596          40 :         pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_DATALABEL );
    1597          97 :     if (mxLabel)
    1598          65 :         mxLabel->UpdateText(pDefText);
    1599          32 :     else if (mxAttLabel)
    1600           0 :         mxLabel = mxAttLabel->CreateDataLabel( pDefText );
    1601          97 : }
    1602             : 
    1603             : // ----------------------------------------------------------------------------
    1604             : 
    1605           0 : XclImpChSerTrendLine::XclImpChSerTrendLine( const XclImpChRoot& rRoot ) :
    1606           0 :     XclImpChRoot( rRoot )
    1607             : {
    1608           0 : }
    1609             : 
    1610           0 : void XclImpChSerTrendLine::ReadChSerTrendLine( XclImpStream& rStrm )
    1611             : {
    1612           0 :     rStrm   >> maData.mnLineType
    1613           0 :             >> maData.mnOrder
    1614           0 :             >> maData.mfIntercept
    1615           0 :             >> maData.mnShowEquation
    1616           0 :             >> maData.mnShowRSquared
    1617           0 :             >> maData.mfForecastFor
    1618           0 :             >> maData.mfForecastBack;
    1619           0 : }
    1620             : 
    1621           0 : Reference< XRegressionCurve > XclImpChSerTrendLine::CreateRegressionCurve() const
    1622             : {
    1623             :     // trend line type
    1624           0 :     Reference< XRegressionCurve > xRegCurve;
    1625           0 :     switch( maData.mnLineType )
    1626             :     {
    1627             :         case EXC_CHSERTREND_POLYNOMIAL:
    1628           0 :             if( maData.mnOrder == 1 )
    1629             :             {
    1630           0 :                 xRegCurve = LinearRegressionCurve::create( comphelper::getProcessComponentContext() );
    1631             :             } else {
    1632           0 :                 xRegCurve = PolynomialRegressionCurve::create( comphelper::getProcessComponentContext() );
    1633             :             }
    1634           0 :         break;
    1635             :         case EXC_CHSERTREND_EXPONENTIAL:
    1636           0 :             xRegCurve = ExponentialRegressionCurve::create( comphelper::getProcessComponentContext() );
    1637           0 :         break;
    1638             :         case EXC_CHSERTREND_LOGARITHMIC:
    1639           0 :             xRegCurve = LogarithmicRegressionCurve::create( comphelper::getProcessComponentContext() );
    1640           0 :         break;
    1641             :         case EXC_CHSERTREND_POWER:
    1642           0 :             xRegCurve = PotentialRegressionCurve::create( comphelper::getProcessComponentContext() );
    1643           0 :         break;
    1644             :         case EXC_CHSERTREND_MOVING_AVG:
    1645           0 :             xRegCurve = MovingAverageRegressionCurve::create( comphelper::getProcessComponentContext() );
    1646           0 :         break;
    1647             :     }
    1648             : 
    1649             :     // trend line formatting
    1650           0 :     if( xRegCurve.is() && mxDataFmt )
    1651             :     {
    1652           0 :         ScfPropertySet aPropSet( xRegCurve );
    1653           0 :         mxDataFmt->ConvertLine( aPropSet, EXC_CHOBJTYPE_TRENDLINE );
    1654             : 
    1655           0 :         aPropSet.SetProperty(EXC_CHPROP_POLYNOMIAL_DEGREE, static_cast<sal_Int32> (maData.mnOrder) );
    1656           0 :         aPropSet.SetProperty(EXC_CHPROP_MOVING_AVERAGE_PERIOD, static_cast<sal_Int32> (maData.mnOrder) );
    1657           0 :         aPropSet.SetProperty(EXC_CHPROP_EXTRAPOLATE_FORWARD, maData.mfForecastFor);
    1658           0 :         aPropSet.SetProperty(EXC_CHPROP_EXTRAPOLATE_BACKWARD, maData.mfForecastBack);
    1659             : 
    1660           0 :         sal_Bool bForceIntercept = lcl_IsForceIntercept(maData.mfIntercept);
    1661           0 :         aPropSet.SetProperty(EXC_CHPROP_FORCE_INTERCEPT, bForceIntercept);
    1662           0 :         if (bForceIntercept)
    1663             :         {
    1664           0 :             aPropSet.SetProperty(EXC_CHPROP_INTERCEPT_VALUE, maData.mfIntercept);
    1665             :         }
    1666             : 
    1667             :         // #i83100# show equation and correlation coefficient
    1668           0 :         ScfPropertySet aLabelProp( xRegCurve->getEquationProperties() );
    1669           0 :         aLabelProp.SetBoolProperty( EXC_CHPROP_SHOWEQUATION, maData.mnShowEquation != 0 );
    1670           0 :         aLabelProp.SetBoolProperty( EXC_CHPROP_SHOWCORRELATION, maData.mnShowRSquared != 0 );
    1671             : 
    1672             :         // #i83100# formatting of the equation text box
    1673           0 :         if (const XclImpChText* pLabel = mxDataFmt->GetDataLabel())
    1674             :         {
    1675           0 :             pLabel->ConvertFont( aLabelProp );
    1676           0 :             pLabel->ConvertFrame( aLabelProp );
    1677           0 :             pLabel->ConvertNumFmt( aLabelProp, false );
    1678           0 :         }
    1679             :     }
    1680             : 
    1681             :     // missing features
    1682             :     // #i20819# polynomial trend lines
    1683             :     // #i66819# moving average trend lines
    1684             :     // #i5085# manual trend line size
    1685             :     // #i34093# manual crossing point
    1686             : 
    1687           0 :     return xRegCurve;
    1688             : }
    1689             : 
    1690             : // ----------------------------------------------------------------------------
    1691             : 
    1692           0 : XclImpChSerErrorBar::XclImpChSerErrorBar( const XclImpChRoot& rRoot ) :
    1693           0 :     XclImpChRoot( rRoot )
    1694             : {
    1695           0 : }
    1696             : 
    1697           0 : void XclImpChSerErrorBar::ReadChSerErrorBar( XclImpStream& rStrm )
    1698             : {
    1699           0 :     rStrm >> maData.mnBarType >> maData.mnSourceType >> maData.mnLineEnd;
    1700           0 :     rStrm.Ignore( 1 );
    1701           0 :     rStrm >> maData.mfValue >> maData.mnValueCount;
    1702           0 : }
    1703             : 
    1704           0 : void XclImpChSerErrorBar::SetSeriesData( XclImpChSourceLinkRef xValueLink, XclImpChDataFormatRef xDataFmt )
    1705             : {
    1706           0 :     mxValueLink = xValueLink;
    1707           0 :     mxDataFmt = xDataFmt;
    1708           0 : }
    1709             : 
    1710           0 : Reference< XLabeledDataSequence > XclImpChSerErrorBar::CreateValueSequence() const
    1711             : {
    1712           0 :     return lclCreateLabeledDataSequence( mxValueLink, XclChartHelper::GetErrorBarValuesRole( maData.mnBarType ) );
    1713             : }
    1714             : 
    1715           0 : Reference< XPropertySet > XclImpChSerErrorBar::CreateErrorBar( const XclImpChSerErrorBar* pPosBar, const XclImpChSerErrorBar* pNegBar )
    1716             : {
    1717           0 :     Reference< XPropertySet > xErrorBar;
    1718             : 
    1719           0 :     if( const XclImpChSerErrorBar* pPrimaryBar = pPosBar ? pPosBar : pNegBar )
    1720             :     {
    1721           0 :         xErrorBar.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_ERRORBAR ), UNO_QUERY );
    1722           0 :         ScfPropertySet aBarProp( xErrorBar );
    1723             : 
    1724             :         // plus/minus bars visible?
    1725           0 :         aBarProp.SetBoolProperty( EXC_CHPROP_SHOWPOSITIVEERROR, pPosBar != 0 );
    1726           0 :         aBarProp.SetBoolProperty( EXC_CHPROP_SHOWNEGATIVEERROR, pNegBar != 0 );
    1727             : 
    1728             :         // type of displayed error
    1729           0 :         switch( pPrimaryBar->maData.mnSourceType )
    1730             :         {
    1731             :             case EXC_CHSERERR_PERCENT:
    1732           0 :                 aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::RELATIVE );
    1733           0 :                 aBarProp.SetProperty( EXC_CHPROP_POSITIVEERROR, pPrimaryBar->maData.mfValue );
    1734           0 :                 aBarProp.SetProperty( EXC_CHPROP_NEGATIVEERROR, pPrimaryBar->maData.mfValue );
    1735           0 :             break;
    1736             :             case EXC_CHSERERR_FIXED:
    1737           0 :                 aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::ABSOLUTE );
    1738           0 :                 aBarProp.SetProperty( EXC_CHPROP_POSITIVEERROR, pPrimaryBar->maData.mfValue );
    1739           0 :                 aBarProp.SetProperty( EXC_CHPROP_NEGATIVEERROR, pPrimaryBar->maData.mfValue );
    1740           0 :             break;
    1741             :             case EXC_CHSERERR_STDDEV:
    1742           0 :                 aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::STANDARD_DEVIATION );
    1743           0 :                 aBarProp.SetProperty( EXC_CHPROP_WEIGHT, pPrimaryBar->maData.mfValue );
    1744           0 :             break;
    1745             :             case EXC_CHSERERR_STDERR:
    1746           0 :                 aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::STANDARD_ERROR );
    1747           0 :             break;
    1748             :             case EXC_CHSERERR_CUSTOM:
    1749             :             {
    1750           0 :                 aBarProp.SetProperty( EXC_CHPROP_ERRORBARSTYLE, cssc::ErrorBarStyle::FROM_DATA );
    1751             :                 // attach data sequences to erorr bar
    1752           0 :                 Reference< XDataSink > xDataSink( xErrorBar, UNO_QUERY );
    1753           0 :                 if( xDataSink.is() )
    1754             :                 {
    1755             :                     // create vector of all value sequences
    1756           0 :                     ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
    1757             :                     // add positive values
    1758           0 :                     if( pPosBar )
    1759             :                     {
    1760           0 :                         Reference< XLabeledDataSequence > xValueSeq = pPosBar->CreateValueSequence();
    1761           0 :                         if( xValueSeq.is() )
    1762           0 :                             aLabeledSeqVec.push_back( xValueSeq );
    1763             :                     }
    1764             :                     // add negative values
    1765           0 :                     if( pNegBar )
    1766             :                     {
    1767           0 :                         Reference< XLabeledDataSequence > xValueSeq = pNegBar->CreateValueSequence();
    1768           0 :                         if( xValueSeq.is() )
    1769           0 :                             aLabeledSeqVec.push_back( xValueSeq );
    1770             :                     }
    1771             :                     // attach labeled data sequences to series
    1772           0 :                     if( aLabeledSeqVec.empty() )
    1773           0 :                         xErrorBar.clear();
    1774             :                     else
    1775           0 :                         xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
    1776           0 :                 }
    1777             :             }
    1778           0 :             break;
    1779             :             default:
    1780           0 :                 xErrorBar.clear();
    1781             :         }
    1782             : 
    1783             :         // error bar formatting
    1784           0 :         if( pPrimaryBar->mxDataFmt && xErrorBar.is() )
    1785           0 :             pPrimaryBar->mxDataFmt->ConvertLine( aBarProp, EXC_CHOBJTYPE_ERRORBAR );
    1786             :     }
    1787             : 
    1788           0 :     return xErrorBar;
    1789             : }
    1790             : 
    1791             : // ----------------------------------------------------------------------------
    1792             : 
    1793          40 : XclImpChSeries::XclImpChSeries( const XclImpChRoot& rRoot, sal_uInt16 nSeriesIdx ) :
    1794             :     XclImpChRoot( rRoot ),
    1795             :     mnGroupIdx( EXC_CHSERGROUP_NONE ),
    1796             :     mnSeriesIdx( nSeriesIdx ),
    1797          40 :     mnParentIdx( EXC_CHSERIES_INVALID )
    1798             : {
    1799          40 : }
    1800             : 
    1801          40 : void XclImpChSeries::ReadHeaderRecord( XclImpStream& rStrm )
    1802             : {
    1803          40 :     rStrm >> maData.mnCategType >> maData.mnValueType >> maData.mnCategCount >> maData.mnValueCount;
    1804          40 :     if( GetBiff() == EXC_BIFF8 )
    1805          40 :         rStrm >> maData.mnBubbleType >> maData.mnBubbleCount;
    1806          40 : }
    1807             : 
    1808         445 : void XclImpChSeries::ReadSubRecord( XclImpStream& rStrm )
    1809             : {
    1810         445 :     switch( rStrm.GetRecId() )
    1811             :     {
    1812             :         case EXC_ID_CHSOURCELINK:
    1813         160 :             ReadChSourceLink( rStrm );
    1814         160 :         break;
    1815             :         case EXC_ID_CHDATAFORMAT:
    1816          97 :             ReadChDataFormat( rStrm );
    1817          97 :         break;
    1818             :         case EXC_ID_CHSERGROUP:
    1819          40 :             rStrm >> mnGroupIdx;
    1820          40 :         break;
    1821             :         case EXC_ID_CHSERPARENT:
    1822           0 :             ReadChSerParent( rStrm );
    1823           0 :         break;
    1824             :         case EXC_ID_CHSERTRENDLINE:
    1825           0 :             ReadChSerTrendLine( rStrm );
    1826           0 :         break;
    1827             :         case EXC_ID_CHSERERRORBAR:
    1828           0 :             ReadChSerErrorBar( rStrm );
    1829           0 :         break;
    1830             :     }
    1831         445 : }
    1832             : 
    1833          97 : void XclImpChSeries::SetDataFormat( const XclImpChDataFormatRef& xDataFmt )
    1834             : {
    1835          97 :     if (!xDataFmt)
    1836          40 :         return;
    1837             : 
    1838          97 :     sal_uInt16 nPointIdx = xDataFmt->GetPointPos().mnPointIdx;
    1839          97 :     if (nPointIdx == EXC_CHDATAFORMAT_ALLPOINTS)
    1840             :     {
    1841          40 :         if (mxSeriesFmt)
    1842             :             // Don't overwrite the existing format.
    1843           0 :             return;
    1844             : 
    1845          40 :         mxSeriesFmt = xDataFmt;
    1846          40 :         if (HasParentSeries())
    1847           0 :             return;
    1848             : 
    1849          40 :         XclImpChTypeGroupRef pTypeGroup = GetChartData().GetTypeGroup(mnGroupIdx);
    1850          40 :         if (pTypeGroup)
    1851          40 :             pTypeGroup->SetUsedFormatIndex(xDataFmt->GetFormatIdx());
    1852             : 
    1853          40 :         return;
    1854             :     }
    1855             : 
    1856          57 :     if (nPointIdx >= EXC_CHDATAFORMAT_MAXPOINTCOUNT)
    1857             :         // Above the max point count.  Bail out.
    1858           0 :         return;
    1859             : 
    1860          57 :     XclImpChDataFormatMap::iterator itr = maPointFmts.lower_bound(nPointIdx);
    1861          57 :     if (itr == maPointFmts.end() || maPointFmts.key_comp()(nPointIdx, itr->first))
    1862             :     {
    1863             :         // No object exists at this point index position.  Insert it.
    1864          57 :         itr = maPointFmts.insert(itr, XclImpChDataFormatMap::value_type(nPointIdx, xDataFmt));
    1865             :     }
    1866             : }
    1867             : 
    1868          65 : void XclImpChSeries::SetDataLabel( const XclImpChTextRef& xLabel )
    1869             : {
    1870          65 :     if (!xLabel)
    1871           0 :         return;
    1872             : 
    1873          65 :     sal_uInt16 nPointIdx = xLabel->GetPointPos().mnPointIdx;
    1874          65 :     if ((nPointIdx != EXC_CHDATAFORMAT_ALLPOINTS) && (nPointIdx >= EXC_CHDATAFORMAT_MAXPOINTCOUNT))
    1875             :         // Above the maximum allowed data points. Bail out.
    1876           0 :         return;
    1877             : 
    1878          65 :     XclImpChTextMap::iterator itr = maLabels.lower_bound(nPointIdx);
    1879          65 :     if (itr == maLabels.end() || maLabels.key_comp()(nPointIdx, itr->first))
    1880             :     {
    1881             :         // No object exists at this point index position.  Insert it.
    1882          65 :         itr = maLabels.insert(itr, XclImpChTextMap::value_type(nPointIdx, xLabel));
    1883             :     }
    1884             : }
    1885             : 
    1886           0 : void XclImpChSeries::AddChildSeries( const XclImpChSeries& rSeries )
    1887             : {
    1888             :     OSL_ENSURE( !HasParentSeries(), "XclImpChSeries::AddChildSeries - not allowed for child series" );
    1889             : 
    1890             :     /*  In Excel, trend lines and error bars are stored as own series. In Calc,
    1891             :         these are properties of the parent series. This function adds the
    1892             :         settings of the passed series to this series. */
    1893           0 :     maTrendLines.insert( maTrendLines.end(), rSeries.maTrendLines.begin(), rSeries.maTrendLines.end() );
    1894           0 :     maErrorBars.insert( rSeries.maErrorBars.begin(), rSeries.maErrorBars.end() );
    1895           0 : }
    1896             : 
    1897          40 : void XclImpChSeries::FinalizeDataFormats()
    1898             : {
    1899          40 :     if( HasParentSeries() )
    1900             :     {
    1901             :         // *** series is a child series, e.g. trend line or error bar ***
    1902             : 
    1903             :         // create missing series format
    1904           0 :         if( !mxSeriesFmt )
    1905           0 :             mxSeriesFmt = CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS, 0 );
    1906             : 
    1907           0 :         if( mxSeriesFmt )
    1908             :         {
    1909             :             // #i83100# set text label format, e.g. for trend line equations
    1910           0 :             XclImpChTextRef xLabel;
    1911           0 :             XclImpChTextMap::iterator itr = maLabels.find(EXC_CHDATAFORMAT_ALLPOINTS);
    1912           0 :             if (itr != maLabels.end())
    1913           0 :                 xLabel = itr->second;
    1914           0 :             mxSeriesFmt->SetDataLabel(xLabel);
    1915             :             // create missing automatic formats
    1916           0 :             mxSeriesFmt->UpdateTrendLineFormat();
    1917             :         }
    1918             : 
    1919             :         // copy series formatting to child objects
    1920           0 :         for( XclImpChSerTrendLineList::iterator aLIt = maTrendLines.begin(), aLEnd = maTrendLines.end(); aLIt != aLEnd; ++aLIt )
    1921           0 :             (*aLIt)->SetDataFormat( mxSeriesFmt );
    1922           0 :         for( XclImpChSerErrorBarMap::iterator aMIt = maErrorBars.begin(), aMEnd = maErrorBars.end(); aMIt != aMEnd; ++aMIt )
    1923           0 :             aMIt->second->SetSeriesData( mxValueLink, mxSeriesFmt );
    1924             :     }
    1925          40 :     else if( XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
    1926             :     {
    1927             :         // *** series is a regular data series ***
    1928             : 
    1929             :         // create missing series format
    1930          40 :         if( !mxSeriesFmt )
    1931             :         {
    1932             :             // #i51639# use a new unused format index to create series default format
    1933           0 :             sal_uInt16 nFormatIdx = pTypeGroup->PopUnusedFormatIndex();
    1934           0 :             mxSeriesFmt = CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS, nFormatIdx );
    1935             :         }
    1936             : 
    1937             :         // set text labels to data formats
    1938         105 :         for( XclImpChTextMap::iterator aTIt = maLabels.begin(), aTEnd = maLabels.end(); aTIt != aTEnd; ++aTIt )
    1939             :         {
    1940          65 :             sal_uInt16 nPointIdx = aTIt->first;
    1941          65 :             if (nPointIdx == EXC_CHDATAFORMAT_ALLPOINTS)
    1942             :             {
    1943          38 :                 if (!mxSeriesFmt)
    1944           0 :                     mxSeriesFmt = CreateDataFormat(nPointIdx, EXC_CHDATAFORMAT_DEFAULT);
    1945          38 :                 mxSeriesFmt->SetDataLabel(aTIt->second);
    1946             :             }
    1947          27 :             else if (nPointIdx < EXC_CHDATAFORMAT_MAXPOINTCOUNT)
    1948             :             {
    1949          27 :                 XclImpChDataFormatRef p;
    1950          27 :                 XclImpChDataFormatMap::iterator itr = maPointFmts.lower_bound(nPointIdx);
    1951          27 :                 if (itr == maPointFmts.end() || maPointFmts.key_comp()(nPointIdx, itr->first))
    1952             :                 {
    1953             :                     // No object exists at this point index position.  Insert
    1954             :                     // a new one.
    1955           0 :                     p = CreateDataFormat(nPointIdx, EXC_CHDATAFORMAT_DEFAULT);
    1956             :                     itr = maPointFmts.insert(
    1957           0 :                         itr, XclImpChDataFormatMap::value_type(nPointIdx, p));
    1958             :                 }
    1959             :                 else
    1960          27 :                     p = itr->second;
    1961          27 :                 p->SetDataLabel(aTIt->second);
    1962             :             }
    1963             :         }
    1964             : 
    1965             :         // update series format (copy missing formatting from group default format)
    1966          40 :         if( mxSeriesFmt )
    1967          40 :             mxSeriesFmt->UpdateSeriesFormat( pTypeGroup->GetTypeInfo(), pTypeGroup->GetGroupFormat().get() );
    1968             : 
    1969             :         // update data point formats (removes unchanged automatic formatting)
    1970          97 :         for( XclImpChDataFormatMap::iterator aFIt = maPointFmts.begin(), aFEnd = maPointFmts.end(); aFIt != aFEnd; ++aFIt )
    1971          57 :             aFIt->second->UpdatePointFormat( pTypeGroup->GetTypeInfo(), mxSeriesFmt.get() );
    1972             :     }
    1973          40 : }
    1974             : 
    1975             : namespace {
    1976             : 
    1977             : /** Returns the property set of the specified data point. */
    1978         112 : ScfPropertySet lclGetPointPropSet( Reference< XDataSeries > xDataSeries, sal_uInt16 nPointIdx )
    1979             : {
    1980         112 :     ScfPropertySet aPropSet;
    1981             :     try
    1982             :     {
    1983         112 :         aPropSet.Set( xDataSeries->getDataPointByIndex( static_cast< sal_Int32 >( nPointIdx ) ) );
    1984             :     }
    1985           0 :     catch( Exception& )
    1986             :     {
    1987             :         OSL_FAIL( "lclGetPointPropSet - no data point property set" );
    1988             :     }
    1989         112 :     return aPropSet;
    1990             : }
    1991             : 
    1992             : } // namespace
    1993             : 
    1994          40 : Reference< XLabeledDataSequence > XclImpChSeries::CreateValueSequence( const OUString& rValueRole ) const
    1995             : {
    1996          40 :     return lclCreateLabeledDataSequence( mxValueLink, rValueRole, mxTitleLink.get() );
    1997             : }
    1998             : 
    1999          40 : Reference< XLabeledDataSequence > XclImpChSeries::CreateCategSequence( const OUString& rCategRole ) const
    2000             : {
    2001          40 :     return lclCreateLabeledDataSequence( mxCategLink, rCategRole );
    2002             : }
    2003             : 
    2004          40 : Reference< XDataSeries > XclImpChSeries::CreateDataSeries() const
    2005             : {
    2006          40 :     Reference< XDataSeries > xDataSeries;
    2007          40 :     if( const XclImpChTypeGroup* pTypeGroup = GetChartData().GetTypeGroup( mnGroupIdx ).get() )
    2008             :     {
    2009          40 :         const XclChExtTypeInfo& rTypeInfo = pTypeGroup->GetTypeInfo();
    2010             : 
    2011             :         // create the data series object
    2012          40 :         xDataSeries.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_DATASERIES ), UNO_QUERY );
    2013             : 
    2014             :         // attach data and title sequences to series
    2015          40 :         Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
    2016          40 :         if( xDataSink.is() )
    2017             :         {
    2018             :             // create vector of all value sequences
    2019          40 :             ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
    2020             :             // add Y values
    2021             :             Reference< XLabeledDataSequence > xYValueSeq =
    2022          80 :                 CreateValueSequence( EXC_CHPROP_ROLE_YVALUES );
    2023          40 :             if( xYValueSeq.is() )
    2024          40 :                 aLabeledSeqVec.push_back( xYValueSeq );
    2025             :             // add X values
    2026          40 :             if( !rTypeInfo.mbCategoryAxis )
    2027             :             {
    2028             :                 Reference< XLabeledDataSequence > xXValueSeq =
    2029           0 :                     CreateCategSequence( EXC_CHPROP_ROLE_XVALUES );
    2030           0 :                 if( xXValueSeq.is() )
    2031           0 :                     aLabeledSeqVec.push_back( xXValueSeq );
    2032             :                 // add size values of bubble charts
    2033           0 :                 if( rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES )
    2034             :                 {
    2035             :                     Reference< XLabeledDataSequence > xSizeValueSeq =
    2036           0 :                         lclCreateLabeledDataSequence( mxBubbleLink, EXC_CHPROP_ROLE_SIZEVALUES, mxTitleLink.get() );
    2037           0 :                     if( xSizeValueSeq.is() )
    2038           0 :                         aLabeledSeqVec.push_back( xSizeValueSeq );
    2039           0 :                 }
    2040             :             }
    2041             :             // attach labeled data sequences to series
    2042          40 :             if( !aLabeledSeqVec.empty() )
    2043          80 :                 xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
    2044             :         }
    2045             : 
    2046             :         // series formatting
    2047          80 :         ScfPropertySet aSeriesProp( xDataSeries );
    2048          40 :         if( mxSeriesFmt )
    2049          40 :             mxSeriesFmt->Convert( aSeriesProp, rTypeInfo );
    2050             : 
    2051             :         // trend lines
    2052          40 :         ConvertTrendLines( xDataSeries );
    2053             : 
    2054             :         // error bars
    2055          80 :         Reference< XPropertySet > xErrorBarX = CreateErrorBar( EXC_CHSERERR_XPLUS, EXC_CHSERERR_XMINUS );
    2056          40 :         if( xErrorBarX.is() )
    2057           0 :             aSeriesProp.SetProperty( EXC_CHPROP_ERRORBARX, xErrorBarX );
    2058          80 :         Reference< XPropertySet > xErrorBarY = CreateErrorBar( EXC_CHSERERR_YPLUS, EXC_CHSERERR_YMINUS );
    2059          40 :         if( xErrorBarY.is() )
    2060           0 :             aSeriesProp.SetProperty( EXC_CHPROP_ERRORBARY, xErrorBarY );
    2061             : 
    2062             :         // own area formatting for every data point (TODO: varying line color not supported)
    2063          40 :         bool bVarPointFmt = pTypeGroup->HasVarPointFormat() && rTypeInfo.IsSeriesFrameFormat();
    2064             : #if EXC_CHART2_VARYCOLORSBY_PROP
    2065             :         aSeriesProp.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY, bVarPointFmt );
    2066             : #else
    2067          40 :         aSeriesProp.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE );
    2068             : #endif
    2069             :         // #i91271# always set area formatting for every point in pie/doughnut charts
    2070          40 :         if (mxSeriesFmt && mxValueLink && ((bVarPointFmt && mxSeriesFmt->IsAutoArea()) || (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE)))
    2071             :         {
    2072          92 :             for( sal_uInt16 nPointIdx = 0, nPointCount = mxValueLink->GetCellCount(); nPointIdx < nPointCount; ++nPointIdx )
    2073             :             {
    2074          55 :                 ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, nPointIdx );
    2075          55 :                 mxSeriesFmt->ConvertArea( aPointProp, bVarPointFmt ? nPointIdx : mnSeriesIdx, false );
    2076          55 :             }
    2077             :         }
    2078             : 
    2079             :         // data point formatting
    2080          97 :         for( XclImpChDataFormatMap::const_iterator aIt = maPointFmts.begin(), aEnd = maPointFmts.end(); aIt != aEnd; ++aIt )
    2081             :         {
    2082          57 :             ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, aIt->first );
    2083          57 :             aIt->second->Convert( aPointProp, rTypeInfo );
    2084          97 :         }
    2085             :     }
    2086          40 :     return xDataSeries;
    2087             : }
    2088             : 
    2089          40 : void XclImpChSeries::FillAllSourceLinks( ::std::vector< ScTokenRef >& rTokens ) const
    2090             : {
    2091          40 :     if( mxValueLink )
    2092          40 :         mxValueLink->FillSourceLink( rTokens );
    2093          40 :     if( mxCategLink )
    2094          40 :         mxCategLink->FillSourceLink( rTokens );
    2095          40 :     if( mxTitleLink )
    2096          40 :         mxTitleLink->FillSourceLink( rTokens );
    2097          40 :     if( mxBubbleLink )
    2098          40 :         mxBubbleLink->FillSourceLink( rTokens );
    2099          40 : }
    2100             : 
    2101         160 : void XclImpChSeries::ReadChSourceLink( XclImpStream& rStrm )
    2102             : {
    2103         160 :     XclImpChSourceLinkRef xSrcLink( new XclImpChSourceLink( GetChRoot() ) );
    2104         160 :     xSrcLink->ReadChSourceLink( rStrm );
    2105         160 :     switch( xSrcLink->GetDestType() )
    2106             :     {
    2107          40 :         case EXC_CHSRCLINK_TITLE:       mxTitleLink = xSrcLink;     break;
    2108          40 :         case EXC_CHSRCLINK_VALUES:      mxValueLink = xSrcLink;     break;
    2109          40 :         case EXC_CHSRCLINK_CATEGORY:    mxCategLink = xSrcLink;     break;
    2110          40 :         case EXC_CHSRCLINK_BUBBLES:     mxBubbleLink = xSrcLink;    break;
    2111         160 :     }
    2112         160 : }
    2113             : 
    2114          97 : void XclImpChSeries::ReadChDataFormat( XclImpStream& rStrm )
    2115             : {
    2116             :     // #i51639# chart stores all data formats and assigns them later to the series
    2117          97 :     GetChartData().ReadChDataFormat( rStrm );
    2118          97 : }
    2119             : 
    2120           0 : void XclImpChSeries::ReadChSerParent( XclImpStream& rStrm )
    2121             : {
    2122           0 :     rStrm >> mnParentIdx;
    2123             :     // index to parent series is 1-based, convert it to 0-based
    2124           0 :     if( mnParentIdx > 0 )
    2125           0 :         --mnParentIdx;
    2126             :     else
    2127           0 :         mnParentIdx = EXC_CHSERIES_INVALID;
    2128           0 : }
    2129             : 
    2130           0 : void XclImpChSeries::ReadChSerTrendLine( XclImpStream& rStrm )
    2131             : {
    2132           0 :     XclImpChSerTrendLineRef xTrendLine( new XclImpChSerTrendLine( GetChRoot() ) );
    2133           0 :     xTrendLine->ReadChSerTrendLine( rStrm );
    2134           0 :     maTrendLines.push_back( xTrendLine );
    2135           0 : }
    2136             : 
    2137           0 : void XclImpChSeries::ReadChSerErrorBar( XclImpStream& rStrm )
    2138             : {
    2139             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2140           0 :     auto_ptr<XclImpChSerErrorBar> pErrorBar(new XclImpChSerErrorBar(GetChRoot()));
    2141             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2142           0 :     pErrorBar->ReadChSerErrorBar(rStrm);
    2143           0 :     sal_uInt8 nBarType = pErrorBar->GetBarType();
    2144           0 :     maErrorBars.insert(nBarType, pErrorBar);
    2145           0 : }
    2146             : 
    2147           0 : XclImpChDataFormatRef XclImpChSeries::CreateDataFormat( sal_uInt16 nPointIdx, sal_uInt16 nFormatIdx )
    2148             : {
    2149           0 :     XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
    2150           0 :     xDataFmt->SetPointPos( XclChDataPointPos( mnSeriesIdx, nPointIdx ), nFormatIdx );
    2151           0 :     return xDataFmt;
    2152             : }
    2153             : 
    2154          40 : void XclImpChSeries::ConvertTrendLines( Reference< XDataSeries > xDataSeries ) const
    2155             : {
    2156          40 :     Reference< XRegressionCurveContainer > xRegCurveCont( xDataSeries, UNO_QUERY );
    2157          40 :     if( xRegCurveCont.is() )
    2158             :     {
    2159          40 :         for( XclImpChSerTrendLineList::const_iterator aIt = maTrendLines.begin(), aEnd = maTrendLines.end(); aIt != aEnd; ++aIt )
    2160             :         {
    2161             :             try
    2162             :             {
    2163           0 :                 Reference< XRegressionCurve > xRegCurve = (*aIt)->CreateRegressionCurve();
    2164           0 :                 if( xRegCurve.is() )
    2165           0 :                     xRegCurveCont->addRegressionCurve( xRegCurve );
    2166             :             }
    2167           0 :             catch( Exception& )
    2168             :             {
    2169             :                 OSL_FAIL( "XclImpChSeries::ConvertTrendLines - cannot add regression curve" );
    2170             :             }
    2171             :         }
    2172          40 :     }
    2173          40 : }
    2174             : 
    2175          80 : Reference< XPropertySet > XclImpChSeries::CreateErrorBar( sal_uInt8 nPosBarId, sal_uInt8 nNegBarId ) const
    2176             : {
    2177          80 :     XclImpChSerErrorBarMap::const_iterator itrPosBar = maErrorBars.find(nPosBarId);
    2178          80 :     XclImpChSerErrorBarMap::const_iterator itrNegBar = maErrorBars.find(nNegBarId);
    2179          80 :     XclImpChSerErrorBarMap::const_iterator itrEnd = maErrorBars.end();
    2180          80 :     if (itrPosBar == itrEnd || itrNegBar == itrEnd)
    2181          80 :         return Reference<XPropertySet>();
    2182             : 
    2183           0 :     return XclImpChSerErrorBar::CreateErrorBar(itrPosBar->second, itrNegBar->second);
    2184             : }
    2185             : 
    2186             : // Chart type groups ==========================================================
    2187             : 
    2188          40 : XclImpChType::XclImpChType( const XclImpChRoot& rRoot ) :
    2189             :     XclImpChRoot( rRoot ),
    2190             :     mnRecId( EXC_ID_CHUNKNOWN ),
    2191          40 :     maTypeInfo( rRoot.GetChartTypeInfo( EXC_CHTYPEID_UNKNOWN ) )
    2192             : {
    2193          40 : }
    2194             : 
    2195         179 : void XclImpChType::ReadChType( XclImpStream& rStrm )
    2196             : {
    2197         179 :     sal_uInt16 nRecId = rStrm.GetRecId();
    2198         179 :     bool bKnownType = true;
    2199             : 
    2200         179 :     switch( nRecId )
    2201             :     {
    2202             :         case EXC_ID_CHBAR:
    2203           1 :             rStrm >> maData.mnOverlap >> maData.mnGap >> maData.mnFlags;
    2204           1 :         break;
    2205             : 
    2206             :         case EXC_ID_CHLINE:
    2207             :         case EXC_ID_CHAREA:
    2208             :         case EXC_ID_CHRADARLINE:
    2209             :         case EXC_ID_CHRADARAREA:
    2210           1 :             rStrm >> maData.mnFlags;
    2211           1 :         break;
    2212             : 
    2213             :         case EXC_ID_CHPIE:
    2214          37 :             rStrm >> maData.mnRotation >> maData.mnPieHole;
    2215          37 :             if( GetBiff() == EXC_BIFF8 )
    2216          37 :                 rStrm >> maData.mnFlags;
    2217             :             else
    2218           0 :                 maData.mnFlags = 0;
    2219          37 :         break;
    2220             : 
    2221             :         case EXC_ID_CHPIEEXT:
    2222           0 :             maData.mnRotation = 0;
    2223           0 :             maData.mnPieHole = 0;
    2224           0 :             maData.mnFlags = 0;
    2225           0 :         break;
    2226             : 
    2227             :         case EXC_ID_CHSCATTER:
    2228           0 :             if( GetBiff() == EXC_BIFF8 )
    2229           0 :                 rStrm >> maData.mnBubbleSize >> maData.mnBubbleType >> maData.mnFlags;
    2230             :             else
    2231           0 :                 maData.mnFlags = 0;
    2232           0 :         break;
    2233             : 
    2234             :         case EXC_ID_CHSURFACE:
    2235           0 :             rStrm >> maData.mnFlags;
    2236           0 :         break;
    2237             : 
    2238             :         default:
    2239         140 :             bKnownType = false;
    2240             :     }
    2241             : 
    2242         179 :     if( bKnownType )
    2243          39 :         mnRecId = nRecId;
    2244         179 : }
    2245             : 
    2246          40 : void XclImpChType::Finalize( bool bStockChart )
    2247             : {
    2248          40 :     switch( mnRecId )
    2249             :     {
    2250             :         case EXC_ID_CHLINE:
    2251             :             maTypeInfo = GetChartTypeInfo( bStockChart ?
    2252           1 :                 EXC_CHTYPEID_STOCK : EXC_CHTYPEID_LINE );
    2253           1 :         break;
    2254             :         case EXC_ID_CHBAR:
    2255             :             maTypeInfo = GetChartTypeInfo( ::get_flagvalue(
    2256             :                 maData.mnFlags, EXC_CHBAR_HORIZONTAL,
    2257           1 :                 EXC_CHTYPEID_HORBAR, EXC_CHTYPEID_BAR ) );
    2258           1 :         break;
    2259             :         case EXC_ID_CHPIE:
    2260          37 :             maTypeInfo = GetChartTypeInfo( (maData.mnPieHole > 0) ?
    2261          37 :                 EXC_CHTYPEID_DONUT : EXC_CHTYPEID_PIE );
    2262          37 :         break;
    2263             :         case EXC_ID_CHSCATTER:
    2264             :             maTypeInfo = GetChartTypeInfo( ::get_flagvalue(
    2265             :                 maData.mnFlags, EXC_CHSCATTER_BUBBLES,
    2266           0 :                 EXC_CHTYPEID_BUBBLES, EXC_CHTYPEID_SCATTER ) );
    2267           0 :         break;
    2268             :         default:
    2269           1 :             maTypeInfo = GetChartTypeInfo( mnRecId );
    2270             :     }
    2271             : 
    2272          40 :     switch( maTypeInfo.meTypeId )
    2273             :     {
    2274             :         case EXC_CHTYPEID_PIEEXT:
    2275             :         case EXC_CHTYPEID_BUBBLES:
    2276             :         case EXC_CHTYPEID_SURFACE:
    2277             :         case EXC_CHTYPEID_UNKNOWN:
    2278           1 :             GetTracer().TraceChartUnKnownType();
    2279           1 :         break;
    2280             :         default:;
    2281             :     }
    2282          40 : }
    2283             : 
    2284          80 : bool XclImpChType::IsStacked() const
    2285             : {
    2286          80 :     bool bStacked = false;
    2287          80 :     if( maTypeInfo.mbSupportsStacking ) switch( maTypeInfo.meTypeCateg )
    2288             :     {
    2289             :         case EXC_CHTYPECATEG_LINE:
    2290             :             bStacked =
    2291           4 :                 ::get_flag( maData.mnFlags, EXC_CHLINE_STACKED ) &&
    2292           4 :                 !::get_flag( maData.mnFlags, EXC_CHLINE_PERCENT );
    2293           2 :         break;
    2294             :         case EXC_CHTYPECATEG_BAR:
    2295             :             bStacked =
    2296           4 :                 ::get_flag( maData.mnFlags, EXC_CHBAR_STACKED ) &&
    2297           4 :                 !::get_flag( maData.mnFlags, EXC_CHBAR_PERCENT );
    2298           4 :         break;
    2299             :         default:;
    2300             :     }
    2301          80 :     return bStacked;
    2302             : }
    2303             : 
    2304         118 : bool XclImpChType::IsPercent() const
    2305             : {
    2306         118 :     bool bPercent = false;
    2307         118 :     if( maTypeInfo.mbSupportsStacking ) switch( maTypeInfo.meTypeCateg )
    2308             :     {
    2309             :         case EXC_CHTYPECATEG_LINE:
    2310             :             bPercent =
    2311           2 :                 ::get_flag( maData.mnFlags, EXC_CHLINE_STACKED ) &&
    2312           2 :                 ::get_flag( maData.mnFlags, EXC_CHLINE_PERCENT );
    2313           1 :         break;
    2314             :         case EXC_CHTYPECATEG_BAR:
    2315             :             bPercent =
    2316           6 :                 ::get_flag( maData.mnFlags, EXC_CHBAR_STACKED ) &&
    2317           6 :                 ::get_flag( maData.mnFlags, EXC_CHBAR_PERCENT );
    2318           6 :         break;
    2319             :         default:;
    2320             :     }
    2321         118 :     return bPercent;
    2322             : }
    2323             : 
    2324          40 : bool XclImpChType::HasCategoryLabels() const
    2325             : {
    2326             :     // radar charts disable category labels in chart type, not in CHTICK of X axis
    2327          40 :     return (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_RADAR) || ::get_flag( maData.mnFlags, EXC_CHRADAR_AXISLABELS );
    2328             : }
    2329             : 
    2330          40 : Reference< XCoordinateSystem > XclImpChType::CreateCoordSystem( bool b3dChart ) const
    2331             : {
    2332             :     // create the coordinate system object
    2333          40 :     Reference< css::uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
    2334          40 :     Reference< XCoordinateSystem > xCoordSystem;
    2335          40 :     if( maTypeInfo.mbPolarCoordSystem )
    2336             :     {
    2337          37 :         if( b3dChart )
    2338           0 :             xCoordSystem = css::chart2::PolarCoordinateSystem2d::create(xContext);
    2339             :         else
    2340          37 :             xCoordSystem = css::chart2::PolarCoordinateSystem3d::create(xContext);
    2341             :     }
    2342             :     else
    2343             :     {
    2344           3 :         if( b3dChart )
    2345           0 :             xCoordSystem = css::chart2::CartesianCoordinateSystem3d::create(xContext);
    2346             :         else
    2347           3 :             xCoordSystem = css::chart2::CartesianCoordinateSystem2d::create(xContext);
    2348             :     }
    2349             : 
    2350             :     // swap X and Y axis
    2351          40 :     if( maTypeInfo.mbSwappedAxesSet )
    2352             :     {
    2353           0 :         ScfPropertySet aCoordSysProp( xCoordSystem );
    2354           0 :         aCoordSysProp.SetBoolProperty( EXC_CHPROP_SWAPXANDYAXIS, true );
    2355             :     }
    2356             : 
    2357          40 :     return xCoordSystem;
    2358             : }
    2359             : 
    2360          40 : Reference< XChartType > XclImpChType::CreateChartType( Reference< XDiagram > xDiagram, bool b3dChart ) const
    2361             : {
    2362          40 :     OUString aService = OUString::createFromAscii( maTypeInfo.mpcServiceName );
    2363          40 :     Reference< XChartType > xChartType( ScfApiHelper::CreateInstance( aService ), UNO_QUERY );
    2364             : 
    2365             :     // additional properties
    2366          40 :     switch( maTypeInfo.meTypeCateg )
    2367             :     {
    2368             :         case EXC_CHTYPECATEG_BAR:
    2369             :         {
    2370           2 :             ScfPropertySet aTypeProp( xChartType );
    2371           4 :             Sequence< sal_Int32 > aInt32Seq( 2 );
    2372           2 :             aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = -maData.mnOverlap;
    2373           2 :             aTypeProp.SetProperty( EXC_CHPROP_OVERLAPSEQ, aInt32Seq );
    2374           2 :             aInt32Seq[ 0 ] = aInt32Seq[ 1 ] = maData.mnGap;
    2375           4 :             aTypeProp.SetProperty( EXC_CHPROP_GAPWIDTHSEQ, aInt32Seq );
    2376             :         }
    2377           2 :         break;
    2378             :         case EXC_CHTYPECATEG_PIE:
    2379             :         {
    2380          37 :             ScfPropertySet aTypeProp( xChartType );
    2381          37 :             aTypeProp.SetBoolProperty( EXC_CHPROP_USERINGS, maTypeInfo.meTypeId == EXC_CHTYPEID_DONUT );
    2382             :             /*  #i85166# starting angle of first pie slice. 3D pie charts use Y
    2383             :                 rotation setting in view3D element. Of-pie charts do not
    2384             :                 support pie rotation. */
    2385          37 :             if( !b3dChart && (maTypeInfo.meTypeId != EXC_CHTYPEID_PIEEXT) )
    2386             :             {
    2387          37 :                 ScfPropertySet aDiaProp( xDiagram );
    2388          37 :                 XclImpChRoot::ConvertPieRotation( aDiaProp, maData.mnRotation );
    2389          37 :             }
    2390             :         }
    2391          37 :         break;
    2392             :         default:;
    2393             :     }
    2394             : 
    2395          40 :     return xChartType;
    2396             : }
    2397             : 
    2398             : // ----------------------------------------------------------------------------
    2399             : 
    2400           0 : void XclImpChChart3d::ReadChChart3d( XclImpStream& rStrm )
    2401             : {
    2402           0 :     rStrm   >> maData.mnRotation
    2403           0 :             >> maData.mnElevation
    2404           0 :             >> maData.mnEyeDist
    2405           0 :             >> maData.mnRelHeight
    2406           0 :             >> maData.mnRelDepth
    2407           0 :             >> maData.mnDepthGap
    2408           0 :             >> maData.mnFlags;
    2409           0 : }
    2410             : 
    2411           0 : void XclImpChChart3d::Convert( ScfPropertySet& rPropSet, bool b3dWallChart ) const
    2412             : {
    2413             :     namespace cssd = ::com::sun::star::drawing;
    2414             : 
    2415             : //    #i104057# do not assert this, written by broken external generators
    2416             : //    OSL_ENSURE( ::get_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS ) == b3dWallChart, "XclImpChChart3d::Convert - wrong wall flag" );
    2417             : 
    2418           0 :     sal_Int32 nRotationY = 0;
    2419           0 :     sal_Int32 nRotationX = 0;
    2420           0 :     sal_Int32 nPerspective = 15;
    2421           0 :     bool bRightAngled = false;
    2422           0 :     cssd::ProjectionMode eProjMode = cssd::ProjectionMode_PERSPECTIVE;
    2423           0 :     Color aAmbientColor, aLightColor;
    2424             : 
    2425           0 :     if( b3dWallChart )
    2426             :     {
    2427             :         // Y rotation (Excel [0..359], Chart2 [-179,180])
    2428           0 :         nRotationY = maData.mnRotation % 360;
    2429           0 :         if( nRotationY > 180 ) nRotationY -= 360;
    2430             :         // X rotation a.k.a. elevation (Excel [-90..90], Chart2 [-179,180])
    2431           0 :         nRotationX = limit_cast< sal_Int32, sal_Int32 >( maData.mnElevation, -90, 90 );
    2432             :         // perspective (Excel and Chart2 [0,100])
    2433           0 :         nPerspective = limit_cast< sal_Int32, sal_Int32 >( maData.mnEyeDist, 0, 100 );
    2434             :         // right-angled axes
    2435           0 :         bRightAngled = !::get_flag( maData.mnFlags, EXC_CHCHART3D_REAL3D );
    2436             :         // projection mode (parallel axes, if right-angled, #i90360# or if perspective is at 0%)
    2437           0 :         bool bParallel = bRightAngled || (nPerspective == 0);
    2438           0 :         eProjMode = bParallel ? cssd::ProjectionMode_PARALLEL : cssd::ProjectionMode_PERSPECTIVE;
    2439             :         // ambient color (Gray 20%)
    2440           0 :         aAmbientColor.SetColor( RGB_COLORDATA( 204, 204, 204 ) );
    2441             :         // light color (Gray 60%)
    2442           0 :         aLightColor.SetColor( RGB_COLORDATA( 102, 102, 102 ) );
    2443             :     }
    2444             :     else
    2445             :     {
    2446             :         // Y rotation not used in pie charts, but 'first pie slice angle'
    2447           0 :         nRotationY = 0;
    2448           0 :         XclImpChRoot::ConvertPieRotation( rPropSet, maData.mnRotation );
    2449             :         // X rotation a.k.a. elevation (map Excel [10..80] to Chart2 [-80,-10])
    2450           0 :         nRotationX = limit_cast< sal_Int32, sal_Int32 >( maData.mnElevation, 10, 80 ) - 90;
    2451             :         // perspective (Excel and Chart2 [0,100])
    2452           0 :         nPerspective = limit_cast< sal_Int32, sal_Int32 >( maData.mnEyeDist, 0, 100 );
    2453             :         // no right-angled axes in pie charts, but parallel projection
    2454           0 :         bRightAngled = false;
    2455           0 :         eProjMode = cssd::ProjectionMode_PARALLEL;
    2456             :         // ambient color (Gray 30%)
    2457           0 :         aAmbientColor.SetColor( RGB_COLORDATA( 179, 179, 179 ) );
    2458             :         // light color (Gray 70%)
    2459           0 :         aLightColor.SetColor( RGB_COLORDATA( 76, 76, 76 ) );
    2460             :     }
    2461             : 
    2462             :     // properties
    2463           0 :     rPropSet.SetProperty( EXC_CHPROP_3DRELATIVEHEIGHT, (sal_Int32)(maData.mnRelHeight / 2)); // seems to be 200%, cange to 100%
    2464           0 :     rPropSet.SetProperty( EXC_CHPROP_ROTATIONVERTICAL, nRotationY );
    2465           0 :     rPropSet.SetProperty( EXC_CHPROP_ROTATIONHORIZONTAL, nRotationX );
    2466           0 :     rPropSet.SetProperty( EXC_CHPROP_PERSPECTIVE, nPerspective );
    2467           0 :     rPropSet.SetBoolProperty( EXC_CHPROP_RIGHTANGLEDAXES, bRightAngled );
    2468           0 :     rPropSet.SetProperty( EXC_CHPROP_D3DSCENEPERSPECTIVE, eProjMode );
    2469             : 
    2470             :     // light settings
    2471           0 :     rPropSet.SetProperty( EXC_CHPROP_D3DSCENESHADEMODE, cssd::ShadeMode_FLAT );
    2472           0 :     rPropSet.SetColorProperty( EXC_CHPROP_D3DSCENEAMBIENTCOLOR, aAmbientColor );
    2473           0 :     rPropSet.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON1, false );
    2474           0 :     rPropSet.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON2, true );
    2475           0 :     rPropSet.SetColorProperty( EXC_CHPROP_D3DSCENELIGHTCOLOR2, aLightColor );
    2476           0 :     rPropSet.SetProperty( EXC_CHPROP_D3DSCENELIGHTDIR2, cssd::Direction3D( 0.2, 0.4, 1.0 ) );
    2477           0 : }
    2478             : 
    2479             : // ----------------------------------------------------------------------------
    2480             : 
    2481          21 : XclImpChLegend::XclImpChLegend( const XclImpChRoot& rRoot ) :
    2482          21 :     XclImpChRoot( rRoot )
    2483             : {
    2484          21 : }
    2485             : 
    2486          21 : void XclImpChLegend::ReadHeaderRecord( XclImpStream& rStrm )
    2487             : {
    2488          21 :     rStrm >> maData.maRect >> maData.mnDockMode >> maData.mnSpacing >> maData.mnFlags;
    2489             : 
    2490             :     // trace unsupported features
    2491          21 :     if( GetTracer().IsEnabled() )
    2492             :     {
    2493           0 :         if( maData.mnDockMode == EXC_CHLEGEND_NOTDOCKED )
    2494           0 :             GetTracer().TraceChartLegendPosition();
    2495           0 :         if( ::get_flag( maData.mnFlags, EXC_CHLEGEND_DATATABLE ) )
    2496           0 :             GetTracer().TraceChartDataTable();
    2497             :     }
    2498          21 : }
    2499             : 
    2500         179 : void XclImpChLegend::ReadSubRecord( XclImpStream& rStrm )
    2501             : {
    2502         179 :     switch( rStrm.GetRecId() )
    2503             :     {
    2504             :         case EXC_ID_CHFRAMEPOS:
    2505          21 :             mxFramePos.reset( new XclImpChFramePos );
    2506          21 :             mxFramePos->ReadChFramePos( rStrm );
    2507          21 :         break;
    2508             :         case EXC_ID_CHTEXT:
    2509          21 :             mxText.reset( new XclImpChText( GetChRoot() ) );
    2510          21 :             mxText->ReadRecordGroup( rStrm );
    2511          21 :         break;
    2512             :         case EXC_ID_CHFRAME:
    2513          19 :             mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
    2514          19 :             mxFrame->ReadRecordGroup( rStrm );
    2515          19 :         break;
    2516             :     }
    2517         179 : }
    2518             : 
    2519          21 : void XclImpChLegend::Finalize()
    2520             : {
    2521             :     // legend default formatting differs in OOChart and Excel, missing frame means automatic
    2522          21 :     if( !mxFrame )
    2523           2 :         mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
    2524             :     // Update text formatting. If mxText is empty, the passed default text is used.
    2525          21 :     lclUpdateText( mxText, GetChartData().GetDefaultText( EXC_CHTEXTTYPE_LEGEND ) );
    2526          21 : }
    2527             : 
    2528          21 : Reference< XLegend > XclImpChLegend::CreateLegend() const
    2529             : {
    2530          21 :     Reference< XLegend > xLegend( ScfApiHelper::CreateInstance( SERVICE_CHART2_LEGEND ), UNO_QUERY );
    2531          21 :     if( xLegend.is() )
    2532             :     {
    2533          21 :         ScfPropertySet aLegendProp( xLegend );
    2534          21 :         aLegendProp.SetBoolProperty( EXC_CHPROP_SHOW, true );
    2535             : 
    2536             :         // frame properties
    2537          21 :         if( mxFrame )
    2538          21 :             mxFrame->Convert( aLegendProp );
    2539             :         // text properties
    2540          21 :         if( mxText )
    2541          21 :             mxText->ConvertFont( aLegendProp );
    2542             : 
    2543             :         /*  Legend position and size. Default positions are used only if the
    2544             :             plot area is positioned automatically (Excel sets the plot area to
    2545             :             manual mode, if the legend is moved or resized). With manual plot
    2546             :             areas, Excel ignores the value in maData.mnDockMode completely. */
    2547          21 :         cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
    2548          21 :         cssc::ChartLegendExpansion eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
    2549          21 :         if( !GetChartData().IsManualPlotArea() ) switch( maData.mnDockMode )
    2550             :         {
    2551             :             case EXC_CHLEGEND_LEFT:
    2552           0 :                 eApiPos = cssc2::LegendPosition_LINE_START;
    2553           0 :                 eApiExpand = cssc::ChartLegendExpansion_HIGH;
    2554           0 :             break;
    2555             :             case EXC_CHLEGEND_RIGHT:
    2556             :             // top-right not supported
    2557             :             case EXC_CHLEGEND_CORNER:
    2558           1 :                 eApiPos = cssc2::LegendPosition_LINE_END;
    2559           1 :                 eApiExpand = cssc::ChartLegendExpansion_HIGH;
    2560           1 :             break;
    2561             :             case EXC_CHLEGEND_TOP:
    2562           0 :                 eApiPos = cssc2::LegendPosition_PAGE_START;
    2563           0 :                 eApiExpand = cssc::ChartLegendExpansion_WIDE;
    2564           0 :             break;
    2565             :             case EXC_CHLEGEND_BOTTOM:
    2566           0 :                 eApiPos = cssc2::LegendPosition_PAGE_END;
    2567           0 :                 eApiExpand = cssc::ChartLegendExpansion_WIDE;
    2568           0 :             break;
    2569             :         }
    2570             : 
    2571             :         // no automatic position/size: try to find the correct position and size
    2572          21 :         if( eApiPos == cssc2::LegendPosition_CUSTOM )
    2573             :         {
    2574          20 :             const XclChFramePos* pFramePos = mxFramePos ? &mxFramePos->GetFramePosData() : 0;
    2575             : 
    2576             :             /*  Legend position. Only the settings from the CHFRAMEPOS record
    2577             :                 are used by Excel, the position in the CHLEGEND record will be
    2578             :                 ignored. */
    2579          20 :             if( pFramePos )
    2580             :             {
    2581             :                 RelativePosition aRelPos(
    2582          20 :                     CalcRelativeFromChartX( pFramePos->maRect.mnX ),
    2583          20 :                     CalcRelativeFromChartY( pFramePos->maRect.mnY ),
    2584          60 :                     ::com::sun::star::drawing::Alignment_TOP_LEFT );
    2585          20 :                 aLegendProp.SetProperty( EXC_CHPROP_RELATIVEPOSITION, aRelPos );
    2586             :             }
    2587             :             else
    2588             :             {
    2589             :                 // no manual position/size found, just go for the default
    2590           0 :                 eApiPos = cssc2::LegendPosition_LINE_END;
    2591             :             }
    2592             : 
    2593             :             /*  Legend size. The member mnBRMode specifies whether size is
    2594             :                 automatic or changes manually. Manual size is given in points,
    2595             :                 not in chart units. */
    2596          39 :             if( pFramePos && (pFramePos->mnBRMode == EXC_CHFRAMEPOS_ABSSIZE_POINTS) &&
    2597          38 :                 (pFramePos->maRect.mnWidth > 0) && (pFramePos->maRect.mnHeight > 0) )
    2598             :             {
    2599          19 :                 eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
    2600          19 :                 sal_Int32 nWidthHmm = static_cast< sal_Int32 >( pFramePos->maRect.mnWidth / EXC_POINTS_PER_HMM );
    2601          19 :                 sal_Int32 nHeightHmm = static_cast< sal_Int32 >( pFramePos->maRect.mnHeight / EXC_POINTS_PER_HMM );
    2602          19 :                 RelativeSize aRelSize( CalcRelativeFromHmmX( nWidthHmm ), CalcRelativeFromHmmY( nHeightHmm ) );
    2603          19 :                 aLegendProp.SetProperty( EXC_CHPROP_RELATIVESIZE, aRelSize );
    2604             :             }
    2605             :             else
    2606             :             {
    2607             :                 // automatic size: determine entry direction from flags
    2608             :                 eApiExpand = ::get_flagvalue( maData.mnFlags, EXC_CHLEGEND_STACKED,
    2609           1 :                     cssc::ChartLegendExpansion_HIGH, cssc::ChartLegendExpansion_WIDE );
    2610             :             }
    2611             :         }
    2612          21 :         aLegendProp.SetProperty( EXC_CHPROP_ANCHORPOSITION, eApiPos );
    2613          21 :         aLegendProp.SetProperty( EXC_CHPROP_EXPANSION, eApiExpand );
    2614             :     }
    2615          21 :     return xLegend;
    2616             : }
    2617             : 
    2618             : // ----------------------------------------------------------------------------
    2619             : 
    2620           0 : XclImpChDropBar::XclImpChDropBar( sal_uInt16 nDropBar ) :
    2621             :     mnDropBar( nDropBar ),
    2622           0 :     mnBarDist( 0 )
    2623             : {
    2624           0 : }
    2625             : 
    2626           0 : void XclImpChDropBar::ReadHeaderRecord( XclImpStream& rStrm )
    2627             : {
    2628           0 :     rStrm >> mnBarDist;
    2629           0 : }
    2630             : 
    2631           0 : void XclImpChDropBar::Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const
    2632             : {
    2633           0 :     XclChObjectType eObjType = EXC_CHOBJTYPE_BACKGROUND;
    2634           0 :     switch( mnDropBar )
    2635             :     {
    2636           0 :         case EXC_CHDROPBAR_UP:      eObjType = EXC_CHOBJTYPE_WHITEDROPBAR;  break;
    2637           0 :         case EXC_CHDROPBAR_DOWN:    eObjType = EXC_CHOBJTYPE_BLACKDROPBAR;  break;
    2638             :     }
    2639           0 :     ConvertFrameBase( rRoot, rPropSet, eObjType );
    2640           0 : }
    2641             : 
    2642             : // ----------------------------------------------------------------------------
    2643             : 
    2644          40 : XclImpChTypeGroup::XclImpChTypeGroup( const XclImpChRoot& rRoot ) :
    2645             :     XclImpChRoot( rRoot ),
    2646             :     maType( rRoot ),
    2647          40 :     maTypeInfo( maType.GetTypeInfo() )
    2648             : {
    2649             :     // Initialize unused format indexes set. At this time, all formats are unused.
    2650       10280 :     for( sal_uInt16 nFormatIdx = 0; nFormatIdx <= EXC_CHSERIES_MAXSERIES; ++nFormatIdx )
    2651       10240 :         maUnusedFormats.insert( maUnusedFormats.end(), nFormatIdx );
    2652          40 : }
    2653             : 
    2654          40 : void XclImpChTypeGroup::ReadHeaderRecord( XclImpStream& rStrm )
    2655             : {
    2656          40 :     rStrm.Ignore( 16 );
    2657          40 :     rStrm >> maData.mnFlags >> maData.mnGroupIdx;
    2658          40 : }
    2659             : 
    2660         219 : void XclImpChTypeGroup::ReadSubRecord( XclImpStream& rStrm )
    2661             : {
    2662         219 :     switch( rStrm.GetRecId() )
    2663             :     {
    2664             :         case EXC_ID_CHCHART3D:
    2665           0 :             mxChart3d.reset( new XclImpChChart3d );
    2666           0 :             mxChart3d->ReadChChart3d( rStrm );
    2667           0 :         break;
    2668             :         case EXC_ID_CHLEGEND:
    2669          21 :             mxLegend.reset( new XclImpChLegend( GetChRoot() ) );
    2670          21 :             mxLegend->ReadRecordGroup( rStrm );
    2671          21 :         break;
    2672             :         case EXC_ID_CHDEFAULTTEXT:
    2673           0 :             GetChartData().ReadChDefaultText( rStrm );
    2674           0 :         break;
    2675             :         case EXC_ID_CHDROPBAR:
    2676           0 :             ReadChDropBar( rStrm );
    2677           0 :         break;
    2678             :         case EXC_ID_CHCHARTLINE:
    2679           0 :             ReadChChartLine( rStrm );
    2680           0 :         break;
    2681             :         case EXC_ID_CHDATAFORMAT:
    2682          19 :             ReadChDataFormat( rStrm );
    2683          19 :         break;
    2684             :         default:
    2685         179 :             maType.ReadChType( rStrm );
    2686             :     }
    2687         219 : }
    2688             : 
    2689          40 : void XclImpChTypeGroup::Finalize()
    2690             : {
    2691             :     // check and set valid chart type
    2692             :     bool bStockChart =
    2693          41 :         (maType.GetRecId() == EXC_ID_CHLINE) &&         // must be a line chart
    2694           2 :         !mxChart3d &&                                   // must be a 2d chart
    2695          41 :         HasHiLoLine() &&                                // must contain hi-lo lines
    2696          40 :         (maSeries.size() == static_cast<XclImpChSeriesVec::size_type>(HasDropBars() ? 4 : 3));   // correct series count
    2697          40 :     maType.Finalize( bStockChart );
    2698             : 
    2699             :     // extended type info
    2700          40 :     maTypeInfo.Set( maType.GetTypeInfo(), static_cast< bool >(mxChart3d), false );
    2701             : 
    2702             :     // reverse series order for some unstacked 2D chart types
    2703          40 :     if( maTypeInfo.mbReverseSeries && !Is3dChart() && !maType.IsStacked() && !maType.IsPercent() )
    2704           0 :         ::std::reverse( maSeries.begin(), maSeries.end() );
    2705             : 
    2706             :     // update chart type group format, may depend on chart type finalized above
    2707          40 :     if( mxGroupFmt )
    2708          19 :         mxGroupFmt->UpdateGroupFormat( maTypeInfo );
    2709          40 : }
    2710             : 
    2711          40 : void XclImpChTypeGroup::AddSeries( XclImpChSeriesRef xSeries )
    2712             : {
    2713          40 :     if( xSeries )
    2714          40 :         maSeries.push_back( xSeries );
    2715             :     // store first inserted series separately, series order may be reversed later
    2716          40 :     if( !mxFirstSeries )
    2717          40 :         mxFirstSeries = xSeries;
    2718          40 : }
    2719             : 
    2720          40 : void XclImpChTypeGroup::SetUsedFormatIndex( sal_uInt16 nFormatIdx )
    2721             : {
    2722          40 :     maUnusedFormats.erase( nFormatIdx );
    2723          40 : }
    2724             : 
    2725           0 : sal_uInt16 XclImpChTypeGroup::PopUnusedFormatIndex()
    2726             : {
    2727             :     OSL_ENSURE( !maUnusedFormats.empty(), "XclImpChTypeGroup::PopUnusedFormatIndex - no more format indexes available" );
    2728           0 :     sal_uInt16 nFormatIdx = maUnusedFormats.empty() ? 0 : *maUnusedFormats.begin();
    2729           0 :     SetUsedFormatIndex( nFormatIdx );
    2730           0 :     return nFormatIdx;
    2731             : }
    2732             : 
    2733          40 : bool XclImpChTypeGroup::HasVarPointFormat() const
    2734             : {
    2735         116 :     return ::get_flag( maData.mnFlags, EXC_CHTYPEGROUP_VARIEDCOLORS ) &&
    2736          39 :         ((maTypeInfo.meVarPointMode == EXC_CHVARPOINT_MULTI) ||         // multiple series allowed
    2737           2 :             ((maTypeInfo.meVarPointMode == EXC_CHVARPOINT_SINGLE) &&    // or exactly 1 series?
    2738          41 :                 (maSeries.size() == 1)));
    2739             : }
    2740             : 
    2741          40 : bool XclImpChTypeGroup::HasConnectorLines() const
    2742             : {
    2743             :     // existence of connector lines (only in stacked bar charts)
    2744          40 :     if ( !(maType.IsStacked() || maType.IsPercent()) || (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_BAR) )
    2745          40 :         return false;
    2746           0 :     XclImpChLineFormatMap::const_iterator xConLine = maChartLines.find( EXC_CHCHARTLINE_CONNECT );
    2747           0 :     return ( xConLine != maChartLines.end() && xConLine->second->HasLine() );
    2748             : }
    2749             : 
    2750          38 : const String& XclImpChTypeGroup::GetSingleSeriesTitle() const
    2751             : {
    2752             :     // no automatic title for series with trendlines or error bars
    2753             :     // pie charts always show an automatic title, even if more series exist
    2754          76 :     return (mxFirstSeries && !mxFirstSeries->HasChildSeries() && (maTypeInfo.mbSingleSeriesVis || (maSeries.size() == 1))) ?
    2755          76 :         mxFirstSeries->GetTitle() : String::EmptyString();
    2756             : }
    2757             : 
    2758          40 : void XclImpChTypeGroup::ConvertChart3d( ScfPropertySet& rPropSet ) const
    2759             : {
    2760          40 :     if( mxChart3d )
    2761           0 :         mxChart3d->Convert( rPropSet, Is3dWallChart() );
    2762          40 : }
    2763             : 
    2764          40 : Reference< XCoordinateSystem > XclImpChTypeGroup::CreateCoordSystem() const
    2765             : {
    2766          40 :     return maType.CreateCoordSystem( Is3dChart() );
    2767             : }
    2768             : 
    2769          40 : Reference< XChartType > XclImpChTypeGroup::CreateChartType( Reference< XDiagram > xDiagram, sal_Int32 nApiAxesSetIdx ) const
    2770             : {
    2771             :     OSL_ENSURE( IsValidGroup(), "XclImpChTypeGroup::CreateChartType - type group without series" );
    2772             : 
    2773             :     // create the chart type object
    2774          40 :     Reference< XChartType > xChartType = maType.CreateChartType( xDiagram, Is3dChart() );
    2775             : 
    2776             :     // bar chart connector lines
    2777          40 :     if( HasConnectorLines() )
    2778             :     {
    2779           0 :         ScfPropertySet aDiaProp( xDiagram );
    2780           0 :         aDiaProp.SetBoolProperty( EXC_CHPROP_CONNECTBARS, true );
    2781             :     }
    2782             : 
    2783             :     /*  Stock chart needs special processing. Create one 'big' series with
    2784             :         data sequences of different roles. */
    2785          40 :     if( maTypeInfo.meTypeId == EXC_CHTYPEID_STOCK )
    2786           0 :         CreateStockSeries( xChartType, nApiAxesSetIdx );
    2787             :     else
    2788          40 :         CreateDataSeries( xChartType, nApiAxesSetIdx );
    2789             : 
    2790          40 :     return xChartType;
    2791             : }
    2792             : 
    2793          40 : Reference< XLabeledDataSequence > XclImpChTypeGroup::CreateCategSequence() const
    2794             : {
    2795          40 :     Reference< XLabeledDataSequence > xLabeledSeq;
    2796             :     // create category sequence from first visible series
    2797          40 :     if( mxFirstSeries )
    2798          40 :         xLabeledSeq = mxFirstSeries->CreateCategSequence( EXC_CHPROP_ROLE_CATEG );
    2799          40 :     return xLabeledSeq;
    2800             : }
    2801             : 
    2802           0 : void XclImpChTypeGroup::ReadChDropBar( XclImpStream& rStrm )
    2803             : {
    2804           0 :     if (maDropBars.find(EXC_CHDROPBAR_UP) == maDropBars.end())
    2805             :     {
    2806             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2807           0 :         auto_ptr<XclImpChDropBar> p(new XclImpChDropBar(EXC_CHDROPBAR_UP));
    2808             :         SAL_WNODEPRECATED_DECLARATIONS_POP
    2809           0 :         p->ReadRecordGroup(rStrm);
    2810           0 :         maDropBars.insert(EXC_CHDROPBAR_UP, p);
    2811             :     }
    2812           0 :     else if(maDropBars.find(EXC_CHDROPBAR_DOWN) == maDropBars.end())
    2813             :     {
    2814             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2815           0 :         auto_ptr<XclImpChDropBar> p(new XclImpChDropBar(EXC_CHDROPBAR_DOWN));
    2816             :         SAL_WNODEPRECATED_DECLARATIONS_POP
    2817           0 :         p->ReadRecordGroup(rStrm);
    2818           0 :         maDropBars.insert(EXC_CHDROPBAR_DOWN, p);
    2819             :     }
    2820           0 : }
    2821             : 
    2822           0 : void XclImpChTypeGroup::ReadChChartLine( XclImpStream& rStrm )
    2823             : {
    2824           0 :     sal_uInt16 nLineId = rStrm.ReaduInt16();
    2825           0 :     if( (rStrm.GetNextRecId() == EXC_ID_CHLINEFORMAT) && rStrm.StartNextRecord() )
    2826             :     {
    2827           0 :         XclImpChLineFormat xLineFmt;
    2828           0 :         xLineFmt.ReadChLineFormat( rStrm );
    2829           0 :         maChartLines[ nLineId ] = xLineFmt;
    2830             :     }
    2831           0 : }
    2832             : 
    2833          19 : void XclImpChTypeGroup::ReadChDataFormat( XclImpStream& rStrm )
    2834             : {
    2835             :     // global series and data point format
    2836          19 :     XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
    2837          19 :     xDataFmt->ReadRecordGroup( rStrm );
    2838          19 :     const XclChDataPointPos& rPos = xDataFmt->GetPointPos();
    2839          38 :     if( (rPos.mnSeriesIdx == 0) && (rPos.mnPointIdx == 0) &&
    2840          19 :             (xDataFmt->GetFormatIdx() == EXC_CHDATAFORMAT_DEFAULT) )
    2841          19 :         mxGroupFmt = xDataFmt;
    2842          19 : }
    2843             : 
    2844             : 
    2845          40 : void XclImpChTypeGroup::InsertDataSeries( Reference< XChartType > xChartType,
    2846             :         Reference< XDataSeries > xSeries, sal_Int32 nApiAxesSetIdx ) const
    2847             : {
    2848          40 :     Reference< XDataSeriesContainer > xSeriesCont( xChartType, UNO_QUERY );
    2849          40 :     if( xSeriesCont.is() && xSeries.is() )
    2850             :     {
    2851             :         // series stacking mode
    2852          40 :         cssc2::StackingDirection eStacking = cssc2::StackingDirection_NO_STACKING;
    2853             :         // stacked overrides deep-3d
    2854          40 :         if( maType.IsStacked() || maType.IsPercent() )
    2855           1 :             eStacking = cssc2::StackingDirection_Y_STACKING;
    2856          39 :         else if( Is3dDeepChart() )
    2857           0 :             eStacking = cssc2::StackingDirection_Z_STACKING;
    2858             : 
    2859             :         // additional series properties
    2860          40 :         ScfPropertySet aSeriesProp( xSeries );
    2861          40 :         aSeriesProp.SetProperty( EXC_CHPROP_STACKINGDIR, eStacking );
    2862          40 :         aSeriesProp.SetProperty( EXC_CHPROP_ATTAXISINDEX, nApiAxesSetIdx );
    2863             : 
    2864             :         // insert series into container
    2865             :         try
    2866             :         {
    2867          40 :             xSeriesCont->addDataSeries( xSeries );
    2868             :         }
    2869           0 :         catch( Exception& )
    2870             :         {
    2871             :             OSL_FAIL( "XclImpChTypeGroup::InsertDataSeries - cannot add data series" );
    2872          40 :         }
    2873          40 :     }
    2874          40 : }
    2875             : 
    2876          40 : void XclImpChTypeGroup::CreateDataSeries( Reference< XChartType > xChartType, sal_Int32 nApiAxesSetIdx ) const
    2877             : {
    2878          40 :     bool bSpline = false;
    2879          80 :     for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt )
    2880             :     {
    2881          40 :         Reference< XDataSeries > xDataSeries = (*aIt)->CreateDataSeries();
    2882          40 :         InsertDataSeries( xChartType, xDataSeries, nApiAxesSetIdx );
    2883          40 :         bSpline |= (*aIt)->HasSpline();
    2884          40 :     }
    2885             :     // spline - TODO: set at single series (#i66858#)
    2886          40 :     if( bSpline && !maTypeInfo.IsSeriesFrameFormat() && (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_RADAR) )
    2887             :     {
    2888           0 :         ScfPropertySet aTypeProp( xChartType );
    2889           0 :         aTypeProp.SetProperty( EXC_CHPROP_CURVESTYLE, ::com::sun::star::chart2::CurveStyle_CUBIC_SPLINES );
    2890             :     }
    2891          40 : }
    2892             : 
    2893           0 : void XclImpChTypeGroup::CreateStockSeries( Reference< XChartType > xChartType, sal_Int32 nApiAxesSetIdx ) const
    2894             : {
    2895             :     // create the data series object
    2896           0 :     Reference< XDataSeries > xDataSeries( ScfApiHelper::CreateInstance( SERVICE_CHART2_DATASERIES ), UNO_QUERY );
    2897           0 :     Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
    2898           0 :     if( xDataSink.is() )
    2899             :     {
    2900             :         // create a list of data sequences from all series
    2901           0 :         ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
    2902             :         OSL_ENSURE( maSeries.size() >= 3, "XclImpChTypeGroup::CreateChartType - missing stock series" );
    2903           0 :         int nRoleIdx = (maSeries.size() == 3) ? 1 : 0;
    2904           0 :         for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end();
    2905           0 :                 (nRoleIdx < 4) && (aIt != aEnd); ++nRoleIdx, ++aIt )
    2906             :         {
    2907             :             // create a data sequence with a specific role
    2908           0 :             OUString aRole;
    2909           0 :             switch( nRoleIdx )
    2910             :             {
    2911           0 :                 case 0: aRole = EXC_CHPROP_ROLE_OPENVALUES;     break;
    2912           0 :                 case 1: aRole = EXC_CHPROP_ROLE_HIGHVALUES;     break;
    2913           0 :                 case 2: aRole = EXC_CHPROP_ROLE_LOWVALUES;      break;
    2914           0 :                 case 3: aRole = EXC_CHPROP_ROLE_CLOSEVALUES;    break;
    2915             :             }
    2916           0 :             Reference< XLabeledDataSequence > xDataSeq = (*aIt)->CreateValueSequence( aRole );
    2917           0 :             if( xDataSeq.is() )
    2918           0 :                 aLabeledSeqVec.push_back( xDataSeq );
    2919           0 :         }
    2920             : 
    2921             :         // attach labeled data sequences to series and insert series into chart type
    2922           0 :         xDataSink->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec ) );
    2923             : 
    2924             :         // formatting of special stock chart elements
    2925           0 :         ScfPropertySet aTypeProp( xChartType );
    2926           0 :         aTypeProp.SetBoolProperty( EXC_CHPROP_JAPANESE, HasDropBars() );
    2927           0 :         aTypeProp.SetBoolProperty( EXC_CHPROP_SHOWFIRST, HasDropBars() );
    2928           0 :         aTypeProp.SetBoolProperty( EXC_CHPROP_SHOWHIGHLOW, true );
    2929             :         // hi-lo line format
    2930           0 :         XclImpChLineFormatMap::const_iterator xHiLoLine = maChartLines.find( EXC_CHCHARTLINE_HILO );
    2931           0 :         if ( xHiLoLine != maChartLines.end() )
    2932             :         {
    2933           0 :             ScfPropertySet aSeriesProp( xDataSeries );
    2934           0 :             xHiLoLine->second->Convert( GetChRoot(), aSeriesProp, EXC_CHOBJTYPE_HILOLINE );
    2935             :         }
    2936             :         // white dropbar format
    2937           0 :         XclImpChDropBarMap::const_iterator itr = maDropBars.find(EXC_CHDROPBAR_UP);
    2938           0 :         Reference<XPropertySet> xWhitePropSet;
    2939           0 :         if (itr != maDropBars.end() && aTypeProp.GetProperty(xWhitePropSet, EXC_CHPROP_WHITEDAY))
    2940             :         {
    2941           0 :             ScfPropertySet aBarProp( xWhitePropSet );
    2942           0 :             itr->second->Convert(GetChRoot(), aBarProp);
    2943             :         }
    2944             :         // black dropbar format
    2945           0 :         itr = maDropBars.find(EXC_CHDROPBAR_DOWN);
    2946           0 :         Reference<XPropertySet> xBlackPropSet;
    2947           0 :         if (itr != maDropBars.end() && aTypeProp.GetProperty(xBlackPropSet, EXC_CHPROP_BLACKDAY))
    2948             :         {
    2949           0 :             ScfPropertySet aBarProp( xBlackPropSet );
    2950           0 :             itr->second->Convert(GetChRoot(), aBarProp);
    2951             :         }
    2952             : 
    2953             :         // insert the series into the chart type object
    2954           0 :         InsertDataSeries( xChartType, xDataSeries, nApiAxesSetIdx );
    2955           0 :     }
    2956           0 : }
    2957             : 
    2958             : // Axes =======================================================================
    2959             : 
    2960          80 : XclImpChLabelRange::XclImpChLabelRange( const XclImpChRoot& rRoot ) :
    2961          80 :     XclImpChRoot( rRoot )
    2962             : {
    2963          80 : }
    2964             : 
    2965           2 : void XclImpChLabelRange::ReadChLabelRange( XclImpStream& rStrm )
    2966             : {
    2967           2 :     rStrm >> maLabelData.mnCross >> maLabelData.mnLabelFreq >> maLabelData.mnTickFreq >> maLabelData.mnFlags;
    2968           2 : }
    2969             : 
    2970           2 : void XclImpChLabelRange::ReadChDateRange( XclImpStream& rStrm )
    2971             : {
    2972           2 :     rStrm   >> maDateData.mnMinDate
    2973           4 :             >> maDateData.mnMaxDate
    2974           4 :             >> maDateData.mnMajorStep
    2975           4 :             >> maDateData.mnMajorUnit
    2976           4 :             >> maDateData.mnMinorStep
    2977           4 :             >> maDateData.mnMinorUnit
    2978           4 :             >> maDateData.mnBaseUnit
    2979           4 :             >> maDateData.mnCross
    2980           4 :             >> maDateData.mnFlags;
    2981           2 : }
    2982             : 
    2983          40 : void XclImpChLabelRange::Convert( ScfPropertySet& rPropSet, ScaleData& rScaleData, bool bMirrorOrient ) const
    2984             : {
    2985             :     // automatic axis type detection
    2986          40 :     rScaleData.AutoDateAxis = ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTODATE );
    2987             : 
    2988             :     // the flag EXC_CHDATERANGE_DATEAXIS specifies whether this is a date axis
    2989          40 :     if( ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS ) )
    2990             :     {
    2991             :         /*  Chart2 requires axis type CATEGORY for automatic category/date axis
    2992             :             (even if it is a date axis currently). */
    2993           0 :         rScaleData.AxisType = rScaleData.AutoDateAxis ? cssc2::AxisType::CATEGORY : cssc2::AxisType::DATE;
    2994           0 :         rScaleData.Scaling = css::chart2::LinearScaling::create( comphelper::getProcessComponentContext() );
    2995             :         /*  Min/max values depend on base time unit, they specify the number of
    2996             :             days, months, or years starting from null date. */
    2997           0 :         lclConvertTimeValue( GetRoot(), rScaleData.Minimum, maDateData.mnMinDate, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMIN ), maDateData.mnBaseUnit );
    2998           0 :         lclConvertTimeValue( GetRoot(), rScaleData.Maximum, maDateData.mnMaxDate, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAX ), maDateData.mnBaseUnit );
    2999             :         // increment
    3000           0 :         cssc::TimeIncrement& rTimeIncrement = rScaleData.TimeIncrement;
    3001           0 :         lclConvertTimeInterval( rTimeIncrement.MajorTimeInterval, maDateData.mnMajorStep, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAJOR ), maDateData.mnMajorUnit );
    3002           0 :         lclConvertTimeInterval( rTimeIncrement.MinorTimeInterval, maDateData.mnMinorStep, ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMINOR ), maDateData.mnMinorUnit );
    3003             :         // base unit
    3004           0 :         if( ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOBASE ) )
    3005           0 :             rTimeIncrement.TimeResolution.clear();
    3006             :         else
    3007           0 :             rTimeIncrement.TimeResolution <<= lclGetApiTimeUnit( maDateData.mnBaseUnit );
    3008             :     }
    3009             :     else
    3010             :     {
    3011             :         // do not overlap text unless all labels are visible
    3012          40 :         rPropSet.SetBoolProperty( EXC_CHPROP_TEXTOVERLAP, maLabelData.mnLabelFreq == 1 );
    3013             :         // do not break text into several lines unless all labels are visible
    3014          40 :         rPropSet.SetBoolProperty( EXC_CHPROP_TEXTBREAK, maLabelData.mnLabelFreq == 1 );
    3015             :         // do not stagger labels in two lines
    3016          40 :         rPropSet.SetProperty( EXC_CHPROP_ARRANGEORDER, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE );
    3017             :     }
    3018             : 
    3019             :     // reverse order
    3020          40 :     bool bReverse = ::get_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_REVERSE ) != bMirrorOrient;
    3021          40 :     rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
    3022             : 
    3023             :     //! TODO #i58731# show n-th category
    3024          40 : }
    3025             : 
    3026          40 : void XclImpChLabelRange::ConvertAxisPosition( ScfPropertySet& rPropSet, bool b3dChart ) const
    3027             : {
    3028             :     /*  Crossing mode (max-cross flag overrides other crossing settings). Excel
    3029             :         does not move the Y axis in 3D charts, regardless of actual settings.
    3030             :         But: the Y axis has to be moved to "end", if the X axis is mirrored,
    3031             :         to keep it at the left end of the chart. */
    3032          40 :     bool bMaxCross = ::get_flag( maLabelData.mnFlags, b3dChart ? EXC_CHLABELRANGE_REVERSE : EXC_CHLABELRANGE_MAXCROSS );
    3033          40 :     cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
    3034          40 :     rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
    3035             : 
    3036             :     // crossing position (depending on axis type text/date)
    3037          40 :     if( ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS ) )
    3038             :     {
    3039           0 :         bool bAutoCross = ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS );
    3040             :         /*  Crossing position value depends on base time unit, it specifies the
    3041             :             number of days, months, or years from null date. Note that Excel
    3042             :             2007/2010 write broken BIFF8 files, they always stores the number
    3043             :             of days cregardless of the base time unit (and they are reading it
    3044             :             the same way, thus wrongly displaying files written by Excel
    3045             :             97-2003). This filter sticks to the correct behaviour of Excel
    3046             :             97-2003. */
    3047           0 :         double fCrossingPos = bAutoCross ? 1.0 : lclGetSerialDay( GetRoot(), maDateData.mnCross, maDateData.mnBaseUnit );
    3048           0 :         rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
    3049             :     }
    3050             :     else
    3051             :     {
    3052          40 :         double fCrossingPos = b3dChart ? 1.0 : maLabelData.mnCross;
    3053          40 :         rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
    3054             :     }
    3055          40 : }
    3056             : 
    3057             : // ----------------------------------------------------------------------------
    3058             : 
    3059          80 : XclImpChValueRange::XclImpChValueRange( const XclImpChRoot& rRoot ) :
    3060          80 :     XclImpChRoot( rRoot )
    3061             : {
    3062          80 : }
    3063             : 
    3064           2 : void XclImpChValueRange::ReadChValueRange( XclImpStream& rStrm )
    3065             : {
    3066           2 :     rStrm   >> maData.mfMin
    3067           4 :             >> maData.mfMax
    3068           4 :             >> maData.mfMajorStep
    3069           4 :             >> maData.mfMinorStep
    3070           4 :             >> maData.mfCross
    3071           4 :             >> maData.mnFlags;
    3072           2 : }
    3073             : 
    3074          40 : void XclImpChValueRange::Convert( ScaleData& rScaleData, bool bMirrorOrient ) const
    3075             : {
    3076             :     // scaling algorithm
    3077          40 :     bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE );
    3078          40 :     if( bLogScale )
    3079           0 :         rScaleData.Scaling = css::chart2::LogarithmicScaling::create( comphelper::getProcessComponentContext() );
    3080             :     else
    3081          40 :         rScaleData.Scaling = css::chart2::LinearScaling::create( comphelper::getProcessComponentContext() );
    3082             : 
    3083             :     // min/max
    3084          40 :     lclSetExpValueOrClearAny( rScaleData.Minimum, maData.mfMin, bLogScale, ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMIN ) );
    3085          40 :     lclSetExpValueOrClearAny( rScaleData.Maximum, maData.mfMax, bLogScale, ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAX ) );
    3086             : 
    3087             :     // increment
    3088          40 :     bool bAutoMajor = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAJOR );
    3089          40 :     bool bAutoMinor = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR );
    3090             :     // major increment
    3091          40 :     IncrementData& rIncrementData = rScaleData.IncrementData;
    3092          40 :     lclSetValueOrClearAny( rIncrementData.Distance, maData.mfMajorStep, bAutoMajor );
    3093             :     // minor increment
    3094          40 :     Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
    3095          40 :     rSubIncrementSeq.realloc( 1 );
    3096          40 :     Any& rIntervalCount = rSubIncrementSeq[ 0 ].IntervalCount;
    3097          40 :     rIntervalCount.clear();
    3098          40 :     if( bLogScale )
    3099             :     {
    3100           0 :         if( !bAutoMinor )
    3101           0 :             rIntervalCount <<= sal_Int32( 9 );
    3102             :     }
    3103             :     else
    3104             :     {
    3105          40 :         if( !bAutoMajor && !bAutoMinor && (0.0 < maData.mfMinorStep) && (maData.mfMinorStep <= maData.mfMajorStep) )
    3106             :         {
    3107           0 :             double fCount = maData.mfMajorStep / maData.mfMinorStep + 0.5;
    3108           0 :             if( (1.0 <= fCount) && (fCount < 1001.0) )
    3109           0 :                 rIntervalCount <<= static_cast< sal_Int32 >( fCount );
    3110             :         }
    3111             :     }
    3112             : 
    3113             :     // reverse order
    3114          40 :     bool bReverse = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE ) != bMirrorOrient;
    3115          40 :     rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
    3116          40 : }
    3117             : 
    3118          40 : void XclImpChValueRange::ConvertAxisPosition( ScfPropertySet& rPropSet ) const
    3119             : {
    3120          40 :     bool bMaxCross = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_MAXCROSS );
    3121          40 :     bool bAutoCross = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
    3122          40 :     bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE );
    3123             : 
    3124             :     // crossing mode (max-cross flag overrides other crossing settings)
    3125          40 :     cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
    3126          40 :     rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
    3127             : 
    3128             :     // crossing position
    3129          40 :     double fCrossingPos = bAutoCross ? 0.0 : maData.mfCross;
    3130          40 :     if( bLogScale ) fCrossingPos = pow( 10.0, fCrossingPos );
    3131          40 :     rPropSet.SetProperty( EXC_CHPROP_CROSSOVERVALUE, fCrossingPos );
    3132          40 : }
    3133             : 
    3134             : // ----------------------------------------------------------------------------
    3135             : 
    3136             : namespace {
    3137             : 
    3138         160 : sal_Int32 lclGetApiTickmarks( sal_uInt8 nXclTickPos )
    3139             : {
    3140             :     using namespace ::com::sun::star::chart2::TickmarkStyle;
    3141         160 :     sal_Int32 nApiTickmarks = NONE;
    3142         160 :     ::set_flag( nApiTickmarks, INNER, ::get_flag( nXclTickPos, EXC_CHTICK_INSIDE ) );
    3143         160 :     ::set_flag( nApiTickmarks, OUTER, ::get_flag( nXclTickPos, EXC_CHTICK_OUTSIDE ) );
    3144         160 :     return nApiTickmarks;
    3145             : }
    3146             : 
    3147          80 : cssc::ChartAxisLabelPosition lclGetApiLabelPosition( sal_Int8 nXclLabelPos )
    3148             : {
    3149             :     using namespace ::com::sun::star::chart;
    3150          80 :     switch( nXclLabelPos )
    3151             :     {
    3152           0 :         case EXC_CHTICK_LOW:    return ChartAxisLabelPosition_OUTSIDE_START;
    3153           0 :         case EXC_CHTICK_HIGH:   return ChartAxisLabelPosition_OUTSIDE_END;
    3154          80 :         case EXC_CHTICK_NEXT:   return ChartAxisLabelPosition_NEAR_AXIS;
    3155             :     }
    3156           0 :     return ChartAxisLabelPosition_NEAR_AXIS;
    3157             : }
    3158             : 
    3159             : } // namespace
    3160             : 
    3161          80 : XclImpChTick::XclImpChTick( const XclImpChRoot& rRoot ) :
    3162          80 :     XclImpChRoot( rRoot )
    3163             : {
    3164          80 : }
    3165             : 
    3166           4 : void XclImpChTick::ReadChTick( XclImpStream& rStrm )
    3167             : {
    3168           4 :     rStrm   >> maData.mnMajor
    3169           8 :             >> maData.mnMinor
    3170           8 :             >> maData.mnLabelPos
    3171           8 :             >> maData.mnBackMode;
    3172           4 :     rStrm.Ignore( 16 );
    3173           4 :     rStrm   >> maData.maTextColor
    3174           8 :             >> maData.mnFlags;
    3175             : 
    3176           4 :     if( GetBiff() == EXC_BIFF8 )
    3177             :     {
    3178             :         // BIFF8: index into palette used instead of RGB data
    3179           4 :         maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() );
    3180             :         // rotation
    3181           4 :         rStrm >> maData.mnRotation;
    3182             :     }
    3183             :     else
    3184             :     {
    3185             :         // BIFF2-BIFF7: get rotation from text orientation
    3186           0 :         sal_uInt8 nOrient = ::extract_value< sal_uInt8 >( maData.mnFlags, 2, 3 );
    3187           0 :         maData.mnRotation = XclTools::GetXclRotFromOrient( nOrient );
    3188             :     }
    3189           4 : }
    3190             : 
    3191           2 : Color XclImpChTick::GetFontColor() const
    3192             : {
    3193           2 :     return ::get_flag( maData.mnFlags, EXC_CHTICK_AUTOCOLOR ) ? GetFontAutoColor() : maData.maTextColor;
    3194             : }
    3195             : 
    3196          80 : sal_uInt16 XclImpChTick::GetRotation() const
    3197             : {
    3198             :     /* n#720443: Ignore auto-rotation if there is a suggested rotation.
    3199             :      * Better fix would be to improve our axis auto rotation algorithm.
    3200             :      */
    3201          80 :     if( maData.mnRotation != EXC_ROT_NONE )
    3202           2 :         return maData.mnRotation;
    3203          78 :     return ::get_flag( maData.mnFlags, EXC_CHTICK_AUTOROT ) ? EXC_CHART_AUTOROTATION : maData.mnRotation;
    3204             : }
    3205             : 
    3206          80 : void XclImpChTick::Convert( ScfPropertySet& rPropSet ) const
    3207             : {
    3208          80 :     rPropSet.SetProperty( EXC_CHPROP_MAJORTICKS, lclGetApiTickmarks( maData.mnMajor ) );
    3209          80 :     rPropSet.SetProperty( EXC_CHPROP_MINORTICKS, lclGetApiTickmarks( maData.mnMinor ) );
    3210          80 :     rPropSet.SetProperty( EXC_CHPROP_LABELPOSITION, lclGetApiLabelPosition( maData.mnLabelPos ) );
    3211          80 :     rPropSet.SetProperty( EXC_CHPROP_MARKPOSITION, cssc::ChartAxisMarkPosition_AT_AXIS );
    3212          80 : }
    3213             : 
    3214             : // ----------------------------------------------------------------------------
    3215             : 
    3216          80 : XclImpChAxis::XclImpChAxis( const XclImpChRoot& rRoot, sal_uInt16 nAxisType ) :
    3217             :     XclImpChRoot( rRoot ),
    3218          80 :     mnNumFmtIdx( EXC_FORMAT_NOTFOUND )
    3219             : {
    3220          80 :     maData.mnType = nAxisType;
    3221          80 : }
    3222             : 
    3223           4 : void XclImpChAxis::ReadHeaderRecord( XclImpStream& rStrm )
    3224             : {
    3225           4 :     rStrm >> maData.mnType;
    3226           4 : }
    3227             : 
    3228          22 : void XclImpChAxis::ReadSubRecord( XclImpStream& rStrm )
    3229             : {
    3230          22 :     switch( rStrm.GetRecId() )
    3231             :     {
    3232             :         case EXC_ID_CHLABELRANGE:
    3233           2 :             mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
    3234           2 :             mxLabelRange->ReadChLabelRange( rStrm );
    3235           2 :         break;
    3236             :         case EXC_ID_CHDATERANGE:
    3237           2 :             if( !mxLabelRange )
    3238           0 :                 mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
    3239           2 :             mxLabelRange->ReadChDateRange( rStrm );
    3240           2 :         break;
    3241             :         case EXC_ID_CHVALUERANGE:
    3242           2 :             mxValueRange.reset( new XclImpChValueRange( GetChRoot() ) );
    3243           2 :             mxValueRange->ReadChValueRange( rStrm );
    3244           2 :         break;
    3245             :         case EXC_ID_CHFORMAT:
    3246           0 :             rStrm >> mnNumFmtIdx;
    3247           0 :         break;
    3248             :         case EXC_ID_CHTICK:
    3249           4 :             mxTick.reset( new XclImpChTick( GetChRoot() ) );
    3250           4 :             mxTick->ReadChTick( rStrm );
    3251           4 :         break;
    3252             :         case EXC_ID_CHFONT:
    3253           2 :             mxFont.reset( new XclImpChFont );
    3254           2 :             mxFont->ReadChFont( rStrm );
    3255           2 :         break;
    3256             :         case EXC_ID_CHAXISLINE:
    3257           2 :             ReadChAxisLine( rStrm );
    3258           2 :         break;
    3259             :     }
    3260          22 : }
    3261             : 
    3262          80 : void XclImpChAxis::Finalize()
    3263             : {
    3264             :     // add default scaling, needed e.g. to adjust rotation direction of pie and radar charts
    3265          80 :     if( !mxLabelRange )
    3266          78 :         mxLabelRange.reset( new XclImpChLabelRange( GetChRoot() ) );
    3267          80 :     if( !mxValueRange )
    3268          78 :         mxValueRange.reset( new XclImpChValueRange( GetChRoot() ) );
    3269             :     // remove invisible grid lines completely
    3270          80 :     if( mxMajorGrid && !mxMajorGrid->HasLine() )
    3271           0 :         mxMajorGrid.reset();
    3272          80 :     if( mxMinorGrid && !mxMinorGrid->HasLine() )
    3273           0 :         mxMinorGrid.reset();
    3274             :     // default tick settings different in OOChart and Excel
    3275          80 :     if( !mxTick )
    3276          76 :         mxTick.reset( new XclImpChTick( GetChRoot() ) );
    3277             :     // #i4140# different default axis line color
    3278          80 :     if( !mxAxisLine )
    3279             :     {
    3280          80 :         XclChLineFormat aLineFmt;
    3281             :         // set "show axis" flag, default if line format record is missing
    3282          80 :         ::set_flag( aLineFmt.mnFlags, EXC_CHLINEFORMAT_SHOWAXIS );
    3283          80 :         mxAxisLine.reset( new XclImpChLineFormat( aLineFmt ) );
    3284             :     }
    3285             :     // add wall/floor frame for 3d charts
    3286          80 :     if( !mxWallFrame )
    3287          80 :         CreateWallFrame();
    3288          80 : }
    3289             : 
    3290           2 : sal_uInt16 XclImpChAxis::GetFontIndex() const
    3291             : {
    3292           2 :     return mxFont ? mxFont->GetFontIndex() : EXC_FONT_NOTFOUND;
    3293             : }
    3294             : 
    3295           2 : Color XclImpChAxis::GetFontColor() const
    3296             : {
    3297           2 :     return mxTick ? mxTick->GetFontColor() : GetFontAutoColor();
    3298             : }
    3299             : 
    3300          80 : sal_uInt16 XclImpChAxis::GetRotation() const
    3301             : {
    3302          80 :     return mxTick ? mxTick->GetRotation() : EXC_CHART_AUTOROTATION;
    3303             : }
    3304             : 
    3305          80 : Reference< XAxis > XclImpChAxis::CreateAxis( const XclImpChTypeGroup& rTypeGroup, const XclImpChAxis* pCrossingAxis ) const
    3306             : {
    3307             :     // create the axis object (always)
    3308          80 :     Reference< XAxis > xAxis( ScfApiHelper::CreateInstance( SERVICE_CHART2_AXIS ), UNO_QUERY );
    3309          80 :     if( xAxis.is() )
    3310             :     {
    3311          80 :         ScfPropertySet aAxisProp( xAxis );
    3312             :         // #i58688# axis enabled
    3313          80 :         aAxisProp.SetBoolProperty( EXC_CHPROP_SHOW, IsActivated() );
    3314             : 
    3315             :         // axis line properties
    3316          80 :         if( mxAxisLine )
    3317          80 :             mxAxisLine->Convert( GetChRoot(), aAxisProp, EXC_CHOBJTYPE_AXISLINE );
    3318             :         // axis ticks properties
    3319          80 :         if( mxTick )
    3320          80 :             mxTick->Convert( aAxisProp );
    3321             : 
    3322             :         // axis caption text --------------------------------------------------
    3323             : 
    3324             :         // radar charts disable their category labels via chart type, not via axis
    3325         240 :         bool bHasLabels = HasLabels() &&
    3326         200 :             ((GetAxisType() != EXC_CHAXIS_X) || rTypeGroup.HasCategoryLabels());
    3327          80 :         aAxisProp.SetBoolProperty( EXC_CHPROP_DISPLAYLABELS, bHasLabels );
    3328          80 :         if( bHasLabels )
    3329             :         {
    3330             :             // font settings from CHFONT record or from default text
    3331          80 :             if( mxFont )
    3332           2 :                 ConvertFontBase( GetChRoot(), aAxisProp );
    3333          78 :             else if( const XclImpChText* pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISLABEL ) )
    3334          78 :                 pDefText->ConvertFont( aAxisProp );
    3335             :             // label text rotation
    3336          80 :             ConvertRotationBase( GetChRoot(), aAxisProp, true );
    3337             :             // number format
    3338          80 :             sal_uInt32 nScNumFmt = GetNumFmtBuffer().GetScFormat( mnNumFmtIdx );
    3339          80 :             if( nScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND )
    3340           0 :                 aAxisProp.SetProperty( EXC_CHPROP_NUMBERFORMAT, static_cast< sal_Int32 >( nScNumFmt ) );
    3341             :         }
    3342             : 
    3343             :         // axis scaling and increment -----------------------------------------
    3344             : 
    3345          80 :         const XclChExtTypeInfo& rTypeInfo = rTypeGroup.GetTypeInfo();
    3346         160 :         ScaleData aScaleData = xAxis->getScaleData();
    3347             :         // set axis type
    3348          80 :         switch( GetAxisType() )
    3349             :         {
    3350             :             case EXC_CHAXIS_X:
    3351          40 :                 if( rTypeInfo.mbCategoryAxis )
    3352             :                 {
    3353          40 :                     aScaleData.AxisType = cssc2::AxisType::CATEGORY;
    3354          40 :                     aScaleData.Categories = rTypeGroup.CreateCategSequence();
    3355             :                 }
    3356             :                 else
    3357           0 :                     aScaleData.AxisType = cssc2::AxisType::REALNUMBER;
    3358          40 :             break;
    3359             :             case EXC_CHAXIS_Y:
    3360          40 :                 aScaleData.AxisType = rTypeGroup.IsPercent() ?
    3361          40 :                     cssc2::AxisType::PERCENT : cssc2::AxisType::REALNUMBER;
    3362          40 :             break;
    3363             :             case EXC_CHAXIS_Z:
    3364           0 :                 aScaleData.AxisType = cssc2::AxisType::SERIES;
    3365           0 :             break;
    3366             :         }
    3367             :         // axis scaling settings, dependent on axis type
    3368          80 :         switch( aScaleData.AxisType )
    3369             :         {
    3370             :             case cssc2::AxisType::CATEGORY:
    3371             :             case cssc2::AxisType::SERIES:
    3372             :                 OSL_ENSURE( mxLabelRange, "Missing Label Range" );
    3373             :                 // #i71684# radar charts have reversed rotation direction
    3374          40 :                 if (mxLabelRange)
    3375          40 :                     mxLabelRange->Convert( aAxisProp, aScaleData, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR );
    3376          40 :             break;
    3377             :             case cssc2::AxisType::REALNUMBER:
    3378             :             case cssc2::AxisType::PERCENT:
    3379             :                 // #i85167# pie/donut charts have reversed rotation direction (at Y axis!)
    3380          40 :                 mxValueRange->Convert( aScaleData, rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE );
    3381          40 :             break;
    3382             :             default:
    3383             :                 OSL_FAIL( "XclImpChAxis::CreateAxis - unknown axis type" );
    3384             :         }
    3385             : 
    3386             :         /*  Do not set a value to the Origin member anymore (will be done via
    3387             :             new axis properties 'CrossoverPosition' and 'CrossoverValue'). */
    3388          80 :         aScaleData.Origin.clear();
    3389             : 
    3390             :         // write back
    3391          80 :         xAxis->setScaleData( aScaleData );
    3392             : 
    3393             :         // grid ---------------------------------------------------------------
    3394             : 
    3395             :         // main grid
    3396          80 :         ScfPropertySet aGridProp( xAxis->getGridProperties() );
    3397          80 :         aGridProp.SetBoolProperty( EXC_CHPROP_SHOW, HasMajorGrid() );
    3398          80 :         if( mxMajorGrid )
    3399           2 :             mxMajorGrid->Convert( GetChRoot(), aGridProp, EXC_CHOBJTYPE_GRIDLINE );
    3400             :         // sub grid
    3401         160 :         Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
    3402          80 :         if( aSubGridPropSeq.hasElements() )
    3403             :         {
    3404          80 :             ScfPropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
    3405          80 :             aSubGridProp.SetBoolProperty( EXC_CHPROP_SHOW, HasMinorGrid() );
    3406          80 :             if( mxMinorGrid )
    3407           0 :                 mxMinorGrid->Convert( GetChRoot(), aSubGridProp, EXC_CHOBJTYPE_GRIDLINE );
    3408             :         }
    3409             : 
    3410             :         // position of crossing axis ------------------------------------------
    3411             : 
    3412          80 :         if( pCrossingAxis )
    3413         240 :             pCrossingAxis->ConvertAxisPosition( aAxisProp, rTypeGroup );
    3414             :     }
    3415          80 :     return xAxis;
    3416             : }
    3417             : 
    3418           0 : void XclImpChAxis::ConvertWall( ScfPropertySet& rPropSet ) const
    3419             : {
    3420             :     // #i71810# walls and floor in 3D charts use the CHPICFORMAT record for bitmap mode
    3421           0 :     if( mxWallFrame )
    3422           0 :         mxWallFrame->Convert( rPropSet, true );
    3423           0 : }
    3424             : 
    3425          80 : void XclImpChAxis::ConvertAxisPosition( ScfPropertySet& rPropSet, const XclImpChTypeGroup& rTypeGroup ) const
    3426             : {
    3427          80 :     if( ((GetAxisType() == EXC_CHAXIS_X) && rTypeGroup.GetTypeInfo().mbCategoryAxis) || (GetAxisType() == EXC_CHAXIS_Z) )
    3428             :     {
    3429             :         OSL_ENSURE( mxLabelRange, "Missing Label Range" );
    3430          40 :         if (mxLabelRange)
    3431          40 :             mxLabelRange->ConvertAxisPosition( rPropSet, rTypeGroup.Is3dChart() );
    3432             :     }
    3433             :     else
    3434          40 :         mxValueRange->ConvertAxisPosition( rPropSet );
    3435          80 : }
    3436             : 
    3437           2 : void XclImpChAxis::ReadChAxisLine( XclImpStream& rStrm )
    3438             : {
    3439           2 :     XclImpChLineFormatRef* pxLineFmt = 0;
    3440           2 :     bool bWallFrame = false;
    3441           2 :     switch( rStrm.ReaduInt16() )
    3442             :     {
    3443           0 :         case EXC_CHAXISLINE_AXISLINE:   pxLineFmt = &mxAxisLine;    break;
    3444           2 :         case EXC_CHAXISLINE_MAJORGRID:  pxLineFmt = &mxMajorGrid;   break;
    3445           0 :         case EXC_CHAXISLINE_MINORGRID:  pxLineFmt = &mxMinorGrid;   break;
    3446           0 :         case EXC_CHAXISLINE_WALLS:      bWallFrame = true;          break;
    3447             :     }
    3448           2 :     if( bWallFrame )
    3449           0 :         CreateWallFrame();
    3450             : 
    3451           2 :     bool bLoop = pxLineFmt || bWallFrame;
    3452           8 :     while( bLoop )
    3453             :     {
    3454           4 :         sal_uInt16 nRecId = rStrm.GetNextRecId();
    3455           2 :         bLoop = ((nRecId == EXC_ID_CHLINEFORMAT) ||
    3456           2 :                  (nRecId == EXC_ID_CHAREAFORMAT) ||
    3457             :                  (nRecId == EXC_ID_CHESCHERFORMAT))
    3458           6 :                  && rStrm.StartNextRecord();
    3459           4 :         if( bLoop )
    3460             :         {
    3461           2 :             if( pxLineFmt && (nRecId == EXC_ID_CHLINEFORMAT) )
    3462             :             {
    3463           2 :                 pxLineFmt->reset( new XclImpChLineFormat );
    3464           2 :                 (*pxLineFmt)->ReadChLineFormat( rStrm );
    3465             :             }
    3466           0 :             else if( bWallFrame && mxWallFrame )
    3467             :             {
    3468           0 :                 mxWallFrame->ReadSubRecord( rStrm );
    3469             :             }
    3470             :         }
    3471             :     }
    3472           2 : }
    3473             : 
    3474          80 : void XclImpChAxis::CreateWallFrame()
    3475             : {
    3476          80 :     switch( GetAxisType() )
    3477             :     {
    3478             :         case EXC_CHAXIS_X:
    3479          40 :             mxWallFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_WALL3D ) );
    3480          40 :         break;
    3481             :         case EXC_CHAXIS_Y:
    3482          40 :             mxWallFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_FLOOR3D ) );
    3483          40 :         break;
    3484             :         default:
    3485           0 :             mxWallFrame.reset();
    3486             :     }
    3487          80 : }
    3488             : 
    3489             : // ----------------------------------------------------------------------------
    3490             : 
    3491         120 : XclImpChAxesSet::XclImpChAxesSet( const XclImpChRoot& rRoot, sal_uInt16 nAxesSetId ) :
    3492         120 :     XclImpChRoot( rRoot )
    3493             : {
    3494         120 :     maData.mnAxesSetId = nAxesSetId;
    3495         120 : }
    3496             : 
    3497          40 : void XclImpChAxesSet::ReadHeaderRecord( XclImpStream& rStrm )
    3498             : {
    3499          40 :     rStrm >> maData.mnAxesSetId >> maData.maRect;
    3500          40 : }
    3501             : 
    3502         185 : void XclImpChAxesSet::ReadSubRecord( XclImpStream& rStrm )
    3503             : {
    3504         185 :     switch( rStrm.GetRecId() )
    3505             :     {
    3506             :         case EXC_ID_CHFRAMEPOS:
    3507          40 :             mxFramePos.reset( new XclImpChFramePos );
    3508          40 :             mxFramePos->ReadChFramePos( rStrm );
    3509          40 :         break;
    3510             :         case EXC_ID_CHAXIS:
    3511           4 :             ReadChAxis( rStrm );
    3512           4 :         break;
    3513             :         case EXC_ID_CHTEXT:
    3514           0 :             ReadChText( rStrm );
    3515           0 :         break;
    3516             :         case EXC_ID_CHPLOTFRAME:
    3517           2 :             ReadChPlotFrame( rStrm );
    3518           2 :         break;
    3519             :         case EXC_ID_CHTYPEGROUP:
    3520          40 :             ReadChTypeGroup( rStrm );
    3521          40 :         break;
    3522             :     }
    3523         185 : }
    3524             : 
    3525          80 : void XclImpChAxesSet::Finalize()
    3526             : {
    3527          80 :     if( IsValidAxesSet() )
    3528             :     {
    3529             :         // finalize chart type groups, erase empty groups without series
    3530          40 :         XclImpChTypeGroupMap aValidGroups;
    3531          80 :         for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); aIt != aEnd; ++aIt )
    3532             :         {
    3533          40 :             XclImpChTypeGroupRef xTypeGroup = aIt->second;
    3534          40 :             xTypeGroup->Finalize();
    3535          40 :             if( xTypeGroup->IsValidGroup() )
    3536             :                 aValidGroups.insert(
    3537          40 :                     XclImpChTypeGroupMap::value_type(aIt->first, xTypeGroup));
    3538          40 :         }
    3539          40 :         maTypeGroups.swap( aValidGroups );
    3540             :     }
    3541             : 
    3542             :     // invalid chart type groups are deleted now, check again with IsValidAxesSet()
    3543          80 :     if( IsValidAxesSet() )
    3544             :     {
    3545             :         // always create missing axis objects
    3546          40 :         if( !mxXAxis )
    3547          38 :             mxXAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_X ) );
    3548          40 :         if( !mxYAxis )
    3549          38 :             mxYAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Y ) );
    3550          40 :         if( !mxZAxis && GetFirstTypeGroup()->Is3dDeepChart() )
    3551           0 :             mxZAxis.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Z ) );
    3552             : 
    3553             :         // finalize axes
    3554          40 :         if( mxXAxis ) mxXAxis->Finalize();
    3555          40 :         if( mxYAxis ) mxYAxis->Finalize();
    3556          40 :         if( mxZAxis ) mxZAxis->Finalize();
    3557             : 
    3558             :         // finalize axis titles
    3559          40 :         const XclImpChText* pDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISTITLE );
    3560          40 :         String aAutoTitle("Axis Title");
    3561          40 :         lclFinalizeTitle( mxXAxisTitle, pDefText, aAutoTitle );
    3562          40 :         lclFinalizeTitle( mxYAxisTitle, pDefText, aAutoTitle );
    3563          40 :         lclFinalizeTitle( mxZAxisTitle, pDefText, aAutoTitle );
    3564             : 
    3565             :         // #i47745# missing plot frame -> invisible border and area
    3566          40 :         if( !mxPlotFrame )
    3567          38 :             mxPlotFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME ) );
    3568             :     }
    3569          80 : }
    3570             : 
    3571         160 : XclImpChTypeGroupRef XclImpChAxesSet::GetTypeGroup( sal_uInt16 nGroupIdx ) const
    3572             : {
    3573         160 :     XclImpChTypeGroupMap::const_iterator itr = maTypeGroups.find(nGroupIdx);
    3574         160 :     return itr == maTypeGroups.end() ? XclImpChTypeGroupRef() : itr->second;
    3575             : }
    3576             : 
    3577         239 : XclImpChTypeGroupRef XclImpChAxesSet::GetFirstTypeGroup() const
    3578             : {
    3579         239 :     XclImpChTypeGroupRef xTypeGroup;
    3580         239 :     if( !maTypeGroups.empty() )
    3581         239 :         xTypeGroup = maTypeGroups.begin()->second;
    3582         239 :     return xTypeGroup;
    3583             : }
    3584             : 
    3585          59 : XclImpChLegendRef XclImpChAxesSet::GetLegend() const
    3586             : {
    3587          59 :     XclImpChLegendRef xLegend;
    3588          99 :     for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); !xLegend && (aIt != aEnd); ++aIt )
    3589          40 :         xLegend = aIt->second->GetLegend();
    3590          59 :     return xLegend;
    3591             : }
    3592             : 
    3593          38 : const String& XclImpChAxesSet::GetSingleSeriesTitle() const
    3594             : {
    3595          38 :     return (maTypeGroups.size() == 1) ? maTypeGroups.begin()->second->GetSingleSeriesTitle() : String::EmptyString();
    3596             : }
    3597             : 
    3598          80 : void XclImpChAxesSet::Convert( Reference< XDiagram > xDiagram ) const
    3599             : {
    3600          80 :     if( IsValidAxesSet() && xDiagram.is() )
    3601             :     {
    3602             :         // diagram background formatting
    3603          40 :         if( GetAxesSetId() == EXC_CHAXESSET_PRIMARY )
    3604          40 :             ConvertBackground( xDiagram );
    3605             : 
    3606             :         // create the coordinate system, this inserts all chart types and series
    3607          40 :         Reference< XCoordinateSystem > xCoordSystem = CreateCoordSystem( xDiagram );
    3608          40 :         if( xCoordSystem.is() )
    3609             :         {
    3610             :             // insert coordinate system, if not already done
    3611             :             try
    3612             :             {
    3613          40 :                 Reference< XCoordinateSystemContainer > xCoordSystemCont( xDiagram, UNO_QUERY_THROW );
    3614          80 :                 Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems();
    3615          40 :                 if( aCoordSystems.getLength() == 0 )
    3616          80 :                     xCoordSystemCont->addCoordinateSystem( xCoordSystem );
    3617             :             }
    3618           0 :             catch( Exception& )
    3619             :             {
    3620             :                 OSL_FAIL( "XclImpChAxesSet::Convert - cannot insert coordinate system" );
    3621             :             }
    3622             : 
    3623             :             // create the axes with grids and axis titles and insert them into the diagram
    3624          40 :             ConvertAxis( mxXAxis, mxXAxisTitle, xCoordSystem, mxYAxis.get() );
    3625          40 :             ConvertAxis( mxYAxis, mxYAxisTitle, xCoordSystem, mxXAxis.get() );
    3626          40 :             ConvertAxis( mxZAxis, mxZAxisTitle, xCoordSystem, 0 );
    3627          40 :         }
    3628             :     }
    3629          80 : }
    3630             : 
    3631          80 : void XclImpChAxesSet::ConvertTitlePositions() const
    3632             : {
    3633          80 :     if( mxXAxisTitle )
    3634           0 :         mxXAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_X ) );
    3635          80 :     if( mxYAxisTitle )
    3636           0 :         mxYAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Y ) );
    3637          80 :     if( mxZAxisTitle )
    3638           0 :         mxZAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Z ) );
    3639          80 : }
    3640             : 
    3641           4 : void XclImpChAxesSet::ReadChAxis( XclImpStream& rStrm )
    3642             : {
    3643           4 :     XclImpChAxisRef xAxis( new XclImpChAxis( GetChRoot() ) );
    3644           4 :     xAxis->ReadRecordGroup( rStrm );
    3645             : 
    3646           4 :     switch( xAxis->GetAxisType() )
    3647             :     {
    3648           2 :         case EXC_CHAXIS_X:  mxXAxis = xAxis;    break;
    3649           2 :         case EXC_CHAXIS_Y:  mxYAxis = xAxis;    break;
    3650           0 :         case EXC_CHAXIS_Z:  mxZAxis = xAxis;    break;
    3651           4 :     }
    3652           4 : }
    3653             : 
    3654           0 : void XclImpChAxesSet::ReadChText( XclImpStream& rStrm )
    3655             : {
    3656           0 :     XclImpChTextRef xText( new XclImpChText( GetChRoot() ) );
    3657           0 :     xText->ReadRecordGroup( rStrm );
    3658             : 
    3659           0 :     switch( xText->GetLinkTarget() )
    3660             :     {
    3661           0 :         case EXC_CHOBJLINK_XAXIS:   mxXAxisTitle = xText;   break;
    3662           0 :         case EXC_CHOBJLINK_YAXIS:   mxYAxisTitle = xText;   break;
    3663           0 :         case EXC_CHOBJLINK_ZAXIS:   mxZAxisTitle = xText;   break;
    3664           0 :     }
    3665           0 : }
    3666             : 
    3667           2 : void XclImpChAxesSet::ReadChPlotFrame( XclImpStream& rStrm )
    3668             : {
    3669           2 :     if( (rStrm.GetNextRecId() == EXC_ID_CHFRAME) && rStrm.StartNextRecord() )
    3670             :     {
    3671           2 :         mxPlotFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME ) );
    3672           2 :         mxPlotFrame->ReadRecordGroup( rStrm );
    3673             :     }
    3674           2 : }
    3675             : 
    3676          40 : void XclImpChAxesSet::ReadChTypeGroup( XclImpStream& rStrm )
    3677             : {
    3678          40 :     XclImpChTypeGroupRef xTypeGroup( new XclImpChTypeGroup( GetChRoot() ) );
    3679          40 :     xTypeGroup->ReadRecordGroup( rStrm );
    3680          40 :     sal_uInt16 nGroupIdx = xTypeGroup->GetGroupIdx();
    3681          40 :     XclImpChTypeGroupMap::iterator itr = maTypeGroups.lower_bound(nGroupIdx);
    3682          40 :     if (itr != maTypeGroups.end() && !maTypeGroups.key_comp()(nGroupIdx, itr->first))
    3683             :         // Overwrite the existing element.
    3684           0 :         itr->second = xTypeGroup;
    3685             :     else
    3686             :         maTypeGroups.insert(
    3687          40 :             itr, XclImpChTypeGroupMap::value_type(nGroupIdx, xTypeGroup));
    3688          40 : }
    3689             : 
    3690          40 : Reference< XCoordinateSystem > XclImpChAxesSet::CreateCoordSystem( Reference< XDiagram > xDiagram ) const
    3691             : {
    3692          40 :     Reference< XCoordinateSystem > xCoordSystem;
    3693             : 
    3694             :     /*  Try to get existing ccordinate system. For now, all series from primary
    3695             :         and secondary axes sets are inserted into one coordinate system. Later,
    3696             :         this should be changed to use one coordinate system for each axes set. */
    3697          80 :     Reference< XCoordinateSystemContainer > xCoordSystemCont( xDiagram, UNO_QUERY );
    3698          40 :     if( xCoordSystemCont.is() )
    3699             :     {
    3700          40 :         Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems();
    3701             :         OSL_ENSURE( aCoordSystems.getLength() <= 1, "XclImpChAxesSet::CreateCoordSystem - too many existing coordinate systems" );
    3702          40 :         if( aCoordSystems.getLength() > 0 )
    3703           0 :             xCoordSystem = aCoordSystems[ 0 ];
    3704             :     }
    3705             : 
    3706             :     // create the coordinate system according to the first chart type
    3707          40 :     if( !xCoordSystem.is() )
    3708             :     {
    3709          40 :         XclImpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
    3710          40 :         if( xTypeGroup )
    3711             :         {
    3712          40 :             xCoordSystem = xTypeGroup->CreateCoordSystem();
    3713             :             // convert 3d chart settings
    3714          40 :             ScfPropertySet aDiaProp( xDiagram );
    3715          40 :             xTypeGroup->ConvertChart3d( aDiaProp );
    3716          40 :         }
    3717             :     }
    3718             : 
    3719             :     /*  Create XChartType objects for all chart type groups. Each group will
    3720             :         add its series to the data provider attached to the chart document. */
    3721          80 :     Reference< XChartTypeContainer > xChartTypeCont( xCoordSystem, UNO_QUERY );
    3722          40 :     if( xChartTypeCont.is() )
    3723             :     {
    3724          40 :         sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
    3725          80 :         for( XclImpChTypeGroupMap::const_iterator aIt = maTypeGroups.begin(), aEnd = maTypeGroups.end(); aIt != aEnd; ++aIt )
    3726             :         {
    3727             :             try
    3728             :             {
    3729          40 :                 Reference< XChartType > xChartType = aIt->second->CreateChartType( xDiagram, nApiAxesSetIdx );
    3730          40 :                 if( xChartType.is() )
    3731          40 :                     xChartTypeCont->addChartType( xChartType );
    3732             :             }
    3733           0 :             catch( Exception& )
    3734             :             {
    3735             :                 OSL_FAIL( "XclImpChAxesSet::CreateCoordSystem - cannot add chart type" );
    3736             :             }
    3737             :         }
    3738             :     }
    3739             : 
    3740          80 :     return xCoordSystem;
    3741             : }
    3742             : 
    3743         120 : void XclImpChAxesSet::ConvertAxis(
    3744             :         XclImpChAxisRef xChAxis, XclImpChTextRef xChAxisTitle,
    3745             :         Reference< XCoordinateSystem > xCoordSystem, const XclImpChAxis* pCrossingAxis ) const
    3746             : {
    3747         120 :     if( xChAxis )
    3748             :     {
    3749             :         // create and attach the axis object
    3750          80 :         Reference< XAxis > xAxis = CreateAxis( *xChAxis, pCrossingAxis );
    3751          80 :         if( xAxis.is() )
    3752             :         {
    3753             :             // create and attach the axis title
    3754          80 :             if( xChAxisTitle ) try
    3755             :             {
    3756           0 :                 Reference< XTitled > xTitled( xAxis, UNO_QUERY_THROW );
    3757           0 :                 Reference< XTitle > xTitle( xChAxisTitle->CreateTitle(), UNO_SET_THROW );
    3758           0 :                 xTitled->setTitleObject( xTitle );
    3759             :             }
    3760           0 :             catch( Exception& )
    3761             :             {
    3762             :                 OSL_FAIL( "XclImpChAxesSet::ConvertAxis - cannot set axis title" );
    3763             :             }
    3764             : 
    3765             :             // insert axis into coordinate system
    3766             :             try
    3767             :             {
    3768          80 :                 sal_Int32 nApiAxisDim = xChAxis->GetApiAxisDimension();
    3769          80 :                 sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
    3770          80 :                 xCoordSystem->setAxisByDimension( nApiAxisDim, xAxis, nApiAxesSetIdx );
    3771             :             }
    3772           0 :             catch( Exception& )
    3773             :             {
    3774             :                 OSL_FAIL( "XclImpChAxesSet::ConvertAxis - cannot set axis" );
    3775             :             }
    3776          80 :         }
    3777             :     }
    3778         120 : }
    3779             : 
    3780          80 : Reference< XAxis > XclImpChAxesSet::CreateAxis( const XclImpChAxis& rChAxis, const XclImpChAxis* pCrossingAxis ) const
    3781             : {
    3782          80 :     Reference< XAxis > xAxis;
    3783          80 :     if( const XclImpChTypeGroup* pTypeGroup = GetFirstTypeGroup().get() )
    3784          80 :         xAxis = rChAxis.CreateAxis( *pTypeGroup, pCrossingAxis );
    3785          80 :     return xAxis;
    3786             : }
    3787             : 
    3788          40 : void XclImpChAxesSet::ConvertBackground( Reference< XDiagram > xDiagram ) const
    3789             : {
    3790          40 :     XclImpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
    3791          40 :     if( xTypeGroup && xTypeGroup->Is3dWallChart() )
    3792             :     {
    3793             :         // wall/floor formatting (3D charts)
    3794           0 :         if( mxXAxis )
    3795             :         {
    3796           0 :             ScfPropertySet aWallProp( xDiagram->getWall() );
    3797           0 :             mxXAxis->ConvertWall( aWallProp );
    3798             :         }
    3799           0 :         if( mxYAxis )
    3800             :         {
    3801           0 :             ScfPropertySet aFloorProp( xDiagram->getFloor() );
    3802           0 :             mxYAxis->ConvertWall( aFloorProp );
    3803             :         }
    3804             :     }
    3805          40 :     else if( mxPlotFrame )
    3806             :     {
    3807             :         // diagram background formatting
    3808          40 :         ScfPropertySet aWallProp( xDiagram->getWall() );
    3809          40 :         mxPlotFrame->Convert( aWallProp );
    3810          40 :     }
    3811          40 : }
    3812             : 
    3813             : // The chart object ===========================================================
    3814             : 
    3815          40 : XclImpChChart::XclImpChChart( const XclImpRoot& rRoot ) :
    3816          40 :     XclImpChRoot( rRoot, *this )
    3817             : {
    3818          40 :     mxPrimAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) );
    3819          40 :     mxSecnAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) );
    3820          40 : }
    3821             : 
    3822          80 : XclImpChChart::~XclImpChChart()
    3823             : {
    3824          80 : }
    3825             : 
    3826          40 : void XclImpChChart::ReadHeaderRecord( XclImpStream& rStrm )
    3827             : {
    3828             :     // coordinates are stored as 16.16 fixed point
    3829          40 :     rStrm >> maRect;
    3830          40 : }
    3831             : 
    3832         678 : void XclImpChChart::ReadSubRecord( XclImpStream& rStrm )
    3833             : {
    3834         678 :     switch( rStrm.GetRecId() )
    3835             :     {
    3836             :         case EXC_ID_CHFRAME:
    3837          40 :             mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
    3838          40 :             mxFrame->ReadRecordGroup( rStrm );
    3839          40 :         break;
    3840             :         case EXC_ID_CHSERIES:
    3841          40 :             ReadChSeries( rStrm );
    3842          40 :         break;
    3843             :         case EXC_ID_CHPROPERTIES:
    3844          40 :             ReadChProperties( rStrm );
    3845          40 :         break;
    3846             :         case EXC_ID_CHDEFAULTTEXT:
    3847          80 :             ReadChDefaultText( rStrm );
    3848          80 :         break;
    3849             :         case EXC_ID_CHAXESSET:
    3850          40 :             ReadChAxesSet( rStrm );
    3851          40 :         break;
    3852             :         case EXC_ID_CHTEXT:
    3853          86 :             ReadChText( rStrm );
    3854          86 :         break;
    3855             :         case EXC_ID_CHEND:
    3856          40 :             Finalize();     // finalize the entire chart object
    3857          40 :         break;
    3858             :     }
    3859         678 : }
    3860             : 
    3861          80 : void XclImpChChart::ReadChDefaultText( XclImpStream& rStrm )
    3862             : {
    3863          80 :     sal_uInt16 nTextId = rStrm.ReaduInt16();
    3864          80 :     if( (rStrm.GetNextRecId() == EXC_ID_CHTEXT) && rStrm.StartNextRecord() )
    3865             :     {
    3866             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    3867          80 :         auto_ptr<XclImpChText> pText(new XclImpChText(GetChRoot()));
    3868             :         SAL_WNODEPRECATED_DECLARATIONS_POP
    3869          80 :         pText->ReadRecordGroup(rStrm);
    3870          80 :         maDefTexts.insert(nTextId, pText);
    3871             :     }
    3872          80 : }
    3873             : 
    3874          97 : void XclImpChChart::ReadChDataFormat( XclImpStream& rStrm )
    3875             : {
    3876          97 :     XclImpChDataFormatRef xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
    3877          97 :     xDataFmt->ReadRecordGroup( rStrm );
    3878          97 :     if( xDataFmt->GetPointPos().mnSeriesIdx <= EXC_CHSERIES_MAXSERIES )
    3879             :     {
    3880          97 :         const XclChDataPointPos& rPos = xDataFmt->GetPointPos();
    3881          97 :         XclImpChDataFormatMap::iterator itr = maDataFmts.lower_bound(rPos);
    3882          97 :         if (itr == maDataFmts.end() || maDataFmts.key_comp()(rPos, itr->first))
    3883             :             // No element exists for this data point.  Insert it.
    3884             :             maDataFmts.insert(
    3885          97 :                 itr, XclImpChDataFormatMap::value_type(rPos, xDataFmt));
    3886             : 
    3887             :         /*  Do not overwrite existing data format group, Excel always uses the
    3888             :             first data format group occuring in any CHSERIES group. */
    3889          97 :     }
    3890          97 : }
    3891             : 
    3892           0 : void XclImpChChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
    3893             : {
    3894           0 :     if( !mxFrame )
    3895           0 :         mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
    3896           0 :     mxFrame->UpdateObjFrame( rLineData, rFillData );
    3897           0 : }
    3898             : 
    3899         160 : XclImpChTypeGroupRef XclImpChChart::GetTypeGroup( sal_uInt16 nGroupIdx ) const
    3900             : {
    3901         160 :     XclImpChTypeGroupRef xTypeGroup = mxPrimAxesSet->GetTypeGroup( nGroupIdx );
    3902         160 :     if( !xTypeGroup ) xTypeGroup = mxSecnAxesSet->GetTypeGroup( nGroupIdx );
    3903         160 :     if( !xTypeGroup ) xTypeGroup = mxPrimAxesSet->GetFirstTypeGroup();
    3904         160 :     return xTypeGroup;
    3905             : }
    3906             : 
    3907         219 : const XclImpChText* XclImpChChart::GetDefaultText( XclChTextType eTextType ) const
    3908             : {
    3909         219 :     sal_uInt16 nDefTextId = EXC_CHDEFTEXT_GLOBAL;
    3910         219 :     bool bBiff8 = GetBiff() == EXC_BIFF8;
    3911         219 :     switch( eTextType )
    3912             :     {
    3913          40 :         case EXC_CHTEXTTYPE_TITLE:      nDefTextId = EXC_CHDEFTEXT_GLOBAL;                                  break;
    3914          21 :         case EXC_CHTEXTTYPE_LEGEND:     nDefTextId = EXC_CHDEFTEXT_GLOBAL;                                  break;
    3915          40 :         case EXC_CHTEXTTYPE_AXISTITLE:  nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
    3916          78 :         case EXC_CHTEXTTYPE_AXISLABEL:  nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
    3917          40 :         case EXC_CHTEXTTYPE_DATALABEL:  nDefTextId = bBiff8 ? EXC_CHDEFTEXT_AXESSET : EXC_CHDEFTEXT_GLOBAL; break;
    3918             :     }
    3919             : 
    3920         219 :     XclImpChTextMap::const_iterator itr = maDefTexts.find(nDefTextId);
    3921         219 :     return itr == maDefTexts.end() ? NULL : itr->second;
    3922             : }
    3923             : 
    3924          61 : bool XclImpChChart::IsManualPlotArea() const
    3925             : {
    3926             :     // there is no real automatic mode in BIFF5 charts
    3927          61 :     return (GetBiff() <= EXC_BIFF5) || ::get_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
    3928             : }
    3929             : 
    3930          40 : void XclImpChChart::Convert( const Reference<XChartDocument>& xChartDoc,
    3931             :         XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const
    3932             : {
    3933             :     // initialize conversion (locks the model to suppress any internal updates)
    3934          40 :     InitConversion( xChartDoc, rChartRect );
    3935             : 
    3936             :     // chart frame formatting
    3937          40 :     if( mxFrame )
    3938             :     {
    3939          40 :         ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
    3940          40 :         mxFrame->Convert( aFrameProp );
    3941             :     }
    3942             : 
    3943             :     // chart title
    3944          40 :     if( mxTitle ) try
    3945             :     {
    3946          21 :         Reference< XTitled > xTitled( xChartDoc, UNO_QUERY_THROW );
    3947          42 :         Reference< XTitle > xTitle( mxTitle->CreateTitle(), UNO_SET_THROW );
    3948          42 :         xTitled->setTitleObject( xTitle );
    3949             :     }
    3950           0 :     catch( Exception& )
    3951             :     {
    3952             :     }
    3953             : 
    3954             :     /*  Create the diagram object and attach it to the chart document. Currently,
    3955             :         one diagram is used to carry all coordinate systems and data series. */
    3956          40 :     Reference< XDiagram > xDiagram = CreateDiagram();
    3957          40 :     xChartDoc->setFirstDiagram( xDiagram );
    3958             : 
    3959             :     // coordinate systems and chart types, convert axis settings
    3960          40 :     mxPrimAxesSet->Convert( xDiagram );
    3961          40 :     mxSecnAxesSet->Convert( xDiagram );
    3962             : 
    3963             :     // legend
    3964          40 :     if( xDiagram.is() && mxLegend )
    3965          21 :         xDiagram->setLegend( mxLegend->CreateLegend() );
    3966             : 
    3967             :     /*  Following all conversions needing the old Chart1 API that involves full
    3968             :         initialization of the chart view. */
    3969          80 :     Reference< cssc::XChartDocument > xChart1Doc( xChartDoc, UNO_QUERY );
    3970          40 :     if( xChart1Doc.is() )
    3971             :     {
    3972          40 :         Reference< cssc::XDiagram > xDiagram1 = xChart1Doc->getDiagram();
    3973             : 
    3974             :         /*  Set the 'IncludeHiddenCells' property via the old API as only this
    3975             :             ensures that the data provider and all created sequences get this
    3976             :             flag correctly. */
    3977          80 :         ScfPropertySet aDiaProp( xDiagram1 );
    3978          40 :         bool bShowVisCells = ::get_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY );
    3979          40 :         aDiaProp.SetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS, !bShowVisCells );
    3980             : 
    3981             :         // plot area position and size (there is no real automatic mode in BIFF5 charts)
    3982          80 :         XclImpChFramePosRef xPlotAreaPos = mxPrimAxesSet->GetPlotAreaFramePos();
    3983          40 :         if( IsManualPlotArea() && xPlotAreaPos ) try
    3984             :         {
    3985          39 :             const XclChFramePos& rFramePos = xPlotAreaPos->GetFramePosData();
    3986          39 :             if( (rFramePos.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rFramePos.mnBRMode == EXC_CHFRAMEPOS_PARENT) )
    3987             :             {
    3988          39 :                 Reference< cssc::XDiagramPositioning > xPositioning( xDiagram1, UNO_QUERY_THROW );
    3989          39 :                 ::com::sun::star::awt::Rectangle aDiagramRect = CalcHmmFromChartRect( rFramePos.maRect );
    3990             :                 // for pie charts, always set inner plot area size to exclude the data labels as Excel does
    3991          39 :                 const XclImpChTypeGroup* pFirstTypeGroup = mxPrimAxesSet->GetFirstTypeGroup().get();
    3992          39 :                 if( pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE) )
    3993          37 :                     xPositioning->setDiagramPositionExcludingAxes( aDiagramRect );
    3994           2 :                 else if( pFirstTypeGroup && pFirstTypeGroup->Is3dChart() )
    3995           0 :                     xPositioning->setDiagramPositionIncludingAxesAndAxisTitles( aDiagramRect );
    3996             :                 else
    3997           2 :                     xPositioning->setDiagramPositionIncludingAxes( aDiagramRect );
    3998             :             }
    3999             :         }
    4000           0 :         catch( Exception& )
    4001             :         {
    4002             :         }
    4003             : 
    4004             :         // positions of all title objects
    4005          40 :         if( mxTitle )
    4006          21 :             mxTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_TITLE ) );
    4007          40 :         mxPrimAxesSet->ConvertTitlePositions();
    4008          80 :         mxSecnAxesSet->ConvertTitlePositions();
    4009             :     }
    4010             : 
    4011             :     // unlock the model
    4012          40 :     FinishConversion( rDffConv );
    4013             : 
    4014             :     // start listening to this chart
    4015          40 :     ScDocument& rDoc = GetRoot().GetDoc();
    4016          40 :     if( ScChartListenerCollection* pChartCollection = rDoc.GetChartListenerCollection() )
    4017             :     {
    4018             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    4019          40 :         ::std::auto_ptr< ::std::vector< ScTokenRef > > xRefTokens( new ::std::vector< ScTokenRef > );
    4020             :         SAL_WNODEPRECATED_DECLARATIONS_POP
    4021          80 :         for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt )
    4022          40 :             (*aIt)->FillAllSourceLinks( *xRefTokens );
    4023          40 :         if( !xRefTokens->empty() )
    4024             :         {
    4025             :             SAL_WNODEPRECATED_DECLARATIONS_PUSH
    4026          40 :             ::std::auto_ptr< ScChartListener > xListener( new ScChartListener( rObjName, &rDoc, xRefTokens.release() ) );
    4027             :             SAL_WNODEPRECATED_DECLARATIONS_POP
    4028          40 :             xListener->SetUsed( true );
    4029          40 :             xListener->StartListeningTo();
    4030          40 :             pChartCollection->insert( xListener.release() );
    4031          40 :         }
    4032          40 :     }
    4033          40 : }
    4034             : 
    4035          40 : void XclImpChChart::ReadChSeries( XclImpStream& rStrm )
    4036             : {
    4037          40 :     sal_uInt16 nNewSeriesIdx = static_cast< sal_uInt16 >( maSeries.size() );
    4038          40 :     XclImpChSeriesRef xSeries( new XclImpChSeries( GetChRoot(), nNewSeriesIdx ) );
    4039          40 :     xSeries->ReadRecordGroup( rStrm );
    4040          40 :     maSeries.push_back( xSeries );
    4041          40 : }
    4042             : 
    4043          40 : void XclImpChChart::ReadChProperties( XclImpStream& rStrm )
    4044             : {
    4045          40 :     rStrm >> maProps.mnFlags >> maProps.mnEmptyMode;
    4046          40 : }
    4047             : 
    4048          40 : void XclImpChChart::ReadChAxesSet( XclImpStream& rStrm )
    4049             : {
    4050          40 :     XclImpChAxesSetRef xAxesSet( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_NONE ) );
    4051          40 :     xAxesSet->ReadRecordGroup( rStrm );
    4052          40 :     switch( xAxesSet->GetAxesSetId() )
    4053             :     {
    4054          40 :         case EXC_CHAXESSET_PRIMARY:     mxPrimAxesSet = xAxesSet;   break;
    4055           0 :         case EXC_CHAXESSET_SECONDARY:   mxSecnAxesSet = xAxesSet;   break;
    4056          40 :     }
    4057          40 : }
    4058             : 
    4059          86 : void XclImpChChart::ReadChText( XclImpStream& rStrm )
    4060             : {
    4061          86 :     XclImpChTextRef xText( new XclImpChText( GetChRoot() ) );
    4062          86 :     xText->ReadRecordGroup( rStrm );
    4063          86 :     switch( xText->GetLinkTarget() )
    4064             :     {
    4065             :         case EXC_CHOBJLINK_TITLE:
    4066          21 :             mxTitle = xText;
    4067          21 :         break;
    4068             :         case EXC_CHOBJLINK_DATA:
    4069             :         {
    4070          65 :             sal_uInt16 nSeriesIdx = xText->GetPointPos().mnSeriesIdx;
    4071          65 :             if( nSeriesIdx < maSeries.size() )
    4072          65 :                 maSeries[ nSeriesIdx ]->SetDataLabel( xText );
    4073             :         }
    4074          65 :         break;
    4075          86 :     }
    4076          86 : }
    4077             : 
    4078          40 : void XclImpChChart::Finalize()
    4079             : {
    4080             :     // finalize series (must be done first)
    4081          40 :     FinalizeSeries();
    4082             :     // #i49218# legend may be attached to primary or secondary axes set
    4083          40 :     mxLegend = mxPrimAxesSet->GetLegend();
    4084          40 :     if( !mxLegend )
    4085          19 :         mxLegend = mxSecnAxesSet->GetLegend();
    4086          40 :     if( mxLegend )
    4087          21 :         mxLegend->Finalize();
    4088             :     // axes sets, updates chart type group default formats -> must be called before FinalizeDataFormats()
    4089          40 :     mxPrimAxesSet->Finalize();
    4090          40 :     mxSecnAxesSet->Finalize();
    4091             :     // formatting of all series
    4092          40 :     FinalizeDataFormats();
    4093             :     // #i47745# missing frame -> invisible border and area
    4094          40 :     if( !mxFrame )
    4095           0 :         mxFrame.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND ) );
    4096             :     // chart title
    4097          40 :     FinalizeTitle();
    4098          40 : }
    4099             : 
    4100          40 : void XclImpChChart::FinalizeSeries()
    4101             : {
    4102          80 :     for( XclImpChSeriesVec::iterator aSIt = maSeries.begin(), aSEnd = maSeries.end(); aSIt != aSEnd; ++aSIt )
    4103             :     {
    4104          40 :         XclImpChSeriesRef xSeries = *aSIt;
    4105          40 :         if( xSeries->HasParentSeries() )
    4106             :         {
    4107             :             /*  Process child series (trend lines and error bars). Data of
    4108             :                 child series will be set at the connected parent series. */
    4109           0 :             if( xSeries->GetParentIdx() < maSeries.size() )
    4110           0 :                 maSeries[ xSeries->GetParentIdx() ]->AddChildSeries( *xSeries );
    4111             :         }
    4112             :         else
    4113             :         {
    4114             :             // insert the series into the related chart type group
    4115          40 :             if( XclImpChTypeGroup* pTypeGroup = GetTypeGroup( xSeries->GetGroupIdx() ).get() )
    4116          40 :                 pTypeGroup->AddSeries( xSeries );
    4117             :         }
    4118          40 :     }
    4119          40 : }
    4120             : 
    4121          40 : void XclImpChChart::FinalizeDataFormats()
    4122             : {
    4123             :     /*  #i51639# (part 1): CHDATAFORMAT groups are part of CHSERIES groups.
    4124             :         Each CHDATAFORMAT group specifies the series and data point it is
    4125             :         assigned to. This makes it possible to have a data format that is
    4126             :         related to another series, e.g. a CHDATAFORMAT group for series 2 is
    4127             :         part of a CHSERIES group that describes series 1. Therefore the chart
    4128             :         itself has collected all CHDATAFORMAT groups to be able to store data
    4129             :         format groups for series that have not been imported at that time. This
    4130             :         loop finally assigns these groups to the related series. */
    4131         137 :     for( XclImpChDataFormatMap::const_iterator aMIt = maDataFmts.begin(), aMEnd = maDataFmts.end(); aMIt != aMEnd; ++aMIt )
    4132             :     {
    4133          97 :         sal_uInt16 nSeriesIdx = aMIt->first.mnSeriesIdx;
    4134          97 :         if( nSeriesIdx < maSeries.size() )
    4135          97 :             maSeries[ nSeriesIdx ]->SetDataFormat( aMIt->second );
    4136             :     }
    4137             : 
    4138             :     /*  #i51639# (part 2): Finalize data formats of all series. This adds for
    4139             :         example missing CHDATAFORMAT groups for entire series that are needed
    4140             :         for automatic colors of lines and areas. */
    4141          80 :     for( XclImpChSeriesVec::iterator aVIt = maSeries.begin(), aVEnd = maSeries.end(); aVIt != aVEnd; ++aVIt )
    4142          40 :         (*aVIt)->FinalizeDataFormats();
    4143          40 : }
    4144             : 
    4145          40 : void XclImpChChart::FinalizeTitle()
    4146             : {
    4147             :     // special handling for auto-generated title
    4148          40 :     String aAutoTitle;
    4149          40 :     if( !mxTitle || (!mxTitle->IsDeleted() && !mxTitle->HasString()) )
    4150             :     {
    4151             :         // automatic title from first series name (if there are no series on secondary axes set)
    4152          38 :         if( !mxSecnAxesSet->IsValidAxesSet() )
    4153          38 :             aAutoTitle = mxPrimAxesSet->GetSingleSeriesTitle();
    4154          38 :         if( mxTitle || (aAutoTitle.Len() > 0) )
    4155             :         {
    4156          19 :             if( !mxTitle )
    4157           0 :                 mxTitle.reset( new XclImpChText( GetChRoot() ) );
    4158          19 :             if( aAutoTitle.Len() == 0 )
    4159           0 :                 aAutoTitle = "Chart Title";
    4160             :         }
    4161             :     }
    4162             : 
    4163             :     // will reset mxTitle, if it does not contain a string and no auto title exists
    4164          40 :     lclFinalizeTitle( mxTitle, GetDefaultText( EXC_CHTEXTTYPE_TITLE ), aAutoTitle );
    4165          40 : }
    4166             : 
    4167          40 : Reference< XDiagram > XclImpChChart::CreateDiagram() const
    4168             : {
    4169             :     // create a diagram object
    4170          40 :     Reference< XDiagram > xDiagram( ScfApiHelper::CreateInstance( SERVICE_CHART2_DIAGRAM ), UNO_QUERY );
    4171             : 
    4172             :     // convert global chart settings
    4173          80 :     ScfPropertySet aDiaProp( xDiagram );
    4174             : 
    4175             :     // treatment of missing values
    4176             :     using namespace cssc::MissingValueTreatment;
    4177          40 :     sal_Int32 nMissingValues = LEAVE_GAP;
    4178          40 :     switch( maProps.mnEmptyMode )
    4179             :     {
    4180           2 :         case EXC_CHPROPS_EMPTY_SKIP:        nMissingValues = LEAVE_GAP; break;
    4181          38 :         case EXC_CHPROPS_EMPTY_ZERO:        nMissingValues = USE_ZERO;  break;
    4182           0 :         case EXC_CHPROPS_EMPTY_INTERPOLATE: nMissingValues = CONTINUE;  break;
    4183             :     }
    4184          40 :     aDiaProp.SetProperty( EXC_CHPROP_MISSINGVALUETREATMENT, nMissingValues );
    4185             : 
    4186          80 :     return xDiagram;
    4187             : }
    4188             : 
    4189             : // ----------------------------------------------------------------------------
    4190             : 
    4191          38 : XclImpChartDrawing::XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab ) :
    4192             :     XclImpDrawing( rRoot, bOwnTab ), // sheet charts may contain OLE objects
    4193          38 :     mnScTab( rRoot.GetCurrScTab() ),
    4194          76 :     mbOwnTab( bOwnTab )
    4195             : {
    4196          38 : }
    4197             : 
    4198          38 : void XclImpChartDrawing::ConvertObjects( XclImpDffConverter& rDffConv,
    4199             :         const Reference< XModel >& rxModel, const Rectangle& rChartRect )
    4200             : {
    4201          38 :     maChartRect = rChartRect;   // needed in CalcAnchorRect() callback
    4202             : 
    4203          38 :     SdrModel* pSdrModel = 0;
    4204          38 :     SdrPage* pSdrPage = 0;
    4205          38 :     if( mbOwnTab )
    4206             :     {
    4207             :         // chart sheet: insert all shapes into the sheet, not into the chart object
    4208           0 :         pSdrModel = GetDoc().GetDrawLayer();
    4209           0 :         pSdrPage = GetSdrPage( mnScTab );
    4210             :     }
    4211             :     else
    4212             :     {
    4213             :         // embedded chart object: insert all shapes into the chart
    4214             :         try
    4215             :         {
    4216          38 :             Reference< XDrawPageSupplier > xDrawPageSupp( rxModel, UNO_QUERY_THROW );
    4217          76 :             Reference< XDrawPage > xDrawPage( xDrawPageSupp->getDrawPage(), UNO_SET_THROW );
    4218          38 :             pSdrPage = ::GetSdrPageFromXDrawPage( xDrawPage );
    4219          76 :             pSdrModel = pSdrPage ? pSdrPage->GetModel() : 0;
    4220             :         }
    4221           0 :         catch( Exception& )
    4222             :         {
    4223             :         }
    4224             :     }
    4225             : 
    4226          38 :     if( pSdrModel && pSdrPage )
    4227          38 :         ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage );
    4228          38 : }
    4229             : 
    4230           0 : Rectangle XclImpChartDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const
    4231             : {
    4232             :     /*  In objects with DFF client anchor, the position of the shape is stored
    4233             :         in the cell address components of the client anchor. In old BIFF3-BIFF5
    4234             :         objects, the position is stored in the offset components of the anchor. */
    4235             :     Rectangle aRect(
    4236           0 :         static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth()  + 0.5 ),
    4237           0 :         static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ),
    4238           0 :         static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol  : rAnchor.mnRX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth()  + 0.5 ),
    4239           0 :         static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow  : rAnchor.mnBY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ) );
    4240           0 :     aRect.Justify();
    4241             :     // move shapes into chart area for sheet charts
    4242           0 :     if( mbOwnTab )
    4243           0 :         aRect.Move( maChartRect.Left(), maChartRect.Top() );
    4244           0 :     return aRect;
    4245             : }
    4246             : 
    4247           0 : void XclImpChartDrawing::OnObjectInserted( const XclImpDrawObjBase& )
    4248             : {
    4249           0 : }
    4250             : 
    4251             : // ----------------------------------------------------------------------------
    4252             : 
    4253          41 : XclImpChart::XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ) :
    4254             :     XclImpRoot( rRoot ),
    4255             :     mbOwnTab( bOwnTab ),
    4256          41 :     mbIsPivotChart( false )
    4257             : {
    4258          41 : }
    4259             : 
    4260          82 : XclImpChart::~XclImpChart()
    4261             : {
    4262          82 : }
    4263             : 
    4264          41 : void XclImpChart::ReadChartSubStream( XclImpStream& rStrm )
    4265             : {
    4266          41 :     XclImpPageSettings& rPageSett = GetPageSettings();
    4267          41 :     XclImpTabViewSettings& rTabViewSett = GetTabViewSettings();
    4268             : 
    4269          41 :     bool bLoop = true;
    4270        1009 :     while( bLoop && rStrm.StartNextRecord() )
    4271             :     {
    4272             :         // page settings - only for charts in entire sheet
    4273         927 :         if( mbOwnTab ) switch( rStrm.GetRecId() )
    4274             :         {
    4275             :             case EXC_ID_HORPAGEBREAKS:
    4276           0 :             case EXC_ID_VERPAGEBREAKS:  rPageSett.ReadPageBreaks( rStrm );      break;
    4277             :             case EXC_ID_HEADER:
    4278           0 :             case EXC_ID_FOOTER:         rPageSett.ReadHeaderFooter( rStrm );    break;
    4279             :             case EXC_ID_LEFTMARGIN:
    4280             :             case EXC_ID_RIGHTMARGIN:
    4281             :             case EXC_ID_TOPMARGIN:
    4282           0 :             case EXC_ID_BOTTOMMARGIN:   rPageSett.ReadMargin( rStrm );          break;
    4283           0 :             case EXC_ID_PRINTHEADERS:   rPageSett.ReadPrintHeaders( rStrm );    break;
    4284           0 :             case EXC_ID_PRINTGRIDLINES: rPageSett.ReadPrintGridLines( rStrm );  break;
    4285             :             case EXC_ID_HCENTER:
    4286           0 :             case EXC_ID_VCENTER:        rPageSett.ReadCenter( rStrm );          break;
    4287           0 :             case EXC_ID_SETUP:          rPageSett.ReadSetup( rStrm );           break;
    4288           0 :             case EXC_ID8_IMGDATA:       rPageSett.ReadImgData( rStrm );         break;
    4289             : 
    4290           0 :             case EXC_ID_WINDOW2:        rTabViewSett.ReadWindow2( rStrm, true );break;
    4291           0 :             case EXC_ID_SCL:            rTabViewSett.ReadScl( rStrm );          break;
    4292             : 
    4293             :             case EXC_ID_SHEETEXT: //0x0862
    4294             :             {
    4295             :                 // FIXME: do not need to pass palette, XclImpTabVieSettings is derived from root
    4296           0 :                 XclImpPalette& rPal = GetPalette();
    4297           0 :                 rTabViewSett.ReadTabBgColor( rStrm,  rPal);
    4298             :             }
    4299           0 :             break;
    4300             : 
    4301           0 :             case EXC_ID_CODENAME:       ReadCodeName( rStrm, false );           break;
    4302             :         }
    4303             : 
    4304             :         // common records
    4305         927 :         switch( rStrm.GetRecId() )
    4306             :         {
    4307          41 :             case EXC_ID_EOF:            bLoop = false;                          break;
    4308             : 
    4309             :             // #i31882# ignore embedded chart objects
    4310             :             case EXC_ID2_BOF:
    4311             :             case EXC_ID3_BOF:
    4312             :             case EXC_ID4_BOF:
    4313           0 :             case EXC_ID5_BOF:           XclTools::SkipSubStream( rStrm );       break;
    4314             : 
    4315          40 :             case EXC_ID_CHCHART:        ReadChChart( rStrm );                   break;
    4316             : 
    4317             :             case EXC_ID8_CHPIVOTREF:
    4318           0 :                 GetTracer().TracePivotChartExists();
    4319           0 :                 mbIsPivotChart = true;
    4320           0 :             break;
    4321             : 
    4322             :             // BIFF specific records
    4323         846 :             default: switch( GetBiff() )
    4324             :             {
    4325           0 :                 case EXC_BIFF5: switch( rStrm.GetRecId() )
    4326             :                 {
    4327           0 :                     case EXC_ID_OBJ:        GetChartDrawing().ReadObj( rStrm );         break;
    4328             :                 }
    4329           0 :                 break;
    4330         846 :                 case EXC_BIFF8: switch( rStrm.GetRecId() )
    4331             :                 {
    4332          38 :                     case EXC_ID_MSODRAWING: GetChartDrawing().ReadMsoDrawing( rStrm );  break;
    4333             :                     // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format
    4334           0 :                     case EXC_ID_OBJ:        GetChartDrawing().ReadObj( rStrm );         break;
    4335             :                 }
    4336         846 :                 break;
    4337             :                 default:;
    4338             :             }
    4339             :         }
    4340             :     }
    4341          41 : }
    4342             : 
    4343           0 : void XclImpChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData )
    4344             : {
    4345           0 :     if( !mxChartData )
    4346           0 :         mxChartData.reset( new XclImpChChart( GetRoot() ) );
    4347           0 :     mxChartData->UpdateObjFrame( rLineData, rFillData );
    4348           0 : }
    4349             : 
    4350          41 : sal_Size XclImpChart::GetProgressSize() const
    4351             : {
    4352             :     return
    4353         120 :         (mxChartData ? mxChartData->GetProgressSize() : 0) +
    4354         120 :         (mxChartDrawing ? mxChartDrawing->GetProgressSize() : 0);
    4355             : }
    4356             : 
    4357          41 : void XclImpChart::Convert( Reference< XModel > xModel, XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const
    4358             : {
    4359          41 :     Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY );
    4360          41 :     if( xChartDoc.is() )
    4361             :     {
    4362          41 :         if( mxChartData )
    4363          40 :             mxChartData->Convert( xChartDoc, rDffConv, rObjName, rChartRect );
    4364          41 :         if( mxChartDrawing )
    4365          38 :             mxChartDrawing->ConvertObjects( rDffConv, xModel, rChartRect );
    4366          41 :     }
    4367          41 : }
    4368             : 
    4369          38 : XclImpChartDrawing& XclImpChart::GetChartDrawing()
    4370             : {
    4371          38 :     if( !mxChartDrawing )
    4372          38 :         mxChartDrawing.reset( new XclImpChartDrawing( GetRoot(), mbOwnTab ) );
    4373          38 :     return *mxChartDrawing;
    4374             : }
    4375             : 
    4376          40 : void XclImpChart::ReadChChart( XclImpStream& rStrm )
    4377             : {
    4378          40 :     mxChartData.reset( new XclImpChChart( GetRoot() ) );
    4379          40 :     mxChartData->ReadRecordGroup( rStrm );
    4380          55 : }
    4381             : 
    4382             : // ============================================================================
    4383             : 
    4384             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10