LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xichart.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 2283 0.0 %
Date: 2014-04-14 Functions: 0 269 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10