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 const XclChFormatInfo
* pEnd
= STATIC_ARRAY_END( spFmtInfos
);
452 for( const XclChFormatInfo
* pIt
= spFmtInfos
; pIt
!= pEnd
; ++pIt
)
453 maInfoMap
[ pIt
->meObjType
] = pIt
;
456 const XclChFormatInfo
& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType
) const
458 XclFmtInfoMap::const_iterator aIt
= maInfoMap
.find( eObjType
);
459 OSL_ENSURE( aIt
!= maInfoMap
.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
460 return (aIt
== maInfoMap
.end()) ? *spFmtInfos
: *aIt
->second
;
463 // Chart type info provider ===================================================
467 // chart type service names
468 const sal_Char SERVICE_CHART2_AREA
[] = "com.sun.star.chart2.AreaChartType";
469 const sal_Char SERVICE_CHART2_CANDLE
[] = "com.sun.star.chart2.CandleStickChartType";
470 const sal_Char SERVICE_CHART2_COLUMN
[] = "com.sun.star.chart2.ColumnChartType";
471 const sal_Char SERVICE_CHART2_LINE
[] = "com.sun.star.chart2.LineChartType";
472 const sal_Char SERVICE_CHART2_NET
[] = "com.sun.star.chart2.NetChartType";
473 const sal_Char SERVICE_CHART2_FILLEDNET
[] = "com.sun.star.chart2.FilledNetChartType";
474 const sal_Char SERVICE_CHART2_PIE
[] = "com.sun.star.chart2.PieChartType";
475 const sal_Char SERVICE_CHART2_SCATTER
[] = "com.sun.star.chart2.ScatterChartType";
476 const sal_Char SERVICE_CHART2_BUBBLE
[] = "com.sun.star.chart2.BubbleChartType";
477 const sal_Char SERVICE_CHART2_SURFACE
[] = "com.sun.star.chart2.ColumnChartType"; // Todo
479 namespace csscd
= cssc::DataLabelPlacement
;
481 static const XclChTypeInfo spTypeInfos
[] =
483 // 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
484 { 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 },
485 { 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 },
486 { 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 },
487 { 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 },
488 { 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 },
489 { 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 },
490 { 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 },
491 { 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 },
492 { 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 },
493 { 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 },
494 { 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 },
495 { 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 },
496 { 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 },
497 { 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 }
502 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo
& rTypeInfo
) :
503 XclChTypeInfo( rTypeInfo
),
509 void XclChExtTypeInfo::Set( const XclChTypeInfo
& rTypeInfo
, bool b3dChart
, bool bSpline
)
511 static_cast< XclChTypeInfo
& >( *this ) = rTypeInfo
;
512 mb3dChart
= mbSupports3d
&& b3dChart
;
516 XclChTypeInfoProvider::XclChTypeInfoProvider()
518 const XclChTypeInfo
* pEnd
= STATIC_ARRAY_END( spTypeInfos
);
519 for( const XclChTypeInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
520 maInfoMap
[ pIt
->meTypeId
] = pIt
;
523 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId
) const
525 XclChTypeInfoMap::const_iterator aIt
= maInfoMap
.find( eTypeId
);
526 OSL_ENSURE( aIt
!= maInfoMap
.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
527 return (aIt
== maInfoMap
.end()) ? *maInfoMap
.rbegin()->second
: *aIt
->second
;
530 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId
) const
532 const XclChTypeInfo
* pEnd
= STATIC_ARRAY_END( spTypeInfos
);
533 for( const XclChTypeInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
534 if( pIt
->mnRecId
== nRecId
)
536 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
537 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
540 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString
& rServiceName
) const
542 const XclChTypeInfo
* pEnd
= STATIC_ARRAY_END( spTypeInfos
);
543 for( const XclChTypeInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
544 if( rServiceName
.equalsAscii( pIt
->mpcServiceName
) )
546 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
547 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
550 // Property helpers ===========================================================
552 XclChObjectTable::XclChObjectTable( Reference
< XMultiServiceFactory
> xFactory
,
553 const OUString
& rServiceName
, const OUString
& rObjNameBase
) :
554 mxFactory( xFactory
),
555 maServiceName( rServiceName
),
556 maObjNameBase( rObjNameBase
),
561 Any
XclChObjectTable::GetObject( const OUString
& rObjName
)
564 if( !mxContainer
.is() )
565 mxContainer
.set( ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), UNO_QUERY
);
566 OSL_ENSURE( mxContainer
.is(), "XclChObjectTable::GetObject - container not found" );
569 if( mxContainer
.is() )
571 // get object from container
574 aObj
= mxContainer
->getByName( rObjName
);
578 OSL_FAIL( "XclChObjectTable::GetObject - object not found" );
584 OUString
XclChObjectTable::InsertObject( const Any
& rObj
)
587 // create object table
588 if( !mxContainer
.is() )
589 mxContainer
.set( ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), UNO_QUERY
);
590 OSL_ENSURE( mxContainer
.is(), "XclChObjectTable::InsertObject - container not found" );
593 if( mxContainer
.is() )
595 // create new unused identifier
598 aObjName
= maObjNameBase
+ OUString::number( ++mnIndex
);
600 while( mxContainer
->hasByName( aObjName
) );
605 mxContainer
->insertByName( aObjName
, rObj
);
609 OSL_FAIL( "XclChObjectTable::InsertObject - cannot insert object" );
616 // Property names -------------------------------------------------------------
620 /** Property names for line style in common objects. */
621 const sal_Char
* const sppcLineNamesCommon
[] =
622 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", 0 };
623 /** Property names for line style in linear series objects. */
624 const sal_Char
* const sppcLineNamesLinear
[] =
625 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", 0 };
626 /** Property names for line style in filled series objects. */
627 const sal_Char
* const sppcLineNamesFilled
[] =
628 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", 0 };
630 /** Property names for solid area style in common objects. */
631 const sal_Char
* const sppcAreaNamesCommon
[] = { "FillStyle", "FillColor", "FillTransparence", 0 };
632 /** Property names for solid area style in filled series objects. */
633 const sal_Char
* const sppcAreaNamesFilled
[] = { "FillStyle", "Color", "Transparency", 0 };
634 /** Property names for gradient area style in common objects. */
635 const sal_Char
* const sppcGradNamesCommon
[] = { "FillStyle", "FillGradientName", 0 };
636 /** Property names for gradient area style in filled series objects. */
637 const sal_Char
* const sppcGradNamesFilled
[] = { "FillStyle", "GradientName", 0 };
638 /** Property names for hatch area style in common objects. */
639 const sal_Char
* const sppcHatchNamesCommon
[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", 0 };
640 /** Property names for hatch area style in filled series objects. */
641 const sal_Char
* const sppcHatchNamesFilled
[] = { "FillStyle", "HatchName", "Color", "FillBackground", 0 };
642 /** Property names for bitmap area style. */
643 const sal_Char
* const sppcBitmapNames
[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 };
647 XclChPropSetHelper::XclChPropSetHelper() :
648 maLineHlpCommon( sppcLineNamesCommon
),
649 maLineHlpLinear( sppcLineNamesLinear
),
650 maLineHlpFilled( sppcLineNamesFilled
),
651 maAreaHlpCommon( sppcAreaNamesCommon
),
652 maAreaHlpFilled( sppcAreaNamesFilled
),
653 maGradHlpCommon( sppcGradNamesCommon
),
654 maGradHlpFilled( sppcGradNamesFilled
),
655 maHatchHlpCommon( sppcHatchNamesCommon
),
656 maHatchHlpFilled( sppcHatchNamesFilled
),
657 maBitmapHlp( sppcBitmapNames
)
661 // read properties ------------------------------------------------------------
663 void XclChPropSetHelper::ReadLineProperties(
664 XclChLineFormat
& rLineFmt
, XclChObjectTable
& rDashTable
,
665 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
667 namespace cssd
= ::com::sun::star::drawing
;
669 // read properties from property set
670 cssd::LineStyle eApiStyle
= cssd::LineStyle_NONE
;
671 sal_Int32 nApiWidth
= 0;
672 sal_Int16 nApiTrans
= 0;
675 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
676 rLineHlp
.ReadFromPropertySet( rPropSet
);
677 rLineHlp
>> eApiStyle
>> nApiWidth
>> rLineFmt
.maColor
>> nApiTrans
>> aDashNameAny
;
679 // clear automatic flag
680 ::set_flag( rLineFmt
.mnFlags
, EXC_CHLINEFORMAT_AUTO
, false );
683 if( nApiWidth
<= 0 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_HAIR
;
684 else if( nApiWidth
<= 35 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_SINGLE
;
685 else if( nApiWidth
<= 70 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_DOUBLE
;
686 else rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_TRIPLE
;
691 case cssd::LineStyle_NONE
:
692 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
694 case cssd::LineStyle_SOLID
:
696 if( nApiTrans
< 13 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
697 else if( nApiTrans
< 38 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DARKTRANS
;
698 else if( nApiTrans
< 63 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_MEDTRANS
;
699 else if( nApiTrans
< 100 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_LIGHTTRANS
;
700 else rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
703 case cssd::LineStyle_DASH
:
705 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
707 cssd::LineDash aApiDash
;
708 if( (aDashNameAny
>>= aDashName
) && (rDashTable
.GetObject( aDashName
) >>= aApiDash
) )
710 // reorder dashes that are shorter than dots
711 if( (aApiDash
.Dashes
== 0) || (aApiDash
.DashLen
< aApiDash
.DotLen
) )
713 ::std::swap( aApiDash
.Dashes
, aApiDash
.Dots
);
714 ::std::swap( aApiDash
.DashLen
, aApiDash
.DotLen
);
716 // ignore dots that are nearly equal to dashes
717 if( aApiDash
.DotLen
* 3 > aApiDash
.DashLen
* 2 )
720 // convert line dash to predefined Excel dash types
721 if( (aApiDash
.Dashes
== 1) && (aApiDash
.Dots
>= 1) )
722 // one dash and one or more dots
723 rLineFmt
.mnPattern
= (aApiDash
.Dots
== 1) ?
724 EXC_CHLINEFORMAT_DASHDOT
: EXC_CHLINEFORMAT_DASHDOTDOT
;
725 else if( aApiDash
.Dashes
>= 1 )
726 // one or more dashes and no dots (also: dash-dash-dot)
727 rLineFmt
.mnPattern
= (aApiDash
.DashLen
< 250) ?
728 EXC_CHLINEFORMAT_DOT
: EXC_CHLINEFORMAT_DASH
;
733 OSL_FAIL( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
734 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
738 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat
& rAreaFmt
,
739 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
741 namespace cssd
= ::com::sun::star::drawing
;
743 // read properties from property set
744 cssd::FillStyle eApiStyle
= cssd::FillStyle_NONE
;
745 sal_Int16 nTransparency
= 0;
747 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
748 rAreaHlp
.ReadFromPropertySet( rPropSet
);
749 rAreaHlp
>> eApiStyle
>> rAreaFmt
.maPattColor
>> nTransparency
;
751 // clear automatic flag
752 ::set_flag( rAreaFmt
.mnFlags
, EXC_CHAREAFORMAT_AUTO
, false );
754 // set fill style transparent or solid (set solid for anything but transparent)
755 rAreaFmt
.mnPattern
= (eApiStyle
== cssd::FillStyle_NONE
) ? EXC_PATT_NONE
: EXC_PATT_SOLID
;
757 // return true to indicate complex fill (gradient, bitmap, solid transparency)
758 return (eApiStyle
!= cssd::FillStyle_NONE
) && ((eApiStyle
!= cssd::FillStyle_SOLID
) || (nTransparency
> 0));
761 void XclChPropSetHelper::ReadEscherProperties(
762 XclChEscherFormat
& rEscherFmt
, XclChPicFormat
& rPicFmt
,
763 XclChObjectTable
& rGradientTable
, XclChObjectTable
& rHatchTable
, XclChObjectTable
& rBitmapTable
,
764 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
766 namespace cssd
= ::com::sun::star::drawing
;
767 namespace cssa
= ::com::sun::star::awt
;
769 // read style and transparency properties from property set
770 cssd::FillStyle eApiStyle
= cssd::FillStyle_NONE
;
772 sal_Int16 nTransparency
= 0;
774 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
775 rAreaHlp
.ReadFromPropertySet( rPropSet
);
776 rAreaHlp
>> eApiStyle
>> aColor
>> nTransparency
;
780 case cssd::FillStyle_SOLID
:
782 OSL_ENSURE( nTransparency
> 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
783 if( (0 < nTransparency
) && (nTransparency
<= 100) )
785 // convert to Escher properties
786 sal_uInt32 nEscherColor
= 0x02000000;
787 ::insert_value( nEscherColor
, aColor
.GetBlue(), 16, 8 );
788 ::insert_value( nEscherColor
, aColor
.GetGreen(), 8, 8 );
789 ::insert_value( nEscherColor
, aColor
.GetRed(), 0, 8 );
790 sal_uInt32 nEscherOpacity
= static_cast< sal_uInt32
>( (100 - nTransparency
) * 655.36 );
791 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
792 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillType
, ESCHER_FillSolid
);
793 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillColor
, nEscherColor
);
794 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillOpacity
, nEscherOpacity
);
795 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackColor
, 0x02FFFFFF );
796 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackOpacity
, 0x00010000 );
797 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x001F001C );
801 case cssd::FillStyle_GRADIENT
:
803 // extract gradient from global gradient table
804 OUString aGradientName
;
805 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
806 rGradHlp
.ReadFromPropertySet( rPropSet
);
807 rGradHlp
>> eApiStyle
>> aGradientName
;
808 cssa::Gradient aGradient
;
809 if( rGradientTable
.GetObject( aGradientName
) >>= aGradient
)
811 // convert to Escher properties
812 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
813 rEscherFmt
.mxEscherSet
->CreateGradientProperties( aGradient
);
817 case cssd::FillStyle_HATCH
:
819 // extract hatch from global hatch table
821 bool bFillBackground
;
822 ScfPropSetHelper
& rHatchHlp
= GetHatchHelper( ePropMode
);
823 rHatchHlp
.ReadFromPropertySet( rPropSet
);
824 rHatchHlp
>> eApiStyle
>> aHatchName
>> aColor
>> bFillBackground
;
826 if( rHatchTable
.GetObject( aHatchName
) >>= aHatch
)
828 // convert to Escher properties
829 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
830 rEscherFmt
.mxEscherSet
->CreateEmbeddedHatchProperties( aHatch
, aColor
, bFillBackground
);
831 rPicFmt
.mnBmpMode
= EXC_CHPICFORMAT_STACK
;
835 case cssd::FillStyle_BITMAP
:
837 // extract bitmap URL from global bitmap table
838 OUString aBitmapName
;
839 cssd::BitmapMode eApiBmpMode
;
840 maBitmapHlp
.ReadFromPropertySet( rPropSet
);
841 maBitmapHlp
>> eApiStyle
>> aBitmapName
>> eApiBmpMode
;
843 if( rBitmapTable
.GetObject( aBitmapName
) >>= aBitmapUrl
)
845 // convert to Escher properties
846 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
847 rEscherFmt
.mxEscherSet
->CreateEmbeddedBitmapProperties( aBitmapUrl
, eApiBmpMode
);
848 rPicFmt
.mnBmpMode
= (eApiBmpMode
== cssd::BitmapMode_REPEAT
) ?
849 EXC_CHPICFORMAT_STACK
: EXC_CHPICFORMAT_STRETCH
;
854 OSL_FAIL( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
858 void XclChPropSetHelper::ReadMarkerProperties(
859 XclChMarkerFormat
& rMarkerFmt
, const ScfPropertySet
& rPropSet
, sal_uInt16 nFormatIdx
)
861 namespace cssc
= ::com::sun::star::chart2
;
862 namespace cssa
= ::com::sun::star::awt
;
863 cssc::Symbol aApiSymbol
;
864 if( rPropSet
.GetProperty( aApiSymbol
, EXC_CHPROP_SYMBOL
) )
866 // clear automatic flag
867 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_AUTO
, false );
870 switch( aApiSymbol
.Style
)
872 case cssc::SymbolStyle_NONE
:
873 rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_NOSYMBOL
;
875 case cssc::SymbolStyle_STANDARD
:
876 switch( aApiSymbol
.StandardSymbol
)
878 case 0: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_SQUARE
; break; // square
879 case 1: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DIAMOND
; break; // diamond
880 case 2: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STDDEV
; break; // arrow down
881 case 3: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_TRIANGLE
; break; // arrow up
882 case 4: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DOWJ
; break; // arrow right, same as import
883 case 5: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_PLUS
; break; // arrow left
884 case 6: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CROSS
; break; // bow tie
885 case 7: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // sand glass
886 case 8: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CIRCLE
; break; // circle new in LibO3.5
887 case 9: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DIAMOND
; break; // star new in LibO3.5
888 case 10: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CROSS
; break; // X new in LibO3.5
889 case 11: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_PLUS
; break; // plus new in LibO3.5
890 case 12: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // asterisk new in LibO3.5
891 case 13: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STDDEV
; break; // horizontal bar new in LibO3.5
892 case 14: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // vertical bar new in LibO3.5
893 default: rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
897 rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
899 bool bHasFillColor
= XclChartHelper::HasMarkerFillColor( rMarkerFmt
.mnMarkerType
);
900 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOFILL
, !bHasFillColor
);
903 sal_Int32 nApiSize
= (aApiSymbol
.Size
.Width
+ aApiSymbol
.Size
.Height
+ 1) / 2;
904 rMarkerFmt
.mnMarkerSize
= XclTools::GetTwipsFromHmm( nApiSize
);
907 rMarkerFmt
.maLineColor
= ScfApiHelper::ConvertFromApiColor( aApiSymbol
.BorderColor
);
908 rMarkerFmt
.maFillColor
= ScfApiHelper::ConvertFromApiColor( aApiSymbol
.FillColor
);
912 sal_uInt16
XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet
& rPropSet
, bool bSupportsStacked
)
914 // chart2 handles rotation as double in the range [0,360)
916 rPropSet
.GetProperty( fAngle
, EXC_CHPROP_TEXTROTATION
);
917 bool bStacked
= bSupportsStacked
&& rPropSet
.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS
);
918 return bStacked
? EXC_ROT_STACKED
:
919 XclTools::GetXclRotation( static_cast< sal_Int32
>( fAngle
* 100.0 + 0.5 ) );
922 // write properties -----------------------------------------------------------
924 void XclChPropSetHelper::WriteLineProperties(
925 ScfPropertySet
& rPropSet
, XclChObjectTable
& rDashTable
,
926 const XclChLineFormat
& rLineFmt
, XclChPropertyMode ePropMode
)
928 namespace cssd
= ::com::sun::star::drawing
;
931 sal_Int32 nApiWidth
= 0; // 0 is the width of a hair line
932 switch( rLineFmt
.mnWeight
)
934 case EXC_CHLINEFORMAT_SINGLE
: nApiWidth
= 35; break;
935 case EXC_CHLINEFORMAT_DOUBLE
: nApiWidth
= 70; break;
936 case EXC_CHLINEFORMAT_TRIPLE
: nApiWidth
= 105; break;
940 cssd::LineStyle eApiStyle
= cssd::LineStyle_NONE
;
941 sal_Int16 nApiTrans
= 0;
942 sal_Int32 nDotLen
= ::std::min
< sal_Int32
>( rLineFmt
.mnWeight
+ 105, 210 );
943 cssd::LineDash
aApiDash( cssd::DashStyle_RECT
, 0, nDotLen
, 0, 4 * nDotLen
, nDotLen
);
945 switch( rLineFmt
.mnPattern
)
947 case EXC_CHLINEFORMAT_SOLID
:
948 eApiStyle
= cssd::LineStyle_SOLID
;
950 case EXC_CHLINEFORMAT_DARKTRANS
:
951 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 25;
953 case EXC_CHLINEFORMAT_MEDTRANS
:
954 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 50;
956 case EXC_CHLINEFORMAT_LIGHTTRANS
:
957 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 75;
959 case EXC_CHLINEFORMAT_DASH
:
960 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= 1;
962 case EXC_CHLINEFORMAT_DOT
:
963 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dots
= 1;
965 case EXC_CHLINEFORMAT_DASHDOT
:
966 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= aApiDash
.Dots
= 1;
968 case EXC_CHLINEFORMAT_DASHDOTDOT
:
969 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= 1; aApiDash
.Dots
= 2;
974 sal_Int32 nApiColor
= ScfApiHelper::ConvertToApiColor( rLineFmt
.maColor
);
976 // try to insert the dash style and receive its name
978 if( eApiStyle
== cssd::LineStyle_DASH
)
980 OUString aDashName
= rDashTable
.InsertObject( ::com::sun::star::uno::makeAny( aApiDash
) );
981 if( !aDashName
.isEmpty() )
982 aDashNameAny
<<= aDashName
;
985 // write the properties
986 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
987 rLineHlp
.InitializeWrite();
988 rLineHlp
<< eApiStyle
<< nApiWidth
<< nApiColor
<< nApiTrans
<< aDashNameAny
;
989 rLineHlp
.WriteToPropertySet( rPropSet
);
992 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet
& rPropSet
,
993 const XclChAreaFormat
& rAreaFmt
, XclChPropertyMode ePropMode
)
995 namespace cssd
= ::com::sun::star::drawing
;
996 cssd::FillStyle eFillStyle
= cssd::FillStyle_NONE
;
998 sal_Int16 nTransparency
= 0;
1001 if( rAreaFmt
.mnPattern
!= EXC_PATT_NONE
)
1003 eFillStyle
= cssd::FillStyle_SOLID
;
1004 aColor
= XclTools::GetPatternColor( rAreaFmt
.maPattColor
, rAreaFmt
.maBackColor
, rAreaFmt
.mnPattern
);
1007 // write the properties
1008 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
1009 rAreaHlp
.InitializeWrite();
1010 rAreaHlp
<< eFillStyle
<< aColor
<< nTransparency
;
1011 rAreaHlp
.WriteToPropertySet( rPropSet
);
1014 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet
& rPropSet
,
1015 XclChObjectTable
& rGradientTable
, XclChObjectTable
& /*rHatchTable*/, XclChObjectTable
& rBitmapTable
,
1016 const XclChEscherFormat
& rEscherFmt
, const XclChPicFormat
* pPicFmt
,
1017 sal_uInt32 nDffFillType
, XclChPropertyMode ePropMode
)
1019 if( rEscherFmt
.mxItemSet
)
1021 if( const XFillStyleItem
* pStyleItem
= static_cast< const XFillStyleItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLSTYLE
, false ) ) )
1023 switch( pStyleItem
->GetValue() )
1025 case drawing::FillStyle_SOLID
:
1026 // #i84812# Excel 2007 writes Escher properties for solid fill
1027 if( const XFillColorItem
* pColorItem
= static_cast< const XFillColorItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLCOLOR
, false ) ) )
1029 namespace cssd
= ::com::sun::star::drawing
;
1030 // get solid transparence too
1031 const XFillTransparenceItem
* pTranspItem
= static_cast< const XFillTransparenceItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLTRANSPARENCE
, false ) );
1032 sal_uInt16 nTransp
= pTranspItem
? pTranspItem
->GetValue() : 0;
1033 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
1034 rAreaHlp
.InitializeWrite();
1035 rAreaHlp
<< cssd::FillStyle_SOLID
<< pColorItem
->GetColorValue() << static_cast< sal_Int16
>( nTransp
);
1036 rAreaHlp
.WriteToPropertySet( rPropSet
);
1039 case drawing::FillStyle_GRADIENT
:
1040 if( const XFillGradientItem
* pGradItem
= static_cast< const XFillGradientItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLGRADIENT
, false ) ) )
1043 if( pGradItem
->QueryValue( aGradientAny
, MID_FILLGRADIENT
) )
1045 OUString aGradName
= rGradientTable
.InsertObject( aGradientAny
);
1046 if( !aGradName
.isEmpty() )
1048 namespace cssd
= ::com::sun::star::drawing
;
1049 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
1050 rGradHlp
.InitializeWrite();
1051 rGradHlp
<< cssd::FillStyle_GRADIENT
<< aGradName
;
1052 rGradHlp
.WriteToPropertySet( rPropSet
);
1057 case drawing::FillStyle_BITMAP
:
1058 if( const XFillBitmapItem
* pBmpItem
= static_cast< const XFillBitmapItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLBITMAP
, false ) ) )
1061 if( pBmpItem
->QueryValue( aBitmapAny
, MID_GRAFURL
) )
1063 OUString aBmpName
= rBitmapTable
.InsertObject( aBitmapAny
);
1064 if( !aBmpName
.isEmpty() )
1066 namespace cssd
= ::com::sun::star::drawing
;
1067 /* #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode.
1068 If not passed, detect fill mode from the DFF property 'fill-type'. */
1069 bool bStretch
= pPicFmt
? (pPicFmt
->mnBmpMode
== EXC_CHPICFORMAT_STRETCH
) : (nDffFillType
== mso_fillPicture
);
1070 cssd::BitmapMode eApiBmpMode
= bStretch
? cssd::BitmapMode_STRETCH
: cssd::BitmapMode_REPEAT
;
1071 maBitmapHlp
.InitializeWrite();
1072 maBitmapHlp
<< cssd::FillStyle_BITMAP
<< aBmpName
<< eApiBmpMode
;
1073 maBitmapHlp
.WriteToPropertySet( rPropSet
);
1079 OSL_FAIL( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1085 void XclChPropSetHelper::WriteMarkerProperties(
1086 ScfPropertySet
& rPropSet
, const XclChMarkerFormat
& rMarkerFmt
)
1088 namespace cssc
= ::com::sun::star::chart2
;
1089 namespace cssa
= ::com::sun::star::awt
;
1092 cssc::Symbol aApiSymbol
;
1093 aApiSymbol
.Style
= cssc::SymbolStyle_STANDARD
;
1094 switch( rMarkerFmt
.mnMarkerType
)
1096 case EXC_CHMARKERFORMAT_NOSYMBOL
: aApiSymbol
.Style
= cssc::SymbolStyle_NONE
; break;
1097 case EXC_CHMARKERFORMAT_SQUARE
: aApiSymbol
.StandardSymbol
= 0; break; // square
1098 case EXC_CHMARKERFORMAT_DIAMOND
: aApiSymbol
.StandardSymbol
= 1; break; // diamond
1099 case EXC_CHMARKERFORMAT_TRIANGLE
: aApiSymbol
.StandardSymbol
= 3; break; // arrow up
1100 case EXC_CHMARKERFORMAT_CROSS
: aApiSymbol
.StandardSymbol
= 10; break; // X, legacy bow tie
1101 case EXC_CHMARKERFORMAT_STAR
: aApiSymbol
.StandardSymbol
= 12; break; // asterisk, legacy sand glass
1102 case EXC_CHMARKERFORMAT_DOWJ
: aApiSymbol
.StandardSymbol
= 4; break; // arrow right, same as export
1103 case EXC_CHMARKERFORMAT_STDDEV
: aApiSymbol
.StandardSymbol
= 13; break; // horizontal bar, legacy arrow down
1104 case EXC_CHMARKERFORMAT_CIRCLE
: aApiSymbol
.StandardSymbol
= 8; break; // circle, legacy arrow right
1105 case EXC_CHMARKERFORMAT_PLUS
: aApiSymbol
.StandardSymbol
= 11; break; // plus, legacy arrow left
1110 sal_Int32 nApiSize
= XclTools::GetHmmFromTwips( rMarkerFmt
.mnMarkerSize
);
1111 aApiSymbol
.Size
= cssa::Size( nApiSize
, nApiSize
);
1114 aApiSymbol
.FillColor
= ScfApiHelper::ConvertToApiColor( rMarkerFmt
.maFillColor
);
1115 aApiSymbol
.BorderColor
= ::get_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOLINE
) ?
1116 aApiSymbol
.FillColor
: ScfApiHelper::ConvertToApiColor( rMarkerFmt
.maLineColor
);
1119 rPropSet
.SetProperty( EXC_CHPROP_SYMBOL
, aApiSymbol
);
1122 void XclChPropSetHelper::WriteRotationProperties(
1123 ScfPropertySet
& rPropSet
, sal_uInt16 nRotation
, bool bSupportsStacked
)
1125 if( nRotation
!= EXC_CHART_AUTOROTATION
)
1127 // chart2 handles rotation as double in the range [0,360)
1128 double fAngle
= XclTools::GetScRotation( nRotation
, 0 ) / 100.0;
1129 rPropSet
.SetProperty( EXC_CHPROP_TEXTROTATION
, fAngle
);
1130 if( bSupportsStacked
)
1131 rPropSet
.SetProperty( EXC_CHPROP_STACKCHARACTERS
, nRotation
== EXC_ROT_STACKED
);
1135 // private --------------------------------------------------------------------
1137 ScfPropSetHelper
& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode
)
1141 case EXC_CHPROPMODE_COMMON
: return maLineHlpCommon
;
1142 case EXC_CHPROPMODE_LINEARSERIES
: return maLineHlpLinear
;
1143 case EXC_CHPROPMODE_FILLEDSERIES
: return maLineHlpFilled
;
1144 default: OSL_FAIL( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1146 return maLineHlpCommon
;
1149 ScfPropSetHelper
& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode
)
1153 case EXC_CHPROPMODE_COMMON
: return maAreaHlpCommon
;
1154 case EXC_CHPROPMODE_FILLEDSERIES
: return maAreaHlpFilled
;
1155 default: OSL_FAIL( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1157 return maAreaHlpCommon
;
1160 ScfPropSetHelper
& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode
)
1164 case EXC_CHPROPMODE_COMMON
: return maGradHlpCommon
;
1165 case EXC_CHPROPMODE_FILLEDSERIES
: return maGradHlpFilled
;
1166 default: OSL_FAIL( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1168 return maGradHlpCommon
;
1171 ScfPropSetHelper
& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode
)
1175 case EXC_CHPROPMODE_COMMON
: return maHatchHlpCommon
;
1176 case EXC_CHPROPMODE_FILLEDSERIES
: return maHatchHlpFilled
;
1177 default: OSL_FAIL( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1179 return maHatchHlpCommon
;
1184 /* The following local functions implement getting the XShape interface of all
1185 supported title objects (chart and axes). This needs some effort due to the
1186 design of the old Chart1 API used to access these objects. */
1188 /** A code fragment that returns a shape object from the passed shape supplier
1189 using the specified interface function. Checks a boolean property first. */
1190 #define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
1191 ScfPropertySet aPropSet( shape_supplier ); \
1192 if( shape_supplier.is() && aPropSet.GetBoolProperty( #property_name ) ) \
1193 return shape_supplier->supplier_func(); \
1194 return Reference< XShape >(); \
1196 /** Implements a function returning the drawing shape of an axis title, if
1197 existing, using the specified API interface and its function. */
1198 #define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
1199 Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
1201 Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
1202 EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
1205 /** Returns the drawing shape of the main title, if existing. */
1206 Reference
< XShape
> lclGetMainTitleShape( const Reference
< cssc::XChartDocument
>& rxChart1Doc
)
1208 EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc
, getTitle
, HasMainTitle
)
1211 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape
, XAxisXSupplier
, getXAxisTitle
, HasXAxisTitle
)
1212 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape
, XAxisYSupplier
, getYAxisTitle
, HasYAxisTitle
)
1213 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape
, XAxisZSupplier
, getZAxisTitle
, HasZAxisTitle
)
1214 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape
, XSecondAxisTitleSupplier
, getSecondXAxisTitle
, HasSecondaryXAxisTitle
)
1215 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape
, XSecondAxisTitleSupplier
, getSecondYAxisTitle
, HasSecondaryYAxisTitle
)
1217 #undef EXC_DEFINEFUNC_GETAXISTITLESHAPE
1218 #undef EXC_IMPLEMENT_GETTITLESHAPE
1222 XclChRootData::XclChRootData()
1223 : mxTypeInfoProv(new XclChTypeInfoProvider
)
1224 , mxFmtInfoProv(new XclChFormatInfoProvider
)
1230 // remember some title shape getter functions
1231 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_TITLE
) ] = lclGetMainTitleShape
;
1232 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_X
) ] = lclGetXAxisTitleShape
;
1233 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_Y
) ] = lclGetYAxisTitleShape
;
1234 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_PRIMARY
, EXC_CHAXIS_Z
) ] = lclGetZAxisTitleShape
;
1235 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_SECONDARY
, EXC_CHAXIS_X
) ] = lclGetSecXAxisTitleShape
;
1236 maGetShapeFuncs
[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE
, EXC_CHAXESSET_SECONDARY
, EXC_CHAXIS_Y
) ] = lclGetSecYAxisTitleShape
;
1239 XclChRootData::~XclChRootData()
1243 void XclChRootData::InitConversion( const XclRoot
& rRoot
, const Reference
< XChartDocument
>& rxChartDoc
, const Rectangle
& rChartRect
)
1245 // remember chart document reference and chart shape position/size
1246 OSL_ENSURE( rxChartDoc
.is(), "XclChRootData::InitConversion - missing chart document" );
1247 mxChartDoc
= rxChartDoc
;
1248 maChartRect
= rChartRect
;
1250 // Excel excludes a border of 5 pixels in each direction from chart area
1251 mnBorderGapX
= rRoot
.GetHmmFromPixelX( 5.0 );
1252 mnBorderGapY
= rRoot
.GetHmmFromPixelY( 5.0 );
1254 // size of a chart unit in 1/100 mm
1255 mfUnitSizeX
= ::std::max
< double >( maChartRect
.GetWidth() - 2 * mnBorderGapX
, mnBorderGapX
) / EXC_CHART_TOTALUNITS
;
1256 mfUnitSizeY
= ::std::max
< double >( maChartRect
.GetHeight() - 2 * mnBorderGapY
, mnBorderGapY
) / EXC_CHART_TOTALUNITS
;
1258 // create object tables
1259 Reference
< XMultiServiceFactory
> xFactory( mxChartDoc
, UNO_QUERY
);
1260 mxLineDashTable
.reset( new XclChObjectTable(
1261 xFactory
, SERVICE_DRAWING_DASHTABLE
, "Excel line dash " ) );
1262 mxGradientTable
.reset( new XclChObjectTable(
1263 xFactory
, SERVICE_DRAWING_GRADIENTTABLE
, "Excel gradient " ) );
1264 mxHatchTable
.reset( new XclChObjectTable(
1265 xFactory
, SERVICE_DRAWING_HATCHTABLE
, "Excel hatch " ) );
1266 mxBitmapTable
.reset( new XclChObjectTable(
1267 xFactory
, SERVICE_DRAWING_BITMAPTABLE
, "Excel bitmap " ) );
1270 void XclChRootData::FinishConversion()
1272 // forget formatting object tables
1273 mxBitmapTable
.reset();
1274 mxHatchTable
.reset();
1275 mxGradientTable
.reset();
1276 mxLineDashTable
.reset();
1277 // forget chart document reference
1281 Reference
< XShape
> XclChRootData::GetTitleShape( const XclChTextKey
& rTitleKey
) const
1283 XclChGetShapeFuncMap::const_iterator aIt
= maGetShapeFuncs
.find( rTitleKey
);
1284 OSL_ENSURE( aIt
!= maGetShapeFuncs
.end(), "XclChRootData::GetTitleShape - invalid title key" );
1285 Reference
< cssc::XChartDocument
> xChart1Doc( mxChartDoc
, UNO_QUERY
);
1286 Reference
< XShape
> xTitleShape
;
1287 if( xChart1Doc
.is() && (aIt
!= maGetShapeFuncs
.end()) )
1288 xTitleShape
= (aIt
->second
)( xChart1Doc
);
1292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */