summaryrefslogtreecommitdiff
path: root/sc/source/filter/inc/xichart.hxx
blob: 25e52f3f0168c77584c49df584a89677a0aa87b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_XICHART_HXX
#define SC_XICHART_HXX

#include <vector>
#include <map>
#include <set>
#include <list>

#include <svl/itemset.hxx>

#include "rangelst.hxx"
#include "token.hxx"
#include "xlchart.hxx"
#include "xlstyle.hxx"
#include "xistring.hxx"
#include "xiroot.hxx"

namespace com { namespace sun { namespace star {
    namespace frame
    {
        class XModel;
    }
    namespace chart2
    {
        struct ScaleData;
        class XChartDocument;
        class XDiagram;
        class XCoordinateSystem;
        class XChartType;
        class XDataSeries;
        class XRegressionCurve;
        class XAxis;
        class XLegend;
        class XTitle;
        class XFormattedString;
        namespace data
        {
            class XDataProvider;
            class XDataSequence;
            class XLabeledDataSequence;
        }
    }
} } }

struct XclObjLineData;
struct XclObjFillData;

// Common =====================================================================

class ScfProgressBar;
class XclImpChRootData;
class XclImpChChart;
class ScTokenArray;

/** Base class for complex chart classes, provides access to other components of the chart. */
class XclImpChRoot : public XclImpRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >        XChartDocRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider >   XDataProviderRef;

public:
    explicit            XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart* pChartData );
    virtual             ~XclImpChRoot();

    /** Returns this root instance - for code readability in derived classes. */
    inline const XclImpChRoot& GetChRoot() const { return *this; }
    /** Returns a reference to the parent chart data object. */
    XclImpChChart&      GetChartData() const;
    /** Returns chart type info for a unique chart type identifier. */
    const XclChTypeInfo& GetChartTypeInfo( XclChTypeId eType ) const;
    /** Returns the first fitting chart type info for an Excel chart type record identifier. */
    const XclChTypeInfo& GetChartTypeInfo( sal_uInt16 nRecId ) const;
    /** Returns an info struct about auto formatting for the passed object type. */
    const XclChFormatInfo& GetFormatInfo( XclChObjectType eObjType ) const;

    /** Returns the default text color for charts. */
    Color               GetFontAutoColor() const;
    /** Returns the automatic line color of linear series. */
    Color               GetSeriesLineAutoColor( sal_uInt16 nFormatIdx ) const;
    /** Returns the automatic fill color of filled series. */
    Color               GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const;

    /** Starts the API chart document conversion. Must be called once before all API conversion. */
    void                InitConversion( XChartDocRef xChartDoc ) const;
    /** Finishes the API chart document conversion. Must be called once after all API conversion. */
    void                FinishConversion( ScfProgressBar& rProgress ) const;

    /** Returns the data provider for the chart document. */
    XDataProviderRef    GetDataProvider() const;

    /** Writes all line properties to the passed property set. */
    void                ConvertLineFormat(
                            ScfPropertySet& rPropSet,
                            const XclChLineFormat& rLineFmt,
                            XclChPropertyMode ePropMode ) const;
    /** Writes solid area properties to the passed property set. */
    void                ConvertAreaFormat(
                            ScfPropertySet& rPropSet,
                            const XclChAreaFormat& rAreaFmt,
                            XclChPropertyMode ePropMode ) const;
    /** Writes gradient or bitmap area properties to the passed property set. */
    void                ConvertEscherFormat(
                            ScfPropertySet& rPropSet,
                            const XclChEscherFormat& rEscherFmt,
                            const XclChPicFormat& rPicFmt,
                            XclChPropertyMode ePropMode ) const;
    /** Writes font properties to the passed property set. */
    void                ConvertFont(
                            ScfPropertySet& rPropSet,
                            sal_uInt16 nFontIdx,
                            const Color* pFontColor = 0 ) const;

    /** Writes the pie rotation property for the passed angle. */
    static void         ConvertPieRotation(
                            ScfPropertySet& rPropSet,
                            sal_uInt16 nAngle );

private:
    typedef ScfRef< XclImpChRootData > XclImpChRootDataRef;
    XclImpChRootDataRef mxChData;           /// Reference to the root data object.
};

// ----------------------------------------------------------------------------

/** Base class for chart record groups. Provides helper functions to read sub records.

    A chart record group consists of a header record, followed by a CHBEGIN
    record, followed by group sub records, and finished with a CHEND record.
 */
class XclImpChGroupBase
{
public:
    virtual             ~XclImpChGroupBase();

    /** Reads the entire record group.
        @descr  First calls ReadHeaderRecord() to read the contents of the
            header record. Then tries to read the sub records. If next record
            is a CHBEGIN record, ReadSubRecord() is called for each following
            record until a CHEND record is found. */
    void                ReadRecordGroup( XclImpStream& rStrm );

    /** Helper to skip a CHBEGIN/CHEND block, includes nested blocks. */
    static void         SkipBlock( XclImpStream& rStrm );

    /** Derived classes implement to read the group header record. */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm ) = 0;
    /** Derived classes implement to read a record from the group. */
    virtual void        ReadSubRecord( XclImpStream& rStrm ) = 0;
};

// Frame formatting ===========================================================

class XclImpChFramePos
{
public:
    /** Reads the CHFRAMEPOS record (frame position and size). */
    void                ReadChFramePos( XclImpStream& rStrm );

private:
    XclChFramePos       maData;             /// Position of the frame.
};

typedef ScfRef< XclImpChFramePos > XclImpChFramePosRef;

// ----------------------------------------------------------------------------

/** The CHLINEFORMAT record containing line formatting data. */
class XclImpChLineFormat
{
public:
    /** Creates a new line format object with automatic formatting. */
    inline explicit     XclImpChLineFormat() {}
    /** Creates a new line format object with the passed formatting. */
    inline explicit     XclImpChLineFormat( const XclChLineFormat& rLineFmt ) : maData( rLineFmt ) {}

    /** Reads the CHLINEFORMAT record (basic line properties). */
    void                ReadChLineFormat( XclImpStream& rStrm );

    /** Returns true, if the line format is set to automatic. */
    inline bool         IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHLINEFORMAT_AUTO ); }
    /** Returns true, if the line style is set to something visible. */
    inline bool         HasLine() const { return IsAuto() || (maData.mnPattern != EXC_CHLINEFORMAT_NONE); }
    /** Returns the line width of this line format (returns 'single', if the line is invisible). */
    inline sal_Int16    GetWeight() const { return (IsAuto() || !HasLine()) ? EXC_CHLINEFORMAT_SINGLE : maData.mnWeight; }
    /** Returns true, if the "show axis" flag is set. */
    inline bool         IsShowAxis() const { return ::get_flag( maData.mnFlags, EXC_CHLINEFORMAT_SHOWAXIS ); }

    /** Converts and writes the contained data to the passed property set. */
    void                Convert( const XclImpChRoot& rRoot,
                            ScfPropertySet& rPropSet, XclChObjectType eObjType,
                            sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;

private:
    XclChLineFormat     maData;             /// Contents of the CHLINEFORMAT record.
};

typedef ScfRef< XclImpChLineFormat > XclImpChLineFormatRef;

// ----------------------------------------------------------------------------

/** The CHAREAFORMAT record containing simple area formatting data (solid or patterns). */
class XclImpChAreaFormat
{
public:
    /** Creates a new area format object with automatic formatting. */
    inline explicit     XclImpChAreaFormat() {}
    /** Creates a new area format object with the passed formatting. */
    inline explicit     XclImpChAreaFormat( const XclChAreaFormat& rAreaFmt ) : maData( rAreaFmt ) {}

    /** Reads the CHAREAFORMAT record (basic fill properties, e.g. transparent or colored). */
    void                ReadChAreaFormat( XclImpStream& rStrm );

    /** Returns true, if the area format is set to automatic. */
    inline bool         IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHAREAFORMAT_AUTO ); }
    /** Returns true, if the area style is set to something visible. */
    inline bool         HasArea() const { return IsAuto() || (maData.mnPattern != EXC_PATT_NONE); }

    /** Converts and writes the contained data to the passed property set. */
    void                Convert( const XclImpChRoot& rRoot,
                            ScfPropertySet& rPropSet, XclChObjectType eObjType,
                            sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;

private:
    XclChAreaFormat     maData;             /// Contents of the CHAREAFORMAT record.
};

typedef ScfRef< XclImpChAreaFormat > XclImpChAreaFormatRef;

// ----------------------------------------------------------------------------

/** The CHESCHERFORMAT record containing complex area formatting data (bitmaps, hatches). */
class XclImpChEscherFormat : public XclImpChGroupBase
{
public:
    explicit            XclImpChEscherFormat( const XclImpRoot& rRoot );

    /** Reads the CHESCHERFORMAT record (complex fill data) (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );
    /** Reads a record from the CHESCHERFORMAT group (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );

    /** Converts and writes the contained data to the passed property set. */
    void                Convert( const XclImpChRoot& rRoot,
                            ScfPropertySet& rPropSet, XclChObjectType eObjType ) const;

private:
    XclChEscherFormat   maData;             /// Fill properties for complex areas (CHESCHERFORMAT record).
    XclChPicFormat      maPicFmt;           /// Image options, e.g. stretched, stacked (CHPICFORMAT record).
};

typedef ScfRef< XclImpChEscherFormat > XclImpChEscherFormatRef;

// ----------------------------------------------------------------------------

/** Base class for record groups containing frame formatting.

    Frame formatting can be part of several record groups, e.g. CHFRAME,
    CHDATAFORMAT, CHDROPBAR. It consists of CHLINEFORMAT, CHAREAFORMAT, and
    CHESCHERFORMAT group.
 */
class XclImpChFrameBase : public XclImpChGroupBase
{
public:
    /** Creates a new frame object without internal formatting objects. */
    inline explicit     XclImpChFrameBase() {}
    /** Creates a new frame object with specific default formatting. */
    explicit            XclImpChFrameBase( const XclChFormatInfo& rFmtInfo );

    /** Reads a frame formatting record (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );

    /** Returns true, if the line format is set to automatic. */
    inline bool         IsAutoLine() const { return !mxLineFmt || mxLineFmt->IsAuto(); }
    /** Returns true, if the line style is set to something visible. */
    inline bool         HasLine() const { return IsAutoLine() || mxLineFmt->HasLine(); }
    /** Returns the line weight used for this frame. */
    inline sal_Int16    GetLineWeight() const { return mxLineFmt.is() ? mxLineFmt->GetWeight() : EXC_CHLINEFORMAT_SINGLE; }

    /** Returns true, if the area format is set to automatic. */
    inline bool         IsAutoArea() const { return !mxEscherFmt && (!mxAreaFmt || mxAreaFmt->IsAuto()); }
    /** Returns true, if the area style is set to something visible. */
    inline bool         HasArea() const { return mxEscherFmt.is() || IsAutoArea() || mxAreaFmt->HasArea(); }

protected:
    /** Converts and writes the contained line formatting to the passed property set. */
    void                ConvertLineBase( const XclImpChRoot& rRoot,
                            ScfPropertySet& rPropSet, XclChObjectType eObjType,
                            sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
    /** Converts and writes the contained area formatting to the passed property set. */
    void                ConvertAreaBase( const XclImpChRoot& rRoot,
                            ScfPropertySet& rPropSet, XclChObjectType eObjType,
                            sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;
    /** Converts and writes the contained data to the passed property set. */
    void                ConvertFrameBase( const XclImpChRoot& rRoot,
                            ScfPropertySet& rPropSet, XclChObjectType eObjType,
                            sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const;

protected:
    XclImpChLineFormatRef mxLineFmt;        /// Line format (CHLINEFORMAT record).
    XclImpChAreaFormatRef mxAreaFmt;        /// Area format (CHAREAFORMAT record).
    XclImpChEscherFormatRef mxEscherFmt;    /// Complex area format (CHESCHERFORMAT record).
};

// ----------------------------------------------------------------------------

/** Represents the CHFRAME record group containing object frame properties.

    The CHFRAME group consists of: CHFRAME, CHBEGIN, CHLINEFORMAT,
    CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
 */
class XclImpChFrame : public XclImpChFrameBase, protected XclImpChRoot
{
public:
    /** Creates a new frame object with specific default formatting. */
    explicit            XclImpChFrame(
                            const XclImpChRoot& rRoot,
                            XclChObjectType eObjType );

    /** Reads the CHFRAME record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );

    /** Sets formatting from BIFF3-BIFF5 OBJ record, if own formatting is invisible. */
    void                UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData );

    /** Converts and writes the contained data to the passed property set. */
    void                Convert( ScfPropertySet& rPropSet ) const;

private:
    XclChFrame          maData;             /// Contents of the CHFRAME record.
    XclChObjectType     meObjType;          /// Type of the represented object.
};

typedef ScfRef< XclImpChFrame > XclImpChFrameRef;

// Source links ===============================================================

class XclImpChSourceLink : protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >   XDataSequenceRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XFormattedString >      XFormattedStringRef;
    typedef ::com::sun::star::uno::Sequence< XFormattedStringRef >                              XFormattedStringSeq;

public:
    explicit            XclImpChSourceLink( const XclImpChRoot& rRoot );
    virtual             ~XclImpChSourceLink();

    /** Reads the CHSOURCELINK record (link to source data). */
    void                ReadChSourceLink( XclImpStream& rStrm );
    /** Sets explicit string data for this text object. */
    void                SetString( const String& rString );
    /** Sets formatting runs read from a CHFORMATRUNS record. */
    void                SetTextFormats( const XclFormatRunVec& rFormats );

    /** Returns the destination object (title, values, category, ...). */
    inline sal_uInt8    GetDestType() const { return maData.mnDestType; }
    /** Returns the link type (to worksheet, directly, default, ...). */
    inline sal_uInt8    GetLinkType() const { return maData.mnLinkType; }

    /** Returns true, if the source link contains explicit string data. */
    inline bool         HasString() const { return mxString.is() && !mxString->IsEmpty(); }
    /** Returns explicit string data or an empty string. */
    inline const String& GetString() const { return mxString.is() ? mxString->GetText() : String::EmptyString(); }
    /** Returns the number of data points of this source link. */
    sal_uInt16          GetCellCount() const;

    /** Converts and writes the contained number format to the passed property set. */
    void                ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const;

    /** Creates a data sequence containing the link into the Calc document. */
    XDataSequenceRef    CreateDataSequence( const ::rtl::OUString& rRole ) const;
    /** Creates a sequence of formatted string objects. */
    XFormattedStringSeq CreateStringSequence( const XclImpChRoot& rRoot,
                            sal_uInt16 nLeadFontIdx, const Color& rLeadFontColor ) const;

    void                FillSourceLink(::std::vector<ScSharedTokenRef>& rTokens) const;

private:
    XclChSourceLink     maData;             /// Contents of the CHSOURCELINK record.
    XclImpStringRef     mxString;           /// Text data (CHSTRING record).
    ScfRef< ScTokenArray> mxTokenArray;     /// Token array representing the data ranges.
};

typedef ScfRef< XclImpChSourceLink > XclImpChSourceLinkRef;

// Text =======================================================================

/** Base class for objects with font settings. Provides font conversion helper functions. */
class XclImpChFontBase
{
public:
    virtual             ~XclImpChFontBase();

    /** Derived classes return the leading font index for the text object. */
    virtual sal_uInt16  GetFontIndex() const = 0;
    /** Derived classes return the leading font color for the text object. */
    virtual Color       GetFontColor() const = 0;
    /** Derived classes return the rotation value for the text object. */
    virtual sal_uInt16  GetRotation() const = 0;

    /** Converts and writes the contained font settings to the passed property set. */
    void                ConvertFontBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const;
    /** Converts and writes the contained rotation settings to the passed property set. */
    void                ConvertRotationBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, bool bSupportsStacked ) const;
};

// ----------------------------------------------------------------------------

/** The CHFONT record containing a font index for text objects. */
class XclImpChFont
{
public:
    explicit            XclImpChFont();
    /** Reads the CHFONT record (font index). */
    void                ReadChFont( XclImpStream& rStrm );

    /** Returns the contained font index. */
    inline sal_uInt16   GetFontIndex() const { return mnFontIdx; }

private:
    sal_uInt16          mnFontIdx;          /// Index into font buffer.
};

typedef ScfRef< XclImpChFont > XclImpChFontRef;

// ----------------------------------------------------------------------------

/** Represents the CHTEXT record group containing text object properties.

    The CHTEXT group consists of: CHTEXT, CHBEGIN, CHFRAMEPOS, CHFONT,
    CHFORMATRUNS, CHSOURCELINK, CHSTRING, CHFRAME group, CHOBJECTLINK, and CHEND.
 */
class XclImpChText : public XclImpChGroupBase, public XclImpChFontBase, protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTitle > XTitleRef;

public:
    explicit            XclImpChText( const XclImpChRoot& rRoot );

    /** Reads the CHTEXT record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );
    /** Reads a record from the CHTEXT group (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );

    /** Returns the leading font index for the text object. */
    virtual sal_uInt16  GetFontIndex() const;
    /** Returns the leading font color for the text object. */
    virtual Color       GetFontColor() const;
    /** Returns the rotation value for the text object. */
    virtual sal_uInt16  GetRotation() const;

    /** Sets explicit string data for this text object. */
    void                SetString( const String& rString );
    /** Updates missing parts of this text object from the passed object. */
    void                UpdateText( const XclImpChText* pParentText );
    /** Updates display type of this data point label text object. */
    void                UpdateDataLabel( bool bCateg, bool bValue, bool bPercent );

    /** Returns the target object this text is linked to. */
    inline sal_uInt16   GetLinkTarget() const { return maObjLink.mnTarget; }
    /** Returns the position of the data point label this text is linked to. */
    inline const XclChDataPointPos& GetPointPos() const { return maObjLink.maPointPos; }
    /** Returns true, if this text group contains string data. */
    inline bool         HasString() const { return mxSrcLink.is() && mxSrcLink->HasString(); }
    /** Returns true, if the text object is marked as deleted. */
    inline bool         IsDeleted() const { return ::get_flag( maData.mnFlags, EXC_CHTEXT_DELETED ); }

    /** Converts and writes the contained font settings to the passed property set. */
    void                ConvertFont( ScfPropertySet& rPropSet ) const;
    /** Converts and writes the contained rotation settings to the passed property set. */
    void                ConvertRotation( ScfPropertySet& rPropSet, bool bSupportsStacked ) const;
    /** Converts and writes the contained frame data to the passed property set. */
    void                ConvertFrame( ScfPropertySet& rPropSet ) const;
    /** Converts and writes the contained number format to the passed property set. */
    void                ConvertNumFmt( ScfPropertySet& rPropSet, bool bPercent ) const;
    /** Converts and writes all contained data to the passed data point label property set. */
    void                ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeInfo& rTypeInfo ) const;
    /** Creates a title text object. */
    XTitleRef           CreateTitle() const;

private:
    using               XclImpChRoot::ConvertFont;

    /** Reads a CHFRLABELPROPS record. */
    void                ReadChFrLabelProps( XclImpStream& rStrm );

private:
    typedef ScfRef< XclChFrLabelProps > XclChFrLabelPropsRef;

    XclChText           maData;             /// Contents of the CHTEXT record.
    XclChObjectLink     maObjLink;          /// Link target for this text object.
    XclFormatRunVec     maFormats;          /// Formatting runs (CHFORMATRUNS record).
    XclImpChSourceLinkRef mxSrcLink;        /// Linked data (CHSOURCELINK with CHSTRING record).
    XclImpChFrameRef    mxFrame;            /// Text object frame properties (CHFRAME group).
    XclImpChFontRef     mxFont;             /// Index into font buffer (CHFONT record).
    XclChFrLabelPropsRef mxLabelProps;      /// Extended data label properties (CHFRLABELPROPS record).
};

typedef ScfRef< XclImpChText > XclImpChTextRef;

// Data series ================================================================

/** The CHMARKERFORMAT record containing data point marker formatting data. */
class XclImpChMarkerFormat
{
public:
    /** Reads the CHMARKERFORMAT record (data point marker properties). */
    void                ReadChMarkerFormat( XclImpStream& rStrm );

    /** Returns true, if the marker format is set to automatic. */
    inline bool         IsAuto() const { return ::get_flag( maData.mnFlags, EXC_CHMARKERFORMAT_AUTO ); }

    /** Converts and writes the contained data to the passed property set. */
    void                Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet,
                            sal_uInt16 nFormatIdx, sal_Int16 nLineWeight ) const;
    /** Sets the marker fill color as main color to the passed property set. */
    void                ConvertColor( const XclImpChRoot& rRoot,
                            ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const;

private:
    XclChMarkerFormat   maData;             /// Contents of the CHMARKERFORMAT record.
};

typedef ScfRef< XclImpChMarkerFormat > XclImpChMarkerFormatRef;

// ----------------------------------------------------------------------------

/** The CHPIEFORMAT record containing data point formatting data for pie segments. */
class XclImpChPieFormat
{
public:
    explicit            XclImpChPieFormat();
    /** Reads the CHPIEFORMAT record (pie segment properties). */
    void                ReadChPieFormat( XclImpStream& rStrm );
    /** Converts and writes the contained data to the passed property set. */
    void                Convert( ScfPropertySet& rPropSet ) const;

private:
    sal_uInt16          mnPieDist;          /// Pie distance to diagram center.
};

typedef ScfRef< XclImpChPieFormat > XclImpChPieFormatRef;

// ----------------------------------------------------------------------------

/** The CHSERIESFORMAT record containing additional settings for a data series. */
class XclImpChSeriesFormat
{
public:
    explicit            XclImpChSeriesFormat();
    /** Reads the CHSERIESFORMAT record (additional settings for a series). */
    void                ReadChSeriesFormat( XclImpStream& rStrm );
    /** Returns true, if the series line is smoothed. */
    inline bool         HasSpline() const { return ::get_flag( mnFlags, EXC_CHSERIESFORMAT_SMOOTHED ); }

private:
    sal_uInt16          mnFlags;            /// Additional flags.
};

typedef ScfRef< XclImpChSeriesFormat > XclImpChSeriesFormatRef;

// ----------------------------------------------------------------------------

/** The CH3DDATAFORMAT record containing the bar type in 3D bar charts. */
class XclImpCh3dDataFormat
{
public:
    /** Reads the CH3DDATAFORMAT record (3D bar properties). */
    void                ReadCh3dDataFormat( XclImpStream& rStrm );
    /** Converts and writes the contained data to the passed property set. */
    void                Convert( ScfPropertySet& rPropSet ) const;

private:
    XclCh3dDataFormat   maData;             /// Contents of the CH3DDATAFORMAT record.
};

typedef ScfRef< XclImpCh3dDataFormat > XclImpCh3dDataFormatRef;

// ----------------------------------------------------------------------------

/** The CHATTACHEDLABEL record that contains the type of a data point label. */
class XclImpChAttachedLabel : protected XclImpChRoot
{
public:
    explicit            XclImpChAttachedLabel( const XclImpChRoot& rRoot );
    /** Reads the CHATTACHEDLABEL record (data series/point labels). */
    void                ReadChAttachedLabel( XclImpStream& rStrm );
    /** Creates a CHTEXT group for the label. Clones xParentText and sets additional label settings */
    XclImpChTextRef     CreateDataLabel( XclImpChTextRef xParent ) const;

private:
    sal_uInt16          mnFlags;            /// Additional flags.
};

typedef ScfRef< XclImpChAttachedLabel > XclImpChAttLabelRef;

// ----------------------------------------------------------------------------

/** Represents the CHDATAFORMAT record group containing data point properties.

    The CHDATAFORMAT group consists of: CHDATAFORMAT, CHBEGIN, CHFRAME group,
    CHMARKERFORMAT, CHPIEFORMAT, CH3DDATAFORMAT, CHSERIESFORMAT,
    CHATTACHEDLABEL, CHEND.
 */
class XclImpChDataFormat : public XclImpChFrameBase, protected XclImpChRoot
{
public:
    explicit            XclImpChDataFormat( const XclImpChRoot& rRoot );

    /** Reads the CHDATAFORMAT record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );
    /** Reads a record from the CHDATAFORMAT group (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );

    /** Sets this object to the specified data point position. */
    void                SetPointPos( const XclChDataPointPos& rPointPos, sal_uInt16 nFormatIdx );
    /** Sets type and text formatting for a data point label (CHTEXT group). */
    inline void         SetDataLabel( XclImpChTextRef xLabel ) { mxLabel = xLabel; }

    /** Updates default data format for series group. */
    void                UpdateGroupFormat( const XclChExtTypeInfo& rTypeInfo );
    /** Updates missing series settings from the passed chart type group data format. */
    void                UpdateSeriesFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pGroupFmt );
    /** Updates missing data point settings from the passed series format. */
    void                UpdatePointFormat( const XclChExtTypeInfo& rTypeInfo, const XclImpChDataFormat* pSeriesFmt );
    /** Updates default data format for trend lines. */
    void                UpdateTrendLineFormat();

    /** Returns the position of the data point described by this group. */
    inline const XclChDataPointPos& GetPointPos() const { return maData.maPointPos; }
    /** Returns the format index of the data point described by this group. */
    inline sal_uInt16   GetFormatIdx() const { return maData.mnFormatIdx; }
    /** Returns true, if markers are set to automatic format. */
    inline bool         IsAutoMarker() const { return !mxMarkerFmt || mxMarkerFmt->IsAuto(); }
    /** Returns true, if the series line is smoothed. */
    inline bool         HasSpline() const { return mxSeriesFmt.is() && mxSeriesFmt->HasSpline(); }
    /** Returns the data label text object. */
    inline XclImpChTextRef GetDataLabel() const { return mxLabel; }

    /** Converts and writes the contained data to the passed property set. */
    void                Convert( ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo ) const;
    /** Writes the line format only, e.g. for trend lines or error bars. */
    void                ConvertLine( ScfPropertySet& rPropSet, XclChObjectType eObjType ) const;
    /** Writes the area format only for the series or a data point. */
    void                ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const;

private:
    /** Removes unused formatting (e.g. pie distance in a bar chart). */
    void                RemoveUnusedFormats( const XclChExtTypeInfo& rTypeInfo );
    /** Updates or creates the data point label. */
    void                UpdateDataLabel( const XclImpChDataFormat* pParentFmt );

private:
    XclChDataFormat     maData;             /// Contents of the CHDATAFORMAT record.
    XclImpChMarkerFormatRef mxMarkerFmt;    /// Data point marker (CHMARKERFORMAT record).
    XclImpChPieFormatRef mxPieFmt;          /// Pie segment format (CHPIEFORMAT record).
    XclImpChSeriesFormatRef mxSeriesFmt;    /// Series properties (CHSERIESFORMAT record).
    XclImpCh3dDataFormatRef mx3dDataFmt;    /// 3D bar format (CH3DDATAFORMAT record).
    XclImpChAttLabelRef mxAttLabel;         /// Data point label type (CHATTACHEDLABEL record).
    XclImpChTextRef     mxLabel;            /// Data point label formatting (CHTEXT group).
};

typedef ScfRef< XclImpChDataFormat > XclImpChDataFormatRef;

// ----------------------------------------------------------------------------

/** Represents the CHSERTRENDLINE record containing settings for a trend line. */
class XclImpChSerTrendLine : protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XRegressionCurve > XRegressionCurveRef;

public:
    explicit            XclImpChSerTrendLine( const XclImpChRoot& rRoot );

    /** Reads the CHSERTRENDLINE record. */
    void                ReadChSerTrendLine( XclImpStream& rStrm );
    /** Sets formatting information for the trend line. */
    inline void         SetDataFormat( XclImpChDataFormatRef xDataFmt ) { mxDataFmt = xDataFmt; }

    /** Creates an API object representing this trend line. */
    XRegressionCurveRef CreateRegressionCurve() const;

private:
    XclChSerTrendLine   maData;             /// Contents of the CHSERTRENDLINE record.
    XclImpChDataFormatRef mxDataFmt;        /// Formatting settings of the trend line.
};

typedef ScfRef< XclImpChSerTrendLine > XclImpChSerTrendLineRef;

// ----------------------------------------------------------------------------

/** Represents the CHSERERRORBAR record containing settings for error bars. */
class XclImpChSerErrorBar : protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence >    XLabeledDataSeqRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >                   XPropertySetRef;

public:
    explicit            XclImpChSerErrorBar( const XclImpChRoot& rRoot );

    /** Reads the CHSERERRORBAR record. */
    void                ReadChSerErrorBar( XclImpStream& rStrm );
    /** Sets link and formatting information for the error bars. */
    void                SetSeriesData(
                            XclImpChSourceLinkRef xValueLink,
                            XclImpChDataFormatRef xDataFmt );

    /** Returns the type of this error bar (X/Y, plus/minus). */
    inline sal_uInt8    GetBarType() const { return maData.mnBarType; }
    /** Creates a labeled data sequence object from value data link. */
    XLabeledDataSeqRef  CreateValueSequence() const;

    /** Tries to create an error bar API object from the specified Excel error bars. */
    static XPropertySetRef CreateErrorBar(
                            const XclImpChSerErrorBar* pPosBar,
                            const XclImpChSerErrorBar* pNegBar );

private:
    XclChSerErrorBar    maData;             /// Contents of the CHSERERRORBAR record.
    XclImpChSourceLinkRef mxValueLink;      /// Link data for manual error bar values.
    XclImpChDataFormatRef mxDataFmt;        /// Formatting settings of the error bars.
};

typedef ScfRef< XclImpChSerErrorBar > XclImpChSerErrorBarRef;

// ----------------------------------------------------------------------------

/** Represents the CHSERIES record group describing a data series in a chart.

    The CHSERIES group consists of: CHSERIES, CHBEGIN, CHSOURCELINK groups,
    CHDATAFORMAT groups, CHSERGROUP, CHSERPARENT, CHSERERRORBAR,
    CHSERTRENDLINE, CHEND.
 */
class XclImpChSeries : public XclImpChGroupBase, protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >                   XDataSeriesRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence >    XLabeledDataSeqRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >                   XPropertySetRef;

public:
    explicit            XclImpChSeries( const XclImpChRoot& rRoot, sal_uInt16 nSeriesIdx );

    /** Reads the CHSERIES record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );
    /** Reads a record from the CHSERIES group (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );

    /** Sets a data point or series format (CHDATAFORMAT group) for this series. */
    void                SetDataFormat( XclImpChDataFormatRef xDataFmt );
    /** Sets a label text (CHTEXT group) attached  to a series or data point. */
    void                SetDataLabel( XclImpChTextRef xLabel );
    /** Adds error bar settings from the passed series to the own series. */
    void                AddChildSeries( const XclImpChSeries& rSeries );
    /** Updates missing series formatting by using default formatting from axes sets. */
    void                FinalizeDataFormats();

    /** Returns the axes set identifier this series is assigned to (primary/secondary). */
    inline sal_uInt16   GetGroupIdx() const { return mnGroupIdx; }
    /** Returns the 0-based series index described by this series. */
    inline sal_uInt16   GetSeriesIdx() const { return mnSeriesIdx; }
    /** Returns the 0-based index of the parent series (e.g. of a trend line). */
    inline sal_uInt16   GetParentIdx() const { return mnParentIdx; }
    /** Returns the format index of the series used for automatic line and area colors. */
    inline sal_uInt16   GetFormatIdx() const { return mxSeriesFmt.is() ? mxSeriesFmt->GetFormatIdx() : EXC_CHDATAFORMAT_DEFAULT; }
    /** Returns true, if the series is child of another series (e.g. trend line). */
    inline bool         HasParentSeries() const { return mnParentIdx != EXC_CHSERIES_INVALID; }
    /** Returns true, if the series contains child series (e.g. trend lines). */
    inline bool         HasChildSeries() const { return !maTrendLines.empty() || !maErrorBars.empty(); }
    /** Returns series title or an empty string, if the series does not contain a title. */
    inline const String& GetTitle() const { return mxTitleLink.is() ? mxTitleLink->GetString() : String::EmptyString(); }

    /** Returns true, if the series line is smoothed. */
    inline bool         HasSpline() const { return mxSeriesFmt.is() && mxSeriesFmt->HasSpline(); }

    /** Creates a labeled data sequence object from value data link. */
    XLabeledDataSeqRef  CreateValueSequence( const ::rtl::OUString& rValueRole ) const;
    /** Creates a labeled data sequence object from category data link. */
    XLabeledDataSeqRef  CreateCategSequence( const ::rtl::OUString& rCategRole ) const;
    /** Creates a data series object with initialized source links. */
    XDataSeriesRef      CreateDataSeries() const;

    void                FillAllSourceLinks(::std::vector<ScSharedTokenRef>& rTokens) const;

private:
    /** Reads a CHSOURCELINK record. */
    void                ReadChSourceLink( XclImpStream& rStrm );
    /** Reads a CHDATAFORMAT group containing series and point formatting. */
    void                ReadChDataFormat( XclImpStream& rStrm );
    /** Reads a CHSERPARENT record specifying the parent series of this series. */
    void                ReadChSerParent( XclImpStream& rStrm );
    /** Reads a CHSERTRENDLINE record containing trend line settings. */
    void                ReadChSerTrendLine( XclImpStream& rStrm );
    /** Reads a CHSERERRORBAR record containing error bar settings. */
    void                ReadChSerErrorBar( XclImpStream& rStrm );

    /** Creates a new CHDATAFORMAT group with the specified point index. */
    XclImpChDataFormatRef CreateDataFormat( sal_uInt16 nPointIdx, sal_uInt16 nFormatIdx );
    /** Returns the pointer to a CHDATAFORMAT group reference or 0 for invalid pointer index. */
    XclImpChDataFormatRef* GetDataFormatRef( sal_uInt16 nPointIdx );
    /** Returns the pointer to a CHTEXT group reference or 0 for invalid pointer index. */
    XclImpChTextRef*    GetDataLabelRef( sal_uInt16 nPointIdx );

    /** Converts all trend lines and inserts them into the passed API data series object. */
    void                ConvertTrendLines( XDataSeriesRef xDataSeries ) const;
    /** Tries to create an error bar API object from the specified Excel error bars. */
    XPropertySetRef     CreateErrorBar( sal_uInt8 nPosBarId, sal_uInt8 nNegBarId ) const;

private:
    typedef ScfRefMap< sal_uInt16, XclImpChDataFormat > XclImpChDataFormatMap;
    typedef ScfRefMap< sal_uInt16, XclImpChText >       XclImpChTextMap;
    typedef ::std::list< XclImpChSerTrendLineRef >      XclImpChSerTrendLineList;
    typedef ScfRefMap< sal_uInt8, XclImpChSerErrorBar > XclImpChSerErrorBarMap;

    XclChSeries         maData;             /// Contents of the CHSERIES record.
    XclImpChSourceLinkRef mxValueLink;      /// Link data for series values.
    XclImpChSourceLinkRef mxCategLink;      /// Link data for series category names.
    XclImpChSourceLinkRef mxTitleLink;      /// Link data for series title.
    XclImpChSourceLinkRef mxBubbleLink;     /// Link data for series bubble sizes.
    XclImpChDataFormatRef mxSeriesFmt;      /// CHDATAFORMAT group for series format.
    XclImpChDataFormatMap maPointFmts;      /// CHDATAFORMAT groups for data point formats.
    XclImpChTextMap     maLabels;           /// Data point labels (CHTEXT groups).
    XclImpChSerTrendLineList maTrendLines;  /// Trend line settings (CHSERTRENDLINE records).
    XclImpChSerErrorBarMap maErrorBars;     /// Error bar settings (CHSERERRORBAR records).
    sal_uInt16          mnGroupIdx;         /// Chart type group (CHTYPEGROUP group) this series is assigned to.
    sal_uInt16          mnSeriesIdx;        /// 0-based series index.
    sal_uInt16          mnParentIdx;        /// 0-based index of parent series (trend lines and error bars).
};

typedef ScfRef< XclImpChSeries > XclImpChSeriesRef;

// Chart type groups ==========================================================

class XclImpChType : protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >          XDiagramRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >        XChartTypeRef;

public:
    explicit            XclImpChType( const XclImpChRoot& rRoot );

    /** Reads a chart type record (e.g. CHBAR, CHLINE, CHPIE, ...). */
    void                ReadChType( XclImpStream& rStrm );
    /** Final processing after reading the entire chart. */
    void                Finalize( bool bStockChart );

    /** Returns the record identifier of the chart type record. */
    inline sal_uInt16   GetRecId() const { return mnRecId; }
    /** Returns the chart type info struct for the contained chart type. */
    inline const XclChTypeInfo& GetTypeInfo() const { return maTypeInfo; }
    /** Returns true, if the series in this chart type group are stacked on each other (no percentage). */
    bool                IsStacked() const;
    /** Returns true, if the series in this chart type group are stacked on each other as percentage. */
    bool                IsPercent() const;
    /** Returns true, if chart type has category labels enabled (may be disabled in radar charts). */
    bool                HasCategoryLabels() const;

    /** Creates a coordinate system according to the contained chart type. */
    XCoordSystemRef     CreateCoordSystem( bool b3dChart ) const;
    /** Creates and returns an object that represents the contained chart type. */
    XChartTypeRef       CreateChartType( XDiagramRef xDiagram, bool b3dChart ) const;

private:
    XclChType           maData;             /// Contents of the chart type record.
    sal_uInt16          mnRecId;            /// Record identifier for chart type.
    XclChTypeInfo       maTypeInfo;         /// Chart type info for the contained type.
};

// ----------------------------------------------------------------------------

/** Represents the CHCHART3D record that contains 3D view settings. */
class XclImpChChart3d
{
public:
    /** Reads the CHCHART3D record (properties for 3D charts). */
    void                ReadChChart3d( XclImpStream& rStrm );
    /** Returns true, if the data points are clustered on the X axis. */
    inline bool         IsClustered() const { return ::get_flag( maData.mnFlags, EXC_CHCHART3D_CLUSTER ); }
    /** Converts and writes the contained data to the passed property set. */
    void                Convert( ScfPropertySet& rPropSet, bool b3dWallChart ) const;

private:
    XclChChart3d        maData;             /// Contents of the CHCHART3D record.
};

typedef ScfRef< XclImpChChart3d > XclImpChChart3dRef;

// ----------------------------------------------------------------------------

/** Represents the CHLEGEND record group describing the chart legend.

    The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAME group,
    CHTEXT group, CHEND.
 */
class XclImpChLegend : public XclImpChGroupBase, protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XLegend > XLegendRef;

public:
    explicit            XclImpChLegend( const XclImpChRoot& rRoot );

    /** Reads the CHLEGEND record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );
    /** Reads a record from the CHLEGEND group (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );
    /** Final processing after reading the entire chart. */
    void                Finalize();

    /** Creates a new legend object. */
    XLegendRef          CreateLegend() const;

private:
    XclChLegend         maData;             /// Contents of the CHLEGEND record.
    XclImpChTextRef     mxText;             /// Legend text format (CHTEXT group).
    XclImpChFrameRef    mxFrame;            /// Legend frame format (CHFRAME group).
};

typedef ScfRef< XclImpChLegend > XclImpChLegendRef;

// ----------------------------------------------------------------------------

/** Represents the CHDROPBAR record group describing pos/neg bars in line charts.

    The CHDROPBAR group consists of: CHDROPBAR, CHBEGIN, CHLINEFORMAT,
    CHAREAFORMAT, CHESCHERFORMAT group, CHEND.
 */
class XclImpChDropBar : public XclImpChFrameBase
{
public:
    explicit            XclImpChDropBar( sal_uInt16 nDropBar );

    /** Reads the CHDROPBAR record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );

    /** Converts and writes the contained frame data to the passed property set. */
    void                Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet ) const;

private:
    sal_uInt16          mnDropBar;          /// Drop bar identifier, needed for auto format.
    sal_uInt16          mnBarDist;          /// Distance between bars (CHDROPBAR record).
};

typedef ScfRef< XclImpChDropBar > XclImpChDropBarRef;

// ----------------------------------------------------------------------------

/** Represents the CHTYPEGROUP record group describing a group of series.

    The CHTYPEGROUP group consists of: CHTYPEGROUP, CHBEGIN, a chart type
    record (e.g. CHBAR, CHLINE, CHAREA, CHPIE, ...), CHCHART3D, CHLEGEND group,
    CHDEFAULTTEXT groups (CHDEFAULTTEXT with CHTEXT groups), CHDROPBAR groups,
    CHCHARTLINE groups (CHCHARTLINE with CHLINEFORMAT), CHDATAFORMAT group,
    CHEND.
 */
class XclImpChTypeGroup : public XclImpChGroupBase, protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >                      XDiagramRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem >             XCoordSystemRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >                    XChartTypeRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >                   XDataSeriesRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XLabeledDataSequence >    XLabeledDataSeqRef;

public:
    explicit            XclImpChTypeGroup( const XclImpChRoot& rRoot );

    /** Reads the CHTYPEGROUP record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );
    /** Reads a record from the CHTYPEGROUP group (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );
    /** Final processing after reading the entire chart. */
    void                Finalize();

    /** Inserts a series attached to this chart type group.*/
    void                AddSeries( XclImpChSeriesRef xSeries );
    /** Marks the passed format index as used. PopUnusedFormatIndex() will not return this index. */
    void                SetUsedFormatIndex( sal_uInt16 nFormatIdx );
    /** Returns the next unused format index and marks it as used. */
    sal_uInt16          PopUnusedFormatIndex();

    /** Returns the index of this chart type group. */
    inline sal_uInt16   GetGroupIdx() const { return maData.mnGroupIdx; }
    /** Returns the chart type info struct for the contained chart type. */
    inline const XclChExtTypeInfo& GetTypeInfo() const { return maTypeInfo; }
    /** Returns true, if this chart type group contains at least one valid series. */
    inline bool         IsValidGroup() const { return !maSeries.empty(); }
    /** Returns true, if the series in this chart type group are stacked on each other (no percentage). */
    inline bool         IsStacked() const { return maType.IsStacked(); }
    /** Returns true, if the series in this chart type group are stacked on each other as percentage. */
    inline bool         IsPercent() const { return maType.IsPercent(); }
    /** Returns true, if the chart is three-dimensional. */
    inline bool         Is3dChart() const { return mxChart3d.is() && maTypeInfo.mbSupports3d; }
    /** Returns true, if chart type supports wall and floor format in 3d mode. */
    inline bool         Is3dWallChart() const { return Is3dChart() && (maTypeInfo.meTypeCateg != EXC_CHTYPECATEG_PIE); }
    /** Returns true, if the series in this chart type group are ordered on the Z axis. */
    inline bool         Is3dDeepChart() const { return Is3dWallChart() && mxChart3d.is() && !mxChart3d->IsClustered(); }
    /** Returns true, if category (X axis) labels are enabled (may be disabled in radar charts). */
    inline bool         HasCategoryLabels() const { return maType.HasCategoryLabels(); }
    /** Returns true, if points of a series show varying automatic area format. */
    bool                HasVarPointFormat() const;
    /** Returns true, if bars are connected with lines (stacked bar charts only). */
    bool                HasConnectorLines() const;

    /** Returns the legend object. */
    inline XclImpChLegendRef GetLegend() const { return mxLegend; }
    /** Returns the default series data format. */
    inline XclImpChDataFormatRef GetGroupFormat() const { return mxGroupFmt; }
    /** Returns series title, if the chart type group contains only one single series. */
    const String&       GetSingleSeriesTitle() const;

    /** Converts and writes all 3D settings to the passed diagram. */
    void                ConvertChart3d( ScfPropertySet& rPropSet ) const;
    /** Creates a coordinate system according to the contained chart type. */
    XCoordSystemRef     CreateCoordSystem() const;
    /** Creates and returns an object that represents the contained chart type. */
    XChartTypeRef       CreateChartType( XDiagramRef xDiagram, sal_Int32 nApiAxesSetIdx ) const;
    /** Creates a labeled data sequence object for axis categories. */
    XLabeledDataSeqRef  CreateCategSequence() const;

private:
    /** Reads a CHDROPBAR record group. */
    void                ReadChDropBar( XclImpStream& rStrm );
    /** Reads a CHCHARTLINE record group. */
    void                ReadChChartLine( XclImpStream& rStrm );
    /** Reads a CHDATAFORMAT record group (default series format). */
    void                ReadChDataFormat( XclImpStream& rStrm );

    /** Returns true, if the chart type group contains a hi-lo line format. */
    inline bool         HasHiLoLine() const { return maChartLines.has( EXC_CHCHARTLINE_HILO ); }
    /** Returns true, if the chart type group contains drop bar formats. */
    inline bool         HasDropBars() const { return !maDropBars.empty(); }

    /** Inserts the passed series into the chart type. Adds additional properties to the series. */
    void                InsertDataSeries( XChartTypeRef xChartType,
                            XDataSeriesRef xSeries, sal_Int32 nApiAxesSetIdx ) const;
    /** Creates all data series of any chart type except stock charts. */
    void                CreateDataSeries( XChartTypeRef xChartType, sal_Int32 nApiAxesSetIdx ) const;
    /** Creates all data series of of a stock chart. */
    void                CreateStockSeries( XChartTypeRef xChartType, sal_Int32 nApiAxesSetIdx ) const;

private:
    typedef ::std::vector< XclImpChSeriesRef >          XclImpChSeriesVec;
    typedef ScfRefMap< sal_uInt16, XclImpChDropBar >    XclImpChDropBarMap;
    typedef ScfRefMap< sal_uInt16, XclImpChLineFormat > XclImpChLineFormatMap;
    typedef ::std::set< sal_uInt16 >                    UInt16Set;

    XclChTypeGroup      maData;             /// Contents of the CHTYPEGROUP record.
    XclImpChType        maType;             /// Chart type (e.g. CHBAR, CHLINE, ...).
    XclChExtTypeInfo    maTypeInfo;         /// Extended chart type info.
    XclImpChSeriesVec   maSeries;           /// Series attached to this chart type group (CHSERIES groups).
    XclImpChSeriesRef   mxFirstSeries;      /// First series in this chart type group (CHSERIES groups).
    XclImpChChart3dRef  mxChart3d;          /// 3D settings (CHCHART3D record).
    XclImpChLegendRef   mxLegend;           /// Chart legend (CHLEGEND group).
    XclImpChDropBarMap  maDropBars;         /// Dropbars (CHDROPBAR group).
    XclImpChLineFormatMap maChartLines;     /// Global line formats (CHCHARTLINE group).
    XclImpChDataFormatRef mxGroupFmt;       /// Default format for all series (CHDATAFORMAT group).
    UInt16Set           maUnusedFormats;    /// Contains unused format indexes for automatic colors.
};

typedef ScfRef< XclImpChTypeGroup > XclImpChTypeGroupRef;

// Axes =======================================================================

class XclImpChLabelRange : protected XclImpChRoot
{
public:
    typedef ::com::sun::star::chart2::ScaleData ScaleData;

public:
    explicit            XclImpChLabelRange( const XclImpChRoot& rRoot );
    /** Reads the CHLABELRANGE record (category axis scaling properties). */
    void                ReadChLabelRange( XclImpStream& rStrm );
    /** Converts category axis scaling settings. */
    void                Convert( ScfPropertySet& rPropSet, ScaleData& rScaleData, bool bMirrorOrient ) const;
    /** Converts position settings of this axis at a crossing axis. */
    void                ConvertAxisPosition( ScfPropertySet& rPropSet, bool b3dChart ) const;

private:
    XclChLabelRange     maData;             /// Contents of the CHLABELRANGE record.
};

typedef ScfRef< XclImpChLabelRange > XclImpChLabelRangeRef;

// ----------------------------------------------------------------------------

class XclImpChValueRange : protected XclImpChRoot
{
public:
    typedef ::com::sun::star::chart2::ScaleData ScaleData;

public:
    explicit            XclImpChValueRange( const XclImpChRoot& rRoot );
    /** Reads the CHVALUERANGE record (numeric axis scaling properties). */
    void                ReadChValueRange( XclImpStream& rStrm );
    /** Converts value axis scaling settings. */
    void                Convert( ScaleData& rScaleData, bool bMirrorOrient ) const;
    /** Converts position settings of this axis at a crossing axis. */
    void                ConvertAxisPosition( ScfPropertySet& rPropSet ) const;

private:
    XclChValueRange     maData;             /// Contents of the CHVALUERANGE record.
};

typedef ScfRef< XclImpChValueRange > XclImpChValueRangeRef;

// ----------------------------------------------------------------------------

class XclImpChTick : protected XclImpChRoot
{
public:
    explicit            XclImpChTick( const XclImpChRoot& rRoot );
    /** Reads the CHTICK record (axis ticks properties). */
    void                ReadChTick( XclImpStream& rStrm );

    /** Returns true, if the axis shows attached labels. */
    inline bool         HasLabels() const { return maData.mnLabelPos != EXC_CHTICK_NOLABEL; }
    /** Returns the leading font color for the axis labels. */
    Color               GetFontColor() const;
    /** Returns the rotation value for the axis labels. */
    sal_uInt16          GetRotation() const;

    /** Converts and writes the contained data to the passed property set. */
    void                Convert( ScfPropertySet& rPropSet ) const;

private:
    XclChTick           maData;             /// Contents of the CHTICK record.
};

typedef ScfRef< XclImpChTick > XclImpChTickRef;

// ----------------------------------------------------------------------------

/** Represents the CHAXIS record group describing an entire chart axis.

    The CHAXIS group consists of: CHAXIS, CHBEGIN, CHLABELRANGE, CHEXTRANGE,
    CHVALUERANGE, CHFORMAT, CHTICK, CHFONT, CHAXISLINE groups (CHAXISLINE with
    CHLINEFORMAT, CHAREAFORMAT, and CHESCHERFORMAT group), CHEND.
 */
class XclImpChAxis : public XclImpChGroupBase, public XclImpChFontBase, protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis > XAxisRef;

public:
    explicit            XclImpChAxis( const XclImpChRoot& rRoot, sal_uInt16 nAxisType = EXC_CHAXIS_NONE );

    /** Reads the CHAXIS record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );
    /** Reads a record from the CHAXIS group (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );
    /** Final processing after reading the entire chart. */
    void                Finalize();

    /** Returns the font index for the axis labels. */
    virtual sal_uInt16  GetFontIndex() const;
    /** Returns the font color for the axis labels. */
    virtual Color       GetFontColor() const;
    /** Returns the rotation value for axis labels. */
    virtual sal_uInt16  GetRotation() const;

    /** Returns the type of this axis. */
    inline sal_uInt16   GetAxisType() const { return maData.mnType; }
    /** Returns the axis dimension index used by the chart API. */
    inline sal_Int32    GetApiAxisDimension() const { return maData.GetApiAxisDimension(); }
    /** Returns true, if the axis is active. */
    inline bool         IsActivated() const { return !mxAxisLine || mxAxisLine->IsShowAxis(); }
    /** Returns true, if the axis contains caption labels. */
    inline bool         HasLabels() const { return !mxTick || mxTick->HasLabels(); }
    /** Returns true, if the axis shows its major grid lines. */
    inline bool         HasMajorGrid() const { return mxMajorGrid.is(); }
    /** Returns true, if the axis shows its minor grid lines. */
    inline bool         HasMinorGrid() const { return mxMinorGrid.is(); }

    /** Creates an API axis object. */
    XAxisRef            CreateAxis( const XclImpChTypeGroup& rTypeGroup, const XclImpChAxis* pCrossingAxis ) const;
    /** Converts and writes 3D wall/floor properties to the passed property set. */
    void                ConvertWall( ScfPropertySet& rPropSet ) const;
    /** Converts position settings of this axis at a crossing axis. */
    void                ConvertAxisPosition( ScfPropertySet& rPropSet, const XclImpChTypeGroup& rTypeGroup ) const;

private:
    /** Reads a CHAXISLINE record specifying the target for following line properties. */
    void                ReadChAxisLine( XclImpStream& rStrm );
    /** Creates a CHFRAME object and stores it into the mxWallFrame member. */
    void                CreateWallFrame();

private:
    XclChAxis           maData;             /// Contents of the CHAXIS record.
    XclImpChLabelRangeRef mxLabelRange;     /// Category scaling (CHLABELRANGE record).
    XclImpChValueRangeRef mxValueRange;     /// Value scaling (CHVALUERANGE record).
    XclImpChTickRef     mxTick;             /// Axis ticks (CHTICK record).
    XclImpChFontRef     mxFont;             /// Index into font buffer (CHFONT record).
    XclImpChLineFormatRef mxAxisLine;       /// Axis line format (CHLINEFORMAT record).
    XclImpChLineFormatRef mxMajorGrid;      /// Major grid line format (CHLINEFORMAT record).
    XclImpChLineFormatRef mxMinorGrid;      /// Minor grid line format (CHLINEFORMAT record).
    XclImpChFrameRef    mxWallFrame;        /// Wall/floor format (sub records of CHFRAME group).
    sal_uInt16          mnNumFmtIdx;        /// Index into number format buffer (CHFORMAT record).
};

typedef ScfRef< XclImpChAxis > XclImpChAxisRef;

// ----------------------------------------------------------------------------

/** Represents the CHAXESSET record group describing an axes set (X/Y/Z axes).

    The CHAXESSET group consists of: CHAXESSET, CHBEGIN, CHFRAMEPOS, CHAXIS
    groups, CHTEXT groups, CHPLOTFRAME group (CHPLOTFRAME with CHFRAME group),
    CHTYPEGROUP group, CHEND.
 */
class XclImpChAxesSet : public XclImpChGroupBase, protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >          XDiagramRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > XCoordSystemRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >             XAxisRef;

public:
    explicit            XclImpChAxesSet( const XclImpChRoot& rRoot, sal_uInt16 nAxesSetId );

    /** Reads the CHAXESSET record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );
    /** Reads a record from the CHAXESSET group (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );
    /** Final processing after reading the entire chart. */
    void                Finalize();

    /** Returns true, if this axes set exists (returns false if this is a dummy object). */
    inline bool         IsValidAxesSet() const { return !maTypeGroups.empty(); }
    /** Returns the index of the axes set (primary/secondary). */
    inline sal_uInt16   GetAxesSetId() const { return maData.mnAxesSetId; }
    /** Returns the axes set index used by the chart API. */
    inline sal_Int32    GetApiAxesSetIndex() const { return maData.GetApiAxesSetIndex(); }

    /** Returns the specified chart type group. */
    inline XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const { return maTypeGroups.get( nGroupIdx ); }
    /** Returns the first chart type group. */
    XclImpChTypeGroupRef GetFirstTypeGroup() const;
    /** Looks for a legend in all chart type groups and returns it. */
    XclImpChLegendRef   GetLegend() const;
    /** Returns series title, if the axes set contains only one single series. */
    const String&       GetSingleSeriesTitle() const;

    /** Creates a coordinate system and converts all series and axis settings. */
    void                Convert( XDiagramRef xDiagram ) const;

private:
    /** Reads a CHAXIS record group containing a single axis. */
    void                ReadChAxis( XclImpStream& rStrm );
    /** Reads a CHTEXT record group containing an axis title. */
    void                ReadChText( XclImpStream& rStrm );
    /** Reads the CHPLOTFRAME record group containing diagram area formatting. */
    void                ReadChPlotFrame( XclImpStream& rStrm );
    /** Reads a CHTYPEGROUP record group containing chart type and chart settings. */
    void                ReadChTypeGroup( XclImpStream& rStrm );

    /** Updates text formatting of the passed axis title with global text formatting. */
    void                UpdateAxisTitle( XclImpChTextRef xTitle );

    /** Creates a coordinate system that contains all chart types for this axes set. */
    XCoordSystemRef     CreateCoordSystem( XDiagramRef xDiagram ) const;
    /** Creates and inserts an axis into the container and registers the coordinate system. */
    void                ConvertAxis( XclImpChAxisRef xChAxis, XclImpChTextRef xChAxisTitle,
                            XCoordSystemRef xCoordSystem, const XclImpChAxis* pCrossingAxis ) const;
    /** Creates and returns an API axis object. */
    XAxisRef            CreateAxis( const XclImpChAxis& rChAxis, const XclImpChAxis* pCrossingAxis ) const;
    /** Writes all properties of the background area to the passed diagram. */
    void                ConvertBackground( XDiagramRef xDiagram ) const;

private:
    typedef ScfRefMap< sal_uInt16, XclImpChTypeGroup > XclImpChTypeGroupMap;

    XclChAxesSet        maData;             /// Contents of the CHAXESSET record.
    XclImpChFramePosRef mxPos;              /// Position of the axes set (CHFRAMEPOS record).
    XclImpChAxisRef     mxXAxis;            /// The X axis (CHAXIS group).
    XclImpChAxisRef     mxYAxis;            /// The Y axis (CHAXIS group).
    XclImpChAxisRef     mxZAxis;            /// The Z axis (CHAXIS group).
    XclImpChTextRef     mxXAxisTitle;       /// The X axis title (CHTEXT group).
    XclImpChTextRef     mxYAxisTitle;       /// The Y axis title (CHTEXT group).
    XclImpChTextRef     mxZAxisTitle;       /// The Z axis title (CHTEXT group).
    XclImpChFrameRef    mxPlotFrame;        /// Plot area (CHPLOTFRAME group).
    XclImpChTypeGroupMap maTypeGroups;      /// Chart type groups (CHTYPEGROUP group).
};

typedef ScfRef< XclImpChAxesSet > XclImpChAxesSetRef;

// The chart object ===========================================================

/** Represents the CHCHART record group describing the chart contents.

    The CHCHART group consists of: CHCHART, CHBEGIN, SCL, CHPLOTGROWTH, CHFRAME
    group, CHSERIES groups, CHPROPERTIES, CHDEFAULTTEXT groups (CHDEFAULTTEXT
    with CHTEXT groups), CHUSEDAXESSETS, CHAXESSET groups, CHTEXT groups, CHEND.
 */
class XclImpChChart : public XclImpChGroupBase, protected XclImpChRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >    XChartDocRef;
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >          XDiagramRef;

public:
    explicit            XclImpChChart( const XclImpRoot& rRoot );
    virtual             ~XclImpChChart();

    /** Reads the CHCHART record (called by base class). */
    virtual void        ReadHeaderRecord( XclImpStream& rStrm );
    /** Reads a record from the CHCHART group (called by base class). */
    virtual void        ReadSubRecord( XclImpStream& rStrm );
    /** Reads a CHDEFAULTTEXT group (default text formats). */
    void                ReadChDefaultText( XclImpStream& rStrm );
    /** Reads a CHDATAFORMAT group describing a series format or a data point format. */
    void                ReadChDataFormat( XclImpStream& rStrm );

    /** Sets formatting from BIFF3-BIFF5 OBJ record, if own formatting is invisible. */
    void                UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData );

    /** Returns the specified chart type group. */
    XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const;
    /** Returns the specified default text. */
    XclImpChTextRef     GetDefaultText( XclChTextType eTextType ) const;
    /** Returns the number of units on the progress bar needed for the chart. */
    inline sal_Size     GetProgressSize() const { return 2 * EXC_CHART_PROGRESS_SIZE; }

    /** Converts and writes all properties to the passed chart. */
    void                Convert( XChartDocRef xChartDoc, ScfProgressBar& rProgress, const ::rtl::OUString& rObjName ) const;

private:
    /** Reads a CHSERIES group (data series source and formatting). */
    void                ReadChSeries( XclImpStream& rStrm );
    /** Reads a CHPROPERTIES record (global chart properties). */
    void                ReadChProperties( XclImpStream& rStrm );
    /** Reads a CHAXESSET group (primary/secondary axes set). */
    void                ReadChAxesSet( XclImpStream& rStrm );
    /** Reads a CHTEXT group (chart title and series/point captions). */
    void                ReadChText( XclImpStream& rStrm );

    /** Final processing after reading the entire chart data. */
    void                Finalize();
    /** Finalizes series list, assigns child series to parent series. */
    void                FinalizeSeries();
    /** Assigns all imported CHDATAFORMAT groups to the respective series. */
    void                FinalizeDataFormats();
    /** Finalizes chart title, tries to detect title auto-generated from series name. */
    void                FinalizeTitle();

    /** Creates and returns a new diagram object and converts global chart settings. */
    XDiagramRef         CreateDiagram() const;

private:
    typedef ::std::vector< XclImpChSeriesRef >                  XclImpChSeriesVec;
    typedef ScfRefMap< XclChDataPointPos, XclImpChDataFormat >  XclImpChDataFormatMap;
    typedef ScfRefMap< sal_uInt16, XclImpChText >               XclImpChTextMap;

    XclChRectangle      maRect;             /// Position of the chart on the sheet (CHCHART record).
    XclImpChSeriesVec   maSeries;           /// List of series data (CHSERIES groups).
    XclImpChDataFormatMap maDataFmts;       /// All series and point formats (CHDATAFORMAT groups).
    XclImpChFrameRef    mxFrame;            /// Chart frame format (CHFRAME group).
    XclChProperties     maProps;            /// Chart properties (CHPROPERTIES record).
    XclImpChTextMap     maDefTexts;         /// Default text objects (CHDEFAULTTEXT groups).
    XclImpChAxesSetRef  mxPrimAxesSet;      /// Primary axes set (CHAXESSET group).
    XclImpChAxesSetRef  mxSecnAxesSet;      /// Secondary axes set (CHAXESSET group).
    XclImpChTextRef     mxTitle;            /// Chart title (CHTEXT group).
    XclImpChLegendRef   mxLegend;           /// Chart legend (CHLEGEND group).
};

typedef ScfRef< XclImpChChart > XclImpChChartRef;

// ----------------------------------------------------------------------------

/** Represents the entire chart substream (all records in BOF/EOF block). */
class XclImpChart : protected XclImpRoot
{
public:
    typedef ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > XModelRef;

public:
    /** Constructs a new chart object.
        @param bOwnTab  True = chart is on an own sheet; false = chart is an embedded object. */
    explicit            XclImpChart( const XclImpRoot& rRoot, bool bOwnTab );

    /** Reads the complete chart substream (BOF/EOF block).
        @descr  The passed stream must be located in the BOF record of the chart substream. */
    void                ReadChartSubStream( XclImpStream& rStrm );
    /** Sets formatting from BIFF3-BIFF5 OBJ record, if own formatting is invisible. */
    void                UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData );

    /** Returns the number of units on the progress bar needed for the chart. */
    sal_Size            GetProgressSize() const;
    /** Returns true, if the chart is based on a pivot table. */
    inline bool         IsPivotChart() const { return mbIsPivotChart; }

    /** Creates the chart object in the passed component. */
    void                Convert( XModelRef xModel, ScfProgressBar& rProgress, const ::rtl::OUString& rObjName ) const;

private:
    /** Reads the CHCHART group (entire chart data). */
    void                ReadChChart( XclImpStream& rStrm );

private:
    XclImpChChartRef    mxChartData;        /// The chart data (CHCHART group).
    bool                mbOwnTab;           /// true = own sheet; false = embedded object.
    bool                mbIsPivotChart;     /// true = chart is based on a pivot table.
};

// ============================================================================

#endif