1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "xlchart.hxx"
23 #include <com/sun/star/container/XNameContainer.hpp>
24 #include <com/sun/star/awt/Size.hpp>
25 #include <com/sun/star/awt/Gradient.hpp>
26 #include <com/sun/star/drawing/Hatch.hpp>
27 #include <com/sun/star/drawing/LineDash.hpp>
28 #include <com/sun/star/drawing/LineStyle.hpp>
29 #include <com/sun/star/drawing/FillStyle.hpp>
30 #include <com/sun/star/drawing/BitmapMode.hpp>
31 #include <com/sun/star/chart/DataLabelPlacement.hpp>
32 #include <com/sun/star/chart/XAxisXSupplier.hpp>
33 #include <com/sun/star/chart/XAxisYSupplier.hpp>
34 #include <com/sun/star/chart/XAxisZSupplier.hpp>
35 #include <com/sun/star/chart/XChartDocument.hpp>
36 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
37 #include <com/sun/star/chart2/Symbol.hpp>
39 #include <sal/macros.h>
40 #include <rtl/math.hxx>
41 #include <svl/itemset.hxx>
42 #include <svx/xfillit0.hxx>
43 #include <svx/xflclit.hxx>
44 #include <svx/xfltrit.hxx>
45 #include <svx/xflgrit.hxx>
46 #include <svx/xbtmpit.hxx>
47 #include <svx/unomid.hxx>
48 #include <filter/msfilter/escherex.hxx>
49 #include <editeng/memberids.hrc>
52 #include "xlstyle.hxx"
54 using ::com::sun::star::uno::Any
;
55 using ::com::sun::star::uno::Reference
;
56 using ::com::sun::star::uno::UNO_QUERY
;
57 using ::com::sun::star::uno::Exception
;
58 using ::com::sun::star::lang::XMultiServiceFactory
;
59 using ::com::sun::star::chart2::XChartDocument
;
60 using ::com::sun::star::drawing::XShape
;
62 namespace cssc
= ::com::sun::star::chart
;
64 // Common =====================================================================
66 XclChRectangle::XclChRectangle() :
74 // ----------------------------------------------------------------------------
76 XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx
, sal_uInt16 nPointIdx
) :
77 mnSeriesIdx( nSeriesIdx
),
78 mnPointIdx( nPointIdx
)
82 bool operator<( const XclChDataPointPos
& rL
, const XclChDataPointPos
& rR
)
84 return (rL
.mnSeriesIdx
< rR
.mnSeriesIdx
) ||
85 ((rL
.mnSeriesIdx
== rR
.mnSeriesIdx
) && (rL
.mnPointIdx
< rR
.mnPointIdx
));
88 // ----------------------------------------------------------------------------
90 XclChFrBlock::XclChFrBlock( sal_uInt16 nType
) :
98 // Frame formatting ===========================================================
100 XclChFramePos::XclChFramePos() :
101 mnTLMode( EXC_CHFRAMEPOS_PARENT
),
102 mnBRMode( EXC_CHFRAMEPOS_PARENT
)
106 // ----------------------------------------------------------------------------
108 XclChLineFormat::XclChLineFormat() :
109 maColor( COL_BLACK
),
110 mnPattern( EXC_CHLINEFORMAT_SOLID
),
111 mnWeight( EXC_CHLINEFORMAT_SINGLE
),
112 mnFlags( EXC_CHLINEFORMAT_AUTO
)
116 // ----------------------------------------------------------------------------
118 XclChAreaFormat::XclChAreaFormat() :
119 maPattColor( COL_WHITE
),
120 maBackColor( COL_BLACK
),
121 mnPattern( EXC_PATT_SOLID
),
122 mnFlags( EXC_CHAREAFORMAT_AUTO
)
126 // ----------------------------------------------------------------------------
128 XclChEscherFormat::XclChEscherFormat()
132 XclChEscherFormat::~XclChEscherFormat()
136 // ----------------------------------------------------------------------------
138 XclChPicFormat::XclChPicFormat() :
139 mnBmpMode( EXC_CHPICFORMAT_NONE
),
140 mnFlags( EXC_CHPICFORMAT_TOPBOTTOM
| EXC_CHPICFORMAT_FRONTBACK
| EXC_CHPICFORMAT_LEFTRIGHT
),
145 // ----------------------------------------------------------------------------
147 XclChFrame::XclChFrame() :
148 mnFormat( EXC_CHFRAME_STANDARD
),
149 mnFlags( EXC_CHFRAME_AUTOSIZE
| EXC_CHFRAME_AUTOPOS
)
153 // Source links ===============================================================
155 XclChSourceLink::XclChSourceLink() :
156 mnDestType( EXC_CHSRCLINK_TITLE
),
157 mnLinkType( EXC_CHSRCLINK_DEFAULT
),
163 // Text =======================================================================
165 XclChObjectLink::XclChObjectLink() :
166 mnTarget( EXC_CHOBJLINK_NONE
)
170 // ----------------------------------------------------------------------------
172 XclChFrLabelProps::XclChFrLabelProps() :
177 // ----------------------------------------------------------------------------
179 XclChText::XclChText() :
180 maTextColor( COL_BLACK
),
181 mnHAlign( EXC_CHTEXT_ALIGN_CENTER
),
182 mnVAlign( EXC_CHTEXT_ALIGN_CENTER
),
183 mnBackMode( EXC_CHTEXT_TRANSPARENT
),
184 mnFlags( EXC_CHTEXT_AUTOCOLOR
| EXC_CHTEXT_AUTOFILL
),
185 mnFlags2( EXC_CHTEXT_POS_DEFAULT
),
186 mnRotation( EXC_ROT_NONE
)
190 // Data series ================================================================
192 XclChMarkerFormat::XclChMarkerFormat() :
193 maLineColor( COL_BLACK
),
194 maFillColor( COL_WHITE
),
195 mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE
),
196 mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL
),
197 mnFlags( EXC_CHMARKERFORMAT_AUTO
)
201 // ----------------------------------------------------------------------------
203 XclCh3dDataFormat::XclCh3dDataFormat() :
204 mnBase( EXC_CH3DDATAFORMAT_RECT
),
205 mnTop( EXC_CH3DDATAFORMAT_STRAIGHT
)
209 // ----------------------------------------------------------------------------
211 XclChDataFormat::XclChDataFormat() :
212 mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT
),
217 // ----------------------------------------------------------------------------
219 XclChSerTrendLine::XclChSerTrendLine() :
220 mfForecastFor( 0.0 ),
221 mfForecastBack( 0.0 ),
222 mnLineType( EXC_CHSERTREND_POLYNOMIAL
),
227 /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
228 there is no interception point. Cannot use ::rtl::math::setNan() here
229 cause it misses the sign bit. */
230 sal_math_Double
* pDouble
= reinterpret_cast< sal_math_Double
* >( &mfIntercept
);
231 pDouble
->w32_parts
.msw
= pDouble
->w32_parts
.lsw
= 0xFFFFFFFF;
234 // ----------------------------------------------------------------------------
236 XclChSerErrorBar::XclChSerErrorBar() :
239 mnBarType( EXC_CHSERERR_NONE
),
240 mnSourceType( EXC_CHSERERR_FIXED
),
241 mnLineEnd( EXC_CHSERERR_END_TSHAPE
)
245 // ----------------------------------------------------------------------------
247 XclChSeries::XclChSeries() :
248 mnCategType( EXC_CHSERIES_NUMERIC
),
249 mnValueType( EXC_CHSERIES_NUMERIC
),
250 mnBubbleType( EXC_CHSERIES_NUMERIC
),
257 // Chart type groups ==========================================================
259 XclChType::XclChType() :
265 mnBubbleType( EXC_CHSCATTER_AREA
),
270 // ----------------------------------------------------------------------------
272 XclChChart3d::XclChChart3d() :
279 mnFlags( EXC_CHCHART3D_AUTOHEIGHT
)
283 // ----------------------------------------------------------------------------
285 XclChLegend::XclChLegend() :
286 mnDockMode( EXC_CHLEGEND_RIGHT
),
287 mnSpacing( EXC_CHLEGEND_MEDIUM
),
288 mnFlags( EXC_CHLEGEND_DOCKED
| EXC_CHLEGEND_AUTOSERIES
|
289 EXC_CHLEGEND_AUTOPOSX
| EXC_CHLEGEND_AUTOPOSY
| EXC_CHLEGEND_STACKED
)
293 // ----------------------------------------------------------------------------
295 XclChTypeGroup::XclChTypeGroup() :
297 mnGroupIdx( EXC_CHSERGROUP_NONE
)
301 // ----------------------------------------------------------------------------
303 XclChProperties::XclChProperties() :
305 mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP
)
309 // Axes =======================================================================
311 XclChLabelRange::XclChLabelRange() :
319 // ----------------------------------------------------------------------------
321 XclChDateRange::XclChDateRange() :
325 mnMajorUnit( EXC_CHDATERANGE_DAYS
),
327 mnMinorUnit( EXC_CHDATERANGE_DAYS
),
328 mnBaseUnit( EXC_CHDATERANGE_DAYS
),
330 mnFlags( EXC_CHDATERANGE_AUTOMIN
| EXC_CHDATERANGE_AUTOMAX
|
331 EXC_CHDATERANGE_AUTOMAJOR
| EXC_CHDATERANGE_AUTOMINOR
|
332 EXC_CHDATERANGE_AUTOBASE
| EXC_CHDATERANGE_AUTOCROSS
|
333 EXC_CHDATERANGE_AUTODATE
)
337 // ----------------------------------------------------------------------------
339 XclChValueRange::XclChValueRange() :
345 mnFlags( EXC_CHVALUERANGE_AUTOMIN
| EXC_CHVALUERANGE_AUTOMAX
|
346 EXC_CHVALUERANGE_AUTOMAJOR
| EXC_CHVALUERANGE_AUTOMINOR
|
347 EXC_CHVALUERANGE_AUTOCROSS
| EXC_CHVALUERANGE_BIT8
)
351 // ----------------------------------------------------------------------------
353 XclChTick::XclChTick() :
354 maTextColor( COL_BLACK
),
355 mnMajor( EXC_CHTICK_INSIDE
| EXC_CHTICK_OUTSIDE
),
357 mnLabelPos( EXC_CHTICK_NEXT
),
358 mnBackMode( EXC_CHTICK_TRANSPARENT
),
359 mnFlags( EXC_CHTICK_AUTOCOLOR
| EXC_CHTICK_AUTOROT
),
360 mnRotation( EXC_ROT_NONE
)
364 // ----------------------------------------------------------------------------
366 XclChAxis::XclChAxis() :
367 mnType( EXC_CHAXIS_NONE
)
371 sal_Int32
XclChAxis::GetApiAxisDimension() const
373 sal_Int32 nApiAxisDim
= EXC_CHART_AXIS_NONE
;
376 case EXC_CHAXIS_X
: nApiAxisDim
= EXC_CHART_AXIS_X
; break;
377 case EXC_CHAXIS_Y
: nApiAxisDim
= EXC_CHART_AXIS_Y
; break;
378 case EXC_CHAXIS_Z
: nApiAxisDim
= EXC_CHART_AXIS_Z
; break;
383 // ----------------------------------------------------------------------------
385 XclChAxesSet::XclChAxesSet() :
386 mnAxesSetId( EXC_CHAXESSET_PRIMARY
)
390 sal_Int32
XclChAxesSet::GetApiAxesSetIndex() const
392 sal_Int32 nApiAxesSetIdx
= EXC_CHART_AXESSET_NONE
;
393 switch( mnAxesSetId
)
395 case EXC_CHAXESSET_PRIMARY
: nApiAxesSetIdx
= EXC_CHART_AXESSET_PRIMARY
; break;
396 case EXC_CHAXESSET_SECONDARY
: nApiAxesSetIdx
= EXC_CHART_AXESSET_SECONDARY
; break;
398 return nApiAxesSetIdx
;
401 // Static helper functions ====================================================
403 sal_uInt16
XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx
)
405 static const sal_uInt16 spnLineColors
[] =
407 32, 33, 34, 35, 36, 37, 38, 39,
408 40, 41, 42, 43, 44, 45, 46, 47,
409 48, 49, 50, 51, 52, 53, 54, 55,
410 56, 57, 58, 59, 60, 61, 62, 8,
411 9, 10, 11, 12, 13, 14, 15, 16,
412 17, 18, 19, 20, 21, 22, 23, 24,
413 25, 26, 27, 28, 29, 30, 31, 63
415 return spnLineColors
[ nFormatIdx
% SAL_N_ELEMENTS( spnLineColors
) ];
418 sal_uInt16
XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx
)
420 static const sal_uInt16 spnFillColors
[] =
422 24, 25, 26, 27, 28, 29, 30, 31,
423 32, 33, 34, 35, 36, 37, 38, 39,
424 40, 41, 42, 43, 44, 45, 46, 47,
425 48, 49, 50, 51, 52, 53, 54, 55,
426 56, 57, 58, 59, 60, 61, 62, 63,
427 8, 9, 10, 11, 12, 13, 14, 15,
428 16, 17, 18, 19, 20, 21, 22, 23
430 return spnFillColors
[ nFormatIdx
% SAL_N_ELEMENTS( spnFillColors
) ];
433 sal_uInt8
XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx
)
435 static const sal_uInt8 spnTrans
[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
436 return spnTrans
[ (nFormatIdx
/ 56) % SAL_N_ELEMENTS( spnTrans
) ];
439 sal_uInt16
XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx
)
441 static const sal_uInt16 spnSymbols
[] = {
442 EXC_CHMARKERFORMAT_DIAMOND
, EXC_CHMARKERFORMAT_SQUARE
, EXC_CHMARKERFORMAT_TRIANGLE
,
443 EXC_CHMARKERFORMAT_CROSS
, EXC_CHMARKERFORMAT_STAR
, EXC_CHMARKERFORMAT_CIRCLE
,
444 EXC_CHMARKERFORMAT_PLUS
, EXC_CHMARKERFORMAT_DOWJ
, EXC_CHMARKERFORMAT_STDDEV
};
445 return spnSymbols
[ nFormatIdx
% SAL_N_ELEMENTS( spnSymbols
) ];
448 bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType
)
450 static const bool spbFilled
[] = {
451 false, true, true, true, false, false, false, false, true, false };
452 return (nMarkerType
< SAL_N_ELEMENTS( spbFilled
)) && spbFilled
[ nMarkerType
];
455 OUString
XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType
)
459 case EXC_CHSERERR_XPLUS
: return OUString( EXC_CHPROP_ROLE_ERRORBARS_POSX
);
460 case EXC_CHSERERR_XMINUS
: return OUString( EXC_CHPROP_ROLE_ERRORBARS_NEGX
);
461 case EXC_CHSERERR_YPLUS
: return OUString( EXC_CHPROP_ROLE_ERRORBARS_POSY
);
462 case EXC_CHSERERR_YMINUS
: return OUString( EXC_CHPROP_ROLE_ERRORBARS_NEGY
);
463 default: OSL_FAIL( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
468 // Chart formatting info provider =============================================
472 static const XclChFormatInfo spFmtInfos
[] =
474 // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
475 { EXC_CHOBJTYPE_BACKGROUND
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, true, true, true },
476 { EXC_CHOBJTYPE_PLOTFRAME
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, true, true, true },
477 { EXC_CHOBJTYPE_WALL3D
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, true, false, true },
478 { EXC_CHOBJTYPE_FLOOR3D
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, 23, EXC_CHFRAMETYPE_AUTO
, true, false, true },
479 { EXC_CHOBJTYPE_TEXT
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, true, true },
480 { EXC_CHOBJTYPE_LEGEND
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, true, true, true },
481 { EXC_CHOBJTYPE_LINEARSERIES
, EXC_CHPROPMODE_LINEARSERIES
, 0xFFFF, EXC_CHLINEFORMAT_SINGLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, false, false, false },
482 { EXC_CHOBJTYPE_FILLEDSERIES
, EXC_CHPROPMODE_FILLEDSERIES
, EXC_COLOR_CHBORDERAUTO
, EXC_CHLINEFORMAT_SINGLE
, 0xFFFF, EXC_CHFRAMETYPE_AUTO
, false, false, true },
483 { EXC_CHOBJTYPE_AXISLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, false, false, false },
484 { EXC_CHOBJTYPE_GRIDLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, true, false },
485 { EXC_CHOBJTYPE_TRENDLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_DOUBLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
486 { EXC_CHOBJTYPE_ERRORBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_SINGLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
487 { EXC_CHOBJTYPE_CONNECTLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
488 { EXC_CHOBJTYPE_HILOLINE
, EXC_CHPROPMODE_LINEARSERIES
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
489 { EXC_CHOBJTYPE_WHITEDROPBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, true },
490 { EXC_CHOBJTYPE_BLACKDROPBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, true }
495 // ----------------------------------------------------------------------------
497 XclChFormatInfoProvider::XclChFormatInfoProvider()
499 const XclChFormatInfo
* pEnd
= STATIC_ARRAY_END( spFmtInfos
);
500 for( const XclChFormatInfo
* pIt
= spFmtInfos
; pIt
!= pEnd
; ++pIt
)
501 maInfoMap
[ pIt
->meObjType
] = pIt
;
504 const XclChFormatInfo
& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType
) const
506 XclFmtInfoMap::const_iterator aIt
= maInfoMap
.find( eObjType
);
507 OSL_ENSURE( aIt
!= maInfoMap
.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
508 return (aIt
== maInfoMap
.end()) ? *spFmtInfos
: *aIt
->second
;
511 // Chart type info provider ===================================================
515 // chart type service names
516 const sal_Char SERVICE_CHART2_AREA
[] = "com.sun.star.chart2.AreaChartType";
517 const sal_Char SERVICE_CHART2_CANDLE
[] = "com.sun.star.chart2.CandleStickChartType";
518 const sal_Char SERVICE_CHART2_COLUMN
[] = "com.sun.star.chart2.ColumnChartType";
519 const sal_Char SERVICE_CHART2_LINE
[] = "com.sun.star.chart2.LineChartType";
520 const sal_Char SERVICE_CHART2_NET
[] = "com.sun.star.chart2.NetChartType";
521 const sal_Char SERVICE_CHART2_FILLEDNET
[] = "com.sun.star.chart2.FilledNetChartType";
522 const sal_Char SERVICE_CHART2_PIE
[] = "com.sun.star.chart2.PieChartType";
523 const sal_Char SERVICE_CHART2_SCATTER
[] = "com.sun.star.chart2.ScatterChartType";
524 const sal_Char SERVICE_CHART2_BUBBLE
[] = "com.sun.star.chart2.BubbleChartType";
525 const sal_Char SERVICE_CHART2_SURFACE
[] = "com.sun.star.chart2.ColumnChartType"; // Todo
527 namespace csscd
= cssc::DataLabelPlacement
;
529 static const XclChTypeInfo spTypeInfos
[] =
531 // chart type chart type category record id service varied point color def label pos comb2d 3d polar area2d area3d 1stvis xcateg swap stack revers betw
532 { EXC_CHTYPEID_BAR
, EXC_CHTYPECATEG_BAR
, EXC_ID_CHBAR
, SERVICE_CHART2_COLUMN
, EXC_CHVARPOINT_SINGLE
, csscd::OUTSIDE
, true, true, false, true, true, false, true, false, true, false, true },
533 { EXC_CHTYPEID_HORBAR
, EXC_CHTYPECATEG_BAR
, EXC_ID_CHBAR
, SERVICE_CHART2_COLUMN
, EXC_CHVARPOINT_SINGLE
, csscd::OUTSIDE
, false, true, false, true, true, false, true, true, true, false, true },
534 { EXC_CHTYPEID_LINE
, EXC_CHTYPECATEG_LINE
, EXC_ID_CHLINE
, SERVICE_CHART2_LINE
, EXC_CHVARPOINT_SINGLE
, csscd::RIGHT
, true, true, false, false, true, false, true, false, true, false, false },
535 { EXC_CHTYPEID_AREA
, EXC_CHTYPECATEG_LINE
, EXC_ID_CHAREA
, SERVICE_CHART2_AREA
, EXC_CHVARPOINT_NONE
, csscd::CENTER
, true, true, false, true, true, false, true, false, true, true, false },
536 { EXC_CHTYPEID_STOCK
, EXC_CHTYPECATEG_LINE
, EXC_ID_CHLINE
, SERVICE_CHART2_CANDLE
, EXC_CHVARPOINT_NONE
, csscd::RIGHT
, true, false, false, false, false, false, true, false, true, false, false },
537 { EXC_CHTYPEID_RADARLINE
, EXC_CHTYPECATEG_RADAR
, EXC_ID_CHRADARLINE
, SERVICE_CHART2_NET
, EXC_CHVARPOINT_SINGLE
, csscd::TOP
, false, false, true, false, true, false, true, false, false, false, false },
538 { EXC_CHTYPEID_RADARAREA
, EXC_CHTYPECATEG_RADAR
, EXC_ID_CHRADARAREA
, SERVICE_CHART2_FILLEDNET
, EXC_CHVARPOINT_NONE
, csscd::TOP
, false, false, true, true, true, false, true, false, false, true, false },
539 { EXC_CHTYPEID_PIE
, EXC_CHTYPECATEG_PIE
, EXC_ID_CHPIE
, SERVICE_CHART2_PIE
, EXC_CHVARPOINT_MULTI
, csscd::AVOID_OVERLAP
, false, true, true, true, true, true, true, false, false, false, false },
540 { EXC_CHTYPEID_DONUT
, EXC_CHTYPECATEG_PIE
, EXC_ID_CHPIE
, SERVICE_CHART2_PIE
, EXC_CHVARPOINT_MULTI
, csscd::AVOID_OVERLAP
, false, true, true, true, true, false, true, false, false, false, false },
541 { EXC_CHTYPEID_PIEEXT
, EXC_CHTYPECATEG_PIE
, EXC_ID_CHPIEEXT
, SERVICE_CHART2_PIE
, EXC_CHVARPOINT_MULTI
, csscd::AVOID_OVERLAP
, false, false, true, true, true, true, true, false, false, false, false },
542 { EXC_CHTYPEID_SCATTER
, EXC_CHTYPECATEG_SCATTER
, EXC_ID_CHSCATTER
, SERVICE_CHART2_SCATTER
, EXC_CHVARPOINT_SINGLE
, csscd::RIGHT
, true, false, false, false, true, false, false, false, false, false, false },
543 { EXC_CHTYPEID_BUBBLES
, EXC_CHTYPECATEG_SCATTER
, EXC_ID_CHSCATTER
, SERVICE_CHART2_BUBBLE
, EXC_CHVARPOINT_SINGLE
, csscd::RIGHT
, false, false, false, true, true, false, false, false, false, false, false },
544 { EXC_CHTYPEID_SURFACE
, EXC_CHTYPECATEG_SURFACE
, EXC_ID_CHSURFACE
, SERVICE_CHART2_SURFACE
, EXC_CHVARPOINT_NONE
, csscd::RIGHT
, false, true, false, true, true, false, true, false, false, false, false },
545 { EXC_CHTYPEID_UNKNOWN
, EXC_CHTYPECATEG_BAR
, EXC_ID_CHBAR
, SERVICE_CHART2_COLUMN
, EXC_CHVARPOINT_SINGLE
, csscd::OUTSIDE
, true, true, false, true, true, false, true, false, true, false, true }
550 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo
& rTypeInfo
) :
551 XclChTypeInfo( rTypeInfo
),
557 void XclChExtTypeInfo::Set( const XclChTypeInfo
& rTypeInfo
, bool b3dChart
, bool bSpline
)
559 static_cast< XclChTypeInfo
& >( *this ) = rTypeInfo
;
560 mb3dChart
= mbSupports3d
&& b3dChart
;
564 // ----------------------------------------------------------------------------
566 XclChTypeInfoProvider::XclChTypeInfoProvider()
568 const XclChTypeInfo
* pEnd
= STATIC_ARRAY_END( spTypeInfos
);
569 for( const XclChTypeInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
570 maInfoMap
[ pIt
->meTypeId
] = pIt
;
573 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId
) const
575 XclChTypeInfoMap::const_iterator aIt
= maInfoMap
.find( eTypeId
);
576 OSL_ENSURE( aIt
!= maInfoMap
.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
577 return (aIt
== maInfoMap
.end()) ? *maInfoMap
.rbegin()->second
: *aIt
->second
;
580 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId
) const
582 const XclChTypeInfo
* pEnd
= STATIC_ARRAY_END( spTypeInfos
);
583 for( const XclChTypeInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
584 if( pIt
->mnRecId
== nRecId
)
586 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
587 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
590 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString
& rServiceName
) const
592 const XclChTypeInfo
* pEnd
= STATIC_ARRAY_END( spTypeInfos
);
593 for( const XclChTypeInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
594 if( rServiceName
.equalsAscii( pIt
->mpcServiceName
) )
596 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
597 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
600 // Property helpers ===========================================================
602 XclChObjectTable::XclChObjectTable( Reference
< XMultiServiceFactory
> xFactory
,
603 const OUString
& rServiceName
, const OUString
& rObjNameBase
) :
604 mxFactory( xFactory
),
605 maServiceName( rServiceName
),
606 maObjNameBase( rObjNameBase
),
611 Any
XclChObjectTable::GetObject( const OUString
& rObjName
)
614 if( !mxContainer
.is() )
615 mxContainer
.set( ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), UNO_QUERY
);
616 OSL_ENSURE( mxContainer
.is(), "XclChObjectTable::GetObject - container not found" );
619 if( mxContainer
.is() )
621 // get object from container
624 aObj
= mxContainer
->getByName( rObjName
);
628 OSL_FAIL( "XclChObjectTable::GetObject - object not found" );
634 OUString
XclChObjectTable::InsertObject( const Any
& rObj
)
637 // create object table
638 if( !mxContainer
.is() )
639 mxContainer
.set( ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), UNO_QUERY
);
640 OSL_ENSURE( mxContainer
.is(), "XclChObjectTable::InsertObject - container not found" );
643 if( mxContainer
.is() )
645 // create new unused identifier
648 aObjName
= maObjNameBase
+ OUString::valueOf( ++mnIndex
);
650 while( mxContainer
->hasByName( aObjName
) );
655 mxContainer
->insertByName( aObjName
, rObj
);
659 OSL_FAIL( "XclChObjectTable::InsertObject - cannot insert object" );
660 aObjName
= OUString();
666 // Property names -------------------------------------------------------------
670 /** Property names for line style in common objects. */
671 const sal_Char
* const sppcLineNamesCommon
[] =
672 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", 0 };
673 /** Property names for line style in linear series objects. */
674 const sal_Char
* const sppcLineNamesLinear
[] =
675 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", 0 };
676 /** Property names for line style in filled series objects. */
677 const sal_Char
* const sppcLineNamesFilled
[] =
678 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", 0 };
680 /** Property names for solid area style in common objects. */
681 const sal_Char
* const sppcAreaNamesCommon
[] = { "FillStyle", "FillColor", "FillTransparence", 0 };
682 /** Property names for solid area style in filled series objects. */
683 const sal_Char
* const sppcAreaNamesFilled
[] = { "FillStyle", "Color", "Transparency", 0 };
684 /** Property names for gradient area style in common objects. */
685 const sal_Char
* const sppcGradNamesCommon
[] = { "FillStyle", "FillGradientName", 0 };
686 /** Property names for gradient area style in filled series objects. */
687 const sal_Char
* const sppcGradNamesFilled
[] = { "FillStyle", "GradientName", 0 };
688 /** Property names for hatch area style in common objects. */
689 const sal_Char
* const sppcHatchNamesCommon
[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", 0 };
690 /** Property names for hatch area style in filled series objects. */
691 const sal_Char
* const sppcHatchNamesFilled
[] = { "FillStyle", "HatchName", "Color", "FillBackground", 0 };
692 /** Property names for bitmap area style. */
693 const sal_Char
* const sppcBitmapNames
[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 };
697 // ----------------------------------------------------------------------------
699 XclChPropSetHelper::XclChPropSetHelper() :
700 maLineHlpCommon( sppcLineNamesCommon
),
701 maLineHlpLinear( sppcLineNamesLinear
),
702 maLineHlpFilled( sppcLineNamesFilled
),
703 maAreaHlpCommon( sppcAreaNamesCommon
),
704 maAreaHlpFilled( sppcAreaNamesFilled
),
705 maGradHlpCommon( sppcGradNamesCommon
),
706 maGradHlpFilled( sppcGradNamesFilled
),
707 maHatchHlpCommon( sppcHatchNamesCommon
),
708 maHatchHlpFilled( sppcHatchNamesFilled
),
709 maBitmapHlp( sppcBitmapNames
)
713 // read properties ------------------------------------------------------------
715 void XclChPropSetHelper::ReadLineProperties(
716 XclChLineFormat
& rLineFmt
, XclChObjectTable
& rDashTable
,
717 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
719 namespace cssd
= ::com::sun::star::drawing
;
721 // read properties from property set
722 cssd::LineStyle eApiStyle
= cssd::LineStyle_NONE
;
723 sal_Int32 nApiWidth
= 0;
724 sal_Int16 nApiTrans
= 0;
727 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
728 rLineHlp
.ReadFromPropertySet( rPropSet
);
729 rLineHlp
>> eApiStyle
>> nApiWidth
>> rLineFmt
.maColor
>> nApiTrans
>> aDashNameAny
;
731 // clear automatic flag
732 ::set_flag( rLineFmt
.mnFlags
, EXC_CHLINEFORMAT_AUTO
, false );
735 if( nApiWidth
<= 0 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_HAIR
;
736 else if( nApiWidth
<= 35 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_SINGLE
;
737 else if( nApiWidth
<= 70 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_DOUBLE
;
738 else rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_TRIPLE
;
743 case cssd::LineStyle_NONE
:
744 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
746 case cssd::LineStyle_SOLID
:
748 if( nApiTrans
< 13 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
749 else if( nApiTrans
< 38 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DARKTRANS
;
750 else if( nApiTrans
< 63 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_MEDTRANS
;
751 else if( nApiTrans
< 100 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_LIGHTTRANS
;
752 else rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
755 case cssd::LineStyle_DASH
:
757 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
759 cssd::LineDash aApiDash
;
760 if( (aDashNameAny
>>= aDashName
) && (rDashTable
.GetObject( aDashName
) >>= aApiDash
) )
762 // reorder dashes that are shorter than dots
763 if( (aApiDash
.Dashes
== 0) || (aApiDash
.DashLen
< aApiDash
.DotLen
) )
765 ::std::swap( aApiDash
.Dashes
, aApiDash
.Dots
);
766 ::std::swap( aApiDash
.DashLen
, aApiDash
.DotLen
);
768 // ignore dots that are nearly equal to dashes
769 if( aApiDash
.DotLen
* 3 > aApiDash
.DashLen
* 2 )
772 // convert line dash to predefined Excel dash types
773 if( (aApiDash
.Dashes
== 1) && (aApiDash
.Dots
>= 1) )
774 // one dash and one or more dots
775 rLineFmt
.mnPattern
= (aApiDash
.Dots
== 1) ?
776 EXC_CHLINEFORMAT_DASHDOT
: EXC_CHLINEFORMAT_DASHDOTDOT
;
777 else if( aApiDash
.Dashes
>= 1 )
778 // one or more dashes and no dots (also: dash-dash-dot)
779 rLineFmt
.mnPattern
= (aApiDash
.DashLen
< 250) ?
780 EXC_CHLINEFORMAT_DOT
: EXC_CHLINEFORMAT_DASH
;
785 OSL_FAIL( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
786 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
790 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat
& rAreaFmt
,
791 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
793 namespace cssd
= ::com::sun::star::drawing
;
795 // read properties from property set
796 cssd::FillStyle eApiStyle
= cssd::FillStyle_NONE
;
797 sal_Int16 nTransparency
= 0;
799 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
800 rAreaHlp
.ReadFromPropertySet( rPropSet
);
801 rAreaHlp
>> eApiStyle
>> rAreaFmt
.maPattColor
>> nTransparency
;
803 // clear automatic flag
804 ::set_flag( rAreaFmt
.mnFlags
, EXC_CHAREAFORMAT_AUTO
, false );
806 // set fill style transparent or solid (set solid for anything but transparent)
807 rAreaFmt
.mnPattern
= (eApiStyle
== cssd::FillStyle_NONE
) ? EXC_PATT_NONE
: EXC_PATT_SOLID
;
809 // return true to indicate complex fill (gradient, bitmap, solid transparency)
810 return (eApiStyle
!= cssd::FillStyle_NONE
) && ((eApiStyle
!= cssd::FillStyle_SOLID
) || (nTransparency
> 0));
813 void XclChPropSetHelper::ReadEscherProperties(
814 XclChEscherFormat
& rEscherFmt
, XclChPicFormat
& rPicFmt
,
815 XclChObjectTable
& rGradientTable
, XclChObjectTable
& rHatchTable
, XclChObjectTable
& rBitmapTable
,
816 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
818 namespace cssd
= ::com::sun::star::drawing
;
819 namespace cssa
= ::com::sun::star::awt
;
821 // read style and transparency properties from property set
822 cssd::FillStyle eApiStyle
= cssd::FillStyle_NONE
;
824 sal_Int16 nTransparency
= 0;
826 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
827 rAreaHlp
.ReadFromPropertySet( rPropSet
);
828 rAreaHlp
>> eApiStyle
>> aColor
>> nTransparency
;
832 case cssd::FillStyle_SOLID
:
834 OSL_ENSURE( nTransparency
> 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
835 if( (0 < nTransparency
) && (nTransparency
<= 100) )
837 // convert to Escher properties
838 sal_uInt32 nEscherColor
= 0x02000000;
839 ::insert_value( nEscherColor
, aColor
.GetBlue(), 16, 8 );
840 ::insert_value( nEscherColor
, aColor
.GetGreen(), 8, 8 );
841 ::insert_value( nEscherColor
, aColor
.GetRed(), 0, 8 );
842 sal_uInt32 nEscherOpacity
= static_cast< sal_uInt32
>( (100 - nTransparency
) * 655.36 );
843 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
844 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillType
, ESCHER_FillSolid
);
845 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillColor
, nEscherColor
);
846 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillOpacity
, nEscherOpacity
);
847 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackColor
, 0x02FFFFFF );
848 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackOpacity
, 0x00010000 );
849 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x001F001C );
853 case cssd::FillStyle_GRADIENT
:
855 // extract gradient from global gradient table
856 OUString aGradientName
;
857 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
858 rGradHlp
.ReadFromPropertySet( rPropSet
);
859 rGradHlp
>> eApiStyle
>> aGradientName
;
860 cssa::Gradient aGradient
;
861 if( rGradientTable
.GetObject( aGradientName
) >>= aGradient
)
863 // convert to Escher properties
864 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
865 rEscherFmt
.mxEscherSet
->CreateGradientProperties( aGradient
);
869 case cssd::FillStyle_HATCH
:
871 // extract hatch from global hatch table
873 bool bFillBackground
;
874 ScfPropSetHelper
& rHatchHlp
= GetHatchHelper( ePropMode
);
875 rHatchHlp
.ReadFromPropertySet( rPropSet
);
876 rHatchHlp
>> eApiStyle
>> aHatchName
>> aColor
>> bFillBackground
;
878 if( rHatchTable
.GetObject( aHatchName
) >>= aHatch
)
880 // convert to Escher properties
881 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
882 rEscherFmt
.mxEscherSet
->CreateEmbeddedHatchProperties( aHatch
, aColor
, bFillBackground
);
883 rPicFmt
.mnBmpMode
= EXC_CHPICFORMAT_STACK
;
887 case cssd::FillStyle_BITMAP
:
889 // extract bitmap URL from global bitmap table
890 OUString aBitmapName
;
891 cssd::BitmapMode eApiBmpMode
;
892 maBitmapHlp
.ReadFromPropertySet( rPropSet
);
893 maBitmapHlp
>> eApiStyle
>> aBitmapName
>> eApiBmpMode
;
895 if( rBitmapTable
.GetObject( aBitmapName
) >>= aBitmapUrl
)
897 // convert to Escher properties
898 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
899 rEscherFmt
.mxEscherSet
->CreateEmbeddedBitmapProperties( aBitmapUrl
, eApiBmpMode
);
900 rPicFmt
.mnBmpMode
= (eApiBmpMode
== cssd::BitmapMode_REPEAT
) ?
901 EXC_CHPICFORMAT_STACK
: EXC_CHPICFORMAT_STRETCH
;
906 OSL_FAIL( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
910 void XclChPropSetHelper::ReadMarkerProperties(
911 XclChMarkerFormat
& rMarkerFmt
, const ScfPropertySet
& rPropSet
, sal_uInt16 nFormatIdx
)
913 namespace cssc
= ::com::sun::star::chart2
;
914 namespace cssa
= ::com::sun::star::awt
;
915 cssc::Symbol aApiSymbol
;
916 if( rPropSet
.GetProperty( aApiSymbol
, EXC_CHPROP_SYMBOL
) )
918 // clear automatic flag
919 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_AUTO
, false );
922 switch( aApiSymbol
.Style
)
924 case cssc::SymbolStyle_NONE
:
925 rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_NOSYMBOL
;
927 case cssc::SymbolStyle_STANDARD
:
928 switch( aApiSymbol
.StandardSymbol
)
930 case 0: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_SQUARE
; break; // square
931 case 1: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DIAMOND
; break; // diamond
932 case 2: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STDDEV
; break; // arrow down
933 case 3: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_TRIANGLE
; break; // arrow up
934 case 4: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DOWJ
; break; // arrow right, same as import
935 case 5: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_PLUS
; break; // arrow left
936 case 6: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CROSS
; break; // bow tie
937 case 7: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // sand glass
938 case 8: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CIRCLE
; break; // circle new in LibO3.5
939 case 9: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DIAMOND
; break; // star new in LibO3.5
940 case 10: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CROSS
; break; // X new in LibO3.5
941 case 11: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_PLUS
; break; // plus new in LibO3.5
942 case 12: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // asterisk new in LibO3.5
943 case 13: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STDDEV
; break; // horizontal bar new in LibO3.5
944 case 14: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // vertical bar new in LibO3.5
945 default: rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
949 rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
951 bool bHasFillColor
= XclChartHelper::HasMarkerFillColor( rMarkerFmt
.mnMarkerType
);
952 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOFILL
, !bHasFillColor
);
955 sal_Int32 nApiSize
= (aApiSymbol
.Size
.Width
+ aApiSymbol
.Size
.Height
+ 1) / 2;
956 rMarkerFmt
.mnMarkerSize
= XclTools::GetTwipsFromHmm( nApiSize
);
959 rMarkerFmt
.maLineColor
= ScfApiHelper::ConvertFromApiColor( aApiSymbol
.BorderColor
);
960 rMarkerFmt
.maFillColor
= ScfApiHelper::ConvertFromApiColor( aApiSymbol
.FillColor
);
964 sal_uInt16
XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet
& rPropSet
, bool bSupportsStacked
)
966 // chart2 handles rotation as double in the range [0,360)
968 rPropSet
.GetProperty( fAngle
, EXC_CHPROP_TEXTROTATION
);
969 bool bStacked
= bSupportsStacked
&& rPropSet
.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS
);
970 return bStacked
? EXC_ROT_STACKED
:
971 XclTools::GetXclRotation( static_cast< sal_Int32
>( fAngle
* 100.0 + 0.5 ) );
974 // write properties -----------------------------------------------------------
976 void XclChPropSetHelper::WriteLineProperties(
977 ScfPropertySet
& rPropSet
, XclChObjectTable
& rDashTable
,
978 const XclChLineFormat
& rLineFmt
, XclChPropertyMode ePropMode
)
980 namespace cssd
= ::com::sun::star::drawing
;
983 sal_Int32 nApiWidth
= 0; // 0 is the width of a hair line
984 switch( rLineFmt
.mnWeight
)
986 case EXC_CHLINEFORMAT_SINGLE
: nApiWidth
= 35; break;
987 case EXC_CHLINEFORMAT_DOUBLE
: nApiWidth
= 70; break;
988 case EXC_CHLINEFORMAT_TRIPLE
: nApiWidth
= 105; break;
992 cssd::LineStyle eApiStyle
= cssd::LineStyle_NONE
;
993 sal_Int16 nApiTrans
= 0;
994 sal_Int32 nDotLen
= ::std::min
< sal_Int32
>( rLineFmt
.mnWeight
+ 105, 210 );
995 cssd::LineDash
aApiDash( cssd::DashStyle_RECT
, 0, nDotLen
, 0, 4 * nDotLen
, nDotLen
);
997 switch( rLineFmt
.mnPattern
)
999 case EXC_CHLINEFORMAT_SOLID
:
1000 eApiStyle
= cssd::LineStyle_SOLID
;
1002 case EXC_CHLINEFORMAT_DARKTRANS
:
1003 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 25;
1005 case EXC_CHLINEFORMAT_MEDTRANS
:
1006 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 50;
1008 case EXC_CHLINEFORMAT_LIGHTTRANS
:
1009 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 75;
1011 case EXC_CHLINEFORMAT_DASH
:
1012 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= 1;
1014 case EXC_CHLINEFORMAT_DOT
:
1015 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dots
= 1;
1017 case EXC_CHLINEFORMAT_DASHDOT
:
1018 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= aApiDash
.Dots
= 1;
1020 case EXC_CHLINEFORMAT_DASHDOTDOT
:
1021 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= 1; aApiDash
.Dots
= 2;
1026 sal_Int32 nApiColor
= ScfApiHelper::ConvertToApiColor( rLineFmt
.maColor
);
1028 // try to insert the dash style and receive its name
1030 if( eApiStyle
== cssd::LineStyle_DASH
)
1032 OUString aDashName
= rDashTable
.InsertObject( ::com::sun::star::uno::makeAny( aApiDash
) );
1033 if( !aDashName
.isEmpty() )
1034 aDashNameAny
<<= aDashName
;
1037 // write the properties
1038 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
1039 rLineHlp
.InitializeWrite();
1040 rLineHlp
<< eApiStyle
<< nApiWidth
<< nApiColor
<< nApiTrans
<< aDashNameAny
;
1041 rLineHlp
.WriteToPropertySet( rPropSet
);
1044 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet
& rPropSet
,
1045 const XclChAreaFormat
& rAreaFmt
, XclChPropertyMode ePropMode
)
1047 namespace cssd
= ::com::sun::star::drawing
;
1048 cssd::FillStyle eFillStyle
= cssd::FillStyle_NONE
;
1050 sal_Int16 nTransparency
= 0;
1053 if( rAreaFmt
.mnPattern
!= EXC_PATT_NONE
)
1055 eFillStyle
= cssd::FillStyle_SOLID
;
1056 aColor
= XclTools::GetPatternColor( rAreaFmt
.maPattColor
, rAreaFmt
.maBackColor
, rAreaFmt
.mnPattern
);
1059 // write the properties
1060 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
1061 rAreaHlp
.InitializeWrite();
1062 rAreaHlp
<< eFillStyle
<< aColor
<< nTransparency
;
1063 rAreaHlp
.WriteToPropertySet( rPropSet
);
1066 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet
& rPropSet
,
1067 XclChObjectTable
& rGradientTable
, XclChObjectTable
& /*rHatchTable*/, XclChObjectTable
& rBitmapTable
,
1068 const XclChEscherFormat
& rEscherFmt
, const XclChPicFormat
* pPicFmt
,
1069 sal_uInt32 nDffFillType
, XclChPropertyMode ePropMode
)
1071 if( rEscherFmt
.mxItemSet
)
1073 if( const XFillStyleItem
* pStyleItem
= static_cast< const XFillStyleItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLSTYLE
, false ) ) )
1075 switch( pStyleItem
->GetValue() )
1078 // #i84812# Excel 2007 writes Escher properties for solid fill
1079 if( const XFillColorItem
* pColorItem
= static_cast< const XFillColorItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLCOLOR
, false ) ) )
1081 namespace cssd
= ::com::sun::star::drawing
;
1082 // get solid transparence too
1083 const XFillTransparenceItem
* pTranspItem
= static_cast< const XFillTransparenceItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLTRANSPARENCE
, false ) );
1084 sal_uInt16 nTransp
= pTranspItem
? pTranspItem
->GetValue() : 0;
1085 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
1086 rAreaHlp
.InitializeWrite();
1087 rAreaHlp
<< cssd::FillStyle_SOLID
<< pColorItem
->GetColorValue() << static_cast< sal_Int16
>( nTransp
);
1088 rAreaHlp
.WriteToPropertySet( rPropSet
);
1091 case XFILL_GRADIENT
:
1092 if( const XFillGradientItem
* pGradItem
= static_cast< const XFillGradientItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLGRADIENT
, false ) ) )
1095 if( pGradItem
->QueryValue( aGradientAny
, MID_FILLGRADIENT
) )
1097 OUString aGradName
= rGradientTable
.InsertObject( aGradientAny
);
1098 if( !aGradName
.isEmpty() )
1100 namespace cssd
= ::com::sun::star::drawing
;
1101 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
1102 rGradHlp
.InitializeWrite();
1103 rGradHlp
<< cssd::FillStyle_GRADIENT
<< aGradName
;
1104 rGradHlp
.WriteToPropertySet( rPropSet
);
1110 if( const XFillBitmapItem
* pBmpItem
= static_cast< const XFillBitmapItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLBITMAP
, false ) ) )
1113 if( pBmpItem
->QueryValue( aBitmapAny
, MID_GRAFURL
) )
1115 OUString aBmpName
= rBitmapTable
.InsertObject( aBitmapAny
);
1116 if( !aBmpName
.isEmpty() )
1118 namespace cssd
= ::com::sun::star::drawing
;
1119 /* #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode.
1120 If not passed, detect fill mode from the DFF property 'fill-type'. */
1121 bool bStretch
= pPicFmt
? (pPicFmt
->mnBmpMode
== EXC_CHPICFORMAT_STRETCH
) : (nDffFillType
== mso_fillPicture
);
1122 cssd::BitmapMode eApiBmpMode
= bStretch
? cssd::BitmapMode_STRETCH
: cssd::BitmapMode_REPEAT
;
1123 maBitmapHlp
.InitializeWrite();
1124 maBitmapHlp
<< cssd::FillStyle_BITMAP
<< aBmpName
<< eApiBmpMode
;
1125 maBitmapHlp
.WriteToPropertySet( rPropSet
);
1131 OSL_FAIL( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1137 void XclChPropSetHelper::WriteMarkerProperties(
1138 ScfPropertySet
& rPropSet
, const XclChMarkerFormat
& rMarkerFmt
)
1140 namespace cssc
= ::com::sun::star::chart2
;
1141 namespace cssa
= ::com::sun::star::awt
;
1144 cssc::Symbol aApiSymbol
;
1145 aApiSymbol
.Style
= cssc::SymbolStyle_STANDARD
;
1146 switch( rMarkerFmt
.mnMarkerType
)
1148 case EXC_CHMARKERFORMAT_NOSYMBOL
: aApiSymbol
.Style
= cssc::SymbolStyle_NONE
; break;
1149 case EXC_CHMARKERFORMAT_SQUARE
: aApiSymbol
.StandardSymbol
= 0; break; // square
1150 case EXC_CHMARKERFORMAT_DIAMOND
: aApiSymbol
.StandardSymbol
= 1; break; // diamond
1151 case EXC_CHMARKERFORMAT_TRIANGLE
: aApiSymbol
.StandardSymbol
= 3; break; // arrow up
1152 case EXC_CHMARKERFORMAT_CROSS
: aApiSymbol
.StandardSymbol
= 10; break; // X, legacy bow tie
1153 case EXC_CHMARKERFORMAT_STAR
: aApiSymbol
.StandardSymbol
= 12; break; // asterisk, legacy sand glass
1154 case EXC_CHMARKERFORMAT_DOWJ
: aApiSymbol
.StandardSymbol
= 4; break; // arrow right, same as export
1155 case EXC_CHMARKERFORMAT_STDDEV
: aApiSymbol
.StandardSymbol
= 13; break; // horizontal bar, legacy arrow down
1156 case EXC_CHMARKERFORMAT_CIRCLE
: aApiSymbol
.StandardSymbol
= 8; break; // circle, legacy arrow right
1157 case EXC_CHMARKERFORMAT_PLUS
: aApiSymbol
.StandardSymbol
= 11; break; // plus, legacy arrow left
1162 sal_Int32 nApiSize
= XclTools::GetHmmFromTwips( rMarkerFmt
.mnMarkerSize
);
1163 aApiSymbol
.Size
= cssa::Size( nApiSize
, nApiSize
);
1166 aApiSymbol
.FillColor
= ScfApiHelper::ConvertToApiColor( rMarkerFmt
.maFillColor
);
1167 aApiSymbol
.BorderColor
= ::get_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOLINE
) ?
1168 aApiSymbol
.FillColor
: ScfApiHelper::ConvertToApiColor( rMarkerFmt
.maLineColor
);
1171 rPropSet
.SetProperty( EXC_CHPROP_SYMBOL
, aApiSymbol
);
1174 void XclChPropSetHelper::WriteRotationProperties(
1175 ScfPropertySet
& rPropSet
, sal_uInt16 nRotation
, bool bSupportsStacked
)
1177 if( nRotation
!= EXC_CHART_AUTOROTATION
)
1179 // chart2 handles rotation as double in the range [0,360)
1180 double fAngle
= XclTools::GetScRotation( nRotation
, 0 ) / 100.0;
1181 rPropSet
.SetProperty( EXC_CHPROP_TEXTROTATION
, fAngle
);
1182 if( bSupportsStacked
)
1183 rPropSet
.SetProperty( EXC_CHPROP_STACKCHARACTERS
, nRotation
== EXC_ROT_STACKED
);
1187 // private --------------------------------------------------------------------
1189 ScfPropSetHelper
& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode
)
1193 case EXC_CHPROPMODE_COMMON
: return maLineHlpCommon
;
1194 case EXC_CHPROPMODE_LINEARSERIES
: return maLineHlpLinear
;
1195 case EXC_CHPROPMODE_FILLEDSERIES
: return maLineHlpFilled
;
1196 default: OSL_FAIL( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1198 return maLineHlpCommon
;
1201 ScfPropSetHelper
& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode
)
1205 case EXC_CHPROPMODE_COMMON
: return maAreaHlpCommon
;
1206 case EXC_CHPROPMODE_FILLEDSERIES
: return maAreaHlpFilled
;
1207 default: OSL_FAIL( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1209 return maAreaHlpCommon
;
1212 ScfPropSetHelper
& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode
)
1216 case EXC_CHPROPMODE_COMMON
: return maGradHlpCommon
;
1217 case EXC_CHPROPMODE_FILLEDSERIES
: return maGradHlpFilled
;
1218 default: OSL_FAIL( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1220 return maGradHlpCommon
;
1223 ScfPropSetHelper
& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode
)
1227 case EXC_CHPROPMODE_COMMON
: return maHatchHlpCommon
;
1228 case EXC_CHPROPMODE_FILLEDSERIES
: return maHatchHlpFilled
;
1229 default: OSL_FAIL( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1231 return maHatchHlpCommon
;
1234 // ============================================================================
1238 /* The following local functions implement getting the XShape interface of all
1239 supported title objects (chart and axes). This needs some effort due to the
1240 design of the old Chart1 API used to access these objects. */
1242 /** A code fragment that returns a shape object from the passed shape supplier
1243 using the specified interface function. Checks a boolean property first. */
1244 #define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
1245 ScfPropertySet aPropSet( shape_supplier ); \
1246 if( shape_supplier.is() && aPropSet.GetBoolProperty( #property_name ) ) \
1247 return shape_supplier->supplier_func(); \
1248 return Reference< XShape >(); \
1250 /** Implements a function returning the drawing shape of an axis title, if
1251 existing, using the specified API interface and its function. */
1252 #define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
1253 Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
1255 Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
1256 EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
1259 /** Returns the drawing shape of the main title, if existing. */
1260 Reference
< XShape
> lclGetMainTitleShape( const Reference
< cssc::XChartDocument
>& rxChart1Doc
)
1262 EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc
, getTitle
, HasMainTitle
)
1265 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape
, XAxisXSupplier
, getXAxisTitle
, HasXAxisTitle
)
1266 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape
, XAxisYSupplier
, getYAxisTitle
, HasYAxisTitle
)
1267 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape
, XAxisZSupplier
, getZAxisTitle
, HasZAxisTitle
)
1268 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape
, XSecondAxisTitleSupplier
, getSecondXAxisTitle
, HasSecondaryXAxisTitle
)
1269 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape
, XSecondAxisTitleSupplier
, getSecondYAxisTitle
, HasSecondaryYAxisTitle
)
1271 #undef EXC_DEFINEFUNC_GETAXISTITLESHAPE
1272 #undef EXC_IMPLEMENT_GETTITLESHAPE
1276 // ----------------------------------------------------------------------------
1278 XclChRootData::XclChRootData() :
1279 mxTypeInfoProv( new XclChTypeInfoProvider
),
1280 mxFmtInfoProv( new XclChFormatInfoProvider
),
1284 // remember some title shape getter functions
1285 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_TITLE
) ] = lclGetMainTitleShape
;
1286 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_X
) ] = lclGetXAxisTitleShape
;
1287 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_Y
) ] = lclGetYAxisTitleShape
;
1288 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_Z
) ] = lclGetZAxisTitleShape
;
1289 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_SECONDARY
, EXC_CHAXIS_X
) ] = lclGetSecXAxisTitleShape
;
1290 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_SECONDARY
, EXC_CHAXIS_Y
) ] = lclGetSecYAxisTitleShape
;
1293 XclChRootData::~XclChRootData()
1297 void XclChRootData::InitConversion( const XclRoot
& rRoot
, const Reference
< XChartDocument
>& rxChartDoc
, const Rectangle
& rChartRect
)
1299 // remember chart document reference and chart shape position/size
1300 OSL_ENSURE( rxChartDoc
.is(), "XclChRootData::InitConversion - missing chart document" );
1301 mxChartDoc
= rxChartDoc
;
1302 maChartRect
= rChartRect
;
1304 // Excel excludes a border of 5 pixels in each direction from chart area
1305 mnBorderGapX
= rRoot
.GetHmmFromPixelX( 5.0 );
1306 mnBorderGapY
= rRoot
.GetHmmFromPixelY( 5.0 );
1308 // size of a chart unit in 1/100 mm
1309 mfUnitSizeX
= ::std::max
< double >( maChartRect
.GetWidth() - 2 * mnBorderGapX
, mnBorderGapX
) / EXC_CHART_TOTALUNITS
;
1310 mfUnitSizeY
= ::std::max
< double >( maChartRect
.GetHeight() - 2 * mnBorderGapY
, mnBorderGapY
) / EXC_CHART_TOTALUNITS
;
1312 // create object tables
1313 Reference
< XMultiServiceFactory
> xFactory( mxChartDoc
, UNO_QUERY
);
1314 mxLineDashTable
.reset( new XclChObjectTable(
1315 xFactory
, SERVICE_DRAWING_DASHTABLE
, "Excel line dash " ) );
1316 mxGradientTable
.reset( new XclChObjectTable(
1317 xFactory
, SERVICE_DRAWING_GRADIENTTABLE
, "Excel gradient " ) );
1318 mxHatchTable
.reset( new XclChObjectTable(
1319 xFactory
, SERVICE_DRAWING_HATCHTABLE
, "Excel hatch " ) );
1320 mxBitmapTable
.reset( new XclChObjectTable(
1321 xFactory
, SERVICE_DRAWING_BITMAPTABLE
, "Excel bitmap " ) );
1324 void XclChRootData::FinishConversion()
1326 // forget formatting object tables
1327 mxBitmapTable
.reset();
1328 mxHatchTable
.reset();
1329 mxGradientTable
.reset();
1330 mxLineDashTable
.reset();
1331 // forget chart document reference
1335 Reference
< XShape
> XclChRootData::GetTitleShape( const XclChTextKey
& rTitleKey
) const
1337 XclChGetShapeFuncMap::const_iterator aIt
= maGetShapeFuncs
.find( rTitleKey
);
1338 OSL_ENSURE( aIt
!= maGetShapeFuncs
.end(), "XclChRootData::GetTitleShape - invalid title key" );
1339 Reference
< cssc::XChartDocument
> xChart1Doc( mxChartDoc
, UNO_QUERY
);
1340 Reference
< XShape
> xTitleShape
;
1341 if( xChart1Doc
.is() && (aIt
!= maGetShapeFuncs
.end()) )
1342 xTitleShape
= (aIt
->second
)( xChart1Doc
);
1346 // ============================================================================
1348 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */