Update ooo320-m1
[ooovba.git] / sc / source / filter / excel / xlchart.cxx
blobd5664c088e29df919c0b90229a9e58c75dd193a2
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>
60 #include "global.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() :
76 mnX( 0 ),
77 mnY( 0 ),
78 mnWidth( 0 ),
79 mnHeight( 0 )
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 ) :
100 mnType( nType ),
101 mnContext( 0 ),
102 mnValue1( 0 ),
103 mnValue2( 0 )
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 ),
151 mfScale( 0.5 )
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 ),
168 mnFlags( 0 ),
169 mnNumFmtIdx( 0 )
173 // Text =======================================================================
175 XclChObjectLink::XclChObjectLink() :
176 mnTarget( EXC_CHOBJLINK_NONE )
180 // ----------------------------------------------------------------------------
182 XclChFrLabelProps::XclChFrLabelProps() :
183 mnFlags( 0 )
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 ),
223 mnFlags( 0 )
227 // ----------------------------------------------------------------------------
229 XclChSerTrendLine::XclChSerTrendLine() :
230 mfForecastFor( 0.0 ),
231 mfForecastBack( 0.0 ),
232 mnLineType( EXC_CHSERTREND_POLYNOMIAL ),
233 mnOrder( 1 ),
234 mnShowEquation( 0 ),
235 mnShowRSquared( 0 )
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() :
247 mfValue( 0.0 ),
248 mnValueCount( 1 ),
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 ),
261 mnCategCount( 0 ),
262 mnValueCount( 0 ),
263 mnBubbleCount( 0 )
267 // Chart type groups ==========================================================
269 XclChType::XclChType() :
270 mnOverlap( 0 ),
271 mnGap( 150 ),
272 mnRotation( 0 ),
273 mnPieHole( 0 ),
274 mnBubbleSize( 100 ),
275 mnBubbleType( EXC_CHSCATTER_AREA ),
276 mnFlags( 0 )
280 // ----------------------------------------------------------------------------
282 XclChChart3d::XclChChart3d() :
283 mnRotation( 20 ),
284 mnElevation( 15 ),
285 mnEyeDist( 30 ),
286 mnRelHeight( 100 ),
287 mnRelDepth( 100 ),
288 mnDepthGap( 150 ),
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() :
306 mnFlags( 0 ),
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() :
322 mnCross( 1 ),
323 mnLabelFreq( 1 ),
324 mnTickFreq( 1 ),
325 mnFlags( 0 )
329 // ----------------------------------------------------------------------------
331 XclChValueRange::XclChValueRange() :
332 mfMin( 0.0 ),
333 mfMax( 0.0 ),
334 mfMajorStep( 0.0 ),
335 mfMinorStep( 0.0 ),
336 mfCross( 0.0 ),
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 ),
347 mnMinor( 0 ),
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;
365 switch( mnType )
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;
371 return nApiAxisDim;
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 )
448 switch( 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" );
456 return OUString();
459 // Chart formatting info provider =============================================
461 namespace {
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 ===================================================
504 namespace {
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 }
539 } // namespace
541 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo ) :
542 XclChTypeInfo( rTypeInfo ),
543 mb3dChart( false ),
544 mbSpline( false )
548 void XclChExtTypeInfo::Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline )
550 static_cast< XclChTypeInfo& >( *this ) = rTypeInfo;
551 mb3dChart = mbSupports3d && b3dChart;
552 mbSpline = bSpline;
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 )
576 return *pIt;
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 ) )
586 return *pIt;
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 ),
598 mnIndex( 0 )
602 Any XclChObjectTable::GetObject( const OUString& rObjName )
604 // get object table
605 if( !mxContainer.is() )
606 mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
607 DBG_ASSERT( mxContainer.is(), "XclChObjectTable::GetObject - container not found" );
609 Any aObj;
610 if( mxContainer.is() )
612 // get object from container
615 aObj = mxContainer->getByName( rObjName );
617 catch( Exception& )
619 DBG_ERRORFILE( "XclChObjectTable::GetObject - object not found" );
622 return aObj;
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" );
633 OUString aObjName;
634 if( mxContainer.is() )
636 // create new unused identifier
639 aObjName = maObjNameBase + OUString::valueOf( ++mnIndex );
641 while( mxContainer->hasByName( aObjName ) );
643 // insert object
646 mxContainer->insertByName( aObjName, rObj );
648 catch( Exception& )
650 DBG_ERRORFILE( "XclChObjectTable::InsertObject - cannot insert object" );
651 aObjName = OUString();
654 return aObjName;
657 // Property names -------------------------------------------------------------
659 namespace {
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 };
690 } // namespace
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;
721 Any aDashNameAny;
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 );
730 // line width
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;
736 // line style
737 switch( eApiStyle )
739 case cssd::LineStyle_NONE:
740 rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
741 break;
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;
750 break;
751 case cssd::LineStyle_DASH:
753 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
754 OUString aDashName;
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 )
766 aApiDash.Dots = 0;
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;
779 break;
780 default:
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;
819 Color aColor;
820 sal_Int16 nTransparency = 0;
822 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
823 rAreaHlp.ReadFromPropertySet( rPropSet );
824 rAreaHlp >> eApiStyle >> aColor >> nTransparency;
826 switch( eApiStyle )
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 );
848 break;
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 );
864 break;
865 case cssd::FillStyle_HATCH:
867 // extract hatch from global hatch table
868 OUString aHatchName;
869 bool bFillBackground;
870 ScfPropSetHelper& rHatchHlp = GetHatchHelper( ePropMode );
871 rHatchHlp.ReadFromPropertySet( rPropSet );
872 rHatchHlp >> eApiStyle >> aHatchName >> aColor >> bFillBackground;
873 cssd::Hatch aHatch;
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;
882 break;
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;
890 OUString aBitmapUrl;
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;
900 break;
901 default:
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 );
917 // symbol style
918 switch( aApiSymbol.Style )
920 case cssc::SymbolStyle_NONE:
921 rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
922 break;
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 );
936 break;
937 default:
938 rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
940 bool bHasFillColor = XclChartHelper::HasMarkerFillColor( rMarkerFmt.mnMarkerType );
941 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOFILL, !bHasFillColor );
943 // symbol size
944 sal_Int32 nApiSize = (aApiSymbol.Size.Width + aApiSymbol.Size.Height + 1) / 2;
945 rMarkerFmt.mnMarkerSize = XclTools::GetTwipsFromHmm( nApiSize );
947 // symbol colors
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)
956 double fAngle = 0.0;
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
969 bool bShow;
970 cssc::LegendPosition eApiPos;
971 cssc::LegendExpansion eApiExpand;
972 Any aRelPosAny;
973 maLegendHlp.ReadFromPropertySet( rPropSet );
974 maLegendHlp >> bShow >> eApiPos >> eApiExpand >> aRelPosAny;
975 DBG_ASSERT( bShow, "XclChPropSetHelper::ReadLegendProperties - legend must be visible" );
977 // legend position
978 switch( eApiPos )
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;
986 // legend expansion
987 ::set_flag( rLegend.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand != cssc::LegendExpansion_WIDE );
988 // legend position
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 );
997 else
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;
1011 // line width
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;
1020 // line style
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;
1030 break;
1031 case EXC_CHLINEFORMAT_DARKTRANS:
1032 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 25;
1033 break;
1034 case EXC_CHLINEFORMAT_MEDTRANS:
1035 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 50;
1036 break;
1037 case EXC_CHLINEFORMAT_LIGHTTRANS:
1038 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 75;
1039 break;
1040 case EXC_CHLINEFORMAT_DASH:
1041 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1;
1042 break;
1043 case EXC_CHLINEFORMAT_DOT:
1044 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dots = 1;
1045 break;
1046 case EXC_CHLINEFORMAT_DASHDOT:
1047 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = aApiDash.Dots = 1;
1048 break;
1049 case EXC_CHLINEFORMAT_DASHDOTDOT:
1050 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1; aApiDash.Dots = 2;
1051 break;
1054 // line color
1055 sal_Int32 nApiColor = ScfApiHelper::ConvertToApiColor( rLineFmt.maColor );
1057 // try to insert the dash style and receive its name
1058 Any aDashNameAny;
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;
1078 Color aColor;
1079 sal_Int16 nTransparency = 0;
1081 // fill color
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() )
1106 case XFILL_SOLID:
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 );
1119 break;
1120 case XFILL_GRADIENT:
1121 if( const XFillGradientItem* pGradItem = static_cast< const XFillGradientItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLGRADIENT, FALSE ) ) )
1123 Any aGradientAny;
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 );
1137 break;
1138 case XFILL_BITMAP:
1139 if( const XFillBitmapItem* pBmpItem = static_cast< const XFillBitmapItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLBITMAP, FALSE ) ) )
1141 Any aBitmapAny;
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 );
1156 break;
1157 default:
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;
1170 // symbol style
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
1187 // symbol size
1188 sal_Int32 nApiSize = XclTools::GetHmmFromTwips( rMarkerFmt.mnMarkerSize );
1189 aApiSymbol.Size = cssa::Size( nApiSize, nApiSize );
1191 // symbol colors
1192 aApiSymbol.FillColor = ScfApiHelper::ConvertToApiColor( rMarkerFmt.maFillColor );
1193 aApiSymbol.BorderColor = ::get_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOLINE ) ?
1194 aApiSymbol.FillColor : ScfApiHelper::ConvertToApiColor( rMarkerFmt.maLineColor );
1196 // set the property
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;
1219 // legend position
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;
1228 // legend expansion
1229 cssc::LegendExpansion eApiExpand = ::get_flagvalue(
1230 rLegend.mnFlags, EXC_CHLEGEND_STACKED, cssc::LegendExpansion_HIGH, cssc::LegendExpansion_WIDE );
1231 // legend position
1232 Any aRelPosAny;
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;
1238 if( fRatio > 1.5 )
1239 eApiExpand = cssc::LegendExpansion_WIDE;
1240 else if( fRatio < 0.75 )
1241 eApiExpand = cssc::LegendExpansion_HIGH;
1242 else
1243 eApiExpand = cssc::LegendExpansion_BALANCED;
1244 // set position
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 )
1262 switch( 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 )
1274 switch( 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 )
1285 switch( 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 )
1296 switch( 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" );
1320 return mxChartDoc;
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
1349 mxChartDoc.clear();
1352 // ============================================================================