1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xichart.cxx,v $
10 * $Revision: 1.20.62.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "xichart.hxx"
39 #include <com/sun/star/frame/XModel.hpp>
40 #include <com/sun/star/drawing/Direction3D.hpp>
41 #include <com/sun/star/drawing/ProjectionMode.hpp>
42 #include <com/sun/star/drawing/ShadeMode.hpp>
43 #include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
44 #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
45 #include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
46 #include <com/sun/star/chart/ChartAxisPosition.hpp>
47 #include <com/sun/star/chart/XChartDocument.hpp>
48 #include <com/sun/star/chart2/XChartDocument.hpp>
49 #include <com/sun/star/chart2/XDiagram.hpp>
50 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
51 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
52 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
53 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
54 #include <com/sun/star/chart2/XTitled.hpp>
55 #include <com/sun/star/chart2/data/XDataProvider.hpp>
56 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
57 #include <com/sun/star/chart2/data/XDataSink.hpp>
58 #include <com/sun/star/chart2/AxisType.hpp>
59 #include <com/sun/star/chart2/CurveStyle.hpp>
60 #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
61 #include <com/sun/star/chart2/DataPointLabel.hpp>
62 #include <com/sun/star/chart2/StackingDirection.hpp>
63 #include <com/sun/star/chart2/TickmarkStyle.hpp>
64 #include <com/sun/star/chart/DataLabelPlacement.hpp>
65 #include <com/sun/star/chart/ErrorBarStyle.hpp>
66 #include <com/sun/star/chart/MissingValueTreatment.hpp>
68 #include <sfx2/objsh.hxx>
70 #include "document.hxx"
71 #include "drwlayer.hxx"
72 #include "rangeutl.hxx"
73 #include "tokenarray.hxx"
75 #include "compiler.hxx"
76 #include "reftokenhelper.hxx"
77 #include "chartlis.hxx"
78 #include "fprogressbar.hxx"
79 #include "xltracer.hxx"
80 #include "xistream.hxx"
81 #include "xiformula.hxx"
82 #include "xistyle.hxx"
85 #include "xiescher.hxx"
87 using ::rtl::OUString
;
88 using ::rtl::OUStringBuffer
;
89 using ::com::sun::star::uno::Any
;
90 using ::com::sun::star::uno::Reference
;
91 using ::com::sun::star::uno::Sequence
;
92 using ::com::sun::star::uno::UNO_QUERY
;
93 using ::com::sun::star::uno::UNO_QUERY_THROW
;
94 using ::com::sun::star::uno::Exception
;
95 using ::com::sun::star::beans::XPropertySet
;
96 using ::com::sun::star::lang::XMultiServiceFactory
;
97 using ::com::sun::star::frame::XModel
;
98 using ::com::sun::star::util::XNumberFormatsSupplier
;
100 using ::com::sun::star::chart2::XChartDocument
;
101 using ::com::sun::star::chart2::XDiagram
;
102 using ::com::sun::star::chart2::XCoordinateSystemContainer
;
103 using ::com::sun::star::chart2::XCoordinateSystem
;
104 using ::com::sun::star::chart2::XChartTypeContainer
;
105 using ::com::sun::star::chart2::XChartType
;
106 using ::com::sun::star::chart2::XDataSeriesContainer
;
107 using ::com::sun::star::chart2::XDataSeries
;
108 using ::com::sun::star::chart2::XRegressionCurve
;
109 using ::com::sun::star::chart2::XRegressionCurveContainer
;
110 using ::com::sun::star::chart2::XAxis
;
111 using ::com::sun::star::chart2::XScaling
;
112 using ::com::sun::star::chart2::ScaleData
;
113 using ::com::sun::star::chart2::IncrementData
;
114 using ::com::sun::star::chart2::SubIncrement
;
115 using ::com::sun::star::chart2::XLegend
;
116 using ::com::sun::star::chart2::XTitled
;
117 using ::com::sun::star::chart2::XTitle
;
118 using ::com::sun::star::chart2::XFormattedString
;
120 using ::com::sun::star::chart2::data::XDataProvider
;
121 using ::com::sun::star::chart2::data::XDataReceiver
;
122 using ::com::sun::star::chart2::data::XDataSink
;
123 using ::com::sun::star::chart2::data::XLabeledDataSequence
;
124 using ::com::sun::star::chart2::data::XDataSequence
;
126 using ::formula::FormulaToken
;
127 using ::formula::StackVar
;
131 // Helpers ====================================================================
135 XclImpStream
& operator>>( XclImpStream
& rStrm
, XclChRectangle
& rRect
)
137 return rStrm
>> rRect
.mnX
>> rRect
.mnY
>> rRect
.mnWidth
>> rRect
.mnHeight
;
140 template< typename Type
>
141 void lclSetValueOrClearAny( Any
& rAny
, const Type
& rValue
, bool bClear
)
149 void lclSetExpValueOrClearAny( Any
& rAny
, double fValue
, bool bLogScale
, bool bClear
)
151 if( !bClear
&& bLogScale
)
152 fValue
= pow( 10.0, fValue
);
153 lclSetValueOrClearAny( rAny
, fValue
, bClear
);
158 // Common =====================================================================
160 /** Stores global data needed in various classes of the Chart import filter. */
161 class XclImpChRootData
: public XclChRootData
164 explicit XclImpChRootData( XclImpChChart
* pChartData
);
166 /** Returns a reference to the parent chart data object. */
167 inline XclImpChChart
& GetChartData() const { return *mpChartData
; }
170 XclImpChChart
* mpChartData
; /// Pointer to the chart data object.
173 XclImpChRootData::XclImpChRootData( XclImpChChart
* pChartData
) :
174 mpChartData( pChartData
)
178 // ----------------------------------------------------------------------------
180 XclImpChRoot::XclImpChRoot( const XclImpRoot
& rRoot
, XclImpChChart
* pChartData
) :
182 mxChData( new XclImpChRootData( pChartData
) )
186 XclImpChRoot::~XclImpChRoot()
190 XclImpChChart
& XclImpChRoot::GetChartData() const
192 return mxChData
->GetChartData();
195 const XclChTypeInfo
& XclImpChRoot::GetChartTypeInfo( XclChTypeId eType
) const
197 return mxChData
->GetTypeInfoProvider().GetTypeInfo( eType
);
200 const XclChTypeInfo
& XclImpChRoot::GetChartTypeInfo( sal_uInt16 nRecId
) const
202 return mxChData
->GetTypeInfoProvider().GetTypeInfoFromRecId( nRecId
);
205 const XclChFormatInfo
& XclImpChRoot::GetFormatInfo( XclChObjectType eObjType
) const
207 return mxChData
->GetFormatInfoProvider().GetFormatInfo( eObjType
);
210 Color
XclImpChRoot::GetFontAutoColor() const
212 return GetPalette().GetColor( EXC_COLOR_CHWINDOWTEXT
);
215 Color
XclImpChRoot::GetSeriesLineAutoColor( sal_uInt16 nFormatIdx
) const
217 return GetPalette().GetColor( XclChartHelper::GetSeriesLineAutoColorIdx( nFormatIdx
) );
220 Color
XclImpChRoot::GetSeriesFillAutoColor( sal_uInt16 nFormatIdx
) const
222 const XclImpPalette
& rPal
= GetPalette();
223 Color aColor
= rPal
.GetColor( XclChartHelper::GetSeriesFillAutoColorIdx( nFormatIdx
) );
224 sal_uInt8 nTrans
= XclChartHelper::GetSeriesFillAutoTransp( nFormatIdx
);
225 return ScfTools::GetMixedColor( aColor
, rPal
.GetColor( EXC_COLOR_CHWINDOWBACK
), nTrans
);
228 void XclImpChRoot::InitConversion( Reference
< XChartDocument
> xChartDoc
) const
230 // create formatting object tables
231 mxChData
->InitConversion( xChartDoc
);
233 // lock the model to suppress any internal updates
234 Reference
< XModel
> xModel( xChartDoc
, UNO_QUERY
);
236 xModel
->lockControllers();
238 SfxObjectShell
* pDocShell
= GetDocShell();
239 Reference
< XDataReceiver
> xDataRec( xChartDoc
, UNO_QUERY
);
240 if( pDocShell
&& xDataRec
.is() )
242 // create and register a data provider
243 Reference
< XDataProvider
> xDataProv(
244 ScfApiHelper::CreateInstance( pDocShell
, SERVICE_CHART2_DATAPROVIDER
), UNO_QUERY
);
246 xDataRec
->attachDataProvider( xDataProv
);
247 // attach the number formatter
248 Reference
< XNumberFormatsSupplier
> xNumFmtSupp( pDocShell
->GetModel(), UNO_QUERY
);
249 if( xNumFmtSupp
.is() )
250 xDataRec
->attachNumberFormatsSupplier( xNumFmtSupp
);
254 void XclImpChRoot::FinishConversion( ScfProgressBar
& rProgress
) const
256 rProgress
.Progress( EXC_CHART_PROGRESS_SIZE
);
258 Reference
< XModel
> xModel( mxChData
->GetChartDoc(), UNO_QUERY
);
260 xModel
->unlockControllers();
261 rProgress
.Progress( EXC_CHART_PROGRESS_SIZE
);
263 mxChData
->FinishConversion();
266 Reference
< XDataProvider
> XclImpChRoot::GetDataProvider() const
268 return mxChData
->GetChartDoc()->getDataProvider();
271 void XclImpChRoot::ConvertLineFormat( ScfPropertySet
& rPropSet
,
272 const XclChLineFormat
& rLineFmt
, XclChPropertyMode ePropMode
) const
274 GetChartPropSetHelper().WriteLineProperties(
275 rPropSet
, mxChData
->GetLineDashTable(), rLineFmt
, ePropMode
);
278 void XclImpChRoot::ConvertAreaFormat( ScfPropertySet
& rPropSet
,
279 const XclChAreaFormat
& rAreaFmt
, XclChPropertyMode ePropMode
) const
281 GetChartPropSetHelper().WriteAreaProperties( rPropSet
, rAreaFmt
, ePropMode
);
284 void XclImpChRoot::ConvertEscherFormat( ScfPropertySet
& rPropSet
,
285 const XclChEscherFormat
& rEscherFmt
, const XclChPicFormat
& rPicFmt
,
286 XclChPropertyMode ePropMode
) const
288 GetChartPropSetHelper().WriteEscherProperties( rPropSet
,
289 mxChData
->GetGradientTable(), mxChData
->GetHatchTable(), mxChData
->GetBitmapTable(),
290 rEscherFmt
, rPicFmt
, ePropMode
);
293 void XclImpChRoot::ConvertFont( ScfPropertySet
& rPropSet
,
294 sal_uInt16 nFontIdx
, const Color
* pFontColor
) const
296 GetFontBuffer().WriteFontProperties( rPropSet
, EXC_FONTPROPSET_CHART
, nFontIdx
, pFontColor
);
299 void XclImpChRoot::ConvertPieRotation( ScfPropertySet
& rPropSet
, sal_uInt16 nAngle
)
301 sal_Int32 nApiRot
= (450 - (nAngle
% 360)) % 360;
302 rPropSet
.SetProperty( EXC_CHPROP_STARTINGANGLE
, nApiRot
);
305 // ----------------------------------------------------------------------------
307 XclImpChGroupBase::~XclImpChGroupBase()
311 void XclImpChGroupBase::ReadRecordGroup( XclImpStream
& rStrm
)
313 // read contents of the header record
314 ReadHeaderRecord( rStrm
);
316 // only read sub records, if the next record is a CHBEGIN
317 if( rStrm
.GetNextRecId() == EXC_ID_CHBEGIN
)
319 // read the CHBEGIN record, may be used for special initial processing
320 rStrm
.StartNextRecord();
321 ReadSubRecord( rStrm
);
323 // read the nested records
325 while( bLoop
&& rStrm
.StartNextRecord() )
327 sal_uInt16 nRecId
= rStrm
.GetRecId();
328 bLoop
= nRecId
!= EXC_ID_CHEND
;
329 // skip unsupported nested blocks
330 if( nRecId
== EXC_ID_CHBEGIN
)
333 ReadSubRecord( rStrm
);
336 /* Returns with current CHEND record or unchanged stream, if no record
337 group present. In every case another call to StartNextRecord() will go
338 to next record of interest. */
341 void XclImpChGroupBase::SkipBlock( XclImpStream
& rStrm
)
343 DBG_ASSERT( rStrm
.GetRecId() == EXC_ID_CHBEGIN
, "XclImpChGroupBase::SkipBlock - no CHBEGIN record" );
344 // do nothing if current record is not CHBEGIN
345 bool bLoop
= rStrm
.GetRecId() == EXC_ID_CHBEGIN
;
346 while( bLoop
&& rStrm
.StartNextRecord() )
348 sal_uInt16 nRecId
= rStrm
.GetRecId();
349 bLoop
= nRecId
!= EXC_ID_CHEND
;
350 // skip nested record groups
351 if( nRecId
== EXC_ID_CHBEGIN
)
356 // Frame formatting ===========================================================
358 void XclImpChFramePos::ReadChFramePos( XclImpStream
& rStrm
)
360 rStrm
>> maData
.mnObjType
>> maData
.mnSizeMode
>> maData
.maRect
;
363 // ----------------------------------------------------------------------------
365 void XclImpChLineFormat::ReadChLineFormat( XclImpStream
& rStrm
)
367 rStrm
>> maData
.maColor
>> maData
.mnPattern
>> maData
.mnWeight
>> maData
.mnFlags
;
369 const XclImpRoot
& rRoot
= rStrm
.GetRoot();
370 if( rRoot
.GetBiff() == EXC_BIFF8
)
371 // #116397# BIFF8: index into palette used instead of RGB data
372 maData
.maColor
= rRoot
.GetPalette().GetColor( rStrm
.ReaduInt16() );
375 void XclImpChLineFormat::Convert( const XclImpChRoot
& rRoot
,
376 ScfPropertySet
& rPropSet
, XclChObjectType eObjType
, sal_uInt16 nFormatIdx
) const
378 const XclChFormatInfo
& rFmtInfo
= rRoot
.GetFormatInfo( eObjType
);
381 XclChLineFormat aLineFmt
;
382 aLineFmt
.maColor
= (eObjType
== EXC_CHOBJTYPE_LINEARSERIES
) ?
383 rRoot
.GetSeriesLineAutoColor( nFormatIdx
) :
384 rRoot
.GetPalette().GetColor( rFmtInfo
.mnAutoLineColorIdx
);
385 aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
386 aLineFmt
.mnWeight
= rFmtInfo
.mnAutoLineWeight
;
387 rRoot
.ConvertLineFormat( rPropSet
, aLineFmt
, rFmtInfo
.mePropMode
);
391 rRoot
.ConvertLineFormat( rPropSet
, maData
, rFmtInfo
.mePropMode
);
395 // ----------------------------------------------------------------------------
397 void XclImpChAreaFormat::ReadChAreaFormat( XclImpStream
& rStrm
)
399 rStrm
>> maData
.maPattColor
>> maData
.maBackColor
>> maData
.mnPattern
>> maData
.mnFlags
;
401 const XclImpRoot
& rRoot
= rStrm
.GetRoot();
402 if( rRoot
.GetBiff() == EXC_BIFF8
)
404 // #116397# BIFF8: index into palette used instead of RGB data
405 const XclImpPalette
& rPal
= rRoot
.GetPalette();
406 maData
.maPattColor
= rPal
.GetColor( rStrm
.ReaduInt16() );
407 maData
.maBackColor
= rPal
.GetColor( rStrm
.ReaduInt16());
411 void XclImpChAreaFormat::Convert( const XclImpChRoot
& rRoot
,
412 ScfPropertySet
& rPropSet
, XclChObjectType eObjType
, sal_uInt16 nFormatIdx
) const
414 const XclChFormatInfo
& rFmtInfo
= rRoot
.GetFormatInfo( eObjType
);
417 XclChAreaFormat aAreaFmt
;
418 aAreaFmt
.maPattColor
= (eObjType
== EXC_CHOBJTYPE_FILLEDSERIES
) ?
419 rRoot
.GetSeriesFillAutoColor( nFormatIdx
) :
420 rRoot
.GetPalette().GetColor( rFmtInfo
.mnAutoPattColorIdx
);
421 aAreaFmt
.mnPattern
= EXC_PATT_SOLID
;
422 rRoot
.ConvertAreaFormat( rPropSet
, aAreaFmt
, rFmtInfo
.mePropMode
);
426 rRoot
.ConvertAreaFormat( rPropSet
, maData
, rFmtInfo
.mePropMode
);
430 // ----------------------------------------------------------------------------
432 XclImpChEscherFormat::XclImpChEscherFormat( const XclImpRoot
& rRoot
)
434 maData
.mxItemSet
.reset(
435 new SfxItemSet( rRoot
.GetDoc().GetDrawLayer()->GetItemPool() ) );
438 void XclImpChEscherFormat::ReadHeaderRecord( XclImpStream
& rStrm
)
440 // read from stream - CHESCHERFORMAT uses own ID for record continuation
441 XclImpDffPropSet
aPropSet( rStrm
.GetRoot() );
442 rStrm
.ResetRecord( true, rStrm
.GetRecId() );
445 aPropSet
.FillToItemSet( *maData
.mxItemSet
);
446 // get bitmap mode from DFF item set
447 sal_uInt32 nType
= aPropSet
.GetPropertyValue( DFF_Prop_fillType
, mso_fillSolid
);
448 maPicFmt
.mnBmpMode
= (nType
== mso_fillPicture
) ? EXC_CHPICFORMAT_STRETCH
: EXC_CHPICFORMAT_STACK
;
451 void XclImpChEscherFormat::ReadSubRecord( XclImpStream
& rStrm
)
453 switch( rStrm
.GetRecId() )
455 case EXC_ID_CHPICFORMAT
:
456 rStrm
>> maPicFmt
.mnBmpMode
>> maPicFmt
.mnFormat
>> maPicFmt
.mnFlags
>> maPicFmt
.mfScale
;
461 void XclImpChEscherFormat::Convert( const XclImpChRoot
& rRoot
,
462 ScfPropertySet
& rPropSet
, XclChObjectType eObjType
) const
464 const XclChFormatInfo
& rFmtInfo
= rRoot
.GetFormatInfo( eObjType
);
465 rRoot
.ConvertEscherFormat( rPropSet
, maData
, maPicFmt
, rFmtInfo
.mePropMode
);
468 // ----------------------------------------------------------------------------
470 XclImpChFrameBase::XclImpChFrameBase( const XclChFormatInfo
& rFmtInfo
)
472 if( rFmtInfo
.mbCreateDefFrame
) switch( rFmtInfo
.meDefFrameType
)
474 case EXC_CHFRAMETYPE_AUTO
:
475 mxLineFmt
.reset( new XclImpChLineFormat
);
476 if( rFmtInfo
.mbIsFrame
)
477 mxAreaFmt
.reset( new XclImpChAreaFormat
);
479 case EXC_CHFRAMETYPE_INVISIBLE
:
481 XclChLineFormat aLineFmt
;
482 ::set_flag( aLineFmt
.mnFlags
, EXC_CHLINEFORMAT_AUTO
, false );
483 aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
484 mxLineFmt
.reset( new XclImpChLineFormat( aLineFmt
) );
485 if( rFmtInfo
.mbIsFrame
)
487 XclChAreaFormat aAreaFmt
;
488 ::set_flag( aAreaFmt
.mnFlags
, EXC_CHAREAFORMAT_AUTO
, false );
489 aAreaFmt
.mnPattern
= EXC_PATT_NONE
;
490 mxAreaFmt
.reset( new XclImpChAreaFormat( aAreaFmt
) );
495 DBG_ERRORFILE( "XclImpChFrameBase::XclImpChFrameBase - unknown frame type" );
499 void XclImpChFrameBase::ReadSubRecord( XclImpStream
& rStrm
)
501 switch( rStrm
.GetRecId() )
503 case EXC_ID_CHLINEFORMAT
:
504 mxLineFmt
.reset( new XclImpChLineFormat
);
505 mxLineFmt
->ReadChLineFormat( rStrm
);
507 case EXC_ID_CHAREAFORMAT
:
508 mxAreaFmt
.reset( new XclImpChAreaFormat
);
509 mxAreaFmt
->ReadChAreaFormat( rStrm
);
511 case EXC_ID_CHESCHERFORMAT
:
512 mxEscherFmt
.reset( new XclImpChEscherFormat( rStrm
.GetRoot() ) );
513 mxEscherFmt
->ReadRecordGroup( rStrm
);
518 void XclImpChFrameBase::ConvertLineBase( const XclImpChRoot
& rRoot
,
519 ScfPropertySet
& rPropSet
, XclChObjectType eObjType
, sal_uInt16 nFormatIdx
) const
522 mxLineFmt
->Convert( rRoot
, rPropSet
, eObjType
, nFormatIdx
);
525 void XclImpChFrameBase::ConvertAreaBase( const XclImpChRoot
& rRoot
,
526 ScfPropertySet
& rPropSet
, XclChObjectType eObjType
, sal_uInt16 nFormatIdx
) const
528 if( rRoot
.GetFormatInfo( eObjType
).mbIsFrame
)
530 // CHESCHERFORMAT overrides CHAREAFORMAT (even if it is auto)
531 if( mxEscherFmt
.is() )
532 mxEscherFmt
->Convert( rRoot
, rPropSet
, eObjType
);
533 else if( mxAreaFmt
.is() )
534 mxAreaFmt
->Convert( rRoot
, rPropSet
, eObjType
, nFormatIdx
);
538 void XclImpChFrameBase::ConvertFrameBase( const XclImpChRoot
& rRoot
,
539 ScfPropertySet
& rPropSet
, XclChObjectType eObjType
, sal_uInt16 nFormatIdx
) const
541 ConvertLineBase( rRoot
, rPropSet
, eObjType
, nFormatIdx
);
542 ConvertAreaBase( rRoot
, rPropSet
, eObjType
, nFormatIdx
);
545 // ----------------------------------------------------------------------------
547 XclImpChFrame::XclImpChFrame( const XclImpChRoot
& rRoot
, XclChObjectType eObjType
) :
548 XclImpChFrameBase( rRoot
.GetFormatInfo( eObjType
) ),
549 XclImpChRoot( rRoot
),
550 meObjType( eObjType
)
554 void XclImpChFrame::ReadHeaderRecord( XclImpStream
& rStrm
)
556 rStrm
>> maData
.mnFormat
>> maData
.mnFlags
;
559 void XclImpChFrame::UpdateObjFrame( const XclObjLineData
& rLineData
, const XclObjFillData
& rFillData
)
561 const XclImpPalette
& rPal
= GetPalette();
563 if( rLineData
.IsVisible() && (!mxLineFmt
|| !mxLineFmt
->HasLine()) )
566 XclChLineFormat aLineFmt
;
567 aLineFmt
.maColor
= rPal
.GetColor( rLineData
.mnColorIdx
);
568 switch( rLineData
.mnStyle
)
570 case EXC_OBJ_LINE_SOLID
: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
; break;
571 case EXC_OBJ_LINE_DASH
: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DASH
; break;
572 case EXC_OBJ_LINE_DOT
: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DOT
; break;
573 case EXC_OBJ_LINE_DASHDOT
: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DASHDOT
; break;
574 case EXC_OBJ_LINE_DASHDOTDOT
: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DASHDOTDOT
; break;
575 case EXC_OBJ_LINE_MEDTRANS
: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_MEDTRANS
; break;
576 case EXC_OBJ_LINE_DARKTRANS
: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DARKTRANS
; break;
577 case EXC_OBJ_LINE_LIGHTTRANS
: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_LIGHTTRANS
; break;
578 case EXC_OBJ_LINE_NONE
: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
; break;
579 default: aLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
581 switch( rLineData
.mnWidth
)
583 case EXC_OBJ_LINE_HAIR
: aLineFmt
.mnWeight
= EXC_CHLINEFORMAT_HAIR
; break;
584 case EXC_OBJ_LINE_THIN
: aLineFmt
.mnWeight
= EXC_CHLINEFORMAT_SINGLE
; break;
585 case EXC_OBJ_LINE_MEDIUM
: aLineFmt
.mnWeight
= EXC_CHLINEFORMAT_DOUBLE
; break;
586 case EXC_OBJ_LINE_THICK
: aLineFmt
.mnWeight
= EXC_CHLINEFORMAT_TRIPLE
; break;
587 default: aLineFmt
.mnWeight
= EXC_CHLINEFORMAT_HAIR
;
589 ::set_flag( aLineFmt
.mnFlags
, EXC_CHLINEFORMAT_AUTO
, rLineData
.IsAuto() );
590 mxLineFmt
.reset( new XclImpChLineFormat( aLineFmt
) );
593 if( rFillData
.IsFilled() && (!mxAreaFmt
|| !mxAreaFmt
->HasArea()) && !mxEscherFmt
)
596 XclChAreaFormat aAreaFmt
;
597 aAreaFmt
.maPattColor
= rPal
.GetColor( rFillData
.mnPattColorIdx
);
598 aAreaFmt
.maBackColor
= rPal
.GetColor( rFillData
.mnBackColorIdx
);
599 aAreaFmt
.mnPattern
= rFillData
.mnPattern
;
600 ::set_flag( aAreaFmt
.mnFlags
, EXC_CHAREAFORMAT_AUTO
, rFillData
.IsAuto() );
601 mxAreaFmt
.reset( new XclImpChAreaFormat( aAreaFmt
) );
605 void XclImpChFrame::Convert( ScfPropertySet
& rPropSet
) const
607 ConvertFrameBase( GetChRoot(), rPropSet
, meObjType
);
610 // Source links ===============================================================
614 /** Creates a labeled data sequence object, adds link for series title if present. */
615 Reference
< XLabeledDataSequence
> lclCreateLabeledDataSequence(
616 XclImpChSourceLinkRef xValueLink
, const OUString
& rValueRole
,
617 const XclImpChSourceLink
* pTitleLink
= 0 )
619 // create data sequence for values and title
620 Reference
< XDataSequence
> xValueSeq
;
621 if( xValueLink
.is() )
622 xValueSeq
= xValueLink
->CreateDataSequence( rValueRole
);
623 Reference
< XDataSequence
> xTitleSeq
;
625 xTitleSeq
= pTitleLink
->CreateDataSequence( EXC_CHPROP_ROLE_LABEL
);
627 // create the labeled data sequence, if values or title are present
628 Reference
< XLabeledDataSequence
> xLabeledSeq
;
629 if( xValueSeq
.is() || xTitleSeq
.is() )
630 xLabeledSeq
.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_LABELEDDATASEQ
), UNO_QUERY
);
631 if( xLabeledSeq
.is() )
634 xLabeledSeq
->setValues( xValueSeq
);
636 xLabeledSeq
->setLabel( xTitleSeq
);
643 // ----------------------------------------------------------------------------
645 XclImpChSourceLink::XclImpChSourceLink( const XclImpChRoot
& rRoot
) :
646 XclImpChRoot( rRoot
)
650 XclImpChSourceLink::~XclImpChSourceLink()
654 void XclImpChSourceLink::ReadChSourceLink( XclImpStream
& rStrm
)
656 rStrm
>> maData
.mnDestType
659 >> maData
.mnNumFmtIdx
;
661 mxTokenArray
.reset();
662 if( GetLinkType() == EXC_CHSRCLINK_WORKSHEET
)
665 XclTokenArray aXclTokArr
;
668 // convert BIFF formula tokens to Calc token array
669 if( const ScTokenArray
* pTokens
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CHART
, aXclTokArr
) )
670 mxTokenArray
.reset( pTokens
->Clone() );
673 // try to read a following CHSTRING record
674 if( (rStrm
.GetNextRecId() == EXC_ID_CHSTRING
) && rStrm
.StartNextRecord() )
676 mxString
.reset( new XclImpString
);
678 mxString
->Read( rStrm
, EXC_STR_8BITLENGTH
| EXC_STR_SEPARATEFORMATS
);
682 void XclImpChSourceLink::SetString( const String
& rString
)
685 mxString
.reset( new XclImpString
);
686 mxString
->SetText( rString
);
689 void XclImpChSourceLink::SetTextFormats( const XclFormatRunVec
& rFormats
)
692 mxString
->SetFormats( rFormats
);
695 sal_uInt16
XclImpChSourceLink::GetCellCount() const
697 sal_uInt32 nCellCount
= 0;
698 if( mxTokenArray
.is() )
700 mxTokenArray
->Reset();
701 for( const FormulaToken
* pToken
= mxTokenArray
->First(); pToken
; pToken
= mxTokenArray
->Next() )
703 switch( pToken
->GetType() )
705 case ::formula::svSingleRef
:
706 case ::formula::svExternalSingleRef
:
710 case ::formula::svDoubleRef
:
711 case ::formula::svExternalDoubleRef
:
714 const ScComplexRefData
& rComplexRef
= static_cast< const ScToken
* >( pToken
)->GetDoubleRef();
715 const ScSingleRefData
& rRef1
= rComplexRef
.Ref1
;
716 const ScSingleRefData
& rRef2
= rComplexRef
.Ref2
;
717 sal_uInt32 nTabs
= static_cast< sal_uInt32
>( rRef2
.nTab
- rRef1
.nTab
+ 1 );
718 sal_uInt32 nCols
= static_cast< sal_uInt32
>( rRef2
.nCol
- rRef1
.nCol
+ 1 );
719 sal_uInt32 nRows
= static_cast< sal_uInt32
>( rRef2
.nRow
- rRef1
.nRow
+ 1 );
720 nCellCount
+= nCols
* nRows
* nTabs
;
727 return limit_cast
< sal_uInt16
>( nCellCount
);
730 void XclImpChSourceLink::ConvertNumFmt( ScfPropertySet
& rPropSet
, bool bPercent
) const
732 bool bLinkToSource
= ::get_flag( maData
.mnFlags
, EXC_CHSRCLINK_NUMFMT
);
733 sal_uInt32 nScNumFmt
= bLinkToSource
? GetNumFmtBuffer().GetScFormat( maData
.mnNumFmtIdx
) : NUMBERFORMAT_ENTRY_NOT_FOUND
;
734 OUString aPropName
= bPercent
? EXC_CHPROP_PERCENTAGENUMFMT
: EXC_CHPROP_NUMBERFORMAT
;
735 if( nScNumFmt
!= NUMBERFORMAT_ENTRY_NOT_FOUND
)
736 rPropSet
.SetProperty( aPropName
, static_cast< sal_Int32
>( nScNumFmt
) );
738 // restore 'link to source' at data point (series may contain manual number format)
739 rPropSet
.SetAnyProperty( aPropName
, Any() );
742 Reference
< XDataSequence
> XclImpChSourceLink::CreateDataSequence( const OUString
& rRole
) const
744 Reference
< XDataSequence
> xDataSeq
;
745 Reference
< XDataProvider
> xDataProv
= GetDataProvider();
746 if( xDataProv
.is() && mxTokenArray
.is() )
748 ScCompiler
aComp( GetDocPtr(), ScAddress(), *mxTokenArray
);
749 aComp
.SetGrammar( ::formula::FormulaGrammar::GRAM_ENGLISH
);
750 OUStringBuffer aRangeRep
;
751 aComp
.CreateStringFromTokenArray( aRangeRep
);
754 xDataSeq
= xDataProv
->createDataSequenceByRangeRepresentation( aRangeRep
.makeStringAndClear() );
756 ScfPropertySet
aSeqProp( xDataSeq
);
757 aSeqProp
.SetProperty( EXC_CHPROP_ROLE
, rRole
);
761 // DBG_ERRORFILE( "XclImpChSourceLink::CreateDataSequence - cannot create data sequence" );
767 Sequence
< Reference
< XFormattedString
> > XclImpChSourceLink::CreateStringSequence(
768 const XclImpChRoot
& rRoot
, sal_uInt16 nLeadFontIdx
, const Color
& rLeadFontColor
) const
770 ::std::vector
< Reference
< XFormattedString
> > aStringVec
;
773 for( XclImpStringIterator
aIt( *mxString
); aIt
.Is(); ++aIt
)
775 Reference
< XFormattedString
> xFmtStr(
776 ScfApiHelper::CreateInstance( SERVICE_CHART2_FORMATTEDSTRING
), UNO_QUERY
);
780 xFmtStr
->setString( aIt
.GetPortionText() );
782 // set font formatting and font color
783 ScfPropertySet
aStringProp( xFmtStr
);
784 sal_uInt16 nFontIdx
= aIt
.GetPortionFont();
785 if( (nFontIdx
== EXC_FONT_NOTFOUND
) && (aIt
.GetPortionIndex() == 0) )
786 // leading unformatted portion - use passed font settings
787 rRoot
.ConvertFont( aStringProp
, nLeadFontIdx
, &rLeadFontColor
);
789 rRoot
.ConvertFont( aStringProp
, nFontIdx
);
791 // add string to vector of strings
792 aStringVec
.push_back( xFmtStr
);
796 return ScfApiHelper::VectorToSequence( aStringVec
);
799 void XclImpChSourceLink::FillSourceLink(vector
<ScSharedTokenRef
>& rTokens
) const
801 if (!mxTokenArray
.is())
805 mxTokenArray
->Reset();
806 for (FormulaToken
* p
= mxTokenArray
->First(); p
; p
= mxTokenArray
->Next())
808 ScSharedTokenRef
pToken(static_cast<ScToken
*>(p
->Clone()));
809 if (ScRefTokenHelper::isRef(pToken
))
810 // This is a reference token. Store it.
811 ScRefTokenHelper::join(rTokens
, pToken
);
815 // Text =======================================================================
817 XclImpChFontBase::~XclImpChFontBase()
821 void XclImpChFontBase::ConvertFontBase( const XclImpChRoot
& rRoot
, ScfPropertySet
& rPropSet
) const
823 Color aFontColor
= GetFontColor();
824 rRoot
.ConvertFont( rPropSet
, GetFontIndex(), &aFontColor
);
827 void XclImpChFontBase::ConvertRotationBase( const XclImpChRoot
& rRoot
, ScfPropertySet
& rPropSet
, bool bSupportsStacked
) const
829 rRoot
.GetChartPropSetHelper().WriteRotationProperties( rPropSet
, GetRotation(), bSupportsStacked
);
832 // ----------------------------------------------------------------------------
834 XclImpChFont::XclImpChFont() :
835 mnFontIdx( EXC_FONT_NOTFOUND
)
839 void XclImpChFont::ReadChFont( XclImpStream
& rStrm
)
844 // ----------------------------------------------------------------------------
846 XclImpChText::XclImpChText( const XclImpChRoot
& rRoot
) :
847 XclImpChRoot( rRoot
)
851 void XclImpChText::ReadHeaderRecord( XclImpStream
& rStrm
)
853 rStrm
>> maData
.mnHAlign
856 >> maData
.maTextColor
860 if( GetBiff() == EXC_BIFF8
)
862 // #116397# BIFF8: index into palette used instead of RGB data
863 maData
.maTextColor
= GetPalette().GetColor( rStrm
.ReaduInt16() );
864 // placement and rotation
865 rStrm
>> maData
.mnPlacement
>> maData
.mnRotation
;
866 // lower 4 bits used for placement, other bits contain garbage
867 maData
.mnPlacement
&= 0x000F;
871 // BIFF2-BIFF7: get rotation from text orientation
872 sal_uInt8 nOrient
= ::extract_value
< sal_uInt8
>( maData
.mnFlags
, 8, 3 );
873 maData
.mnRotation
= XclTools::GetXclRotFromOrient( nOrient
);
877 void XclImpChText::ReadSubRecord( XclImpStream
& rStrm
)
879 switch( rStrm
.GetRecId() )
882 mxFont
.reset( new XclImpChFont
);
883 mxFont
->ReadChFont( rStrm
);
885 case EXC_ID_CHFORMATRUNS
:
886 if( GetBiff() == EXC_BIFF8
)
887 XclImpString::ReadFormats( rStrm
, maFormats
);
889 case EXC_ID_CHSOURCELINK
:
890 mxSrcLink
.reset( new XclImpChSourceLink( GetChRoot() ) );
891 mxSrcLink
->ReadChSourceLink( rStrm
);
894 mxFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_TEXT
) );
895 mxFrame
->ReadRecordGroup( rStrm
);
897 case EXC_ID_CHOBJECTLINK
:
898 rStrm
>> maObjLink
.mnTarget
>> maObjLink
.maPointPos
.mnSeriesIdx
>> maObjLink
.maPointPos
.mnPointIdx
;
900 case EXC_ID_CHFRLABELPROPS
:
901 ReadChFrLabelProps( rStrm
);
904 if( mxSrcLink
.is() && !maFormats
.empty() )
905 mxSrcLink
->SetTextFormats( maFormats
);
910 sal_uInt16
XclImpChText::GetFontIndex() const
912 return mxFont
.is() ? mxFont
->GetFontIndex() : EXC_FONT_NOTFOUND
;
915 Color
XclImpChText::GetFontColor() const
917 return ::get_flag( maData
.mnFlags
, EXC_CHTEXT_AUTOCOLOR
) ? GetFontAutoColor() : maData
.maTextColor
;
920 sal_uInt16
XclImpChText::GetRotation() const
922 return maData
.mnRotation
;
925 void XclImpChText::SetString( const String
& rString
)
928 mxSrcLink
.reset( new XclImpChSourceLink( GetChRoot() ) );
929 mxSrcLink
->SetString( rString
);
932 void XclImpChText::UpdateText( const XclImpChText
* pParentText
)
936 // update missing members
938 mxFrame
= pParentText
->mxFrame
;
941 mxFont
= pParentText
->mxFont
;
942 // text color is taken from CHTEXT record, not from font in CHFONT
943 ::set_flag( maData
.mnFlags
, EXC_CHTEXT_AUTOCOLOR
, ::get_flag( pParentText
->maData
.mnFlags
, EXC_CHTEXT_AUTOCOLOR
) );
944 maData
.maTextColor
= pParentText
->maData
.maTextColor
;
949 void XclImpChText::UpdateDataLabel( bool bCateg
, bool bValue
, bool bPercent
)
951 ::set_flag( maData
.mnFlags
, EXC_CHTEXT_SHOWCATEG
, bCateg
);
952 ::set_flag( maData
.mnFlags
, EXC_CHTEXT_SHOWVALUE
, bValue
);
953 ::set_flag( maData
.mnFlags
, EXC_CHTEXT_SHOWPERCENT
, bPercent
);
954 ::set_flag( maData
.mnFlags
, EXC_CHTEXT_SHOWCATEGPERC
, bCateg
&& bPercent
);
955 ::set_flag( maData
.mnFlags
, EXC_CHTEXT_DELETED
, !bCateg
&& !bValue
&& !bPercent
);
958 void XclImpChText::ConvertFont( ScfPropertySet
& rPropSet
) const
960 ConvertFontBase( GetChRoot(), rPropSet
);
963 void XclImpChText::ConvertRotation( ScfPropertySet
& rPropSet
, bool bSupportsStacked
) const
965 ConvertRotationBase( GetChRoot(), rPropSet
, bSupportsStacked
);
968 void XclImpChText::ConvertFrame( ScfPropertySet
& rPropSet
) const
971 mxFrame
->Convert( rPropSet
);
974 void XclImpChText::ConvertNumFmt( ScfPropertySet
& rPropSet
, bool bPercent
) const
977 mxSrcLink
->ConvertNumFmt( rPropSet
, bPercent
);
980 void XclImpChText::ConvertDataLabel( ScfPropertySet
& rPropSet
, const XclChTypeInfo
& rTypeInfo
) const
982 // existing CHFRLABELPROPS record wins over flags from CHTEXT
983 sal_uInt16 nShowFlags
= mxLabelProps
.is() ? mxLabelProps
->mnFlags
: maData
.mnFlags
;
984 sal_uInt16 SHOWANYCATEG
= mxLabelProps
.is() ? EXC_CHFRLABELPROPS_SHOWCATEG
: (EXC_CHTEXT_SHOWCATEGPERC
| EXC_CHTEXT_SHOWCATEG
);
985 sal_uInt16 SHOWANYVALUE
= mxLabelProps
.is() ? EXC_CHFRLABELPROPS_SHOWVALUE
: EXC_CHTEXT_SHOWVALUE
;
986 sal_uInt16 SHOWANYPERCENT
= mxLabelProps
.is() ? EXC_CHFRLABELPROPS_SHOWPERCENT
: (EXC_CHTEXT_SHOWPERCENT
| EXC_CHTEXT_SHOWCATEGPERC
);
987 sal_uInt16 SHOWANYBUBBLE
= mxLabelProps
.is() ? EXC_CHFRLABELPROPS_SHOWBUBBLE
: EXC_CHTEXT_SHOWBUBBLE
;
989 // get raw flags for label values
990 bool bShowNone
= IsDeleted();
991 bool bShowCateg
= !bShowNone
&& ::get_flag( nShowFlags
, SHOWANYCATEG
);
992 bool bShowPercent
= !bShowNone
&& ::get_flag( nShowFlags
, SHOWANYPERCENT
);
993 bool bShowValue
= !bShowNone
&& ::get_flag( nShowFlags
, SHOWANYVALUE
);
994 bool bShowBubble
= !bShowNone
&& ::get_flag( nShowFlags
, SHOWANYBUBBLE
);
996 // adjust to Chart2 behaviour
997 if( rTypeInfo
.meTypeId
== EXC_CHTYPEID_BUBBLES
)
998 bShowValue
= bShowBubble
; // Chart2 bubble charts show bubble size if 'ShowValue' is set
1001 bool bShowAny
= bShowValue
|| bShowPercent
|| bShowCateg
;
1002 bool bShowSymbol
= bShowAny
&& ::get_flag( maData
.mnFlags
, EXC_CHTEXT_SHOWSYMBOL
);
1004 // create API struct for label values, set API label separator
1005 namespace cssc
= ::com::sun::star::chart2
;
1006 cssc::DataPointLabel
aPointLabel( bShowValue
, bShowPercent
, bShowCateg
, bShowSymbol
);
1007 rPropSet
.SetProperty( EXC_CHPROP_LABEL
, aPointLabel
);
1008 String aSep
= mxLabelProps
.is() ? mxLabelProps
->maSeparator
: String( sal_Unicode( '\n' ) );
1009 if( aSep
.Len() == 0 )
1010 aSep
= CREATE_STRING( "; " );
1011 rPropSet
.SetStringProperty( EXC_CHPROP_LABELSEPARATOR
, aSep
);
1013 // text properties of attached label
1016 ConvertFont( rPropSet
);
1017 ConvertRotation( rPropSet
, false );
1019 using namespace ::com::sun::star::chart::DataLabelPlacement
;
1020 sal_Int32 nPlacement
= rTypeInfo
.mnDefaultLabelPos
;
1021 switch( maData
.mnPlacement
)
1023 case EXC_CHTEXT_POS_DEFAULT
: nPlacement
= rTypeInfo
.mnDefaultLabelPos
; break;
1024 case EXC_CHTEXT_POS_OUTSIDE
: nPlacement
= OUTSIDE
; break;
1025 case EXC_CHTEXT_POS_INSIDE
: nPlacement
= INSIDE
; break;
1026 case EXC_CHTEXT_POS_CENTER
: nPlacement
= CENTER
; break;
1027 case EXC_CHTEXT_POS_AXIS
: nPlacement
= NEAR_ORIGIN
; break;
1028 case EXC_CHTEXT_POS_ABOVE
: nPlacement
= TOP
; break;
1029 case EXC_CHTEXT_POS_BELOW
: nPlacement
= BOTTOM
; break;
1030 case EXC_CHTEXT_POS_LEFT
: nPlacement
= LEFT
; break;
1031 case EXC_CHTEXT_POS_RIGHT
: nPlacement
= RIGHT
; break;
1032 case EXC_CHTEXT_POS_AUTO
: nPlacement
= AVOID_OVERLAP
; break;
1034 rPropSet
.SetProperty( EXC_CHPROP_LABELPLACEMENT
, nPlacement
);
1035 // label number format (percentage format wins over value format)
1036 if( bShowPercent
|| bShowValue
)
1037 ConvertNumFmt( rPropSet
, bShowPercent
);
1041 Reference
< XTitle
> XclImpChText::CreateTitle() const
1043 Reference
< XTitle
> xTitle
;
1044 if( mxSrcLink
.is() && mxSrcLink
->HasString() )
1046 // create the formatted strings
1047 Sequence
< Reference
< XFormattedString
> > aStringSeq(
1048 mxSrcLink
->CreateStringSequence( GetChRoot(), GetFontIndex(), GetFontColor() ) );
1049 if( aStringSeq
.hasElements() )
1051 // create the title object
1052 xTitle
.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_TITLE
), UNO_QUERY
);
1055 // set the formatted strings
1056 xTitle
->setText( aStringSeq
);
1057 // more title formatting properties
1058 ScfPropertySet
aTitleProp( xTitle
);
1059 ConvertFrame( aTitleProp
);
1060 ConvertRotation( aTitleProp
, true );
1067 void XclImpChText::ReadChFrLabelProps( XclImpStream
& rStrm
)
1069 if( GetBiff() == EXC_BIFF8
)
1071 mxLabelProps
.reset( new XclChFrLabelProps
);
1074 rStrm
>> mxLabelProps
->mnFlags
>> nSepLen
;
1076 mxLabelProps
->maSeparator
= rStrm
.ReadUniString( nSepLen
);
1082 void lclUpdateText( XclImpChTextRef
& rxText
, XclImpChTextRef xDefText
)
1085 rxText
->UpdateText( xDefText
.get() );
1090 void lclFinalizeTitle( XclImpChTextRef
& rxTitle
, XclImpChTextRef xDefText
)
1092 /* Do not update a title, if it is not visible (if rxTitle is null).
1093 Existing reference indicates enabled title. */
1096 if( rxTitle
->HasString() )
1097 rxTitle
->UpdateText( xDefText
.get() );
1105 // Data series ================================================================
1107 void XclImpChMarkerFormat::ReadChMarkerFormat( XclImpStream
& rStrm
)
1109 rStrm
>> maData
.maLineColor
>> maData
.maFillColor
>> maData
.mnMarkerType
>> maData
.mnFlags
;
1111 const XclImpRoot
& rRoot
= rStrm
.GetRoot();
1112 if( rRoot
.GetBiff() == EXC_BIFF8
)
1114 // #116397# BIFF8: index into palette used instead of RGB data
1115 const XclImpPalette
& rPal
= rRoot
.GetPalette();
1116 maData
.maLineColor
= rPal
.GetColor( rStrm
.ReaduInt16() );
1117 maData
.maFillColor
= rPal
.GetColor( rStrm
.ReaduInt16() );
1119 rStrm
>> maData
.mnMarkerSize
;
1123 void XclImpChMarkerFormat::Convert( const XclImpChRoot
& rRoot
,
1124 ScfPropertySet
& rPropSet
, sal_uInt16 nFormatIdx
, sal_Int16 nLineWeight
) const
1128 XclChMarkerFormat aMarkerFmt
;
1129 // line and fill color of the symbol are equal to series line color
1130 //! TODO: Excel sets no fill color for specific symbols (e.g. cross)
1131 aMarkerFmt
.maLineColor
= aMarkerFmt
.maFillColor
= rRoot
.GetSeriesLineAutoColor( nFormatIdx
);
1132 switch( nLineWeight
)
1134 case EXC_CHLINEFORMAT_HAIR
: aMarkerFmt
.mnMarkerSize
= EXC_CHMARKERFORMAT_HAIRSIZE
; break;
1135 case EXC_CHLINEFORMAT_SINGLE
: aMarkerFmt
.mnMarkerSize
= EXC_CHMARKERFORMAT_SINGLESIZE
; break;
1136 case EXC_CHLINEFORMAT_DOUBLE
: aMarkerFmt
.mnMarkerSize
= EXC_CHMARKERFORMAT_DOUBLESIZE
; break;
1137 case EXC_CHLINEFORMAT_TRIPLE
: aMarkerFmt
.mnMarkerSize
= EXC_CHMARKERFORMAT_TRIPLESIZE
; break;
1138 default: aMarkerFmt
.mnMarkerSize
= EXC_CHMARKERFORMAT_SINGLESIZE
;
1140 aMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
1141 rRoot
.GetChartPropSetHelper().WriteMarkerProperties( rPropSet
, aMarkerFmt
);
1145 rRoot
.GetChartPropSetHelper().WriteMarkerProperties( rPropSet
, maData
);
1149 void XclImpChMarkerFormat::ConvertColor( const XclImpChRoot
& rRoot
,
1150 ScfPropertySet
& rPropSet
, sal_uInt16 nFormatIdx
) const
1152 Color aLineColor
= IsAuto() ? rRoot
.GetSeriesLineAutoColor( nFormatIdx
) : maData
.maFillColor
;
1153 rPropSet
.SetColorProperty( EXC_CHPROP_COLOR
, aLineColor
);
1156 // ----------------------------------------------------------------------------
1158 XclImpChPieFormat::XclImpChPieFormat() :
1163 void XclImpChPieFormat::ReadChPieFormat( XclImpStream
& rStrm
)
1168 void XclImpChPieFormat::Convert( ScfPropertySet
& rPropSet
) const
1170 double fApiDist
= ::std::min
< double >( mnPieDist
/ 100.0, 1.0 );
1171 rPropSet
.SetProperty( EXC_CHPROP_OFFSET
, fApiDist
);
1174 // ----------------------------------------------------------------------------
1176 XclImpChSeriesFormat::XclImpChSeriesFormat() :
1181 void XclImpChSeriesFormat::ReadChSeriesFormat( XclImpStream
& rStrm
)
1186 // ----------------------------------------------------------------------------
1188 void XclImpCh3dDataFormat::ReadCh3dDataFormat( XclImpStream
& rStrm
)
1190 rStrm
>> maData
.mnBase
>> maData
.mnTop
;
1193 void XclImpCh3dDataFormat::Convert( ScfPropertySet
& rPropSet
) const
1195 using namespace ::com::sun::star::chart2::DataPointGeometry3D
;
1196 sal_Int32 nApiType
= (maData
.mnBase
== EXC_CH3DDATAFORMAT_RECT
) ?
1197 ((maData
.mnTop
== EXC_CH3DDATAFORMAT_STRAIGHT
) ? CUBOID
: PYRAMID
) :
1198 ((maData
.mnTop
== EXC_CH3DDATAFORMAT_STRAIGHT
) ? CYLINDER
: CONE
);
1199 rPropSet
.SetProperty( EXC_CHPROP_GEOMETRY3D
, nApiType
);
1202 // ----------------------------------------------------------------------------
1204 XclImpChAttachedLabel::XclImpChAttachedLabel( const XclImpChRoot
& rRoot
) :
1205 XclImpChRoot( rRoot
),
1210 void XclImpChAttachedLabel::ReadChAttachedLabel( XclImpStream
& rStrm
)
1215 XclImpChTextRef
XclImpChAttachedLabel::CreateDataLabel( XclImpChTextRef xParent
) const
1217 const sal_uInt16 EXC_CHATTLABEL_SHOWANYVALUE
= EXC_CHATTLABEL_SHOWVALUE
;
1218 const sal_uInt16 EXC_CHATTLABEL_SHOWANYPERCENT
= EXC_CHATTLABEL_SHOWPERCENT
| EXC_CHATTLABEL_SHOWCATEGPERC
;
1219 const sal_uInt16 EXC_CHATTLABEL_SHOWANYCATEG
= EXC_CHATTLABEL_SHOWCATEG
| EXC_CHATTLABEL_SHOWCATEGPERC
;
1221 XclImpChTextRef
xLabel( xParent
.is() ? new XclImpChText( *xParent
) : new XclImpChText( GetChRoot() ) );
1222 xLabel
->UpdateDataLabel(
1223 ::get_flag( mnFlags
, EXC_CHATTLABEL_SHOWANYCATEG
),
1224 ::get_flag( mnFlags
, EXC_CHATTLABEL_SHOWANYVALUE
),
1225 ::get_flag( mnFlags
, EXC_CHATTLABEL_SHOWANYPERCENT
) );
1229 // ----------------------------------------------------------------------------
1231 XclImpChDataFormat::XclImpChDataFormat( const XclImpChRoot
& rRoot
) :
1232 XclImpChRoot( rRoot
)
1236 void XclImpChDataFormat::ReadHeaderRecord( XclImpStream
& rStrm
)
1238 rStrm
>> maData
.maPointPos
.mnPointIdx
1239 >> maData
.maPointPos
.mnSeriesIdx
1240 >> maData
.mnFormatIdx
1244 void XclImpChDataFormat::ReadSubRecord( XclImpStream
& rStrm
)
1246 switch( rStrm
.GetRecId() )
1248 case EXC_ID_CHMARKERFORMAT
:
1249 mxMarkerFmt
.reset( new XclImpChMarkerFormat
);
1250 mxMarkerFmt
->ReadChMarkerFormat( rStrm
);
1252 case EXC_ID_CHPIEFORMAT
:
1253 mxPieFmt
.reset( new XclImpChPieFormat
);
1254 mxPieFmt
->ReadChPieFormat( rStrm
);
1256 case EXC_ID_CHSERIESFORMAT
:
1257 mxSeriesFmt
.reset( new XclImpChSeriesFormat
);
1258 mxSeriesFmt
->ReadChSeriesFormat( rStrm
);
1260 case EXC_ID_CH3DDATAFORMAT
:
1261 mx3dDataFmt
.reset( new XclImpCh3dDataFormat
);
1262 mx3dDataFmt
->ReadCh3dDataFormat( rStrm
);
1264 case EXC_ID_CHATTACHEDLABEL
:
1265 mxAttLabel
.reset( new XclImpChAttachedLabel( GetChRoot() ) );
1266 mxAttLabel
->ReadChAttachedLabel( rStrm
);
1269 XclImpChFrameBase::ReadSubRecord( rStrm
);
1273 void XclImpChDataFormat::SetPointPos( const XclChDataPointPos
& rPointPos
, sal_uInt16 nFormatIdx
)
1275 maData
.maPointPos
= rPointPos
;
1276 maData
.mnFormatIdx
= nFormatIdx
;
1279 void XclImpChDataFormat::UpdateGroupFormat( const XclChExtTypeInfo
& rTypeInfo
)
1281 // remove formats not used for the current chart type
1282 RemoveUnusedFormats( rTypeInfo
);
1285 void XclImpChDataFormat::UpdateSeriesFormat( const XclChExtTypeInfo
& rTypeInfo
, const XclImpChDataFormat
* pGroupFmt
)
1287 // update missing formats from passed chart type group format
1291 mxLineFmt
= pGroupFmt
->mxLineFmt
;
1292 if( !mxAreaFmt
&& !mxEscherFmt
)
1294 mxAreaFmt
= pGroupFmt
->mxAreaFmt
;
1295 mxEscherFmt
= pGroupFmt
->mxEscherFmt
;
1298 mxMarkerFmt
= pGroupFmt
->mxMarkerFmt
;
1300 mxPieFmt
= pGroupFmt
->mxPieFmt
;
1302 mxSeriesFmt
= pGroupFmt
->mxSeriesFmt
;
1304 mx3dDataFmt
= pGroupFmt
->mx3dDataFmt
;
1306 mxAttLabel
= pGroupFmt
->mxAttLabel
;
1309 /* Create missing but required formats. Existing line, area, and marker
1310 format objects are needed to create automatic series formatting. */
1312 mxLineFmt
.reset( new XclImpChLineFormat
);
1313 if( !mxAreaFmt
&& !mxEscherFmt
)
1314 mxAreaFmt
.reset( new XclImpChAreaFormat
);
1316 mxMarkerFmt
.reset( new XclImpChMarkerFormat
);
1318 // remove formats not used for the current chart type
1319 RemoveUnusedFormats( rTypeInfo
);
1320 // update data label
1321 UpdateDataLabel( pGroupFmt
);
1324 void XclImpChDataFormat::UpdatePointFormat( const XclChExtTypeInfo
& rTypeInfo
, const XclImpChDataFormat
* pSeriesFmt
)
1326 // remove formats if they are automatic in this and in the passed series format
1329 if( IsAutoLine() && pSeriesFmt
->IsAutoLine() )
1331 if( IsAutoArea() && pSeriesFmt
->IsAutoArea() )
1333 if( IsAutoMarker() && pSeriesFmt
->IsAutoMarker() )
1334 mxMarkerFmt
.reset();
1335 mxSeriesFmt
.reset();
1338 // Excel ignores 3D bar format for single data points
1339 mx3dDataFmt
.reset();
1340 // remove point line formats for linear chart types, TODO: implement in OOChart
1341 if( !rTypeInfo
.IsSeriesFrameFormat() )
1344 // remove formats not used for the current chart type
1345 RemoveUnusedFormats( rTypeInfo
);
1346 // update data label
1347 UpdateDataLabel( pSeriesFmt
);
1350 void XclImpChDataFormat::UpdateTrendLineFormat()
1353 mxLineFmt
.reset( new XclImpChLineFormat
);
1355 mxEscherFmt
.reset();
1356 mxMarkerFmt
.reset();
1358 mxSeriesFmt
.reset();
1359 mx3dDataFmt
.reset();
1361 // update data label
1362 UpdateDataLabel( 0 );
1365 void XclImpChDataFormat::Convert( ScfPropertySet
& rPropSet
, const XclChExtTypeInfo
& rTypeInfo
) const
1367 // line and area format
1368 ConvertFrameBase( GetChRoot(), rPropSet
, rTypeInfo
.GetSeriesObjectType(), maData
.mnFormatIdx
);
1369 #if EXC_CHART2_3DBAR_HAIRLINES_ONLY
1370 // #i83151# only hair lines in 3D charts with filled data points
1371 if( rTypeInfo
.mb3dChart
&& rTypeInfo
.IsSeriesFrameFormat() && mxLineFmt
.is() && mxLineFmt
->HasLine() )
1372 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "BorderWidth" ), 0 );
1376 if( mxMarkerFmt
.is() )
1377 mxMarkerFmt
->Convert( GetChRoot(), rPropSet
, maData
.mnFormatIdx
, GetLineWeight() );
1379 mxPieFmt
->Convert( rPropSet
);
1380 if( mx3dDataFmt
.is() )
1381 mx3dDataFmt
->Convert( rPropSet
);
1383 mxLabel
->ConvertDataLabel( rPropSet
, rTypeInfo
);
1386 rPropSet
.SetProperty
< sal_Int16
>( EXC_CHPROP_PERCENTDIAGONAL
, 0 );
1388 /* Special case: set marker color as line color, if series line is not
1389 visible. This makes the color visible in the marker area.
1390 TODO: remove this if OOChart supports own colors in markers. */
1391 if( !rTypeInfo
.IsSeriesFrameFormat() && !HasLine() && mxMarkerFmt
.is() )
1392 mxMarkerFmt
->ConvertColor( GetChRoot(), rPropSet
, maData
.mnFormatIdx
);
1395 void XclImpChDataFormat::ConvertLine( ScfPropertySet
& rPropSet
, XclChObjectType eObjType
) const
1397 ConvertLineBase( GetChRoot(), rPropSet
, eObjType
);
1400 void XclImpChDataFormat::ConvertArea( ScfPropertySet
& rPropSet
, sal_uInt16 nFormatIdx
) const
1402 ConvertAreaBase( GetChRoot(), rPropSet
, EXC_CHOBJTYPE_FILLEDSERIES
, nFormatIdx
);
1405 void XclImpChDataFormat::RemoveUnusedFormats( const XclChExtTypeInfo
& rTypeInfo
)
1407 // data point marker only in linear 2D charts
1408 if( rTypeInfo
.IsSeriesFrameFormat() )
1409 mxMarkerFmt
.reset();
1410 // pie format only in pie/donut charts
1411 if( rTypeInfo
.meTypeCateg
!= EXC_CHTYPECATEG_PIE
)
1413 // 3D format only in 3D bar charts
1414 if( !rTypeInfo
.mb3dChart
|| (rTypeInfo
.meTypeCateg
!= EXC_CHTYPECATEG_BAR
) )
1415 mx3dDataFmt
.reset();
1418 void XclImpChDataFormat::UpdateDataLabel( const XclImpChDataFormat
* pParentFmt
)
1420 /* CHTEXT groups linked to data labels override existing CHATTACHEDLABEL
1421 records. Only if there is a CHATTACHEDLABEL record without a CHTEXT
1422 group, the contents of the CHATTACHEDLABEL record are used. In this
1423 case a new CHTEXT group is created and filled with the settings from
1424 the CHATTACHEDLABEL record. */
1425 XclImpChTextRef xDefText
;
1427 xDefText
= pParentFmt
->GetDataLabel();
1429 xDefText
= GetChartData().GetDefaultText( EXC_CHTEXTTYPE_DATALABEL
);
1431 mxLabel
->UpdateText( xDefText
.get() );
1432 else if( mxAttLabel
.is() )
1433 mxLabel
= mxAttLabel
->CreateDataLabel( xDefText
);
1436 // ----------------------------------------------------------------------------
1438 XclImpChSerTrendLine::XclImpChSerTrendLine( const XclImpChRoot
& rRoot
) :
1439 XclImpChRoot( rRoot
)
1443 void XclImpChSerTrendLine::ReadChSerTrendLine( XclImpStream
& rStrm
)
1445 rStrm
>> maData
.mnLineType
1447 >> maData
.mfIntercept
1448 >> maData
.mnShowEquation
1449 >> maData
.mnShowRSquared
1450 >> maData
.mfForecastFor
1451 >> maData
.mfForecastBack
;
1454 Reference
< XRegressionCurve
> XclImpChSerTrendLine::CreateRegressionCurve() const
1458 switch( maData
.mnLineType
)
1460 case EXC_CHSERTREND_POLYNOMIAL
:
1461 // TODO: only linear trend lines are supported by OOChart (#i20819#)
1462 if( maData
.mnOrder
== 1 )
1463 aService
= SERVICE_CHART2_LINEARREGCURVE
;
1465 case EXC_CHSERTREND_EXPONENTIAL
:
1466 aService
= SERVICE_CHART2_EXPREGCURVE
;
1468 case EXC_CHSERTREND_LOGARITHMIC
:
1469 aService
= SERVICE_CHART2_LOGREGCURVE
;
1471 case EXC_CHSERTREND_POWER
:
1472 aService
= SERVICE_CHART2_POTREGCURVE
;
1475 Reference
< XRegressionCurve
> xRegCurve
;
1476 if( aService
.getLength() > 0 )
1477 xRegCurve
.set( ScfApiHelper::CreateInstance( aService
), UNO_QUERY
);
1479 // trend line formatting
1480 if( xRegCurve
.is() && mxDataFmt
.is() )
1482 ScfPropertySet
aPropSet( xRegCurve
);
1483 mxDataFmt
->ConvertLine( aPropSet
, EXC_CHOBJTYPE_TRENDLINE
);
1485 // #i83100# show equation and correlation coefficient
1486 ScfPropertySet
aLabelProp( xRegCurve
->getEquationProperties() );
1487 aLabelProp
.SetBoolProperty( EXC_CHPROP_SHOWEQUATION
, maData
.mnShowEquation
!= 0 );
1488 aLabelProp
.SetBoolProperty( EXC_CHPROP_SHOWCORRELATION
, maData
.mnShowRSquared
!= 0 );
1490 // #i83100# formatting of the equation text box
1491 if( const XclImpChText
* pLabel
= mxDataFmt
->GetDataLabel().get() )
1493 pLabel
->ConvertFont( aLabelProp
);
1494 pLabel
->ConvertFrame( aLabelProp
);
1495 pLabel
->ConvertNumFmt( aLabelProp
, false );
1500 // #i20819# polynomial trend lines
1501 // #i66819# moving average trend lines
1502 // #i5085# manual trend line size
1503 // #i34093# manual crossing point
1508 // ----------------------------------------------------------------------------
1510 XclImpChSerErrorBar::XclImpChSerErrorBar( const XclImpChRoot
& rRoot
) :
1511 XclImpChRoot( rRoot
)
1515 void XclImpChSerErrorBar::ReadChSerErrorBar( XclImpStream
& rStrm
)
1517 rStrm
>> maData
.mnBarType
>> maData
.mnSourceType
>> maData
.mnLineEnd
;
1519 rStrm
>> maData
.mfValue
>> maData
.mnValueCount
;
1522 void XclImpChSerErrorBar::SetSeriesData( XclImpChSourceLinkRef xValueLink
, XclImpChDataFormatRef xDataFmt
)
1524 mxValueLink
= xValueLink
;
1525 mxDataFmt
= xDataFmt
;
1528 Reference
< XLabeledDataSequence
> XclImpChSerErrorBar::CreateValueSequence() const
1530 return lclCreateLabeledDataSequence( mxValueLink
, XclChartHelper::GetErrorBarValuesRole( maData
.mnBarType
) );
1533 Reference
< XPropertySet
> XclImpChSerErrorBar::CreateErrorBar( const XclImpChSerErrorBar
* pPosBar
, const XclImpChSerErrorBar
* pNegBar
)
1535 Reference
< XPropertySet
> xErrorBar
;
1537 if( const XclImpChSerErrorBar
* pPrimaryBar
= pPosBar
? pPosBar
: pNegBar
)
1539 xErrorBar
.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_ERRORBAR
), UNO_QUERY
);
1540 ScfPropertySet
aBarProp( xErrorBar
);
1542 // plus/minus bars visible?
1543 aBarProp
.SetBoolProperty( EXC_CHPROP_SHOWPOSITIVEERROR
, pPosBar
!= 0 );
1544 aBarProp
.SetBoolProperty( EXC_CHPROP_SHOWNEGATIVEERROR
, pNegBar
!= 0 );
1546 // type of displayed error
1547 namespace cssc
= ::com::sun::star::chart
;
1548 switch( pPrimaryBar
->maData
.mnSourceType
)
1550 case EXC_CHSERERR_PERCENT
:
1551 aBarProp
.SetProperty( EXC_CHPROP_ERRORBARSTYLE
, cssc::ErrorBarStyle::RELATIVE
);
1552 aBarProp
.SetProperty( EXC_CHPROP_POSITIVEERROR
, pPrimaryBar
->maData
.mfValue
);
1553 aBarProp
.SetProperty( EXC_CHPROP_NEGATIVEERROR
, pPrimaryBar
->maData
.mfValue
);
1555 case EXC_CHSERERR_FIXED
:
1556 aBarProp
.SetProperty( EXC_CHPROP_ERRORBARSTYLE
, cssc::ErrorBarStyle::ABSOLUTE
);
1557 aBarProp
.SetProperty( EXC_CHPROP_POSITIVEERROR
, pPrimaryBar
->maData
.mfValue
);
1558 aBarProp
.SetProperty( EXC_CHPROP_NEGATIVEERROR
, pPrimaryBar
->maData
.mfValue
);
1560 case EXC_CHSERERR_STDDEV
:
1561 aBarProp
.SetProperty( EXC_CHPROP_ERRORBARSTYLE
, cssc::ErrorBarStyle::STANDARD_DEVIATION
);
1562 aBarProp
.SetProperty( EXC_CHPROP_WEIGHT
, pPrimaryBar
->maData
.mfValue
);
1564 case EXC_CHSERERR_STDERR
:
1565 aBarProp
.SetProperty( EXC_CHPROP_ERRORBARSTYLE
, cssc::ErrorBarStyle::STANDARD_ERROR
);
1567 case EXC_CHSERERR_CUSTOM
:
1569 aBarProp
.SetProperty( EXC_CHPROP_ERRORBARSTYLE
, cssc::ErrorBarStyle::FROM_DATA
);
1570 // attach data sequences to erorr bar
1571 Reference
< XDataSink
> xDataSink( xErrorBar
, UNO_QUERY
);
1572 if( xDataSink
.is() )
1574 // create vector of all value sequences
1575 ::std::vector
< Reference
< XLabeledDataSequence
> > aLabeledSeqVec
;
1576 // add positive values
1579 Reference
< XLabeledDataSequence
> xValueSeq
= pPosBar
->CreateValueSequence();
1580 if( xValueSeq
.is() )
1581 aLabeledSeqVec
.push_back( xValueSeq
);
1583 // add negative values
1586 Reference
< XLabeledDataSequence
> xValueSeq
= pNegBar
->CreateValueSequence();
1587 if( xValueSeq
.is() )
1588 aLabeledSeqVec
.push_back( xValueSeq
);
1590 // attach labeled data sequences to series
1591 if( aLabeledSeqVec
.empty() )
1594 xDataSink
->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec
) );
1602 // error bar formatting
1603 if( pPrimaryBar
->mxDataFmt
.is() && xErrorBar
.is() )
1604 pPrimaryBar
->mxDataFmt
->ConvertLine( aBarProp
, EXC_CHOBJTYPE_ERRORBAR
);
1610 // ----------------------------------------------------------------------------
1612 XclImpChSeries::XclImpChSeries( const XclImpChRoot
& rRoot
, sal_uInt16 nSeriesIdx
) :
1613 XclImpChRoot( rRoot
),
1614 mnGroupIdx( EXC_CHSERGROUP_NONE
),
1615 mnSeriesIdx( nSeriesIdx
),
1616 mnParentIdx( EXC_CHSERIES_INVALID
)
1620 void XclImpChSeries::ReadHeaderRecord( XclImpStream
& rStrm
)
1622 rStrm
>> maData
.mnCategType
>> maData
.mnValueType
>> maData
.mnCategCount
>> maData
.mnValueCount
;
1623 if( GetBiff() == EXC_BIFF8
)
1624 rStrm
>> maData
.mnBubbleType
>> maData
.mnBubbleCount
;
1627 void XclImpChSeries::ReadSubRecord( XclImpStream
& rStrm
)
1629 switch( rStrm
.GetRecId() )
1631 case EXC_ID_CHSOURCELINK
:
1632 ReadChSourceLink( rStrm
);
1634 case EXC_ID_CHDATAFORMAT
:
1635 ReadChDataFormat( rStrm
);
1637 case EXC_ID_CHSERGROUP
:
1638 rStrm
>> mnGroupIdx
;
1640 case EXC_ID_CHSERPARENT
:
1641 ReadChSerParent( rStrm
);
1643 case EXC_ID_CHSERTRENDLINE
:
1644 ReadChSerTrendLine( rStrm
);
1646 case EXC_ID_CHSERERRORBAR
:
1647 ReadChSerErrorBar( rStrm
);
1652 void XclImpChSeries::SetDataFormat( XclImpChDataFormatRef xDataFmt
)
1656 XclImpChDataFormatRef
* pxDataFmt
= GetDataFormatRef( xDataFmt
->GetPointPos().mnPointIdx
);
1657 // do not overwrite existing data format
1658 if( pxDataFmt
&& !*pxDataFmt
)
1660 *pxDataFmt
= xDataFmt
;
1661 // #i51639# register series format index at chart type group
1662 if( (pxDataFmt
== &mxSeriesFmt
) && !HasParentSeries() )
1663 if( XclImpChTypeGroup
* pTypeGroup
= GetChartData().GetTypeGroup( mnGroupIdx
).get() )
1664 pTypeGroup
->SetUsedFormatIndex( xDataFmt
->GetFormatIdx() );
1669 void XclImpChSeries::SetDataLabel( XclImpChTextRef xLabel
)
1673 XclImpChTextRef
* pxLabel
= GetDataLabelRef( xLabel
->GetPointPos().mnPointIdx
);
1674 if( pxLabel
&& !*pxLabel
)
1679 void XclImpChSeries::AddChildSeries( const XclImpChSeries
& rSeries
)
1681 DBG_ASSERT( !HasParentSeries(), "XclImpChSeries::AddChildSeries - not allowed for child series" );
1683 /* In Excel, trend lines and error bars are stored as own series. In Calc,
1684 these are properties of the parent series. This function adds the
1685 settings of the passed series to this series. */
1686 maTrendLines
.insert( maTrendLines
.end(), rSeries
.maTrendLines
.begin(), rSeries
.maTrendLines
.end() );
1687 maErrorBars
.insert( rSeries
.maErrorBars
.begin(), rSeries
.maErrorBars
.end() );
1690 void XclImpChSeries::FinalizeDataFormats()
1692 if( HasParentSeries() )
1694 // *** series is a child series, e.g. trend line or error bar ***
1696 // create missing series format
1698 mxSeriesFmt
= CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS
, 0 );
1700 if( mxSeriesFmt
.is() )
1702 // #i83100# set text label format, e.g. for trend line equations
1703 mxSeriesFmt
->SetDataLabel( maLabels
.get( EXC_CHDATAFORMAT_ALLPOINTS
) );
1704 // create missing automatic formats
1705 mxSeriesFmt
->UpdateTrendLineFormat();
1708 // copy series formatting to child objects
1709 for( XclImpChSerTrendLineList::iterator aLIt
= maTrendLines
.begin(), aLEnd
= maTrendLines
.end(); aLIt
!= aLEnd
; ++aLIt
)
1710 (*aLIt
)->SetDataFormat( mxSeriesFmt
);
1711 for( XclImpChSerErrorBarMap::iterator aMIt
= maErrorBars
.begin(), aMEnd
= maErrorBars
.end(); aMIt
!= aMEnd
; ++aMIt
)
1712 aMIt
->second
->SetSeriesData( mxValueLink
, mxSeriesFmt
);
1714 else if( XclImpChTypeGroup
* pTypeGroup
= GetChartData().GetTypeGroup( mnGroupIdx
).get() )
1716 // *** series is a regular data series ***
1718 // create missing series format
1721 // #i51639# use a new unused format index to create series default format
1722 sal_uInt16 nFormatIdx
= pTypeGroup
->PopUnusedFormatIndex();
1723 mxSeriesFmt
= CreateDataFormat( EXC_CHDATAFORMAT_ALLPOINTS
, nFormatIdx
);
1726 // set text labels to data formats
1727 for( XclImpChTextMap::iterator aTIt
= maLabels
.begin(), aTEnd
= maLabels
.end(); aTIt
!= aTEnd
; ++aTIt
)
1729 if( XclImpChDataFormatRef
* pxDataFmt
= GetDataFormatRef( aTIt
->first
) )
1732 *pxDataFmt
= CreateDataFormat( aTIt
->first
, EXC_CHDATAFORMAT_DEFAULT
);
1733 (*pxDataFmt
)->SetDataLabel( aTIt
->second
);
1737 // update series format (copy missing formatting from group default format)
1738 if( mxSeriesFmt
.is() )
1739 mxSeriesFmt
->UpdateSeriesFormat( pTypeGroup
->GetTypeInfo(), pTypeGroup
->GetGroupFormat().get() );
1741 // update data point formats (removes unchanged automatic formatting)
1742 for( XclImpChDataFormatMap::iterator aFIt
= maPointFmts
.begin(), aFEnd
= maPointFmts
.end(); aFIt
!= aFEnd
; ++aFIt
)
1743 aFIt
->second
->UpdatePointFormat( pTypeGroup
->GetTypeInfo(), mxSeriesFmt
.get() );
1749 /** Returns the property set of the specified data point. */
1750 ScfPropertySet
lclGetPointPropSet( Reference
< XDataSeries
> xDataSeries
, sal_uInt16 nPointIdx
)
1752 ScfPropertySet aPropSet
;
1755 aPropSet
.Set( xDataSeries
->getDataPointByIndex( static_cast< sal_Int32
>( nPointIdx
) ) );
1759 DBG_ERRORFILE( "lclGetPointPropSet - no data point property set" );
1766 Reference
< XLabeledDataSequence
> XclImpChSeries::CreateValueSequence( const OUString
& rValueRole
) const
1768 return lclCreateLabeledDataSequence( mxValueLink
, rValueRole
, mxTitleLink
.get() );
1771 Reference
< XLabeledDataSequence
> XclImpChSeries::CreateCategSequence( const OUString
& rCategRole
) const
1773 return lclCreateLabeledDataSequence( mxCategLink
, rCategRole
);
1776 Reference
< XDataSeries
> XclImpChSeries::CreateDataSeries() const
1778 Reference
< XDataSeries
> xDataSeries
;
1779 if( const XclImpChTypeGroup
* pTypeGroup
= GetChartData().GetTypeGroup( mnGroupIdx
).get() )
1781 const XclChExtTypeInfo
& rTypeInfo
= pTypeGroup
->GetTypeInfo();
1783 // create the data series object
1784 xDataSeries
.set( ScfApiHelper::CreateInstance( SERVICE_CHART2_DATASERIES
), UNO_QUERY
);
1786 // attach data and title sequences to series
1787 Reference
< XDataSink
> xDataSink( xDataSeries
, UNO_QUERY
);
1788 if( xDataSink
.is() )
1790 // create vector of all value sequences
1791 ::std::vector
< Reference
< XLabeledDataSequence
> > aLabeledSeqVec
;
1793 Reference
< XLabeledDataSequence
> xYValueSeq
=
1794 CreateValueSequence( EXC_CHPROP_ROLE_YVALUES
);
1795 if( xYValueSeq
.is() )
1796 aLabeledSeqVec
.push_back( xYValueSeq
);
1798 if( !rTypeInfo
.mbCategoryAxis
)
1800 Reference
< XLabeledDataSequence
> xXValueSeq
=
1801 CreateCategSequence( EXC_CHPROP_ROLE_XVALUES
);
1802 if( xXValueSeq
.is() )
1803 aLabeledSeqVec
.push_back( xXValueSeq
);
1804 // add size values of bubble charts
1805 if( rTypeInfo
.meTypeId
== EXC_CHTYPEID_BUBBLES
)
1807 Reference
< XLabeledDataSequence
> xSizeValueSeq
=
1808 lclCreateLabeledDataSequence( mxBubbleLink
, EXC_CHPROP_ROLE_SIZEVALUES
, mxTitleLink
.get() );
1809 if( xSizeValueSeq
.is() )
1810 aLabeledSeqVec
.push_back( xSizeValueSeq
);
1813 // attach labeled data sequences to series
1814 if( !aLabeledSeqVec
.empty() )
1815 xDataSink
->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec
) );
1818 // series formatting
1819 ScfPropertySet
aSeriesProp( xDataSeries
);
1820 if( mxSeriesFmt
.is() )
1821 mxSeriesFmt
->Convert( aSeriesProp
, rTypeInfo
);
1824 ConvertTrendLines( xDataSeries
);
1827 Reference
< XPropertySet
> xErrorBarX
= CreateErrorBar( EXC_CHSERERR_XPLUS
, EXC_CHSERERR_XMINUS
);
1828 if( xErrorBarX
.is() )
1829 aSeriesProp
.SetProperty( EXC_CHPROP_ERRORBARX
, xErrorBarX
);
1830 Reference
< XPropertySet
> xErrorBarY
= CreateErrorBar( EXC_CHSERERR_YPLUS
, EXC_CHSERERR_YMINUS
);
1831 if( xErrorBarY
.is() )
1832 aSeriesProp
.SetProperty( EXC_CHPROP_ERRORBARY
, xErrorBarY
);
1834 // own area formatting for every data point (TODO: varying line color not supported)
1835 bool bVarPointFmt
= pTypeGroup
->HasVarPointFormat() && rTypeInfo
.IsSeriesFrameFormat();
1836 #if EXC_CHART2_VARYCOLORSBY_PROP
1837 aSeriesProp
.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY
, bVarPointFmt
);
1839 aSeriesProp
.SetBoolProperty( EXC_CHPROP_VARYCOLORSBY
, rTypeInfo
.meTypeCateg
== EXC_CHTYPECATEG_PIE
);
1841 // #i91271# always set area formatting for every point in pie/doughnut charts
1842 if( mxSeriesFmt
.is() && ((bVarPointFmt
&& mxSeriesFmt
->IsAutoArea()) || (rTypeInfo
.meTypeCateg
== EXC_CHTYPECATEG_PIE
)) )
1844 for( sal_uInt16 nPointIdx
= 0, nPointCount
= mxValueLink
->GetCellCount(); nPointIdx
< nPointCount
; ++nPointIdx
)
1846 ScfPropertySet aPointProp
= lclGetPointPropSet( xDataSeries
, nPointIdx
);
1847 mxSeriesFmt
->ConvertArea( aPointProp
, bVarPointFmt
? nPointIdx
: mnSeriesIdx
);
1851 // data point formatting
1852 for( XclImpChDataFormatMap::const_iterator aIt
= maPointFmts
.begin(), aEnd
= maPointFmts
.end(); aIt
!= aEnd
; ++aIt
)
1854 ScfPropertySet aPointProp
= lclGetPointPropSet( xDataSeries
, aIt
->first
);
1855 aIt
->second
->Convert( aPointProp
, rTypeInfo
);
1861 void XclImpChSeries::FillAllSourceLinks(vector
<ScSharedTokenRef
>& rTokens
) const
1863 mxValueLink
->FillSourceLink(rTokens
);
1864 mxCategLink
->FillSourceLink(rTokens
);
1865 mxTitleLink
->FillSourceLink(rTokens
);
1866 mxBubbleLink
->FillSourceLink(rTokens
);
1869 void XclImpChSeries::ReadChSourceLink( XclImpStream
& rStrm
)
1871 XclImpChSourceLinkRef
xSrcLink( new XclImpChSourceLink( GetChRoot() ) );
1872 xSrcLink
->ReadChSourceLink( rStrm
);
1873 switch( xSrcLink
->GetDestType() )
1875 case EXC_CHSRCLINK_TITLE
: mxTitleLink
= xSrcLink
; break;
1876 case EXC_CHSRCLINK_VALUES
: mxValueLink
= xSrcLink
; break;
1877 case EXC_CHSRCLINK_CATEGORY
: mxCategLink
= xSrcLink
; break;
1878 case EXC_CHSRCLINK_BUBBLES
: mxBubbleLink
= xSrcLink
; break;
1882 void XclImpChSeries::ReadChDataFormat( XclImpStream
& rStrm
)
1884 // #i51639# chart stores all data formats and assigns them later to the series
1885 GetChartData().ReadChDataFormat( rStrm
);
1888 void XclImpChSeries::ReadChSerParent( XclImpStream
& rStrm
)
1890 rStrm
>> mnParentIdx
;
1891 // index to parent series is 1-based, convert it to 0-based
1892 if( mnParentIdx
> 0 )
1895 mnParentIdx
= EXC_CHSERIES_INVALID
;
1898 void XclImpChSeries::ReadChSerTrendLine( XclImpStream
& rStrm
)
1900 XclImpChSerTrendLineRef
xTrendLine( new XclImpChSerTrendLine( GetChRoot() ) );
1901 xTrendLine
->ReadChSerTrendLine( rStrm
);
1902 maTrendLines
.push_back( xTrendLine
);
1905 void XclImpChSeries::ReadChSerErrorBar( XclImpStream
& rStrm
)
1907 XclImpChSerErrorBarRef
xErrorBar( new XclImpChSerErrorBar( GetChRoot() ) );
1908 xErrorBar
->ReadChSerErrorBar( rStrm
);
1909 maErrorBars
[ xErrorBar
->GetBarType() ] = xErrorBar
;
1912 XclImpChDataFormatRef
XclImpChSeries::CreateDataFormat( sal_uInt16 nPointIdx
, sal_uInt16 nFormatIdx
)
1914 XclImpChDataFormatRef
xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
1915 xDataFmt
->SetPointPos( XclChDataPointPos( mnSeriesIdx
, nPointIdx
), nFormatIdx
);
1919 XclImpChDataFormatRef
* XclImpChSeries::GetDataFormatRef( sal_uInt16 nPointIdx
)
1921 if( nPointIdx
== EXC_CHDATAFORMAT_ALLPOINTS
)
1922 return &mxSeriesFmt
;
1923 if( nPointIdx
< EXC_CHDATAFORMAT_MAXPOINTCOUNT
)
1924 return &maPointFmts
[ nPointIdx
];
1928 XclImpChTextRef
* XclImpChSeries::GetDataLabelRef( sal_uInt16 nPointIdx
)
1930 if( (nPointIdx
== EXC_CHDATAFORMAT_ALLPOINTS
) || (nPointIdx
< EXC_CHDATAFORMAT_MAXPOINTCOUNT
) )
1931 return &maLabels
[ nPointIdx
];
1935 void XclImpChSeries::ConvertTrendLines( Reference
< XDataSeries
> xDataSeries
) const
1937 Reference
< XRegressionCurveContainer
> xRegCurveCont( xDataSeries
, UNO_QUERY
);
1938 if( xRegCurveCont
.is() )
1940 for( XclImpChSerTrendLineList::const_iterator aIt
= maTrendLines
.begin(), aEnd
= maTrendLines
.end(); aIt
!= aEnd
; ++aIt
)
1944 Reference
< XRegressionCurve
> xRegCurve
= (*aIt
)->CreateRegressionCurve();
1945 if( xRegCurve
.is() )
1946 xRegCurveCont
->addRegressionCurve( xRegCurve
);
1950 DBG_ERRORFILE( "XclImpChSeries::ConvertTrendLines - cannot add regression curve" );
1956 Reference
< XPropertySet
> XclImpChSeries::CreateErrorBar( sal_uInt8 nPosBarId
, sal_uInt8 nNegBarId
) const
1958 return XclImpChSerErrorBar::CreateErrorBar( maErrorBars
.get( nPosBarId
).get(), maErrorBars
.get( nNegBarId
).get() );
1961 // Chart type groups ==========================================================
1963 XclImpChType::XclImpChType( const XclImpChRoot
& rRoot
) :
1964 XclImpChRoot( rRoot
),
1965 mnRecId( EXC_ID_CHUNKNOWN
),
1966 maTypeInfo( rRoot
.GetChartTypeInfo( EXC_CHTYPEID_UNKNOWN
) )
1970 void XclImpChType::ReadChType( XclImpStream
& rStrm
)
1972 sal_uInt16 nRecId
= rStrm
.GetRecId();
1973 bool bKnownType
= true;
1978 rStrm
>> maData
.mnOverlap
>> maData
.mnGap
>> maData
.mnFlags
;
1983 case EXC_ID_CHRADARLINE
:
1984 case EXC_ID_CHRADARAREA
:
1985 rStrm
>> maData
.mnFlags
;
1989 rStrm
>> maData
.mnRotation
>> maData
.mnPieHole
;
1990 if( GetBiff() == EXC_BIFF8
)
1991 rStrm
>> maData
.mnFlags
;
1996 case EXC_ID_CHPIEEXT
:
1997 maData
.mnRotation
= 0;
1998 maData
.mnPieHole
= 0;
2002 case EXC_ID_CHSCATTER
:
2003 if( GetBiff() == EXC_BIFF8
)
2004 rStrm
>> maData
.mnBubbleSize
>> maData
.mnBubbleType
>> maData
.mnFlags
;
2009 case EXC_ID_CHSURFACE
:
2010 rStrm
>> maData
.mnFlags
;
2021 void XclImpChType::Finalize( bool bStockChart
)
2026 maTypeInfo
= GetChartTypeInfo( bStockChart
?
2027 EXC_CHTYPEID_STOCK
: EXC_CHTYPEID_LINE
);
2030 maTypeInfo
= GetChartTypeInfo( ::get_flagvalue(
2031 maData
.mnFlags
, EXC_CHBAR_HORIZONTAL
,
2032 EXC_CHTYPEID_HORBAR
, EXC_CHTYPEID_BAR
) );
2035 maTypeInfo
= GetChartTypeInfo( (maData
.mnPieHole
> 0) ?
2036 EXC_CHTYPEID_DONUT
: EXC_CHTYPEID_PIE
);
2038 case EXC_ID_CHSCATTER
:
2039 maTypeInfo
= GetChartTypeInfo( ::get_flagvalue(
2040 maData
.mnFlags
, EXC_CHSCATTER_BUBBLES
,
2041 EXC_CHTYPEID_BUBBLES
, EXC_CHTYPEID_SCATTER
) );
2044 maTypeInfo
= GetChartTypeInfo( mnRecId
);
2047 switch( maTypeInfo
.meTypeId
)
2049 case EXC_CHTYPEID_PIEEXT
:
2050 case EXC_CHTYPEID_BUBBLES
:
2051 case EXC_CHTYPEID_SURFACE
:
2052 case EXC_CHTYPEID_UNKNOWN
:
2053 GetTracer().TraceChartUnKnownType();
2059 bool XclImpChType::IsStacked() const
2061 bool bStacked
= false;
2062 if( maTypeInfo
.mbSupportsStacking
) switch( maTypeInfo
.meTypeCateg
)
2064 case EXC_CHTYPECATEG_LINE
:
2066 ::get_flag( maData
.mnFlags
, EXC_CHLINE_STACKED
) &&
2067 !::get_flag( maData
.mnFlags
, EXC_CHLINE_PERCENT
);
2069 case EXC_CHTYPECATEG_BAR
:
2071 ::get_flag( maData
.mnFlags
, EXC_CHBAR_STACKED
) &&
2072 !::get_flag( maData
.mnFlags
, EXC_CHBAR_PERCENT
);
2079 bool XclImpChType::IsPercent() const
2081 bool bPercent
= false;
2082 if( maTypeInfo
.mbSupportsStacking
) switch( maTypeInfo
.meTypeCateg
)
2084 case EXC_CHTYPECATEG_LINE
:
2086 ::get_flag( maData
.mnFlags
, EXC_CHLINE_STACKED
) &&
2087 ::get_flag( maData
.mnFlags
, EXC_CHLINE_PERCENT
);
2089 case EXC_CHTYPECATEG_BAR
:
2091 ::get_flag( maData
.mnFlags
, EXC_CHBAR_STACKED
) &&
2092 ::get_flag( maData
.mnFlags
, EXC_CHBAR_PERCENT
);
2099 bool XclImpChType::HasCategoryLabels() const
2101 // radar charts disable category labels in chart type, not in CHTICK of X axis
2102 return (maTypeInfo
.meTypeCateg
!= EXC_CHTYPECATEG_RADAR
) || ::get_flag( maData
.mnFlags
, EXC_CHRADAR_AXISLABELS
);
2105 Reference
< XCoordinateSystem
> XclImpChType::CreateCoordSystem( bool b3dChart
) const
2108 OUString aCoordSysService
;
2109 if( maTypeInfo
.mbPolarCoordSystem
)
2112 aCoordSysService
= SERVICE_CHART2_POLARCOORDSYS3D
;
2114 aCoordSysService
= SERVICE_CHART2_POLARCOORDSYS2D
;
2119 aCoordSysService
= SERVICE_CHART2_CARTESIANCOORDSYS3D
;
2121 aCoordSysService
= SERVICE_CHART2_CARTESIANCOORDSYS2D
;
2124 // create the coordinate system object
2125 Reference
< XCoordinateSystem
> xCoordSystem( ScfApiHelper::CreateInstance( aCoordSysService
), UNO_QUERY
);
2127 // swap X and Y axis
2128 if( maTypeInfo
.mbSwappedAxesSet
)
2130 ScfPropertySet
aCoordSysProp( xCoordSystem
);
2131 aCoordSysProp
.SetBoolProperty( EXC_CHPROP_SWAPXANDYAXIS
, true );
2134 return xCoordSystem
;
2137 Reference
< XChartType
> XclImpChType::CreateChartType( Reference
< XDiagram
> xDiagram
, bool b3dChart
) const
2139 OUString aService
= OUString::createFromAscii( maTypeInfo
.mpcServiceName
);
2140 Reference
< XChartType
> xChartType( ScfApiHelper::CreateInstance( aService
), UNO_QUERY
);
2142 // additional properties
2143 switch( maTypeInfo
.meTypeCateg
)
2145 case EXC_CHTYPECATEG_LINE
:
2147 ScfPropertySet
aTypeProp(xChartType
);
2148 bool bStacked
= (maData
.mnFlags
& EXC_CHLINE_STACKED
);
2149 bool bPercent
= (maData
.mnFlags
& EXC_CHLINE_PERCENT
);
2150 aTypeProp
.SetBoolProperty(EXC_CHPROP_STACKED
, bStacked
);
2151 aTypeProp
.SetBoolProperty(EXC_CHPROP_PERCENT
, bPercent
);
2154 case EXC_CHTYPECATEG_BAR
:
2156 ScfPropertySet
aTypeProp( xChartType
);
2157 Sequence
< sal_Int32
> aInt32Seq( 2 );
2158 aInt32Seq
[ 0 ] = aInt32Seq
[ 1 ] = -maData
.mnOverlap
;
2159 aTypeProp
.SetProperty( EXC_CHPROP_OVERLAPSEQ
, aInt32Seq
);
2160 aInt32Seq
[ 0 ] = aInt32Seq
[ 1 ] = maData
.mnGap
;
2161 aTypeProp
.SetProperty( EXC_CHPROP_GAPWIDTHSEQ
, aInt32Seq
);
2162 bool bStacked
= (maData
.mnFlags
& EXC_CHBAR_STACKED
);
2163 bool bPercent
= (maData
.mnFlags
& EXC_CHBAR_PERCENT
);
2164 aTypeProp
.SetBoolProperty(EXC_CHPROP_STACKED
, bStacked
);
2165 aTypeProp
.SetBoolProperty(EXC_CHPROP_PERCENT
, bPercent
);
2168 case EXC_CHTYPECATEG_PIE
:
2170 ScfPropertySet
aTypeProp( xChartType
);
2171 aTypeProp
.SetBoolProperty( EXC_CHPROP_USERINGS
, maTypeInfo
.meTypeId
== EXC_CHTYPEID_DONUT
);
2172 /* #i85166# starting angle of first pie slice. 3D pie charts use Y
2173 rotation setting in view3D element. Of-pie charts do not
2174 support pie rotation. */
2175 if( !b3dChart
&& (maTypeInfo
.meTypeId
!= EXC_CHTYPEID_PIEEXT
) )
2177 ScfPropertySet
aDiaProp( xDiagram
);
2178 XclImpChRoot::ConvertPieRotation( aDiaProp
, maData
.mnRotation
);
2188 // ----------------------------------------------------------------------------
2190 void XclImpChChart3d::ReadChChart3d( XclImpStream
& rStrm
)
2192 rStrm
>> maData
.mnRotation
2193 >> maData
.mnElevation
2195 >> maData
.mnRelHeight
2196 >> maData
.mnRelDepth
2197 >> maData
.mnDepthGap
2201 void XclImpChChart3d::Convert( ScfPropertySet
& rPropSet
, bool b3dWallChart
) const
2203 namespace cssd
= ::com::sun::star::drawing
;
2205 // #i104057# do not assert this, written by broken external generators
2206 // DBG_ASSERT( ::get_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS ) == b3dWallChart, "XclImpChChart3d::Convert - wrong wall flag" );
2208 sal_Int32 nRotationY
= 0;
2209 sal_Int32 nRotationX
= 0;
2210 sal_Int32 nPerspective
= 15;
2211 bool bRightAngled
= false;
2212 cssd::ProjectionMode eProjMode
= cssd::ProjectionMode_PERSPECTIVE
;
2213 Color aAmbientColor
, aLightColor
;
2217 // Y rotation (Excel [0..359], Chart2 [-179,180])
2218 nRotationY
= maData
.mnRotation
% 360;
2219 if( nRotationY
> 180 ) nRotationY
-= 360;
2220 // X rotation a.k.a. elevation (Excel [-90..90], Chart2 [-179,180])
2221 nRotationX
= limit_cast
< sal_Int32
, sal_Int32
>( maData
.mnElevation
, -90, 90 );
2222 // perspective (Excel and Chart2 [0,100])
2223 nPerspective
= limit_cast
< sal_Int32
, sal_Int32
>( maData
.mnEyeDist
, 0, 100 );
2224 // right-angled axes
2225 bRightAngled
= !::get_flag( maData
.mnFlags
, EXC_CHCHART3D_REAL3D
);
2226 // projection mode (parallel axes, if right-angled, #i90360# or if perspective is at 0%)
2227 bool bParallel
= bRightAngled
|| (nPerspective
== 0);
2228 eProjMode
= bParallel
? cssd::ProjectionMode_PARALLEL
: cssd::ProjectionMode_PERSPECTIVE
;
2229 // ambient color (Gray 20%)
2230 aAmbientColor
.SetColor( RGB_COLORDATA( 204, 204, 204 ) );
2231 // light color (Gray 60%)
2232 aLightColor
.SetColor( RGB_COLORDATA( 102, 102, 102 ) );
2236 // Y rotation not used in pie charts, but 'first pie slice angle'
2238 XclImpChRoot::ConvertPieRotation( rPropSet
, maData
.mnRotation
);
2239 // X rotation a.k.a. elevation (map Excel [10..80] to Chart2 [-80,-10])
2240 nRotationX
= limit_cast
< sal_Int32
, sal_Int32
>( maData
.mnElevation
, 10, 80 ) - 90;
2241 // perspective (Excel and Chart2 [0,100])
2242 nPerspective
= limit_cast
< sal_Int32
, sal_Int32
>( maData
.mnEyeDist
, 0, 100 );
2243 // no right-angled axes in pie charts, but parallel projection
2244 bRightAngled
= false;
2245 eProjMode
= cssd::ProjectionMode_PARALLEL
;
2246 // ambient color (Gray 30%)
2247 aAmbientColor
.SetColor( RGB_COLORDATA( 179, 179, 179 ) );
2248 // light color (Gray 70%)
2249 aLightColor
.SetColor( RGB_COLORDATA( 76, 76, 76 ) );
2253 rPropSet
.SetProperty( EXC_CHPROP_ROTATIONVERTICAL
, nRotationY
);
2254 rPropSet
.SetProperty( EXC_CHPROP_ROTATIONHORIZONTAL
, nRotationX
);
2255 rPropSet
.SetProperty( EXC_CHPROP_PERSPECTIVE
, nPerspective
);
2256 rPropSet
.SetBoolProperty( EXC_CHPROP_RIGHTANGLEDAXES
, bRightAngled
);
2257 rPropSet
.SetProperty( EXC_CHPROP_D3DSCENEPERSPECTIVE
, eProjMode
);
2260 rPropSet
.SetProperty( EXC_CHPROP_D3DSCENESHADEMODE
, cssd::ShadeMode_FLAT
);
2261 rPropSet
.SetColorProperty( EXC_CHPROP_D3DSCENEAMBIENTCOLOR
, aAmbientColor
);
2262 rPropSet
.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON1
, false );
2263 rPropSet
.SetBoolProperty( EXC_CHPROP_D3DSCENELIGHTON2
, true );
2264 rPropSet
.SetColorProperty( EXC_CHPROP_D3DSCENELIGHTCOLOR2
, aLightColor
);
2265 rPropSet
.SetProperty( EXC_CHPROP_D3DSCENELIGHTDIR2
, cssd::Direction3D( 0.2, 0.4, 1.0 ) );
2268 // ----------------------------------------------------------------------------
2270 XclImpChLegend::XclImpChLegend( const XclImpChRoot
& rRoot
) :
2271 XclImpChRoot( rRoot
)
2275 void XclImpChLegend::ReadHeaderRecord( XclImpStream
& rStrm
)
2277 rStrm
>> maData
.maRect
>> maData
.mnDockMode
>> maData
.mnSpacing
>> maData
.mnFlags
;
2279 // trace unsupported features
2280 if( GetTracer().IsEnabled() )
2282 if( maData
.mnDockMode
== EXC_CHLEGEND_NOTDOCKED
)
2283 GetTracer().TraceChartLegendPosition();
2284 if( ::get_flag( maData
.mnFlags
, EXC_CHLEGEND_DATATABLE
) )
2285 GetTracer().TraceChartDataTable();
2289 void XclImpChLegend::ReadSubRecord( XclImpStream
& rStrm
)
2291 switch( rStrm
.GetRecId() )
2294 mxText
.reset( new XclImpChText( GetChRoot() ) );
2295 mxText
->ReadRecordGroup( rStrm
);
2297 case EXC_ID_CHFRAME
:
2298 mxFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND
) );
2299 mxFrame
->ReadRecordGroup( rStrm
);
2304 void XclImpChLegend::Finalize()
2306 // legend default formatting differs in OOChart and Excel, missing frame means automatic
2308 mxFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_LEGEND
) );
2309 // Update text formatting. If mxText is empty, the passed default text is used.
2310 lclUpdateText( mxText
, GetChartData().GetDefaultText( EXC_CHTEXTTYPE_LEGEND
) );
2313 Reference
< XLegend
> XclImpChLegend::CreateLegend() const
2315 Reference
< XLegend
> xLegend( ScfApiHelper::CreateInstance( SERVICE_CHART2_LEGEND
), UNO_QUERY
);
2318 ScfPropertySet
aLegendProp( xLegend
);
2322 mxFrame
->Convert( aLegendProp
);
2325 mxText
->ConvertFont( aLegendProp
);
2326 // special legend properties
2327 GetChartPropSetHelper().WriteLegendProperties( aLegendProp
, maData
);
2332 // ----------------------------------------------------------------------------
2334 XclImpChDropBar::XclImpChDropBar( sal_uInt16 nDropBar
) :
2335 mnDropBar( nDropBar
),
2340 void XclImpChDropBar::ReadHeaderRecord( XclImpStream
& rStrm
)
2345 void XclImpChDropBar::Convert( const XclImpChRoot
& rRoot
, ScfPropertySet
& rPropSet
) const
2347 XclChObjectType eObjType
= EXC_CHOBJTYPE_BACKGROUND
;
2350 case EXC_CHDROPBAR_UP
: eObjType
= EXC_CHOBJTYPE_WHITEDROPBAR
; break;
2351 case EXC_CHDROPBAR_DOWN
: eObjType
= EXC_CHOBJTYPE_BLACKDROPBAR
; break;
2353 ConvertFrameBase( rRoot
, rPropSet
, eObjType
);
2356 // ----------------------------------------------------------------------------
2358 XclImpChTypeGroup::XclImpChTypeGroup( const XclImpChRoot
& rRoot
) :
2359 XclImpChRoot( rRoot
),
2361 maTypeInfo( maType
.GetTypeInfo() )
2363 // Initialize unused format indexes set. At this time, all formats are unused.
2364 for( sal_uInt16 nFormatIdx
= 0; nFormatIdx
<= EXC_CHSERIES_MAXSERIES
; ++nFormatIdx
)
2365 maUnusedFormats
.insert( maUnusedFormats
.end(), nFormatIdx
);
2368 void XclImpChTypeGroup::ReadHeaderRecord( XclImpStream
& rStrm
)
2370 rStrm
>> maData
.maRect
>> maData
.mnFlags
>> maData
.mnGroupIdx
;
2373 void XclImpChTypeGroup::ReadSubRecord( XclImpStream
& rStrm
)
2375 switch( rStrm
.GetRecId() )
2377 case EXC_ID_CHCHART3D
:
2378 mxChart3d
.reset( new XclImpChChart3d
);
2379 mxChart3d
->ReadChChart3d( rStrm
);
2381 case EXC_ID_CHLEGEND
:
2382 mxLegend
.reset( new XclImpChLegend( GetChRoot() ) );
2383 mxLegend
->ReadRecordGroup( rStrm
);
2385 case EXC_ID_CHDEFAULTTEXT
:
2386 GetChartData().ReadChDefaultText( rStrm
);
2388 case EXC_ID_CHDROPBAR
:
2389 ReadChDropBar( rStrm
);
2391 case EXC_ID_CHCHARTLINE
:
2392 ReadChChartLine( rStrm
);
2394 case EXC_ID_CHDATAFORMAT
:
2395 ReadChDataFormat( rStrm
);
2398 maType
.ReadChType( rStrm
);
2402 void XclImpChTypeGroup::Finalize()
2404 // check and set valid chart type
2406 (maType
.GetRecId() == EXC_ID_CHLINE
) && // must be a line chart
2407 !mxChart3d
&& // must be a 2d chart
2408 HasHiLoLine() && // must contain hi-lo lines
2409 (maSeries
.size() == static_cast<XclImpChSeriesVec::size_type
>(HasDropBars() ? 4 : 3)); // correct series count
2410 maType
.Finalize( bStockChart
);
2412 // extended type info
2413 maTypeInfo
.Set( maType
.GetTypeInfo(), mxChart3d
.is(), false );
2415 // reverse series order for some unstacked 2D chart types
2416 if( maTypeInfo
.mbReverseSeries
&& !Is3dChart() && !maType
.IsStacked() && !maType
.IsPercent() )
2417 ::std::reverse( maSeries
.begin(), maSeries
.end() );
2419 // update chart type group format, may depend on chart type finalized above
2420 if( mxGroupFmt
.is() )
2421 mxGroupFmt
->UpdateGroupFormat( maTypeInfo
);
2424 void XclImpChTypeGroup::AddSeries( XclImpChSeriesRef xSeries
)
2427 maSeries
.push_back( xSeries
);
2428 // store first inserted series separately, series order may be reversed later
2429 if( !mxFirstSeries
)
2430 mxFirstSeries
= xSeries
;
2433 void XclImpChTypeGroup::SetUsedFormatIndex( sal_uInt16 nFormatIdx
)
2435 maUnusedFormats
.erase( nFormatIdx
);
2438 sal_uInt16
XclImpChTypeGroup::PopUnusedFormatIndex()
2440 DBG_ASSERT( !maUnusedFormats
.empty(), "XclImpChTypeGroup::PopUnusedFormatIndex - no more format indexes available" );
2441 sal_uInt16 nFormatIdx
= maUnusedFormats
.empty() ? 0 : *maUnusedFormats
.begin();
2442 SetUsedFormatIndex( nFormatIdx
);
2446 bool XclImpChTypeGroup::HasVarPointFormat() const
2448 return ::get_flag( maData
.mnFlags
, EXC_CHTYPEGROUP_VARIEDCOLORS
) &&
2449 ((maTypeInfo
.meVarPointMode
== EXC_CHVARPOINT_MULTI
) || // multiple series allowed
2450 ((maTypeInfo
.meVarPointMode
== EXC_CHVARPOINT_SINGLE
) && // or exactly 1 series?
2451 (maSeries
.size() == 1)));
2454 bool XclImpChTypeGroup::HasConnectorLines() const
2456 // existence of connector lines (only in stacked bar charts)
2457 bool bAnyStacked
= maType
.IsStacked() || maType
.IsPercent();
2458 XclImpChLineFormatRef xConnLine
= maChartLines
.get( EXC_CHCHARTLINE_CONNECT
);
2459 return bAnyStacked
&& (maTypeInfo
.meTypeCateg
== EXC_CHTYPECATEG_BAR
) && xConnLine
.is() && xConnLine
->HasLine();
2462 const String
& XclImpChTypeGroup::GetSingleSeriesTitle() const
2464 // no automatic title for series with trendlines or error bars
2465 // pie charts always show an automatic title, even if more series exist
2466 return (mxFirstSeries
.is() && !mxFirstSeries
->HasChildSeries() && (maTypeInfo
.mbSingleSeriesVis
|| (maSeries
.size() == 1))) ?
2467 mxFirstSeries
->GetTitle() : String::EmptyString();
2470 void XclImpChTypeGroup::ConvertChart3d( ScfPropertySet
& rPropSet
) const
2472 if( mxChart3d
.is() )
2473 mxChart3d
->Convert( rPropSet
, Is3dWallChart() );
2476 Reference
< XCoordinateSystem
> XclImpChTypeGroup::CreateCoordSystem() const
2478 return maType
.CreateCoordSystem( Is3dChart() );
2481 Reference
< XChartType
> XclImpChTypeGroup::CreateChartType( Reference
< XDiagram
> xDiagram
, sal_Int32 nApiAxesSetIdx
) const
2483 DBG_ASSERT( IsValidGroup(), "XclImpChTypeGroup::CreateChartType - type group without series" );
2485 // create the chart type object
2486 Reference
< XChartType
> xChartType
= maType
.CreateChartType( xDiagram
, Is3dChart() );
2488 // bar chart connector lines
2489 if( HasConnectorLines() )
2491 ScfPropertySet
aDiaProp( xDiagram
);
2492 aDiaProp
.SetBoolProperty( EXC_CHPROP_CONNECTBARS
, true );
2495 /* Stock chart needs special processing. Create one 'big' series with
2496 data sequences of different roles. */
2497 if( maTypeInfo
.meTypeId
== EXC_CHTYPEID_STOCK
)
2498 CreateStockSeries( xChartType
, nApiAxesSetIdx
);
2500 CreateDataSeries( xChartType
, nApiAxesSetIdx
);
2505 Reference
< XLabeledDataSequence
> XclImpChTypeGroup::CreateCategSequence() const
2507 Reference
< XLabeledDataSequence
> xLabeledSeq
;
2508 // create category sequence from first visible series
2509 if( mxFirstSeries
.is() )
2510 xLabeledSeq
= mxFirstSeries
->CreateCategSequence( EXC_CHPROP_ROLE_CATEG
);
2514 void XclImpChTypeGroup::ReadChDropBar( XclImpStream
& rStrm
)
2516 sal_uInt16 nDropBar
= EXC_CHDROPBAR_NONE
;
2517 if( !maDropBars
.has( EXC_CHDROPBAR_UP
) )
2518 nDropBar
= EXC_CHDROPBAR_UP
;
2519 else if( !maDropBars
.has( EXC_CHDROPBAR_DOWN
) )
2520 nDropBar
= EXC_CHDROPBAR_DOWN
;
2522 if( nDropBar
!= EXC_CHDROPBAR_NONE
)
2524 XclImpChDropBarRef
xDropBar( new XclImpChDropBar( nDropBar
) );
2525 xDropBar
->ReadRecordGroup( rStrm
);
2526 maDropBars
[ nDropBar
] = xDropBar
;
2530 void XclImpChTypeGroup::ReadChChartLine( XclImpStream
& rStrm
)
2532 sal_uInt16 nLineId
= rStrm
.ReaduInt16();
2533 if( (rStrm
.GetNextRecId() == EXC_ID_CHLINEFORMAT
) && rStrm
.StartNextRecord() )
2535 XclImpChLineFormatRef
xLineFmt( new XclImpChLineFormat
);
2536 xLineFmt
->ReadChLineFormat( rStrm
);
2537 maChartLines
[ nLineId
] = xLineFmt
;
2541 void XclImpChTypeGroup::ReadChDataFormat( XclImpStream
& rStrm
)
2543 // global series and data point format
2544 XclImpChDataFormatRef
xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
2545 xDataFmt
->ReadRecordGroup( rStrm
);
2546 const XclChDataPointPos
& rPos
= xDataFmt
->GetPointPos();
2547 if( (rPos
.mnSeriesIdx
== 0) && (rPos
.mnPointIdx
== 0) &&
2548 (xDataFmt
->GetFormatIdx() == EXC_CHDATAFORMAT_DEFAULT
) )
2549 mxGroupFmt
= xDataFmt
;
2553 void XclImpChTypeGroup::InsertDataSeries( Reference
< XChartType
> xChartType
,
2554 Reference
< XDataSeries
> xSeries
, sal_Int32 nApiAxesSetIdx
) const
2556 Reference
< XDataSeriesContainer
> xSeriesCont( xChartType
, UNO_QUERY
);
2557 if( xSeriesCont
.is() && xSeries
.is() )
2559 // series stacking mode
2560 namespace cssc
= ::com::sun::star::chart2
;
2561 cssc::StackingDirection eStacking
= cssc::StackingDirection_NO_STACKING
;
2562 // stacked overrides deep-3d
2563 if( maType
.IsStacked() || maType
.IsPercent() )
2564 eStacking
= cssc::StackingDirection_Y_STACKING
;
2565 else if( Is3dDeepChart() )
2566 eStacking
= cssc::StackingDirection_Z_STACKING
;
2568 // additional series properties
2569 ScfPropertySet
aSeriesProp( xSeries
);
2570 aSeriesProp
.SetProperty( EXC_CHPROP_STACKINGDIR
, eStacking
);
2571 aSeriesProp
.SetProperty( EXC_CHPROP_ATTAXISINDEX
, nApiAxesSetIdx
);
2573 // insert series into container
2576 xSeriesCont
->addDataSeries( xSeries
);
2580 DBG_ERRORFILE( "XclImpChTypeGroup::InsertDataSeries - cannot add data series" );
2585 void XclImpChTypeGroup::CreateDataSeries( Reference
< XChartType
> xChartType
, sal_Int32 nApiAxesSetIdx
) const
2587 bool bSpline
= false;
2588 for( XclImpChSeriesVec::const_iterator aIt
= maSeries
.begin(), aEnd
= maSeries
.end(); aIt
!= aEnd
; ++aIt
)
2590 Reference
< XDataSeries
> xDataSeries
= (*aIt
)->CreateDataSeries();
2591 InsertDataSeries( xChartType
, xDataSeries
, nApiAxesSetIdx
);
2592 bSpline
|= (*aIt
)->HasSpline();
2594 // spline - TODO: set at single series (#i66858#)
2595 if( bSpline
&& !maTypeInfo
.IsSeriesFrameFormat() && (maTypeInfo
.meTypeCateg
!= EXC_CHTYPECATEG_RADAR
) )
2597 ScfPropertySet
aTypeProp( xChartType
);
2598 aTypeProp
.SetProperty( EXC_CHPROP_CURVESTYLE
, ::com::sun::star::chart2::CurveStyle_CUBIC_SPLINES
);
2602 void XclImpChTypeGroup::CreateStockSeries( Reference
< XChartType
> xChartType
, sal_Int32 nApiAxesSetIdx
) const
2604 // create the data series object
2605 Reference
< XDataSeries
> xDataSeries( ScfApiHelper::CreateInstance( SERVICE_CHART2_DATASERIES
), UNO_QUERY
);
2606 Reference
< XDataSink
> xDataSink( xDataSeries
, UNO_QUERY
);
2607 if( xDataSink
.is() )
2609 // create a list of data sequences from all series
2610 ::std::vector
< Reference
< XLabeledDataSequence
> > aLabeledSeqVec
;
2611 DBG_ASSERT( maSeries
.size() >= 3, "XclImpChTypeGroup::CreateChartType - missing stock series" );
2612 int nRoleIdx
= (maSeries
.size() == 3) ? 1 : 0;
2613 for( XclImpChSeriesVec::const_iterator aIt
= maSeries
.begin(), aEnd
= maSeries
.end();
2614 (nRoleIdx
< 4) && (aIt
!= aEnd
); ++nRoleIdx
, ++aIt
)
2616 // create a data sequence with a specific role
2620 case 0: aRole
= EXC_CHPROP_ROLE_OPENVALUES
; break;
2621 case 1: aRole
= EXC_CHPROP_ROLE_HIGHVALUES
; break;
2622 case 2: aRole
= EXC_CHPROP_ROLE_LOWVALUES
; break;
2623 case 3: aRole
= EXC_CHPROP_ROLE_CLOSEVALUES
; break;
2625 Reference
< XLabeledDataSequence
> xDataSeq
= (*aIt
)->CreateValueSequence( aRole
);
2627 aLabeledSeqVec
.push_back( xDataSeq
);
2630 // attach labeled data sequences to series and insert series into chart type
2631 xDataSink
->setData( ScfApiHelper::VectorToSequence( aLabeledSeqVec
) );
2633 // formatting of special stock chart elements
2634 ScfPropertySet
aTypeProp( xChartType
);
2635 aTypeProp
.SetBoolProperty( EXC_CHPROP_JAPANESE
, HasDropBars() );
2636 aTypeProp
.SetBoolProperty( EXC_CHPROP_SHOWFIRST
, HasDropBars() );
2637 aTypeProp
.SetBoolProperty( EXC_CHPROP_SHOWHIGHLOW
, true );
2638 // hi-lo line format
2639 XclImpChLineFormatRef xHiLoLine
= maChartLines
.get( EXC_CHCHARTLINE_HILO
);
2640 if( xHiLoLine
.is() )
2642 ScfPropertySet
aSeriesProp( xDataSeries
);
2643 xHiLoLine
->Convert( GetChRoot(), aSeriesProp
, EXC_CHOBJTYPE_HILOLINE
);
2645 // white dropbar format
2646 XclImpChDropBarRef xUpBar
= maDropBars
.get( EXC_CHDROPBAR_UP
);
2647 Reference
< XPropertySet
> xWhitePropSet
;
2648 if( xUpBar
.is() && aTypeProp
.GetProperty( xWhitePropSet
, EXC_CHPROP_WHITEDAY
) )
2650 ScfPropertySet
aBarProp( xWhitePropSet
);
2651 xUpBar
->Convert( GetChRoot(), aBarProp
);
2653 // black dropbar format
2654 XclImpChDropBarRef xDownBar
= maDropBars
.get( EXC_CHDROPBAR_DOWN
);
2655 Reference
< XPropertySet
> xBlackPropSet
;
2656 if( xDownBar
.is() && aTypeProp
.GetProperty( xBlackPropSet
, EXC_CHPROP_BLACKDAY
) )
2658 ScfPropertySet
aBarProp( xBlackPropSet
);
2659 xDownBar
->Convert( GetChRoot(), aBarProp
);
2662 // insert the series into the chart type object
2663 InsertDataSeries( xChartType
, xDataSeries
, nApiAxesSetIdx
);
2667 // Axes =======================================================================
2669 XclImpChLabelRange::XclImpChLabelRange( const XclImpChRoot
& rRoot
) :
2670 XclImpChRoot( rRoot
)
2674 void XclImpChLabelRange::ReadChLabelRange( XclImpStream
& rStrm
)
2676 rStrm
>> maData
.mnCross
>> maData
.mnLabelFreq
>> maData
.mnTickFreq
>> maData
.mnFlags
;
2679 void XclImpChLabelRange::Convert( ScfPropertySet
& rPropSet
, ScaleData
& rScaleData
, bool bMirrorOrient
) const
2681 // do not overlap text unless all labels are visible
2682 rPropSet
.SetBoolProperty( EXC_CHPROP_TEXTOVERLAP
, maData
.mnLabelFreq
== 1 );
2683 // do not break text into several lines unless all labels are visible
2684 rPropSet
.SetBoolProperty( EXC_CHPROP_TEXTBREAK
, maData
.mnLabelFreq
== 1 );
2685 // do not stagger labels in two lines
2686 namespace cssc
= ::com::sun::star::chart
;
2687 rPropSet
.SetProperty( EXC_CHPROP_ARRANGEORDER
, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE
);
2690 namespace cssc2
= ::com::sun::star::chart2
;
2691 bool bReverse
= ::get_flag( maData
.mnFlags
, EXC_CHLABELRANGE_REVERSE
) != bMirrorOrient
;
2692 rScaleData
.Orientation
= bReverse
? cssc2::AxisOrientation_REVERSE
: cssc2::AxisOrientation_MATHEMATICAL
;
2694 //! TODO #i58731# show n-th category
2697 void XclImpChLabelRange::ConvertAxisPosition( ScfPropertySet
& rPropSet
, bool b3dChart
) const
2699 /* Crossing mode (max-cross flag overrides other crossing settings). Excel
2700 does not move the Y axis in 3D charts, regardless of actual settings.
2701 But: the Y axis has to be moved to "end", if the X axis is mirrored,
2702 to keep it at the left end of the chart. */
2703 bool bMaxCross
= ::get_flag( maData
.mnFlags
, b3dChart
? EXC_CHLABELRANGE_REVERSE
: EXC_CHLABELRANGE_MAXCROSS
);
2704 namespace cssc
= ::com::sun::star::chart
;
2705 cssc::ChartAxisPosition eAxisPos
= bMaxCross
? cssc::ChartAxisPosition_END
: cssc::ChartAxisPosition_VALUE
;
2706 rPropSet
.SetProperty( EXC_CHPROP_CROSSOVERPOSITION
, eAxisPos
);
2708 // crossing position
2709 double fCrossingPos
= b3dChart
? 1.0 : maData
.mnCross
;
2710 rPropSet
.SetProperty( EXC_CHPROP_CROSSOVERVALUE
, fCrossingPos
);
2713 // ----------------------------------------------------------------------------
2715 XclImpChValueRange::XclImpChValueRange( const XclImpChRoot
& rRoot
) :
2716 XclImpChRoot( rRoot
)
2720 void XclImpChValueRange::ReadChValueRange( XclImpStream
& rStrm
)
2722 rStrm
>> maData
.mfMin
2724 >> maData
.mfMajorStep
2725 >> maData
.mfMinorStep
2730 void XclImpChValueRange::Convert( ScaleData
& rScaleData
, bool bMirrorOrient
, bool bPercent
) const
2732 // scaling algorithm
2733 bool bLogScale
= ::get_flag( maData
.mnFlags
, EXC_CHVALUERANGE_LOGSCALE
);
2734 OUString aScalingService
= bLogScale
? SERVICE_CHART2_LOGSCALING
: SERVICE_CHART2_LINEARSCALING
;
2735 rScaleData
.Scaling
.set( ScfApiHelper::CreateInstance( aScalingService
), UNO_QUERY
);
2738 double fMinVal
= bPercent
? maData
.mfMin
/100.0 : maData
.mfMin
;
2739 double fMaxVal
= bPercent
? maData
.mfMax
/100.0 : maData
.mfMax
;
2740 lclSetExpValueOrClearAny( rScaleData
.Minimum
, fMinVal
, bLogScale
, ::get_flag( maData
.mnFlags
, EXC_CHVALUERANGE_AUTOMIN
) );
2741 lclSetExpValueOrClearAny( rScaleData
.Maximum
, fMaxVal
, bLogScale
, ::get_flag( maData
.mnFlags
, EXC_CHVALUERANGE_AUTOMAX
) );
2744 bool bAutoMajor
= ::get_flag( maData
.mnFlags
, EXC_CHVALUERANGE_AUTOMAJOR
);
2745 bool bAutoMinor
= ::get_flag( maData
.mnFlags
, EXC_CHVALUERANGE_AUTOMINOR
);
2747 IncrementData
& rIncrementData
= rScaleData
.IncrementData
;
2748 double fMajorStep
= bPercent
? maData
.mfMajorStep
/100.0 : maData
.mfMajorStep
;
2749 lclSetValueOrClearAny( rIncrementData
.Distance
, fMajorStep
, bAutoMajor
);
2751 Sequence
< SubIncrement
>& rSubIncrementSeq
= rIncrementData
.SubIncrements
;
2752 rSubIncrementSeq
.realloc( 1 );
2753 Any
& rIntervalCount
= rSubIncrementSeq
[ 0 ].IntervalCount
;
2756 rIntervalCount
<<= sal_Int32( 10 );
2760 sal_Int32 nCount
= 0;
2761 if( !bAutoMajor
&& !bAutoMinor
&& (0.0 < maData
.mfMinorStep
) && (maData
.mfMinorStep
<= maData
.mfMajorStep
) )
2763 double fCount
= maData
.mfMajorStep
/ maData
.mfMinorStep
+ 0.5;
2764 if( fCount
< 1001.0 )
2765 nCount
= static_cast< sal_Int32
>( fCount
);
2767 lclSetValueOrClearAny( rIntervalCount
, nCount
, nCount
== 0 );
2771 namespace cssc2
= ::com::sun::star::chart2
;
2772 bool bReverse
= ::get_flag( maData
.mnFlags
, EXC_CHVALUERANGE_REVERSE
) != bMirrorOrient
;
2773 rScaleData
.Orientation
= bReverse
? cssc2::AxisOrientation_REVERSE
: cssc2::AxisOrientation_MATHEMATICAL
;
2776 void XclImpChValueRange::ConvertAxisPosition( ScfPropertySet
& rPropSet
) const
2778 bool bMaxCross
= ::get_flag( maData
.mnFlags
, EXC_CHVALUERANGE_MAXCROSS
);
2779 bool bAutoCross
= ::get_flag( maData
.mnFlags
, EXC_CHVALUERANGE_AUTOCROSS
);
2780 bool bLogScale
= ::get_flag( maData
.mnFlags
, EXC_CHVALUERANGE_LOGSCALE
);
2782 // crossing mode (max-cross flag overrides other crossing settings)
2783 namespace cssc
= ::com::sun::star::chart
;
2784 cssc::ChartAxisPosition eAxisPos
= bMaxCross
? cssc::ChartAxisPosition_END
: cssc::ChartAxisPosition_VALUE
;
2785 rPropSet
.SetProperty( EXC_CHPROP_CROSSOVERPOSITION
, eAxisPos
);
2787 // crossing position
2788 double fCrossingPos
= bAutoCross
? 0.0 : maData
.mfCross
;
2789 if( bLogScale
) fCrossingPos
= pow( 10.0, fCrossingPos
);
2790 rPropSet
.SetProperty( EXC_CHPROP_CROSSOVERVALUE
, fCrossingPos
);
2793 // ----------------------------------------------------------------------------
2797 sal_Int32
lclGetApiTickmarks( sal_uInt8 nXclTickPos
)
2799 using namespace ::com::sun::star::chart2::TickmarkStyle
;
2800 sal_Int32 nApiTickmarks
= NONE
;
2801 ::set_flag( nApiTickmarks
, INNER
, ::get_flag( nXclTickPos
, EXC_CHTICK_INSIDE
) );
2802 ::set_flag( nApiTickmarks
, OUTER
, ::get_flag( nXclTickPos
, EXC_CHTICK_OUTSIDE
) );
2803 return nApiTickmarks
;
2806 ::com::sun::star::chart::ChartAxisLabelPosition
lclGetApiLabelPosition( sal_Int8 nXclLabelPos
)
2808 using namespace ::com::sun::star::chart
;
2809 switch( nXclLabelPos
)
2811 case EXC_CHTICK_LOW
: return ChartAxisLabelPosition_OUTSIDE_START
;
2812 case EXC_CHTICK_HIGH
: return ChartAxisLabelPosition_OUTSIDE_END
;
2813 case EXC_CHTICK_NEXT
: return ChartAxisLabelPosition_NEAR_AXIS
;
2815 return ChartAxisLabelPosition_NEAR_AXIS
;
2820 XclImpChTick::XclImpChTick( const XclImpChRoot
& rRoot
) :
2821 XclImpChRoot( rRoot
)
2825 void XclImpChTick::ReadChTick( XclImpStream
& rStrm
)
2827 rStrm
>> maData
.mnMajor
2829 >> maData
.mnLabelPos
2830 >> maData
.mnBackMode
2832 >> maData
.maTextColor
2835 if( GetBiff() == EXC_BIFF8
)
2837 // #116397# BIFF8: index into palette used instead of RGB data
2838 maData
.maTextColor
= GetPalette().GetColor( rStrm
.ReaduInt16() );
2840 rStrm
>> maData
.mnRotation
;
2844 // BIFF2-BIFF7: get rotation from text orientation
2845 sal_uInt8 nOrient
= ::extract_value
< sal_uInt8
>( maData
.mnFlags
, 2, 3 );
2846 maData
.mnRotation
= XclTools::GetXclRotFromOrient( nOrient
);
2850 Color
XclImpChTick::GetFontColor() const
2852 return ::get_flag( maData
.mnFlags
, EXC_CHTICK_AUTOCOLOR
) ? GetFontAutoColor() : maData
.maTextColor
;
2855 sal_uInt16
XclImpChTick::GetRotation() const
2857 return ::get_flag( maData
.mnFlags
, EXC_CHTICK_AUTOROT
) ? EXC_CHART_AUTOROTATION
: maData
.mnRotation
;
2860 void XclImpChTick::Convert( ScfPropertySet
& rPropSet
) const
2862 rPropSet
.SetProperty( EXC_CHPROP_MAJORTICKS
, lclGetApiTickmarks( maData
.mnMajor
) );
2863 rPropSet
.SetProperty( EXC_CHPROP_MINORTICKS
, lclGetApiTickmarks( maData
.mnMinor
) );
2864 rPropSet
.SetProperty( EXC_CHPROP_LABELPOSITION
, lclGetApiLabelPosition( maData
.mnLabelPos
) );
2865 rPropSet
.SetProperty( EXC_CHPROP_MARKPOSITION
, ::com::sun::star::chart::ChartAxisMarkPosition_AT_AXIS
);
2868 // ----------------------------------------------------------------------------
2870 XclImpChAxis::XclImpChAxis( const XclImpChRoot
& rRoot
, sal_uInt16 nAxisType
) :
2871 XclImpChRoot( rRoot
),
2872 mnNumFmtIdx( EXC_FORMAT_NOTFOUND
)
2874 maData
.mnType
= nAxisType
;
2877 void XclImpChAxis::ReadHeaderRecord( XclImpStream
& rStrm
)
2879 rStrm
>> maData
.mnType
>> maData
.maRect
;
2882 void XclImpChAxis::ReadSubRecord( XclImpStream
& rStrm
)
2884 switch( rStrm
.GetRecId() )
2886 case EXC_ID_CHLABELRANGE
:
2887 mxLabelRange
.reset( new XclImpChLabelRange( GetChRoot() ) );
2888 mxLabelRange
->ReadChLabelRange( rStrm
);
2890 case EXC_ID_CHVALUERANGE
:
2891 mxValueRange
.reset( new XclImpChValueRange( GetChRoot() ) );
2892 mxValueRange
->ReadChValueRange( rStrm
);
2894 case EXC_ID_CHFORMAT
:
2895 rStrm
>> mnNumFmtIdx
;
2898 mxTick
.reset( new XclImpChTick( GetChRoot() ) );
2899 mxTick
->ReadChTick( rStrm
);
2902 mxFont
.reset( new XclImpChFont
);
2903 mxFont
->ReadChFont( rStrm
);
2905 case EXC_ID_CHAXISLINE
:
2906 ReadChAxisLine( rStrm
);
2911 void XclImpChAxis::Finalize()
2913 // add default scaling, needed e.g. to adjust rotation direction of pie and radar charts
2915 mxLabelRange
.reset( new XclImpChLabelRange( GetChRoot() ) );
2917 mxValueRange
.reset( new XclImpChValueRange( GetChRoot() ) );
2918 // remove invisible grid lines completely
2919 if( mxMajorGrid
.is() && !mxMajorGrid
->HasLine() )
2920 mxMajorGrid
.reset();
2921 if( mxMinorGrid
.is() && !mxMinorGrid
->HasLine() )
2922 mxMinorGrid
.reset();
2923 // default tick settings different in OOChart and Excel
2925 mxTick
.reset( new XclImpChTick( GetChRoot() ) );
2926 // #i4140# different default axis line color
2929 XclChLineFormat aLineFmt
;
2930 // set "show axis" flag, default if line format record is missing
2931 ::set_flag( aLineFmt
.mnFlags
, EXC_CHLINEFORMAT_SHOWAXIS
);
2932 mxAxisLine
.reset( new XclImpChLineFormat( aLineFmt
) );
2934 // add wall/floor frame for 3d charts
2939 sal_uInt16
XclImpChAxis::GetFontIndex() const
2941 return mxFont
.is() ? mxFont
->GetFontIndex() : EXC_FONT_NOTFOUND
;
2944 Color
XclImpChAxis::GetFontColor() const
2946 return mxTick
.is() ? mxTick
->GetFontColor() : GetFontAutoColor();
2949 sal_uInt16
XclImpChAxis::GetRotation() const
2951 return mxTick
.is() ? mxTick
->GetRotation() : EXC_CHART_AUTOROTATION
;
2954 Reference
< XAxis
> XclImpChAxis::CreateAxis( const XclImpChTypeGroup
& rTypeGroup
, const XclImpChAxis
* pCrossingAxis
) const
2956 namespace cssc2
= ::com::sun::star::chart2
;
2958 // create the axis object (always)
2959 Reference
< XAxis
> xAxis( ScfApiHelper::CreateInstance( SERVICE_CHART2_AXIS
), UNO_QUERY
);
2962 ScfPropertySet
aAxisProp( xAxis
);
2963 // #i58688# axis enabled
2964 aAxisProp
.SetBoolProperty( EXC_CHPROP_SHOW
, IsActivated() );
2966 // axis line properties
2967 if( mxAxisLine
.is() )
2968 mxAxisLine
->Convert( GetChRoot(), aAxisProp
, EXC_CHOBJTYPE_AXISLINE
);
2969 // axis ticks properties
2971 mxTick
->Convert( aAxisProp
);
2973 // axis caption text --------------------------------------------------
2975 // radar charts disable their category labels via chart type, not via axis
2976 bool bHasLabels
= HasLabels() &&
2977 ((GetAxisType() != EXC_CHAXIS_X
) || rTypeGroup
.HasCategoryLabels());
2978 aAxisProp
.SetBoolProperty( EXC_CHPROP_DISPLAYLABELS
, bHasLabels
);
2981 // font settings from CHFONT record or from default text
2983 ConvertFontBase( GetChRoot(), aAxisProp
);
2984 else if( const XclImpChText
* pDefText
= GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISLABEL
).get() )
2985 pDefText
->ConvertFont( aAxisProp
);
2986 // label text rotation
2987 ConvertRotationBase( GetChRoot(), aAxisProp
, true );
2989 sal_uInt32 nScNumFmt
= GetNumFmtBuffer().GetScFormat( mnNumFmtIdx
);
2990 if( nScNumFmt
!= NUMBERFORMAT_ENTRY_NOT_FOUND
)
2991 aAxisProp
.SetProperty( EXC_CHPROP_NUMBERFORMAT
, static_cast< sal_Int32
>( nScNumFmt
) );
2994 // axis scaling and increment -----------------------------------------
2996 const XclChExtTypeInfo
& rTypeInfo
= rTypeGroup
.GetTypeInfo();
2997 ScaleData aScaleData
= xAxis
->getScaleData();
2999 switch( GetAxisType() )
3002 if( rTypeInfo
.mbCategoryAxis
)
3004 aScaleData
.AxisType
= cssc2::AxisType::CATEGORY
;
3005 aScaleData
.Categories
= rTypeGroup
.CreateCategSequence();
3008 aScaleData
.AxisType
= cssc2::AxisType::REALNUMBER
;
3011 aScaleData
.AxisType
= rTypeGroup
.IsPercent() ?
3012 cssc2::AxisType::PERCENT
: cssc2::AxisType::REALNUMBER
;
3015 aScaleData
.AxisType
= cssc2::AxisType::SERIES
;
3018 // axis scaling settings, dependent on axis type
3019 switch( aScaleData
.AxisType
)
3021 case cssc2::AxisType::CATEGORY
:
3022 case cssc2::AxisType::SERIES
:
3023 // #i71684# radar charts have reversed rotation direction
3024 mxLabelRange
->Convert( aAxisProp
, aScaleData
, rTypeInfo
.meTypeCateg
== EXC_CHTYPECATEG_RADAR
);
3026 case cssc2::AxisType::REALNUMBER
:
3027 case cssc2::AxisType::PERCENT
:
3029 bool bPercent
= (aScaleData
.AxisType
== cssc2::AxisType::PERCENT
);
3030 // #i85167# pie/donut charts have reversed rotation direction (at Y axis!)
3031 mxValueRange
->Convert( aScaleData
, rTypeInfo
.meTypeCateg
== EXC_CHTYPECATEG_PIE
, bPercent
);
3035 DBG_ERRORFILE( "XclImpChAxis::CreateAxis - unknown axis type" );
3038 /* Do not set a value to the Origin member anymore (will be done via
3039 new axis properties 'CrossoverPosition' and 'CrossoverValue'). */
3040 aScaleData
.Origin
.clear();
3043 xAxis
->setScaleData( aScaleData
);
3045 // grid ---------------------------------------------------------------
3048 ScfPropertySet
aGridProp( xAxis
->getGridProperties() );
3049 aGridProp
.SetBoolProperty( EXC_CHPROP_SHOW
, HasMajorGrid() );
3050 if( mxMajorGrid
.is() )
3051 mxMajorGrid
->Convert( GetChRoot(), aGridProp
, EXC_CHOBJTYPE_GRIDLINE
);
3053 Sequence
< Reference
< XPropertySet
> > aSubGridPropSeq
= xAxis
->getSubGridProperties();
3054 if( aSubGridPropSeq
.hasElements() )
3056 ScfPropertySet
aSubGridProp( aSubGridPropSeq
[ 0 ] );
3057 aSubGridProp
.SetBoolProperty( EXC_CHPROP_SHOW
, HasMinorGrid() );
3058 if( mxMinorGrid
.is() )
3059 mxMinorGrid
->Convert( GetChRoot(), aSubGridProp
, EXC_CHOBJTYPE_GRIDLINE
);
3062 // position of crossing axis ------------------------------------------
3065 pCrossingAxis
->ConvertAxisPosition( aAxisProp
, rTypeGroup
);
3070 void XclImpChAxis::ConvertWall( ScfPropertySet
& rPropSet
) const
3072 if( mxWallFrame
.is() )
3073 mxWallFrame
->Convert( rPropSet
);
3076 void XclImpChAxis::ConvertAxisPosition( ScfPropertySet
& rPropSet
, const XclImpChTypeGroup
& rTypeGroup
) const
3078 if( ((GetAxisType() == EXC_CHAXIS_X
) && rTypeGroup
.GetTypeInfo().mbCategoryAxis
) || (GetAxisType() == EXC_CHAXIS_Z
) )
3079 mxLabelRange
->ConvertAxisPosition( rPropSet
, rTypeGroup
.Is3dChart() );
3081 mxValueRange
->ConvertAxisPosition( rPropSet
);
3084 void XclImpChAxis::ReadChAxisLine( XclImpStream
& rStrm
)
3086 XclImpChLineFormatRef
* pxLineFmt
= 0;
3087 bool bWallFrame
= false;
3088 switch( rStrm
.ReaduInt16() )
3090 case EXC_CHAXISLINE_AXISLINE
: pxLineFmt
= &mxAxisLine
; break;
3091 case EXC_CHAXISLINE_MAJORGRID
: pxLineFmt
= &mxMajorGrid
; break;
3092 case EXC_CHAXISLINE_MINORGRID
: pxLineFmt
= &mxMinorGrid
; break;
3093 case EXC_CHAXISLINE_WALLS
: bWallFrame
= true; break;
3098 bool bLoop
= pxLineFmt
|| bWallFrame
;
3101 sal_uInt16 nRecId
= rStrm
.GetNextRecId();
3102 bLoop
= ((nRecId
== EXC_ID_CHLINEFORMAT
) ||
3103 (nRecId
== EXC_ID_CHAREAFORMAT
) ||
3104 (nRecId
== EXC_ID_CHESCHERFORMAT
))
3105 && rStrm
.StartNextRecord();
3108 if( pxLineFmt
&& (nRecId
== EXC_ID_CHLINEFORMAT
) )
3110 pxLineFmt
->reset( new XclImpChLineFormat
);
3111 (*pxLineFmt
)->ReadChLineFormat( rStrm
);
3113 else if( bWallFrame
&& mxWallFrame
.is() )
3115 mxWallFrame
->ReadSubRecord( rStrm
);
3121 void XclImpChAxis::CreateWallFrame()
3123 switch( GetAxisType() )
3126 mxWallFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_WALL3D
) );
3129 mxWallFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_FLOOR3D
) );
3132 mxWallFrame
.reset();
3136 // ----------------------------------------------------------------------------
3138 XclImpChAxesSet::XclImpChAxesSet( const XclImpChRoot
& rRoot
, sal_uInt16 nAxesSetId
) :
3139 XclImpChRoot( rRoot
)
3141 maData
.mnAxesSetId
= nAxesSetId
;
3144 void XclImpChAxesSet::ReadHeaderRecord( XclImpStream
& rStrm
)
3146 rStrm
>> maData
.mnAxesSetId
>> maData
.maRect
;
3149 void XclImpChAxesSet::ReadSubRecord( XclImpStream
& rStrm
)
3151 switch( rStrm
.GetRecId() )
3153 case EXC_ID_CHFRAMEPOS
:
3154 mxPos
.reset( new XclImpChFramePos
);
3155 mxPos
->ReadChFramePos( rStrm
);
3158 ReadChAxis( rStrm
);
3161 ReadChText( rStrm
);
3163 case EXC_ID_CHPLOTFRAME
:
3164 ReadChPlotFrame( rStrm
);
3166 case EXC_ID_CHTYPEGROUP
:
3167 ReadChTypeGroup( rStrm
);
3172 void XclImpChAxesSet::Finalize()
3174 if( IsValidAxesSet() )
3176 // finalize chart type groups, erase empty groups without series
3177 XclImpChTypeGroupMap aValidGroups
;
3178 for( XclImpChTypeGroupMap::const_iterator aIt
= maTypeGroups
.begin(), aEnd
= maTypeGroups
.end(); aIt
!= aEnd
; ++aIt
)
3180 XclImpChTypeGroupRef xTypeGroup
= aIt
->second
;
3181 xTypeGroup
->Finalize();
3182 if( xTypeGroup
->IsValidGroup() )
3183 aValidGroups
[ aIt
->first
] = xTypeGroup
;
3185 maTypeGroups
.swap( aValidGroups
);
3188 // invalid chart type groups are deleted now, check again with IsValidAxesSet()
3189 if( IsValidAxesSet() )
3191 // always create missing axis objects
3193 mxXAxis
.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_X
) );
3195 mxYAxis
.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Y
) );
3196 if( !mxZAxis
&& GetFirstTypeGroup()->Is3dDeepChart() )
3197 mxZAxis
.reset( new XclImpChAxis( GetChRoot(), EXC_CHAXIS_Z
) );
3200 if( mxXAxis
.is() ) mxXAxis
->Finalize();
3201 if( mxYAxis
.is() ) mxYAxis
->Finalize();
3202 if( mxZAxis
.is() ) mxZAxis
->Finalize();
3204 // finalize axis titles
3205 XclImpChTextRef xDefText
= GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISTITLE
);
3206 lclFinalizeTitle( mxXAxisTitle
, xDefText
);
3207 lclFinalizeTitle( mxYAxisTitle
, xDefText
);
3208 lclFinalizeTitle( mxZAxisTitle
, xDefText
);
3210 // #i47745# missing plot frame -> invisible border and area
3212 mxPlotFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME
) );
3216 XclImpChTypeGroupRef
XclImpChAxesSet::GetFirstTypeGroup() const
3218 XclImpChTypeGroupRef xTypeGroup
;
3219 if( !maTypeGroups
.empty() )
3220 xTypeGroup
= maTypeGroups
.begin()->second
;
3224 XclImpChLegendRef
XclImpChAxesSet::GetLegend() const
3226 XclImpChLegendRef xLegend
;
3227 for( XclImpChTypeGroupMap::const_iterator aIt
= maTypeGroups
.begin(), aEnd
= maTypeGroups
.end(); !xLegend
&& (aIt
!= aEnd
); ++aIt
)
3228 xLegend
= aIt
->second
->GetLegend();
3232 const String
& XclImpChAxesSet::GetSingleSeriesTitle() const
3234 return (maTypeGroups
.size() == 1) ? maTypeGroups
.begin()->second
->GetSingleSeriesTitle() : String::EmptyString();
3237 void XclImpChAxesSet::Convert( Reference
< XDiagram
> xDiagram
) const
3239 if( IsValidAxesSet() && xDiagram
.is() )
3241 // diagram background formatting
3242 if( GetAxesSetId() == EXC_CHAXESSET_PRIMARY
)
3243 ConvertBackground( xDiagram
);
3245 // create the coordinate system, this inserts all chart types and series
3246 Reference
< XCoordinateSystem
> xCoordSystem
= CreateCoordSystem( xDiagram
);
3247 if( xCoordSystem
.is() )
3249 // insert coordinate system, if not already done
3252 Reference
< XCoordinateSystemContainer
> xCoordSystemCont( xDiagram
, UNO_QUERY_THROW
);
3253 Sequence
< Reference
< XCoordinateSystem
> > aCoordSystems
= xCoordSystemCont
->getCoordinateSystems();
3254 if( aCoordSystems
.getLength() == 0 )
3255 xCoordSystemCont
->addCoordinateSystem( xCoordSystem
);
3259 DBG_ERRORFILE( "XclImpChAxesSet::Convert - cannot insert coordinate system" );
3262 // create the axes with grids and axis titles and insert them into the diagram
3263 ConvertAxis( mxXAxis
, mxXAxisTitle
, xCoordSystem
, mxYAxis
.get() );
3264 ConvertAxis( mxYAxis
, mxYAxisTitle
, xCoordSystem
, mxXAxis
.get() );
3265 ConvertAxis( mxZAxis
, mxZAxisTitle
, xCoordSystem
, 0 );
3270 void XclImpChAxesSet::ReadChAxis( XclImpStream
& rStrm
)
3272 XclImpChAxisRef
xAxis( new XclImpChAxis( GetChRoot() ) );
3273 xAxis
->ReadRecordGroup( rStrm
);
3275 switch( xAxis
->GetAxisType() )
3277 case EXC_CHAXIS_X
: mxXAxis
= xAxis
; break;
3278 case EXC_CHAXIS_Y
: mxYAxis
= xAxis
; break;
3279 case EXC_CHAXIS_Z
: mxZAxis
= xAxis
; break;
3283 void XclImpChAxesSet::ReadChText( XclImpStream
& rStrm
)
3285 XclImpChTextRef
xText( new XclImpChText( GetChRoot() ) );
3286 xText
->ReadRecordGroup( rStrm
);
3288 switch( xText
->GetLinkTarget() )
3290 case EXC_CHOBJLINK_XAXIS
: mxXAxisTitle
= xText
; break;
3291 case EXC_CHOBJLINK_YAXIS
: mxYAxisTitle
= xText
; break;
3292 case EXC_CHOBJLINK_ZAXIS
: mxZAxisTitle
= xText
; break;
3296 void XclImpChAxesSet::ReadChPlotFrame( XclImpStream
& rStrm
)
3298 if( (rStrm
.GetNextRecId() == EXC_ID_CHFRAME
) && rStrm
.StartNextRecord() )
3300 mxPlotFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_PLOTFRAME
) );
3301 mxPlotFrame
->ReadRecordGroup( rStrm
);
3305 void XclImpChAxesSet::ReadChTypeGroup( XclImpStream
& rStrm
)
3307 XclImpChTypeGroupRef
xTypeGroup( new XclImpChTypeGroup( GetChRoot() ) );
3308 xTypeGroup
->ReadRecordGroup( rStrm
);
3309 maTypeGroups
[ xTypeGroup
->GetGroupIdx() ] = xTypeGroup
;
3312 Reference
< XCoordinateSystem
> XclImpChAxesSet::CreateCoordSystem( Reference
< XDiagram
> xDiagram
) const
3314 Reference
< XCoordinateSystem
> xCoordSystem
;
3316 /* Try to get existing ccordinate system. For now, all series from primary
3317 and secondary axes sets are inserted into one coordinate system. Later,
3318 this should be changed to use one coordinate system for each axes set. */
3319 Reference
< XCoordinateSystemContainer
> xCoordSystemCont( xDiagram
, UNO_QUERY
);
3320 if( xCoordSystemCont
.is() )
3322 Sequence
< Reference
< XCoordinateSystem
> > aCoordSystems
= xCoordSystemCont
->getCoordinateSystems();
3323 DBG_ASSERT( aCoordSystems
.getLength() <= 1, "XclImpChAxesSet::CreateCoordSystem - too many existing coordinate systems" );
3324 if( aCoordSystems
.getLength() > 0 )
3325 xCoordSystem
= aCoordSystems
[ 0 ];
3328 // create the coordinate system according to the first chart type
3329 if( !xCoordSystem
.is() )
3331 XclImpChTypeGroupRef xTypeGroup
= GetFirstTypeGroup();
3332 if( xTypeGroup
.is() )
3334 xCoordSystem
= xTypeGroup
->CreateCoordSystem();
3335 // convert 3d chart settings
3336 ScfPropertySet
aDiaProp( xDiagram
);
3337 xTypeGroup
->ConvertChart3d( aDiaProp
);
3341 /* Create XChartType objects for all chart type groups. Each group will
3342 add its series to the data provider attached to the chart document. */
3343 Reference
< XChartTypeContainer
> xChartTypeCont( xCoordSystem
, UNO_QUERY
);
3344 if( xChartTypeCont
.is() )
3346 sal_Int32 nApiAxesSetIdx
= GetApiAxesSetIndex();
3347 for( XclImpChTypeGroupMap::const_iterator aIt
= maTypeGroups
.begin(), aEnd
= maTypeGroups
.end(); aIt
!= aEnd
; ++aIt
)
3351 Reference
< XChartType
> xChartType
= aIt
->second
->CreateChartType( xDiagram
, nApiAxesSetIdx
);
3352 if( xChartType
.is() )
3353 xChartTypeCont
->addChartType( xChartType
);
3357 DBG_ERRORFILE( "XclImpChAxesSet::CreateCoordSystem - cannot add chart type" );
3362 return xCoordSystem
;
3365 void XclImpChAxesSet::ConvertAxis(
3366 XclImpChAxisRef xChAxis
, XclImpChTextRef xChAxisTitle
,
3367 Reference
< XCoordinateSystem
> xCoordSystem
, const XclImpChAxis
* pCrossingAxis
) const
3371 // create and attach the axis object
3372 Reference
< XAxis
> xAxis
= CreateAxis( *xChAxis
, pCrossingAxis
);
3375 // create and attach the axis title
3376 if( xChAxisTitle
.is() )
3378 Reference
< XTitled
> xTitled( xAxis
, UNO_QUERY
);
3380 xTitled
->setTitleObject( xChAxisTitle
->CreateTitle() );
3383 // insert axis into coordinate system
3386 sal_Int32 nApiAxisDim
= xChAxis
->GetApiAxisDimension();
3387 sal_Int32 nApiAxesSetIdx
= GetApiAxesSetIndex();
3388 xCoordSystem
->setAxisByDimension( nApiAxisDim
, xAxis
, nApiAxesSetIdx
);
3392 DBG_ERRORFILE( "XclImpChAxesSet::ConvertAxis - cannot set axis" );
3398 Reference
< XAxis
> XclImpChAxesSet::CreateAxis( const XclImpChAxis
& rChAxis
, const XclImpChAxis
* pCrossingAxis
) const
3400 Reference
< XAxis
> xAxis
;
3401 if( const XclImpChTypeGroup
* pTypeGroup
= GetFirstTypeGroup().get() )
3402 xAxis
= rChAxis
.CreateAxis( *pTypeGroup
, pCrossingAxis
);
3406 void XclImpChAxesSet::ConvertBackground( Reference
< XDiagram
> xDiagram
) const
3408 XclImpChTypeGroupRef xTypeGroup
= GetFirstTypeGroup();
3409 if( xTypeGroup
.is() && xTypeGroup
->Is3dWallChart() )
3411 // wall/floor formatting (3D charts)
3414 ScfPropertySet
aWallProp( xDiagram
->getWall() );
3415 mxXAxis
->ConvertWall( aWallProp
);
3419 ScfPropertySet
aFloorProp( xDiagram
->getFloor() );
3420 mxYAxis
->ConvertWall( aFloorProp
);
3423 else if( mxPlotFrame
.is() )
3425 // diagram background formatting
3426 ScfPropertySet
aWallProp( xDiagram
->getWall() );
3427 mxPlotFrame
->Convert( aWallProp
);
3431 // The chart object ===========================================================
3433 XclImpChChart::XclImpChChart( const XclImpRoot
& rRoot
) :
3434 XclImpChRoot( rRoot
, this )
3436 mxPrimAxesSet
.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY
) );
3437 mxSecnAxesSet
.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY
) );
3440 XclImpChChart::~XclImpChChart()
3444 void XclImpChChart::ReadHeaderRecord( XclImpStream
& rStrm
)
3446 // coordinates are stored as 16.16 fixed point
3450 void XclImpChChart::ReadSubRecord( XclImpStream
& rStrm
)
3452 switch( rStrm
.GetRecId() )
3454 case EXC_ID_CHFRAME
:
3455 mxFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND
) );
3456 mxFrame
->ReadRecordGroup( rStrm
);
3458 case EXC_ID_CHSERIES
:
3459 ReadChSeries( rStrm
);
3461 case EXC_ID_CHPROPERTIES
:
3462 ReadChProperties( rStrm
);
3464 case EXC_ID_CHDEFAULTTEXT
:
3465 ReadChDefaultText( rStrm
);
3467 case EXC_ID_CHAXESSET
:
3468 ReadChAxesSet( rStrm
);
3471 ReadChText( rStrm
);
3474 Finalize(); // finalize the entire chart object
3479 void XclImpChChart::ReadChDefaultText( XclImpStream
& rStrm
)
3481 sal_uInt16 nTextId
= rStrm
.ReaduInt16();
3482 if( (rStrm
.GetNextRecId() == EXC_ID_CHTEXT
) && rStrm
.StartNextRecord() )
3484 XclImpChTextRef
xText( new XclImpChText( GetChRoot() ) );
3485 xText
->ReadRecordGroup( rStrm
);
3486 maDefTexts
[ nTextId
] = xText
;
3490 void XclImpChChart::ReadChDataFormat( XclImpStream
& rStrm
)
3492 XclImpChDataFormatRef
xDataFmt( new XclImpChDataFormat( GetChRoot() ) );
3493 xDataFmt
->ReadRecordGroup( rStrm
);
3494 if( xDataFmt
->GetPointPos().mnSeriesIdx
<= EXC_CHSERIES_MAXSERIES
)
3496 XclImpChDataFormatRef
& rxMapFmt
= maDataFmts
[ xDataFmt
->GetPointPos() ];
3497 /* Do not overwrite existing data format group, Excel always uses the
3498 first data format group occuring in any CHSERIES group. */
3500 rxMapFmt
= xDataFmt
;
3504 void XclImpChChart::UpdateObjFrame( const XclObjLineData
& rLineData
, const XclObjFillData
& rFillData
)
3507 mxFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND
) );
3508 mxFrame
->UpdateObjFrame( rLineData
, rFillData
);
3511 XclImpChTypeGroupRef
XclImpChChart::GetTypeGroup( sal_uInt16 nGroupIdx
) const
3513 XclImpChTypeGroupRef xTypeGroup
= mxPrimAxesSet
->GetTypeGroup( nGroupIdx
);
3514 if( !xTypeGroup
) xTypeGroup
= mxSecnAxesSet
->GetTypeGroup( nGroupIdx
);
3515 if( !xTypeGroup
) xTypeGroup
= mxPrimAxesSet
->GetFirstTypeGroup();
3519 XclImpChTextRef
XclImpChChart::GetDefaultText( XclChTextType eTextType
) const
3521 sal_uInt16 nDefTextId
= EXC_CHDEFTEXT_GLOBAL
;
3522 bool bBiff8
= GetBiff() == EXC_BIFF8
;
3525 case EXC_CHTEXTTYPE_TITLE
: nDefTextId
= EXC_CHDEFTEXT_GLOBAL
; break;
3526 case EXC_CHTEXTTYPE_LEGEND
: nDefTextId
= EXC_CHDEFTEXT_GLOBAL
; break;
3527 case EXC_CHTEXTTYPE_AXISTITLE
: nDefTextId
= bBiff8
? EXC_CHDEFTEXT_AXESSET
: EXC_CHDEFTEXT_GLOBAL
; break;
3528 case EXC_CHTEXTTYPE_AXISLABEL
: nDefTextId
= bBiff8
? EXC_CHDEFTEXT_AXESSET
: EXC_CHDEFTEXT_GLOBAL
; break;
3529 case EXC_CHTEXTTYPE_DATALABEL
: nDefTextId
= bBiff8
? EXC_CHDEFTEXT_AXESSET
: EXC_CHDEFTEXT_GLOBAL
; break;
3531 return maDefTexts
.get( nDefTextId
);
3534 void XclImpChChart::Convert( Reference
< XChartDocument
> xChartDoc
, ScfProgressBar
& rProgress
, const OUString
& rObjName
) const
3536 // initialize conversion (locks the model to suppress any internal updates)
3537 InitConversion( xChartDoc
);
3539 // chart frame and title
3542 ScfPropertySet
aFrameProp( xChartDoc
->getPageBackground() );
3543 mxFrame
->Convert( aFrameProp
);
3547 Reference
< XTitled
> xTitled( xChartDoc
, UNO_QUERY
);
3548 Reference
< XTitle
> xTitle
= mxTitle
->CreateTitle();
3549 if( xTitled
.is() && xTitle
.is() )
3550 xTitled
->setTitleObject( xTitle
);
3553 /* Create the diagram object and attach it to the chart document. Currently,
3554 one diagram is used to carry all coordinate systems and data series. */
3555 Reference
< XDiagram
> xDiagram
= CreateDiagram();
3556 xChartDoc
->setFirstDiagram( xDiagram
);
3558 // coordinate systems and chart types, convert axis settings
3559 mxPrimAxesSet
->Convert( xDiagram
);
3560 mxSecnAxesSet
->Convert( xDiagram
);
3563 if( xDiagram
.is() && mxLegend
.is() )
3564 xDiagram
->setLegend( mxLegend
->CreateLegend() );
3566 // set the IncludeHiddenCells property via the old API as only this ensures that the data provider and al created sequences get this flag correctly
3567 Reference
< com::sun::star::chart::XChartDocument
> xStandardApiChartDoc( xChartDoc
, UNO_QUERY
);
3568 if( xStandardApiChartDoc
.is() )
3570 ScfPropertySet
aDiagramProp( xStandardApiChartDoc
->getDiagram() );
3571 bool bShowVisCells
= (maProps
.mnFlags
& EXC_CHPROPS_SHOWVISIBLEONLY
);
3572 aDiagramProp
.SetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS
, !bShowVisCells
);
3576 FinishConversion( rProgress
);
3578 ScDocument
* pDoc
= &GetRoot().GetDoc();
3579 ScChartListenerCollection
* pChartCollection
= pDoc
->GetChartListenerCollection();
3580 if (pChartCollection
)
3582 // Now, start listening to this chart.
3583 ::std::auto_ptr
< vector
<ScSharedTokenRef
> > pRefTokens(new vector
<ScSharedTokenRef
>);
3584 for (XclImpChSeriesVec::const_iterator itr
= maSeries
.begin(), itrEnd
= maSeries
.end(); itr
!= itrEnd
; ++itr
)
3586 const XclImpChSeriesRef
& rSeries
= *itr
;
3587 rSeries
->FillAllSourceLinks(*pRefTokens
);
3589 if (!pRefTokens
->empty())
3591 ::std::auto_ptr
<ScChartListener
> pListener(
3592 new ScChartListener(rObjName
, pDoc
, pRefTokens
.release()));
3593 pListener
->SetDirty(true);
3594 pListener
->StartListeningTo();
3595 pChartCollection
->Insert(pListener
.release());
3601 void XclImpChChart::ReadChSeries( XclImpStream
& rStrm
)
3603 sal_uInt16 nNewSeriesIdx
= static_cast< sal_uInt16
>( maSeries
.size() );
3604 XclImpChSeriesRef
xSeries( new XclImpChSeries( GetChRoot(), nNewSeriesIdx
) );
3605 xSeries
->ReadRecordGroup( rStrm
);
3606 maSeries
.push_back( xSeries
);
3609 void XclImpChChart::ReadChProperties( XclImpStream
& rStrm
)
3611 rStrm
>> maProps
.mnFlags
>> maProps
.mnEmptyMode
;
3614 void XclImpChChart::ReadChAxesSet( XclImpStream
& rStrm
)
3616 XclImpChAxesSetRef
xAxesSet( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_NONE
) );
3617 xAxesSet
->ReadRecordGroup( rStrm
);
3618 switch( xAxesSet
->GetAxesSetId() )
3620 case EXC_CHAXESSET_PRIMARY
: mxPrimAxesSet
= xAxesSet
; break;
3621 case EXC_CHAXESSET_SECONDARY
: mxSecnAxesSet
= xAxesSet
; break;
3625 void XclImpChChart::ReadChText( XclImpStream
& rStrm
)
3627 XclImpChTextRef
xText( new XclImpChText( GetChRoot() ) );
3628 xText
->ReadRecordGroup( rStrm
);
3629 switch( xText
->GetLinkTarget() )
3631 case EXC_CHOBJLINK_TITLE
:
3634 case EXC_CHOBJLINK_DATA
:
3636 sal_uInt16 nSeriesIdx
= xText
->GetPointPos().mnSeriesIdx
;
3637 if( nSeriesIdx
< maSeries
.size() )
3638 maSeries
[ nSeriesIdx
]->SetDataLabel( xText
);
3644 void XclImpChChart::Finalize()
3646 // finalize series (must be done first)
3648 // #i49218# legend may be attached to primary or secondary axes set
3649 mxLegend
= mxPrimAxesSet
->GetLegend();
3651 mxLegend
= mxSecnAxesSet
->GetLegend();
3653 mxLegend
->Finalize();
3654 // axes sets, updates chart type group default formats -> must be called before FinalizeDataFormats()
3655 mxPrimAxesSet
->Finalize();
3656 mxSecnAxesSet
->Finalize();
3657 // formatting of all series
3658 FinalizeDataFormats();
3659 // #i47745# missing frame -> invisible border and area
3661 mxFrame
.reset( new XclImpChFrame( GetChRoot(), EXC_CHOBJTYPE_BACKGROUND
) );
3666 void XclImpChChart::FinalizeSeries()
3668 for( XclImpChSeriesVec::iterator aSIt
= maSeries
.begin(), aSEnd
= maSeries
.end(); aSIt
!= aSEnd
; ++aSIt
)
3670 XclImpChSeriesRef xSeries
= *aSIt
;
3671 if( xSeries
->HasParentSeries() )
3673 /* Process child series (trend lines and error bars). Data of
3674 child series will be set at the connected parent series. */
3675 if( xSeries
->GetParentIdx() < maSeries
.size() )
3676 maSeries
[ xSeries
->GetParentIdx() ]->AddChildSeries( *xSeries
);
3680 // insert the series into the related chart type group
3681 if( XclImpChTypeGroup
* pTypeGroup
= GetTypeGroup( xSeries
->GetGroupIdx() ).get() )
3682 pTypeGroup
->AddSeries( xSeries
);
3687 void XclImpChChart::FinalizeDataFormats()
3689 /* #i51639# (part 1): CHDATAFORMAT groups are part of CHSERIES groups.
3690 Each CHDATAFORMAT group specifies the series and data point it is
3691 assigned to. This makes it possible to have a data format that is
3692 related to another series, e.g. a CHDATAFORMAT group for series 2 is
3693 part of a CHSERIES group that describes series 1. Therefore the chart
3694 itself has collected all CHDATAFORMAT groups to be able to store data
3695 format groups for series that have not been imported at that time. This
3696 loop finally assigns these groups to the related series. */
3697 for( XclImpChDataFormatMap::const_iterator aMIt
= maDataFmts
.begin(), aMEnd
= maDataFmts
.end(); aMIt
!= aMEnd
; ++aMIt
)
3699 sal_uInt16 nSeriesIdx
= aMIt
->first
.mnSeriesIdx
;
3700 if( nSeriesIdx
< maSeries
.size() )
3701 maSeries
[ nSeriesIdx
]->SetDataFormat( aMIt
->second
);
3704 /* #i51639# (part 2): Finalize data formats of all series. This adds for
3705 example missing CHDATAFORMAT groups for entire series that are needed
3706 for automatic colors of lines and areas. */
3707 for( XclImpChSeriesVec::iterator aVIt
= maSeries
.begin(), aVEnd
= maSeries
.end(); aVIt
!= aVEnd
; ++aVIt
)
3708 (*aVIt
)->FinalizeDataFormats();
3711 void XclImpChChart::FinalizeTitle()
3713 if( (!mxTitle
|| (!mxTitle
->IsDeleted() && !mxTitle
->HasString())) && !mxSecnAxesSet
->IsValidAxesSet() )
3715 /* Chart title is auto-generated from series title, if there is only
3716 one series with title in the chart. */
3717 const String
& rSerTitle
= mxPrimAxesSet
->GetSingleSeriesTitle();
3718 if( rSerTitle
.Len() > 0 )
3721 mxTitle
.reset( new XclImpChText( GetChRoot() ) );
3722 mxTitle
->SetString( rSerTitle
);
3726 // will reset mxTitle, if it does not contain a string
3727 lclFinalizeTitle( mxTitle
, GetDefaultText( EXC_CHTEXTTYPE_TITLE
) );
3730 Reference
< XDiagram
> XclImpChChart::CreateDiagram() const
3732 // create a diagram object
3733 Reference
< XDiagram
> xDiagram( ScfApiHelper::CreateInstance( SERVICE_CHART2_DIAGRAM
), UNO_QUERY
);
3735 // convert global chart settings
3736 ScfPropertySet
aDiaProp( xDiagram
);
3738 // treatment of missing values
3739 using namespace ::com::sun::star::chart::MissingValueTreatment
;
3740 sal_Int32 nMissingValues
= LEAVE_GAP
;
3741 switch( maProps
.mnEmptyMode
)
3743 case EXC_CHPROPS_EMPTY_SKIP
: nMissingValues
= LEAVE_GAP
; break;
3744 case EXC_CHPROPS_EMPTY_ZERO
: nMissingValues
= USE_ZERO
; break;
3745 case EXC_CHPROPS_EMPTY_INTERPOLATE
: nMissingValues
= CONTINUE
; break;
3747 aDiaProp
.SetProperty( EXC_CHPROP_MISSINGVALUETREATMENT
, nMissingValues
);
3752 // ----------------------------------------------------------------------------
3754 XclImpChart::XclImpChart( const XclImpRoot
& rRoot
, bool bOwnTab
) :
3755 XclImpRoot( rRoot
),
3756 mbOwnTab( bOwnTab
),
3757 mbIsPivotChart( false )
3761 void XclImpChart::ReadChartSubStream( XclImpStream
& rStrm
)
3763 XclImpPageSettings
& rPageSett
= GetPageSettings();
3764 XclImpTabViewSettings
& rTabViewSett
= GetTabViewSettings();
3767 while( bLoop
&& rStrm
.StartNextRecord() )
3769 // page settings - only for charts in entire sheet
3770 if( mbOwnTab
) switch( rStrm
.GetRecId() )
3772 case EXC_ID_HORPAGEBREAKS
:
3773 case EXC_ID_VERPAGEBREAKS
: rPageSett
.ReadPageBreaks( rStrm
); break;
3775 case EXC_ID_FOOTER
: rPageSett
.ReadHeaderFooter( rStrm
); break;
3776 case EXC_ID_LEFTMARGIN
:
3777 case EXC_ID_RIGHTMARGIN
:
3778 case EXC_ID_TOPMARGIN
:
3779 case EXC_ID_BOTTOMMARGIN
: rPageSett
.ReadMargin( rStrm
); break;
3780 case EXC_ID_PRINTHEADERS
: rPageSett
.ReadPrintHeaders( rStrm
); break;
3781 case EXC_ID_PRINTGRIDLINES
: rPageSett
.ReadPrintGridLines( rStrm
); break;
3782 case EXC_ID_HCENTER
:
3783 case EXC_ID_VCENTER
: rPageSett
.ReadCenter( rStrm
); break;
3784 case EXC_ID_SETUP
: rPageSett
.ReadSetup( rStrm
); break;
3785 case EXC_ID8_IMGDATA
: rPageSett
.ReadImgData( rStrm
); break;
3787 case EXC_ID_WINDOW2
: rTabViewSett
.ReadWindow2( rStrm
, true );break;
3788 case EXC_ID_SCL
: rTabViewSett
.ReadScl( rStrm
); break;
3789 case EXC_ID_SHEETEXT
: //0x0862
3791 XclImpPalette
& rPal
= GetPalette();
3792 rTabViewSett
.ReadTabBgColor( rStrm
, rPal
);
3797 switch( rStrm
.GetRecId() )
3799 case EXC_ID_EOF
: bLoop
= false; break;
3801 // #i31882# ignore embedded chart objects
3805 case EXC_ID5_BOF
: XclTools::SkipSubStream( rStrm
); break;
3807 case EXC_ID_CHCHART
: ReadChChart( rStrm
); break;
3808 case EXC_ID_OBJ
: GetTracer().TraceChartEmbeddedObj(); break;
3810 case EXC_ID8_CHPIVOTREF
:
3811 GetTracer().TracePivotChartExists();
3812 mbIsPivotChart
= true;
3818 void XclImpChart::UpdateObjFrame( const XclObjLineData
& rLineData
, const XclObjFillData
& rFillData
)
3821 mxChartData
.reset( new XclImpChChart( GetRoot() ) );
3822 mxChartData
->UpdateObjFrame( rLineData
, rFillData
);
3825 sal_Size
XclImpChart::GetProgressSize() const
3827 return mxChartData
.is() ? mxChartData
->GetProgressSize() : 0;
3830 void XclImpChart::Convert( Reference
< XModel
> xModel
, ScfProgressBar
& rProgress
, const OUString
& rObjName
) const
3832 Reference
< XChartDocument
> xChartDoc( xModel
, UNO_QUERY
);
3833 if( mxChartData
.is() && xChartDoc
.is() )
3834 mxChartData
->Convert( xChartDoc
, rProgress
, rObjName
);
3837 void XclImpChart::ReadChChart( XclImpStream
& rStrm
)
3839 mxChartData
.reset( new XclImpChChart( GetRoot() ) );
3840 mxChartData
->ReadRecordGroup( rStrm
);
3843 // ============================================================================