1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xlchart.cxx,v $
10 * $Revision: 1.11.62.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "xlchart.hxx"
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/awt/Size.hpp>
38 #include <com/sun/star/awt/Gradient.hpp>
39 #include <com/sun/star/drawing/Hatch.hpp>
40 #include <com/sun/star/drawing/LineDash.hpp>
41 #include <com/sun/star/drawing/LineStyle.hpp>
42 #include <com/sun/star/drawing/FillStyle.hpp>
43 #include <com/sun/star/drawing/BitmapMode.hpp>
44 #include <com/sun/star/chart2/RelativePosition.hpp>
45 #include <com/sun/star/chart2/LegendPosition.hpp>
46 #include <com/sun/star/chart2/LegendExpansion.hpp>
47 #include <com/sun/star/chart2/Symbol.hpp>
48 #include <com/sun/star/chart/DataLabelPlacement.hpp>
50 #include <rtl/math.hxx>
51 #include <svtools/itemset.hxx>
52 #include <svx/xfillit0.hxx>
53 #include <svx/xflclit.hxx>
54 #include <svx/xfltrit.hxx>
55 #include <svx/xflgrit.hxx>
56 #include <svx/xbtmpit.hxx>
57 #include <svx/unomid.hxx>
58 #include <svx/escherex.hxx>
61 #include "xlconst.hxx"
62 #include "xlstyle.hxx"
63 #include "xltools.hxx"
65 using ::rtl::OUString
;
66 using ::com::sun::star::uno::Any
;
67 using ::com::sun::star::uno::Reference
;
68 using ::com::sun::star::uno::UNO_QUERY
;
69 using ::com::sun::star::uno::Exception
;
70 using ::com::sun::star::lang::XMultiServiceFactory
;
71 using ::com::sun::star::chart2::XChartDocument
;
73 // Common =====================================================================
75 XclChRectangle::XclChRectangle() :
83 // ----------------------------------------------------------------------------
85 XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx
, sal_uInt16 nPointIdx
) :
86 mnSeriesIdx( nSeriesIdx
),
87 mnPointIdx( nPointIdx
)
91 bool operator<( const XclChDataPointPos
& rL
, const XclChDataPointPos
& rR
)
93 return (rL
.mnSeriesIdx
< rR
.mnSeriesIdx
) ||
94 ((rL
.mnSeriesIdx
== rR
.mnSeriesIdx
) && (rL
.mnPointIdx
< rR
.mnPointIdx
));
97 // ----------------------------------------------------------------------------
99 XclChFrBlock::XclChFrBlock( sal_uInt16 nType
) :
107 // Frame formatting ===========================================================
109 XclChFramePos::XclChFramePos() :
110 mnObjType( EXC_CHFRAMEPOS_ANY
),
111 mnSizeMode( EXC_CHFRAMEPOS_AUTOSIZE
)
115 // ----------------------------------------------------------------------------
117 XclChLineFormat::XclChLineFormat() :
118 maColor( COL_BLACK
),
119 mnPattern( EXC_CHLINEFORMAT_SOLID
),
120 mnWeight( EXC_CHLINEFORMAT_SINGLE
),
121 mnFlags( EXC_CHLINEFORMAT_AUTO
)
125 // ----------------------------------------------------------------------------
127 XclChAreaFormat::XclChAreaFormat() :
128 maPattColor( COL_WHITE
),
129 maBackColor( COL_BLACK
),
130 mnPattern( EXC_PATT_SOLID
),
131 mnFlags( EXC_CHAREAFORMAT_AUTO
)
135 // ----------------------------------------------------------------------------
137 XclChEscherFormat::XclChEscherFormat()
141 XclChEscherFormat::~XclChEscherFormat()
145 // ----------------------------------------------------------------------------
147 XclChPicFormat::XclChPicFormat() :
148 mnBmpMode( EXC_CHPICFORMAT_NONE
),
149 mnFormat( EXC_CHPICFORMAT_DEFAULT
),
150 mnFlags( EXC_CHPICFORMAT_DEFAULTFLAGS
),
155 // ----------------------------------------------------------------------------
157 XclChFrame::XclChFrame() :
158 mnFormat( EXC_CHFRAME_STANDARD
),
159 mnFlags( EXC_CHFRAME_AUTOSIZE
| EXC_CHFRAME_AUTOPOS
)
163 // Source links ===============================================================
165 XclChSourceLink::XclChSourceLink() :
166 mnDestType( EXC_CHSRCLINK_TITLE
),
167 mnLinkType( EXC_CHSRCLINK_DEFAULT
),
173 // Text =======================================================================
175 XclChObjectLink::XclChObjectLink() :
176 mnTarget( EXC_CHOBJLINK_NONE
)
180 // ----------------------------------------------------------------------------
182 XclChFrLabelProps::XclChFrLabelProps() :
187 // ----------------------------------------------------------------------------
189 XclChText::XclChText() :
190 maTextColor( COL_BLACK
),
191 mnHAlign( EXC_CHTEXT_ALIGN_CENTER
),
192 mnVAlign( EXC_CHTEXT_ALIGN_CENTER
),
193 mnBackMode( EXC_CHTEXT_TRANSPARENT
),
194 mnFlags( EXC_CHTEXT_AUTOCOLOR
| EXC_CHTEXT_AUTOFILL
),
195 mnPlacement( EXC_CHTEXT_POS_DEFAULT
),
196 mnRotation( EXC_ROT_NONE
)
200 // Data series ================================================================
202 XclChMarkerFormat::XclChMarkerFormat() :
203 maLineColor( COL_BLACK
),
204 maFillColor( COL_WHITE
),
205 mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE
),
206 mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL
),
207 mnFlags( EXC_CHMARKERFORMAT_AUTO
)
211 // ----------------------------------------------------------------------------
213 XclCh3dDataFormat::XclCh3dDataFormat() :
214 mnBase( EXC_CH3DDATAFORMAT_RECT
),
215 mnTop( EXC_CH3DDATAFORMAT_STRAIGHT
)
219 // ----------------------------------------------------------------------------
221 XclChDataFormat::XclChDataFormat() :
222 mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT
),
227 // ----------------------------------------------------------------------------
229 XclChSerTrendLine::XclChSerTrendLine() :
230 mfForecastFor( 0.0 ),
231 mfForecastBack( 0.0 ),
232 mnLineType( EXC_CHSERTREND_POLYNOMIAL
),
237 /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
238 there is no interception point. Cannot use ::rtl::math::setNan() here
239 cause it misses the sign bit. */
240 sal_math_Double
* pDouble
= reinterpret_cast< sal_math_Double
* >( &mfIntercept
);
241 pDouble
->w32_parts
.msw
= pDouble
->w32_parts
.lsw
= 0xFFFFFFFF;
244 // ----------------------------------------------------------------------------
246 XclChSerErrorBar::XclChSerErrorBar() :
249 mnBarType( EXC_CHSERERR_NONE
),
250 mnSourceType( EXC_CHSERERR_FIXED
),
251 mnLineEnd( EXC_CHSERERR_END_TSHAPE
)
255 // ----------------------------------------------------------------------------
257 XclChSeries::XclChSeries() :
258 mnCategType( EXC_CHSERIES_NUMERIC
),
259 mnValueType( EXC_CHSERIES_NUMERIC
),
260 mnBubbleType( EXC_CHSERIES_NUMERIC
),
267 // Chart type groups ==========================================================
269 XclChType::XclChType() :
275 mnBubbleType( EXC_CHSCATTER_AREA
),
280 // ----------------------------------------------------------------------------
282 XclChChart3d::XclChChart3d() :
289 mnFlags( EXC_CHCHART3D_AUTOHEIGHT
)
293 // ----------------------------------------------------------------------------
295 XclChLegend::XclChLegend() :
296 mnDockMode( EXC_CHLEGEND_RIGHT
),
297 mnSpacing( EXC_CHLEGEND_MEDIUM
),
298 mnFlags( EXC_CHLEGEND_DOCKED
| EXC_CHLEGEND_AUTOSERIES
|
299 EXC_CHLEGEND_AUTOPOSX
| EXC_CHLEGEND_AUTOPOSY
| EXC_CHLEGEND_STACKED
)
303 // ----------------------------------------------------------------------------
305 XclChTypeGroup::XclChTypeGroup() :
307 mnGroupIdx( EXC_CHSERGROUP_NONE
)
311 // ----------------------------------------------------------------------------
313 XclChProperties::XclChProperties() :
314 mnFlags( EXC_CHPROPS_MANSERIES
),
315 mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP
)
319 // Axes =======================================================================
321 XclChLabelRange::XclChLabelRange() :
329 // ----------------------------------------------------------------------------
331 XclChValueRange::XclChValueRange() :
337 mnFlags( EXC_CHVALUERANGE_AUTOMIN
| EXC_CHVALUERANGE_AUTOMAX
|
338 EXC_CHVALUERANGE_AUTOMAJOR
| EXC_CHVALUERANGE_AUTOMINOR
| EXC_CHVALUERANGE_AUTOCROSS
| EXC_CHVALUERANGE_BIT8
)
342 // ----------------------------------------------------------------------------
344 XclChTick::XclChTick() :
345 maTextColor( COL_BLACK
),
346 mnMajor( EXC_CHTICK_INSIDE
| EXC_CHTICK_OUTSIDE
),
348 mnLabelPos( EXC_CHTICK_NEXT
),
349 mnBackMode( EXC_CHTICK_TRANSPARENT
),
350 mnFlags( EXC_CHTICK_AUTOCOLOR
| EXC_CHTICK_AUTOROT
),
351 mnRotation( EXC_ROT_NONE
)
355 // ----------------------------------------------------------------------------
357 XclChAxis::XclChAxis() :
358 mnType( EXC_CHAXIS_NONE
)
362 sal_Int32
XclChAxis::GetApiAxisDimension() const
364 sal_Int32 nApiAxisDim
= EXC_CHART_AXIS_NONE
;
367 case EXC_CHAXIS_X
: nApiAxisDim
= EXC_CHART_AXIS_X
; break;
368 case EXC_CHAXIS_Y
: nApiAxisDim
= EXC_CHART_AXIS_Y
; break;
369 case EXC_CHAXIS_Z
: nApiAxisDim
= EXC_CHART_AXIS_Z
; break;
374 // ----------------------------------------------------------------------------
376 XclChAxesSet::XclChAxesSet() :
377 mnAxesSetId( EXC_CHAXESSET_PRIMARY
)
381 sal_Int32
XclChAxesSet::GetApiAxesSetIndex() const
383 sal_Int32 nApiAxesSetIdx
= EXC_CHART_AXESSET_NONE
;
384 switch( mnAxesSetId
)
386 case EXC_CHAXESSET_PRIMARY
: nApiAxesSetIdx
= EXC_CHART_AXESSET_PRIMARY
; break;
387 case EXC_CHAXESSET_SECONDARY
: nApiAxesSetIdx
= EXC_CHART_AXESSET_SECONDARY
; break;
389 return nApiAxesSetIdx
;
392 // Static helper functions ====================================================
394 sal_uInt16
XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx
)
396 static const sal_uInt16 spnLineColors
[] =
398 32, 33, 34, 35, 36, 37, 38, 39,
399 40, 41, 42, 43, 44, 45, 46, 47,
400 48, 49, 50, 51, 52, 53, 54, 55,
401 56, 57, 58, 59, 60, 61, 62, 8,
402 9, 10, 11, 12, 13, 14, 15, 16,
403 17, 18, 19, 20, 21, 22, 23, 24,
404 25, 26, 27, 28, 29, 30, 31, 63
406 return spnLineColors
[ nFormatIdx
% STATIC_TABLE_SIZE( spnLineColors
) ];
409 sal_uInt16
XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx
)
411 static const sal_uInt16 spnFillColors
[] =
413 24, 25, 26, 27, 28, 29, 30, 31,
414 32, 33, 34, 35, 36, 37, 38, 39,
415 40, 41, 42, 43, 44, 45, 46, 47,
416 48, 49, 50, 51, 52, 53, 54, 55,
417 56, 57, 58, 59, 60, 61, 62, 63,
418 8, 9, 10, 11, 12, 13, 14, 15,
419 16, 17, 18, 19, 20, 21, 22, 23
421 return spnFillColors
[ nFormatIdx
% STATIC_TABLE_SIZE( spnFillColors
) ];
424 sal_uInt8
XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx
)
426 static const sal_uInt8 spnTrans
[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
427 return spnTrans
[ (nFormatIdx
/ 56) % STATIC_TABLE_SIZE( spnTrans
) ];
430 sal_uInt16
XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx
)
432 static const sal_uInt16 spnSymbols
[] = {
433 EXC_CHMARKERFORMAT_DIAMOND
, EXC_CHMARKERFORMAT_SQUARE
, EXC_CHMARKERFORMAT_TRIANGLE
,
434 EXC_CHMARKERFORMAT_CROSS
, EXC_CHMARKERFORMAT_STAR
, EXC_CHMARKERFORMAT_CIRCLE
,
435 EXC_CHMARKERFORMAT_PLUS
, EXC_CHMARKERFORMAT_DOWJ
, EXC_CHMARKERFORMAT_STDDEV
};
436 return spnSymbols
[ nFormatIdx
% STATIC_TABLE_SIZE( spnSymbols
) ];
439 bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType
)
441 static const bool spbFilled
[] = {
442 false, true, true, true, false, false, false, false, true, false };
443 return (nMarkerType
< STATIC_TABLE_SIZE( spbFilled
)) && spbFilled
[ nMarkerType
];
446 OUString
XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType
)
450 case EXC_CHSERERR_XPLUS
: return EXC_CHPROP_ROLE_ERRORBARS_POSX
;
451 case EXC_CHSERERR_XMINUS
: return EXC_CHPROP_ROLE_ERRORBARS_NEGX
;
452 case EXC_CHSERERR_YPLUS
: return EXC_CHPROP_ROLE_ERRORBARS_POSY
;
453 case EXC_CHSERERR_YMINUS
: return EXC_CHPROP_ROLE_ERRORBARS_NEGY
;
454 default: DBG_ERRORFILE( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
459 // Chart formatting info provider =============================================
463 static const XclChFormatInfo spFmtInfos
[] =
465 // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
466 { EXC_CHOBJTYPE_BACKGROUND
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, true, true, true },
467 { EXC_CHOBJTYPE_PLOTFRAME
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, true, true, true },
468 { EXC_CHOBJTYPE_WALL3D
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, true, false, true },
469 { EXC_CHOBJTYPE_FLOOR3D
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, 23, EXC_CHFRAMETYPE_AUTO
, true, false, true },
470 { EXC_CHOBJTYPE_TEXT
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, true, true },
471 { EXC_CHOBJTYPE_LEGEND
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, true, true, true },
472 { EXC_CHOBJTYPE_LINEARSERIES
, EXC_CHPROPMODE_LINEARSERIES
, 0xFFFF, EXC_CHLINEFORMAT_SINGLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, false, false, false },
473 { EXC_CHOBJTYPE_FILLEDSERIES
, EXC_CHPROPMODE_FILLEDSERIES
, EXC_COLOR_CHBORDERAUTO
, EXC_CHLINEFORMAT_SINGLE
, 0xFFFF, EXC_CHFRAMETYPE_AUTO
, false, false, true },
474 { EXC_CHOBJTYPE_AXISLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_AUTO
, false, false, false },
475 { EXC_CHOBJTYPE_GRIDLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, true, false },
476 { EXC_CHOBJTYPE_TRENDLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_DOUBLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
477 { EXC_CHOBJTYPE_ERRORBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_SINGLE
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
478 { EXC_CHOBJTYPE_CONNECTLINE
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
479 { EXC_CHOBJTYPE_HILOLINE
, EXC_CHPROPMODE_LINEARSERIES
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, false },
480 { EXC_CHOBJTYPE_WHITEDROPBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWBACK
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, true },
481 { EXC_CHOBJTYPE_BLACKDROPBAR
, EXC_CHPROPMODE_COMMON
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHLINEFORMAT_HAIR
, EXC_COLOR_CHWINDOWTEXT
, EXC_CHFRAMETYPE_INVISIBLE
, false, false, true }
486 // ----------------------------------------------------------------------------
488 XclChFormatInfoProvider::XclChFormatInfoProvider()
490 const XclChFormatInfo
* pEnd
= STATIC_TABLE_END( spFmtInfos
);
491 for( const XclChFormatInfo
* pIt
= spFmtInfos
; pIt
!= pEnd
; ++pIt
)
492 maInfoMap
[ pIt
->meObjType
] = pIt
;
495 const XclChFormatInfo
& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType
) const
497 XclFmtInfoMap::const_iterator aIt
= maInfoMap
.find( eObjType
);
498 DBG_ASSERT( aIt
!= maInfoMap
.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
499 return (aIt
== maInfoMap
.end()) ? *spFmtInfos
: *aIt
->second
;
502 // Chart type info provider ===================================================
506 // chart type service names
507 const sal_Char SERVICE_CHART2_AREA
[] = "com.sun.star.chart2.AreaChartType";
508 const sal_Char SERVICE_CHART2_CANDLE
[] = "com.sun.star.chart2.CandleStickChartType";
509 const sal_Char SERVICE_CHART2_COLUMN
[] = "com.sun.star.chart2.ColumnChartType";
510 const sal_Char SERVICE_CHART2_LINE
[] = "com.sun.star.chart2.LineChartType";
511 const sal_Char SERVICE_CHART2_NET
[] = "com.sun.star.chart2.NetChartType";
512 const sal_Char SERVICE_CHART2_FILLEDNET
[] = "com.sun.star.chart2.FilledNetChartType";
513 const sal_Char SERVICE_CHART2_PIE
[] = "com.sun.star.chart2.PieChartType";
514 const sal_Char SERVICE_CHART2_SCATTER
[] = "com.sun.star.chart2.ScatterChartType";
515 const sal_Char SERVICE_CHART2_BUBBLE
[] = "com.sun.star.chart2.BubbleChartType";
516 const sal_Char SERVICE_CHART2_SURFACE
[] = "com.sun.star.chart2.ColumnChartType"; // Todo
518 namespace csscd
= ::com::sun::star::chart::DataLabelPlacement
;
520 static const XclChTypeInfo spTypeInfos
[] =
522 // 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
523 { 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 },
524 { 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 },
525 { 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 },
526 { 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 },
527 { 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 },
528 { 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 },
529 { 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 },
530 { 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 },
531 { 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, true, false },
532 { 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 },
533 { 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 },
534 { 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 },
535 { 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 },
536 { 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 }
541 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo
& rTypeInfo
) :
542 XclChTypeInfo( rTypeInfo
),
548 void XclChExtTypeInfo::Set( const XclChTypeInfo
& rTypeInfo
, bool b3dChart
, bool bSpline
)
550 static_cast< XclChTypeInfo
& >( *this ) = rTypeInfo
;
551 mb3dChart
= mbSupports3d
&& b3dChart
;
555 // ----------------------------------------------------------------------------
557 XclChTypeInfoProvider::XclChTypeInfoProvider()
559 const XclChTypeInfo
* pEnd
= STATIC_TABLE_END( spTypeInfos
);
560 for( const XclChTypeInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
561 maInfoMap
[ pIt
->meTypeId
] = pIt
;
564 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId
) const
566 XclChTypeInfoMap::const_iterator aIt
= maInfoMap
.find( eTypeId
);
567 DBG_ASSERT( aIt
!= maInfoMap
.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
568 return (aIt
== maInfoMap
.end()) ? *maInfoMap
.rbegin()->second
: *aIt
->second
;
571 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId
) const
573 const XclChTypeInfo
* pEnd
= STATIC_TABLE_END( spTypeInfos
);
574 for( const XclChTypeInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
575 if( pIt
->mnRecId
== nRecId
)
577 DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
578 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
581 const XclChTypeInfo
& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString
& rServiceName
) const
583 const XclChTypeInfo
* pEnd
= STATIC_TABLE_END( spTypeInfos
);
584 for( const XclChTypeInfo
* pIt
= spTypeInfos
; pIt
!= pEnd
; ++pIt
)
585 if( rServiceName
.equalsAscii( pIt
->mpcServiceName
) )
587 DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
588 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN
);
591 // Property helpers ===========================================================
593 XclChObjectTable::XclChObjectTable( Reference
< XMultiServiceFactory
> xFactory
,
594 const OUString
& rServiceName
, const OUString
& rObjNameBase
) :
595 mxFactory( xFactory
),
596 maServiceName( rServiceName
),
597 maObjNameBase( rObjNameBase
),
602 Any
XclChObjectTable::GetObject( const OUString
& rObjName
)
605 if( !mxContainer
.is() )
606 mxContainer
.set( ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), UNO_QUERY
);
607 DBG_ASSERT( mxContainer
.is(), "XclChObjectTable::GetObject - container not found" );
610 if( mxContainer
.is() )
612 // get object from container
615 aObj
= mxContainer
->getByName( rObjName
);
619 DBG_ERRORFILE( "XclChObjectTable::GetObject - object not found" );
625 OUString
XclChObjectTable::InsertObject( const Any
& rObj
)
628 // create object table
629 if( !mxContainer
.is() )
630 mxContainer
.set( ScfApiHelper::CreateInstance( mxFactory
, maServiceName
), UNO_QUERY
);
631 DBG_ASSERT( mxContainer
.is(), "XclChObjectTable::InsertObject - container not found" );
634 if( mxContainer
.is() )
636 // create new unused identifier
639 aObjName
= maObjNameBase
+ OUString::valueOf( ++mnIndex
);
641 while( mxContainer
->hasByName( aObjName
) );
646 mxContainer
->insertByName( aObjName
, rObj
);
650 DBG_ERRORFILE( "XclChObjectTable::InsertObject - cannot insert object" );
651 aObjName
= OUString();
657 // Property names -------------------------------------------------------------
661 /** Property names for line style in common objects. */
662 const sal_Char
* const sppcLineNamesCommon
[] =
663 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", 0 };
664 /** Property names for line style in linear series objects. */
665 const sal_Char
* const sppcLineNamesLinear
[] =
666 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", 0 };
667 /** Property names for line style in filled series objects. */
668 const sal_Char
* const sppcLineNamesFilled
[] =
669 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", 0 };
671 /** Property names for solid area style in common objects. */
672 const sal_Char
* const sppcAreaNamesCommon
[] = { "FillStyle", "FillColor", "FillTransparence", 0 };
673 /** Property names for solid area style in filled series objects. */
674 const sal_Char
* const sppcAreaNamesFilled
[] = { "FillStyle", "Color", "Transparency", 0 };
675 /** Property names for gradient area style in common objects. */
676 const sal_Char
* const sppcGradNamesCommon
[] = { "FillStyle", "FillGradientName", 0 };
677 /** Property names for gradient area style in filled series objects. */
678 const sal_Char
* const sppcGradNamesFilled
[] = { "FillStyle", "GradientName", 0 };
679 /** Property names for hatch area style in common objects. */
680 const sal_Char
* const sppcHatchNamesCommon
[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", 0 };
681 /** Property names for hatch area style in filled series objects. */
682 const sal_Char
* const sppcHatchNamesFilled
[] = { "FillStyle", "HatchName", "Color", "FillBackground", 0 };
683 /** Property names for bitmap area style. */
684 const sal_Char
* const sppcBitmapNames
[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 };
686 /** Property names for legend properties. */
687 const sal_Char
* const sppcLegendNames
[] =
688 { "Show", "AnchorPosition", "Expansion", "RelativePosition", 0 };
692 // ----------------------------------------------------------------------------
694 XclChPropSetHelper::XclChPropSetHelper() :
695 maLineHlpCommon( sppcLineNamesCommon
),
696 maLineHlpLinear( sppcLineNamesLinear
),
697 maLineHlpFilled( sppcLineNamesFilled
),
698 maAreaHlpCommon( sppcAreaNamesCommon
),
699 maAreaHlpFilled( sppcAreaNamesFilled
),
700 maGradHlpCommon( sppcGradNamesCommon
),
701 maGradHlpFilled( sppcGradNamesFilled
),
702 maHatchHlpCommon( sppcHatchNamesCommon
),
703 maHatchHlpFilled( sppcHatchNamesFilled
),
704 maBitmapHlp( sppcBitmapNames
),
705 maLegendHlp( sppcLegendNames
)
709 // read properties ------------------------------------------------------------
711 void XclChPropSetHelper::ReadLineProperties(
712 XclChLineFormat
& rLineFmt
, XclChObjectTable
& rDashTable
,
713 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
715 namespace cssd
= ::com::sun::star::drawing
;
717 // read properties from property set
718 cssd::LineStyle eApiStyle
= cssd::LineStyle_NONE
;
719 sal_Int32 nApiWidth
= 0;
720 sal_Int16 nApiTrans
= 0;
723 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
724 rLineHlp
.ReadFromPropertySet( rPropSet
);
725 rLineHlp
>> eApiStyle
>> nApiWidth
>> rLineFmt
.maColor
>> nApiTrans
>> aDashNameAny
;
727 // clear automatic flag
728 ::set_flag( rLineFmt
.mnFlags
, EXC_CHLINEFORMAT_AUTO
, false );
731 if( nApiWidth
<= 0 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_HAIR
;
732 else if( nApiWidth
<= 35 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_SINGLE
;
733 else if( nApiWidth
<= 70 ) rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_DOUBLE
;
734 else rLineFmt
.mnWeight
= EXC_CHLINEFORMAT_TRIPLE
;
739 case cssd::LineStyle_NONE
:
740 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
742 case cssd::LineStyle_SOLID
:
744 if( nApiTrans
< 13 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
745 else if( nApiTrans
< 38 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_DARKTRANS
;
746 else if( nApiTrans
< 63 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_MEDTRANS
;
747 else if( nApiTrans
< 100 ) rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_LIGHTTRANS
;
748 else rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_NONE
;
751 case cssd::LineStyle_DASH
:
753 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
755 cssd::LineDash aApiDash
;
756 if( (aDashNameAny
>>= aDashName
) && (rDashTable
.GetObject( aDashName
) >>= aApiDash
) )
758 // reorder dashes that are shorter than dots
759 if( (aApiDash
.Dashes
== 0) || (aApiDash
.DashLen
< aApiDash
.DotLen
) )
761 ::std::swap( aApiDash
.Dashes
, aApiDash
.Dots
);
762 ::std::swap( aApiDash
.DashLen
, aApiDash
.DotLen
);
764 // ignore dots that are nearly equal to dashes
765 if( aApiDash
.DotLen
* 3 > aApiDash
.DashLen
* 2 )
768 // convert line dash to predefined Excel dash types
769 if( (aApiDash
.Dashes
== 1) && (aApiDash
.Dots
>= 1) )
770 // one dash and one or more dots
771 rLineFmt
.mnPattern
= (aApiDash
.Dots
== 1) ?
772 EXC_CHLINEFORMAT_DASHDOT
: EXC_CHLINEFORMAT_DASHDOTDOT
;
773 else if( aApiDash
.Dashes
>= 1 )
774 // one or more dashes and no dots (also: dash-dash-dot)
775 rLineFmt
.mnPattern
= (aApiDash
.DashLen
< 250) ?
776 EXC_CHLINEFORMAT_DOT
: EXC_CHLINEFORMAT_DASH
;
781 DBG_ERRORFILE( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
782 rLineFmt
.mnPattern
= EXC_CHLINEFORMAT_SOLID
;
786 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat
& rAreaFmt
,
787 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
789 namespace cssd
= ::com::sun::star::drawing
;
791 // read properties from property set
792 cssd::FillStyle eApiStyle
= cssd::FillStyle_NONE
;
793 sal_Int16 nTransparency
= 0;
795 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
796 rAreaHlp
.ReadFromPropertySet( rPropSet
);
797 rAreaHlp
>> eApiStyle
>> rAreaFmt
.maPattColor
>> nTransparency
;
799 // clear automatic flag
800 ::set_flag( rAreaFmt
.mnFlags
, EXC_CHAREAFORMAT_AUTO
, false );
802 // set fill style transparent or solid (set solid for anything but transparent)
803 rAreaFmt
.mnPattern
= (eApiStyle
== cssd::FillStyle_NONE
) ? EXC_PATT_NONE
: EXC_PATT_SOLID
;
805 // return true to indicate complex fill (gradient, bitmap, solid transparency)
806 return (eApiStyle
!= cssd::FillStyle_NONE
) && ((eApiStyle
!= cssd::FillStyle_SOLID
) || (nTransparency
> 0));
809 void XclChPropSetHelper::ReadEscherProperties(
810 XclChEscherFormat
& rEscherFmt
, XclChPicFormat
& rPicFmt
,
811 XclChObjectTable
& rGradientTable
, XclChObjectTable
& rHatchTable
, XclChObjectTable
& rBitmapTable
,
812 const ScfPropertySet
& rPropSet
, XclChPropertyMode ePropMode
)
814 namespace cssd
= ::com::sun::star::drawing
;
815 namespace cssa
= ::com::sun::star::awt
;
817 // read style and transparency properties from property set
818 cssd::FillStyle eApiStyle
= cssd::FillStyle_NONE
;
820 sal_Int16 nTransparency
= 0;
822 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
823 rAreaHlp
.ReadFromPropertySet( rPropSet
);
824 rAreaHlp
>> eApiStyle
>> aColor
>> nTransparency
;
828 case cssd::FillStyle_SOLID
:
830 DBG_ASSERT( nTransparency
> 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
831 if( (0 < nTransparency
) && (nTransparency
<= 100) )
833 // convert to Escher properties
834 sal_uInt32 nEscherColor
= 0x02000000;
835 ::insert_value( nEscherColor
, aColor
.GetBlue(), 16, 8 );
836 ::insert_value( nEscherColor
, aColor
.GetGreen(), 8, 8 );
837 ::insert_value( nEscherColor
, aColor
.GetRed(), 0, 8 );
838 sal_uInt32 nEscherOpacity
= static_cast< sal_uInt32
>( (100 - nTransparency
) * 655.36 );
839 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
840 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillType
, ESCHER_FillSolid
);
841 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillColor
, nEscherColor
);
842 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillOpacity
, nEscherOpacity
);
843 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackColor
, 0x02FFFFFF );
844 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fillBackOpacity
, 0x00010000 );
845 rEscherFmt
.mxEscherSet
->AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x001F001C );
849 case cssd::FillStyle_GRADIENT
:
851 // extract gradient from global gradient table
852 OUString aGradientName
;
853 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
854 rGradHlp
.ReadFromPropertySet( rPropSet
);
855 rGradHlp
>> eApiStyle
>> aGradientName
;
856 cssa::Gradient aGradient
;
857 if( rGradientTable
.GetObject( aGradientName
) >>= aGradient
)
859 // convert to Escher properties
860 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
861 rEscherFmt
.mxEscherSet
->CreateGradientProperties( aGradient
);
865 case cssd::FillStyle_HATCH
:
867 // extract hatch from global hatch table
869 bool bFillBackground
;
870 ScfPropSetHelper
& rHatchHlp
= GetHatchHelper( ePropMode
);
871 rHatchHlp
.ReadFromPropertySet( rPropSet
);
872 rHatchHlp
>> eApiStyle
>> aHatchName
>> aColor
>> bFillBackground
;
874 if( rHatchTable
.GetObject( aHatchName
) >>= aHatch
)
876 // convert to Escher properties
877 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
878 rEscherFmt
.mxEscherSet
->CreateEmbeddedHatchProperties( aHatch
, aColor
, bFillBackground
);
879 rPicFmt
.mnBmpMode
= EXC_CHPICFORMAT_STACK
;
883 case cssd::FillStyle_BITMAP
:
885 // extract bitmap URL from global bitmap table
886 OUString aBitmapName
;
887 cssd::BitmapMode eApiBmpMode
;
888 maBitmapHlp
.ReadFromPropertySet( rPropSet
);
889 maBitmapHlp
>> eApiStyle
>> aBitmapName
>> eApiBmpMode
;
891 if( rBitmapTable
.GetObject( aBitmapName
) >>= aBitmapUrl
)
893 // convert to Escher properties
894 rEscherFmt
.mxEscherSet
.reset( new EscherPropertyContainer
);
895 rEscherFmt
.mxEscherSet
->CreateEmbeddedBitmapProperties( aBitmapUrl
, eApiBmpMode
);
896 rPicFmt
.mnBmpMode
= (eApiBmpMode
== cssd::BitmapMode_REPEAT
) ?
897 EXC_CHPICFORMAT_STACK
: EXC_CHPICFORMAT_STRETCH
;
902 DBG_ERRORFILE( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
906 void XclChPropSetHelper::ReadMarkerProperties(
907 XclChMarkerFormat
& rMarkerFmt
, const ScfPropertySet
& rPropSet
, sal_uInt16 nFormatIdx
)
909 namespace cssc
= ::com::sun::star::chart2
;
910 namespace cssa
= ::com::sun::star::awt
;
911 cssc::Symbol aApiSymbol
;
912 if( rPropSet
.GetProperty( aApiSymbol
, EXC_CHPROP_SYMBOL
) )
914 // clear automatic flag
915 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_AUTO
, false );
918 switch( aApiSymbol
.Style
)
920 case cssc::SymbolStyle_NONE
:
921 rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_NOSYMBOL
;
923 case cssc::SymbolStyle_STANDARD
:
924 switch( aApiSymbol
.StandardSymbol
)
926 case 0: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_SQUARE
; break; // square
927 case 1: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_DIAMOND
; break; // diamond
928 case 2: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STDDEV
; break; // arrow down
929 case 3: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_TRIANGLE
; break; // arrow up
930 case 4: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CIRCLE
; break; // arrow right
931 case 5: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_PLUS
; break; // arrow left
932 case 6: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_CROSS
; break; // bow tie
933 case 7: rMarkerFmt
.mnMarkerType
= EXC_CHMARKERFORMAT_STAR
; break; // sand glass
934 default: rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
938 rMarkerFmt
.mnMarkerType
= XclChartHelper::GetAutoMarkerType( nFormatIdx
);
940 bool bHasFillColor
= XclChartHelper::HasMarkerFillColor( rMarkerFmt
.mnMarkerType
);
941 ::set_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOFILL
, !bHasFillColor
);
944 sal_Int32 nApiSize
= (aApiSymbol
.Size
.Width
+ aApiSymbol
.Size
.Height
+ 1) / 2;
945 rMarkerFmt
.mnMarkerSize
= XclTools::GetTwipsFromHmm( nApiSize
);
948 rMarkerFmt
.maLineColor
= ScfApiHelper::ConvertFromApiColor( aApiSymbol
.BorderColor
);
949 rMarkerFmt
.maFillColor
= ScfApiHelper::ConvertFromApiColor( aApiSymbol
.FillColor
);
953 sal_uInt16
XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet
& rPropSet
, bool bSupportsStacked
)
955 // chart2 handles rotation as double in the range [0,360)
957 rPropSet
.GetProperty( fAngle
, EXC_CHPROP_TEXTROTATION
);
958 bool bStacked
= bSupportsStacked
&& rPropSet
.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS
);
959 return bStacked
? EXC_ROT_STACKED
:
960 XclTools::GetXclRotation( static_cast< sal_Int32
>( fAngle
* 100.0 + 0.5 ) );
963 void XclChPropSetHelper::ReadLegendProperties( XclChLegend
& rLegend
, const ScfPropertySet
& rPropSet
)
965 namespace cssc
= ::com::sun::star::chart2
;
966 namespace cssd
= ::com::sun::star::drawing
;
968 // read the properties
970 cssc::LegendPosition eApiPos
;
971 cssc::LegendExpansion eApiExpand
;
973 maLegendHlp
.ReadFromPropertySet( rPropSet
);
974 maLegendHlp
>> bShow
>> eApiPos
>> eApiExpand
>> aRelPosAny
;
975 DBG_ASSERT( bShow
, "XclChPropSetHelper::ReadLegendProperties - legend must be visible" );
980 case cssc::LegendPosition_LINE_START
: rLegend
.mnDockMode
= EXC_CHLEGEND_LEFT
; break;
981 case cssc::LegendPosition_LINE_END
: rLegend
.mnDockMode
= EXC_CHLEGEND_RIGHT
; break;
982 case cssc::LegendPosition_PAGE_START
: rLegend
.mnDockMode
= EXC_CHLEGEND_TOP
; break;
983 case cssc::LegendPosition_PAGE_END
: rLegend
.mnDockMode
= EXC_CHLEGEND_BOTTOM
; break;
984 default: rLegend
.mnDockMode
= EXC_CHLEGEND_NOTDOCKED
;
987 ::set_flag( rLegend
.mnFlags
, EXC_CHLEGEND_STACKED
, eApiExpand
!= cssc::LegendExpansion_WIDE
);
989 if( rLegend
.mnDockMode
== EXC_CHLEGEND_NOTDOCKED
)
991 cssc::RelativePosition aRelPos
;
992 if( aRelPosAny
>>= aRelPos
)
994 rLegend
.maRect
.mnX
= limit_cast
< sal_Int32
>( aRelPos
.Primary
* 4000.0, 0, 4000 );
995 rLegend
.maRect
.mnY
= limit_cast
< sal_Int32
>( aRelPos
.Secondary
* 4000.0, 0, 4000 );
998 rLegend
.mnDockMode
= EXC_CHLEGEND_LEFT
;
1000 ::set_flag( rLegend
.mnFlags
, EXC_CHLEGEND_DOCKED
, rLegend
.mnDockMode
!= EXC_CHLEGEND_NOTDOCKED
);
1003 // write properties -----------------------------------------------------------
1005 void XclChPropSetHelper::WriteLineProperties(
1006 ScfPropertySet
& rPropSet
, XclChObjectTable
& rDashTable
,
1007 const XclChLineFormat
& rLineFmt
, XclChPropertyMode ePropMode
)
1009 namespace cssd
= ::com::sun::star::drawing
;
1012 sal_Int32 nApiWidth
= 0; // 0 is the width of a hair line
1013 switch( rLineFmt
.mnWeight
)
1015 case EXC_CHLINEFORMAT_SINGLE
: nApiWidth
= 35; break;
1016 case EXC_CHLINEFORMAT_DOUBLE
: nApiWidth
= 70; break;
1017 case EXC_CHLINEFORMAT_TRIPLE
: nApiWidth
= 105; break;
1021 cssd::LineStyle eApiStyle
= cssd::LineStyle_NONE
;
1022 sal_Int16 nApiTrans
= 0;
1023 sal_Int32 nDotLen
= ::std::min
< sal_Int32
>( rLineFmt
.mnWeight
+ 105, 210 );
1024 cssd::LineDash
aApiDash( cssd::DashStyle_RECT
, 0, nDotLen
, 0, 4 * nDotLen
, nDotLen
);
1026 switch( rLineFmt
.mnPattern
)
1028 case EXC_CHLINEFORMAT_SOLID
:
1029 eApiStyle
= cssd::LineStyle_SOLID
;
1031 case EXC_CHLINEFORMAT_DARKTRANS
:
1032 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 25;
1034 case EXC_CHLINEFORMAT_MEDTRANS
:
1035 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 50;
1037 case EXC_CHLINEFORMAT_LIGHTTRANS
:
1038 eApiStyle
= cssd::LineStyle_SOLID
; nApiTrans
= 75;
1040 case EXC_CHLINEFORMAT_DASH
:
1041 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= 1;
1043 case EXC_CHLINEFORMAT_DOT
:
1044 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dots
= 1;
1046 case EXC_CHLINEFORMAT_DASHDOT
:
1047 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= aApiDash
.Dots
= 1;
1049 case EXC_CHLINEFORMAT_DASHDOTDOT
:
1050 eApiStyle
= cssd::LineStyle_DASH
; aApiDash
.Dashes
= 1; aApiDash
.Dots
= 2;
1055 sal_Int32 nApiColor
= ScfApiHelper::ConvertToApiColor( rLineFmt
.maColor
);
1057 // try to insert the dash style and receive its name
1059 if( eApiStyle
== cssd::LineStyle_DASH
)
1061 OUString aDashName
= rDashTable
.InsertObject( ::com::sun::star::uno::makeAny( aApiDash
) );
1062 if( aDashName
.getLength() )
1063 aDashNameAny
<<= aDashName
;
1066 // write the properties
1067 ScfPropSetHelper
& rLineHlp
= GetLineHelper( ePropMode
);
1068 rLineHlp
.InitializeWrite();
1069 rLineHlp
<< eApiStyle
<< nApiWidth
<< nApiColor
<< nApiTrans
<< aDashNameAny
;
1070 rLineHlp
.WriteToPropertySet( rPropSet
);
1073 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet
& rPropSet
,
1074 const XclChAreaFormat
& rAreaFmt
, XclChPropertyMode ePropMode
)
1076 namespace cssd
= ::com::sun::star::drawing
;
1077 cssd::FillStyle eFillStyle
= cssd::FillStyle_NONE
;
1079 sal_Int16 nTransparency
= 0;
1082 if( rAreaFmt
.mnPattern
!= EXC_PATT_NONE
)
1084 eFillStyle
= cssd::FillStyle_SOLID
;
1085 aColor
= XclTools::GetPatternColor( rAreaFmt
.maPattColor
, rAreaFmt
.maBackColor
, rAreaFmt
.mnPattern
);
1088 // write the properties
1089 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
1090 rAreaHlp
.InitializeWrite();
1091 rAreaHlp
<< eFillStyle
<< aColor
<< nTransparency
;
1092 rAreaHlp
.WriteToPropertySet( rPropSet
);
1095 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet
& rPropSet
,
1096 XclChObjectTable
& rGradientTable
, XclChObjectTable
& /*rHatchTable*/, XclChObjectTable
& rBitmapTable
,
1097 const XclChEscherFormat
& rEscherFmt
, const XclChPicFormat
& rPicFmt
,
1098 XclChPropertyMode ePropMode
)
1100 if( rEscherFmt
.mxItemSet
.is() )
1102 if( const XFillStyleItem
* pStyleItem
= static_cast< const XFillStyleItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLSTYLE
, FALSE
) ) )
1104 switch( pStyleItem
->GetValue() )
1107 // #i84812# Excel 2007 writes Escher properties for solid fill
1108 if( const XFillColorItem
* pColorItem
= static_cast< const XFillColorItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLCOLOR
, FALSE
) ) )
1110 namespace cssd
= ::com::sun::star::drawing
;
1111 // get solid transparence too
1112 const XFillTransparenceItem
* pTranspItem
= static_cast< const XFillTransparenceItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLTRANSPARENCE
, FALSE
) );
1113 sal_uInt16 nTransp
= pTranspItem
? pTranspItem
->GetValue() : 0;
1114 ScfPropSetHelper
& rAreaHlp
= GetAreaHelper( ePropMode
);
1115 rAreaHlp
.InitializeWrite();
1116 rAreaHlp
<< cssd::FillStyle_SOLID
<< pColorItem
->GetColorValue() << static_cast< sal_Int16
>( nTransp
);
1117 rAreaHlp
.WriteToPropertySet( rPropSet
);
1120 case XFILL_GRADIENT
:
1121 if( const XFillGradientItem
* pGradItem
= static_cast< const XFillGradientItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLGRADIENT
, FALSE
) ) )
1124 if( pGradItem
->QueryValue( aGradientAny
, MID_FILLGRADIENT
) )
1126 OUString aGradName
= rGradientTable
.InsertObject( aGradientAny
);
1127 if( aGradName
.getLength() )
1129 namespace cssd
= ::com::sun::star::drawing
;
1130 ScfPropSetHelper
& rGradHlp
= GetGradientHelper( ePropMode
);
1131 rGradHlp
.InitializeWrite();
1132 rGradHlp
<< cssd::FillStyle_GRADIENT
<< aGradName
;
1133 rGradHlp
.WriteToPropertySet( rPropSet
);
1139 if( const XFillBitmapItem
* pBmpItem
= static_cast< const XFillBitmapItem
* >( rEscherFmt
.mxItemSet
->GetItem( XATTR_FILLBITMAP
, FALSE
) ) )
1142 if( pBmpItem
->QueryValue( aBitmapAny
, MID_GRAFURL
) )
1144 OUString aBmpName
= rBitmapTable
.InsertObject( aBitmapAny
);
1145 if( aBmpName
.getLength() )
1147 namespace cssd
= ::com::sun::star::drawing
;
1148 cssd::BitmapMode eApiBmpMode
= (rPicFmt
.mnBmpMode
== EXC_CHPICFORMAT_STRETCH
) ?
1149 cssd::BitmapMode_STRETCH
: cssd::BitmapMode_REPEAT
;
1150 maBitmapHlp
.InitializeWrite();
1151 maBitmapHlp
<< cssd::FillStyle_BITMAP
<< aBmpName
<< eApiBmpMode
;
1152 maBitmapHlp
.WriteToPropertySet( rPropSet
);
1158 DBG_ERRORFILE( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1164 void XclChPropSetHelper::WriteMarkerProperties(
1165 ScfPropertySet
& rPropSet
, const XclChMarkerFormat
& rMarkerFmt
)
1167 namespace cssc
= ::com::sun::star::chart2
;
1168 namespace cssa
= ::com::sun::star::awt
;
1171 cssc::Symbol aApiSymbol
;
1172 aApiSymbol
.Style
= cssc::SymbolStyle_STANDARD
;
1173 switch( rMarkerFmt
.mnMarkerType
)
1175 case EXC_CHMARKERFORMAT_NOSYMBOL
: aApiSymbol
.Style
= cssc::SymbolStyle_NONE
; break;
1176 case EXC_CHMARKERFORMAT_SQUARE
: aApiSymbol
.StandardSymbol
= 0; break; // square
1177 case EXC_CHMARKERFORMAT_DIAMOND
: aApiSymbol
.StandardSymbol
= 1; break; // diamond
1178 case EXC_CHMARKERFORMAT_TRIANGLE
: aApiSymbol
.StandardSymbol
= 3; break; // arrow up
1179 case EXC_CHMARKERFORMAT_CROSS
: aApiSymbol
.StandardSymbol
= 6; break; // bow tie
1180 case EXC_CHMARKERFORMAT_STAR
: aApiSymbol
.StandardSymbol
= 7; break; // sand glass
1181 case EXC_CHMARKERFORMAT_DOWJ
: aApiSymbol
.StandardSymbol
= 4; break; // arrow right
1182 case EXC_CHMARKERFORMAT_STDDEV
: aApiSymbol
.StandardSymbol
= 2; break; // arrow down
1183 case EXC_CHMARKERFORMAT_CIRCLE
: aApiSymbol
.StandardSymbol
= 4; break; // arrow right
1184 case EXC_CHMARKERFORMAT_PLUS
: aApiSymbol
.StandardSymbol
= 5; break; // arrow left
1188 sal_Int32 nApiSize
= XclTools::GetHmmFromTwips( rMarkerFmt
.mnMarkerSize
);
1189 aApiSymbol
.Size
= cssa::Size( nApiSize
, nApiSize
);
1192 aApiSymbol
.FillColor
= ScfApiHelper::ConvertToApiColor( rMarkerFmt
.maFillColor
);
1193 aApiSymbol
.BorderColor
= ::get_flag( rMarkerFmt
.mnFlags
, EXC_CHMARKERFORMAT_NOLINE
) ?
1194 aApiSymbol
.FillColor
: ScfApiHelper::ConvertToApiColor( rMarkerFmt
.maLineColor
);
1197 rPropSet
.SetProperty( EXC_CHPROP_SYMBOL
, aApiSymbol
);
1200 void XclChPropSetHelper::WriteRotationProperties(
1201 ScfPropertySet
& rPropSet
, sal_uInt16 nRotation
, bool bSupportsStacked
)
1203 if( nRotation
!= EXC_CHART_AUTOROTATION
)
1205 // chart2 handles rotation as double in the range [0,360)
1206 double fAngle
= XclTools::GetScRotation( nRotation
, 0 ) / 100.0;
1207 rPropSet
.SetProperty( EXC_CHPROP_TEXTROTATION
, fAngle
);
1208 if( bSupportsStacked
)
1209 rPropSet
.SetProperty( EXC_CHPROP_STACKCHARACTERS
, nRotation
== EXC_ROT_STACKED
);
1213 void XclChPropSetHelper::WriteLegendProperties(
1214 ScfPropertySet
& rPropSet
, const XclChLegend
& rLegend
)
1216 namespace cssc
= ::com::sun::star::chart2
;
1217 namespace cssd
= ::com::sun::star::drawing
;
1220 cssc::LegendPosition eApiPos
= cssc::LegendPosition_CUSTOM
;
1221 switch( rLegend
.mnDockMode
)
1223 case EXC_CHLEGEND_LEFT
: eApiPos
= cssc::LegendPosition_LINE_START
; break;
1224 case EXC_CHLEGEND_RIGHT
: eApiPos
= cssc::LegendPosition_LINE_END
; break;
1225 case EXC_CHLEGEND_TOP
: eApiPos
= cssc::LegendPosition_PAGE_START
; break;
1226 case EXC_CHLEGEND_BOTTOM
: eApiPos
= cssc::LegendPosition_PAGE_END
; break;
1229 cssc::LegendExpansion eApiExpand
= ::get_flagvalue(
1230 rLegend
.mnFlags
, EXC_CHLEGEND_STACKED
, cssc::LegendExpansion_HIGH
, cssc::LegendExpansion_WIDE
);
1233 if( eApiPos
== cssc::LegendPosition_CUSTOM
)
1235 // #i71697# it is not possible to set the size directly, do some magic here
1236 double fRatio
= ((rLegend
.maRect
.mnWidth
> 0) && (rLegend
.maRect
.mnHeight
> 0)) ?
1237 (static_cast< double >( rLegend
.maRect
.mnWidth
) / rLegend
.maRect
.mnHeight
) : 1.0;
1239 eApiExpand
= cssc::LegendExpansion_WIDE
;
1240 else if( fRatio
< 0.75 )
1241 eApiExpand
= cssc::LegendExpansion_HIGH
;
1243 eApiExpand
= cssc::LegendExpansion_BALANCED
;
1245 cssc::RelativePosition aRelPos
;
1246 aRelPos
.Primary
= rLegend
.maRect
.mnX
/ 4000.0;
1247 aRelPos
.Secondary
= rLegend
.maRect
.mnY
/ 4000.0;
1248 aRelPos
.Anchor
= cssd::Alignment_TOP_LEFT
;
1249 aRelPosAny
<<= aRelPos
;
1252 // write the properties
1253 maLegendHlp
.InitializeWrite();
1254 maLegendHlp
<< true << eApiPos
<< eApiExpand
<< aRelPosAny
;
1255 maLegendHlp
.WriteToPropertySet( rPropSet
);
1258 // private --------------------------------------------------------------------
1260 ScfPropSetHelper
& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode
)
1264 case EXC_CHPROPMODE_COMMON
: return maLineHlpCommon
;
1265 case EXC_CHPROPMODE_LINEARSERIES
: return maLineHlpLinear
;
1266 case EXC_CHPROPMODE_FILLEDSERIES
: return maLineHlpFilled
;
1267 default: DBG_ERRORFILE( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1269 return maLineHlpCommon
;
1272 ScfPropSetHelper
& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode
)
1276 case EXC_CHPROPMODE_COMMON
: return maAreaHlpCommon
;
1277 case EXC_CHPROPMODE_FILLEDSERIES
: return maAreaHlpFilled
;
1278 default: DBG_ERRORFILE( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1280 return maAreaHlpCommon
;
1283 ScfPropSetHelper
& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode
)
1287 case EXC_CHPROPMODE_COMMON
: return maGradHlpCommon
;
1288 case EXC_CHPROPMODE_FILLEDSERIES
: return maGradHlpFilled
;
1289 default: DBG_ERRORFILE( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1291 return maGradHlpCommon
;
1294 ScfPropSetHelper
& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode
)
1298 case EXC_CHPROPMODE_COMMON
: return maHatchHlpCommon
;
1299 case EXC_CHPROPMODE_FILLEDSERIES
: return maHatchHlpFilled
;
1300 default: DBG_ERRORFILE( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1302 return maHatchHlpCommon
;
1305 // ============================================================================
1307 XclChRootData::XclChRootData() :
1308 mxTypeInfoProv( new XclChTypeInfoProvider
),
1309 mxFmtInfoProv( new XclChFormatInfoProvider
)
1313 XclChRootData::~XclChRootData()
1317 Reference
< XChartDocument
> XclChRootData::GetChartDoc() const
1319 DBG_ASSERT( mxChartDoc
.is(), "XclChRootData::GetChartDoc - missing chart document" );
1323 void XclChRootData::InitConversion( XChartDocRef xChartDoc
)
1325 // remember chart document reference
1326 DBG_ASSERT( xChartDoc
.is(), "XclChRootData::InitConversion - missing chart document" );
1327 mxChartDoc
= xChartDoc
;
1329 // create object tables
1330 Reference
< XMultiServiceFactory
> xFactory( mxChartDoc
, UNO_QUERY
);
1331 mxLineDashTable
.reset( new XclChObjectTable(
1332 xFactory
, SERVICE_DRAWING_DASHTABLE
, CREATE_OUSTRING( "Excel line dash " ) ) );
1333 mxGradientTable
.reset( new XclChObjectTable(
1334 xFactory
, SERVICE_DRAWING_GRADIENTTABLE
, CREATE_OUSTRING( "Excel gradient " ) ) );
1335 mxHatchTable
.reset( new XclChObjectTable(
1336 xFactory
, SERVICE_DRAWING_HATCHTABLE
, CREATE_OUSTRING( "Excel hatch " ) ) );
1337 mxBitmapTable
.reset( new XclChObjectTable(
1338 xFactory
, SERVICE_DRAWING_BITMAPTABLE
, CREATE_OUSTRING( "Excel bitmap " ) ) );
1341 void XclChRootData::FinishConversion()
1343 // forget formatting object tables
1344 mxBitmapTable
.reset();
1345 mxHatchTable
.reset();
1346 mxGradientTable
.reset();
1347 mxLineDashTable
.reset();
1348 // forget chart document reference
1352 // ============================================================================