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 .
20 #include <xlchart.hxx>
22 #include <com/sun/star/container/XNameContainer.hpp>
23 #include <com/sun/star/awt/Size.hpp>
24 #include <com/sun/star/awt/Gradient.hpp>
25 #include <com/sun/star/drawing/Hatch.hpp>
26 #include <com/sun/star/drawing/LineDash.hpp>
27 #include <com/sun/star/drawing/LineStyle.hpp>
28 #include <com/sun/star/drawing/FillStyle.hpp>
29 #include <com/sun/star/drawing/BitmapMode.hpp>
30 #include <com/sun/star/chart/DataLabelPlacement.hpp>
31 #include <com/sun/star/chart/XAxisXSupplier.hpp>
32 #include <com/sun/star/chart/XAxisYSupplier.hpp>
33 #include <com/sun/star/chart/XAxisZSupplier.hpp>
34 #include <com/sun/star/chart/XChartDocument.hpp>
35 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
36 #include <com/sun/star/chart2/Symbol.hpp>
37 #include <com/sun/star/chart2/XChartDocument.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <sal/macros.h>
41 #include <sal/mathconf.h>
42 #include <svl/itemset.hxx>
43 #include <svx/xfillit0.hxx>
44 #include <svx/xflclit.hxx>
45 #include <svx/xfltrit.hxx>
46 #include <svx/xflgrit.hxx>
47 #include <svx/xbtmpit.hxx>
48 #include <svx/unomid.hxx>
49 #include <filter/msfilter/escherex.hxx>
51 #include <xlstyle.hxx>
52 #include <xltools.hxx>
56 // Common =====================================================================
58 XclChRectangle::XclChRectangle() :
66 XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx
, sal_uInt16 nPointIdx
) :
67 mnSeriesIdx( nSeriesIdx
),
68 mnPointIdx( nPointIdx
)
72 bool operator<( const XclChDataPointPos
& rL
, const XclChDataPointPos
& rR
)
74 return (rL
.mnSeriesIdx
< rR
.mnSeriesIdx
) ||
75 ((rL
.mnSeriesIdx
== rR
.mnSeriesIdx
) && (rL
.mnPointIdx
< rR
.mnPointIdx
));
78 XclChFrBlock::XclChFrBlock( sal_uInt16 nType
) :
86 // Frame formatting ===========================================================
88 XclChFramePos::XclChFramePos() :
89 mnTLMode( EXC_CHFRAMEPOS_PARENT
),
90 mnBRMode( EXC_CHFRAMEPOS_PARENT
)
94 XclChLineFormat::XclChLineFormat() :
96 mnPattern( EXC_CHLINEFORMAT_SOLID
),
97 mnWeight( EXC_CHLINEFORMAT_SINGLE
),
98 mnFlags( EXC_CHLINEFORMAT_AUTO
)
102 XclChAreaFormat::XclChAreaFormat() :
103 maPattColor( COL_WHITE
),
104 maBackColor( COL_BLACK
),
105 mnPattern( EXC_PATT_SOLID
),
106 mnFlags( EXC_CHAREAFORMAT_AUTO
)
110 XclChEscherFormat::XclChEscherFormat()
114 XclChEscherFormat::~XclChEscherFormat()
118 XclChPicFormat::XclChPicFormat() :
119 mnBmpMode( EXC_CHPICFORMAT_NONE
),
120 mnFlags( EXC_CHPICFORMAT_TOPBOTTOM
| EXC_CHPICFORMAT_FRONTBACK
| EXC_CHPICFORMAT_LEFTRIGHT
),
125 XclChFrame::XclChFrame() :
126 mnFormat( EXC_CHFRAME_STANDARD
),
127 mnFlags( EXC_CHFRAME_AUTOSIZE
| EXC_CHFRAME_AUTOPOS
)
131 // Source links ===============================================================
133 XclChSourceLink::XclChSourceLink() :
134 mnDestType( EXC_CHSRCLINK_TITLE
),
135 mnLinkType( EXC_CHSRCLINK_DEFAULT
),
141 // Text =======================================================================
143 XclChObjectLink::XclChObjectLink() :
144 mnTarget( EXC_CHOBJLINK_NONE
)
148 XclChFrLabelProps::XclChFrLabelProps() :
153 XclChText::XclChText() :
154 maTextColor( COL_BLACK
),
155 mnHAlign( EXC_CHTEXT_ALIGN_CENTER
),
156 mnVAlign( EXC_CHTEXT_ALIGN_CENTER
),
157 mnBackMode( EXC_CHTEXT_TRANSPARENT
),
158 mnFlags( EXC_CHTEXT_AUTOCOLOR
| EXC_CHTEXT_AUTOFILL
),
159 mnFlags2( EXC_CHTEXT_POS_DEFAULT
),
160 mnRotation( EXC_ROT_NONE
)
164 // Data series ================================================================
166 XclChMarkerFormat::XclChMarkerFormat() :
167 maLineColor( COL_BLACK
),
168 maFillColor( COL_WHITE
),
169 mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE
),
170 mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL
),
171 mnFlags( EXC_CHMARKERFORMAT_AUTO
)
175 XclCh3dDataFormat::XclCh3dDataFormat() :
176 mnBase( EXC_CH3DDATAFORMAT_RECT
),
177 mnTop( EXC_CH3DDATAFORMAT_STRAIGHT
)
181 XclChDataFormat::XclChDataFormat() :
182 mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT
),
187 XclChSerTrendLine::XclChSerTrendLine() :
188 mfForecastFor( 0.0 ),
189 mfForecastBack( 0.0 ),
190 mnLineType( EXC_CHSERTREND_POLYNOMIAL
),
195 /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
196 there is no interception point. Cannot use ::rtl::math::setNan() here
197 cause it misses the sign bit. */
198 sal_math_Double
* pDouble
= reinterpret_cast< sal_math_Double
* >( &mfIntercept
);
199 pDouble
->w32_parts
.msw
= pDouble
->w32_parts
.lsw
= 0xFFFFFFFF;
202 XclChSerErrorBar::XclChSerErrorBar() :
205 mnBarType( EXC_CHSERERR_NONE
),
206 mnSourceType( EXC_CHSERERR_FIXED
),
207 mnLineEnd( EXC_CHSERERR_END_TSHAPE
)
211 XclChSeries::XclChSeries() :
212 mnCategType( EXC_CHSERIES_NUMERIC
),
213 mnValueType( EXC_CHSERIES_NUMERIC
),
214 mnBubbleType( EXC_CHSERIES_NUMERIC
),
221 // Chart type groups ==========================================================
223 XclChType::XclChType() :
229 mnBubbleType( EXC_CHSCATTER_AREA
),
234 XclChChart3d::XclChChart3d() :
241 mnFlags( EXC_CHCHART3D_AUTOHEIGHT
)
245 XclChLegend::XclChLegend() :
246 mnDockMode( EXC_CHLEGEND_RIGHT
),
247 mnSpacing( EXC_CHLEGEND_MEDIUM
),
248 mnFlags( EXC_CHLEGEND_DOCKED
| EXC_CHLEGEND_AUTOSERIES
|
249 EXC_CHLEGEND_AUTOPOSX
| EXC_CHLEGEND_AUTOPOSY
| EXC_CHLEGEND_STACKED
)
253 XclChTypeGroup::XclChTypeGroup() :
255 mnGroupIdx( EXC_CHSERGROUP_NONE
)
259 XclChProperties::XclChProperties() :
261 mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP
)
265 // Axes =======================================================================
267 XclChLabelRange::XclChLabelRange() :
275 XclChDateRange::XclChDateRange() :
279 mnMajorUnit( EXC_CHDATERANGE_DAYS
),
281 mnMinorUnit( EXC_CHDATERANGE_DAYS
),
282 mnBaseUnit( EXC_CHDATERANGE_DAYS
),
284 mnFlags( EXC_CHDATERANGE_AUTOMIN
| EXC_CHDATERANGE_AUTOMAX
|
285 EXC_CHDATERANGE_AUTOMAJOR
| EXC_CHDATERANGE_AUTOMINOR
|
286 EXC_CHDATERANGE_AUTOBASE
| EXC_CHDATERANGE_AUTOCROSS
|
287 EXC_CHDATERANGE_AUTODATE
)
291 XclChValueRange::XclChValueRange() :
297 mnFlags( EXC_CHVALUERANGE_AUTOMIN
| EXC_CHVALUERANGE_AUTOMAX
|
298 EXC_CHVALUERANGE_AUTOMAJOR
| EXC_CHVALUERANGE_AUTOMINOR
|
299 EXC_CHVALUERANGE_AUTOCROSS
| EXC_CHVALUERANGE_BIT8
)
303 XclChTick::XclChTick() :
304 maTextColor( COL_BLACK
),
305 mnMajor( EXC_CHTICK_INSIDE
| EXC_CHTICK_OUTSIDE
),
307 mnLabelPos( EXC_CHTICK_NEXT
),
308 mnBackMode( EXC_CHTICK_TRANSPARENT
),
309 mnFlags( EXC_CHTICK_AUTOCOLOR
| EXC_CHTICK_AUTOROT
),
310 mnRotation( EXC_ROT_NONE
)
314 XclChAxis::XclChAxis() :
315 mnType( EXC_CHAXIS_NONE
)
319 sal_Int32
XclChAxis::GetApiAxisDimension() const
321 sal_Int32 nApiAxisDim
= EXC_CHART_AXIS_NONE
;
324 case EXC_CHAXIS_X
: nApiAxisDim
= EXC_CHART_AXIS_X
; break;
325 case EXC_CHAXIS_Y
: nApiAxisDim
= EXC_CHART_AXIS_Y
; break;
326 case EXC_CHAXIS_Z
: nApiAxisDim
= EXC_CHART_AXIS_Z
; break;
331 XclChAxesSet::XclChAxesSet() :
332 mnAxesSetId( EXC_CHAXESSET_PRIMARY
)
336 sal_Int32
XclChAxesSet::GetApiAxesSetIndex() const
338 sal_Int32 nApiAxesSetIdx
= EXC_CHART_AXESSET_NONE
;
339 switch( mnAxesSetId
)
341 case EXC_CHAXESSET_PRIMARY
: nApiAxesSetIdx
= EXC_CHART_AXESSET_PRIMARY
; break;
342 case EXC_CHAXESSET_SECONDARY
: nApiAxesSetIdx
= EXC_CHART_AXESSET_SECONDARY
; break;
344 return nApiAxesSetIdx
;
347 // Static helper functions ====================================================
349 sal_uInt16
XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx
)
351 static const sal_uInt16 spnLineColors
[] =
353 32, 33, 34, 35, 36, 37, 38, 39,
354 40, 41, 42, 43, 44, 45, 46, 47,
355 48, 49, 50, 51, 52, 53, 54, 55,
356 56, 57, 58, 59, 60, 61, 62, 8,
357 9, 10, 11, 12, 13, 14, 15, 16,
358 17, 18, 19, 20, 21, 22, 23, 24,
359 25, 26, 27, 28, 29, 30, 31, 63
361 return spnLineColors
[ nFormatIdx
% SAL_N_ELEMENTS( spnLineColors
) ];
364 sal_uInt16
XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx
)
366 static const sal_uInt16 spnFillColors
[] =
368 24, 25, 26, 27, 28, 29, 30, 31,
369 32, 33, 34, 35, 36, 37, 38, 39,
370 40, 41, 42, 43, 44, 45, 46, 47,
371 48, 49, 50, 51, 52, 53, 54, 55,
372 56, 57, 58, 59, 60, 61, 62, 63,
373 8, 9, 10, 11, 12, 13, 14, 15,
374 16, 17, 18, 19, 20, 21, 22, 23
376 return spnFillColors
[ nFormatIdx
% SAL_N_ELEMENTS( spnFillColors
) ];
379 sal_uInt8
XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx
)
381 static const sal_uInt8 spnTrans
[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
382 return spnTrans
[ (nFormatIdx
/ 56) % SAL_N_ELEMENTS( spnTrans
) ];
385 sal_uInt16
XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx
)
387 static const sal_uInt16 spnSymbols
[] = {
388 EXC_CHMARKERFORMAT_DIAMOND
, EXC_CHMARKERFORMAT_SQUARE
, EXC_CHMARKERFORMAT_TRIANGLE
,
389 EXC_CHMARKERFORMAT_CROSS
, EXC_CHMARKERFORMAT_STAR
, EXC_CHMARKERFORMAT_CIRCLE
,
390 EXC_CHMARKERFORMAT_PLUS
, EXC_CHMARKERFORMAT_DOWJ
, EXC_CHMARKERFORMAT_STDDEV
};
391 return spnSymbols
[ nFormatIdx
% SAL_N_ELEMENTS( spnSymbols
) ];
394 bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType
)
396 static const bool spbFilled
[] = {
397 false, true, true, true, false, false, false, false, true, false };
398 return (nMarkerType
< SAL_N_ELEMENTS( spbFilled
)) && spbFilled
[ nMarkerType
];
401 OUString
XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType
)
405 case EXC_CHSERERR_XPLUS
: return EXC_CHPROP_ROLE_ERRORBARS_POSX
;
406 case EXC_CHSERERR_XMINUS
: return EXC_CHPROP_ROLE_ERRORBARS_NEGX
;
407 case EXC_CHSERERR_YPLUS
: return EXC_CHPROP_ROLE_ERRORBARS_POSY
;
408 case EXC_CHSERERR_YMINUS
: return EXC_CHPROP_ROLE_ERRORBARS_NEGY
;
409 default: OSL_FAIL( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
414 // Chart formatting info provider =============================================
418 const XclChFormatInfo spFmtInfos
[] =
420 // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
421 { EXC_CHOBJTYPE_BACKGROUND
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, true, true, true },
422 { EXC_CHOBJTYPE_PLOTFRAME
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, true, true, true },
423 { EXC_CHOBJTYPE_WALL3D
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, true, false, true },
424 { EXC_CHOBJTYPE_FLOOR3D
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, 23, EXC_CHFRAMETYPE_AUTO
, true, false, true },
425 { EXC_CHOBJTYPE_TEXT
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, true, true },
426 { EXC_CHOBJTYPE_LEGEND
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, true, true, true },
427 { EXC_CHOBJTYPE_LINEARSERIES
, EXC_CHPROPMODE_LINEARSERIES
, 0xFFFF, EXC_CHLINEFORMAT_SINGLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, false, false, false },
428 { EXC_CHOBJTYPE_FILLEDSERIES
, EXC_CHPROPMODE_FILLEDSERIES
, EXC_COLOR_CHBORDERAUTO
, EXC_CHLINEFORMAT_SINGLE
, 0xFFFF, EXC_CHFRAMETYPE_AUTO
, false, false, true },
429 { EXC_CHOBJTYPE_AXISLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, false, false, false },
430 { EXC_CHOBJTYPE_GRIDLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, true, false },
431 { EXC_CHOBJTYPE_TRENDLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_DOUBLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
432 { EXC_CHOBJTYPE_ERRORBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_SINGLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
433 { EXC_CHOBJTYPE_CONNECTLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
434 { EXC_CHOBJTYPE_HILOLINE
, EXC_CHPROPMODE_LINEARSERIES
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
435 { EXC_CHOBJTYPE_WHITEDROPBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, true },
436 { EXC_CHOBJTYPE_BLACKDROPBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, true }
441 XclChFormatInfoProvider::XclChFormatInfoProvider()
443 for(auto const &rIt
: spFmtInfos
)
444 maInfoMap
[ rIt
.meObjType
] = &rIt
;
447 const XclChFormatInfo
& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType
) const
449 XclFmtInfoMap::const_iterator aIt
= maInfoMap
.find( eObjType
);
450 OSL_ENSURE( aIt
!= maInfoMap
.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
451 return (aIt
== maInfoMap
.end()) ? *spFmtInfos
: *aIt
->second
;
454 // Chart type info provider ===================================================
458 // chart type service names
459 const char SERVICE_CHART2_AREA
[] = "com.sun.star.chart2.AreaChartType";
460 const char SERVICE_CHART2_CANDLE
[] = "com.sun.star.chart2.CandleStickChartType";
461 const char SERVICE_CHART2_COLUMN
[] = "com.sun.star.chart2.ColumnChartType";
462 const char SERVICE_CHART2_LINE
[] = "com.sun.star.chart2.LineChartType";
463 const char SERVICE_CHART2_NET
[] = "com.sun.star.chart2.NetChartType";
464 const char SERVICE_CHART2_FILLEDNET
[] = "com.sun.star.chart2.FilledNetChartType";
465 const char SERVICE_CHART2_PIE
[] = "com.sun.star.chart2.PieChartType";
466 const char SERVICE_CHART2_SCATTER
[] = "com.sun.star.chart2.ScatterChartType";
467 const char SERVICE_CHART2_BUBBLE
[] = "com.sun.star.chart2.BubbleChartType";
468 const char SERVICE_CHART2_SURFACE
[] = "com.sun.star.chart2.ColumnChartType"; // Todo
470 namespace csscd
= css::chart::DataLabelPlacement
;
472 const XclChTypeInfo spTypeInfos
[] =
474 // 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
475 { 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 },
476 { 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 },
477 { 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 },
478 { 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 },
479 { 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 },
480 { 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 },
481 { 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 },
482 { 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 },
483 { 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 },
484 { 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 },
485 { 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 },
486 { 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 },
487 { 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 },
488 { 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 }
493 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo
& rTypeInfo
) :
494 XclChTypeInfo( rTypeInfo
),
500 void XclChExtTypeInfo::Set( const XclChTypeInfo
& rTypeInfo
, bool b3dChart
, bool bSpline
)
502 static_cast< XclChTypeInfo
& >( *this ) = rTypeInfo
;
503 mb3dChart
= mbSupports3d
&& b3dChart
;
507 XclChTypeInfoProvider::XclChTypeInfoProvider()
509 for(const auto &rIt
: spTypeInfos
)
510 maInfoMap
[ rIt
.meTypeId
] = &rIt
;
513 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId
) const
515 XclChTypeInfoMap::const_iterator aIt
= maInfoMap
.find( eTypeId
);
516 OSL_ENSURE( aIt
!= maInfoMap
.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
517 return (aIt
== maInfoMap
.end()) ? *maInfoMap
.rbegin()->second
: *aIt
->second
;
520 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId
) const
522 for(const auto &rIt
: spTypeInfos
)
524 if(rIt
.mnRecId
== nRecId
)
527 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
528 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
531 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString
& rServiceName
) const
533 for(auto const &rIt
: spTypeInfos
)
534 if( rServiceName
.equalsAscii( rIt
.mpcServiceName
) )
536 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
537 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
540 // Property helpers ===========================================================
542 XclChObjectTable::XclChObjectTable(uno::Reference
<lang::XMultiServiceFactory
> const & xFactory
,
543 const OUString
& rServiceName
, const OUString
& rObjNameBase
) :
544 mxFactory( xFactory
),
545 maServiceName( rServiceName
),
546 maObjNameBase( rObjNameBase
),
551 uno::Any
XclChObjectTable::GetObject( const OUString
& rObjName
)
554 if( !mxContainer
.is() )
555 mxContainer
.set(ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), uno::UNO_QUERY
);
556 OSL_ENSURE( mxContainer
.is(), "XclChObjectTable::GetObject - container not found" );
559 if( mxContainer
.is() )
561 // get object from container
564 aObj
= mxContainer
->getByName( rObjName
);
566 catch (uno::Exception
&)
568 OSL_FAIL( "XclChObjectTable::GetObject - object not found" );
574 OUString
XclChObjectTable::InsertObject(const uno::Any
& rObj
)
577 // create object table
578 if( !mxContainer
.is() )
579 mxContainer
.set(ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), uno::UNO_QUERY
);
580 OSL_ENSURE( mxContainer
.is(), "XclChObjectTable::InsertObject - container not found" );
583 if( mxContainer
.is() )
585 // create new unused identifier
588 aObjName
= maObjNameBase
+ OUString::number( ++mnIndex
);
590 while( mxContainer
->hasByName( aObjName
) );
595 mxContainer
->insertByName( aObjName
, rObj
);
597 catch (uno::Exception
&)
599 OSL_FAIL( "XclChObjectTable::InsertObject - cannot insert object" );
606 // Property names -------------------------------------------------------------
610 /** Property names for line style in common objects. */
611 const char* const sppcLineNamesCommon
[] =
612 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", nullptr };
613 /** Property names for line style in linear series objects. */
614 const char* const sppcLineNamesLinear
[] =
615 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", nullptr };
616 /** Property names for line style in filled series objects. */
617 const char* const sppcLineNamesFilled
[] =
618 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", nullptr };
620 /** Property names for solid area style in common objects. */
621 const char* const sppcAreaNamesCommon
[] = { "FillStyle", "FillColor", "FillTransparence", nullptr };
622 /** Property names for solid area style in filled series objects. */
623 const char* const sppcAreaNamesFilled
[] = { "FillStyle", "Color", "Transparency", nullptr };
624 /** Property names for gradient area style in common objects. */
625 const char* const sppcGradNamesCommon
[] = { "FillStyle", "FillGradientName", nullptr };
626 /** Property names for gradient area style in filled series objects. */
627 const char* const sppcGradNamesFilled
[] = { "FillStyle", "GradientName", nullptr };
628 /** Property names for hatch area style in common objects. */
629 const char* const sppcHatchNamesCommon
[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", nullptr };
630 /** Property names for hatch area style in filled series objects. */
631 const char* const sppcHatchNamesFilled
[] = { "FillStyle", "HatchName", "Color", "FillBackground", nullptr };
632 /** Property names for bitmap area style. */
633 const char* const sppcBitmapNames
[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", nullptr };
637 XclChPropSetHelper::XclChPropSetHelper() :
638 maLineHlpCommon( sppcLineNamesCommon
),
639 maLineHlpLinear( sppcLineNamesLinear
),
640 maLineHlpFilled( sppcLineNamesFilled
),
641 maAreaHlpCommon( sppcAreaNamesCommon
),
642 maAreaHlpFilled( sppcAreaNamesFilled
),
643 maGradHlpCommon( sppcGradNamesCommon
),
644 maGradHlpFilled( sppcGradNamesFilled
),
645 maHatchHlpCommon( sppcHatchNamesCommon
),
646 maHatchHlpFilled( sppcHatchNamesFilled
),
647 maBitmapHlp( sppcBitmapNames
)
651 // read properties ------------------------------------------------------------
653 void XclChPropSetHelper::ReadLineProperties(
654 XclChLineFormat
& rLineFmt
, XclChObjectTable
& rDashTable
,
655 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
657 // read properties from property set
658 drawing::LineStyle eApiStyle
= drawing::LineStyle_NONE
;
659 sal_Int32 nApiWidth
= 0;
660 sal_Int16 nApiTrans
= 0;
661 uno::Any aDashNameAny
;
663 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
664 rLineHlp
.ReadFromPropertySet( rPropSet
);
665 rLineHlp
>> eApiStyle
>> nApiWidth
>> rLineFmt
.maColor
>> nApiTrans
>> aDashNameAny
;
667 // clear automatic flag
668 ::set_flag( rLineFmt
.mnFlags
, EXC_CHLINEFORMAT_AUTO
, false );
671 if( nApiWidth
<= 0 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_HAIR
;
672 else if( nApiWidth
<= 35 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_SINGLE
;
673 else if( nApiWidth
<= 70 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_DOUBLE
;
674 else rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_TRIPLE
;
679 case drawing::LineStyle_NONE
:
680 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
682 case drawing::LineStyle_SOLID
:
684 if( nApiTrans
< 13 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
685 else if( nApiTrans
< 38 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DARKTRANS
;
686 else if( nApiTrans
< 63 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_MEDTRANS
;
687 else if( nApiTrans
< 100 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_LIGHTTRANS
;
688 else rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
691 case drawing::LineStyle_DASH
:
693 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
695 drawing::LineDash aApiDash
;
696 if( (aDashNameAny
>>= aDashName
) && (rDashTable
.GetObject( aDashName
) >>= aApiDash
) )
698 // reorder dashes that are shorter than dots
699 if( (aApiDash
.Dashes
== 0) || (aApiDash
.DashLen
< aApiDash
.DotLen
) )
701 ::std::swap( aApiDash
.Dashes
, aApiDash
.Dots
);
702 ::std::swap( aApiDash
.DashLen
, aApiDash
.DotLen
);
704 // ignore dots that are nearly equal to dashes
705 if( aApiDash
.DotLen
* 3 > aApiDash
.DashLen
* 2 )
708 // convert line dash to predefined Excel dash types
709 if( (aApiDash
.Dashes
== 1) && (aApiDash
.Dots
>= 1) )
710 // one dash and one or more dots
711 rLineFmt
.mnPattern
= (aApiDash
.Dots
== 1) ?
712 EXC_CHLINEFORMAT_DASHDOT
: EXC_CHLINEFORMAT_DASHDOTDOT
;
713 else if( aApiDash
.Dashes
>= 1 )
714 // one or more dashes and no dots (also: dash-dash-dot)
715 rLineFmt
.mnPattern
= (aApiDash
.DashLen
< 250) ?
716 EXC_CHLINEFORMAT_DOT
: EXC_CHLINEFORMAT_DASH
;
721 OSL_FAIL( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
722 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
726 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat
& rAreaFmt
,
727 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
729 // read properties from property set
730 drawing::FillStyle eApiStyle
= drawing::FillStyle_NONE
;
731 sal_Int16 nTransparency
= 0;
733 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
734 rAreaHlp
.ReadFromPropertySet( rPropSet
);
735 rAreaHlp
>> eApiStyle
>> rAreaFmt
.maPattColor
>> nTransparency
;
737 // clear automatic flag
738 ::set_flag( rAreaFmt
.mnFlags
, EXC_CHAREAFORMAT_AUTO
, false );
740 // set fill style transparent or solid (set solid for anything but transparent)
741 rAreaFmt
.mnPattern
= (eApiStyle
== drawing::FillStyle_NONE
) ? EXC_PATT_NONE
: EXC_PATT_SOLID
;
743 // return true to indicate complex fill (gradient, bitmap, solid transparency)
744 return (eApiStyle
!= drawing::FillStyle_NONE
) && ((eApiStyle
!= drawing::FillStyle_SOLID
) || (nTransparency
> 0));
747 void XclChPropSetHelper::ReadEscherProperties(
748 XclChEscherFormat
& rEscherFmt
, XclChPicFormat
& rPicFmt
,
749 XclChObjectTable
& rGradientTable
, XclChObjectTable
& rHatchTable
, XclChObjectTable
& rBitmapTable
,
750 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
752 // read style and transparency properties from property set
753 drawing::FillStyle eApiStyle
= drawing::FillStyle_NONE
;
755 sal_Int16 nTransparency
= 0;
757 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
758 rAreaHlp
.ReadFromPropertySet( rPropSet
);
759 rAreaHlp
>> eApiStyle
>> aColor
>> nTransparency
;
763 case drawing::FillStyle_SOLID
:
765 OSL_ENSURE( nTransparency
> 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
766 if( (0 < nTransparency
) && (nTransparency
<= 100) )
768 // convert to Escher properties
769 sal_uInt32 nEscherColor
= 0x02000000;
770 ::insert_value( nEscherColor
, aColor
.GetBlue(), 16, 8 );
771 ::insert_value( nEscherColor
, aColor
.GetGreen(), 8, 8 );
772 ::insert_value( nEscherColor
, aColor
.GetRed(), 0, 8 );
773 sal_uInt32 nEscherOpacity
= static_cast< sal_uInt32
>( (100 - nTransparency
) * 655.36 );
774 rEscherFmt
.mxEscherSet
= std::make_shared
<EscherPropertyContainer
>();
775 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillType
, ESCHER_FillSolid
);
776 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillColor
, nEscherColor
);
777 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillOpacity
, nEscherOpacity
);
778 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackColor
, 0x02FFFFFF );
779 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackOpacity
, 0x00010000 );
780 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x001F001C );
784 case drawing::FillStyle_GRADIENT
:
786 // extract gradient from global gradient table
787 OUString aGradientName
;
788 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
789 rGradHlp
.ReadFromPropertySet( rPropSet
);
790 rGradHlp
>> eApiStyle
>> aGradientName
;
791 awt::Gradient aGradient
;
792 if( rGradientTable
.GetObject( aGradientName
) >>= aGradient
)
794 // convert to Escher properties
795 rEscherFmt
.mxEscherSet
= std::make_shared
<EscherPropertyContainer
>();
796 rEscherFmt
.mxEscherSet
->CreateGradientProperties( aGradient
);
800 case drawing::FillStyle_HATCH
:
802 // extract hatch from global hatch table
804 bool bFillBackground
;
805 ScfPropSetHelper
& rHatchHlp
= GetHatchHelper( ePropMode
);
806 rHatchHlp
.ReadFromPropertySet( rPropSet
);
807 rHatchHlp
>> eApiStyle
>> aHatchName
>> aColor
>> bFillBackground
;
808 drawing::Hatch aHatch
;
809 if( rHatchTable
.GetObject( aHatchName
) >>= aHatch
)
811 // convert to Escher properties
812 rEscherFmt
.mxEscherSet
= std::make_shared
<EscherPropertyContainer
>();
813 rEscherFmt
.mxEscherSet
->CreateEmbeddedHatchProperties( aHatch
, aColor
, bFillBackground
);
814 rPicFmt
.mnBmpMode
= EXC_CHPICFORMAT_STACK
;
818 case drawing::FillStyle_BITMAP
:
820 // extract bitmap URL from global bitmap table
821 OUString aBitmapName
;
822 drawing::BitmapMode eApiBmpMode
;
823 maBitmapHlp
.ReadFromPropertySet( rPropSet
);
824 maBitmapHlp
>> eApiStyle
>> aBitmapName
>> eApiBmpMode
;
825 uno::Reference
<awt::XBitmap
> xBitmap
;
826 if (rBitmapTable
.GetObject( aBitmapName
) >>= xBitmap
)
828 // convert to Escher properties
829 rEscherFmt
.mxEscherSet
= std::make_shared
<EscherPropertyContainer
>();
830 rEscherFmt
.mxEscherSet
->CreateEmbeddedBitmapProperties( xBitmap
, eApiBmpMode
);
831 rPicFmt
.mnBmpMode
= (eApiBmpMode
== drawing::BitmapMode_REPEAT
) ?
832 EXC_CHPICFORMAT_STACK
: EXC_CHPICFORMAT_STRETCH
;
837 OSL_FAIL( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
841 void XclChPropSetHelper::ReadMarkerProperties(
842 XclChMarkerFormat
& rMarkerFmt
, const ScfPropertySet
& rPropSet
, sal_uInt16 nFormatIdx
)
844 chart2::Symbol aApiSymbol
;
845 if( !rPropSet
.GetProperty( aApiSymbol
, EXC_CHPROP_SYMBOL
) )
848 // clear automatic flag
849 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_AUTO
, false );
852 switch( aApiSymbol
.Style
)
854 case chart2::SymbolStyle_NONE
:
855 rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_NOSYMBOL
;
857 case chart2::SymbolStyle_STANDARD
:
858 switch( aApiSymbol
.StandardSymbol
)
860 case 0: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_SQUARE
; break; // square
861 case 1: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DIAMOND
; break; // diamond
862 case 2: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STDDEV
; break; // arrow down
863 case 3: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_TRIANGLE
; break; // arrow up
864 case 4: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DOWJ
; break; // arrow right, same as import
865 case 5: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_PLUS
; break; // arrow left
866 case 6: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CROSS
; break; // bow tie
867 case 7: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // sand glass
868 case 8: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CIRCLE
; break; // circle new in LibO3.5
869 case 9: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DIAMOND
; break; // star new in LibO3.5
870 case 10: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CROSS
; break; // X new in LibO3.5
871 case 11: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_PLUS
; break; // plus new in LibO3.5
872 case 12: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // asterisk new in LibO3.5
873 case 13: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STDDEV
; break; // horizontal bar new in LibO3.5
874 case 14: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // vertical bar new in LibO3.5
875 default: rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
879 rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
881 bool bHasFillColor
= XclChartHelper::HasMarkerFillColor( rMarkerFmt
.mnMarkerType
);
882 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOFILL
, !bHasFillColor
);
885 sal_Int32 nApiSize
= (aApiSymbol
.Size
.Width
+ aApiSymbol
.Size
.Height
+ 1) / 2;
886 rMarkerFmt
.mnMarkerSize
= XclTools::GetTwipsFromHmm( nApiSize
);
889 rMarkerFmt
.maLineColor
= Color( ColorTransparency
, aApiSymbol
.BorderColor
);
890 rMarkerFmt
.maFillColor
= Color( ColorTransparency
, aApiSymbol
.FillColor
);
893 sal_uInt16
XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet
& rPropSet
, bool bSupportsStacked
)
895 // chart2 handles rotation as double in the range [0,360)
897 rPropSet
.GetProperty( fAngle
, EXC_CHPROP_TEXTROTATION
);
898 bool bStacked
= bSupportsStacked
&& rPropSet
.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS
);
899 return bStacked
? EXC_ROT_STACKED
:
900 XclTools::GetXclRotation( Degree100(static_cast< sal_Int32
>( fAngle
* 100.0 + 0.5 )) );
903 // write properties -----------------------------------------------------------
905 void XclChPropSetHelper::WriteLineProperties(
906 ScfPropertySet
& rPropSet
, XclChObjectTable
& rDashTable
,
907 const XclChLineFormat
& rLineFmt
, XclChPropertyMode ePropMode
)
910 sal_Int32 nApiWidth
= 0; // 0 is the width of a hair line
911 switch( rLineFmt
.mnWeight
)
913 case EXC_CHLINEFORMAT_SINGLE
: nApiWidth
= 35; break;
914 case EXC_CHLINEFORMAT_DOUBLE
: nApiWidth
= 70; break;
915 case EXC_CHLINEFORMAT_TRIPLE
: nApiWidth
= 105; break;
919 drawing::LineStyle eApiStyle
= drawing::LineStyle_NONE
;
920 sal_Int16 nApiTrans
= 0;
921 sal_Int32 nDotLen
= ::std::min
< sal_Int32
>( rLineFmt
.mnWeight
+ 105, 210 );
922 drawing::LineDash
aApiDash( drawing::DashStyle_RECT
, 0, nDotLen
, 0, 4 * nDotLen
, nDotLen
);
924 switch( rLineFmt
.mnPattern
)
926 case EXC_CHLINEFORMAT_SOLID
:
927 eApiStyle
= drawing::LineStyle_SOLID
;
929 case EXC_CHLINEFORMAT_DARKTRANS
:
930 eApiStyle
= drawing::LineStyle_SOLID
; nApiTrans
= 25;
932 case EXC_CHLINEFORMAT_MEDTRANS
:
933 eApiStyle
= drawing::LineStyle_SOLID
; nApiTrans
= 50;
935 case EXC_CHLINEFORMAT_LIGHTTRANS
:
936 eApiStyle
= drawing::LineStyle_SOLID
; nApiTrans
= 75;
938 case EXC_CHLINEFORMAT_DASH
:
939 eApiStyle
= drawing::LineStyle_DASH
; aApiDash
.Dashes
= 1;
941 case EXC_CHLINEFORMAT_DOT
:
942 eApiStyle
= drawing::LineStyle_DASH
; aApiDash
.Dots
= 1;
944 case EXC_CHLINEFORMAT_DASHDOT
:
945 eApiStyle
= drawing::LineStyle_DASH
; aApiDash
.Dashes
= aApiDash
.Dots
= 1;
947 case EXC_CHLINEFORMAT_DASHDOTDOT
:
948 eApiStyle
= drawing::LineStyle_DASH
; aApiDash
.Dashes
= 1; aApiDash
.Dots
= 2;
953 sal_Int32 nApiColor
= sal_Int32( rLineFmt
.maColor
);
955 // try to insert the dash style and receive its name
956 uno::Any aDashNameAny
;
957 if( eApiStyle
== drawing::LineStyle_DASH
)
959 OUString aDashName
= rDashTable
.InsertObject( uno::makeAny( aApiDash
) );
960 if( !aDashName
.isEmpty() )
961 aDashNameAny
<<= aDashName
;
964 // write the properties
965 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
966 rLineHlp
.InitializeWrite();
967 rLineHlp
<< eApiStyle
<< nApiWidth
<< nApiColor
<< nApiTrans
<< aDashNameAny
;
968 rLineHlp
.WriteToPropertySet( rPropSet
);
971 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet
& rPropSet
,
972 const XclChAreaFormat
& rAreaFmt
, XclChPropertyMode ePropMode
)
974 drawing::FillStyle eFillStyle
= drawing::FillStyle_NONE
;
978 if( rAreaFmt
.mnPattern
!= EXC_PATT_NONE
)
980 eFillStyle
= drawing::FillStyle_SOLID
;
981 aColor
= XclTools::GetPatternColor( rAreaFmt
.maPattColor
, rAreaFmt
.maBackColor
, rAreaFmt
.mnPattern
);
984 // write the properties
985 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
986 rAreaHlp
.InitializeWrite();
987 rAreaHlp
<< eFillStyle
<< aColor
<< sal_Int16(0)/*nTransparency*/;
988 rAreaHlp
.WriteToPropertySet( rPropSet
);
991 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet
& rPropSet
,
992 XclChObjectTable
& rGradientTable
, XclChObjectTable
& rBitmapTable
,
993 const XclChEscherFormat
& rEscherFmt
, const XclChPicFormat
* pPicFmt
,
994 sal_uInt32 nDffFillType
, XclChPropertyMode ePropMode
)
996 if( !rEscherFmt
.mxItemSet
)
999 const XFillStyleItem
* pStyleItem
= rEscherFmt
.mxItemSet
->GetItem
<XFillStyleItem
>( XATTR_FILLSTYLE
, false );
1003 switch( pStyleItem
->GetValue() )
1005 case drawing::FillStyle_SOLID
:
1006 // #i84812# Excel 2007 writes Escher properties for solid fill
1007 if( const XFillColorItem
* pColorItem
= rEscherFmt
.mxItemSet
->GetItem
<XFillColorItem
>( XATTR_FILLCOLOR
, false ) )
1009 // get solid transparence too
1010 const XFillTransparenceItem
* pTranspItem
= rEscherFmt
.mxItemSet
->GetItem
<XFillTransparenceItem
>( XATTR_FILLTRANSPARENCE
, false );
1011 sal_uInt16 nTransp
= pTranspItem
? pTranspItem
->GetValue() : 0;
1012 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
1013 rAreaHlp
.InitializeWrite();
1014 rAreaHlp
<< drawing::FillStyle_SOLID
<< pColorItem
->GetColorValue() << static_cast< sal_Int16
>( nTransp
);
1015 rAreaHlp
.WriteToPropertySet( rPropSet
);
1018 case drawing::FillStyle_GRADIENT
:
1019 if( const XFillGradientItem
* pGradItem
= rEscherFmt
.mxItemSet
->GetItem
<XFillGradientItem
>( XATTR_FILLGRADIENT
, false ) )
1021 uno::Any aGradientAny
;
1022 if( pGradItem
->QueryValue( aGradientAny
, MID_FILLGRADIENT
) )
1024 OUString aGradName
= rGradientTable
.InsertObject( aGradientAny
);
1025 if( !aGradName
.isEmpty() )
1027 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
1028 rGradHlp
.InitializeWrite();
1029 rGradHlp
<< drawing::FillStyle_GRADIENT
<< aGradName
;
1030 rGradHlp
.WriteToPropertySet( rPropSet
);
1035 case drawing::FillStyle_BITMAP
:
1036 if( const XFillBitmapItem
* pBmpItem
= rEscherFmt
.mxItemSet
->GetItem
<XFillBitmapItem
>( XATTR_FILLBITMAP
, false ) )
1038 uno::Any aBitmapAny
;
1039 if (pBmpItem
->QueryValue(aBitmapAny
, MID_BITMAP
))
1041 OUString aBmpName
= rBitmapTable
.InsertObject( aBitmapAny
);
1042 if( !aBmpName
.isEmpty() )
1044 /* #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode.
1045 If not passed, detect fill mode from the DFF property 'fill-type'. */
1046 bool bStretch
= pPicFmt
? (pPicFmt
->mnBmpMode
== EXC_CHPICFORMAT_STRETCH
) : (nDffFillType
== mso_fillPicture
);
1047 drawing::BitmapMode eApiBmpMode
= bStretch
? drawing::BitmapMode_STRETCH
: drawing::BitmapMode_REPEAT
;
1048 maBitmapHlp
.InitializeWrite();
1049 maBitmapHlp
<< drawing::FillStyle_BITMAP
<< aBmpName
<< eApiBmpMode
;
1050 maBitmapHlp
.WriteToPropertySet( rPropSet
);
1056 OSL_FAIL( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1060 void XclChPropSetHelper::WriteMarkerProperties(
1061 ScfPropertySet
& rPropSet
, const XclChMarkerFormat
& rMarkerFmt
)
1064 chart2::Symbol aApiSymbol
;
1065 aApiSymbol
.Style
= chart2::SymbolStyle_STANDARD
;
1066 switch( rMarkerFmt
.mnMarkerType
)
1068 case EXC_CHMARKERFORMAT_NOSYMBOL
: aApiSymbol
.Style
= chart2::SymbolStyle_NONE
; break;
1069 case EXC_CHMARKERFORMAT_SQUARE
: aApiSymbol
.StandardSymbol
= 0; break; // square
1070 case EXC_CHMARKERFORMAT_DIAMOND
: aApiSymbol
.StandardSymbol
= 1; break; // diamond
1071 case EXC_CHMARKERFORMAT_TRIANGLE
: aApiSymbol
.StandardSymbol
= 3; break; // arrow up
1072 case EXC_CHMARKERFORMAT_CROSS
: aApiSymbol
.StandardSymbol
= 10; break; // X, legacy bow tie
1073 case EXC_CHMARKERFORMAT_STAR
: aApiSymbol
.StandardSymbol
= 12; break; // asterisk, legacy sand glass
1074 case EXC_CHMARKERFORMAT_DOWJ
: aApiSymbol
.StandardSymbol
= 4; break; // arrow right, same as export
1075 case EXC_CHMARKERFORMAT_STDDEV
: aApiSymbol
.StandardSymbol
= 13; break; // horizontal bar, legacy arrow down
1076 case EXC_CHMARKERFORMAT_CIRCLE
: aApiSymbol
.StandardSymbol
= 8; break; // circle, legacy arrow right
1077 case EXC_CHMARKERFORMAT_PLUS
: aApiSymbol
.StandardSymbol
= 11; break; // plus, legacy arrow left
1082 sal_Int32 nApiSize
= XclTools::GetHmmFromTwips( rMarkerFmt
.mnMarkerSize
);
1083 aApiSymbol
.Size
= awt::Size( nApiSize
, nApiSize
);
1086 aApiSymbol
.FillColor
= sal_Int32( rMarkerFmt
.maFillColor
);
1087 aApiSymbol
.BorderColor
= ::get_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOLINE
) ?
1088 aApiSymbol
.FillColor
: sal_Int32( rMarkerFmt
.maLineColor
);
1091 rPropSet
.SetProperty( EXC_CHPROP_SYMBOL
, aApiSymbol
);
1094 void XclChPropSetHelper::WriteRotationProperties(
1095 ScfPropertySet
& rPropSet
, sal_uInt16 nRotation
, bool bSupportsStacked
)
1097 if( nRotation
!= EXC_CHART_AUTOROTATION
)
1099 // chart2 handles rotation as double in the range [0,360)
1100 double fAngle
= XclTools::GetScRotation( nRotation
, 0_deg100
).get() / 100.0;
1101 rPropSet
.SetProperty( EXC_CHPROP_TEXTROTATION
, fAngle
);
1102 if( bSupportsStacked
)
1103 rPropSet
.SetProperty( EXC_CHPROP_STACKCHARACTERS
, nRotation
== EXC_ROT_STACKED
);
1107 // private --------------------------------------------------------------------
1109 ScfPropSetHelper
& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode
)
1113 case EXC_CHPROPMODE_COMMON
: return maLineHlpCommon
;
1114 case EXC_CHPROPMODE_LINEARSERIES
: return maLineHlpLinear
;
1115 case EXC_CHPROPMODE_FILLEDSERIES
: return maLineHlpFilled
;
1116 default: OSL_FAIL( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1118 return maLineHlpCommon
;
1121 ScfPropSetHelper
& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode
)
1125 case EXC_CHPROPMODE_COMMON
: return maAreaHlpCommon
;
1126 case EXC_CHPROPMODE_FILLEDSERIES
: return maAreaHlpFilled
;
1127 default: OSL_FAIL( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1129 return maAreaHlpCommon
;
1132 ScfPropSetHelper
& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode
)
1136 case EXC_CHPROPMODE_COMMON
: return maGradHlpCommon
;
1137 case EXC_CHPROPMODE_FILLEDSERIES
: return maGradHlpFilled
;
1138 default: OSL_FAIL( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1140 return maGradHlpCommon
;
1143 ScfPropSetHelper
& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode
)
1147 case EXC_CHPROPMODE_COMMON
: return maHatchHlpCommon
;
1148 case EXC_CHPROPMODE_FILLEDSERIES
: return maHatchHlpFilled
;
1149 default: OSL_FAIL( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1151 return maHatchHlpCommon
;
1156 /* The following local functions implement getting the XShape interface of all
1157 supported title objects (chart and axes). This needs some effort due to the
1158 design of the old Chart1 API used to access these objects. */
1160 /** Returns the drawing shape of the main title, if existing. */
1161 uno::Reference
<drawing::XShape
> lclGetMainTitleShape(const uno::Reference
<chart::XChartDocument
> & rxChart1Doc
)
1163 ScfPropertySet
aPropSet(rxChart1Doc
);
1164 if (rxChart1Doc
.is() && aPropSet
.GetBoolProperty("HasMainTitle"))
1165 return rxChart1Doc
->getTitle();
1166 return uno::Reference
<drawing::XShape
>();
1169 uno::Reference
<drawing::XShape
> lclGetXAxisTitleShape(const uno::Reference
<chart::XChartDocument
> & rxChart1Doc
)
1171 uno::Reference
<chart::XAxisXSupplier
> xAxisSupp(rxChart1Doc
->getDiagram(), uno::UNO_QUERY
);
1172 ScfPropertySet
aPropSet(xAxisSupp
);
1173 if (xAxisSupp
.is() && aPropSet
.GetBoolProperty("HasXAxisTitle"))
1174 return xAxisSupp
->getXAxisTitle();
1175 return uno::Reference
<drawing::XShape
>();
1178 uno::Reference
<drawing::XShape
> lclGetYAxisTitleShape(const uno::Reference
<chart::XChartDocument
> & rxChart1Doc
)
1180 uno::Reference
<chart::XAxisYSupplier
> xAxisSupp(rxChart1Doc
->getDiagram(), uno::UNO_QUERY
);
1181 ScfPropertySet
aPropSet(xAxisSupp
);
1182 if (xAxisSupp
.is() && aPropSet
.GetBoolProperty("HasYAxisTitle"))
1183 return xAxisSupp
->getYAxisTitle();
1184 return uno::Reference
<drawing::XShape
>();
1187 uno::Reference
<drawing::XShape
> lclGetZAxisTitleShape(const uno::Reference
<chart::XChartDocument
> & rxChart1Doc
)
1189 uno::Reference
<chart::XAxisZSupplier
> xAxisSupp(rxChart1Doc
->getDiagram(), uno::UNO_QUERY
);
1190 ScfPropertySet
aPropSet(xAxisSupp
);
1191 if (xAxisSupp
.is() && aPropSet
.GetBoolProperty("HasZAxisTitle"))
1192 return xAxisSupp
->getZAxisTitle();
1193 return uno::Reference
<drawing::XShape
>();
1196 uno::Reference
<drawing::XShape
> lclGetSecXAxisTitleShape(const uno::Reference
<chart::XChartDocument
> & rxChart1Doc
)
1198 uno::Reference
<chart::XSecondAxisTitleSupplier
> xAxisSupp(rxChart1Doc
->getDiagram(), uno::UNO_QUERY
);
1199 ScfPropertySet
aPropSet(xAxisSupp
);
1200 if (xAxisSupp
.is() && aPropSet
.GetBoolProperty("HasSecondaryXAxisTitle"))
1201 return xAxisSupp
->getSecondXAxisTitle();
1202 return uno::Reference
<drawing::XShape
>();
1205 uno::Reference
<drawing::XShape
> lclGetSecYAxisTitleShape(const uno::Reference
<chart::XChartDocument
> & rxChart1Doc
)
1207 uno::Reference
<chart::XSecondAxisTitleSupplier
> xAxisSupp(rxChart1Doc
->getDiagram(), uno::UNO_QUERY
);
1208 ScfPropertySet
aPropSet(xAxisSupp
);
1209 if (xAxisSupp
.is() && aPropSet
.GetBoolProperty("HasSecondaryYAxisTitle"))
1210 return xAxisSupp
->getSecondYAxisTitle();
1211 return uno::Reference
<drawing::XShape
>();
1216 XclChRootData::XclChRootData()
1217 : mxTypeInfoProv(std::make_shared
<XclChTypeInfoProvider
>())
1218 , mxFmtInfoProv(std::make_shared
<XclChFormatInfoProvider
>())
1224 // remember some title shape getter functions
1225 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_TITLE
) ] = lclGetMainTitleShape
;
1226 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_X
) ] = lclGetXAxisTitleShape
;
1227 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_Y
) ] = lclGetYAxisTitleShape
;
1228 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_Z
) ] = lclGetZAxisTitleShape
;
1229 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_SECONDARY
, EXC_CHAXIS_X
) ] = lclGetSecXAxisTitleShape
;
1230 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_SECONDARY
, EXC_CHAXIS_Y
) ] = lclGetSecYAxisTitleShape
;
1233 XclChRootData::~XclChRootData()
1237 void XclChRootData::InitConversion(const XclRoot
& rRoot
, const uno::Reference
<chart2::XChartDocument
> & rxChartDoc
, const tools::Rectangle
& rChartRect
)
1239 // remember chart document reference and chart shape position/size
1240 OSL_ENSURE( rxChartDoc
.is(), "XclChRootData::InitConversion - missing chart document" );
1241 mxChartDoc
= rxChartDoc
;
1242 maChartRect
= rChartRect
;
1244 // Excel excludes a border of 5 pixels in each direction from chart area
1245 mnBorderGapX
= rRoot
.GetHmmFromPixelX( 5.0 );
1246 mnBorderGapY
= rRoot
.GetHmmFromPixelY( 5.0 );
1248 // size of a chart unit in 1/100 mm
1249 mfUnitSizeX
= std::max
<double>( maChartRect
.GetWidth() - 2 * mnBorderGapX
, mnBorderGapX
) / EXC_CHART_TOTALUNITS
;
1250 mfUnitSizeY
= std::max
<double>( maChartRect
.GetHeight() - 2 * mnBorderGapY
, mnBorderGapY
) / EXC_CHART_TOTALUNITS
;
1252 // create object tables
1253 uno::Reference
<lang::XMultiServiceFactory
> xFactory(mxChartDoc
, uno::UNO_QUERY
);
1254 mxLineDashTable
= std::make_shared
<XclChObjectTable
>(xFactory
, SERVICE_DRAWING_DASHTABLE
, "Excel line dash ");
1255 mxGradientTable
= std::make_shared
<XclChObjectTable
>(xFactory
, SERVICE_DRAWING_GRADIENTTABLE
, "Excel gradient ");
1256 mxHatchTable
= std::make_shared
<XclChObjectTable
>(xFactory
, SERVICE_DRAWING_HATCHTABLE
, "Excel hatch ");
1257 mxBitmapTable
= std::make_shared
<XclChObjectTable
>(xFactory
, SERVICE_DRAWING_BITMAPTABLE
, "Excel bitmap ");
1260 void XclChRootData::FinishConversion()
1262 // forget formatting object tables
1263 mxBitmapTable
.reset();
1264 mxHatchTable
.reset();
1265 mxGradientTable
.reset();
1266 mxLineDashTable
.reset();
1267 // forget chart document reference
1271 uno::Reference
<drawing::XShape
> XclChRootData::GetTitleShape(const XclChTextKey
& rTitleKey
) const
1273 XclChGetShapeFuncMap::const_iterator aIt
= maGetShapeFuncs
.find( rTitleKey
);
1274 OSL_ENSURE( aIt
!= maGetShapeFuncs
.end(), "XclChRootData::GetTitleShape - invalid title key" );
1275 uno::Reference
<chart::XChartDocument
> xChart1Doc( mxChartDoc
, uno::UNO_QUERY
);
1276 uno::Reference
<drawing::XShape
> xTitleShape
;
1277 if (xChart1Doc
.is() && (aIt
!= maGetShapeFuncs
.end()))
1278 xTitleShape
= (aIt
->second
)(xChart1Doc
);
1282 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */