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>
38 #include <sal/macros.h>
39 #include <rtl/math.hxx>
40 #include <svl/itemset.hxx>
41 #include <svx/xfillit0.hxx>
42 #include <svx/xflclit.hxx>
43 #include <svx/xfltrit.hxx>
44 #include <svx/xflgrit.hxx>
45 #include <svx/xbtmpit.hxx>
46 #include <svx/unomid.hxx>
47 #include <filter/msfilter/escherex.hxx>
48 #include <editeng/memberids.hrc>
51 #include "xlstyle.hxx"
53 using namespace com::sun::star
;
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 XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx
, sal_uInt16 nPointIdx
) :
75 mnSeriesIdx( nSeriesIdx
),
76 mnPointIdx( nPointIdx
)
80 bool operator<( const XclChDataPointPos
& rL
, const XclChDataPointPos
& rR
)
82 return (rL
.mnSeriesIdx
< rR
.mnSeriesIdx
) ||
83 ((rL
.mnSeriesIdx
== rR
.mnSeriesIdx
) && (rL
.mnPointIdx
< rR
.mnPointIdx
));
86 XclChFrBlock::XclChFrBlock( sal_uInt16 nType
) :
94 // Frame formatting ===========================================================
96 XclChFramePos::XclChFramePos() :
97 mnTLMode( EXC_CHFRAMEPOS_PARENT
),
98 mnBRMode( EXC_CHFRAMEPOS_PARENT
)
102 XclChLineFormat::XclChLineFormat() :
103 maColor( COL_BLACK
),
104 mnPattern( EXC_CHLINEFORMAT_SOLID
),
105 mnWeight( EXC_CHLINEFORMAT_SINGLE
),
106 mnFlags( EXC_CHLINEFORMAT_AUTO
)
110 XclChAreaFormat::XclChAreaFormat() :
111 maPattColor( COL_WHITE
),
112 maBackColor( COL_BLACK
),
113 mnPattern( EXC_PATT_SOLID
),
114 mnFlags( EXC_CHAREAFORMAT_AUTO
)
118 XclChEscherFormat::XclChEscherFormat()
122 XclChEscherFormat::~XclChEscherFormat()
126 XclChPicFormat::XclChPicFormat() :
127 mnBmpMode( EXC_CHPICFORMAT_NONE
),
128 mnFlags( EXC_CHPICFORMAT_TOPBOTTOM
| EXC_CHPICFORMAT_FRONTBACK
| EXC_CHPICFORMAT_LEFTRIGHT
),
133 XclChFrame::XclChFrame() :
134 mnFormat( EXC_CHFRAME_STANDARD
),
135 mnFlags( EXC_CHFRAME_AUTOSIZE
| EXC_CHFRAME_AUTOPOS
)
139 // Source links ===============================================================
141 XclChSourceLink::XclChSourceLink() :
142 mnDestType( EXC_CHSRCLINK_TITLE
),
143 mnLinkType( EXC_CHSRCLINK_DEFAULT
),
149 // Text =======================================================================
151 XclChObjectLink::XclChObjectLink() :
152 mnTarget( EXC_CHOBJLINK_NONE
)
156 XclChFrLabelProps::XclChFrLabelProps() :
161 XclChText::XclChText() :
162 maTextColor( COL_BLACK
),
163 mnHAlign( EXC_CHTEXT_ALIGN_CENTER
),
164 mnVAlign( EXC_CHTEXT_ALIGN_CENTER
),
165 mnBackMode( EXC_CHTEXT_TRANSPARENT
),
166 mnFlags( EXC_CHTEXT_AUTOCOLOR
| EXC_CHTEXT_AUTOFILL
),
167 mnFlags2( EXC_CHTEXT_POS_DEFAULT
),
168 mnRotation( EXC_ROT_NONE
)
172 // Data series ================================================================
174 XclChMarkerFormat::XclChMarkerFormat() :
175 maLineColor( COL_BLACK
),
176 maFillColor( COL_WHITE
),
177 mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE
),
178 mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL
),
179 mnFlags( EXC_CHMARKERFORMAT_AUTO
)
183 XclCh3dDataFormat::XclCh3dDataFormat() :
184 mnBase( EXC_CH3DDATAFORMAT_RECT
),
185 mnTop( EXC_CH3DDATAFORMAT_STRAIGHT
)
189 XclChDataFormat::XclChDataFormat() :
190 mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT
),
195 XclChSerTrendLine::XclChSerTrendLine() :
196 mfForecastFor( 0.0 ),
197 mfForecastBack( 0.0 ),
198 mnLineType( EXC_CHSERTREND_POLYNOMIAL
),
203 /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
204 there is no interception point. Cannot use ::rtl::math::setNan() here
205 cause it misses the sign bit. */
206 sal_math_Double
* pDouble
= reinterpret_cast< sal_math_Double
* >( &mfIntercept
);
207 pDouble
->w32_parts
.msw
= pDouble
->w32_parts
.lsw
= 0xFFFFFFFF;
210 XclChSerErrorBar::XclChSerErrorBar() :
213 mnBarType( EXC_CHSERERR_NONE
),
214 mnSourceType( EXC_CHSERERR_FIXED
),
215 mnLineEnd( EXC_CHSERERR_END_TSHAPE
)
219 XclChSeries::XclChSeries() :
220 mnCategType( EXC_CHSERIES_NUMERIC
),
221 mnValueType( EXC_CHSERIES_NUMERIC
),
222 mnBubbleType( EXC_CHSERIES_NUMERIC
),
229 // Chart type groups ==========================================================
231 XclChType::XclChType() :
237 mnBubbleType( EXC_CHSCATTER_AREA
),
242 XclChChart3d::XclChChart3d() :
249 mnFlags( EXC_CHCHART3D_AUTOHEIGHT
)
253 XclChLegend::XclChLegend() :
254 mnDockMode( EXC_CHLEGEND_RIGHT
),
255 mnSpacing( EXC_CHLEGEND_MEDIUM
),
256 mnFlags( EXC_CHLEGEND_DOCKED
| EXC_CHLEGEND_AUTOSERIES
|
257 EXC_CHLEGEND_AUTOPOSX
| EXC_CHLEGEND_AUTOPOSY
| EXC_CHLEGEND_STACKED
)
261 XclChTypeGroup::XclChTypeGroup() :
263 mnGroupIdx( EXC_CHSERGROUP_NONE
)
267 XclChProperties::XclChProperties() :
269 mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP
)
273 // Axes =======================================================================
275 XclChLabelRange::XclChLabelRange() :
283 XclChDateRange::XclChDateRange() :
287 mnMajorUnit( EXC_CHDATERANGE_DAYS
),
289 mnMinorUnit( EXC_CHDATERANGE_DAYS
),
290 mnBaseUnit( EXC_CHDATERANGE_DAYS
),
292 mnFlags( EXC_CHDATERANGE_AUTOMIN
| EXC_CHDATERANGE_AUTOMAX
|
293 EXC_CHDATERANGE_AUTOMAJOR
| EXC_CHDATERANGE_AUTOMINOR
|
294 EXC_CHDATERANGE_AUTOBASE
| EXC_CHDATERANGE_AUTOCROSS
|
295 EXC_CHDATERANGE_AUTODATE
)
299 XclChValueRange::XclChValueRange() :
305 mnFlags( EXC_CHVALUERANGE_AUTOMIN
| EXC_CHVALUERANGE_AUTOMAX
|
306 EXC_CHVALUERANGE_AUTOMAJOR
| EXC_CHVALUERANGE_AUTOMINOR
|
307 EXC_CHVALUERANGE_AUTOCROSS
| EXC_CHVALUERANGE_BIT8
)
311 XclChTick::XclChTick() :
312 maTextColor( COL_BLACK
),
313 mnMajor( EXC_CHTICK_INSIDE
| EXC_CHTICK_OUTSIDE
),
315 mnLabelPos( EXC_CHTICK_NEXT
),
316 mnBackMode( EXC_CHTICK_TRANSPARENT
),
317 mnFlags( EXC_CHTICK_AUTOCOLOR
| EXC_CHTICK_AUTOROT
),
318 mnRotation( EXC_ROT_NONE
)
322 XclChAxis::XclChAxis() :
323 mnType( EXC_CHAXIS_NONE
)
327 sal_Int32
XclChAxis::GetApiAxisDimension() const
329 sal_Int32 nApiAxisDim
= EXC_CHART_AXIS_NONE
;
332 case EXC_CHAXIS_X
: nApiAxisDim
= EXC_CHART_AXIS_X
; break;
333 case EXC_CHAXIS_Y
: nApiAxisDim
= EXC_CHART_AXIS_Y
; break;
334 case EXC_CHAXIS_Z
: nApiAxisDim
= EXC_CHART_AXIS_Z
; break;
339 XclChAxesSet::XclChAxesSet() :
340 mnAxesSetId( EXC_CHAXESSET_PRIMARY
)
344 sal_Int32
XclChAxesSet::GetApiAxesSetIndex() const
346 sal_Int32 nApiAxesSetIdx
= EXC_CHART_AXESSET_NONE
;
347 switch( mnAxesSetId
)
349 case EXC_CHAXESSET_PRIMARY
: nApiAxesSetIdx
= EXC_CHART_AXESSET_PRIMARY
; break;
350 case EXC_CHAXESSET_SECONDARY
: nApiAxesSetIdx
= EXC_CHART_AXESSET_SECONDARY
; break;
352 return nApiAxesSetIdx
;
355 // Static helper functions ====================================================
357 sal_uInt16
XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx
)
359 static const sal_uInt16 spnLineColors
[] =
361 32, 33, 34, 35, 36, 37, 38, 39,
362 40, 41, 42, 43, 44, 45, 46, 47,
363 48, 49, 50, 51, 52, 53, 54, 55,
364 56, 57, 58, 59, 60, 61, 62, 8,
365 9, 10, 11, 12, 13, 14, 15, 16,
366 17, 18, 19, 20, 21, 22, 23, 24,
367 25, 26, 27, 28, 29, 30, 31, 63
369 return spnLineColors
[ nFormatIdx
% SAL_N_ELEMENTS( spnLineColors
) ];
372 sal_uInt16
XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx
)
374 static const sal_uInt16 spnFillColors
[] =
376 24, 25, 26, 27, 28, 29, 30, 31,
377 32, 33, 34, 35, 36, 37, 38, 39,
378 40, 41, 42, 43, 44, 45, 46, 47,
379 48, 49, 50, 51, 52, 53, 54, 55,
380 56, 57, 58, 59, 60, 61, 62, 63,
381 8, 9, 10, 11, 12, 13, 14, 15,
382 16, 17, 18, 19, 20, 21, 22, 23
384 return spnFillColors
[ nFormatIdx
% SAL_N_ELEMENTS( spnFillColors
) ];
387 sal_uInt8
XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx
)
389 static const sal_uInt8 spnTrans
[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
390 return spnTrans
[ (nFormatIdx
/ 56) % SAL_N_ELEMENTS( spnTrans
) ];
393 sal_uInt16
XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx
)
395 static const sal_uInt16 spnSymbols
[] = {
396 EXC_CHMARKERFORMAT_DIAMOND
, EXC_CHMARKERFORMAT_SQUARE
, EXC_CHMARKERFORMAT_TRIANGLE
,
397 EXC_CHMARKERFORMAT_CROSS
, EXC_CHMARKERFORMAT_STAR
, EXC_CHMARKERFORMAT_CIRCLE
,
398 EXC_CHMARKERFORMAT_PLUS
, EXC_CHMARKERFORMAT_DOWJ
, EXC_CHMARKERFORMAT_STDDEV
};
399 return spnSymbols
[ nFormatIdx
% SAL_N_ELEMENTS( spnSymbols
) ];
402 bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType
)
404 static const bool spbFilled
[] = {
405 false, true, true, true, false, false, false, false, true, false };
406 return (nMarkerType
< SAL_N_ELEMENTS( spbFilled
)) && spbFilled
[ nMarkerType
];
409 OUString
XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType
)
413 case EXC_CHSERERR_XPLUS
: return OUString( EXC_CHPROP_ROLE_ERRORBARS_POSX
);
414 case EXC_CHSERERR_XMINUS
: return OUString( EXC_CHPROP_ROLE_ERRORBARS_NEGX
);
415 case EXC_CHSERERR_YPLUS
: return OUString( EXC_CHPROP_ROLE_ERRORBARS_POSY
);
416 case EXC_CHSERERR_YMINUS
: return OUString( EXC_CHPROP_ROLE_ERRORBARS_NEGY
);
417 default: OSL_FAIL( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
422 // Chart formatting info provider =============================================
426 static const XclChFormatInfo spFmtInfos
[] =
428 // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
429 { EXC_CHOBJTYPE_BACKGROUND
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, true, true, true },
430 { EXC_CHOBJTYPE_PLOTFRAME
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, true, true, true },
431 { EXC_CHOBJTYPE_WALL3D
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, true, false, true },
432 { EXC_CHOBJTYPE_FLOOR3D
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, 23, EXC_CHFRAMETYPE_AUTO
, true, false, true },
433 { EXC_CHOBJTYPE_TEXT
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, true, true },
434 { EXC_CHOBJTYPE_LEGEND
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, true, true, true },
435 { EXC_CHOBJTYPE_LINEARSERIES
, EXC_CHPROPMODE_LINEARSERIES
, 0xFFFF, EXC_CHLINEFORMAT_SINGLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, false, false, false },
436 { EXC_CHOBJTYPE_FILLEDSERIES
, EXC_CHPROPMODE_FILLEDSERIES
, EXC_COLOR_CHBORDERAUTO
, EXC_CHLINEFORMAT_SINGLE
, 0xFFFF, EXC_CHFRAMETYPE_AUTO
, false, false, true },
437 { EXC_CHOBJTYPE_AXISLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, false, false, false },
438 { EXC_CHOBJTYPE_GRIDLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, true, false },
439 { EXC_CHOBJTYPE_TRENDLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_DOUBLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
440 { EXC_CHOBJTYPE_ERRORBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_SINGLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
441 { EXC_CHOBJTYPE_CONNECTLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
442 { EXC_CHOBJTYPE_HILOLINE
, EXC_CHPROPMODE_LINEARSERIES
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
443 { EXC_CHOBJTYPE_WHITEDROPBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, true },
444 { EXC_CHOBJTYPE_BLACKDROPBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, true }
449 XclChFormatInfoProvider::XclChFormatInfoProvider()
451 for(auto const &rIt
: spFmtInfos
)
452 maInfoMap
[ rIt
.meObjType
] = &rIt
;
455 const XclChFormatInfo
& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType
) const
457 XclFmtInfoMap::const_iterator aIt
= maInfoMap
.find( eObjType
);
458 OSL_ENSURE( aIt
!= maInfoMap
.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
459 return (aIt
== maInfoMap
.end()) ? *spFmtInfos
: *aIt
->second
;
462 // Chart type info provider ===================================================
466 // chart type service names
467 const sal_Char SERVICE_CHART2_AREA
[] = "com.sun.star.chart2.AreaChartType";
468 const sal_Char SERVICE_CHART2_CANDLE
[] = "com.sun.star.chart2.CandleStickChartType";
469 const sal_Char SERVICE_CHART2_COLUMN
[] = "com.sun.star.chart2.ColumnChartType";
470 const sal_Char SERVICE_CHART2_LINE
[] = "com.sun.star.chart2.LineChartType";
471 const sal_Char SERVICE_CHART2_NET
[] = "com.sun.star.chart2.NetChartType";
472 const sal_Char SERVICE_CHART2_FILLEDNET
[] = "com.sun.star.chart2.FilledNetChartType";
473 const sal_Char SERVICE_CHART2_PIE
[] = "com.sun.star.chart2.PieChartType";
474 const sal_Char SERVICE_CHART2_SCATTER
[] = "com.sun.star.chart2.ScatterChartType";
475 const sal_Char SERVICE_CHART2_BUBBLE
[] = "com.sun.star.chart2.BubbleChartType";
476 const sal_Char SERVICE_CHART2_SURFACE
[] = "com.sun.star.chart2.ColumnChartType"; // Todo
478 namespace csscd
= cssc::DataLabelPlacement
;
480 static const XclChTypeInfo spTypeInfos
[] =
482 // 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
483 { 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 },
484 { 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 },
485 { 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 },
486 { 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 },
487 { 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 },
488 { 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 },
489 { 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 },
490 { 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 },
491 { 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 },
492 { 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 },
493 { 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 },
494 { 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 },
495 { 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 },
496 { 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 }
501 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo
& rTypeInfo
) :
502 XclChTypeInfo( rTypeInfo
),
508 void XclChExtTypeInfo::Set( const XclChTypeInfo
& rTypeInfo
, bool b3dChart
, bool bSpline
)
510 static_cast< XclChTypeInfo
& >( *this ) = rTypeInfo
;
511 mb3dChart
= mbSupports3d
&& b3dChart
;
515 XclChTypeInfoProvider::XclChTypeInfoProvider()
517 for(const auto &rIt
: spTypeInfos
)
518 maInfoMap
[ rIt
.meTypeId
] = &rIt
;
521 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId
) const
523 XclChTypeInfoMap::const_iterator aIt
= maInfoMap
.find( eTypeId
);
524 OSL_ENSURE( aIt
!= maInfoMap
.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
525 return (aIt
== maInfoMap
.end()) ? *maInfoMap
.rbegin()->second
: *aIt
->second
;
528 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId
) const
530 for(const auto &rIt
: spTypeInfos
)
532 if(rIt
.mnRecId
== nRecId
)
535 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
536 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
539 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString
& rServiceName
) const
541 for(auto const &rIt
: spTypeInfos
)
542 if( rServiceName
.equalsAscii( rIt
.mpcServiceName
) )
544 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
545 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
548 // Property helpers ===========================================================
550 XclChObjectTable::XclChObjectTable( Reference
< XMultiServiceFactory
> xFactory
,
551 const OUString
& rServiceName
, const OUString
& rObjNameBase
) :
552 mxFactory( xFactory
),
553 maServiceName( rServiceName
),
554 maObjNameBase( rObjNameBase
),
559 Any
XclChObjectTable::GetObject( const OUString
& rObjName
)
562 if( !mxContainer
.is() )
563 mxContainer
.set( ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), UNO_QUERY
);
564 OSL_ENSURE( mxContainer
.is(), "XclChObjectTable::GetObject - container not found" );
567 if( mxContainer
.is() )
569 // get object from container
572 aObj
= mxContainer
->getByName( rObjName
);
576 OSL_FAIL( "XclChObjectTable::GetObject - object not found" );
582 OUString
XclChObjectTable::InsertObject( const Any
& rObj
)
585 // create object table
586 if( !mxContainer
.is() )
587 mxContainer
.set( ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), UNO_QUERY
);
588 OSL_ENSURE( mxContainer
.is(), "XclChObjectTable::InsertObject - container not found" );
591 if( mxContainer
.is() )
593 // create new unused identifier
596 aObjName
= maObjNameBase
+ OUString::number( ++mnIndex
);
598 while( mxContainer
->hasByName( aObjName
) );
603 mxContainer
->insertByName( aObjName
, rObj
);
607 OSL_FAIL( "XclChObjectTable::InsertObject - cannot insert object" );
614 // Property names -------------------------------------------------------------
618 /** Property names for line style in common objects. */
619 const sal_Char
* const sppcLineNamesCommon
[] =
620 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", nullptr };
621 /** Property names for line style in linear series objects. */
622 const sal_Char
* const sppcLineNamesLinear
[] =
623 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", nullptr };
624 /** Property names for line style in filled series objects. */
625 const sal_Char
* const sppcLineNamesFilled
[] =
626 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", nullptr };
628 /** Property names for solid area style in common objects. */
629 const sal_Char
* const sppcAreaNamesCommon
[] = { "FillStyle", "FillColor", "FillTransparence", nullptr };
630 /** Property names for solid area style in filled series objects. */
631 const sal_Char
* const sppcAreaNamesFilled
[] = { "FillStyle", "Color", "Transparency", nullptr };
632 /** Property names for gradient area style in common objects. */
633 const sal_Char
* const sppcGradNamesCommon
[] = { "FillStyle", "FillGradientName", nullptr };
634 /** Property names for gradient area style in filled series objects. */
635 const sal_Char
* const sppcGradNamesFilled
[] = { "FillStyle", "GradientName", nullptr };
636 /** Property names for hatch area style in common objects. */
637 const sal_Char
* const sppcHatchNamesCommon
[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", nullptr };
638 /** Property names for hatch area style in filled series objects. */
639 const sal_Char
* const sppcHatchNamesFilled
[] = { "FillStyle", "HatchName", "Color", "FillBackground", nullptr };
640 /** Property names for bitmap area style. */
641 const sal_Char
* const sppcBitmapNames
[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", nullptr };
645 XclChPropSetHelper::XclChPropSetHelper() :
646 maLineHlpCommon( sppcLineNamesCommon
),
647 maLineHlpLinear( sppcLineNamesLinear
),
648 maLineHlpFilled( sppcLineNamesFilled
),
649 maAreaHlpCommon( sppcAreaNamesCommon
),
650 maAreaHlpFilled( sppcAreaNamesFilled
),
651 maGradHlpCommon( sppcGradNamesCommon
),
652 maGradHlpFilled( sppcGradNamesFilled
),
653 maHatchHlpCommon( sppcHatchNamesCommon
),
654 maHatchHlpFilled( sppcHatchNamesFilled
),
655 maBitmapHlp( sppcBitmapNames
)
659 // read properties ------------------------------------------------------------
661 void XclChPropSetHelper::ReadLineProperties(
662 XclChLineFormat
& rLineFmt
, XclChObjectTable
& rDashTable
,
663 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
665 namespace cssd
= ::com::sun::star::drawing
;
667 // read properties from property set
668 cssd::LineStyle eApiStyle
= cssd::LineStyle_NONE
;
669 sal_Int32 nApiWidth
= 0;
670 sal_Int16 nApiTrans
= 0;
673 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
674 rLineHlp
.ReadFromPropertySet( rPropSet
);
675 rLineHlp
>> eApiStyle
>> nApiWidth
>> rLineFmt
.maColor
>> nApiTrans
>> aDashNameAny
;
677 // clear automatic flag
678 ::set_flag( rLineFmt
.mnFlags
, EXC_CHLINEFORMAT_AUTO
, false );
681 if( nApiWidth
<= 0 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_HAIR
;
682 else if( nApiWidth
<= 35 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_SINGLE
;
683 else if( nApiWidth
<= 70 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_DOUBLE
;
684 else rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_TRIPLE
;
689 case cssd::LineStyle_NONE
:
690 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
692 case cssd::LineStyle_SOLID
:
694 if( nApiTrans
< 13 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
695 else if( nApiTrans
< 38 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DARKTRANS
;
696 else if( nApiTrans
< 63 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_MEDTRANS
;
697 else if( nApiTrans
< 100 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_LIGHTTRANS
;
698 else rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
701 case cssd::LineStyle_DASH
:
703 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
705 cssd::LineDash aApiDash
;
706 if( (aDashNameAny
>>= aDashName
) && (rDashTable
.GetObject( aDashName
) >>= aApiDash
) )
708 // reorder dashes that are shorter than dots
709 if( (aApiDash
.Dashes
== 0) || (aApiDash
.DashLen
< aApiDash
.DotLen
) )
711 ::std::swap( aApiDash
.Dashes
, aApiDash
.Dots
);
712 ::std::swap( aApiDash
.DashLen
, aApiDash
.DotLen
);
714 // ignore dots that are nearly equal to dashes
715 if( aApiDash
.DotLen
* 3 > aApiDash
.DashLen
* 2 )
718 // convert line dash to predefined Excel dash types
719 if( (aApiDash
.Dashes
== 1) && (aApiDash
.Dots
>= 1) )
720 // one dash and one or more dots
721 rLineFmt
.mnPattern
= (aApiDash
.Dots
== 1) ?
722 EXC_CHLINEFORMAT_DASHDOT
: EXC_CHLINEFORMAT_DASHDOTDOT
;
723 else if( aApiDash
.Dashes
>= 1 )
724 // one or more dashes and no dots (also: dash-dash-dot)
725 rLineFmt
.mnPattern
= (aApiDash
.DashLen
< 250) ?
726 EXC_CHLINEFORMAT_DOT
: EXC_CHLINEFORMAT_DASH
;
731 OSL_FAIL( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
732 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
736 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat
& rAreaFmt
,
737 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
739 namespace cssd
= ::com::sun::star::drawing
;
741 // read properties from property set
742 cssd::FillStyle eApiStyle
= cssd::FillStyle_NONE
;
743 sal_Int16 nTransparency
= 0;
745 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
746 rAreaHlp
.ReadFromPropertySet( rPropSet
);
747 rAreaHlp
>> eApiStyle
>> rAreaFmt
.maPattColor
>> nTransparency
;
749 // clear automatic flag
750 ::set_flag( rAreaFmt
.mnFlags
, EXC_CHAREAFORMAT_AUTO
, false );
752 // set fill style transparent or solid (set solid for anything but transparent)
753 rAreaFmt
.mnPattern
= (eApiStyle
== cssd::FillStyle_NONE
) ? EXC_PATT_NONE
: EXC_PATT_SOLID
;
755 // return true to indicate complex fill (gradient, bitmap, solid transparency)
756 return (eApiStyle
!= cssd::FillStyle_NONE
) && ((eApiStyle
!= cssd::FillStyle_SOLID
) || (nTransparency
> 0));
759 void XclChPropSetHelper::ReadEscherProperties(
760 XclChEscherFormat
& rEscherFmt
, XclChPicFormat
& rPicFmt
,
761 XclChObjectTable
& rGradientTable
, XclChObjectTable
& rHatchTable
, XclChObjectTable
& rBitmapTable
,
762 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
764 namespace cssd
= ::com::sun::star::drawing
;
765 namespace cssa
= ::com::sun::star::awt
;
767 // read style and transparency properties from property set
768 cssd::FillStyle eApiStyle
= cssd::FillStyle_NONE
;
770 sal_Int16 nTransparency
= 0;
772 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
773 rAreaHlp
.ReadFromPropertySet( rPropSet
);
774 rAreaHlp
>> eApiStyle
>> aColor
>> nTransparency
;
778 case cssd::FillStyle_SOLID
:
780 OSL_ENSURE( nTransparency
> 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
781 if( (0 < nTransparency
) && (nTransparency
<= 100) )
783 // convert to Escher properties
784 sal_uInt32 nEscherColor
= 0x02000000;
785 ::insert_value( nEscherColor
, aColor
.GetBlue(), 16, 8 );
786 ::insert_value( nEscherColor
, aColor
.GetGreen(), 8, 8 );
787 ::insert_value( nEscherColor
, aColor
.GetRed(), 0, 8 );
788 sal_uInt32 nEscherOpacity
= static_cast< sal_uInt32
>( (100 - nTransparency
) * 655.36 );
789 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
790 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillType
, ESCHER_FillSolid
);
791 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillColor
, nEscherColor
);
792 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillOpacity
, nEscherOpacity
);
793 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackColor
, 0x02FFFFFF );
794 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackOpacity
, 0x00010000 );
795 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x001F001C );
799 case cssd::FillStyle_GRADIENT
:
801 // extract gradient from global gradient table
802 OUString aGradientName
;
803 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
804 rGradHlp
.ReadFromPropertySet( rPropSet
);
805 rGradHlp
>> eApiStyle
>> aGradientName
;
806 cssa::Gradient aGradient
;
807 if( rGradientTable
.GetObject( aGradientName
) >>= aGradient
)
809 // convert to Escher properties
810 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
811 rEscherFmt
.mxEscherSet
->CreateGradientProperties( aGradient
);
815 case cssd::FillStyle_HATCH
:
817 // extract hatch from global hatch table
819 bool bFillBackground
;
820 ScfPropSetHelper
& rHatchHlp
= GetHatchHelper( ePropMode
);
821 rHatchHlp
.ReadFromPropertySet( rPropSet
);
822 rHatchHlp
>> eApiStyle
>> aHatchName
>> aColor
>> bFillBackground
;
824 if( rHatchTable
.GetObject( aHatchName
) >>= aHatch
)
826 // convert to Escher properties
827 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
828 rEscherFmt
.mxEscherSet
->CreateEmbeddedHatchProperties( aHatch
, aColor
, bFillBackground
);
829 rPicFmt
.mnBmpMode
= EXC_CHPICFORMAT_STACK
;
833 case cssd::FillStyle_BITMAP
:
835 // extract bitmap URL from global bitmap table
836 OUString aBitmapName
;
837 cssd::BitmapMode eApiBmpMode
;
838 maBitmapHlp
.ReadFromPropertySet( rPropSet
);
839 maBitmapHlp
>> eApiStyle
>> aBitmapName
>> eApiBmpMode
;
841 if( rBitmapTable
.GetObject( aBitmapName
) >>= aBitmapUrl
)
843 // convert to Escher properties
844 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
845 rEscherFmt
.mxEscherSet
->CreateEmbeddedBitmapProperties( aBitmapUrl
, eApiBmpMode
);
846 rPicFmt
.mnBmpMode
= (eApiBmpMode
== cssd::BitmapMode_REPEAT
) ?
847 EXC_CHPICFORMAT_STACK
: EXC_CHPICFORMAT_STRETCH
;
852 OSL_FAIL( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
856 void XclChPropSetHelper::ReadMarkerProperties(
857 XclChMarkerFormat
& rMarkerFmt
, const ScfPropertySet
& rPropSet
, sal_uInt16 nFormatIdx
)
859 namespace cssc
= ::com::sun::star::chart2
;
860 cssc::Symbol aApiSymbol
;
861 if( rPropSet
.GetProperty( aApiSymbol
, EXC_CHPROP_SYMBOL
) )
863 // clear automatic flag
864 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_AUTO
, false );
867 switch( aApiSymbol
.Style
)
869 case cssc::SymbolStyle_NONE
:
870 rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_NOSYMBOL
;
872 case cssc::SymbolStyle_STANDARD
:
873 switch( aApiSymbol
.StandardSymbol
)
875 case 0: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_SQUARE
; break; // square
876 case 1: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DIAMOND
; break; // diamond
877 case 2: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STDDEV
; break; // arrow down
878 case 3: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_TRIANGLE
; break; // arrow up
879 case 4: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DOWJ
; break; // arrow right, same as import
880 case 5: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_PLUS
; break; // arrow left
881 case 6: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CROSS
; break; // bow tie
882 case 7: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // sand glass
883 case 8: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CIRCLE
; break; // circle new in LibO3.5
884 case 9: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DIAMOND
; break; // star new in LibO3.5
885 case 10: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CROSS
; break; // X new in LibO3.5
886 case 11: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_PLUS
; break; // plus new in LibO3.5
887 case 12: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // asterisk new in LibO3.5
888 case 13: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STDDEV
; break; // horizontal bar new in LibO3.5
889 case 14: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // vertical bar new in LibO3.5
890 default: rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
894 rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
896 bool bHasFillColor
= XclChartHelper::HasMarkerFillColor( rMarkerFmt
.mnMarkerType
);
897 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOFILL
, !bHasFillColor
);
900 sal_Int32 nApiSize
= (aApiSymbol
.Size
.Width
+ aApiSymbol
.Size
.Height
+ 1) / 2;
901 rMarkerFmt
.mnMarkerSize
= XclTools::GetTwipsFromHmm( nApiSize
);
904 rMarkerFmt
.maLineColor
= ScfApiHelper::ConvertFromApiColor( aApiSymbol
.BorderColor
);
905 rMarkerFmt
.maFillColor
= ScfApiHelper::ConvertFromApiColor( aApiSymbol
.FillColor
);
909 sal_uInt16
XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet
& rPropSet
, bool bSupportsStacked
)
911 // chart2 handles rotation as double in the range [0,360)
913 rPropSet
.GetProperty( fAngle
, EXC_CHPROP_TEXTROTATION
);
914 bool bStacked
= bSupportsStacked
&& rPropSet
.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS
);
915 return bStacked
? EXC_ROT_STACKED
:
916 XclTools::GetXclRotation( static_cast< sal_Int32
>( fAngle
* 100.0 + 0.5 ) );
919 // write properties -----------------------------------------------------------
921 void XclChPropSetHelper::WriteLineProperties(
922 ScfPropertySet
& rPropSet
, XclChObjectTable
& rDashTable
,
923 const XclChLineFormat
& rLineFmt
, XclChPropertyMode ePropMode
)
925 namespace cssd
= ::com::sun::star::drawing
;
928 sal_Int32 nApiWidth
= 0; // 0 is the width of a hair line
929 switch( rLineFmt
.mnWeight
)
931 case EXC_CHLINEFORMAT_SINGLE
: nApiWidth
= 35; break;
932 case EXC_CHLINEFORMAT_DOUBLE
: nApiWidth
= 70; break;
933 case EXC_CHLINEFORMAT_TRIPLE
: nApiWidth
= 105; break;
937 cssd::LineStyle eApiStyle
= cssd::LineStyle_NONE
;
938 sal_Int16 nApiTrans
= 0;
939 sal_Int32 nDotLen
= ::std::min
< sal_Int32
>( rLineFmt
.mnWeight
+ 105, 210 );
940 cssd::LineDash
aApiDash( cssd::DashStyle_RECT
, 0, nDotLen
, 0, 4 * nDotLen
, nDotLen
);
942 switch( rLineFmt
.mnPattern
)
944 case EXC_CHLINEFORMAT_SOLID
:
945 eApiStyle
= cssd::LineStyle_SOLID
;
947 case EXC_CHLINEFORMAT_DARKTRANS
:
948 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 25;
950 case EXC_CHLINEFORMAT_MEDTRANS
:
951 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 50;
953 case EXC_CHLINEFORMAT_LIGHTTRANS
:
954 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 75;
956 case EXC_CHLINEFORMAT_DASH
:
957 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= 1;
959 case EXC_CHLINEFORMAT_DOT
:
960 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dots
= 1;
962 case EXC_CHLINEFORMAT_DASHDOT
:
963 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= aApiDash
.Dots
= 1;
965 case EXC_CHLINEFORMAT_DASHDOTDOT
:
966 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= 1; aApiDash
.Dots
= 2;
971 sal_Int32 nApiColor
= ScfApiHelper::ConvertToApiColor( rLineFmt
.maColor
);
973 // try to insert the dash style and receive its name
975 if( eApiStyle
== cssd::LineStyle_DASH
)
977 OUString aDashName
= rDashTable
.InsertObject( css::uno::makeAny( aApiDash
) );
978 if( !aDashName
.isEmpty() )
979 aDashNameAny
<<= aDashName
;
982 // write the properties
983 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
984 rLineHlp
.InitializeWrite();
985 rLineHlp
<< eApiStyle
<< nApiWidth
<< nApiColor
<< nApiTrans
<< aDashNameAny
;
986 rLineHlp
.WriteToPropertySet( rPropSet
);
989 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet
& rPropSet
,
990 const XclChAreaFormat
& rAreaFmt
, XclChPropertyMode ePropMode
)
992 namespace cssd
= ::com::sun::star::drawing
;
993 cssd::FillStyle eFillStyle
= cssd::FillStyle_NONE
;
995 sal_Int16 nTransparency
= 0;
998 if( rAreaFmt
.mnPattern
!= EXC_PATT_NONE
)
1000 eFillStyle
= cssd::FillStyle_SOLID
;
1001 aColor
= XclTools::GetPatternColor( rAreaFmt
.maPattColor
, rAreaFmt
.maBackColor
, rAreaFmt
.mnPattern
);
1004 // write the properties
1005 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
1006 rAreaHlp
.InitializeWrite();
1007 rAreaHlp
<< eFillStyle
<< aColor
<< nTransparency
;
1008 rAreaHlp
.WriteToPropertySet( rPropSet
);
1011 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet
& rPropSet
,
1012 XclChObjectTable
& rGradientTable
, XclChObjectTable
& /*rHatchTable*/, XclChObjectTable
& rBitmapTable
,
1013 const XclChEscherFormat
& rEscherFmt
, const XclChPicFormat
* pPicFmt
,
1014 sal_uInt32 nDffFillType
, XclChPropertyMode ePropMode
)
1016 if( rEscherFmt
.mxItemSet
)
1018 if( const XFillStyleItem
* pStyleItem
= static_cast< const XFillStyleItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLSTYLE
, false ) ) )
1020 switch( pStyleItem
->GetValue() )
1022 case drawing::FillStyle_SOLID
:
1023 // #i84812# Excel 2007 writes Escher properties for solid fill
1024 if( const XFillColorItem
* pColorItem
= static_cast< const XFillColorItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLCOLOR
, false ) ) )
1026 namespace cssd
= ::com::sun::star::drawing
;
1027 // get solid transparence too
1028 const XFillTransparenceItem
* pTranspItem
= static_cast< const XFillTransparenceItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLTRANSPARENCE
, false ) );
1029 sal_uInt16 nTransp
= pTranspItem
? pTranspItem
->GetValue() : 0;
1030 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
1031 rAreaHlp
.InitializeWrite();
1032 rAreaHlp
<< cssd::FillStyle_SOLID
<< pColorItem
->GetColorValue() << static_cast< sal_Int16
>( nTransp
);
1033 rAreaHlp
.WriteToPropertySet( rPropSet
);
1036 case drawing::FillStyle_GRADIENT
:
1037 if( const XFillGradientItem
* pGradItem
= static_cast< const XFillGradientItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLGRADIENT
, false ) ) )
1040 if( pGradItem
->QueryValue( aGradientAny
, MID_FILLGRADIENT
) )
1042 OUString aGradName
= rGradientTable
.InsertObject( aGradientAny
);
1043 if( !aGradName
.isEmpty() )
1045 namespace cssd
= ::com::sun::star::drawing
;
1046 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
1047 rGradHlp
.InitializeWrite();
1048 rGradHlp
<< cssd::FillStyle_GRADIENT
<< aGradName
;
1049 rGradHlp
.WriteToPropertySet( rPropSet
);
1054 case drawing::FillStyle_BITMAP
:
1055 if( const XFillBitmapItem
* pBmpItem
= static_cast< const XFillBitmapItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLBITMAP
, false ) ) )
1058 if( pBmpItem
->QueryValue( aBitmapAny
, MID_GRAFURL
) )
1060 OUString aBmpName
= rBitmapTable
.InsertObject( aBitmapAny
);
1061 if( !aBmpName
.isEmpty() )
1063 namespace cssd
= ::com::sun::star::drawing
;
1064 /* #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode.
1065 If not passed, detect fill mode from the DFF property 'fill-type'. */
1066 bool bStretch
= pPicFmt
? (pPicFmt
->mnBmpMode
== EXC_CHPICFORMAT_STRETCH
) : (nDffFillType
== mso_fillPicture
);
1067 cssd::BitmapMode eApiBmpMode
= bStretch
? cssd::BitmapMode_STRETCH
: cssd::BitmapMode_REPEAT
;
1068 maBitmapHlp
.InitializeWrite();
1069 maBitmapHlp
<< cssd::FillStyle_BITMAP
<< aBmpName
<< eApiBmpMode
;
1070 maBitmapHlp
.WriteToPropertySet( rPropSet
);
1076 OSL_FAIL( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1082 void XclChPropSetHelper::WriteMarkerProperties(
1083 ScfPropertySet
& rPropSet
, const XclChMarkerFormat
& rMarkerFmt
)
1085 namespace cssc
= ::com::sun::star::chart2
;
1086 namespace cssa
= ::com::sun::star::awt
;
1089 cssc::Symbol aApiSymbol
;
1090 aApiSymbol
.Style
= cssc::SymbolStyle_STANDARD
;
1091 switch( rMarkerFmt
.mnMarkerType
)
1093 case EXC_CHMARKERFORMAT_NOSYMBOL
: aApiSymbol
.Style
= cssc::SymbolStyle_NONE
; break;
1094 case EXC_CHMARKERFORMAT_SQUARE
: aApiSymbol
.StandardSymbol
= 0; break; // square
1095 case EXC_CHMARKERFORMAT_DIAMOND
: aApiSymbol
.StandardSymbol
= 1; break; // diamond
1096 case EXC_CHMARKERFORMAT_TRIANGLE
: aApiSymbol
.StandardSymbol
= 3; break; // arrow up
1097 case EXC_CHMARKERFORMAT_CROSS
: aApiSymbol
.StandardSymbol
= 10; break; // X, legacy bow tie
1098 case EXC_CHMARKERFORMAT_STAR
: aApiSymbol
.StandardSymbol
= 12; break; // asterisk, legacy sand glass
1099 case EXC_CHMARKERFORMAT_DOWJ
: aApiSymbol
.StandardSymbol
= 4; break; // arrow right, same as export
1100 case EXC_CHMARKERFORMAT_STDDEV
: aApiSymbol
.StandardSymbol
= 13; break; // horizontal bar, legacy arrow down
1101 case EXC_CHMARKERFORMAT_CIRCLE
: aApiSymbol
.StandardSymbol
= 8; break; // circle, legacy arrow right
1102 case EXC_CHMARKERFORMAT_PLUS
: aApiSymbol
.StandardSymbol
= 11; break; // plus, legacy arrow left
1107 sal_Int32 nApiSize
= XclTools::GetHmmFromTwips( rMarkerFmt
.mnMarkerSize
);
1108 aApiSymbol
.Size
= cssa::Size( nApiSize
, nApiSize
);
1111 aApiSymbol
.FillColor
= ScfApiHelper::ConvertToApiColor( rMarkerFmt
.maFillColor
);
1112 aApiSymbol
.BorderColor
= ::get_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOLINE
) ?
1113 aApiSymbol
.FillColor
: ScfApiHelper::ConvertToApiColor( rMarkerFmt
.maLineColor
);
1116 rPropSet
.SetProperty( EXC_CHPROP_SYMBOL
, aApiSymbol
);
1119 void XclChPropSetHelper::WriteRotationProperties(
1120 ScfPropertySet
& rPropSet
, sal_uInt16 nRotation
, bool bSupportsStacked
)
1122 if( nRotation
!= EXC_CHART_AUTOROTATION
)
1124 // chart2 handles rotation as double in the range [0,360)
1125 double fAngle
= XclTools::GetScRotation( nRotation
, 0 ) / 100.0;
1126 rPropSet
.SetProperty( EXC_CHPROP_TEXTROTATION
, fAngle
);
1127 if( bSupportsStacked
)
1128 rPropSet
.SetProperty( EXC_CHPROP_STACKCHARACTERS
, nRotation
== EXC_ROT_STACKED
);
1132 // private --------------------------------------------------------------------
1134 ScfPropSetHelper
& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode
)
1138 case EXC_CHPROPMODE_COMMON
: return maLineHlpCommon
;
1139 case EXC_CHPROPMODE_LINEARSERIES
: return maLineHlpLinear
;
1140 case EXC_CHPROPMODE_FILLEDSERIES
: return maLineHlpFilled
;
1141 default: OSL_FAIL( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1143 return maLineHlpCommon
;
1146 ScfPropSetHelper
& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode
)
1150 case EXC_CHPROPMODE_COMMON
: return maAreaHlpCommon
;
1151 case EXC_CHPROPMODE_FILLEDSERIES
: return maAreaHlpFilled
;
1152 default: OSL_FAIL( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1154 return maAreaHlpCommon
;
1157 ScfPropSetHelper
& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode
)
1161 case EXC_CHPROPMODE_COMMON
: return maGradHlpCommon
;
1162 case EXC_CHPROPMODE_FILLEDSERIES
: return maGradHlpFilled
;
1163 default: OSL_FAIL( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1165 return maGradHlpCommon
;
1168 ScfPropSetHelper
& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode
)
1172 case EXC_CHPROPMODE_COMMON
: return maHatchHlpCommon
;
1173 case EXC_CHPROPMODE_FILLEDSERIES
: return maHatchHlpFilled
;
1174 default: OSL_FAIL( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1176 return maHatchHlpCommon
;
1181 /* The following local functions implement getting the XShape interface of all
1182 supported title objects (chart and axes). This needs some effort due to the
1183 design of the old Chart1 API used to access these objects. */
1185 /** A code fragment that returns a shape object from the passed shape supplier
1186 using the specified interface function. Checks a boolean property first. */
1187 #define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
1188 ScfPropertySet aPropSet( shape_supplier ); \
1189 if( shape_supplier.is() && aPropSet.GetBoolProperty( #property_name ) ) \
1190 return shape_supplier->supplier_func(); \
1191 return Reference< XShape >(); \
1193 /** Implements a function returning the drawing shape of an axis title, if
1194 existing, using the specified API interface and its function. */
1195 #define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
1196 Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
1198 Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
1199 EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
1202 /** Returns the drawing shape of the main title, if existing. */
1203 Reference
< XShape
> lclGetMainTitleShape( const Reference
< cssc::XChartDocument
>& rxChart1Doc
)
1205 EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc
, getTitle
, HasMainTitle
)
1208 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape
, XAxisXSupplier
, getXAxisTitle
, HasXAxisTitle
)
1209 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape
, XAxisYSupplier
, getYAxisTitle
, HasYAxisTitle
)
1210 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape
, XAxisZSupplier
, getZAxisTitle
, HasZAxisTitle
)
1211 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape
, XSecondAxisTitleSupplier
, getSecondXAxisTitle
, HasSecondaryXAxisTitle
)
1212 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape
, XSecondAxisTitleSupplier
, getSecondYAxisTitle
, HasSecondaryYAxisTitle
)
1214 #undef EXC_DEFINEFUNC_GETAXISTITLESHAPE
1215 #undef EXC_IMPLEMENT_GETTITLESHAPE
1219 XclChRootData::XclChRootData()
1220 : mxTypeInfoProv(new XclChTypeInfoProvider
)
1221 , mxFmtInfoProv(new XclChFormatInfoProvider
)
1227 // remember some title shape getter functions
1228 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_TITLE
) ] = lclGetMainTitleShape
;
1229 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_X
) ] = lclGetXAxisTitleShape
;
1230 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_Y
) ] = lclGetYAxisTitleShape
;
1231 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_Z
) ] = lclGetZAxisTitleShape
;
1232 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_SECONDARY
, EXC_CHAXIS_X
) ] = lclGetSecXAxisTitleShape
;
1233 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_SECONDARY
, EXC_CHAXIS_Y
) ] = lclGetSecYAxisTitleShape
;
1236 XclChRootData::~XclChRootData()
1240 void XclChRootData::InitConversion( const XclRoot
& rRoot
, const Reference
< XChartDocument
>& rxChartDoc
, const Rectangle
& rChartRect
)
1242 // remember chart document reference and chart shape position/size
1243 OSL_ENSURE( rxChartDoc
.is(), "XclChRootData::InitConversion - missing chart document" );
1244 mxChartDoc
= rxChartDoc
;
1245 maChartRect
= rChartRect
;
1247 // Excel excludes a border of 5 pixels in each direction from chart area
1248 mnBorderGapX
= rRoot
.GetHmmFromPixelX( 5.0 );
1249 mnBorderGapY
= rRoot
.GetHmmFromPixelY( 5.0 );
1251 // size of a chart unit in 1/100 mm
1252 mfUnitSizeX
= ::std::max
< double >( maChartRect
.GetWidth() - 2 * mnBorderGapX
, mnBorderGapX
) / EXC_CHART_TOTALUNITS
;
1253 mfUnitSizeY
= ::std::max
< double >( maChartRect
.GetHeight() - 2 * mnBorderGapY
, mnBorderGapY
) / EXC_CHART_TOTALUNITS
;
1255 // create object tables
1256 Reference
< XMultiServiceFactory
> xFactory( mxChartDoc
, UNO_QUERY
);
1257 mxLineDashTable
.reset( new XclChObjectTable(
1258 xFactory
, SERVICE_DRAWING_DASHTABLE
, "Excel line dash " ) );
1259 mxGradientTable
.reset( new XclChObjectTable(
1260 xFactory
, SERVICE_DRAWING_GRADIENTTABLE
, "Excel gradient " ) );
1261 mxHatchTable
.reset( new XclChObjectTable(
1262 xFactory
, SERVICE_DRAWING_HATCHTABLE
, "Excel hatch " ) );
1263 mxBitmapTable
.reset( new XclChObjectTable(
1264 xFactory
, SERVICE_DRAWING_BITMAPTABLE
, "Excel bitmap " ) );
1267 void XclChRootData::FinishConversion()
1269 // forget formatting object tables
1270 mxBitmapTable
.reset();
1271 mxHatchTable
.reset();
1272 mxGradientTable
.reset();
1273 mxLineDashTable
.reset();
1274 // forget chart document reference
1278 Reference
< XShape
> XclChRootData::GetTitleShape( const XclChTextKey
& rTitleKey
) const
1280 XclChGetShapeFuncMap::const_iterator aIt
= maGetShapeFuncs
.find( rTitleKey
);
1281 OSL_ENSURE( aIt
!= maGetShapeFuncs
.end(), "XclChRootData::GetTitleShape - invalid title key" );
1282 Reference
< cssc::XChartDocument
> xChart1Doc( mxChartDoc
, UNO_QUERY
);
1283 Reference
< XShape
> xTitleShape
;
1284 if( xChart1Doc
.is() && (aIt
!= maGetShapeFuncs
.end()) )
1285 xTitleShape
= (aIt
->second
)( xChart1Doc
);
1289 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */