LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xechart.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1858 0.0 %
Date: 2014-04-14 Functions: 0 227 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             : 
      21             : #include "xechart.hxx"
      22             : 
      23             : #include <com/sun/star/i18n/XBreakIterator.hpp>
      24             : #include <com/sun/star/i18n/ScriptType.hpp>
      25             : #include <com/sun/star/drawing/FillStyle.hpp>
      26             : #include <com/sun/star/drawing/XShapes.hpp>
      27             : #include <com/sun/star/chart/XChartDocument.hpp>
      28             : #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
      29             : #include <com/sun/star/chart/ChartAxisPosition.hpp>
      30             : #include <com/sun/star/chart/ChartLegendExpansion.hpp>
      31             : #include <com/sun/star/chart/DataLabelPlacement.hpp>
      32             : #include <com/sun/star/chart/ErrorBarStyle.hpp>
      33             : #include <com/sun/star/chart/MissingValueTreatment.hpp>
      34             : #include <com/sun/star/chart/TimeInterval.hpp>
      35             : #include <com/sun/star/chart/TimeUnit.hpp>
      36             : #include <com/sun/star/chart/XAxisSupplier.hpp>
      37             : #include <com/sun/star/chart/XDiagramPositioning.hpp>
      38             : #include <com/sun/star/chart2/XChartDocument.hpp>
      39             : #include <com/sun/star/chart2/XDiagram.hpp>
      40             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      41             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      42             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      43             : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
      44             : #include <com/sun/star/chart2/XTitled.hpp>
      45             : #include <com/sun/star/chart2/XColorScheme.hpp>
      46             : #include <com/sun/star/chart2/data/XDataSource.hpp>
      47             : #include <com/sun/star/chart2/AxisType.hpp>
      48             : #include <com/sun/star/chart2/CurveStyle.hpp>
      49             : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
      50             : #include <com/sun/star/chart2/DataPointLabel.hpp>
      51             : #include <com/sun/star/chart2/LegendPosition.hpp>
      52             : #include <com/sun/star/chart2/RelativePosition.hpp>
      53             : #include <com/sun/star/chart2/RelativeSize.hpp>
      54             : #include <com/sun/star/chart2/StackingDirection.hpp>
      55             : #include <com/sun/star/chart2/TickmarkStyle.hpp>
      56             : 
      57             : #include <tools/gen.hxx>
      58             : #include <vcl/outdev.hxx>
      59             : #include <filter/msfilter/escherex.hxx>
      60             : 
      61             : #include "document.hxx"
      62             : #include "rangelst.hxx"
      63             : #include "rangeutl.hxx"
      64             : #include "compiler.hxx"
      65             : #include "tokenarray.hxx"
      66             : #include "token.hxx"
      67             : #include "xeescher.hxx"
      68             : #include "xeformula.hxx"
      69             : #include "xehelper.hxx"
      70             : #include "xepage.hxx"
      71             : #include "xestyle.hxx"
      72             : 
      73             : #include <boost/scoped_ptr.hpp>
      74             : 
      75             : using ::com::sun::star::uno::Any;
      76             : using ::com::sun::star::uno::Reference;
      77             : using ::com::sun::star::uno::Sequence;
      78             : using ::com::sun::star::uno::UNO_QUERY;
      79             : using ::com::sun::star::uno::UNO_QUERY_THROW;
      80             : using ::com::sun::star::uno::UNO_SET_THROW;
      81             : using ::com::sun::star::uno::Exception;
      82             : using ::com::sun::star::beans::XPropertySet;
      83             : using ::com::sun::star::i18n::XBreakIterator;
      84             : using ::com::sun::star::frame::XModel;
      85             : using ::com::sun::star::drawing::XShape;
      86             : using ::com::sun::star::drawing::XShapes;
      87             : 
      88             : using ::com::sun::star::chart2::IncrementData;
      89             : using ::com::sun::star::chart2::RelativePosition;
      90             : using ::com::sun::star::chart2::RelativeSize;
      91             : using ::com::sun::star::chart2::ScaleData;
      92             : using ::com::sun::star::chart2::SubIncrement;
      93             : using ::com::sun::star::chart2::XAxis;
      94             : using ::com::sun::star::chart2::XChartDocument;
      95             : using ::com::sun::star::chart2::XChartTypeContainer;
      96             : using ::com::sun::star::chart2::XColorScheme;
      97             : using ::com::sun::star::chart2::XCoordinateSystem;
      98             : using ::com::sun::star::chart2::XCoordinateSystemContainer;
      99             : using ::com::sun::star::chart2::XChartType;
     100             : using ::com::sun::star::chart2::XDataSeries;
     101             : using ::com::sun::star::chart2::XDataSeriesContainer;
     102             : using ::com::sun::star::chart2::XDiagram;
     103             : using ::com::sun::star::chart2::XFormattedString;
     104             : using ::com::sun::star::chart2::XLegend;
     105             : using ::com::sun::star::chart2::XRegressionCurve;
     106             : using ::com::sun::star::chart2::XRegressionCurveContainer;
     107             : using ::com::sun::star::chart2::XScaling;
     108             : using ::com::sun::star::chart2::XTitle;
     109             : using ::com::sun::star::chart2::XTitled;
     110             : 
     111             : using ::com::sun::star::chart2::data::XDataSequence;
     112             : using ::com::sun::star::chart2::data::XDataSource;
     113             : using ::com::sun::star::chart2::data::XLabeledDataSequence;
     114             : 
     115             : using ::formula::FormulaGrammar;
     116             : using ::formula::FormulaToken;
     117             : 
     118             : namespace cssc = ::com::sun::star::chart;
     119             : namespace cssc2 = ::com::sun::star::chart2;
     120             : 
     121             : // Helpers ====================================================================
     122             : 
     123             : namespace {
     124             : 
     125           0 : XclExpStream& operator<<( XclExpStream& rStrm, const XclChRectangle& rRect )
     126             : {
     127           0 :     return rStrm << rRect.mnX << rRect.mnY << rRect.mnWidth << rRect.mnHeight;
     128             : }
     129             : 
     130           0 : inline void lclSaveRecord( XclExpStream& rStrm, XclExpRecordRef xRec )
     131             : {
     132           0 :     if( xRec )
     133           0 :         xRec->Save( rStrm );
     134           0 : }
     135             : 
     136             : /** Saves the passed record (group) together with a leading value record. */
     137             : template< typename Type >
     138           0 : void lclSaveRecord( XclExpStream& rStrm, XclExpRecordRef xRec, sal_uInt16 nRecId, Type nValue )
     139             : {
     140           0 :     if( xRec )
     141             :     {
     142           0 :         XclExpValueRecord< Type >( nRecId, nValue ).Save( rStrm );
     143           0 :         xRec->Save( rStrm );
     144             :     }
     145           0 : }
     146             : 
     147             : template<typename ValueType, typename KeyType>
     148           0 : void lclSaveRecord(XclExpStream& rStrm, ValueType* pRec, sal_uInt16 nRecId, KeyType nValue)
     149             : {
     150           0 :     if (pRec)
     151             :     {
     152           0 :         XclExpValueRecord<KeyType>(nRecId, nValue).Save(rStrm);
     153           0 :         pRec->Save(rStrm);
     154             :     }
     155           0 : }
     156             : 
     157           0 : void lclWriteChFrBlockRecord( XclExpStream& rStrm, const XclChFrBlock& rFrBlock, bool bBegin )
     158             : {
     159           0 :     sal_uInt16 nRecId = bBegin ? EXC_ID_CHFRBLOCKBEGIN : EXC_ID_CHFRBLOCKEND;
     160           0 :     rStrm.StartRecord( nRecId, 12 );
     161           0 :     rStrm << nRecId << EXC_FUTUREREC_EMPTYFLAGS << rFrBlock.mnType << rFrBlock.mnContext << rFrBlock.mnValue1 << rFrBlock.mnValue2;
     162           0 :     rStrm.EndRecord();
     163           0 : }
     164             : 
     165             : template< typename Type >
     166           0 : inline bool lclIsAutoAnyOrGetValue( Type& rValue, const Any& rAny )
     167             : {
     168           0 :     return !rAny.hasValue() || !(rAny >>= rValue);
     169             : }
     170             : 
     171           0 : bool lclIsAutoAnyOrGetScaledValue( double& rfValue, const Any& rAny, bool bLogScale )
     172             : {
     173           0 :     bool bIsAuto = lclIsAutoAnyOrGetValue( rfValue, rAny );
     174           0 :     if( !bIsAuto && bLogScale )
     175           0 :         rfValue = log( rfValue ) / log( 10.0 );
     176           0 :     return bIsAuto;
     177             : }
     178             : 
     179           0 : sal_uInt16 lclGetTimeValue( const XclExpRoot& rRoot, double fSerialDate, sal_uInt16 nTimeUnit )
     180             : {
     181           0 :     DateTime aDateTime = rRoot.GetDateTimeFromDouble( fSerialDate );
     182           0 :     switch( nTimeUnit )
     183             :     {
     184             :         case EXC_CHDATERANGE_DAYS:
     185           0 :             return ::limit_cast< sal_uInt16, double >( fSerialDate, 0, SAL_MAX_UINT16 );
     186             :         case EXC_CHDATERANGE_MONTHS:
     187           0 :             return ::limit_cast< sal_uInt16, sal_uInt16 >( 12 * (aDateTime.GetYear() - rRoot.GetBaseYear()) + aDateTime.GetMonth() - 1, 0, SAL_MAX_INT16 );
     188             :         case EXC_CHDATERANGE_YEARS:
     189           0 :             return ::limit_cast< sal_uInt16, sal_uInt16 >( aDateTime.GetYear() - rRoot.GetBaseYear(), 0, SAL_MAX_INT16 );
     190             :         default:
     191             :             OSL_ENSURE( false, "lclGetTimeValue - unexpected time unit" );
     192             :     }
     193           0 :     return ::limit_cast< sal_uInt16, double >( fSerialDate, 0, SAL_MAX_UINT16 );
     194             : }
     195             : 
     196           0 : bool lclConvertTimeValue( const XclExpRoot& rRoot, sal_uInt16& rnValue, const Any& rAny, sal_uInt16 nTimeUnit )
     197             : {
     198           0 :     double fSerialDate = 0;
     199           0 :     bool bAuto = lclIsAutoAnyOrGetValue( fSerialDate, rAny );
     200           0 :     if( !bAuto )
     201           0 :         rnValue = lclGetTimeValue( rRoot, fSerialDate, nTimeUnit );
     202           0 :     return bAuto;
     203             : }
     204             : 
     205           0 : sal_uInt16 lclGetTimeUnit( sal_Int32 nApiTimeUnit )
     206             : {
     207           0 :     switch( nApiTimeUnit )
     208             :     {
     209           0 :         case cssc::TimeUnit::DAY:   return EXC_CHDATERANGE_DAYS;
     210           0 :         case cssc::TimeUnit::MONTH: return EXC_CHDATERANGE_MONTHS;
     211           0 :         case cssc::TimeUnit::YEAR:  return EXC_CHDATERANGE_YEARS;
     212             :         default:                    OSL_ENSURE( false, "lclGetTimeUnit - unexpected time unit" );
     213             :     }
     214           0 :     return EXC_CHDATERANGE_DAYS;
     215             : }
     216             : 
     217           0 : bool lclConvertTimeInterval( sal_uInt16& rnValue, sal_uInt16& rnTimeUnit, const Any& rAny )
     218             : {
     219           0 :     cssc::TimeInterval aInterval;
     220           0 :     bool bAuto = lclIsAutoAnyOrGetValue( aInterval, rAny );
     221           0 :     if( !bAuto )
     222             :     {
     223           0 :         rnValue = ::limit_cast< sal_uInt16, sal_Int32 >( aInterval.Number, 1, SAL_MAX_UINT16 );
     224           0 :         rnTimeUnit = lclGetTimeUnit( aInterval.TimeUnit );
     225             :     }
     226           0 :     return bAuto;
     227             : }
     228             : 
     229             : } // namespace
     230             : 
     231             : // Common =====================================================================
     232             : 
     233             : /** Stores global data needed in various classes of the Chart export filter. */
     234           0 : struct XclExpChRootData : public XclChRootData
     235             : {
     236             :     typedef ::std::vector< XclChFrBlock > XclChFrBlockVector;
     237             : 
     238             :     XclExpChChart&      mrChartData;            /// The chart data object.
     239             :     XclChFrBlockVector  maWrittenFrBlocks;      /// Stack of future record levels already written out.
     240             :     XclChFrBlockVector  maUnwrittenFrBlocks;    /// Stack of future record levels not yet written out.
     241             : 
     242           0 :     inline explicit     XclExpChRootData( XclExpChChart& rChartData ) : mrChartData( rChartData ) {}
     243             : 
     244             :     /** Registers a new future record level. */
     245             :     void                RegisterFutureRecBlock( const XclChFrBlock& rFrBlock );
     246             :     /** Initializes the current future record level (writes all unwritten CHFRBLOCKBEGIN records). */
     247             :     void                InitializeFutureRecBlock( XclExpStream& rStrm );
     248             :     /** Finalizes the current future record level (writes CHFRBLOCKEND record if needed). */
     249             :     void                FinalizeFutureRecBlock( XclExpStream& rStrm );
     250             : };
     251             : 
     252           0 : void XclExpChRootData::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock )
     253             : {
     254           0 :     maUnwrittenFrBlocks.push_back( rFrBlock );
     255           0 : }
     256             : 
     257           0 : void XclExpChRootData::InitializeFutureRecBlock( XclExpStream& rStrm )
     258             : {
     259             :     // first call from a future record writes all missing CHFRBLOCKBEGIN records
     260           0 :     if( !maUnwrittenFrBlocks.empty() )
     261             :     {
     262             :         // write the leading CHFRINFO record
     263           0 :         if( maWrittenFrBlocks.empty() )
     264             :         {
     265           0 :             rStrm.StartRecord( EXC_ID_CHFRINFO, 20 );
     266           0 :             rStrm << EXC_ID_CHFRINFO << EXC_FUTUREREC_EMPTYFLAGS << EXC_CHFRINFO_EXCELXP2003 << EXC_CHFRINFO_EXCELXP2003 << sal_uInt16( 3 );
     267           0 :             rStrm << sal_uInt16( 0x0850 ) << sal_uInt16( 0x085A ) << sal_uInt16( 0x0861 ) << sal_uInt16( 0x0861 ) << sal_uInt16( 0x086A ) << sal_uInt16( 0x086B );
     268           0 :             rStrm.EndRecord();
     269             :         }
     270             :         // write all unwritten CHFRBLOCKBEGIN records
     271           0 :         for( XclChFrBlockVector::const_iterator aIt = maUnwrittenFrBlocks.begin(), aEnd = maUnwrittenFrBlocks.end(); aIt != aEnd; ++aIt )
     272             :         {
     273             :             OSL_ENSURE( aIt->mnType != EXC_CHFRBLOCK_TYPE_UNKNOWN, "XclExpChRootData::InitializeFutureRecBlock - unknown future record block type" );
     274           0 :             lclWriteChFrBlockRecord( rStrm, *aIt, true );
     275             :         }
     276             :         // move all record infos to vector of written blocks
     277           0 :         maWrittenFrBlocks.insert( maWrittenFrBlocks.end(), maUnwrittenFrBlocks.begin(), maUnwrittenFrBlocks.end() );
     278           0 :         maUnwrittenFrBlocks.clear();
     279             :     }
     280           0 : }
     281             : 
     282           0 : void XclExpChRootData::FinalizeFutureRecBlock( XclExpStream& rStrm )
     283             : {
     284             :     OSL_ENSURE( !maUnwrittenFrBlocks.empty() || !maWrittenFrBlocks.empty(), "XclExpChRootData::FinalizeFutureRecBlock - no future record level found" );
     285           0 :     if( !maUnwrittenFrBlocks.empty() )
     286             :     {
     287             :         // no future record has been written, just forget the topmost level
     288           0 :         maUnwrittenFrBlocks.pop_back();
     289             :     }
     290           0 :     else if( !maWrittenFrBlocks.empty() )
     291             :     {
     292             :         // write the CHFRBLOCKEND record for the topmost block and delete it
     293           0 :         lclWriteChFrBlockRecord( rStrm, maWrittenFrBlocks.back(), false );
     294           0 :         maWrittenFrBlocks.pop_back();
     295             :     }
     296           0 : }
     297             : 
     298           0 : XclExpChRoot::XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData ) :
     299             :     XclExpRoot( rRoot ),
     300           0 :     mxChData( new XclExpChRootData( rChartData ) )
     301             : {
     302           0 : }
     303             : 
     304           0 : XclExpChRoot::~XclExpChRoot()
     305             : {
     306           0 : }
     307             : 
     308           0 : Reference< XChartDocument > XclExpChRoot::GetChartDocument() const
     309             : {
     310           0 :     return mxChData->mxChartDoc;
     311             : }
     312             : 
     313           0 : XclExpChChart& XclExpChRoot::GetChartData() const
     314             : {
     315           0 :     return mxChData->mrChartData;
     316             : }
     317             : 
     318           0 : const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
     319             : {
     320           0 :     return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
     321             : }
     322             : 
     323           0 : const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( const OUString& rServiceName ) const
     324             : {
     325           0 :     return mxChData->mxTypeInfoProv->GetTypeInfoFromService( rServiceName );
     326             : }
     327             : 
     328           0 : const XclChFormatInfo& XclExpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
     329             : {
     330           0 :     return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
     331             : }
     332             : 
     333           0 : void XclExpChRoot::InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const
     334             : {
     335           0 :     mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
     336           0 : }
     337             : 
     338           0 : void XclExpChRoot::FinishConversion() const
     339             : {
     340           0 :     mxChData->FinishConversion();
     341           0 : }
     342             : 
     343           0 : bool XclExpChRoot::IsSystemColor( const Color& rColor, sal_uInt16 nSysColorIdx ) const
     344             : {
     345           0 :     XclExpPalette& rPal = GetPalette();
     346           0 :     return rPal.IsSystemColor( nSysColorIdx ) && (rColor == rPal.GetDefColor( nSysColorIdx ));
     347             : }
     348             : 
     349           0 : void XclExpChRoot::SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uInt16 nSysColorIdx ) const
     350             : {
     351             :     OSL_ENSURE( GetPalette().IsSystemColor( nSysColorIdx ), "XclExpChRoot::SetSystemColor - invalid color index" );
     352           0 :     rColor = GetPalette().GetDefColor( nSysColorIdx );
     353           0 :     rnColorId = XclExpPalette::GetColorIdFromIndex( nSysColorIdx );
     354           0 : }
     355             : 
     356           0 : sal_Int32 XclExpChRoot::CalcChartXFromHmm( sal_Int32 nPosX ) const
     357             : {
     358           0 :     return ::limit_cast< sal_Int32, double >( (nPosX - mxChData->mnBorderGapX) / mxChData->mfUnitSizeX, 0, EXC_CHART_TOTALUNITS );
     359             : }
     360             : 
     361           0 : sal_Int32 XclExpChRoot::CalcChartYFromHmm( sal_Int32 nPosY ) const
     362             : {
     363           0 :     return ::limit_cast< sal_Int32, double >( (nPosY - mxChData->mnBorderGapY) / mxChData->mfUnitSizeY, 0, EXC_CHART_TOTALUNITS );
     364             : }
     365             : 
     366           0 : XclChRectangle XclExpChRoot::CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const
     367             : {
     368           0 :     XclChRectangle aRect;
     369           0 :     aRect.mnX = CalcChartXFromHmm( rRect.X );
     370           0 :     aRect.mnY = CalcChartYFromHmm( rRect.Y );
     371           0 :     aRect.mnWidth = CalcChartXFromHmm( rRect.Width );
     372           0 :     aRect.mnHeight = CalcChartYFromHmm( rRect.Height );
     373           0 :     return aRect;
     374             : }
     375             : 
     376           0 : void XclExpChRoot::ConvertLineFormat( XclChLineFormat& rLineFmt,
     377             :         const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
     378             : {
     379           0 :     GetChartPropSetHelper().ReadLineProperties(
     380           0 :         rLineFmt, *mxChData->mxLineDashTable, rPropSet, ePropMode );
     381           0 : }
     382             : 
     383           0 : bool XclExpChRoot::ConvertAreaFormat( XclChAreaFormat& rAreaFmt,
     384             :         const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
     385             : {
     386           0 :     return GetChartPropSetHelper().ReadAreaProperties( rAreaFmt, rPropSet, ePropMode );
     387             : }
     388             : 
     389           0 : void XclExpChRoot::ConvertEscherFormat(
     390             :         XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
     391             :         const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
     392             : {
     393           0 :     GetChartPropSetHelper().ReadEscherProperties( rEscherFmt, rPicFmt,
     394           0 :         *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable, rPropSet, ePropMode );
     395           0 : }
     396             : 
     397           0 : sal_uInt16 XclExpChRoot::ConvertFont( const ScfPropertySet& rPropSet, sal_Int16 nScript ) const
     398             : {
     399           0 :     XclFontData aFontData;
     400           0 :     GetFontPropSetHelper().ReadFontProperties( aFontData, rPropSet, EXC_FONTPROPSET_CHART, nScript );
     401           0 :     return GetFontBuffer().Insert( aFontData, EXC_COLOR_CHARTTEXT );
     402             : }
     403             : 
     404           0 : sal_uInt16 XclExpChRoot::ConvertPieRotation( const ScfPropertySet& rPropSet )
     405             : {
     406           0 :     sal_Int32 nApiRot = 0;
     407           0 :     rPropSet.GetProperty( nApiRot, EXC_CHPROP_STARTINGANGLE );
     408           0 :     return static_cast< sal_uInt16 >( (450 - (nApiRot % 360)) % 360 );
     409             : }
     410             : 
     411           0 : void XclExpChRoot::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock )
     412             : {
     413           0 :     mxChData->RegisterFutureRecBlock( rFrBlock );
     414           0 : }
     415             : 
     416           0 : void XclExpChRoot::InitializeFutureRecBlock( XclExpStream& rStrm )
     417             : {
     418           0 :     mxChData->InitializeFutureRecBlock( rStrm );
     419           0 : }
     420             : 
     421           0 : void XclExpChRoot::FinalizeFutureRecBlock( XclExpStream& rStrm )
     422             : {
     423           0 :     mxChData->FinalizeFutureRecBlock( rStrm );
     424           0 : }
     425             : 
     426           0 : XclExpChGroupBase::XclExpChGroupBase( const XclExpChRoot& rRoot,
     427             :         sal_uInt16 nFrType, sal_uInt16 nRecId, sal_Size nRecSize ) :
     428             :     XclExpRecord( nRecId, nRecSize ),
     429             :     XclExpChRoot( rRoot ),
     430           0 :     maFrBlock( nFrType )
     431             : {
     432           0 : }
     433             : 
     434           0 : XclExpChGroupBase::~XclExpChGroupBase()
     435             : {
     436           0 : }
     437             : 
     438           0 : void XclExpChGroupBase::Save( XclExpStream& rStrm )
     439             : {
     440             :     // header record
     441           0 :     XclExpRecord::Save( rStrm );
     442             :     // group records
     443           0 :     if( HasSubRecords() )
     444             :     {
     445             :         // register the future record context corresponding to this record group
     446           0 :         RegisterFutureRecBlock( maFrBlock );
     447             :         // CHBEGIN record
     448           0 :         XclExpEmptyRecord( EXC_ID_CHBEGIN ).Save( rStrm );
     449             :         // embedded records
     450           0 :         WriteSubRecords( rStrm );
     451             :         // finalize the future records, must be done before the closing CHEND
     452           0 :         FinalizeFutureRecBlock( rStrm );
     453             :         // CHEND record
     454           0 :         XclExpEmptyRecord( EXC_ID_CHEND ).Save( rStrm );
     455             :     }
     456           0 : }
     457             : 
     458           0 : bool XclExpChGroupBase::HasSubRecords() const
     459             : {
     460           0 :     return true;
     461             : }
     462             : 
     463           0 : void XclExpChGroupBase::SetFutureRecordContext( sal_uInt16 nFrContext, sal_uInt16 nFrValue1, sal_uInt16 nFrValue2 )
     464             : {
     465           0 :     maFrBlock.mnContext = nFrContext;
     466           0 :     maFrBlock.mnValue1  = nFrValue1;
     467           0 :     maFrBlock.mnValue2  = nFrValue2;
     468           0 : }
     469             : 
     470           0 : XclExpChFutureRecordBase::XclExpChFutureRecordBase( const XclExpChRoot& rRoot,
     471             :         XclFutureRecType eRecType, sal_uInt16 nRecId, sal_Size nRecSize ) :
     472             :     XclExpFutureRecord( eRecType, nRecId, nRecSize ),
     473           0 :     XclExpChRoot( rRoot )
     474             : {
     475           0 : }
     476             : 
     477           0 : void XclExpChFutureRecordBase::Save( XclExpStream& rStrm )
     478             : {
     479           0 :     InitializeFutureRecBlock( rStrm );
     480           0 :     XclExpFutureRecord::Save( rStrm );
     481           0 : }
     482             : 
     483             : // Frame formatting ===========================================================
     484             : 
     485           0 : XclExpChFramePos::XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode ) :
     486           0 :     XclExpRecord( EXC_ID_CHFRAMEPOS, 20 )
     487             : {
     488           0 :     maData.mnTLMode = nTLMode;
     489           0 :     maData.mnBRMode = nBRMode;
     490           0 : }
     491             : 
     492           0 : void XclExpChFramePos::WriteBody( XclExpStream& rStrm )
     493             : {
     494           0 :     rStrm << maData.mnTLMode << maData.mnBRMode << maData.maRect;
     495           0 : }
     496             : 
     497           0 : XclExpChLineFormat::XclExpChLineFormat( const XclExpChRoot& rRoot ) :
     498           0 :     XclExpRecord( EXC_ID_CHLINEFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 10 ),
     499           0 :     mnColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
     500             : {
     501           0 : }
     502             : 
     503           0 : void XclExpChLineFormat::SetDefault( XclChFrameType eDefFrameType )
     504             : {
     505           0 :     switch( eDefFrameType )
     506             :     {
     507             :         case EXC_CHFRAMETYPE_AUTO:
     508           0 :             SetAuto( true );
     509           0 :         break;
     510             :         case EXC_CHFRAMETYPE_INVISIBLE:
     511           0 :             SetAuto( false );
     512           0 :             maData.mnPattern = EXC_CHLINEFORMAT_NONE;
     513           0 :         break;
     514             :         default:
     515             :             OSL_FAIL( "XclExpChLineFormat::SetDefault - unknown frame type" );
     516             :     }
     517           0 : }
     518             : 
     519           0 : void XclExpChLineFormat::Convert( const XclExpChRoot& rRoot,
     520             :         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
     521             : {
     522           0 :     const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
     523           0 :     rRoot.ConvertLineFormat( maData, rPropSet, rFmtInfo.mePropMode );
     524           0 :     if( HasLine() )
     525             :     {
     526             :         // detect system color, set color identifier (TODO: detect automatic series line)
     527           0 :         if( (eObjType != EXC_CHOBJTYPE_LINEARSERIES) && rRoot.IsSystemColor( maData.maColor, rFmtInfo.mnAutoLineColorIdx ) )
     528             :         {
     529             :             // store color index from automatic format data
     530           0 :             mnColorId = XclExpPalette::GetColorIdFromIndex( rFmtInfo.mnAutoLineColorIdx );
     531             :             // try to set automatic mode
     532           0 :             bool bAuto = (maData.mnPattern == EXC_CHLINEFORMAT_SOLID) && (maData.mnWeight == rFmtInfo.mnAutoLineWeight);
     533           0 :             ::set_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO, bAuto );
     534             :         }
     535             :         else
     536             :         {
     537             :             // user defined color - register in palette
     538           0 :             mnColorId = rRoot.GetPalette().InsertColor( maData.maColor, EXC_COLOR_CHARTLINE );
     539             :         }
     540             :     }
     541             :     else
     542             :     {
     543             :         // no line - set default system color
     544           0 :         rRoot.SetSystemColor( maData.maColor, mnColorId, EXC_COLOR_CHWINDOWTEXT );
     545             :     }
     546           0 : }
     547             : 
     548           0 : bool XclExpChLineFormat::IsDefault( XclChFrameType eDefFrameType ) const
     549             : {
     550             :     return
     551           0 :         ((eDefFrameType == EXC_CHFRAMETYPE_INVISIBLE) && !HasLine()) ||
     552           0 :         ((eDefFrameType == EXC_CHFRAMETYPE_AUTO) && IsAuto());
     553             : }
     554             : 
     555           0 : void XclExpChLineFormat::WriteBody( XclExpStream& rStrm )
     556             : {
     557           0 :     rStrm << maData.maColor << maData.mnPattern << maData.mnWeight << maData.mnFlags;
     558           0 :     if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
     559           0 :         rStrm << rStrm.GetRoot().GetPalette().GetColorIndex( mnColorId );
     560           0 : }
     561             : 
     562             : namespace {
     563             : 
     564             : /** Creates a CHLINEFORMAT record from the passed property set. */
     565           0 : XclExpChLineFormatRef lclCreateLineFormat( const XclExpChRoot& rRoot,
     566             :         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
     567             : {
     568           0 :     XclExpChLineFormatRef xLineFmt( new XclExpChLineFormat( rRoot ) );
     569           0 :     xLineFmt->Convert( rRoot, rPropSet, eObjType );
     570           0 :     const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
     571           0 :     if( rFmtInfo.mbDeleteDefFrame && xLineFmt->IsDefault( rFmtInfo.meDefFrameType ) )
     572           0 :         xLineFmt.reset();
     573           0 :     return xLineFmt;
     574             : }
     575             : 
     576             : } // namespace
     577             : 
     578           0 : XclExpChAreaFormat::XclExpChAreaFormat( const XclExpChRoot& rRoot ) :
     579           0 :     XclExpRecord( EXC_ID_CHAREAFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 16 : 12 ),
     580           0 :     mnPattColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) ),
     581           0 :     mnBackColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
     582             : {
     583           0 : }
     584             : 
     585           0 : bool XclExpChAreaFormat::Convert( const XclExpChRoot& rRoot,
     586             :         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
     587             : {
     588           0 :     const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType );
     589           0 :     bool bComplexFill = rRoot.ConvertAreaFormat( maData, rPropSet, rFmtInfo.mePropMode );
     590           0 :     if( HasArea() )
     591             :     {
     592           0 :         bool bSolid = maData.mnPattern == EXC_PATT_SOLID;
     593             :         // detect system color, set color identifier (TODO: detect automatic series area)
     594           0 :         if( (eObjType != EXC_CHOBJTYPE_FILLEDSERIES) && rRoot.IsSystemColor( maData.maPattColor, rFmtInfo.mnAutoPattColorIdx ) )
     595             :         {
     596             :             // store color index from automatic format data
     597           0 :             mnPattColorId = XclExpPalette::GetColorIdFromIndex( rFmtInfo.mnAutoPattColorIdx );
     598             :             // set automatic mode
     599           0 :             ::set_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO, bSolid );
     600             :         }
     601             :         else
     602             :         {
     603             :             // user defined color - register color in palette
     604           0 :             mnPattColorId = rRoot.GetPalette().InsertColor( maData.maPattColor, EXC_COLOR_CHARTAREA );
     605             :         }
     606             :         // background color (default system color for solid fills)
     607           0 :         if( bSolid )
     608           0 :             rRoot.SetSystemColor( maData.maBackColor, mnBackColorId, EXC_COLOR_CHWINDOWTEXT );
     609             :         else
     610           0 :             mnBackColorId = rRoot.GetPalette().InsertColor( maData.maBackColor, EXC_COLOR_CHARTAREA );
     611             :     }
     612             :     else
     613             :     {
     614             :         // no area - set default system colors
     615           0 :         rRoot.SetSystemColor( maData.maPattColor, mnPattColorId, EXC_COLOR_CHWINDOWBACK );
     616           0 :         rRoot.SetSystemColor( maData.maBackColor, mnBackColorId, EXC_COLOR_CHWINDOWTEXT );
     617             :     }
     618           0 :     return bComplexFill;
     619             : }
     620             : 
     621           0 : void XclExpChAreaFormat::SetDefault( XclChFrameType eDefFrameType )
     622             : {
     623           0 :     switch( eDefFrameType )
     624             :     {
     625             :         case EXC_CHFRAMETYPE_AUTO:
     626           0 :             SetAuto( true );
     627           0 :         break;
     628             :         case EXC_CHFRAMETYPE_INVISIBLE:
     629           0 :             SetAuto( false );
     630           0 :             maData.mnPattern = EXC_PATT_NONE;
     631           0 :         break;
     632             :         default:
     633             :             OSL_FAIL( "XclExpChAreaFormat::SetDefault - unknown frame type" );
     634             :     }
     635           0 : }
     636             : 
     637           0 : bool XclExpChAreaFormat::IsDefault( XclChFrameType eDefFrameType ) const
     638             : {
     639             :     return
     640           0 :         ((eDefFrameType == EXC_CHFRAMETYPE_INVISIBLE) && !HasArea()) ||
     641           0 :         ((eDefFrameType == EXC_CHFRAMETYPE_AUTO) && IsAuto());
     642             : }
     643             : 
     644           0 : void XclExpChAreaFormat::WriteBody( XclExpStream& rStrm )
     645             : {
     646           0 :     rStrm << maData.maPattColor << maData.maBackColor << maData.mnPattern << maData.mnFlags;
     647           0 :     if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
     648             :     {
     649           0 :         const XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
     650           0 :         rStrm << rPal.GetColorIndex( mnPattColorId ) << rPal.GetColorIndex( mnBackColorId );
     651             :     }
     652           0 : }
     653             : 
     654           0 : XclExpChEscherFormat::XclExpChEscherFormat( const XclExpChRoot& rRoot ) :
     655             :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_UNKNOWN, EXC_ID_CHESCHERFORMAT ),
     656           0 :     mnColor1Id( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) ),
     657           0 :     mnColor2Id( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) )
     658             : {
     659             :     OSL_ENSURE_BIFF( GetBiff() == EXC_BIFF8 );
     660           0 : }
     661             : 
     662           0 : void XclExpChEscherFormat::Convert( const ScfPropertySet& rPropSet, XclChObjectType eObjType )
     663             : {
     664           0 :     const XclChFormatInfo& rFmtInfo = GetFormatInfo( eObjType );
     665           0 :     ConvertEscherFormat( maData, maPicFmt, rPropSet, rFmtInfo.mePropMode );
     666             :     // register colors in palette
     667           0 :     mnColor1Id = RegisterColor( ESCHER_Prop_fillColor );
     668           0 :     mnColor2Id = RegisterColor( ESCHER_Prop_fillBackColor );
     669           0 : }
     670             : 
     671           0 : bool XclExpChEscherFormat::IsValid() const
     672             : {
     673           0 :     return static_cast< bool >(maData.mxEscherSet);
     674             : }
     675             : 
     676           0 : void XclExpChEscherFormat::Save( XclExpStream& rStrm )
     677             : {
     678           0 :     if( maData.mxEscherSet )
     679             :     {
     680             :         // replace RGB colors with palette indexes in the Escher container
     681           0 :         const XclExpPalette& rPal = GetPalette();
     682           0 :         maData.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, 0x08000000 | rPal.GetColorIndex( mnColor1Id ) );
     683           0 :         maData.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x08000000 | rPal.GetColorIndex( mnColor2Id ) );
     684             : 
     685             :         // save the record group
     686           0 :         XclExpChGroupBase::Save( rStrm );
     687             :     }
     688           0 : }
     689             : 
     690           0 : bool XclExpChEscherFormat::HasSubRecords() const
     691             : {
     692             :     // no subrecords for gradients
     693           0 :     return maPicFmt.mnBmpMode != EXC_CHPICFORMAT_NONE;
     694             : }
     695             : 
     696           0 : void XclExpChEscherFormat::WriteSubRecords( XclExpStream& rStrm )
     697             : {
     698           0 :     rStrm.StartRecord( EXC_ID_CHPICFORMAT, 14 );
     699           0 :     rStrm << maPicFmt.mnBmpMode << sal_uInt16( 0 ) << maPicFmt.mnFlags << maPicFmt.mfScale;
     700           0 :     rStrm.EndRecord();
     701           0 : }
     702             : 
     703           0 : sal_uInt32 XclExpChEscherFormat::RegisterColor( sal_uInt16 nPropId )
     704             : {
     705             :     sal_uInt32 nBGRValue;
     706           0 :     if( maData.mxEscherSet && maData.mxEscherSet->GetOpt( nPropId, nBGRValue ) )
     707             :     {
     708             :         // swap red and blue
     709           0 :         Color aColor( RGB_COLORDATA(
     710             :             COLORDATA_BLUE( nBGRValue ),
     711             :             COLORDATA_GREEN( nBGRValue ),
     712           0 :             COLORDATA_RED( nBGRValue ) ) );
     713           0 :         return GetPalette().InsertColor( aColor, EXC_COLOR_CHARTAREA );
     714             :     }
     715           0 :     return XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK );
     716             : }
     717             : 
     718           0 : void XclExpChEscherFormat::WriteBody( XclExpStream& rStrm )
     719             : {
     720             :     OSL_ENSURE( maData.mxEscherSet, "XclExpChEscherFormat::WriteBody - missing property container" );
     721             :     // write Escher property container via temporary memory stream
     722           0 :     SvMemoryStream aMemStrm;
     723           0 :     maData.mxEscherSet->Commit( aMemStrm );
     724           0 :     aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
     725           0 :     rStrm.CopyFromStream( aMemStrm );
     726           0 : }
     727             : 
     728           0 : XclExpChFrameBase::XclExpChFrameBase()
     729             : {
     730           0 : }
     731             : 
     732           0 : XclExpChFrameBase::~XclExpChFrameBase()
     733             : {
     734           0 : }
     735             : 
     736           0 : void XclExpChFrameBase::ConvertFrameBase( const XclExpChRoot& rRoot,
     737             :         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
     738             : {
     739             :     // line format
     740           0 :     mxLineFmt.reset( new XclExpChLineFormat( rRoot ) );
     741           0 :     mxLineFmt->Convert( rRoot, rPropSet, eObjType );
     742             :     // area format (only for frame objects)
     743           0 :     if( rRoot.GetFormatInfo( eObjType ).mbIsFrame )
     744             :     {
     745           0 :         mxAreaFmt.reset( new XclExpChAreaFormat( rRoot ) );
     746           0 :         bool bComplexFill = mxAreaFmt->Convert( rRoot, rPropSet, eObjType );
     747           0 :         if( (rRoot.GetBiff() == EXC_BIFF8) && bComplexFill )
     748             :         {
     749           0 :             mxEscherFmt.reset( new XclExpChEscherFormat( rRoot ) );
     750           0 :             mxEscherFmt->Convert( rPropSet, eObjType );
     751           0 :             if( mxEscherFmt->IsValid() )
     752           0 :                 mxAreaFmt->SetAuto( false );
     753             :             else
     754           0 :                 mxEscherFmt.reset();
     755             :         }
     756             :     }
     757           0 : }
     758             : 
     759           0 : void XclExpChFrameBase::SetDefaultFrameBase( const XclExpChRoot& rRoot,
     760             :         XclChFrameType eDefFrameType, bool bIsFrame )
     761             : {
     762             :     // line format
     763           0 :     mxLineFmt.reset( new XclExpChLineFormat( rRoot ) );
     764           0 :     mxLineFmt->SetDefault( eDefFrameType );
     765             :     // area format (only for frame objects)
     766           0 :     if( bIsFrame )
     767             :     {
     768           0 :         mxAreaFmt.reset( new XclExpChAreaFormat( rRoot ) );
     769           0 :         mxAreaFmt->SetDefault( eDefFrameType );
     770           0 :         mxEscherFmt.reset();
     771             :     }
     772           0 : }
     773             : 
     774           0 : bool XclExpChFrameBase::IsDefaultFrameBase( XclChFrameType eDefFrameType ) const
     775             : {
     776             :     return
     777           0 :         (!mxLineFmt || mxLineFmt->IsDefault( eDefFrameType )) &&
     778           0 :         (!mxAreaFmt || mxAreaFmt->IsDefault( eDefFrameType ));
     779             : }
     780             : 
     781           0 : void XclExpChFrameBase::WriteFrameRecords( XclExpStream& rStrm )
     782             : {
     783           0 :     lclSaveRecord( rStrm, mxLineFmt );
     784           0 :     lclSaveRecord( rStrm, mxAreaFmt );
     785           0 :     lclSaveRecord( rStrm, mxEscherFmt );
     786           0 : }
     787             : 
     788           0 : XclExpChFrame::XclExpChFrame( const XclExpChRoot& rRoot, XclChObjectType eObjType ) :
     789             :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_FRAME, EXC_ID_CHFRAME, 4 ),
     790           0 :     meObjType( eObjType )
     791             : {
     792           0 : }
     793             : 
     794           0 : void XclExpChFrame::Convert( const ScfPropertySet& rPropSet )
     795             : {
     796           0 :     ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
     797           0 : }
     798             : 
     799           0 : void XclExpChFrame::SetAutoFlags( bool bAutoPos, bool bAutoSize )
     800             : {
     801           0 :     ::set_flag( maData.mnFlags, EXC_CHFRAME_AUTOPOS, bAutoPos );
     802           0 :     ::set_flag( maData.mnFlags, EXC_CHFRAME_AUTOSIZE, bAutoSize );
     803           0 : }
     804             : 
     805           0 : bool XclExpChFrame::IsDefault() const
     806             : {
     807           0 :     return IsDefaultFrameBase( GetFormatInfo( meObjType ).meDefFrameType );
     808             : }
     809             : 
     810           0 : bool XclExpChFrame::IsDeleteable() const
     811             : {
     812           0 :     return IsDefault() && GetFormatInfo( meObjType ).mbDeleteDefFrame;
     813             : }
     814             : 
     815           0 : void XclExpChFrame::Save( XclExpStream& rStrm )
     816             : {
     817           0 :     switch( meObjType )
     818             :     {
     819             :         // wall/floor frame without CHFRAME header record
     820             :         case EXC_CHOBJTYPE_WALL3D:
     821             :         case EXC_CHOBJTYPE_FLOOR3D:
     822           0 :             WriteFrameRecords( rStrm );
     823           0 :         break;
     824             :         default:
     825           0 :             XclExpChGroupBase::Save( rStrm );
     826             :     }
     827           0 : }
     828             : 
     829           0 : void XclExpChFrame::WriteSubRecords( XclExpStream& rStrm )
     830             : {
     831           0 :     WriteFrameRecords( rStrm );
     832           0 : }
     833             : 
     834           0 : void XclExpChFrame::WriteBody( XclExpStream& rStrm )
     835             : {
     836           0 :     rStrm << maData.mnFormat << maData.mnFlags;
     837           0 : }
     838             : 
     839             : namespace {
     840             : 
     841             : /** Creates a CHFRAME record from the passed property set. */
     842           0 : XclExpChFrameRef lclCreateFrame( const XclExpChRoot& rRoot,
     843             :         const ScfPropertySet& rPropSet, XclChObjectType eObjType )
     844             : {
     845           0 :     XclExpChFrameRef xFrame( new XclExpChFrame( rRoot, eObjType ) );
     846           0 :     xFrame->Convert( rPropSet );
     847           0 :     if( xFrame->IsDeleteable() )
     848           0 :         xFrame.reset();
     849           0 :     return xFrame;
     850             : }
     851             : 
     852             : } // namespace
     853             : 
     854             : // Source links ===============================================================
     855             : 
     856             : namespace {
     857             : 
     858           0 : void lclAddDoubleRefData(
     859             :         ScTokenArray& orArray, const FormulaToken& rToken,
     860             :         SCsTAB nScTab1, SCsCOL nScCol1, SCsROW nScRow1,
     861             :         SCsTAB nScTab2, SCsCOL nScCol2, SCsROW nScRow2 )
     862             : {
     863             :     ScComplexRefData aComplexRef;
     864           0 :     aComplexRef.InitRange(ScRange(nScCol1,nScRow1,nScTab1,nScCol2,nScRow2,nScTab2));
     865           0 :     aComplexRef.Ref1.SetFlag3D( true );
     866             : 
     867           0 :     if( orArray.GetLen() > 0 )
     868           0 :         orArray.AddOpCode( ocUnion );
     869             : 
     870             :     OSL_ENSURE( (rToken.GetType() == ::formula::svDoubleRef) || (rToken.GetType() == ::formula::svExternalDoubleRef),
     871             :         "lclAddDoubleRefData - double reference token expected");
     872           0 :     if( rToken.GetType() == ::formula::svExternalDoubleRef )
     873             :         orArray.AddExternalDoubleReference(
     874           0 :             rToken.GetIndex(), rToken.GetString().getString(), aComplexRef);
     875             :     else
     876           0 :         orArray.AddDoubleReference( aComplexRef );
     877           0 : }
     878             : 
     879             : } // namespace
     880             : 
     881           0 : XclExpChSourceLink::XclExpChSourceLink( const XclExpChRoot& rRoot, sal_uInt8 nDestType ) :
     882             :     XclExpRecord( EXC_ID_CHSOURCELINK ),
     883           0 :     XclExpChRoot( rRoot )
     884             : {
     885           0 :     maData.mnDestType = nDestType;
     886           0 :     maData.mnLinkType = EXC_CHSRCLINK_DIRECTLY;
     887           0 : }
     888             : 
     889           0 : sal_uInt16 XclExpChSourceLink::ConvertDataSequence( Reference< XDataSequence > xDataSeq, bool bSplitToColumns, sal_uInt16 nDefCount )
     890             : {
     891           0 :     mxLinkFmla.reset();
     892           0 :     maData.mnLinkType = EXC_CHSRCLINK_DEFAULT;
     893             : 
     894           0 :     if( !xDataSeq.is() )
     895           0 :         return nDefCount;
     896             : 
     897             :     // Compile the range representation string into token array.  Note that the
     898             :     // source range text depends on the current grammar.
     899           0 :     OUString aRangeRepr = xDataSeq->getSourceRangeRepresentation();
     900           0 :     ScCompiler aComp( GetDocPtr(), ScAddress() );
     901           0 :     aComp.SetGrammar( GetDocPtr()->GetGrammar() );
     902           0 :     boost::scoped_ptr<ScTokenArray> pArray(aComp.CompileString(aRangeRepr));
     903           0 :     if( !pArray )
     904           0 :         return nDefCount;
     905             : 
     906           0 :     ScTokenArray aArray;
     907           0 :     sal_uInt32 nValueCount = 0;
     908           0 :     pArray->Reset();
     909           0 :     for( const FormulaToken* pToken = pArray->First(); pToken; pToken = pArray->Next() )
     910             :     {
     911           0 :         switch( pToken->GetType() )
     912             :         {
     913             :             case ::formula::svSingleRef:
     914             :             case ::formula::svExternalSingleRef:
     915             :                 // for a single ref token, just add it to the new token array as is
     916           0 :                 if( aArray.GetLen() > 0 )
     917           0 :                     aArray.AddOpCode( ocUnion );
     918           0 :                 aArray.AddToken( *pToken );
     919           0 :                 ++nValueCount;
     920           0 :             break;
     921             : 
     922             :             case ::formula::svDoubleRef:
     923             :             case ::formula::svExternalDoubleRef:
     924             :             {
     925             :                 // split 3-dimensional ranges into single sheets
     926           0 :                 const ScComplexRefData& rComplexRef = static_cast< const ScToken* >( pToken )->GetDoubleRef();
     927           0 :                 ScAddress aAbs1 = rComplexRef.Ref1.toAbs(ScAddress());
     928           0 :                 ScAddress aAbs2 = rComplexRef.Ref2.toAbs(ScAddress());
     929           0 :                 for (SCsTAB nScTab = aAbs1.Tab(); nScTab <= aAbs2.Tab(); ++nScTab)
     930             :                 {
     931             :                     // split 2-dimensional ranges into single columns
     932           0 :                     if (bSplitToColumns && (aAbs1.Col() < aAbs2.Col()) && (aAbs1.Row() < aAbs2.Row()))
     933           0 :                         for (SCCOL nScCol = aAbs1.Col(); nScCol <= aAbs2.Col(); ++nScCol)
     934           0 :                             lclAddDoubleRefData(aArray, *pToken, nScTab, nScCol, aAbs1.Row(), nScTab, nScCol, aAbs2.Row());
     935             :                     else
     936           0 :                         lclAddDoubleRefData(aArray, *pToken, nScTab, aAbs1.Col(), aAbs1.Row(), nScTab, aAbs2.Col(), aAbs2.Row());
     937             :                 }
     938           0 :                 sal_uInt32 nTabs = static_cast<sal_uInt32>(aAbs2.Tab() - aAbs1.Tab() + 1);
     939           0 :                 sal_uInt32 nCols = static_cast<sal_uInt32>(aAbs2.Col() - aAbs1.Col() + 1);
     940           0 :                 sal_uInt32 nRows = static_cast<sal_uInt32>(aAbs2.Row() - aAbs1.Row() + 1);
     941           0 :                 nValueCount += nCols * nRows * nTabs;
     942             :             }
     943           0 :             break;
     944             : 
     945             :             default:;
     946             :         }
     947             :     }
     948             : 
     949           0 :     const ScAddress aBaseCell;
     950           0 :     mxLinkFmla = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CHART, aArray, &aBaseCell );
     951           0 :     maData.mnLinkType = EXC_CHSRCLINK_WORKSHEET;
     952           0 :     return ulimit_cast< sal_uInt16 >( nValueCount, EXC_CHDATAFORMAT_MAXPOINTCOUNT );
     953             : }
     954             : 
     955           0 : void XclExpChSourceLink::ConvertString( const OUString& aString )
     956             : {
     957           0 :     mxString = XclExpStringHelper::CreateString( GetRoot(), aString, EXC_STR_FORCEUNICODE | EXC_STR_8BITLENGTH | EXC_STR_SEPARATEFORMATS );
     958           0 : }
     959             : 
     960           0 : sal_uInt16 XclExpChSourceLink::ConvertStringSequence( const Sequence< Reference< XFormattedString > >& rStringSeq )
     961             : {
     962           0 :     mxString.reset();
     963           0 :     sal_uInt16 nFontIdx = EXC_FONT_APP;
     964           0 :     if( rStringSeq.hasElements() )
     965             :     {
     966           0 :         mxString = XclExpStringHelper::CreateString( GetRoot(), OUString(), EXC_STR_FORCEUNICODE | EXC_STR_8BITLENGTH | EXC_STR_SEPARATEFORMATS );
     967           0 :         Reference< XBreakIterator > xBreakIt = GetDoc().GetBreakIterator();
     968             :         namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
     969             : 
     970             :         // convert all formatted string entries from the sequence
     971           0 :         const Reference< XFormattedString >* pBeg = rStringSeq.getConstArray();
     972           0 :         const Reference< XFormattedString >* pEnd = pBeg + rStringSeq.getLength();
     973           0 :         for( const Reference< XFormattedString >* pIt = pBeg; pIt != pEnd; ++pIt )
     974             :         {
     975           0 :             if( pIt->is() )
     976             :             {
     977           0 :                 sal_uInt16 nWstrnFontIdx = EXC_FONT_NOTFOUND;
     978           0 :                 sal_uInt16 nAsianFontIdx = EXC_FONT_NOTFOUND;
     979           0 :                 sal_uInt16 nCmplxFontIdx = EXC_FONT_NOTFOUND;
     980           0 :                 OUString aText = (*pIt)->getString();
     981           0 :                 ScfPropertySet aStrProp( *pIt );
     982             : 
     983             :                 // #i63255# get script type for leading weak characters
     984           0 :                 sal_Int16 nLastScript = XclExpStringHelper::GetLeadingScriptType( GetRoot(), aText );
     985             : 
     986             :                 // process all script portions
     987           0 :                 sal_Int32 nPortionPos = 0;
     988           0 :                 sal_Int32 nTextLen = aText.getLength();
     989           0 :                 while( nPortionPos < nTextLen )
     990             :                 {
     991             :                     // get script type and end position of next script portion
     992           0 :                     sal_Int16 nScript = xBreakIt->getScriptType( aText, nPortionPos );
     993           0 :                     sal_Int32 nPortionEnd = xBreakIt->endOfScript( aText, nPortionPos, nScript );
     994             : 
     995             :                     // reuse previous script for following weak portions
     996           0 :                     if( nScript == ApiScriptType::WEAK )
     997           0 :                         nScript = nLastScript;
     998             : 
     999             :                     // Excel start position of this portion
    1000           0 :                     sal_uInt16 nXclPortionStart = mxString->Len();
    1001             :                     // add portion text to Excel string
    1002           0 :                     XclExpStringHelper::AppendString( *mxString, GetRoot(), aText.copy( nPortionPos, nPortionEnd - nPortionPos ) );
    1003           0 :                     if( nXclPortionStart < mxString->Len() )
    1004             :                     {
    1005             :                         // find font index variable dependent on script type
    1006             :                         sal_uInt16& rnFontIdx = (nScript == ApiScriptType::COMPLEX) ? nCmplxFontIdx :
    1007           0 :                             ((nScript == ApiScriptType::ASIAN) ? nAsianFontIdx : nWstrnFontIdx);
    1008             : 
    1009             :                         // insert font into buffer (if not yet done)
    1010           0 :                         if( rnFontIdx == EXC_FONT_NOTFOUND )
    1011           0 :                             rnFontIdx = ConvertFont( aStrProp, nScript );
    1012             : 
    1013             :                         // insert font index into format run vector
    1014           0 :                         mxString->AppendFormat( nXclPortionStart, rnFontIdx );
    1015             :                     }
    1016             : 
    1017             :                     // go to next script portion
    1018           0 :                     nLastScript = nScript;
    1019           0 :                     nPortionPos = nPortionEnd;
    1020           0 :                 }
    1021             :             }
    1022             :         }
    1023           0 :         if( !mxString->IsEmpty() )
    1024             :         {
    1025             :             // get leading font index
    1026           0 :             const XclFormatRunVec& rFormats = mxString->GetFormats();
    1027             :             OSL_ENSURE( !rFormats.empty() && (rFormats.front().mnChar == 0),
    1028             :                 "XclExpChSourceLink::ConvertStringSequenc - missing leading format" );
    1029             :             // remove leading format run, if entire string is equally formatted
    1030           0 :             if( rFormats.size() == 1 )
    1031           0 :                 nFontIdx = mxString->RemoveLeadingFont();
    1032           0 :             else if( !rFormats.empty() )
    1033           0 :                 nFontIdx = rFormats.front().mnFontIdx;
    1034             :             // add trailing format run, if string is rich-formatted
    1035           0 :             if( mxString->IsRich() )
    1036           0 :                 mxString->AppendTrailingFormat( EXC_FONT_APP );
    1037           0 :         }
    1038             :     }
    1039           0 :     return nFontIdx;
    1040             : }
    1041             : 
    1042           0 : void XclExpChSourceLink::ConvertNumFmt( const ScfPropertySet& rPropSet, bool bPercent )
    1043             : {
    1044           0 :     sal_Int32 nApiNumFmt = 0;
    1045           0 :     if( bPercent ? rPropSet.GetProperty( nApiNumFmt, EXC_CHPROP_PERCENTAGENUMFMT ) : rPropSet.GetProperty( nApiNumFmt, EXC_CHPROP_NUMBERFORMAT ) )
    1046             :     {
    1047           0 :         ::set_flag( maData.mnFlags, EXC_CHSRCLINK_NUMFMT );
    1048           0 :         maData.mnNumFmtIdx = GetNumFmtBuffer().Insert( static_cast< sal_uInt32 >( nApiNumFmt ) );
    1049             :     }
    1050           0 : }
    1051             : 
    1052           0 : void XclExpChSourceLink::AppendString( const OUString& rStr )
    1053             : {
    1054           0 :     if (!mxString)
    1055           0 :         return;
    1056           0 :     XclExpStringHelper::AppendString( *mxString, GetRoot(), rStr );
    1057             : }
    1058             : 
    1059           0 : void XclExpChSourceLink::Save( XclExpStream& rStrm )
    1060             : {
    1061             :     // CHFORMATRUNS record
    1062           0 :     if( mxString && mxString->IsRich() )
    1063             :     {
    1064           0 :         sal_Size nRecSize = (1 + mxString->GetFormatsCount()) * ((GetBiff() == EXC_BIFF8) ? 2 : 1);
    1065           0 :         rStrm.StartRecord( EXC_ID_CHFORMATRUNS, nRecSize );
    1066           0 :         mxString->WriteFormats( rStrm, true );
    1067           0 :         rStrm.EndRecord();
    1068             :     }
    1069             :     // CHSOURCELINK record
    1070           0 :     XclExpRecord::Save( rStrm );
    1071             :     // CHSTRING record
    1072           0 :     if( mxString && !mxString->IsEmpty() )
    1073             :     {
    1074           0 :         rStrm.StartRecord( EXC_ID_CHSTRING, 2 + mxString->GetSize() );
    1075           0 :         rStrm << sal_uInt16( 0 ) << *mxString;
    1076           0 :         rStrm.EndRecord();
    1077             :     }
    1078           0 : }
    1079             : 
    1080           0 : void XclExpChSourceLink::WriteBody( XclExpStream& rStrm )
    1081             : {
    1082           0 :     rStrm   << maData.mnDestType
    1083           0 :             << maData.mnLinkType
    1084           0 :             << maData.mnFlags
    1085           0 :             << maData.mnNumFmtIdx
    1086           0 :             << mxLinkFmla;
    1087           0 : }
    1088             : 
    1089             : // Text =======================================================================
    1090             : 
    1091           0 : XclExpChFont::XclExpChFont( sal_uInt16 nFontIdx ) :
    1092           0 :     XclExpUInt16Record( EXC_ID_CHFONT, nFontIdx )
    1093             : {
    1094           0 : }
    1095             : 
    1096           0 : XclExpChObjectLink::XclExpChObjectLink( sal_uInt16 nLinkTarget, const XclChDataPointPos& rPointPos ) :
    1097           0 :     XclExpRecord( EXC_ID_CHOBJECTLINK, 6 )
    1098             : {
    1099           0 :     maData.mnTarget = nLinkTarget;
    1100           0 :     maData.maPointPos = rPointPos;
    1101           0 : }
    1102             : 
    1103           0 : void XclExpChObjectLink::WriteBody( XclExpStream& rStrm )
    1104             : {
    1105           0 :     rStrm << maData.mnTarget << maData.maPointPos.mnSeriesIdx << maData.maPointPos.mnPointIdx;
    1106           0 : }
    1107             : 
    1108           0 : XclExpChFrLabelProps::XclExpChFrLabelProps( const XclExpChRoot& rRoot ) :
    1109           0 :     XclExpChFutureRecordBase( rRoot, EXC_FUTUREREC_UNUSEDREF, EXC_ID_CHFRLABELPROPS, 4 )
    1110             : {
    1111           0 : }
    1112             : 
    1113           0 : void XclExpChFrLabelProps::Convert( const ScfPropertySet& rPropSet, bool bShowSeries,
    1114             :         bool bShowCateg, bool bShowValue, bool bShowPercent, bool bShowBubble )
    1115             : {
    1116             :     // label value flags
    1117           0 :     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWSERIES,  bShowSeries );
    1118           0 :     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWCATEG,   bShowCateg );
    1119           0 :     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWVALUE,   bShowValue );
    1120           0 :     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWPERCENT, bShowPercent );
    1121           0 :     ::set_flag( maData.mnFlags, EXC_CHFRLABELPROPS_SHOWBUBBLE,  bShowBubble );
    1122             : 
    1123             :     // label value separator
    1124           0 :     maData.maSeparator = rPropSet.GetStringProperty( EXC_CHPROP_LABELSEPARATOR );
    1125           0 :     if( maData.maSeparator.isEmpty() )
    1126           0 :         maData.maSeparator = OUString(' ');
    1127           0 : }
    1128             : 
    1129           0 : void XclExpChFrLabelProps::WriteBody( XclExpStream& rStrm )
    1130             : {
    1131           0 :     XclExpString aXclSep( maData.maSeparator, EXC_STR_FORCEUNICODE | EXC_STR_SMARTFLAGS );
    1132           0 :     rStrm << maData.mnFlags << aXclSep;
    1133           0 : }
    1134             : 
    1135           0 : XclExpChFontBase::~XclExpChFontBase()
    1136             : {
    1137           0 : }
    1138             : 
    1139           0 : void XclExpChFontBase::ConvertFontBase( const XclExpChRoot& rRoot, sal_uInt16 nFontIdx )
    1140             : {
    1141           0 :     if( const XclExpFont* pFont = rRoot.GetFontBuffer().GetFont( nFontIdx ) )
    1142             :     {
    1143           0 :         XclExpChFontRef xFont( new XclExpChFont( nFontIdx ) );
    1144           0 :         SetFont( xFont, pFont->GetFontData().maColor, pFont->GetFontColorId() );
    1145             :     }
    1146           0 : }
    1147             : 
    1148           0 : void XclExpChFontBase::ConvertFontBase( const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet )
    1149             : {
    1150           0 :     ConvertFontBase( rRoot, rRoot.ConvertFont( rPropSet, rRoot.GetDefApiScript() ) );
    1151           0 : }
    1152             : 
    1153           0 : void XclExpChFontBase::ConvertRotationBase(
    1154             :         const XclExpChRoot& rRoot, const ScfPropertySet& rPropSet, bool bSupportsStacked )
    1155             : {
    1156           0 :     sal_uInt16 nRotation = rRoot.GetChartPropSetHelper().ReadRotationProperties( rPropSet, bSupportsStacked );
    1157           0 :     SetRotation( nRotation );
    1158           0 : }
    1159             : 
    1160           0 : XclExpChText::XclExpChText( const XclExpChRoot& rRoot ) :
    1161           0 :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_TEXT, EXC_ID_CHTEXT, (rRoot.GetBiff() == EXC_BIFF8) ? 32 : 26 ),
    1162           0 :     mnTextColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
    1163             : {
    1164           0 : }
    1165             : 
    1166           0 : void XclExpChText::SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId )
    1167             : {
    1168           0 :     mxFont = xFont;
    1169           0 :     maData.maTextColor = rColor;
    1170           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOCOLOR, rColor == COL_AUTO );
    1171           0 :     mnTextColorId = nColorId;
    1172           0 : }
    1173             : 
    1174           0 : void XclExpChText::SetRotation( sal_uInt16 nRotation )
    1175             : {
    1176           0 :     maData.mnRotation = nRotation;
    1177           0 :     ::insert_value( maData.mnFlags, XclTools::GetXclOrientFromRot( nRotation ), 8, 3 );
    1178           0 : }
    1179             : 
    1180           0 : void XclExpChText::ConvertTitle( Reference< XTitle > xTitle, sal_uInt16 nTarget, const OUString* pSubTitle )
    1181             : {
    1182           0 :     switch( nTarget )
    1183             :     {
    1184           0 :         case EXC_CHOBJLINK_TITLE:   SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_TITLE );         break;
    1185           0 :         case EXC_CHOBJLINK_YAXIS:   SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 1 );  break;
    1186           0 :         case EXC_CHOBJLINK_XAXIS:   SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 0 );  break;
    1187           0 :         case EXC_CHOBJLINK_ZAXIS:   SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_AXISTITLE, 2 );  break;
    1188             :     }
    1189             : 
    1190           0 :     mxSrcLink.reset();
    1191           0 :     mxObjLink.reset( new XclExpChObjectLink( nTarget, XclChDataPointPos( 0, 0 ) ) );
    1192             : 
    1193           0 :     if( xTitle.is() )
    1194             :     {
    1195             :         // title frame formatting
    1196           0 :         ScfPropertySet aTitleProp( xTitle );
    1197           0 :         mxFrame = lclCreateFrame( GetChRoot(), aTitleProp, EXC_CHOBJTYPE_TEXT );
    1198             : 
    1199             :         // string sequence
    1200           0 :         mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
    1201           0 :         sal_uInt16 nFontIdx = mxSrcLink->ConvertStringSequence( xTitle->getText() );
    1202           0 :         if (pSubTitle)
    1203             :         {
    1204             :             // append subtitle as the 2nd line of the title.
    1205           0 :             OUString aSubTitle("\n");
    1206           0 :             aSubTitle += *pSubTitle;
    1207           0 :             mxSrcLink->AppendString(aSubTitle);
    1208             :         }
    1209             : 
    1210           0 :         ConvertFontBase( GetChRoot(), nFontIdx );
    1211             : 
    1212             :         // rotation
    1213           0 :         ConvertRotationBase( GetChRoot(), aTitleProp, true );
    1214             : 
    1215             :         // manual text position - only for main title
    1216           0 :         mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
    1217           0 :         if( nTarget == EXC_CHOBJLINK_TITLE )
    1218             :         {
    1219           0 :             Any aRelPos;
    1220           0 :             if( aTitleProp.GetAnyProperty( aRelPos, EXC_CHPROP_RELATIVEPOSITION ) && aRelPos.has< RelativePosition >() ) try
    1221             :             {
    1222             :                 // calculate absolute position for CHTEXT record
    1223           0 :                 Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
    1224           0 :                 Reference< XShape > xTitleShape( xChart1Doc->getTitle(), UNO_SET_THROW );
    1225           0 :                 ::com::sun::star::awt::Point aPos = xTitleShape->getPosition();
    1226           0 :                 ::com::sun::star::awt::Size aSize = xTitleShape->getSize();
    1227           0 :                 ::com::sun::star::awt::Rectangle aRect( aPos.X, aPos.Y, aSize.Width, aSize.Height );
    1228           0 :                 maData.maRect = CalcChartRectFromHmm( aRect );
    1229           0 :                 ::insert_value( maData.mnFlags2, EXC_CHTEXT_POS_MOVED, 0, 4 );
    1230             :                 // manual title position implies manual plot area
    1231           0 :                 GetChartData().SetManualPlotArea();
    1232             :                 // calculate the default title position in chart units
    1233           0 :                 sal_Int32 nDefPosX = ::std::max< sal_Int32 >( (EXC_CHART_TOTALUNITS - maData.maRect.mnWidth) / 2, 0 );
    1234           0 :                 sal_Int32 nDefPosY = 85;
    1235             :                 // set the position relative to the standard position
    1236           0 :                 XclChRectangle& rFrameRect = mxFramePos->GetFramePosData().maRect;
    1237           0 :                 rFrameRect.mnX = maData.maRect.mnX - nDefPosX;
    1238           0 :                 rFrameRect.mnY = maData.maRect.mnY - nDefPosY;
    1239             :             }
    1240           0 :             catch( Exception& )
    1241             :             {
    1242           0 :             }
    1243           0 :         }
    1244             :     }
    1245             :     else
    1246             :     {
    1247           0 :         ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED );
    1248             :     }
    1249           0 : }
    1250             : 
    1251           0 : void XclExpChText::ConvertLegend( const ScfPropertySet& rPropSet )
    1252             : {
    1253           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
    1254           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOGEN );
    1255           0 :     ConvertFontBase( GetChRoot(), rPropSet );
    1256           0 : }
    1257             : 
    1258           0 : bool XclExpChText::ConvertDataLabel( const ScfPropertySet& rPropSet,
    1259             :         const XclChTypeInfo& rTypeInfo, const XclChDataPointPos& rPointPos )
    1260             : {
    1261           0 :     SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_DATALABEL, rPointPos.mnPointIdx, rPointPos.mnSeriesIdx );
    1262             : 
    1263           0 :     cssc2::DataPointLabel aPointLabel;
    1264           0 :     if( !rPropSet.GetProperty( aPointLabel, EXC_CHPROP_LABEL ) )
    1265           0 :         return false;
    1266             : 
    1267             :     // percentage only allowed in pie and donut charts
    1268           0 :     bool bIsPie = rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE;
    1269             :     // bubble sizes only allowed in bubble charts
    1270           0 :     bool bIsBubble = rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES;
    1271             :     OSL_ENSURE( (GetBiff() == EXC_BIFF8) || !bIsBubble, "XclExpChText::ConvertDataLabel - bubble charts only in BIFF8" );
    1272             : 
    1273             :     // raw show flags
    1274           0 :     bool bShowValue   = !bIsBubble && aPointLabel.ShowNumber;       // Chart2 uses 'ShowNumber' for bubble size
    1275           0 :     bool bShowPercent = bIsPie && aPointLabel.ShowNumberInPercent;  // percentage only in pie/donut charts
    1276           0 :     bool bShowCateg   = aPointLabel.ShowCategoryName;
    1277           0 :     bool bShowBubble  = bIsBubble && aPointLabel.ShowNumber;        // Chart2 uses 'ShowNumber' for bubble size
    1278           0 :     bool bShowAny     = bShowValue || bShowPercent || bShowCateg || bShowBubble;
    1279             : 
    1280             :     // create the CHFRLABELPROPS record for extended settings in BIFF8
    1281           0 :     if( bShowAny && (GetBiff() == EXC_BIFF8) )
    1282             :     {
    1283           0 :         mxLabelProps.reset( new XclExpChFrLabelProps( GetChRoot() ) );
    1284           0 :         mxLabelProps->Convert( rPropSet, false, bShowCateg, bShowValue, bShowPercent, bShowBubble );
    1285             :     }
    1286             : 
    1287             :     // restrict to combinations allowed in CHTEXT
    1288           0 :     if( bShowPercent ) bShowValue = false;              // percent wins over value
    1289           0 :     if( bShowValue ) bShowCateg = false;                // value wins over category
    1290           0 :     if( bShowValue || bShowCateg ) bShowBubble = false; // value or category wins over bubble size
    1291             : 
    1292             :     // set all flags
    1293           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
    1294           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE, bShowValue );
    1295           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT, bShowPercent );
    1296           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG, bShowCateg );
    1297           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC, bShowPercent && bShowCateg );
    1298           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWBUBBLE, bShowBubble );
    1299           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL, bShowAny && aPointLabel.ShowLegendSymbol );
    1300           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_DELETED, !bShowAny );
    1301             : 
    1302           0 :     if( bShowAny )
    1303             :     {
    1304             :         // font settings
    1305           0 :         ConvertFontBase( GetChRoot(), rPropSet );
    1306           0 :         ConvertRotationBase( GetChRoot(), rPropSet, false );
    1307             :         // label placement
    1308           0 :         sal_Int32 nPlacement = 0;
    1309           0 :         sal_uInt16 nLabelPos = EXC_CHTEXT_POS_AUTO;
    1310           0 :         if( rPropSet.GetProperty( nPlacement, EXC_CHPROP_LABELPLACEMENT ) )
    1311             :         {
    1312             :             using namespace cssc::DataLabelPlacement;
    1313           0 :             if( nPlacement == rTypeInfo.mnDefaultLabelPos )
    1314             :             {
    1315           0 :                 nLabelPos = EXC_CHTEXT_POS_DEFAULT;
    1316             :             }
    1317           0 :             else switch( nPlacement )
    1318             :             {
    1319           0 :                 case AVOID_OVERLAP:     nLabelPos = EXC_CHTEXT_POS_AUTO;    break;
    1320           0 :                 case CENTER:            nLabelPos = EXC_CHTEXT_POS_CENTER;  break;
    1321           0 :                 case TOP:               nLabelPos = EXC_CHTEXT_POS_ABOVE;   break;
    1322           0 :                 case TOP_LEFT:          nLabelPos = EXC_CHTEXT_POS_LEFT;    break;
    1323           0 :                 case LEFT:              nLabelPos = EXC_CHTEXT_POS_LEFT;    break;
    1324           0 :                 case BOTTOM_LEFT:       nLabelPos = EXC_CHTEXT_POS_LEFT;    break;
    1325           0 :                 case BOTTOM:            nLabelPos = EXC_CHTEXT_POS_BELOW;   break;
    1326           0 :                 case BOTTOM_RIGHT:      nLabelPos = EXC_CHTEXT_POS_RIGHT;   break;
    1327           0 :                 case RIGHT:             nLabelPos = EXC_CHTEXT_POS_RIGHT;   break;
    1328           0 :                 case TOP_RIGHT:         nLabelPos = EXC_CHTEXT_POS_RIGHT;   break;
    1329           0 :                 case INSIDE:            nLabelPos = EXC_CHTEXT_POS_INSIDE;  break;
    1330           0 :                 case OUTSIDE:           nLabelPos = EXC_CHTEXT_POS_OUTSIDE; break;
    1331           0 :                 case NEAR_ORIGIN:       nLabelPos = EXC_CHTEXT_POS_AXIS;    break;
    1332             :                 default:                OSL_FAIL( "XclExpChText::ConvertDataLabel - unknown label placement type" );
    1333             :             }
    1334             :         }
    1335           0 :         ::insert_value( maData.mnFlags2, nLabelPos, 0, 4 );
    1336             :         // source link (contains number format)
    1337           0 :         mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
    1338           0 :         if( bShowValue || bShowPercent )
    1339             :             // percentage format wins over value format
    1340           0 :             mxSrcLink->ConvertNumFmt( rPropSet, bShowPercent );
    1341             :         // object link
    1342           0 :         mxObjLink.reset( new XclExpChObjectLink( EXC_CHOBJLINK_DATA, rPointPos ) );
    1343             :     }
    1344             : 
    1345             :     /*  Return true to indicate valid label settings:
    1346             :         - for existing labels at entire series
    1347             :         - for any settings at single data point (to be able to delete a point label) */
    1348           0 :     return bShowAny || (rPointPos.mnPointIdx != EXC_CHDATAFORMAT_ALLPOINTS);
    1349             : }
    1350             : 
    1351           0 : void XclExpChText::ConvertTrendLineEquation( const ScfPropertySet& rPropSet, const XclChDataPointPos& rPointPos )
    1352             : {
    1353             :     // required flags
    1354           0 :     ::set_flag( maData.mnFlags, EXC_CHTEXT_AUTOTEXT );
    1355           0 :     if( GetBiff() == EXC_BIFF8 )
    1356           0 :         ::set_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG ); // must set this to make equation visible in Excel
    1357             :     // frame formatting
    1358           0 :     mxFrame = lclCreateFrame( GetChRoot(), rPropSet, EXC_CHOBJTYPE_TEXT );
    1359             :     // font settings
    1360           0 :     maData.mnHAlign = EXC_CHTEXT_ALIGN_TOPLEFT;
    1361           0 :     maData.mnVAlign = EXC_CHTEXT_ALIGN_TOPLEFT;
    1362           0 :     ConvertFontBase( GetChRoot(), rPropSet );
    1363             :     // source link (contains number format)
    1364           0 :     mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
    1365           0 :     mxSrcLink->ConvertNumFmt( rPropSet, false );
    1366             :     // object link
    1367           0 :     mxObjLink.reset( new XclExpChObjectLink( EXC_CHOBJLINK_DATA, rPointPos ) );
    1368           0 : }
    1369             : 
    1370           0 : sal_uInt16 XclExpChText::GetAttLabelFlags() const
    1371             : {
    1372           0 :     sal_uInt16 nFlags = 0;
    1373           0 :     ::set_flag( nFlags, EXC_CHATTLABEL_SHOWVALUE,     ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWVALUE ) );
    1374           0 :     ::set_flag( nFlags, EXC_CHATTLABEL_SHOWPERCENT,   ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWPERCENT ) );
    1375           0 :     ::set_flag( nFlags, EXC_CHATTLABEL_SHOWCATEGPERC, ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEGPERC ) );
    1376           0 :     ::set_flag( nFlags, EXC_CHATTLABEL_SHOWCATEG,     ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWCATEG ) );
    1377           0 :     return nFlags;
    1378             : }
    1379             : 
    1380           0 : void XclExpChText::WriteSubRecords( XclExpStream& rStrm )
    1381             : {
    1382             :     // CHFRAMEPOS record
    1383           0 :     lclSaveRecord( rStrm, mxFramePos );
    1384             :     // CHFONT record
    1385           0 :     lclSaveRecord( rStrm, mxFont );
    1386             :     // CHSOURCELINK group
    1387           0 :     lclSaveRecord( rStrm, mxSrcLink );
    1388             :     // CHFRAME group
    1389           0 :     lclSaveRecord( rStrm, mxFrame );
    1390             :     // CHOBJECTLINK record
    1391           0 :     lclSaveRecord( rStrm, mxObjLink );
    1392             :     // CHFRLABELPROPS record
    1393           0 :     lclSaveRecord( rStrm, mxLabelProps );
    1394           0 : }
    1395             : 
    1396           0 : void XclExpChText::WriteBody( XclExpStream& rStrm )
    1397             : {
    1398           0 :     rStrm   << maData.mnHAlign
    1399           0 :             << maData.mnVAlign
    1400           0 :             << maData.mnBackMode
    1401           0 :             << maData.maTextColor
    1402           0 :             << maData.maRect
    1403           0 :             << maData.mnFlags;
    1404             : 
    1405           0 :     if( GetBiff() == EXC_BIFF8 )
    1406             :     {
    1407           0 :         rStrm   << GetPalette().GetColorIndex( mnTextColorId )
    1408           0 :                 << maData.mnFlags2
    1409           0 :                 << maData.mnRotation;
    1410             :     }
    1411           0 : }
    1412             : 
    1413             : namespace {
    1414             : 
    1415             : /** Creates and returns an Excel text object from the passed title. */
    1416           0 : XclExpChTextRef lclCreateTitle( const XclExpChRoot& rRoot, Reference< XTitled > xTitled, sal_uInt16 nTarget,
    1417             :                                 const OUString* pSubTitle = NULL )
    1418             : {
    1419           0 :     Reference< XTitle > xTitle;
    1420           0 :     if( xTitled.is() )
    1421           0 :         xTitle = xTitled->getTitleObject();
    1422             : 
    1423           0 :     XclExpChTextRef xText( new XclExpChText( rRoot ) );
    1424           0 :     xText->ConvertTitle( xTitle, nTarget, pSubTitle );
    1425             :     /*  Do not delete the CHTEXT group for the main title. A missing CHTEXT
    1426             :         will be interpreted as auto-generated title showing the series title in
    1427             :         charts that contain exactly one data series. */
    1428           0 :     if( (nTarget != EXC_CHOBJLINK_TITLE) && !xText->HasString() )
    1429           0 :         xText.reset();
    1430             : 
    1431           0 :     return xText;
    1432             : }
    1433             : 
    1434             : }
    1435             : 
    1436             : // Data series ================================================================
    1437             : 
    1438           0 : XclExpChMarkerFormat::XclExpChMarkerFormat( const XclExpChRoot& rRoot ) :
    1439           0 :     XclExpRecord( EXC_ID_CHMARKERFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 20 : 12 ),
    1440           0 :     mnLineColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) ),
    1441           0 :     mnFillColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWBACK ) )
    1442             : {
    1443           0 : }
    1444             : 
    1445           0 : void XclExpChMarkerFormat::Convert( const XclExpChRoot& rRoot,
    1446             :         const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
    1447             : {
    1448           0 :     rRoot.GetChartPropSetHelper().ReadMarkerProperties( maData, rPropSet, nFormatIdx );
    1449             :     /*  Set marker line/fill color to series line color.
    1450             :         TODO: remove this if OOChart supports own colors in markers. */
    1451           0 :     Color aLineColor;
    1452           0 :     if( rPropSet.GetColorProperty( aLineColor, EXC_CHPROP_COLOR ) )
    1453           0 :         maData.maLineColor = maData.maFillColor = aLineColor;
    1454             :     // register colors in palette
    1455           0 :     RegisterColors( rRoot );
    1456           0 : }
    1457             : 
    1458           0 : void XclExpChMarkerFormat::ConvertStockSymbol( const XclExpChRoot& rRoot,
    1459             :         const ScfPropertySet& rPropSet, bool bCloseSymbol )
    1460             : {
    1461             :     // clear the automatic flag
    1462           0 :     ::set_flag( maData.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
    1463             :     // symbol type and color
    1464           0 :     if( bCloseSymbol )
    1465             :     {
    1466             :         // set symbol type for the 'close' data series
    1467           0 :         maData.mnMarkerType = EXC_CHMARKERFORMAT_DOWJ;
    1468           0 :         maData.mnMarkerSize = EXC_CHMARKERFORMAT_DOUBLESIZE;
    1469             :         // set symbol line/fill color to series line color
    1470           0 :         Color aLineColor;
    1471           0 :         if( rPropSet.GetColorProperty( aLineColor, EXC_CHPROP_COLOR ) )
    1472             :         {
    1473           0 :             maData.maLineColor = maData.maFillColor = aLineColor;
    1474           0 :             RegisterColors( rRoot );
    1475             :         }
    1476             :     }
    1477             :     else
    1478             :     {
    1479             :         // set invisible symbol
    1480           0 :         maData.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
    1481             :     }
    1482           0 : }
    1483             : 
    1484           0 : void XclExpChMarkerFormat::RegisterColors( const XclExpChRoot& rRoot )
    1485             : {
    1486           0 :     if( HasMarker() )
    1487             :     {
    1488           0 :         if( HasLineColor() )
    1489           0 :             mnLineColorId = rRoot.GetPalette().InsertColor( maData.maLineColor, EXC_COLOR_CHARTLINE );
    1490           0 :         if( HasFillColor() )
    1491           0 :             mnFillColorId = rRoot.GetPalette().InsertColor( maData.maFillColor, EXC_COLOR_CHARTAREA );
    1492             :     }
    1493           0 : }
    1494             : 
    1495           0 : void XclExpChMarkerFormat::WriteBody( XclExpStream& rStrm )
    1496             : {
    1497           0 :     rStrm << maData.maLineColor << maData.maFillColor << maData.mnMarkerType << maData.mnFlags;
    1498           0 :     if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
    1499             :     {
    1500           0 :         const XclExpPalette& rPal = rStrm.GetRoot().GetPalette();
    1501           0 :         rStrm << rPal.GetColorIndex( mnLineColorId ) << rPal.GetColorIndex( mnFillColorId ) << maData.mnMarkerSize;
    1502             :     }
    1503           0 : }
    1504             : 
    1505           0 : XclExpChPieFormat::XclExpChPieFormat() :
    1506           0 :     XclExpUInt16Record( EXC_ID_CHPIEFORMAT, 0 )
    1507             : {
    1508           0 : }
    1509             : 
    1510           0 : void XclExpChPieFormat::Convert( const ScfPropertySet& rPropSet )
    1511             : {
    1512           0 :     double fApiDist(0.0);
    1513           0 :     if( rPropSet.GetProperty( fApiDist, EXC_CHPROP_OFFSET ) )
    1514           0 :         SetValue( limit_cast< sal_uInt16 >( fApiDist * 100.0, 0, 100 ) );
    1515           0 : }
    1516             : 
    1517           0 : XclExpCh3dDataFormat::XclExpCh3dDataFormat() :
    1518           0 :     XclExpRecord( EXC_ID_CH3DDATAFORMAT, 2 )
    1519             : {
    1520           0 : }
    1521             : 
    1522           0 : void XclExpCh3dDataFormat::Convert( const ScfPropertySet& rPropSet )
    1523             : {
    1524           0 :     sal_Int32 nApiType(0);
    1525           0 :     if( rPropSet.GetProperty( nApiType, EXC_CHPROP_GEOMETRY3D ) )
    1526             :     {
    1527             :         using namespace cssc2::DataPointGeometry3D;
    1528           0 :         switch( nApiType )
    1529             :         {
    1530             :             case CUBOID:
    1531           0 :                 maData.mnBase = EXC_CH3DDATAFORMAT_RECT;
    1532           0 :                 maData.mnTop = EXC_CH3DDATAFORMAT_STRAIGHT;
    1533           0 :             break;
    1534             :             case PYRAMID:
    1535           0 :                 maData.mnBase = EXC_CH3DDATAFORMAT_RECT;
    1536           0 :                 maData.mnTop = EXC_CH3DDATAFORMAT_SHARP;
    1537           0 :             break;
    1538             :             case CYLINDER:
    1539           0 :                 maData.mnBase = EXC_CH3DDATAFORMAT_CIRC;
    1540           0 :                 maData.mnTop = EXC_CH3DDATAFORMAT_STRAIGHT;
    1541           0 :             break;
    1542             :             case CONE:
    1543           0 :                 maData.mnBase = EXC_CH3DDATAFORMAT_CIRC;
    1544           0 :                 maData.mnTop = EXC_CH3DDATAFORMAT_SHARP;
    1545           0 :             break;
    1546             :             default:
    1547             :                 OSL_FAIL( "XclExpCh3dDataFormat::Convert - unknown 3D bar format" );
    1548             :         }
    1549             :     }
    1550           0 : }
    1551             : 
    1552           0 : void XclExpCh3dDataFormat::WriteBody( XclExpStream& rStrm )
    1553             : {
    1554           0 :     rStrm << maData.mnBase << maData.mnTop;
    1555           0 : }
    1556             : 
    1557           0 : XclExpChAttachedLabel::XclExpChAttachedLabel( sal_uInt16 nFlags ) :
    1558           0 :     XclExpUInt16Record( EXC_ID_CHATTACHEDLABEL, nFlags )
    1559             : {
    1560           0 : }
    1561             : 
    1562           0 : XclExpChDataFormat::XclExpChDataFormat( const XclExpChRoot& rRoot,
    1563             :         const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx ) :
    1564           0 :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_DATAFORMAT, EXC_ID_CHDATAFORMAT, 8 )
    1565             : {
    1566           0 :     maData.maPointPos = rPointPos;
    1567           0 :     maData.mnFormatIdx = nFormatIdx;
    1568           0 : }
    1569             : 
    1570           0 : void XclExpChDataFormat::ConvertDataSeries( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo )
    1571             : {
    1572             :     // line and area formatting
    1573           0 :     ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType() );
    1574             : 
    1575             :     // data point symbols
    1576           0 :     bool bIsFrame = rTypeInfo.IsSeriesFrameFormat();
    1577           0 :     if( !bIsFrame )
    1578             :     {
    1579           0 :         mxMarkerFmt.reset( new XclExpChMarkerFormat( GetChRoot() ) );
    1580           0 :         mxMarkerFmt->Convert( GetChRoot(), rPropSet, maData.mnFormatIdx );
    1581             :     }
    1582             : 
    1583             :     // pie segments
    1584           0 :     if( rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE )
    1585             :     {
    1586           0 :         mxPieFmt.reset( new XclExpChPieFormat );
    1587           0 :         mxPieFmt->Convert( rPropSet );
    1588             :     }
    1589             : 
    1590             :     // 3D bars (only allowed for entire series in BIFF8)
    1591           0 :     if( IsSeriesFormat() && (GetBiff() == EXC_BIFF8) && rTypeInfo.mb3dChart && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR) )
    1592             :     {
    1593           0 :         mx3dDataFmt.reset( new XclExpCh3dDataFormat );
    1594           0 :         mx3dDataFmt->Convert( rPropSet );
    1595             :     }
    1596             : 
    1597             :     // spline
    1598           0 :     if( IsSeriesFormat() && rTypeInfo.mbSpline && !bIsFrame )
    1599           0 :         mxSeriesFmt.reset( new XclExpUInt16Record( EXC_ID_CHSERIESFORMAT, EXC_CHSERIESFORMAT_SMOOTHED ) );
    1600             : 
    1601             :     // data point labels
    1602           0 :     XclExpChTextRef xLabel( new XclExpChText( GetChRoot() ) );
    1603           0 :     if( xLabel->ConvertDataLabel( rPropSet, rTypeInfo, maData.maPointPos ) )
    1604             :     {
    1605             :         // CHTEXT groups for data labels are stored in global CHCHART group
    1606           0 :         GetChartData().SetDataLabel( xLabel );
    1607           0 :         mxAttLabel.reset( new XclExpChAttachedLabel( xLabel->GetAttLabelFlags() ) );
    1608           0 :     }
    1609           0 : }
    1610             : 
    1611           0 : void XclExpChDataFormat::ConvertStockSeries( const ScfPropertySet& rPropSet, bool bCloseSymbol )
    1612             : {
    1613             :     // set line format to invisible
    1614           0 :     SetDefaultFrameBase( GetChRoot(), EXC_CHFRAMETYPE_INVISIBLE, false );
    1615             :     // set symbols to invisible or to 'close' series symbol
    1616           0 :     mxMarkerFmt.reset( new XclExpChMarkerFormat( GetChRoot() ) );
    1617           0 :     mxMarkerFmt->ConvertStockSymbol( GetChRoot(), rPropSet, bCloseSymbol );
    1618           0 : }
    1619             : 
    1620           0 : void XclExpChDataFormat::ConvertLine( const ScfPropertySet& rPropSet, XclChObjectType eObjType )
    1621             : {
    1622           0 :     ConvertFrameBase( GetChRoot(), rPropSet, eObjType );
    1623           0 : }
    1624             : 
    1625           0 : void XclExpChDataFormat::WriteSubRecords( XclExpStream& rStrm )
    1626             : {
    1627           0 :     lclSaveRecord( rStrm, mx3dDataFmt );
    1628           0 :     WriteFrameRecords( rStrm );
    1629           0 :     lclSaveRecord( rStrm, mxPieFmt );
    1630           0 :     lclSaveRecord( rStrm, mxMarkerFmt );
    1631           0 :     lclSaveRecord( rStrm, mxSeriesFmt );
    1632           0 :     lclSaveRecord( rStrm, mxAttLabel );
    1633           0 : }
    1634             : 
    1635           0 : void XclExpChDataFormat::WriteBody( XclExpStream& rStrm )
    1636             : {
    1637           0 :     rStrm   << maData.maPointPos.mnPointIdx
    1638           0 :             << maData.maPointPos.mnSeriesIdx
    1639           0 :             << maData.mnFormatIdx
    1640           0 :             << maData.mnFlags;
    1641           0 : }
    1642             : 
    1643           0 : XclExpChSerTrendLine::XclExpChSerTrendLine( const XclExpChRoot& rRoot ) :
    1644             :     XclExpRecord( EXC_ID_CHSERTRENDLINE, 28 ),
    1645           0 :     XclExpChRoot( rRoot )
    1646             : {
    1647           0 : }
    1648             : 
    1649           0 : bool XclExpChSerTrendLine::Convert( Reference< XRegressionCurve > xRegCurve, sal_uInt16 nSeriesIdx )
    1650             : {
    1651           0 :     if( !xRegCurve.is() )
    1652           0 :         return false;
    1653             : 
    1654             :     // trend line type
    1655           0 :     ScfPropertySet aCurveProp( xRegCurve );
    1656             : 
    1657           0 :     OUString aService = aCurveProp.GetServiceName();
    1658           0 :     if( aService == "com.sun.star.chart2.LinearRegressionCurve" )
    1659             :     {
    1660           0 :         maData.mnLineType = EXC_CHSERTREND_POLYNOMIAL;
    1661           0 :         maData.mnOrder = 1;
    1662             :     }
    1663           0 :     else if( aService == "com.sun.star.chart2.ExponentialRegressionCurve" )
    1664             :     {
    1665           0 :         maData.mnLineType = EXC_CHSERTREND_EXPONENTIAL;
    1666             :     }
    1667           0 :     else if( aService == "com.sun.star.chart2.LogarithmicRegressionCurve" )
    1668             :     {
    1669           0 :         maData.mnLineType = EXC_CHSERTREND_LOGARITHMIC;
    1670             :     }
    1671           0 :     else if( aService == "com.sun.star.chart2.PotentialRegressionCurve" )
    1672             :     {
    1673           0 :         maData.mnLineType = EXC_CHSERTREND_POWER;
    1674             :     }
    1675           0 :     else if( aService == "com.sun.star.chart2.PolynomialRegressionCurve" )
    1676             :     {
    1677           0 :         maData.mnLineType = EXC_CHSERTREND_POLYNOMIAL;
    1678             :         sal_Int32 aDegree;
    1679           0 :         aCurveProp.GetProperty(aDegree, EXC_CHPROP_POLYNOMIAL_DEGREE);
    1680           0 :         maData.mnOrder = static_cast<sal_uInt8> (aDegree);
    1681             :     }
    1682           0 :     else if( aService == "com.sun.star.chart2.MovingAverageRegressionCurve" )
    1683             :     {
    1684           0 :         maData.mnLineType = EXC_CHSERTREND_MOVING_AVG;
    1685             :         sal_Int32 aPeriod;
    1686           0 :         aCurveProp.GetProperty(aPeriod, EXC_CHPROP_MOVING_AVERAGE_PERIOD);
    1687           0 :         maData.mnOrder = static_cast<sal_uInt8> (aPeriod);
    1688             :     }
    1689             :     else
    1690             :     {
    1691           0 :         return false;
    1692             :     }
    1693             : 
    1694           0 :     aCurveProp.GetProperty(maData.mfForecastFor,  EXC_CHPROP_EXTRAPOLATE_FORWARD);
    1695           0 :     aCurveProp.GetProperty(maData.mfForecastBack, EXC_CHPROP_EXTRAPOLATE_BACKWARD);
    1696           0 :     sal_Bool bIsForceIntercept = false;
    1697           0 :     aCurveProp.GetProperty(bIsForceIntercept,  EXC_CHPROP_FORCE_INTERCEPT);
    1698           0 :     if (bIsForceIntercept)
    1699           0 :         aCurveProp.GetProperty(maData.mfIntercept, EXC_CHPROP_INTERCEPT_VALUE);
    1700             : 
    1701             : 
    1702             :     // line formatting
    1703           0 :     XclChDataPointPos aPointPos( nSeriesIdx );
    1704           0 :     mxDataFmt.reset( new XclExpChDataFormat( GetChRoot(), aPointPos, 0 ) );
    1705           0 :     mxDataFmt->ConvertLine( aCurveProp, EXC_CHOBJTYPE_TRENDLINE );
    1706             : 
    1707             :     // #i83100# show equation and correlation coefficient
    1708           0 :     ScfPropertySet aEquationProp( xRegCurve->getEquationProperties() );
    1709           0 :     maData.mnShowEquation = aEquationProp.GetBoolProperty( EXC_CHPROP_SHOWEQUATION ) ? 1 : 0;
    1710           0 :     maData.mnShowRSquared = aEquationProp.GetBoolProperty( EXC_CHPROP_SHOWCORRELATION ) ? 1 : 0;
    1711             : 
    1712             :     // #i83100# formatting of the equation text box
    1713           0 :     if( (maData.mnShowEquation != 0) || (maData.mnShowRSquared != 0) )
    1714             :     {
    1715           0 :         mxLabel.reset( new XclExpChText( GetChRoot() ) );
    1716           0 :         mxLabel->ConvertTrendLineEquation( aEquationProp, aPointPos );
    1717             :     }
    1718             : 
    1719             :     // missing features
    1720             :     // #i5085# manual trend line size
    1721             :     // #i34093# manual crossing point
    1722           0 :     return true;
    1723             : }
    1724             : 
    1725           0 : void XclExpChSerTrendLine::WriteBody( XclExpStream& rStrm )
    1726             : {
    1727           0 :     rStrm   << maData.mnLineType
    1728           0 :             << maData.mnOrder
    1729           0 :             << maData.mfIntercept
    1730           0 :             << maData.mnShowEquation
    1731           0 :             << maData.mnShowRSquared
    1732           0 :             << maData.mfForecastFor
    1733           0 :             << maData.mfForecastBack;
    1734           0 : }
    1735             : 
    1736           0 : XclExpChSerErrorBar::XclExpChSerErrorBar( const XclExpChRoot& rRoot, sal_uInt8 nBarType ) :
    1737             :     XclExpRecord( EXC_ID_CHSERERRORBAR, 14 ),
    1738           0 :     XclExpChRoot( rRoot )
    1739             : {
    1740           0 :     maData.mnBarType = nBarType;
    1741           0 : }
    1742             : 
    1743           0 : bool XclExpChSerErrorBar::Convert( XclExpChSourceLink& rValueLink, sal_uInt16& rnValueCount, const ScfPropertySet& rPropSet )
    1744             : {
    1745           0 :     sal_Int32 nBarStyle = 0;
    1746           0 :     bool bOk = rPropSet.GetProperty( nBarStyle, EXC_CHPROP_ERRORBARSTYLE );
    1747           0 :     if( bOk )
    1748             :     {
    1749           0 :         switch( nBarStyle )
    1750             :         {
    1751             :             case cssc::ErrorBarStyle::ABSOLUTE:
    1752           0 :                 maData.mnSourceType = EXC_CHSERERR_FIXED;
    1753           0 :                 rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_POSITIVEERROR );
    1754           0 :             break;
    1755             :             case cssc::ErrorBarStyle::RELATIVE:
    1756           0 :                 maData.mnSourceType = EXC_CHSERERR_PERCENT;
    1757           0 :                 rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_POSITIVEERROR );
    1758           0 :             break;
    1759             :             case cssc::ErrorBarStyle::STANDARD_DEVIATION:
    1760           0 :                 maData.mnSourceType = EXC_CHSERERR_STDDEV;
    1761           0 :                 rPropSet.GetProperty( maData.mfValue, EXC_CHPROP_WEIGHT );
    1762           0 :             break;
    1763             :             case cssc::ErrorBarStyle::STANDARD_ERROR:
    1764           0 :                 maData.mnSourceType = EXC_CHSERERR_STDERR;
    1765           0 :             break;
    1766             :             case cssc::ErrorBarStyle::FROM_DATA:
    1767             :             {
    1768           0 :                 bOk = false;
    1769           0 :                 maData.mnSourceType = EXC_CHSERERR_CUSTOM;
    1770           0 :                 Reference< XDataSource > xDataSource( rPropSet.GetApiPropertySet(), UNO_QUERY );
    1771           0 :                 if( xDataSource.is() )
    1772             :                 {
    1773             :                     // find first sequence with current role
    1774           0 :                     OUString aRole = XclChartHelper::GetErrorBarValuesRole( maData.mnBarType );
    1775           0 :                     Reference< XDataSequence > xValueSeq;
    1776             : 
    1777           0 :                     Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
    1778           0 :                     const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
    1779           0 :                     const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
    1780           0 :                     for( const Reference< XLabeledDataSequence >* pIt = pBeg; !xValueSeq.is() && (pIt != pEnd); ++pIt )
    1781             :                     {
    1782           0 :                         Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
    1783           0 :                         ScfPropertySet aValueProp( xTmpValueSeq );
    1784           0 :                         OUString aCurrRole;
    1785           0 :                         if( aValueProp.GetProperty( aCurrRole, EXC_CHPROP_ROLE ) && (aCurrRole == aRole) )
    1786           0 :                             xValueSeq = xTmpValueSeq;
    1787           0 :                     }
    1788           0 :                     if( xValueSeq.is() )
    1789             :                     {
    1790             :                         // #i86465# pass value count back to series
    1791           0 :                         rnValueCount = maData.mnValueCount = rValueLink.ConvertDataSequence( xValueSeq, true );
    1792           0 :                         bOk = maData.mnValueCount > 0;
    1793           0 :                     }
    1794           0 :                 }
    1795             :             }
    1796           0 :             break;
    1797             :             default:
    1798           0 :                 bOk = false;
    1799             :         }
    1800             :     }
    1801           0 :     return bOk;
    1802             : }
    1803             : 
    1804           0 : void XclExpChSerErrorBar::WriteBody( XclExpStream& rStrm )
    1805             : {
    1806           0 :     rStrm   << maData.mnBarType
    1807           0 :             << maData.mnSourceType
    1808           0 :             << maData.mnLineEnd
    1809           0 :             << sal_uInt8( 1 )       // must be 1 to make line visible
    1810           0 :             << maData.mfValue
    1811           0 :             << maData.mnValueCount;
    1812           0 : }
    1813             : 
    1814             : namespace {
    1815             : 
    1816             : /** Returns the property set of the specified data point. */
    1817           0 : ScfPropertySet lclGetPointPropSet( Reference< XDataSeries > xDataSeries, sal_Int32 nPointIdx )
    1818             : {
    1819           0 :     ScfPropertySet aPropSet;
    1820             :     try
    1821             :     {
    1822           0 :         aPropSet.Set( xDataSeries->getDataPointByIndex( nPointIdx ) );
    1823             :     }
    1824           0 :     catch( Exception& )
    1825             :     {
    1826             :         OSL_FAIL( "lclGetPointPropSet - no data point property set" );
    1827             :     }
    1828           0 :     return aPropSet;
    1829             : }
    1830             : 
    1831             : } // namespace
    1832             : 
    1833           0 : XclExpChSeries::XclExpChSeries( const XclExpChRoot& rRoot, sal_uInt16 nSeriesIdx ) :
    1834           0 :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_SERIES, EXC_ID_CHSERIES, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 8 ),
    1835             :     mnGroupIdx( EXC_CHSERGROUP_NONE ),
    1836             :     mnSeriesIdx( nSeriesIdx ),
    1837           0 :     mnParentIdx( EXC_CHSERIES_INVALID )
    1838             : {
    1839             :     // CHSOURCELINK records are always required, even if unused
    1840           0 :     mxTitleLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
    1841           0 :     mxValueLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_VALUES ) );
    1842           0 :     mxCategLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_CATEGORY ) );
    1843           0 :     if( GetBiff() == EXC_BIFF8 )
    1844           0 :         mxBubbleLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_BUBBLES ) );
    1845           0 : }
    1846             : 
    1847           0 : bool XclExpChSeries::ConvertDataSeries(
    1848             :         Reference< XDiagram > xDiagram, Reference< XDataSeries > xDataSeries,
    1849             :         const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx )
    1850             : {
    1851           0 :     bool bOk = false;
    1852           0 :     Reference< XDataSource > xDataSource( xDataSeries, UNO_QUERY );
    1853           0 :     if( xDataSource.is() )
    1854             :     {
    1855           0 :         Reference< XDataSequence > xYValueSeq, xTitleSeq, xXValueSeq, xBubbleSeq;
    1856             : 
    1857             :         // find first sequence with role 'values-y'
    1858           0 :         Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
    1859           0 :         const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
    1860           0 :         const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
    1861           0 :         for( const Reference< XLabeledDataSequence >* pIt = pBeg; pIt != pEnd; ++pIt )
    1862             :         {
    1863           0 :             Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
    1864           0 :             ScfPropertySet aValueProp( xTmpValueSeq );
    1865           0 :             OUString aRole;
    1866           0 :             if( aValueProp.GetProperty( aRole, EXC_CHPROP_ROLE ) )
    1867             :             {
    1868           0 :                 if( !xYValueSeq.is() && (aRole == EXC_CHPROP_ROLE_YVALUES) )
    1869             :                 {
    1870           0 :                     xYValueSeq = xTmpValueSeq;
    1871           0 :                     if( !xTitleSeq.is() )
    1872           0 :                         xTitleSeq = (*pIt)->getLabel(); // ignore role of label sequence
    1873             :                 }
    1874           0 :                 else if( !xXValueSeq.is() && !rTypeInfo.mbCategoryAxis && (aRole == EXC_CHPROP_ROLE_XVALUES) )
    1875             :                 {
    1876           0 :                     xXValueSeq = xTmpValueSeq;
    1877             :                 }
    1878           0 :                 else if( !xBubbleSeq.is() && (rTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES) && (aRole == EXC_CHPROP_ROLE_SIZEVALUES) )
    1879             :                 {
    1880           0 :                     xBubbleSeq = xTmpValueSeq;
    1881           0 :                     xTitleSeq = (*pIt)->getLabel();     // ignore role of label sequence
    1882             :                 }
    1883             :             }
    1884           0 :         }
    1885             : 
    1886           0 :         bOk = xYValueSeq.is();
    1887           0 :         if( bOk )
    1888             :         {
    1889             :             // chart type group index
    1890           0 :             mnGroupIdx = nGroupIdx;
    1891             : 
    1892             :             // convert source links
    1893           0 :             maData.mnValueCount = mxValueLink->ConvertDataSequence( xYValueSeq, true );
    1894           0 :             mxTitleLink->ConvertDataSequence( xTitleSeq, true );
    1895             : 
    1896             :             // X values of XY charts
    1897           0 :             maData.mnCategCount = mxCategLink->ConvertDataSequence( xXValueSeq, false, maData.mnValueCount );
    1898             : 
    1899             :             // size values of bubble charts
    1900           0 :             if( mxBubbleLink )
    1901           0 :                 mxBubbleLink->ConvertDataSequence( xBubbleSeq, false, maData.mnValueCount );
    1902             : 
    1903             :             // series formatting
    1904           0 :             XclChDataPointPos aPointPos( mnSeriesIdx );
    1905           0 :             ScfPropertySet aSeriesProp( xDataSeries );
    1906           0 :             mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), aPointPos, nFormatIdx ) );
    1907           0 :             mxSeriesFmt->ConvertDataSeries( aSeriesProp, rTypeInfo );
    1908             : 
    1909             :             // trend lines
    1910           0 :             CreateTrendLines( xDataSeries );
    1911             : 
    1912             :             // error bars
    1913           0 :             CreateErrorBars( aSeriesProp, EXC_CHPROP_ERRORBARX, EXC_CHSERERR_XPLUS, EXC_CHSERERR_XMINUS );
    1914           0 :             CreateErrorBars( aSeriesProp, EXC_CHPROP_ERRORBARY, EXC_CHSERERR_YPLUS, EXC_CHSERERR_YMINUS );
    1915             : 
    1916           0 :             if( maData.mnValueCount > 0 )
    1917             :             {
    1918           0 :                 const sal_Int32 nMaxPointCount = maData.mnValueCount;
    1919             : 
    1920             :                 /*  #i91063# Create missing fill properties in pie/doughnut charts.
    1921             :                     If freshly created (never saved to ODF), these charts show
    1922             :                     varying point colors but do not return these points via API. */
    1923           0 :                 if( xDiagram.is() && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_PIE) )
    1924             :                 {
    1925           0 :                     Reference< XColorScheme > xColorScheme = xDiagram->getDefaultColorScheme();
    1926           0 :                     if( xColorScheme.is() )
    1927             :                     {
    1928           0 :                         const OUString aFillStyleName = "FillStyle";
    1929           0 :                         const OUString aColorName = "Color";
    1930             :                         namespace cssd = ::com::sun::star::drawing;
    1931           0 :                         for( sal_Int32 nPointIdx = 0; nPointIdx < nMaxPointCount; ++nPointIdx )
    1932             :                         {
    1933           0 :                             aPointPos.mnPointIdx = static_cast< sal_uInt16 >( nPointIdx );
    1934           0 :                             ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, nPointIdx );
    1935             :                             // test that the point fill style is solid, but no color is set
    1936           0 :                             cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
    1937           0 :                             if( aPointProp.GetProperty( eFillStyle, aFillStyleName ) &&
    1938           0 :                                 (eFillStyle == cssd::FillStyle_SOLID) &&
    1939           0 :                                 !aPointProp.HasProperty( aColorName ) )
    1940             :                             {
    1941           0 :                                 aPointProp.SetProperty( aColorName, xColorScheme->getColorByIndex( nPointIdx ) );
    1942             :                             }
    1943           0 :                         }
    1944           0 :                     }
    1945             :                 }
    1946             : 
    1947             :                 // data point formatting
    1948           0 :                 Sequence< sal_Int32 > aPointIndexes;
    1949           0 :                 if( aSeriesProp.GetProperty( aPointIndexes, EXC_CHPROP_ATTRIBDATAPOINTS ) && aPointIndexes.hasElements() )
    1950             :                 {
    1951           0 :                     const sal_Int32* pnBeg = aPointIndexes.getConstArray();
    1952           0 :                     const sal_Int32* pnEnd = pnBeg + aPointIndexes.getLength();
    1953           0 :                     for( const sal_Int32* pnIt = pnBeg; (pnIt != pnEnd) && (*pnIt < nMaxPointCount); ++pnIt )
    1954             :                     {
    1955           0 :                         aPointPos.mnPointIdx = static_cast< sal_uInt16 >( *pnIt );
    1956           0 :                         ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, *pnIt );
    1957           0 :                         XclExpChDataFormatRef xPointFmt( new XclExpChDataFormat( GetChRoot(), aPointPos, nFormatIdx ) );
    1958           0 :                         xPointFmt->ConvertDataSeries( aPointProp, rTypeInfo );
    1959           0 :                         maPointFmts.AppendRecord( xPointFmt );
    1960           0 :                     }
    1961           0 :                 }
    1962           0 :             }
    1963           0 :         }
    1964             :     }
    1965           0 :     return bOk;
    1966             : }
    1967             : 
    1968           0 : bool XclExpChSeries::ConvertStockSeries( XDataSeriesRef xDataSeries,
    1969             :         const OUString& rValueRole, sal_uInt16 nGroupIdx, sal_uInt16 nFormatIdx, bool bCloseSymbol )
    1970             : {
    1971           0 :     bool bOk = false;
    1972           0 :     Reference< XDataSource > xDataSource( xDataSeries, UNO_QUERY );
    1973           0 :     if( xDataSource.is() )
    1974             :     {
    1975           0 :         Reference< XDataSequence > xYValueSeq, xTitleSeq;
    1976             : 
    1977             :         // find first sequence with passed role
    1978           0 :         Sequence< Reference< XLabeledDataSequence > > aLabeledSeqVec = xDataSource->getDataSequences();
    1979           0 :         const Reference< XLabeledDataSequence >* pBeg = aLabeledSeqVec.getConstArray();
    1980           0 :         const Reference< XLabeledDataSequence >* pEnd = pBeg + aLabeledSeqVec.getLength();
    1981           0 :         for( const Reference< XLabeledDataSequence >* pIt = pBeg; !xYValueSeq.is() && (pIt != pEnd); ++pIt )
    1982             :         {
    1983           0 :             Reference< XDataSequence > xTmpValueSeq = (*pIt)->getValues();
    1984           0 :             ScfPropertySet aValueProp( xTmpValueSeq );
    1985           0 :             OUString aRole;
    1986           0 :             if( aValueProp.GetProperty( aRole, EXC_CHPROP_ROLE ) && (aRole == rValueRole) )
    1987             :             {
    1988           0 :                 xYValueSeq = xTmpValueSeq;
    1989           0 :                 xTitleSeq = (*pIt)->getLabel();     // ignore role of label sequence
    1990             :             }
    1991           0 :         }
    1992             : 
    1993           0 :         bOk = xYValueSeq.is();
    1994           0 :         if( bOk )
    1995             :         {
    1996             :             // chart type group index
    1997           0 :             mnGroupIdx = nGroupIdx;
    1998             :             // convert source links
    1999           0 :             maData.mnValueCount = mxValueLink->ConvertDataSequence( xYValueSeq, true );
    2000           0 :             mxTitleLink->ConvertDataSequence( xTitleSeq, true );
    2001             :             // series formatting
    2002           0 :             ScfPropertySet aSeriesProp( xDataSeries );
    2003           0 :             mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), XclChDataPointPos( mnSeriesIdx ), nFormatIdx ) );
    2004           0 :             mxSeriesFmt->ConvertStockSeries( aSeriesProp, bCloseSymbol );
    2005           0 :         }
    2006             :     }
    2007           0 :     return bOk;
    2008             : }
    2009             : 
    2010           0 : bool XclExpChSeries::ConvertTrendLine( const XclExpChSeries& rParent, Reference< XRegressionCurve > xRegCurve )
    2011             : {
    2012           0 :     InitFromParent( rParent );
    2013             : 
    2014           0 :     mxTrendLine.reset( new XclExpChSerTrendLine( GetChRoot() ) );
    2015           0 :     bool bOk = mxTrendLine->Convert( xRegCurve, mnSeriesIdx );
    2016           0 :     if( bOk )
    2017             :     {
    2018           0 :         OUString aName;
    2019           0 :         ScfPropertySet aProperties( xRegCurve );
    2020           0 :         aProperties.GetProperty(aName, EXC_CHPROP_CURVENAME);
    2021           0 :         mxTitleLink->ConvertString(aName);
    2022             : 
    2023           0 :         mxSeriesFmt = mxTrendLine->GetDataFormat();
    2024           0 :         GetChartData().SetDataLabel( mxTrendLine->GetDataLabel() );
    2025             :     }
    2026           0 :     return bOk;
    2027             : }
    2028             : 
    2029           0 : bool XclExpChSeries::ConvertErrorBar( const XclExpChSeries& rParent, const ScfPropertySet& rPropSet, sal_uInt8 nBarId )
    2030             : {
    2031           0 :     InitFromParent( rParent );
    2032             :     // error bar settings
    2033           0 :     mxErrorBar.reset( new XclExpChSerErrorBar( GetChRoot(), nBarId ) );
    2034           0 :     bool bOk = mxErrorBar->Convert( *mxValueLink, maData.mnValueCount, rPropSet );
    2035           0 :     if( bOk )
    2036             :     {
    2037             :         // error bar formatting
    2038           0 :         mxSeriesFmt.reset( new XclExpChDataFormat( GetChRoot(), XclChDataPointPos( mnSeriesIdx ), 0 ) );
    2039           0 :         mxSeriesFmt->ConvertLine( rPropSet, EXC_CHOBJTYPE_ERRORBAR );
    2040             :     }
    2041           0 :     return bOk;
    2042             : }
    2043             : 
    2044           0 : void XclExpChSeries::ConvertCategSequence( Reference< XLabeledDataSequence > xCategSeq )
    2045             : {
    2046           0 :     if( xCategSeq.is() )
    2047           0 :         maData.mnCategCount = mxCategLink->ConvertDataSequence( xCategSeq->getValues(), false );
    2048           0 : }
    2049             : 
    2050           0 : void XclExpChSeries::WriteSubRecords( XclExpStream& rStrm )
    2051             : {
    2052           0 :     lclSaveRecord( rStrm, mxTitleLink );
    2053           0 :     lclSaveRecord( rStrm, mxValueLink );
    2054           0 :     lclSaveRecord( rStrm, mxCategLink );
    2055           0 :     lclSaveRecord( rStrm, mxBubbleLink );
    2056           0 :     lclSaveRecord( rStrm, mxSeriesFmt );
    2057           0 :     maPointFmts.Save( rStrm );
    2058           0 :     if( mnGroupIdx != EXC_CHSERGROUP_NONE )
    2059           0 :         XclExpUInt16Record( EXC_ID_CHSERGROUP, mnGroupIdx ).Save( rStrm );
    2060           0 :     if( mnParentIdx != EXC_CHSERIES_INVALID )
    2061           0 :         XclExpUInt16Record( EXC_ID_CHSERPARENT, mnParentIdx ).Save( rStrm );
    2062           0 :     lclSaveRecord( rStrm, mxTrendLine );
    2063           0 :     lclSaveRecord( rStrm, mxErrorBar );
    2064           0 : }
    2065             : 
    2066           0 : void XclExpChSeries::InitFromParent( const XclExpChSeries& rParent )
    2067             : {
    2068             :     // index to parent series is stored 1-based
    2069           0 :     mnParentIdx = rParent.mnSeriesIdx + 1;
    2070             :     /*  #i86465# MSO2007 SP1 expects correct point counts in child series
    2071             :         (there was no problem in Excel2003 or Excel2007 without SP1...) */
    2072           0 :     maData.mnCategCount = rParent.maData.mnCategCount;
    2073           0 :     maData.mnValueCount = rParent.maData.mnValueCount;
    2074           0 : }
    2075             : 
    2076           0 : void XclExpChSeries::CreateTrendLines( XDataSeriesRef xDataSeries )
    2077             : {
    2078           0 :     Reference< XRegressionCurveContainer > xRegCurveCont( xDataSeries, UNO_QUERY );
    2079           0 :     if( xRegCurveCont.is() )
    2080             :     {
    2081           0 :         Sequence< Reference< XRegressionCurve > > aRegCurveSeq = xRegCurveCont->getRegressionCurves();
    2082           0 :         const Reference< XRegressionCurve >* pBeg = aRegCurveSeq.getConstArray();
    2083           0 :         const Reference< XRegressionCurve >* pEnd = pBeg + aRegCurveSeq.getLength();
    2084           0 :         for( const Reference< XRegressionCurve >* pIt = pBeg; pIt != pEnd; ++pIt )
    2085             :         {
    2086           0 :             XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
    2087           0 :             if( xSeries && !xSeries->ConvertTrendLine( *this, *pIt ) )
    2088           0 :                 GetChartData().RemoveLastSeries();
    2089           0 :         }
    2090           0 :     }
    2091           0 : }
    2092             : 
    2093           0 : void XclExpChSeries::CreateErrorBars( const ScfPropertySet& rPropSet,
    2094             :         const OUString& rBarPropName, sal_uInt8 nPosBarId, sal_uInt8 nNegBarId )
    2095             : {
    2096           0 :     Reference< XPropertySet > xErrorBar;
    2097           0 :     if( rPropSet.GetProperty( xErrorBar, rBarPropName ) && xErrorBar.is() )
    2098             :     {
    2099           0 :         ScfPropertySet aErrorProp( xErrorBar );
    2100           0 :         CreateErrorBar( aErrorProp, EXC_CHPROP_SHOWPOSITIVEERROR, nPosBarId );
    2101           0 :         CreateErrorBar( aErrorProp, EXC_CHPROP_SHOWNEGATIVEERROR, nNegBarId );
    2102           0 :     }
    2103           0 : }
    2104             : 
    2105           0 : void XclExpChSeries::CreateErrorBar( const ScfPropertySet& rPropSet,
    2106             :         const OUString& rShowPropName, sal_uInt8 nBarId )
    2107             : {
    2108           0 :     if( rPropSet.GetBoolProperty( rShowPropName ) )
    2109             :     {
    2110           0 :         XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
    2111           0 :         if( xSeries && !xSeries->ConvertErrorBar( *this, rPropSet, nBarId ) )
    2112           0 :             GetChartData().RemoveLastSeries();
    2113             :     }
    2114           0 : }
    2115             : 
    2116           0 : void XclExpChSeries::WriteBody( XclExpStream& rStrm )
    2117             : {
    2118           0 :     rStrm << maData.mnCategType << maData.mnValueType << maData.mnCategCount << maData.mnValueCount;
    2119           0 :     if( GetBiff() == EXC_BIFF8 )
    2120           0 :         rStrm << maData.mnBubbleType << maData.mnBubbleCount;
    2121           0 : }
    2122             : 
    2123             : // Chart type groups ==========================================================
    2124             : 
    2125           0 : XclExpChType::XclExpChType( const XclExpChRoot& rRoot ) :
    2126             :     XclExpRecord( EXC_ID_CHUNKNOWN ),
    2127             :     XclExpChRoot( rRoot ),
    2128           0 :     maTypeInfo( rRoot.GetChartTypeInfo( EXC_CHTYPEID_UNKNOWN ) )
    2129             : {
    2130           0 : }
    2131             : 
    2132           0 : void XclExpChType::Convert( Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
    2133             :         sal_Int32 nApiAxesSetIdx, bool bSwappedAxesSet, bool bHasXLabels )
    2134             : {
    2135           0 :     if( xChartType.is() )
    2136             :     {
    2137           0 :         maTypeInfo = GetChartTypeInfo( xChartType->getChartType() );
    2138             :         // special handling for some chart types
    2139           0 :         switch( maTypeInfo.meTypeCateg )
    2140             :         {
    2141             :             case EXC_CHTYPECATEG_BAR:
    2142             :             {
    2143           0 :                 maTypeInfo = GetChartTypeInfo( bSwappedAxesSet ? EXC_CHTYPEID_HORBAR : EXC_CHTYPEID_BAR );
    2144           0 :                 ::set_flag( maData.mnFlags, EXC_CHBAR_HORIZONTAL, bSwappedAxesSet );
    2145           0 :                 ScfPropertySet aTypeProp( xChartType );
    2146           0 :                 Sequence< sal_Int32 > aInt32Seq;
    2147           0 :                 maData.mnOverlap = 0;
    2148           0 :                 if( aTypeProp.GetProperty( aInt32Seq, EXC_CHPROP_OVERLAPSEQ ) && (nApiAxesSetIdx < aInt32Seq.getLength()) )
    2149           0 :                     maData.mnOverlap = limit_cast< sal_Int16 >( -aInt32Seq[ nApiAxesSetIdx ], -100, 100 );
    2150           0 :                 maData.mnGap = 150;
    2151           0 :                 if( aTypeProp.GetProperty( aInt32Seq, EXC_CHPROP_GAPWIDTHSEQ ) && (nApiAxesSetIdx < aInt32Seq.getLength()) )
    2152           0 :                     maData.mnGap = limit_cast< sal_uInt16 >( aInt32Seq[ nApiAxesSetIdx ], 0, 500 );
    2153             :             }
    2154           0 :             break;
    2155             :             case EXC_CHTYPECATEG_RADAR:
    2156           0 :                 ::set_flag( maData.mnFlags, EXC_CHRADAR_AXISLABELS, bHasXLabels );
    2157           0 :             break;
    2158             :             case EXC_CHTYPECATEG_PIE:
    2159             :             {
    2160           0 :                 ScfPropertySet aTypeProp( xChartType );
    2161           0 :                 bool bDonut = aTypeProp.GetBoolProperty( EXC_CHPROP_USERINGS );
    2162           0 :                 maTypeInfo = GetChartTypeInfo( bDonut ? EXC_CHTYPEID_DONUT : EXC_CHTYPEID_PIE );
    2163           0 :                 maData.mnPieHole = bDonut ? 50 : 0;
    2164             :                 // #i85166# starting angle of first pie slice
    2165           0 :                 ScfPropertySet aDiaProp( xDiagram );
    2166           0 :                 maData.mnRotation = XclExpChRoot::ConvertPieRotation( aDiaProp );
    2167             :             }
    2168           0 :             break;
    2169             :             case EXC_CHTYPECATEG_SCATTER:
    2170           0 :                 if( GetBiff() == EXC_BIFF8 )
    2171           0 :                     ::set_flag( maData.mnFlags, EXC_CHSCATTER_BUBBLES, maTypeInfo.meTypeId == EXC_CHTYPEID_BUBBLES );
    2172           0 :             break;
    2173             :             default:;
    2174             :         }
    2175           0 :         SetRecId( maTypeInfo.mnRecId );
    2176             :     }
    2177           0 : }
    2178             : 
    2179           0 : void XclExpChType::SetStacked( bool bPercent )
    2180             : {
    2181           0 :     switch( maTypeInfo.meTypeCateg )
    2182             :     {
    2183             :         case EXC_CHTYPECATEG_LINE:
    2184           0 :             ::set_flag( maData.mnFlags, EXC_CHLINE_STACKED );
    2185           0 :             ::set_flag( maData.mnFlags, EXC_CHLINE_PERCENT, bPercent );
    2186           0 :         break;
    2187             :         case EXC_CHTYPECATEG_BAR:
    2188           0 :             ::set_flag( maData.mnFlags, EXC_CHBAR_STACKED );
    2189           0 :             ::set_flag( maData.mnFlags, EXC_CHBAR_PERCENT, bPercent );
    2190           0 :             maData.mnOverlap = -100;
    2191           0 :         break;
    2192             :         default:;
    2193             :     }
    2194           0 : }
    2195             : 
    2196           0 : void XclExpChType::WriteBody( XclExpStream& rStrm )
    2197             : {
    2198           0 :     switch( GetRecId() )
    2199             :     {
    2200             :         case EXC_ID_CHBAR:
    2201           0 :             rStrm << maData.mnOverlap << maData.mnGap << maData.mnFlags;
    2202           0 :         break;
    2203             : 
    2204             :         case EXC_ID_CHLINE:
    2205             :         case EXC_ID_CHAREA:
    2206             :         case EXC_ID_CHRADARLINE:
    2207             :         case EXC_ID_CHRADARAREA:
    2208           0 :             rStrm << maData.mnFlags;
    2209           0 :         break;
    2210             : 
    2211             :         case EXC_ID_CHPIE:
    2212           0 :             rStrm << maData.mnRotation << maData.mnPieHole;
    2213           0 :             if( GetBiff() == EXC_BIFF8 )
    2214           0 :                 rStrm << maData.mnFlags;
    2215           0 :         break;
    2216             : 
    2217             :         case EXC_ID_CHSCATTER:
    2218           0 :             if( GetBiff() == EXC_BIFF8 )
    2219           0 :                 rStrm << maData.mnBubbleSize << maData.mnBubbleType << maData.mnFlags;
    2220           0 :         break;
    2221             : 
    2222             :         default:
    2223             :             OSL_FAIL( "XclExpChType::WriteBody - unknown chart type" );
    2224             :     }
    2225           0 : }
    2226             : 
    2227           0 : XclExpChChart3d::XclExpChChart3d() :
    2228           0 :     XclExpRecord( EXC_ID_CHCHART3D, 14 )
    2229             : {
    2230           0 : }
    2231             : 
    2232           0 : void XclExpChChart3d::Convert( const ScfPropertySet& rPropSet, bool b3dWallChart )
    2233             : {
    2234           0 :     sal_Int32 nRotationY = 0;
    2235           0 :     rPropSet.GetProperty( nRotationY, EXC_CHPROP_ROTATIONVERTICAL );
    2236           0 :     sal_Int32 nRotationX = 0;
    2237           0 :     rPropSet.GetProperty( nRotationX, EXC_CHPROP_ROTATIONHORIZONTAL );
    2238           0 :     sal_Int32 nPerspective = 15;
    2239           0 :     rPropSet.GetProperty( nPerspective, EXC_CHPROP_PERSPECTIVE );
    2240             : 
    2241           0 :     if( b3dWallChart )
    2242             :     {
    2243             :         // Y rotation (Excel [0..359], Chart2 [-179,180])
    2244           0 :         if( nRotationY < 0 ) nRotationY += 360;
    2245           0 :         maData.mnRotation = static_cast< sal_uInt16 >( nRotationY );
    2246             :         // X rotation a.k.a. elevation (Excel [-90..90], Chart2 [-179,180])
    2247           0 :         maData.mnElevation = limit_cast< sal_Int16 >( nRotationX, -90, 90 );
    2248             :         // perspective (Excel and Chart2 [0,100])
    2249           0 :         maData.mnEyeDist = limit_cast< sal_uInt16 >( nPerspective, 0, 100 );
    2250             :         // flags
    2251           0 :         maData.mnFlags = 0;
    2252           0 :         ::set_flag( maData.mnFlags, EXC_CHCHART3D_REAL3D, !rPropSet.GetBoolProperty( EXC_CHPROP_RIGHTANGLEDAXES ) );
    2253           0 :         ::set_flag( maData.mnFlags, EXC_CHCHART3D_AUTOHEIGHT );
    2254           0 :         ::set_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS );
    2255             :     }
    2256             :     else
    2257             :     {
    2258             :         // Y rotation not used in pie charts, but 'first pie slice angle'
    2259           0 :         maData.mnRotation = XclExpChRoot::ConvertPieRotation( rPropSet );
    2260             :         // X rotation a.k.a. elevation (map Chart2 [-80,-10] to Excel [10..80])
    2261           0 :         maData.mnElevation = limit_cast< sal_Int16 >( (nRotationX + 270) % 180, 10, 80 );
    2262             :         // perspective (Excel and Chart2 [0,100])
    2263           0 :         maData.mnEyeDist = limit_cast< sal_uInt16 >( nPerspective, 0, 100 );
    2264             :         // flags
    2265           0 :         maData.mnFlags = 0;
    2266             :     }
    2267           0 : }
    2268             : 
    2269           0 : void XclExpChChart3d::WriteBody( XclExpStream& rStrm )
    2270             : {
    2271           0 :     rStrm   << maData.mnRotation
    2272           0 :             << maData.mnElevation
    2273           0 :             << maData.mnEyeDist
    2274           0 :             << maData.mnRelHeight
    2275           0 :             << maData.mnRelDepth
    2276           0 :             << maData.mnDepthGap
    2277           0 :             << maData.mnFlags;
    2278           0 : }
    2279             : 
    2280           0 : XclExpChLegend::XclExpChLegend( const XclExpChRoot& rRoot ) :
    2281           0 :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_LEGEND, EXC_ID_CHLEGEND, 20 )
    2282             : {
    2283           0 : }
    2284             : 
    2285           0 : void XclExpChLegend::Convert( const ScfPropertySet& rPropSet )
    2286             : {
    2287             :     // frame properties
    2288           0 :     mxFrame = lclCreateFrame( GetChRoot(), rPropSet, EXC_CHOBJTYPE_LEGEND );
    2289             :     // text properties
    2290           0 :     mxText.reset( new XclExpChText( GetChRoot() ) );
    2291           0 :     mxText->ConvertLegend( rPropSet );
    2292             : 
    2293             :     // legend position and size
    2294           0 :     Any aRelPosAny, aRelSizeAny;
    2295           0 :     rPropSet.GetAnyProperty( aRelPosAny, EXC_CHPROP_RELATIVEPOSITION );
    2296           0 :     rPropSet.GetAnyProperty( aRelSizeAny, EXC_CHPROP_RELATIVESIZE );
    2297           0 :     cssc::ChartLegendExpansion eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
    2298           0 :     rPropSet.GetProperty( eApiExpand, EXC_CHPROP_EXPANSION );
    2299           0 :     if( aRelPosAny.has< RelativePosition >() || ((eApiExpand == cssc::ChartLegendExpansion_CUSTOM) && aRelSizeAny.has< RelativeSize >()) )
    2300             :     {
    2301             :         try
    2302             :         {
    2303             :             /*  The 'RelativePosition' or 'RelativeSize' properties are used as
    2304             :                 indicator of manually changed legend position/size, but due to
    2305             :                 the different anchor modes used by this property (in the
    2306             :                 RelativePosition.Anchor member) it cannot be used to calculate
    2307             :                 the position easily. For this, the Chart1 API will be used
    2308             :                 instead. */
    2309           0 :             Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
    2310           0 :             Reference< XShape > xChart1Legend( xChart1Doc->getLegend(), UNO_SET_THROW );
    2311             :             // coordinates in CHLEGEND record written but not used by Excel
    2312           0 :             mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_CHARTSIZE, EXC_CHFRAMEPOS_PARENT ) );
    2313           0 :             XclChFramePos& rFramePos = mxFramePos->GetFramePosData();
    2314           0 :             rFramePos.mnTLMode = EXC_CHFRAMEPOS_CHARTSIZE;
    2315           0 :             ::com::sun::star::awt::Point aLegendPos = xChart1Legend->getPosition();
    2316           0 :             rFramePos.maRect.mnX = maData.maRect.mnX = CalcChartXFromHmm( aLegendPos.X );
    2317           0 :             rFramePos.maRect.mnY = maData.maRect.mnY = CalcChartYFromHmm( aLegendPos.Y );
    2318             :             // legend size, Excel expects points in CHFRAMEPOS record
    2319           0 :             rFramePos.mnBRMode = EXC_CHFRAMEPOS_ABSSIZE_POINTS;
    2320           0 :             ::com::sun::star::awt::Size aLegendSize = xChart1Legend->getSize();
    2321           0 :             rFramePos.maRect.mnWidth = static_cast< sal_uInt16 >( aLegendSize.Width * EXC_POINTS_PER_HMM + 0.5 );
    2322           0 :             rFramePos.maRect.mnHeight = static_cast< sal_uInt16 >( aLegendSize.Height * EXC_POINTS_PER_HMM + 0.5 );
    2323           0 :             maData.maRect.mnWidth = CalcChartXFromHmm( aLegendSize.Width );
    2324           0 :             maData.maRect.mnHeight = CalcChartYFromHmm( aLegendSize.Height );
    2325           0 :             eApiExpand = cssc::ChartLegendExpansion_CUSTOM;
    2326             :             // manual legend position implies manual plot area
    2327           0 :             GetChartData().SetManualPlotArea();
    2328           0 :             maData.mnDockMode = EXC_CHLEGEND_NOTDOCKED;
    2329             :             // a CHFRAME record with cleared auto flags is needed
    2330           0 :             if( !mxFrame )
    2331           0 :                 mxFrame.reset( new XclExpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND ) );
    2332           0 :             mxFrame->SetAutoFlags( false, false );
    2333             :         }
    2334           0 :         catch( Exception& )
    2335             :         {
    2336             :             OSL_FAIL( "XclExpChLegend::Convert - cannot get legend shape" );
    2337           0 :             maData.mnDockMode = EXC_CHLEGEND_RIGHT;
    2338           0 :             eApiExpand = cssc::ChartLegendExpansion_HIGH;
    2339             :         }
    2340             :     }
    2341             :     else
    2342             :     {
    2343           0 :         cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
    2344           0 :         rPropSet.GetProperty( eApiPos, EXC_CHPROP_ANCHORPOSITION );
    2345           0 :         switch( eApiPos )
    2346             :         {
    2347           0 :             case cssc2::LegendPosition_LINE_START:   maData.mnDockMode = EXC_CHLEGEND_LEFT;      break;
    2348           0 :             case cssc2::LegendPosition_LINE_END:     maData.mnDockMode = EXC_CHLEGEND_RIGHT;     break;
    2349           0 :             case cssc2::LegendPosition_PAGE_START:   maData.mnDockMode = EXC_CHLEGEND_TOP;       break;
    2350           0 :             case cssc2::LegendPosition_PAGE_END:     maData.mnDockMode = EXC_CHLEGEND_BOTTOM;    break;
    2351             :             default:
    2352             :                 OSL_FAIL( "XclExpChLegend::Convert - unrecognized legend position" );
    2353           0 :                 maData.mnDockMode = EXC_CHLEGEND_RIGHT;
    2354           0 :                 eApiExpand = cssc::ChartLegendExpansion_HIGH;
    2355             :         }
    2356             :     }
    2357           0 :     ::set_flag( maData.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand == cssc::ChartLegendExpansion_HIGH );
    2358             : 
    2359             :     // other flags
    2360           0 :     ::set_flag( maData.mnFlags, EXC_CHLEGEND_AUTOSERIES );
    2361           0 :     const sal_uInt16 nAutoFlags = EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY;
    2362           0 :     ::set_flag( maData.mnFlags, nAutoFlags, maData.mnDockMode != EXC_CHLEGEND_NOTDOCKED );
    2363           0 : }
    2364             : 
    2365           0 : void XclExpChLegend::WriteSubRecords( XclExpStream& rStrm )
    2366             : {
    2367           0 :     lclSaveRecord( rStrm, mxFramePos );
    2368           0 :     lclSaveRecord( rStrm, mxText );
    2369           0 :     lclSaveRecord( rStrm, mxFrame );
    2370           0 : }
    2371             : 
    2372           0 : void XclExpChLegend::WriteBody( XclExpStream& rStrm )
    2373             : {
    2374           0 :     rStrm << maData.maRect << maData.mnDockMode << maData.mnSpacing << maData.mnFlags;
    2375           0 : }
    2376             : 
    2377           0 : XclExpChDropBar::XclExpChDropBar( const XclExpChRoot& rRoot, XclChObjectType eObjType ) :
    2378             :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_DROPBAR, EXC_ID_CHDROPBAR, 2 ),
    2379             :     meObjType( eObjType ),
    2380           0 :     mnBarDist( 100 )
    2381             : {
    2382           0 : }
    2383             : 
    2384           0 : void XclExpChDropBar::Convert( const ScfPropertySet& rPropSet )
    2385             : {
    2386           0 :     if( rPropSet.Is() )
    2387           0 :         ConvertFrameBase( GetChRoot(), rPropSet, meObjType );
    2388             :     else
    2389           0 :         SetDefaultFrameBase( GetChRoot(), EXC_CHFRAMETYPE_INVISIBLE, true );
    2390           0 : }
    2391             : 
    2392           0 : void XclExpChDropBar::WriteSubRecords( XclExpStream& rStrm )
    2393             : {
    2394           0 :     WriteFrameRecords( rStrm );
    2395           0 : }
    2396             : 
    2397           0 : void XclExpChDropBar::WriteBody( XclExpStream& rStrm )
    2398             : {
    2399           0 :     rStrm << mnBarDist;
    2400           0 : }
    2401             : 
    2402           0 : XclExpChTypeGroup::XclExpChTypeGroup( const XclExpChRoot& rRoot, sal_uInt16 nGroupIdx ) :
    2403             :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_TYPEGROUP, EXC_ID_CHTYPEGROUP, 20 ),
    2404             :     maType( rRoot ),
    2405           0 :     maTypeInfo( maType.GetTypeInfo() )
    2406             : {
    2407           0 :     maData.mnGroupIdx = nGroupIdx;
    2408           0 : }
    2409             : 
    2410           0 : void XclExpChTypeGroup::ConvertType(
    2411             :         Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
    2412             :         sal_Int32 nApiAxesSetIdx, bool b3dChart, bool bSwappedAxesSet, bool bHasXLabels )
    2413             : {
    2414             :     // chart type settings
    2415           0 :     maType.Convert( xDiagram, xChartType, nApiAxesSetIdx, bSwappedAxesSet, bHasXLabels );
    2416             : 
    2417             :     // spline - TODO: get from single series (#i66858#)
    2418           0 :     ScfPropertySet aTypeProp( xChartType );
    2419             :     cssc2::CurveStyle eCurveStyle;
    2420           0 :     bool bSpline = aTypeProp.GetProperty( eCurveStyle, EXC_CHPROP_CURVESTYLE ) &&
    2421           0 :         (eCurveStyle != cssc2::CurveStyle_LINES);
    2422             : 
    2423             :     // extended type info
    2424           0 :     maTypeInfo.Set( maType.GetTypeInfo(), b3dChart, bSpline );
    2425             : 
    2426             :     // 3d chart settings
    2427           0 :     if( maTypeInfo.mb3dChart )  // only true, if Excel chart supports 3d mode
    2428             :     {
    2429           0 :         mxChart3d.reset( new XclExpChChart3d );
    2430           0 :         ScfPropertySet aDiaProp( xDiagram );
    2431           0 :         mxChart3d->Convert( aDiaProp, Is3dWallChart() );
    2432           0 :     }
    2433           0 : }
    2434             : 
    2435           0 : void XclExpChTypeGroup::ConvertSeries(
    2436             :         Reference< XDiagram > xDiagram, Reference< XChartType > xChartType,
    2437             :         sal_Int32 nGroupAxesSetIdx, bool bPercent, bool bConnectBars )
    2438             : {
    2439           0 :     Reference< XDataSeriesContainer > xSeriesCont( xChartType, UNO_QUERY );
    2440           0 :     if( xSeriesCont.is() )
    2441             :     {
    2442             :         typedef ::std::vector< Reference< XDataSeries > > XDataSeriesVec;
    2443           0 :         XDataSeriesVec aSeriesVec;
    2444             : 
    2445             :         // copy data series attached to the current axes set to the vector
    2446           0 :         Sequence< Reference< XDataSeries > > aSeriesSeq = xSeriesCont->getDataSeries();
    2447           0 :         const Reference< XDataSeries >* pBeg = aSeriesSeq.getConstArray();
    2448           0 :         const Reference< XDataSeries >* pEnd = pBeg + aSeriesSeq.getLength();
    2449           0 :         for( const Reference< XDataSeries >* pIt = pBeg; pIt != pEnd; ++pIt )
    2450             :         {
    2451           0 :             ScfPropertySet aSeriesProp( *pIt );
    2452           0 :             sal_Int32 nSeriesAxesSetIdx(0);
    2453           0 :             if( aSeriesProp.GetProperty( nSeriesAxesSetIdx, EXC_CHPROP_ATTAXISINDEX ) && (nSeriesAxesSetIdx == nGroupAxesSetIdx) )
    2454           0 :                 aSeriesVec.push_back( *pIt );
    2455           0 :         }
    2456             : 
    2457             :         // Are there any series in the current axes set?
    2458           0 :         if( !aSeriesVec.empty() )
    2459             :         {
    2460             :             // stacking direction (stacked/percent/deep 3d) from first series
    2461           0 :             ScfPropertySet aSeriesProp( aSeriesVec.front() );
    2462             :             cssc2::StackingDirection eStacking;
    2463           0 :             if( !aSeriesProp.GetProperty( eStacking, EXC_CHPROP_STACKINGDIR ) )
    2464           0 :                 eStacking = cssc2::StackingDirection_NO_STACKING;
    2465             : 
    2466             :             // stacked or percent chart
    2467           0 :             if( maTypeInfo.mbSupportsStacking && (eStacking == cssc2::StackingDirection_Y_STACKING) )
    2468             :             {
    2469             :                 // percent overrides simple stacking
    2470           0 :                 maType.SetStacked( bPercent );
    2471             : 
    2472             :                 // connected data points (only in stacked bar charts)
    2473           0 :                 if (bConnectBars && (maTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR))
    2474             :                 {
    2475           0 :                     sal_uInt16 nKey = EXC_CHCHARTLINE_CONNECT;
    2476           0 :                     maChartLines.insert(nKey, new XclExpChLineFormat(GetChRoot()));
    2477           0 :                 }
    2478             :             }
    2479             :             else
    2480             :             {
    2481             :                 // reverse series order for some unstacked 2D chart types
    2482           0 :                 if( maTypeInfo.mbReverseSeries && !Is3dChart() )
    2483           0 :                     ::std::reverse( aSeriesVec.begin(), aSeriesVec.end() );
    2484             :             }
    2485             : 
    2486             :             // deep 3d chart or clustered 3d chart (stacked is not clustered)
    2487           0 :             if( (eStacking == cssc2::StackingDirection_NO_STACKING) && Is3dWallChart() )
    2488           0 :                 mxChart3d->SetClustered();
    2489             : 
    2490             :             // varied point colors
    2491           0 :             ::set_flag( maData.mnFlags, EXC_CHTYPEGROUP_VARIEDCOLORS, aSeriesProp.GetBoolProperty( EXC_CHPROP_VARYCOLORSBY ) );
    2492             : 
    2493             :             // process all series
    2494           0 :             for( XDataSeriesVec::const_iterator aIt = aSeriesVec.begin(), aEnd = aSeriesVec.end(); aIt != aEnd; ++aIt )
    2495             :             {
    2496             :                 // create Excel series object, stock charts need special processing
    2497           0 :                 if( maTypeInfo.meTypeId == EXC_CHTYPEID_STOCK )
    2498           0 :                     CreateAllStockSeries( xChartType, *aIt );
    2499             :                 else
    2500           0 :                     CreateDataSeries( xDiagram, *aIt );
    2501           0 :             }
    2502           0 :         }
    2503           0 :     }
    2504           0 : }
    2505             : 
    2506           0 : void XclExpChTypeGroup::ConvertCategSequence( Reference< XLabeledDataSequence > xCategSeq )
    2507             : {
    2508           0 :     for( size_t nIdx = 0, nSize = maSeries.GetSize(); nIdx < nSize; ++nIdx )
    2509           0 :         maSeries.GetRecord( nIdx )->ConvertCategSequence( xCategSeq );
    2510           0 : }
    2511             : 
    2512           0 : void XclExpChTypeGroup::ConvertLegend( const ScfPropertySet& rPropSet )
    2513             : {
    2514           0 :     if( rPropSet.GetBoolProperty( EXC_CHPROP_SHOW ) )
    2515             :     {
    2516           0 :         mxLegend.reset( new XclExpChLegend( GetChRoot() ) );
    2517           0 :         mxLegend->Convert( rPropSet );
    2518             :     }
    2519           0 : }
    2520             : 
    2521           0 : void XclExpChTypeGroup::WriteSubRecords( XclExpStream& rStrm )
    2522             : {
    2523           0 :     maType.Save( rStrm );
    2524           0 :     lclSaveRecord( rStrm, mxChart3d );
    2525           0 :     lclSaveRecord( rStrm, mxLegend );
    2526           0 :     lclSaveRecord( rStrm, mxUpBar );
    2527           0 :     lclSaveRecord( rStrm, mxDownBar );
    2528           0 :     for( XclExpChLineFormatMap::iterator aLIt = maChartLines.begin(), aLEnd = maChartLines.end(); aLIt != aLEnd; ++aLIt )
    2529           0 :         lclSaveRecord( rStrm, aLIt->second, EXC_ID_CHCHARTLINE, aLIt->first );
    2530           0 : }
    2531             : 
    2532           0 : sal_uInt16 XclExpChTypeGroup::GetFreeFormatIdx() const
    2533             : {
    2534           0 :     return static_cast< sal_uInt16 >( maSeries.GetSize() );
    2535             : }
    2536             : 
    2537           0 : void XclExpChTypeGroup::CreateDataSeries(
    2538             :         Reference< XDiagram > xDiagram, Reference< XDataSeries > xDataSeries )
    2539             : {
    2540             :     // let chart create series object with correct series index
    2541           0 :     XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
    2542           0 :     if( xSeries )
    2543             :     {
    2544           0 :         if( xSeries->ConvertDataSeries( xDiagram, xDataSeries, maTypeInfo, GetGroupIdx(), GetFreeFormatIdx() ) )
    2545           0 :             maSeries.AppendRecord( xSeries );
    2546             :         else
    2547           0 :             GetChartData().RemoveLastSeries();
    2548           0 :     }
    2549           0 : }
    2550             : 
    2551           0 : void XclExpChTypeGroup::CreateAllStockSeries(
    2552             :         Reference< XChartType > xChartType, Reference< XDataSeries > xDataSeries )
    2553             : {
    2554             :     // create existing series objects
    2555           0 :     bool bHasOpen = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_OPENVALUES, false );
    2556           0 :     bool bHasHigh = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_HIGHVALUES, false );
    2557           0 :     bool bHasLow = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_LOWVALUES, false );
    2558           0 :     bool bHasClose = CreateStockSeries( xDataSeries, EXC_CHPROP_ROLE_CLOSEVALUES, !bHasOpen );
    2559             : 
    2560             :     // formatting of special stock chart elements
    2561           0 :     ScfPropertySet aTypeProp( xChartType );
    2562             :     // hi-lo lines
    2563           0 :     if( bHasHigh && bHasLow && aTypeProp.GetBoolProperty( EXC_CHPROP_SHOWHIGHLOW ) )
    2564             :     {
    2565           0 :         ScfPropertySet aSeriesProp( xDataSeries );
    2566           0 :         XclExpChLineFormatRef xLineFmt( new XclExpChLineFormat( GetChRoot() ) );
    2567           0 :         xLineFmt->Convert( GetChRoot(), aSeriesProp, EXC_CHOBJTYPE_HILOLINE );
    2568           0 :         sal_uInt16 nKey = EXC_CHCHARTLINE_HILO;
    2569           0 :         maChartLines.insert(nKey, new XclExpChLineFormat(GetChRoot()));
    2570             :     }
    2571             :     // dropbars
    2572           0 :     if( bHasOpen && bHasClose )
    2573             :     {
    2574             :         // dropbar type is dependent on position in the file - always create both
    2575           0 :         Reference< XPropertySet > xWhitePropSet, xBlackPropSet;
    2576             :         // white dropbar format
    2577           0 :         aTypeProp.GetProperty( xWhitePropSet, EXC_CHPROP_WHITEDAY );
    2578           0 :         ScfPropertySet aWhiteProp( xWhitePropSet );
    2579           0 :         mxUpBar.reset( new XclExpChDropBar( GetChRoot(), EXC_CHOBJTYPE_WHITEDROPBAR ) );
    2580           0 :         mxUpBar->Convert( aWhiteProp );
    2581             :         // black dropbar format
    2582           0 :         aTypeProp.GetProperty( xBlackPropSet, EXC_CHPROP_BLACKDAY );
    2583           0 :         ScfPropertySet aBlackProp( xBlackPropSet );
    2584           0 :         mxDownBar.reset( new XclExpChDropBar( GetChRoot(), EXC_CHOBJTYPE_BLACKDROPBAR ) );
    2585           0 :         mxDownBar->Convert( aBlackProp );
    2586           0 :     }
    2587           0 : }
    2588             : 
    2589           0 : bool XclExpChTypeGroup::CreateStockSeries( Reference< XDataSeries > xDataSeries,
    2590             :         const OUString& rValueRole, bool bCloseSymbol )
    2591             : {
    2592           0 :     bool bOk = false;
    2593             :     // let chart create series object with correct series index
    2594           0 :     XclExpChSeriesRef xSeries = GetChartData().CreateSeries();
    2595           0 :     if( xSeries )
    2596             :     {
    2597             :         bOk = xSeries->ConvertStockSeries( xDataSeries,
    2598           0 :             rValueRole, GetGroupIdx(), GetFreeFormatIdx(), bCloseSymbol );
    2599           0 :         if( bOk )
    2600           0 :             maSeries.AppendRecord( xSeries );
    2601             :         else
    2602           0 :             GetChartData().RemoveLastSeries();
    2603             :     }
    2604           0 :     return bOk;
    2605             : }
    2606             : 
    2607           0 : void XclExpChTypeGroup::WriteBody( XclExpStream& rStrm )
    2608             : {
    2609           0 :     rStrm.WriteZeroBytes( 16 );
    2610           0 :     rStrm << maData.mnFlags << maData.mnGroupIdx;
    2611           0 : }
    2612             : 
    2613             : // Axes =======================================================================
    2614             : 
    2615           0 : XclExpChLabelRange::XclExpChLabelRange( const XclExpChRoot& rRoot ) :
    2616             :     XclExpRecord( EXC_ID_CHLABELRANGE, 8 ),
    2617           0 :     XclExpChRoot( rRoot )
    2618             : {
    2619           0 : }
    2620             : 
    2621           0 : void XclExpChLabelRange::Convert( const ScaleData& rScaleData, const ScfPropertySet& rChart1Axis, bool bMirrorOrient )
    2622             : {
    2623             :     /*  Base time unit (using the property 'ExplicitTimeIncrement' from the old
    2624             :         chart API allows to detect axis type (date axis, if property exists),
    2625             :         and to receive the base time unit currently used in case the base time
    2626             :         unit is set to 'automatic'. */
    2627           0 :     cssc::TimeIncrement aTimeIncrement;
    2628           0 :     if( rChart1Axis.GetProperty( aTimeIncrement, EXC_CHPROP_EXPTIMEINCREMENT ) )
    2629             :     {
    2630             :         // property exists -> this is a date axis currently
    2631           0 :         ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS );
    2632             : 
    2633             :         // automatic base time unit, if the UNO Any 'rScaleData.TimeIncrement.TimeResolution' does not contain a valid value...
    2634           0 :         bool bAutoBase = !rScaleData.TimeIncrement.TimeResolution.has< cssc::TimeIncrement >();
    2635           0 :         ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOBASE, bAutoBase );
    2636             : 
    2637             :         // ...but get the current base time unit from the property of the old chart API
    2638           0 :         sal_Int32 nApiTimeUnit = 0;
    2639           0 :         bool bValidBaseUnit = aTimeIncrement.TimeResolution >>= nApiTimeUnit;
    2640             :         OSL_ENSURE( bValidBaseUnit, "XclExpChLabelRange::Convert - cannot ghet base time unit" );
    2641           0 :         maDateData.mnBaseUnit = bValidBaseUnit ? lclGetTimeUnit( nApiTimeUnit ) : EXC_CHDATERANGE_DAYS;
    2642             : 
    2643             :         /*  Min/max values depend on base time unit, they specify the number of
    2644             :             days, months, or years starting from null date. */
    2645           0 :         bool bAutoMin = lclConvertTimeValue( GetRoot(), maDateData.mnMinDate, rScaleData.Minimum, maDateData.mnBaseUnit );
    2646           0 :         ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMIN, bAutoMin );
    2647           0 :         bool bAutoMax = lclConvertTimeValue( GetRoot(), maDateData.mnMaxDate, rScaleData.Maximum, maDateData.mnBaseUnit );
    2648           0 :         ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAX, bAutoMax );
    2649             :     }
    2650             : 
    2651             :     // automatic axis type detection
    2652           0 :     ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTODATE, rScaleData.AutoDateAxis );
    2653             : 
    2654             :     // increment
    2655           0 :     bool bAutoMajor = lclConvertTimeInterval( maDateData.mnMajorStep, maDateData.mnMajorUnit, rScaleData.TimeIncrement.MajorTimeInterval );
    2656           0 :     ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMAJOR, bAutoMajor );
    2657           0 :     bool bAutoMinor = lclConvertTimeInterval( maDateData.mnMinorStep, maDateData.mnMinorUnit, rScaleData.TimeIncrement.MinorTimeInterval );
    2658           0 :     ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOMINOR, bAutoMinor );
    2659             : 
    2660             :     // origin
    2661           0 :     double fOrigin = 0.0;
    2662           0 :     if( !lclIsAutoAnyOrGetValue( fOrigin, rScaleData.Origin ) )
    2663           0 :         maLabelData.mnCross = limit_cast< sal_uInt16 >( fOrigin, 1, 31999 );
    2664             : 
    2665             :     // reverse order
    2666           0 :     if( (rScaleData.Orientation == cssc2::AxisOrientation_REVERSE) != bMirrorOrient )
    2667           0 :         ::set_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_REVERSE );
    2668           0 : }
    2669             : 
    2670           0 : void XclExpChLabelRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
    2671             : {
    2672           0 :     cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
    2673           0 :     rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION );
    2674           0 :     double fCrossingPos = 1.0;
    2675           0 :     rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE );
    2676             : 
    2677           0 :     bool bDateAxis = ::get_flag( maDateData.mnFlags, EXC_CHDATERANGE_DATEAXIS );
    2678           0 :     switch( eAxisPos )
    2679             :     {
    2680             :         case cssc::ChartAxisPosition_ZERO:
    2681             :         case cssc::ChartAxisPosition_START:
    2682           0 :             maLabelData.mnCross = 1;
    2683           0 :             ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS );
    2684           0 :         break;
    2685             :         case cssc::ChartAxisPosition_END:
    2686           0 :             ::set_flag( maLabelData.mnFlags, EXC_CHLABELRANGE_MAXCROSS );
    2687           0 :         break;
    2688             :         case cssc::ChartAxisPosition_VALUE:
    2689           0 :             maLabelData.mnCross = limit_cast< sal_uInt16 >( fCrossingPos, 1, 31999 );
    2690           0 :             ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS, false );
    2691           0 :             if( bDateAxis )
    2692           0 :                 maDateData.mnCross = lclGetTimeValue( GetRoot(), fCrossingPos, maDateData.mnBaseUnit );
    2693           0 :         break;
    2694             :         default:
    2695           0 :             maLabelData.mnCross = 1;
    2696           0 :             ::set_flag( maDateData.mnFlags, EXC_CHDATERANGE_AUTOCROSS );
    2697             :     }
    2698           0 : }
    2699             : 
    2700           0 : void XclExpChLabelRange::Save( XclExpStream& rStrm )
    2701             : {
    2702             :     // the CHLABELRANGE record
    2703           0 :     XclExpRecord::Save( rStrm );
    2704             : 
    2705             :     // the CHDATERANGE record with date axis settings (BIFF8 only)
    2706           0 :     if( GetBiff() == EXC_BIFF8 )
    2707             :     {
    2708           0 :         rStrm.StartRecord( EXC_ID_CHDATERANGE, 18 );
    2709           0 :         rStrm   << maDateData.mnMinDate
    2710           0 :                 << maDateData.mnMaxDate
    2711           0 :                 << maDateData.mnMajorStep
    2712           0 :                 << maDateData.mnMajorUnit
    2713           0 :                 << maDateData.mnMinorStep
    2714           0 :                 << maDateData.mnMinorUnit
    2715           0 :                 << maDateData.mnBaseUnit
    2716           0 :                 << maDateData.mnCross
    2717           0 :                 << maDateData.mnFlags;
    2718           0 :         rStrm.EndRecord();
    2719             :     }
    2720           0 : }
    2721             : 
    2722           0 : void XclExpChLabelRange::WriteBody( XclExpStream& rStrm )
    2723             : {
    2724           0 :     rStrm << maLabelData.mnCross << maLabelData.mnLabelFreq << maLabelData.mnTickFreq << maLabelData.mnFlags;
    2725           0 : }
    2726             : 
    2727           0 : XclExpChValueRange::XclExpChValueRange( const XclExpChRoot& rRoot ) :
    2728             :     XclExpRecord( EXC_ID_CHVALUERANGE, 42 ),
    2729           0 :     XclExpChRoot( rRoot )
    2730             : {
    2731           0 : }
    2732             : 
    2733           0 : void XclExpChValueRange::Convert( const ScaleData& rScaleData )
    2734             : {
    2735             :     // scaling algorithm
    2736           0 :     bool bLogScale = ScfApiHelper::GetServiceName( rScaleData.Scaling ) == "com.sun.star.chart2.LogarithmicScaling";
    2737           0 :     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE, bLogScale );
    2738             : 
    2739             :     // min/max
    2740           0 :     bool bAutoMin = lclIsAutoAnyOrGetScaledValue( maData.mfMin, rScaleData.Minimum, bLogScale );
    2741           0 :     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMIN, bAutoMin );
    2742           0 :     bool bAutoMax = lclIsAutoAnyOrGetScaledValue( maData.mfMax, rScaleData.Maximum, bLogScale );
    2743           0 :     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAX, bAutoMax );
    2744             : 
    2745             :     // origin
    2746           0 :     bool bAutoCross = lclIsAutoAnyOrGetScaledValue( maData.mfCross, rScaleData.Origin, bLogScale );
    2747           0 :     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS, bAutoCross );
    2748             : 
    2749             :     // major increment
    2750           0 :     const IncrementData& rIncrementData = rScaleData.IncrementData;
    2751           0 :     bool bAutoMajor = lclIsAutoAnyOrGetValue( maData.mfMajorStep, rIncrementData.Distance ) || (maData.mfMajorStep <= 0.0);
    2752           0 :     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMAJOR, bAutoMajor );
    2753             :     // minor increment
    2754           0 :     const Sequence< SubIncrement >& rSubIncrementSeq = rIncrementData.SubIncrements;
    2755           0 :     sal_Int32 nCount = 0;
    2756           0 :     bool bAutoMinor = bLogScale || bAutoMajor || (rSubIncrementSeq.getLength() < 1) ||
    2757           0 :         lclIsAutoAnyOrGetValue( nCount, rSubIncrementSeq[ 0 ].IntervalCount ) || (nCount < 1);
    2758           0 :     if( !bAutoMinor )
    2759           0 :         maData.mfMinorStep = maData.mfMajorStep / nCount;
    2760           0 :     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR, bAutoMinor );
    2761             : 
    2762             :     // reverse order
    2763           0 :     ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE, rScaleData.Orientation == cssc2::AxisOrientation_REVERSE );
    2764           0 : }
    2765             : 
    2766           0 : void XclExpChValueRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
    2767             : {
    2768           0 :     cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
    2769           0 :     double fCrossingPos = 0.0;
    2770           0 :     if( rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION ) && rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE ) )
    2771             :     {
    2772           0 :         switch( eAxisPos )
    2773             :         {
    2774             :             case cssc::ChartAxisPosition_ZERO:
    2775             :             case cssc::ChartAxisPosition_START:
    2776           0 :                 ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
    2777           0 :             break;
    2778             :             case cssc::ChartAxisPosition_END:
    2779           0 :                 ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_MAXCROSS );
    2780           0 :             break;
    2781             :             case cssc::ChartAxisPosition_VALUE:
    2782           0 :                 ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS, false );
    2783           0 :                 maData.mfCross = ::get_flagvalue< double >( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE, log( fCrossingPos ) / log( 10.0 ), fCrossingPos );
    2784           0 :             break;
    2785             :             default:
    2786           0 :                 ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOCROSS );
    2787             :         }
    2788             :     }
    2789           0 : }
    2790             : 
    2791           0 : void XclExpChValueRange::WriteBody( XclExpStream& rStrm )
    2792             : {
    2793           0 :     rStrm   << maData.mfMin
    2794           0 :             << maData.mfMax
    2795           0 :             << maData.mfMajorStep
    2796           0 :             << maData.mfMinorStep
    2797           0 :             << maData.mfCross
    2798           0 :             << maData.mnFlags;
    2799           0 : }
    2800             : 
    2801             : namespace {
    2802             : 
    2803           0 : sal_uInt8 lclGetXclTickPos( sal_Int32 nApiTickmarks )
    2804             : {
    2805             :     using namespace cssc2::TickmarkStyle;
    2806           0 :     sal_uInt8 nXclTickPos = 0;
    2807           0 :     ::set_flag( nXclTickPos, EXC_CHTICK_INSIDE,  ::get_flag( nApiTickmarks, INNER ) );
    2808           0 :     ::set_flag( nXclTickPos, EXC_CHTICK_OUTSIDE, ::get_flag( nApiTickmarks, OUTER ) );
    2809           0 :     return nXclTickPos;
    2810             : }
    2811             : 
    2812             : } // namespace
    2813             : 
    2814           0 : XclExpChTick::XclExpChTick( const XclExpChRoot& rRoot ) :
    2815           0 :     XclExpRecord( EXC_ID_CHTICK, (rRoot.GetBiff() == EXC_BIFF8) ? 30 : 26 ),
    2816             :     XclExpChRoot( rRoot ),
    2817           0 :     mnTextColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
    2818             : {
    2819           0 : }
    2820             : 
    2821           0 : void XclExpChTick::Convert( const ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo, sal_uInt16 nAxisType )
    2822             : {
    2823             :     // tick mark style
    2824           0 :     sal_Int32 nApiTickmarks = 0;
    2825           0 :     if( rPropSet.GetProperty( nApiTickmarks, EXC_CHPROP_MAJORTICKS ) )
    2826           0 :         maData.mnMajor = lclGetXclTickPos( nApiTickmarks );
    2827           0 :     if( rPropSet.GetProperty( nApiTickmarks, EXC_CHPROP_MINORTICKS ) )
    2828           0 :         maData.mnMinor = lclGetXclTickPos( nApiTickmarks );
    2829             : 
    2830             :     // axis labels
    2831           0 :     if( (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR) && (nAxisType == EXC_CHAXIS_X) )
    2832             :     {
    2833             :         /*  Radar charts disable their category labels via chart type, not via
    2834             :             axis, and axis labels are always 'near axis'. */
    2835           0 :         maData.mnLabelPos = EXC_CHTICK_NEXT;
    2836             :     }
    2837           0 :     else if( !rPropSet.GetBoolProperty( EXC_CHPROP_DISPLAYLABELS ) )
    2838             :     {
    2839             :         // no labels
    2840           0 :         maData.mnLabelPos = EXC_CHTICK_NOLABEL;
    2841             :     }
    2842           0 :     else if( rTypeInfo.mb3dChart && (nAxisType == EXC_CHAXIS_Y) )
    2843             :     {
    2844             :         // Excel expects 'near axis' at Y axes in 3D charts
    2845           0 :         maData.mnLabelPos = EXC_CHTICK_NEXT;
    2846             :     }
    2847             :     else
    2848             :     {
    2849           0 :         cssc::ChartAxisLabelPosition eApiLabelPos = cssc::ChartAxisLabelPosition_NEAR_AXIS;
    2850           0 :         rPropSet.GetProperty( eApiLabelPos, EXC_CHPROP_LABELPOSITION );
    2851           0 :         switch( eApiLabelPos )
    2852             :         {
    2853             :             case cssc::ChartAxisLabelPosition_NEAR_AXIS:
    2854           0 :             case cssc::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE: maData.mnLabelPos = EXC_CHTICK_NEXT;    break;
    2855           0 :             case cssc::ChartAxisLabelPosition_OUTSIDE_START:        maData.mnLabelPos = EXC_CHTICK_LOW;     break;
    2856           0 :             case cssc::ChartAxisLabelPosition_OUTSIDE_END:          maData.mnLabelPos = EXC_CHTICK_HIGH;    break;
    2857           0 :             default:                                                maData.mnLabelPos = EXC_CHTICK_NEXT;
    2858             :         }
    2859             :     }
    2860           0 : }
    2861             : 
    2862           0 : void XclExpChTick::SetFontColor( const Color& rColor, sal_uInt32 nColorId )
    2863             : {
    2864           0 :     maData.maTextColor = rColor;
    2865           0 :     ::set_flag( maData.mnFlags, EXC_CHTICK_AUTOCOLOR, rColor == COL_AUTO );
    2866           0 :     mnTextColorId = nColorId;
    2867           0 : }
    2868             : 
    2869           0 : void XclExpChTick::SetRotation( sal_uInt16 nRotation )
    2870             : {
    2871           0 :     maData.mnRotation = nRotation;
    2872           0 :     ::set_flag( maData.mnFlags, EXC_CHTICK_AUTOROT, false );
    2873           0 :     ::insert_value( maData.mnFlags, XclTools::GetXclOrientFromRot( nRotation ), 2, 3 );
    2874           0 : }
    2875             : 
    2876           0 : void XclExpChTick::WriteBody( XclExpStream& rStrm )
    2877             : {
    2878           0 :     rStrm   << maData.mnMajor
    2879           0 :             << maData.mnMinor
    2880           0 :             << maData.mnLabelPos
    2881           0 :             << maData.mnBackMode;
    2882           0 :     rStrm.WriteZeroBytes( 16 );
    2883           0 :     rStrm   << maData.maTextColor
    2884           0 :             << maData.mnFlags;
    2885           0 :     if( GetBiff() == EXC_BIFF8 )
    2886           0 :         rStrm << GetPalette().GetColorIndex( mnTextColorId ) << maData.mnRotation;
    2887           0 : }
    2888             : 
    2889             : namespace {
    2890             : 
    2891             : /** Returns an API axis object from the passed coordinate system. */
    2892           0 : Reference< XAxis > lclGetApiAxis( Reference< XCoordinateSystem > xCoordSystem,
    2893             :         sal_Int32 nApiAxisDim, sal_Int32 nApiAxesSetIdx )
    2894             : {
    2895           0 :     Reference< XAxis > xAxis;
    2896           0 :     if( (nApiAxisDim >= 0) && xCoordSystem.is() ) try
    2897             :     {
    2898           0 :         xAxis = xCoordSystem->getAxisByDimension( nApiAxisDim, nApiAxesSetIdx );
    2899             :     }
    2900           0 :     catch( Exception& )
    2901             :     {
    2902             :     }
    2903           0 :     return xAxis;
    2904             : }
    2905             : 
    2906           0 : Reference< cssc::XAxis > lclGetApiChart1Axis( Reference< XChartDocument > xChartDoc,
    2907             :         sal_Int32 nApiAxisDim, sal_Int32 nApiAxesSetIdx )
    2908             : {
    2909           0 :     Reference< cssc::XAxis > xChart1Axis;
    2910             :     try
    2911             :     {
    2912           0 :         Reference< cssc::XChartDocument > xChart1Doc( xChartDoc, UNO_QUERY_THROW );
    2913           0 :         Reference< cssc::XAxisSupplier > xChart1AxisSupp( xChart1Doc->getDiagram(), UNO_QUERY_THROW );
    2914           0 :         switch( nApiAxesSetIdx )
    2915             :         {
    2916             :             case EXC_CHART_AXESSET_PRIMARY:
    2917           0 :                 xChart1Axis = xChart1AxisSupp->getAxis( nApiAxisDim );
    2918           0 :             break;
    2919             :             case EXC_CHART_AXESSET_SECONDARY:
    2920           0 :                 xChart1Axis = xChart1AxisSupp->getSecondaryAxis( nApiAxisDim );
    2921           0 :             break;
    2922           0 :         }
    2923             :     }
    2924           0 :     catch( Exception& )
    2925             :     {
    2926             :     }
    2927           0 :     return xChart1Axis;
    2928             : }
    2929             : 
    2930             : } // namespace
    2931             : 
    2932           0 : XclExpChAxis::XclExpChAxis( const XclExpChRoot& rRoot, sal_uInt16 nAxisType ) :
    2933             :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_AXIS, EXC_ID_CHAXIS, 18 ),
    2934           0 :     mnNumFmtIdx( EXC_FORMAT_NOTFOUND )
    2935             : {
    2936           0 :     maData.mnType = nAxisType;
    2937           0 : }
    2938             : 
    2939           0 : void XclExpChAxis::SetFont( XclExpChFontRef xFont, const Color& rColor, sal_uInt32 nColorId )
    2940             : {
    2941           0 :     mxFont = xFont;
    2942           0 :     if( mxTick )
    2943           0 :         mxTick->SetFontColor( rColor, nColorId );
    2944           0 : }
    2945             : 
    2946           0 : void XclExpChAxis::SetRotation( sal_uInt16 nRotation )
    2947             : {
    2948           0 :     if( mxTick )
    2949           0 :         mxTick->SetRotation( nRotation );
    2950           0 : }
    2951             : 
    2952           0 : void XclExpChAxis::Convert( Reference< XAxis > xAxis, Reference< XAxis > xCrossingAxis,
    2953             :         Reference< cssc::XAxis > xChart1Axis, const XclChExtTypeInfo& rTypeInfo )
    2954             : {
    2955           0 :     ScfPropertySet aAxisProp( xAxis );
    2956           0 :     bool bCategoryAxis = ((GetAxisType() == EXC_CHAXIS_X) && rTypeInfo.mbCategoryAxis) || (GetAxisType() == EXC_CHAXIS_Z);
    2957             : 
    2958             :     // axis line format -------------------------------------------------------
    2959             : 
    2960           0 :     mxAxisLine.reset( new XclExpChLineFormat( GetChRoot() ) );
    2961           0 :     mxAxisLine->Convert( GetChRoot(), aAxisProp, EXC_CHOBJTYPE_AXISLINE );
    2962             :     // #i58688# axis enabled
    2963           0 :     mxAxisLine->SetShowAxis( aAxisProp.GetBoolProperty( EXC_CHPROP_SHOW ) );
    2964             : 
    2965             :     // axis scaling and increment ---------------------------------------------
    2966             : 
    2967           0 :     ScfPropertySet aCrossingProp( xCrossingAxis );
    2968           0 :     if( bCategoryAxis )
    2969             :     {
    2970           0 :         mxLabelRange.reset( new XclExpChLabelRange( GetChRoot() ) );
    2971           0 :         mxLabelRange->SetTicksBetweenCateg( rTypeInfo.mbTicksBetweenCateg );
    2972           0 :         if( xAxis.is() )
    2973             :         {
    2974           0 :             ScfPropertySet aChart1AxisProp( xChart1Axis );
    2975             :             // #i71684# radar charts have reversed rotation direction
    2976           0 :             mxLabelRange->Convert( xAxis->getScaleData(), aChart1AxisProp, (GetAxisType() == EXC_CHAXIS_X) && (rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_RADAR) );
    2977             :         }
    2978             :         // get position of crossing axis on this axis from passed axis object
    2979           0 :         if( aCrossingProp.Is() )
    2980           0 :             mxLabelRange->ConvertAxisPosition( aCrossingProp );
    2981             :     }
    2982             :     else
    2983             :     {
    2984           0 :         mxValueRange.reset( new XclExpChValueRange( GetChRoot() ) );
    2985           0 :         if( xAxis.is() )
    2986           0 :             mxValueRange->Convert( xAxis->getScaleData() );
    2987             :         // get position of crossing axis on this axis from passed axis object
    2988           0 :         if( aCrossingProp.Is() )
    2989           0 :             mxValueRange->ConvertAxisPosition( aCrossingProp );
    2990             :     }
    2991             : 
    2992             :     // axis caption text ------------------------------------------------------
    2993             : 
    2994             :     // axis ticks properties
    2995           0 :     mxTick.reset( new XclExpChTick( GetChRoot() ) );
    2996           0 :     mxTick->Convert( aAxisProp, rTypeInfo, GetAxisType() );
    2997             : 
    2998             :     // axis label formatting and rotation
    2999           0 :     ConvertFontBase( GetChRoot(), aAxisProp );
    3000           0 :     ConvertRotationBase( GetChRoot(), aAxisProp, true );
    3001             : 
    3002             :     // axis number format
    3003           0 :     sal_Int32 nApiNumFmt = 0;
    3004           0 :     if( !bCategoryAxis && aAxisProp.GetProperty( nApiNumFmt, EXC_CHPROP_NUMBERFORMAT ) )
    3005           0 :         mnNumFmtIdx = GetNumFmtBuffer().Insert( static_cast< sal_uInt32 >( nApiNumFmt ) );
    3006             : 
    3007             :     // grid -------------------------------------------------------------------
    3008             : 
    3009           0 :     if( xAxis.is() )
    3010             :     {
    3011             :         // main grid
    3012           0 :         ScfPropertySet aGridProp( xAxis->getGridProperties() );
    3013           0 :         if( aGridProp.GetBoolProperty( EXC_CHPROP_SHOW ) )
    3014           0 :             mxMajorGrid = lclCreateLineFormat( GetChRoot(), aGridProp, EXC_CHOBJTYPE_GRIDLINE );
    3015             :         // sub grid
    3016           0 :         Sequence< Reference< XPropertySet > > aSubGridPropSeq = xAxis->getSubGridProperties();
    3017           0 :         if( aSubGridPropSeq.hasElements() )
    3018             :         {
    3019           0 :             ScfPropertySet aSubGridProp( aSubGridPropSeq[ 0 ] );
    3020           0 :             if( aSubGridProp.GetBoolProperty( EXC_CHPROP_SHOW ) )
    3021           0 :                 mxMinorGrid = lclCreateLineFormat( GetChRoot(), aSubGridProp, EXC_CHOBJTYPE_GRIDLINE );
    3022           0 :         }
    3023           0 :     }
    3024           0 : }
    3025             : 
    3026           0 : void XclExpChAxis::ConvertWall( XDiagramRef xDiagram )
    3027             : {
    3028           0 :     if( xDiagram.is() ) switch( GetAxisType() )
    3029             :     {
    3030             :         case EXC_CHAXIS_X:
    3031             :         {
    3032           0 :             ScfPropertySet aWallProp( xDiagram->getWall() );
    3033           0 :             mxWallFrame = lclCreateFrame( GetChRoot(), aWallProp, EXC_CHOBJTYPE_WALL3D );
    3034             :         }
    3035           0 :         break;
    3036             :         case EXC_CHAXIS_Y:
    3037             :         {
    3038           0 :             ScfPropertySet aFloorProp( xDiagram->getFloor() );
    3039           0 :             mxWallFrame = lclCreateFrame( GetChRoot(), aFloorProp, EXC_CHOBJTYPE_FLOOR3D );
    3040             :         }
    3041           0 :         break;
    3042             :         default:
    3043           0 :             mxWallFrame.reset();
    3044             :     }
    3045           0 : }
    3046             : 
    3047           0 : void XclExpChAxis::WriteSubRecords( XclExpStream& rStrm )
    3048             : {
    3049           0 :     lclSaveRecord( rStrm, mxLabelRange );
    3050           0 :     lclSaveRecord( rStrm, mxValueRange );
    3051           0 :     if( mnNumFmtIdx != EXC_FORMAT_NOTFOUND )
    3052           0 :         XclExpUInt16Record( EXC_ID_CHFORMAT, mnNumFmtIdx ).Save( rStrm );
    3053           0 :     lclSaveRecord( rStrm, mxTick );
    3054           0 :     lclSaveRecord( rStrm, mxFont );
    3055           0 :     lclSaveRecord( rStrm, mxAxisLine, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_AXISLINE );
    3056           0 :     lclSaveRecord( rStrm, mxMajorGrid, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_MAJORGRID );
    3057           0 :     lclSaveRecord( rStrm, mxMinorGrid, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_MINORGRID );
    3058           0 :     lclSaveRecord( rStrm, mxWallFrame, EXC_ID_CHAXISLINE, EXC_CHAXISLINE_WALLS );
    3059           0 : }
    3060             : 
    3061           0 : void XclExpChAxis::WriteBody( XclExpStream& rStrm )
    3062             : {
    3063           0 :     rStrm << maData.mnType;
    3064           0 :     rStrm.WriteZeroBytes( 16 );
    3065           0 : }
    3066             : 
    3067           0 : XclExpChAxesSet::XclExpChAxesSet( const XclExpChRoot& rRoot, sal_uInt16 nAxesSetId ) :
    3068           0 :     XclExpChGroupBase( rRoot, EXC_CHFRBLOCK_TYPE_AXESSET, EXC_ID_CHAXESSET, 18 )
    3069             : {
    3070           0 :     maData.mnAxesSetId = nAxesSetId;
    3071           0 :     SetFutureRecordContext( 0, nAxesSetId );
    3072             : 
    3073             :     /*  Need to set a reasonable size for the plot area, otherwise Excel will
    3074             :         move away embedded shapes while auto-sizing the plot area. This is just
    3075             :         a wild guess, but will be fixed with implementing manual positioning of
    3076             :         chart elements. */
    3077           0 :     maData.maRect.mnX = 262;
    3078           0 :     maData.maRect.mnY = 626;
    3079           0 :     maData.maRect.mnWidth = 3187;
    3080           0 :     maData.maRect.mnHeight = 2633;
    3081           0 : }
    3082             : 
    3083           0 : sal_uInt16 XclExpChAxesSet::Convert( Reference< XDiagram > xDiagram, sal_uInt16 nFirstGroupIdx )
    3084             : {
    3085             :     /*  First unused chart type group index is passed to be able to continue
    3086             :         counting of chart type groups for secondary axes set. */
    3087           0 :     sal_uInt16 nGroupIdx = nFirstGroupIdx;
    3088           0 :     Reference< XCoordinateSystemContainer > xCoordSysCont( xDiagram, UNO_QUERY );
    3089           0 :     if( xCoordSysCont.is() )
    3090             :     {
    3091           0 :         Sequence< Reference< XCoordinateSystem > > aCoordSysSeq = xCoordSysCont->getCoordinateSystems();
    3092           0 :         if( aCoordSysSeq.getLength() > 0 )
    3093             :         {
    3094             :             /*  Process first coordinate system only. Import filter puts all
    3095             :                 chart types into one coordinate system. */
    3096           0 :             Reference< XCoordinateSystem > xCoordSystem = aCoordSysSeq[ 0 ];
    3097           0 :             sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
    3098             : 
    3099             :             // 3d mode
    3100           0 :             bool b3dChart = xCoordSystem.is() && (xCoordSystem->getDimension() == 3);
    3101             : 
    3102             :             // percent charts
    3103             :             namespace ApiAxisType = cssc2::AxisType;
    3104           0 :             Reference< XAxis > xApiYAxis = lclGetApiAxis( xCoordSystem, EXC_CHART_AXIS_Y, nApiAxesSetIdx );
    3105           0 :             bool bPercent = xApiYAxis.is() && (xApiYAxis->getScaleData().AxisType == ApiAxisType::PERCENT);
    3106             : 
    3107             :             // connector lines in bar charts
    3108           0 :             ScfPropertySet aDiaProp( xDiagram );
    3109           0 :             bool bConnectBars = aDiaProp.GetBoolProperty( EXC_CHPROP_CONNECTBARS );
    3110             : 
    3111             :             // swapped axes sets
    3112           0 :             ScfPropertySet aCoordSysProp( xCoordSystem );
    3113           0 :             bool bSwappedAxesSet = aCoordSysProp.GetBoolProperty( EXC_CHPROP_SWAPXANDYAXIS );
    3114             : 
    3115             :             // X axis for later use
    3116           0 :             Reference< XAxis > xApiXAxis = lclGetApiAxis( xCoordSystem, EXC_CHART_AXIS_X, nApiAxesSetIdx );
    3117             :             // X axis labels
    3118           0 :             ScfPropertySet aXAxisProp( xApiXAxis );
    3119           0 :             bool bHasXLabels = aXAxisProp.GetBoolProperty( EXC_CHPROP_DISPLAYLABELS );
    3120             : 
    3121             :             // process chart types
    3122           0 :             Reference< XChartTypeContainer > xChartTypeCont( xCoordSystem, UNO_QUERY );
    3123           0 :             if( xChartTypeCont.is() )
    3124             :             {
    3125           0 :                 Sequence< Reference< XChartType > > aChartTypeSeq = xChartTypeCont->getChartTypes();
    3126           0 :                 const Reference< XChartType >* pBeg = aChartTypeSeq.getConstArray();
    3127           0 :                 const Reference< XChartType >* pEnd = pBeg + aChartTypeSeq.getLength();
    3128           0 :                 for( const Reference< XChartType >* pIt = pBeg; pIt != pEnd; ++pIt )
    3129             :                 {
    3130           0 :                     XclExpChTypeGroupRef xTypeGroup( new XclExpChTypeGroup( GetChRoot(), nGroupIdx ) );
    3131           0 :                     xTypeGroup->ConvertType( xDiagram, *pIt, nApiAxesSetIdx, b3dChart, bSwappedAxesSet, bHasXLabels );
    3132             :                     /*  If new chart type group cannot be inserted into a combination
    3133             :                         chart with existing type groups, insert all series into last
    3134             :                         contained chart type group instead of creating a new group. */
    3135           0 :                     XclExpChTypeGroupRef xLastGroup = GetLastTypeGroup();
    3136           0 :                     if( xLastGroup && !(xTypeGroup->IsCombinable2d() && xLastGroup->IsCombinable2d()) )
    3137             :                     {
    3138           0 :                         xLastGroup->ConvertSeries( xDiagram, *pIt, nApiAxesSetIdx, bPercent, bConnectBars );
    3139             :                     }
    3140             :                     else
    3141             :                     {
    3142           0 :                         xTypeGroup->ConvertSeries( xDiagram, *pIt, nApiAxesSetIdx, bPercent, bConnectBars );
    3143           0 :                         if( xTypeGroup->IsValidGroup() )
    3144             :                         {
    3145           0 :                             maTypeGroups.AppendRecord( xTypeGroup );
    3146           0 :                             ++nGroupIdx;
    3147             :                         }
    3148             :                     }
    3149           0 :                 }
    3150             :             }
    3151             : 
    3152           0 :             if( XclExpChTypeGroup* pGroup = GetFirstTypeGroup().get() )
    3153             :             {
    3154           0 :                 const XclChExtTypeInfo& rTypeInfo = pGroup->GetTypeInfo();
    3155             : 
    3156             :                 // create axes according to chart type (no axes for pie and donut charts)
    3157           0 :                 if( rTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE )
    3158             :                 {
    3159           0 :                     ConvertAxis( mxXAxis, EXC_CHAXIS_X, mxXAxisTitle, EXC_CHOBJLINK_XAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_Y );
    3160           0 :                     ConvertAxis( mxYAxis, EXC_CHAXIS_Y, mxYAxisTitle, EXC_CHOBJLINK_YAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_X );
    3161           0 :                     if( pGroup->Is3dDeepChart() )
    3162           0 :                         ConvertAxis( mxZAxis, EXC_CHAXIS_Z, mxZAxisTitle, EXC_CHOBJLINK_ZAXIS, xCoordSystem, rTypeInfo, EXC_CHART_AXIS_NONE );
    3163             :                 }
    3164             : 
    3165             :                 // X axis category ranges
    3166           0 :                 if( rTypeInfo.mbCategoryAxis && xApiXAxis.is() )
    3167             :                 {
    3168           0 :                     const ScaleData aScaleData = xApiXAxis->getScaleData();
    3169           0 :                     for( size_t nIdx = 0, nSize = maTypeGroups.GetSize(); nIdx < nSize; ++nIdx )
    3170           0 :                         maTypeGroups.GetRecord( nIdx )->ConvertCategSequence( aScaleData.Categories );
    3171             :                 }
    3172             : 
    3173             :                 // legend
    3174           0 :                 if( xDiagram.is() && (GetAxesSetId() == EXC_CHAXESSET_PRIMARY) )
    3175             :                 {
    3176           0 :                     Reference< XLegend > xLegend = xDiagram->getLegend();
    3177           0 :                     if( xLegend.is() )
    3178             :                     {
    3179           0 :                         ScfPropertySet aLegendProp( xLegend );
    3180           0 :                         pGroup->ConvertLegend( aLegendProp );
    3181           0 :                     }
    3182             :                 }
    3183           0 :             }
    3184           0 :         }
    3185             :     }
    3186             : 
    3187             :     // wall/floor/diagram frame formatting
    3188           0 :     if( xDiagram.is() && (GetAxesSetId() == EXC_CHAXESSET_PRIMARY) )
    3189             :     {
    3190           0 :         XclExpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
    3191           0 :         if( xTypeGroup && xTypeGroup->Is3dWallChart() )
    3192             :         {
    3193             :             // wall/floor formatting (3D charts)
    3194           0 :             if( mxXAxis )
    3195           0 :                 mxXAxis->ConvertWall( xDiagram );
    3196           0 :             if( mxYAxis )
    3197           0 :                 mxYAxis->ConvertWall( xDiagram );
    3198             :         }
    3199             :         else
    3200             :         {
    3201             :             // diagram background formatting
    3202           0 :             ScfPropertySet aWallProp( xDiagram->getWall() );
    3203           0 :             mxPlotFrame = lclCreateFrame( GetChRoot(), aWallProp, EXC_CHOBJTYPE_PLOTFRAME );
    3204           0 :         }
    3205             :     }
    3206             : 
    3207             :     // inner and outer plot area position and size
    3208             :     try
    3209             :     {
    3210           0 :         Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
    3211           0 :         Reference< cssc::XDiagramPositioning > xPositioning( xChart1Doc->getDiagram(), UNO_QUERY_THROW );
    3212             :         // set manual flag in chart data
    3213           0 :         if( !xPositioning->isAutomaticDiagramPositioning() )
    3214           0 :             GetChartData().SetManualPlotArea();
    3215             :         // the CHAXESSET record contains the inner plot area
    3216           0 :         maData.maRect = CalcChartRectFromHmm( xPositioning->calculateDiagramPositionExcludingAxes() );
    3217             :         // the embedded CHFRAMEPOS record contains the outer plot area
    3218           0 :         mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
    3219             :         // for pie charts, always use inner plot area size to exclude the data labels as Excel does
    3220           0 :         const XclExpChTypeGroup* pFirstTypeGroup = GetFirstTypeGroup().get();
    3221           0 :         bool bPieChart = pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE);
    3222           0 :         mxFramePos->GetFramePosData().maRect = bPieChart ? maData.maRect :
    3223           0 :             CalcChartRectFromHmm( xPositioning->calculateDiagramPositionIncludingAxes() );
    3224             :     }
    3225           0 :     catch( Exception& )
    3226             :     {
    3227             :     }
    3228             : 
    3229             :     // return first unused chart type group index for next axes set
    3230           0 :     return nGroupIdx;
    3231             : }
    3232             : 
    3233           0 : bool XclExpChAxesSet::Is3dChart() const
    3234             : {
    3235           0 :     XclExpChTypeGroupRef xTypeGroup = GetFirstTypeGroup();
    3236           0 :     return xTypeGroup && xTypeGroup->Is3dChart();
    3237             : }
    3238             : 
    3239           0 : void XclExpChAxesSet::WriteSubRecords( XclExpStream& rStrm )
    3240             : {
    3241           0 :     lclSaveRecord( rStrm, mxFramePos );
    3242           0 :     lclSaveRecord( rStrm, mxXAxis );
    3243           0 :     lclSaveRecord( rStrm, mxYAxis );
    3244           0 :     lclSaveRecord( rStrm, mxZAxis );
    3245           0 :     lclSaveRecord( rStrm, mxXAxisTitle );
    3246           0 :     lclSaveRecord( rStrm, mxYAxisTitle );
    3247           0 :     lclSaveRecord( rStrm, mxZAxisTitle );
    3248           0 :     if( mxPlotFrame )
    3249             :     {
    3250           0 :         XclExpEmptyRecord( EXC_ID_CHPLOTFRAME ).Save( rStrm );
    3251           0 :         mxPlotFrame->Save( rStrm );
    3252             :     }
    3253           0 :     maTypeGroups.Save( rStrm );
    3254           0 : }
    3255             : 
    3256           0 : XclExpChTypeGroupRef XclExpChAxesSet::GetFirstTypeGroup() const
    3257             : {
    3258           0 :     return maTypeGroups.GetFirstRecord();
    3259             : }
    3260             : 
    3261           0 : XclExpChTypeGroupRef XclExpChAxesSet::GetLastTypeGroup() const
    3262             : {
    3263           0 :     return maTypeGroups.GetLastRecord();
    3264             : }
    3265             : 
    3266           0 : void XclExpChAxesSet::ConvertAxis(
    3267             :         XclExpChAxisRef& rxChAxis, sal_uInt16 nAxisType,
    3268             :         XclExpChTextRef& rxChAxisTitle, sal_uInt16 nTitleTarget,
    3269             :         Reference< XCoordinateSystem > xCoordSystem, const XclChExtTypeInfo& rTypeInfo,
    3270             :         sal_Int32 nCrossingAxisDim )
    3271             : {
    3272             :     // create and convert axis object
    3273           0 :     rxChAxis.reset( new XclExpChAxis( GetChRoot(), nAxisType ) );
    3274           0 :     sal_Int32 nApiAxisDim = rxChAxis->GetApiAxisDimension();
    3275           0 :     sal_Int32 nApiAxesSetIdx = GetApiAxesSetIndex();
    3276           0 :     Reference< XAxis > xAxis = lclGetApiAxis( xCoordSystem, nApiAxisDim, nApiAxesSetIdx );
    3277           0 :     Reference< XAxis > xCrossingAxis = lclGetApiAxis( xCoordSystem, nCrossingAxisDim, nApiAxesSetIdx );
    3278           0 :     Reference< cssc::XAxis > xChart1Axis = lclGetApiChart1Axis( GetChartDocument(), nApiAxisDim, nApiAxesSetIdx );
    3279           0 :     rxChAxis->Convert( xAxis, xCrossingAxis, xChart1Axis, rTypeInfo );
    3280             : 
    3281             :     // create and convert axis title
    3282           0 :     Reference< XTitled > xTitled( xAxis, UNO_QUERY );
    3283           0 :     rxChAxisTitle = lclCreateTitle( GetChRoot(), xTitled, nTitleTarget );
    3284           0 : }
    3285             : 
    3286           0 : void XclExpChAxesSet::WriteBody( XclExpStream& rStrm )
    3287             : {
    3288           0 :     rStrm << maData.mnAxesSetId << maData.maRect;
    3289           0 : }
    3290             : 
    3291             : // The chart object ===========================================================
    3292             : 
    3293           0 : static void lcl_getChartSubTitle(const Reference<XChartDocument>& xChartDoc,
    3294             :                                  OUString& rSubTitle)
    3295             : {
    3296           0 :     Reference< ::com::sun::star::chart::XChartDocument > xChartDoc1(xChartDoc, UNO_QUERY);
    3297           0 :     if (!xChartDoc1.is())
    3298           0 :         return;
    3299             : 
    3300           0 :     Reference< XPropertySet > xProp(xChartDoc1->getSubTitle(), UNO_QUERY);
    3301           0 :     if (!xProp.is())
    3302           0 :         return;
    3303             : 
    3304           0 :     OUString aTitle;
    3305           0 :     Any any = xProp->getPropertyValue("String");
    3306           0 :     if (any >>= aTitle)
    3307           0 :         rSubTitle = aTitle;
    3308             : }
    3309             : 
    3310           0 : XclExpChChart::XclExpChChart( const XclExpRoot& rRoot,
    3311             :         Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) :
    3312           0 :     XclExpChGroupBase( XclExpChRoot( rRoot, *this ), EXC_CHFRBLOCK_TYPE_CHART, EXC_ID_CHCHART, 16 )
    3313             : {
    3314           0 :     Size aPtSize = OutputDevice::LogicToLogic( rChartRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( MAP_POINT ) );
    3315             :     // rectangle is stored in 16.16 fixed-point format
    3316           0 :     maRect.mnX = maRect.mnY = 0;
    3317           0 :     maRect.mnWidth = static_cast< sal_Int32 >( aPtSize.Width() << 16 );
    3318           0 :     maRect.mnHeight = static_cast< sal_Int32 >( aPtSize.Height() << 16 );
    3319             : 
    3320             :     // global chart properties (default values)
    3321           0 :     ::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, false );
    3322           0 :     ::set_flag( maProps.mnFlags, EXC_CHPROPS_MANPLOTAREA );
    3323           0 :     maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP;
    3324             : 
    3325             :     // always create both axes set objects
    3326           0 :     mxPrimAxesSet.reset( new XclExpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) );
    3327           0 :     mxSecnAxesSet.reset( new XclExpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) );
    3328             : 
    3329           0 :     if( xChartDoc.is() )
    3330             :     {
    3331           0 :         Reference< XDiagram > xDiagram = xChartDoc->getFirstDiagram();
    3332             : 
    3333             :         // global chart properties (only 'include hidden cells' attribute for now)
    3334           0 :         ScfPropertySet aDiagramProp( xDiagram );
    3335           0 :         bool bIncludeHidden = aDiagramProp.GetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS );
    3336           0 :         ::set_flag( maProps.mnFlags,  EXC_CHPROPS_SHOWVISIBLEONLY, !bIncludeHidden );
    3337             : 
    3338             :         // initialize API conversion (remembers xChartDoc and rChartRect internally)
    3339           0 :         InitConversion( xChartDoc, rChartRect );
    3340             : 
    3341             :         // chart frame
    3342           0 :         ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
    3343           0 :         mxFrame = lclCreateFrame( GetChRoot(), aFrameProp, EXC_CHOBJTYPE_BACKGROUND );
    3344             : 
    3345             :         // chart title
    3346           0 :         Reference< XTitled > xTitled( xChartDoc, UNO_QUERY );
    3347           0 :         OUString aSubTitle;
    3348           0 :         lcl_getChartSubTitle(xChartDoc, aSubTitle);
    3349           0 :         mxTitle = lclCreateTitle( GetChRoot(), xTitled, EXC_CHOBJLINK_TITLE,
    3350           0 :                                   !aSubTitle.isEmpty() ? &aSubTitle : NULL );
    3351             : 
    3352             :         // diagrams (axes sets)
    3353           0 :         sal_uInt16 nFreeGroupIdx = mxPrimAxesSet->Convert( xDiagram, 0 );
    3354           0 :         if( !mxPrimAxesSet->Is3dChart() )
    3355           0 :             mxSecnAxesSet->Convert( xDiagram, nFreeGroupIdx );
    3356             : 
    3357             :         // treatment of missing values
    3358           0 :         ScfPropertySet aDiaProp( xDiagram );
    3359           0 :         sal_Int32 nMissingValues = 0;
    3360           0 :         if( aDiaProp.GetProperty( nMissingValues, EXC_CHPROP_MISSINGVALUETREATMENT ) )
    3361             :         {
    3362             :             using namespace cssc::MissingValueTreatment;
    3363           0 :             switch( nMissingValues )
    3364             :             {
    3365           0 :                 case LEAVE_GAP: maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP;           break;
    3366           0 :                 case USE_ZERO:  maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_ZERO;           break;
    3367           0 :                 case CONTINUE:  maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_INTERPOLATE;    break;
    3368             :             }
    3369             :         }
    3370             : 
    3371             :         // finish API conversion
    3372           0 :         FinishConversion();
    3373             :     }
    3374           0 : }
    3375             : 
    3376           0 : XclExpChSeriesRef XclExpChChart::CreateSeries()
    3377             : {
    3378           0 :     XclExpChSeriesRef xSeries;
    3379           0 :     sal_uInt16 nSeriesIdx = static_cast< sal_uInt16 >( maSeries.GetSize() );
    3380           0 :     if( nSeriesIdx <= EXC_CHSERIES_MAXSERIES )
    3381             :     {
    3382           0 :         xSeries.reset( new XclExpChSeries( GetChRoot(), nSeriesIdx ) );
    3383           0 :         maSeries.AppendRecord( xSeries );
    3384             :     }
    3385           0 :     return xSeries;
    3386             : }
    3387             : 
    3388           0 : void XclExpChChart::RemoveLastSeries()
    3389             : {
    3390           0 :     if( !maSeries.IsEmpty() )
    3391           0 :         maSeries.RemoveRecord( maSeries.GetSize() - 1 );
    3392           0 : }
    3393             : 
    3394           0 : void XclExpChChart::SetDataLabel( XclExpChTextRef xText )
    3395             : {
    3396           0 :     if( xText )
    3397           0 :         maLabels.AppendRecord( xText );
    3398           0 : }
    3399             : 
    3400           0 : void XclExpChChart::SetManualPlotArea()
    3401             : {
    3402             :     // this flag does not exist in BIFF5
    3403           0 :     if( GetBiff() == EXC_BIFF8 )
    3404           0 :         ::set_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
    3405           0 : }
    3406             : 
    3407           0 : void XclExpChChart::WriteSubRecords( XclExpStream& rStrm )
    3408             : {
    3409             :     // background format
    3410           0 :     lclSaveRecord( rStrm, mxFrame );
    3411             : 
    3412             :     // data series
    3413           0 :     maSeries.Save( rStrm );
    3414             : 
    3415             :     // CHPROPERTIES record
    3416           0 :     rStrm.StartRecord( EXC_ID_CHPROPERTIES, 4 );
    3417           0 :     rStrm << maProps.mnFlags << maProps.mnEmptyMode << sal_uInt8( 0 );
    3418           0 :     rStrm.EndRecord();
    3419             : 
    3420             :     // axes sets (always save primary axes set)
    3421           0 :     sal_uInt16 nUsedAxesSets = mxSecnAxesSet->IsValidAxesSet() ? 2 : 1;
    3422           0 :     XclExpUInt16Record( EXC_ID_CHUSEDAXESSETS, nUsedAxesSets ).Save( rStrm );
    3423           0 :     mxPrimAxesSet->Save( rStrm );
    3424           0 :     if( mxSecnAxesSet->IsValidAxesSet() )
    3425           0 :         mxSecnAxesSet->Save( rStrm );
    3426             : 
    3427             :     // chart title and data labels
    3428           0 :     lclSaveRecord( rStrm, mxTitle );
    3429           0 :     maLabels.Save( rStrm );
    3430           0 : }
    3431             : 
    3432           0 : void XclExpChChart::WriteBody( XclExpStream& rStrm )
    3433             : {
    3434           0 :      rStrm << maRect;
    3435           0 : }
    3436             : 
    3437           0 : XclExpChartDrawing::XclExpChartDrawing( const XclExpRoot& rRoot,
    3438             :         const Reference< XModel >& rxModel, const Size& rChartSize ) :
    3439           0 :     XclExpRoot( rRoot )
    3440             : {
    3441           0 :     if( (rChartSize.Width() > 0) && (rChartSize.Height() > 0) )
    3442             :     {
    3443           0 :         ScfPropertySet aPropSet( rxModel );
    3444           0 :         Reference< XShapes > xShapes;
    3445           0 :         if( aPropSet.GetProperty( xShapes, EXC_CHPROP_ADDITIONALSHAPES ) && xShapes.is() && (xShapes->getCount() > 0) )
    3446             :         {
    3447             :             /*  Create a new independent object manager with own DFF stream for the
    3448             :                 DGCONTAINER, pass global manager as parent for shared usage of
    3449             :                 global DFF data (picture container etc.). */
    3450           0 :             mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_TOTALUNITS, EXC_CHART_TOTALUNITS ) );
    3451             :             // initialize the drawing object list
    3452           0 :             mxObjMgr->StartSheet();
    3453             :             // process the draw page (convert all shapes)
    3454           0 :             mxObjRecs = mxObjMgr->ProcessDrawing( xShapes );
    3455             :             // finalize the DFF stream
    3456           0 :             mxObjMgr->EndDocument();
    3457           0 :         }
    3458             :     }
    3459           0 : }
    3460             : 
    3461           0 : XclExpChartDrawing::~XclExpChartDrawing()
    3462             : {
    3463           0 : }
    3464             : 
    3465           0 : void XclExpChartDrawing::Save( XclExpStream& rStrm )
    3466             : {
    3467           0 :     if( mxObjRecs )
    3468           0 :         mxObjRecs->Save( rStrm );
    3469           0 : }
    3470             : 
    3471           0 : XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Rectangle& rChartRect ) :
    3472             :     XclExpSubStream( EXC_BOF_CHART ),
    3473           0 :     XclExpRoot( rRoot )
    3474             : {
    3475           0 :     AppendNewRecord( new XclExpChartPageSettings( rRoot ) );
    3476           0 :     AppendNewRecord( new XclExpBoolRecord( EXC_ID_PROTECT, false ) );
    3477           0 :     AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rChartRect.GetSize() ) );
    3478           0 :     AppendNewRecord( new XclExpUInt16Record( EXC_ID_CHUNITS, EXC_CHUNITS_TWIPS ) );
    3479             : 
    3480           0 :     Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY );
    3481           0 :     AppendNewRecord( new XclExpChChart( rRoot, xChartDoc, rChartRect ) );
    3482           0 : }
    3483             : 
    3484             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10