update ooo310-m15
[ooovba.git] / sc / source / filter / excel / xlchart.cxx
blob76253fcb1f2ffed082fed76e056a90166a27b45e
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 // Frame formatting ===========================================================
99 XclChFramePos::XclChFramePos() :
100 mnObjType( EXC_CHFRAMEPOS_ANY ),
101 mnSizeMode( EXC_CHFRAMEPOS_AUTOSIZE )
105 // ----------------------------------------------------------------------------
107 XclChLineFormat::XclChLineFormat() :
108 maColor( COL_BLACK ),
109 mnPattern( EXC_CHLINEFORMAT_SOLID ),
110 mnWeight( EXC_CHLINEFORMAT_SINGLE ),
111 mnFlags( EXC_CHLINEFORMAT_AUTO )
115 // ----------------------------------------------------------------------------
117 XclChAreaFormat::XclChAreaFormat() :
118 maPattColor( COL_WHITE ),
119 maBackColor( COL_BLACK ),
120 mnPattern( EXC_PATT_SOLID ),
121 mnFlags( EXC_CHAREAFORMAT_AUTO )
125 // ----------------------------------------------------------------------------
127 XclChEscherFormat::XclChEscherFormat()
131 XclChEscherFormat::~XclChEscherFormat()
135 // ----------------------------------------------------------------------------
137 XclChPicFormat::XclChPicFormat() :
138 mnBmpMode( EXC_CHPICFORMAT_NONE ),
139 mnFormat( EXC_CHPICFORMAT_DEFAULT ),
140 mnFlags( EXC_CHPICFORMAT_DEFAULTFLAGS ),
141 mfScale( 0.5 )
145 // ----------------------------------------------------------------------------
147 XclChFrame::XclChFrame() :
148 mnFormat( EXC_CHFRAME_STANDARD ),
149 mnFlags( EXC_CHFRAME_AUTOSIZE | EXC_CHFRAME_AUTOPOS )
153 // Source links ===============================================================
155 XclChSourceLink::XclChSourceLink() :
156 mnDestType( EXC_CHSRCLINK_TITLE ),
157 mnLinkType( EXC_CHSRCLINK_DEFAULT ),
158 mnFlags( 0 ),
159 mnNumFmtIdx( 0 )
163 // Text =======================================================================
165 XclChObjectLink::XclChObjectLink() :
166 mnTarget( EXC_CHOBJLINK_NONE )
170 // ----------------------------------------------------------------------------
172 XclChText::XclChText() :
173 maTextColor( COL_BLACK ),
174 mnHAlign( EXC_CHTEXT_ALIGN_CENTER ),
175 mnVAlign( EXC_CHTEXT_ALIGN_CENTER ),
176 mnBackMode( EXC_CHTEXT_TRANSPARENT ),
177 mnFlags( EXC_CHTEXT_AUTOCOLOR | EXC_CHTEXT_AUTOFILL ),
178 mnPlacement( EXC_CHTEXT_POS_DEFAULT ),
179 mnRotation( EXC_ROT_NONE )
183 // Data series ================================================================
185 XclChMarkerFormat::XclChMarkerFormat() :
186 maLineColor( COL_BLACK ),
187 maFillColor( COL_WHITE ),
188 mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE ),
189 mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL ),
190 mnFlags( EXC_CHMARKERFORMAT_AUTO )
194 // ----------------------------------------------------------------------------
196 XclCh3dDataFormat::XclCh3dDataFormat() :
197 mnBase( EXC_CH3DDATAFORMAT_RECT ),
198 mnTop( EXC_CH3DDATAFORMAT_STRAIGHT )
202 // ----------------------------------------------------------------------------
204 XclChDataFormat::XclChDataFormat() :
205 mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT ),
206 mnFlags( 0 )
210 // ----------------------------------------------------------------------------
212 XclChSerTrendLine::XclChSerTrendLine() :
213 mfForecastFor( 0.0 ),
214 mfForecastBack( 0.0 ),
215 mnLineType( EXC_CHSERTREND_POLYNOMIAL ),
216 mnOrder( 1 ),
217 mnShowEquation( 0 ),
218 mnShowRSquared( 0 )
220 /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
221 there is no interception point. Cannot use ::rtl::math::setNan() here
222 cause it misses the sign bit. */
223 sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &mfIntercept );
224 pDouble->w32_parts.msw = pDouble->w32_parts.lsw = 0xFFFFFFFF;
227 // ----------------------------------------------------------------------------
229 XclChSerErrorBar::XclChSerErrorBar() :
230 mfValue( 0.0 ),
231 mnValueCount( 1 ),
232 mnBarType( EXC_CHSERERR_NONE ),
233 mnSourceType( EXC_CHSERERR_FIXED ),
234 mnLineEnd( EXC_CHSERERR_END_TSHAPE )
238 // ----------------------------------------------------------------------------
240 XclChSeries::XclChSeries() :
241 mnCategType( EXC_CHSERIES_NUMERIC ),
242 mnValueType( EXC_CHSERIES_NUMERIC ),
243 mnBubbleType( EXC_CHSERIES_NUMERIC ),
244 mnCategCount( 0 ),
245 mnValueCount( 0 ),
246 mnBubbleCount( 0 )
250 // Chart type groups ==========================================================
252 XclChType::XclChType() :
253 mnOverlap( 0 ),
254 mnGap( 150 ),
255 mnRotation( 0 ),
256 mnPieHole( 0 ),
257 mnBubbleSize( 100 ),
258 mnBubbleType( EXC_CHSCATTER_AREA ),
259 mnFlags( 0 )
263 // ----------------------------------------------------------------------------
265 XclChChart3d::XclChChart3d() :
266 mnRotation( 20 ),
267 mnElevation( 15 ),
268 mnEyeDist( 30 ),
269 mnRelHeight( 100 ),
270 mnRelDepth( 100 ),
271 mnDepthGap( 150 ),
272 mnFlags( EXC_CHCHART3D_AUTOHEIGHT )
276 // ----------------------------------------------------------------------------
278 XclChLegend::XclChLegend() :
279 mnDockMode( EXC_CHLEGEND_RIGHT ),
280 mnSpacing( EXC_CHLEGEND_MEDIUM ),
281 mnFlags( EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOSERIES |
282 EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY | EXC_CHLEGEND_STACKED )
286 // ----------------------------------------------------------------------------
288 XclChTypeGroup::XclChTypeGroup() :
289 mnFlags( 0 ),
290 mnGroupIdx( EXC_CHSERGROUP_NONE )
294 // ----------------------------------------------------------------------------
296 XclChProperties::XclChProperties() :
297 mnFlags( EXC_CHPROPS_MANSERIES ),
298 mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP )
302 // Axes =======================================================================
304 XclChLabelRange::XclChLabelRange() :
305 mnCross( 1 ),
306 mnLabelFreq( 1 ),
307 mnTickFreq( 1 ),
308 mnFlags( 0 )
312 // ----------------------------------------------------------------------------
314 XclChValueRange::XclChValueRange() :
315 mfMin( 0.0 ),
316 mfMax( 0.0 ),
317 mfMajorStep( 0.0 ),
318 mfMinorStep( 0.0 ),
319 mfCross( 0.0 ),
320 mnFlags( EXC_CHVALUERANGE_AUTOMIN | EXC_CHVALUERANGE_AUTOMAX |
321 EXC_CHVALUERANGE_AUTOMAJOR | EXC_CHVALUERANGE_AUTOMINOR | EXC_CHVALUERANGE_AUTOCROSS | EXC_CHVALUERANGE_BIT8 )
325 // ----------------------------------------------------------------------------
327 XclChTick::XclChTick() :
328 maTextColor( COL_BLACK ),
329 mnMajor( EXC_CHTICK_INSIDE | EXC_CHTICK_OUTSIDE ),
330 mnMinor( 0 ),
331 mnLabelPos( EXC_CHTICK_NEXT ),
332 mnBackMode( EXC_CHTICK_TRANSPARENT ),
333 mnFlags( EXC_CHTICK_AUTOCOLOR | EXC_CHTICK_AUTOROT ),
334 mnRotation( EXC_ROT_NONE )
338 // ----------------------------------------------------------------------------
340 XclChAxis::XclChAxis() :
341 mnType( EXC_CHAXIS_NONE )
345 sal_Int32 XclChAxis::GetApiAxisDimension() const
347 sal_Int32 nApiAxisDim = EXC_CHART_AXIS_NONE;
348 switch( mnType )
350 case EXC_CHAXIS_X: nApiAxisDim = EXC_CHART_AXIS_X; break;
351 case EXC_CHAXIS_Y: nApiAxisDim = EXC_CHART_AXIS_Y; break;
352 case EXC_CHAXIS_Z: nApiAxisDim = EXC_CHART_AXIS_Z; break;
354 return nApiAxisDim;
357 // ----------------------------------------------------------------------------
359 XclChAxesSet::XclChAxesSet() :
360 mnAxesSetId( EXC_CHAXESSET_PRIMARY )
364 sal_Int32 XclChAxesSet::GetApiAxesSetIndex() const
366 sal_Int32 nApiAxesSetIdx = EXC_CHART_AXESSET_NONE;
367 switch( mnAxesSetId )
369 case EXC_CHAXESSET_PRIMARY: nApiAxesSetIdx = EXC_CHART_AXESSET_PRIMARY; break;
370 case EXC_CHAXESSET_SECONDARY: nApiAxesSetIdx = EXC_CHART_AXESSET_SECONDARY; break;
372 return nApiAxesSetIdx;
375 // Static helper functions ====================================================
377 sal_uInt16 XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx )
379 static const sal_uInt16 spnLineColors[] =
381 32, 33, 34, 35, 36, 37, 38, 39,
382 40, 41, 42, 43, 44, 45, 46, 47,
383 48, 49, 50, 51, 52, 53, 54, 55,
384 56, 57, 58, 59, 60, 61, 62, 8,
385 9, 10, 11, 12, 13, 14, 15, 16,
386 17, 18, 19, 20, 21, 22, 23, 24,
387 25, 26, 27, 28, 29, 30, 31, 63
389 return spnLineColors[ nFormatIdx % STATIC_TABLE_SIZE( spnLineColors ) ];
392 sal_uInt16 XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx )
394 static const sal_uInt16 spnFillColors[] =
396 24, 25, 26, 27, 28, 29, 30, 31,
397 32, 33, 34, 35, 36, 37, 38, 39,
398 40, 41, 42, 43, 44, 45, 46, 47,
399 48, 49, 50, 51, 52, 53, 54, 55,
400 56, 57, 58, 59, 60, 61, 62, 63,
401 8, 9, 10, 11, 12, 13, 14, 15,
402 16, 17, 18, 19, 20, 21, 22, 23
404 return spnFillColors[ nFormatIdx % STATIC_TABLE_SIZE( spnFillColors ) ];
407 sal_uInt8 XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx )
409 static const sal_uInt8 spnTrans[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
410 return spnTrans[ (nFormatIdx / 56) % STATIC_TABLE_SIZE( spnTrans ) ];
413 sal_uInt16 XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx )
415 static const sal_uInt16 spnSymbols[] = {
416 EXC_CHMARKERFORMAT_DIAMOND, EXC_CHMARKERFORMAT_SQUARE, EXC_CHMARKERFORMAT_TRIANGLE,
417 EXC_CHMARKERFORMAT_CROSS, EXC_CHMARKERFORMAT_STAR, EXC_CHMARKERFORMAT_CIRCLE,
418 EXC_CHMARKERFORMAT_PLUS, EXC_CHMARKERFORMAT_DOWJ, EXC_CHMARKERFORMAT_STDDEV };
419 return spnSymbols[ nFormatIdx % STATIC_TABLE_SIZE( spnSymbols ) ];
422 bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType )
424 static const bool spbFilled[] = {
425 false, true, true, true, false, false, false, false, true, false };
426 return (nMarkerType < STATIC_TABLE_SIZE( spbFilled )) && spbFilled[ nMarkerType ];
429 OUString XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType )
431 switch( nBarType )
433 case EXC_CHSERERR_XPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSX;
434 case EXC_CHSERERR_XMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGX;
435 case EXC_CHSERERR_YPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSY;
436 case EXC_CHSERERR_YMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGY;
437 default: DBG_ERRORFILE( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
439 return OUString();
442 // Chart formatting info provider =============================================
444 namespace {
446 static const XclChFormatInfo spFmtInfos[] =
448 // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
449 { EXC_CHOBJTYPE_BACKGROUND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
450 { EXC_CHOBJTYPE_PLOTFRAME, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
451 { EXC_CHOBJTYPE_WALL3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, false, true },
452 { EXC_CHOBJTYPE_FLOOR3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, 23, EXC_CHFRAMETYPE_AUTO, true, false, true },
453 { EXC_CHOBJTYPE_TEXT, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, true },
454 { EXC_CHOBJTYPE_LEGEND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, true, true },
455 { EXC_CHOBJTYPE_LINEARSERIES, EXC_CHPROPMODE_LINEARSERIES, 0xFFFF, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
456 { EXC_CHOBJTYPE_FILLEDSERIES, EXC_CHPROPMODE_FILLEDSERIES, EXC_COLOR_CHBORDERAUTO, EXC_CHLINEFORMAT_SINGLE, 0xFFFF, EXC_CHFRAMETYPE_AUTO, false, false, true },
457 { EXC_CHOBJTYPE_AXISLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
458 { EXC_CHOBJTYPE_GRIDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, false },
459 { EXC_CHOBJTYPE_TRENDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_DOUBLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
460 { EXC_CHOBJTYPE_ERRORBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
461 { EXC_CHOBJTYPE_CONNECTLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
462 { EXC_CHOBJTYPE_HILOLINE, EXC_CHPROPMODE_LINEARSERIES, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
463 { EXC_CHOBJTYPE_WHITEDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, true },
464 { EXC_CHOBJTYPE_BLACKDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWTEXT, EXC_CHFRAMETYPE_INVISIBLE, false, false, true }
469 // ----------------------------------------------------------------------------
471 XclChFormatInfoProvider::XclChFormatInfoProvider()
473 const XclChFormatInfo* pEnd = STATIC_TABLE_END( spFmtInfos );
474 for( const XclChFormatInfo* pIt = spFmtInfos; pIt != pEnd; ++pIt )
475 maInfoMap[ pIt->meObjType ] = pIt;
478 const XclChFormatInfo& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType ) const
480 XclFmtInfoMap::const_iterator aIt = maInfoMap.find( eObjType );
481 DBG_ASSERT( aIt != maInfoMap.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
482 return (aIt == maInfoMap.end()) ? *spFmtInfos : *aIt->second;
485 // Chart type info provider ===================================================
487 namespace {
489 // chart type service names
490 const sal_Char SERVICE_CHART2_AREA[] = "com.sun.star.chart2.AreaChartType";
491 const sal_Char SERVICE_CHART2_CANDLE[] = "com.sun.star.chart2.CandleStickChartType";
492 const sal_Char SERVICE_CHART2_COLUMN[] = "com.sun.star.chart2.ColumnChartType";
493 const sal_Char SERVICE_CHART2_LINE[] = "com.sun.star.chart2.LineChartType";
494 const sal_Char SERVICE_CHART2_NET[] = "com.sun.star.chart2.NetChartType";
495 const sal_Char SERVICE_CHART2_PIE[] = "com.sun.star.chart2.PieChartType";
496 const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType";
497 const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
499 namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
501 static const XclChTypeInfo spTypeInfos[] =
503 // chart type chart type category record id service varied point color def label combi comb2d 3d polar area2d area3d 1stvis xcateg swap stack revers betw
504 { 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 },
505 { 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 },
506 { 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, true },
507 { 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 },
508 { 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, true },
509 { 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 },
510 { EXC_CHTYPEID_RADARAREA, EXC_CHTYPECATEG_RADAR, EXC_ID_CHRADARAREA, SERVICE_CHART2_NET, EXC_CHVARPOINT_NONE, csscd::TOP, false, false, true, true, true, false, true, false, false, false, false },
511 { 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 },
512 { 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 },
513 { 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 },
514 { 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 },
515 { EXC_CHTYPEID_BUBBLES, EXC_CHTYPECATEG_SCATTER, EXC_ID_CHSCATTER, SERVICE_CHART2_SCATTER, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, false, false, false, true, true, false, false, false, false, false, false },
516 { 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 },
517 { 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 }
520 } // namespace
522 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo ) :
523 XclChTypeInfo( rTypeInfo ),
524 mb3dChart( false ),
525 mbSpline( false )
529 void XclChExtTypeInfo::Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline )
531 static_cast< XclChTypeInfo& >( *this ) = rTypeInfo;
532 mb3dChart = mbSupports3d && b3dChart;
533 mbSpline = bSpline;
536 // ----------------------------------------------------------------------------
538 XclChTypeInfoProvider::XclChTypeInfoProvider()
540 const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos );
541 for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
542 maInfoMap[ pIt->meTypeId ] = pIt;
545 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId ) const
547 XclChTypeInfoMap::const_iterator aIt = maInfoMap.find( eTypeId );
548 DBG_ASSERT( aIt != maInfoMap.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
549 return (aIt == maInfoMap.end()) ? *maInfoMap.rbegin()->second : *aIt->second;
552 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId ) const
554 const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos );
555 for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
556 if( pIt->mnRecId == nRecId )
557 return *pIt;
558 DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
559 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
562 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString& rServiceName ) const
564 const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos );
565 for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
566 if( rServiceName.equalsAscii( pIt->mpcServiceName ) )
567 return *pIt;
568 DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
569 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
572 // Property helpers ===========================================================
574 XclChObjectTable::XclChObjectTable( Reference< XMultiServiceFactory > xFactory,
575 const OUString& rServiceName, const OUString& rObjNameBase ) :
576 mxFactory( xFactory ),
577 maServiceName( rServiceName ),
578 maObjNameBase( rObjNameBase ),
579 mnIndex( 0 )
583 Any XclChObjectTable::GetObject( const OUString& rObjName )
585 // get object table
586 if( !mxContainer.is() )
587 mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
588 DBG_ASSERT( mxContainer.is(), "XclChObjectTable::GetObject - container not found" );
590 Any aObj;
591 if( mxContainer.is() )
593 // get object from container
596 aObj = mxContainer->getByName( rObjName );
598 catch( Exception& )
600 DBG_ERRORFILE( "XclChObjectTable::GetObject - object not found" );
603 return aObj;
606 OUString XclChObjectTable::InsertObject( const Any& rObj )
609 // create object table
610 if( !mxContainer.is() )
611 mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
612 DBG_ASSERT( mxContainer.is(), "XclChObjectTable::InsertObject - container not found" );
614 OUString aObjName;
615 if( mxContainer.is() )
617 // create new unused identifier
620 aObjName = maObjNameBase + OUString::valueOf( ++mnIndex );
622 while( mxContainer->hasByName( aObjName ) );
624 // insert object
627 mxContainer->insertByName( aObjName, rObj );
629 catch( Exception& )
631 DBG_ERRORFILE( "XclChObjectTable::InsertObject - cannot insert object" );
632 aObjName = OUString();
635 return aObjName;
638 // Property names -------------------------------------------------------------
640 namespace {
642 /** Property names for line style in common objects. */
643 const sal_Char* const sppcLineNamesCommon[] =
644 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", 0 };
645 /** Property names for line style in linear series objects. */
646 const sal_Char* const sppcLineNamesLinear[] =
647 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", 0 };
648 /** Property names for line style in filled series objects. */
649 const sal_Char* const sppcLineNamesFilled[] =
650 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", 0 };
652 /** Property names for solid area style in common objects. */
653 const sal_Char* const sppcAreaNamesCommon[] = { "FillStyle", "FillColor", "FillTransparence", 0 };
654 /** Property names for solid area style in filled series objects. */
655 const sal_Char* const sppcAreaNamesFilled[] = { "FillStyle", "Color", "Transparency", 0 };
656 /** Property names for gradient area style in common objects. */
657 const sal_Char* const sppcGradNamesCommon[] = { "FillStyle", "FillGradientName", 0 };
658 /** Property names for gradient area style in filled series objects. */
659 const sal_Char* const sppcGradNamesFilled[] = { "FillStyle", "GradientName", 0 };
660 /** Property names for hatch area style in common objects. */
661 const sal_Char* const sppcHatchNamesCommon[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", 0 };
662 /** Property names for hatch area style in filled series objects. */
663 const sal_Char* const sppcHatchNamesFilled[] = { "FillStyle", "HatchName", "Color", "FillBackground", 0 };
664 /** Property names for bitmap area style. */
665 const sal_Char* const sppcBitmapNames[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 };
667 /** Property names for text rotation properties. */
668 const sal_Char* const sppcRotationNames[] = { "TextRotation", "StackCharacters", 0 };
669 /** Property names for legend properties. */
670 const sal_Char* const sppcLegendNames[] =
671 { "Show", "AnchorPosition", "Expansion", "RelativePosition", 0 };
673 } // namespace
675 // ----------------------------------------------------------------------------
677 XclChPropSetHelper::XclChPropSetHelper() :
678 maLineHlpCommon( sppcLineNamesCommon ),
679 maLineHlpLinear( sppcLineNamesLinear ),
680 maLineHlpFilled( sppcLineNamesFilled ),
681 maAreaHlpCommon( sppcAreaNamesCommon ),
682 maAreaHlpFilled( sppcAreaNamesFilled ),
683 maGradHlpCommon( sppcGradNamesCommon ),
684 maGradHlpFilled( sppcGradNamesFilled ),
685 maHatchHlpCommon( sppcHatchNamesCommon ),
686 maHatchHlpFilled( sppcHatchNamesFilled ),
687 maBitmapHlp( sppcBitmapNames ),
688 maRotationHlp( sppcRotationNames ),
689 maLegendHlp( sppcLegendNames )
693 // read properties ------------------------------------------------------------
695 void XclChPropSetHelper::ReadLineProperties(
696 XclChLineFormat& rLineFmt, XclChObjectTable& rDashTable,
697 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
699 namespace cssd = ::com::sun::star::drawing;
701 // read properties from property set
702 cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
703 sal_Int32 nApiWidth = 0;
704 sal_Int16 nApiTrans = 0;
705 Any aDashNameAny;
707 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
708 rLineHlp.ReadFromPropertySet( rPropSet );
709 rLineHlp >> eApiStyle >> nApiWidth >> rLineFmt.maColor >> nApiTrans >> aDashNameAny;
711 // clear automatic flag
712 ::set_flag( rLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
714 // line width
715 if( nApiWidth <= 0 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
716 else if( nApiWidth <= 35 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE;
717 else if( nApiWidth <= 70 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE;
718 else rLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE;
720 // line style
721 switch( eApiStyle )
723 case cssd::LineStyle_NONE:
724 rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
725 break;
726 case cssd::LineStyle_SOLID:
728 if( nApiTrans < 13 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
729 else if( nApiTrans < 38 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS;
730 else if( nApiTrans < 63 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS;
731 else if( nApiTrans < 100 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS;
732 else rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
734 break;
735 case cssd::LineStyle_DASH:
737 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
738 OUString aDashName;
739 cssd::LineDash aApiDash;
740 if( (aDashNameAny >>= aDashName) && (rDashTable.GetObject( aDashName ) >>= aApiDash) )
742 // reorder dashes that are shorter than dots
743 if( (aApiDash.Dashes == 0) || (aApiDash.DashLen < aApiDash.DotLen) )
745 ::std::swap( aApiDash.Dashes, aApiDash.Dots );
746 ::std::swap( aApiDash.DashLen, aApiDash.DotLen );
748 // ignore dots that are nearly equal to dashes
749 if( aApiDash.DotLen * 3 > aApiDash.DashLen * 2 )
750 aApiDash.Dots = 0;
752 // convert line dash to predefined Excel dash types
753 if( (aApiDash.Dashes == 1) && (aApiDash.Dots >= 1) )
754 // one dash and one or more dots
755 rLineFmt.mnPattern = (aApiDash.Dots == 1) ?
756 EXC_CHLINEFORMAT_DASHDOT : EXC_CHLINEFORMAT_DASHDOTDOT;
757 else if( aApiDash.Dashes >= 1 )
758 // one or more dashes and no dots (also: dash-dash-dot)
759 rLineFmt.mnPattern = (aApiDash.DashLen < 250) ?
760 EXC_CHLINEFORMAT_DOT : EXC_CHLINEFORMAT_DASH;
763 break;
764 default:
765 DBG_ERRORFILE( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
766 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
770 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat& rAreaFmt,
771 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
773 namespace cssd = ::com::sun::star::drawing;
775 // read properties from property set
776 cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
777 sal_Int16 nTransparency = 0;
779 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
780 rAreaHlp.ReadFromPropertySet( rPropSet );
781 rAreaHlp >> eApiStyle >> rAreaFmt.maPattColor >> nTransparency;
783 // clear automatic flag
784 ::set_flag( rAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
786 // set fill style transparent or solid (set solid for anything but transparent)
787 rAreaFmt.mnPattern = (eApiStyle == cssd::FillStyle_NONE) ? EXC_PATT_NONE : EXC_PATT_SOLID;
789 // return true to indicate complex fill (gradient, bitmap, solid transparency)
790 return (eApiStyle != cssd::FillStyle_NONE) && ((eApiStyle != cssd::FillStyle_SOLID) || (nTransparency > 0));
793 void XclChPropSetHelper::ReadEscherProperties(
794 XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
795 XclChObjectTable& rGradientTable, XclChObjectTable& rHatchTable, XclChObjectTable& rBitmapTable,
796 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
798 namespace cssd = ::com::sun::star::drawing;
799 namespace cssa = ::com::sun::star::awt;
801 // read style and transparency properties from property set
802 cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
803 Color aColor;
804 sal_Int16 nTransparency = 0;
806 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
807 rAreaHlp.ReadFromPropertySet( rPropSet );
808 rAreaHlp >> eApiStyle >> aColor >> nTransparency;
810 switch( eApiStyle )
812 case cssd::FillStyle_SOLID:
814 DBG_ASSERT( nTransparency > 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
815 if( (0 < nTransparency) && (nTransparency <= 100) )
817 // convert to Escher properties
818 sal_uInt32 nEscherColor = 0x02000000;
819 ::insert_value( nEscherColor, aColor.GetBlue(), 16, 8 );
820 ::insert_value( nEscherColor, aColor.GetGreen(), 8, 8 );
821 ::insert_value( nEscherColor, aColor.GetRed(), 0, 8 );
822 sal_uInt32 nEscherOpacity = static_cast< sal_uInt32 >( (100 - nTransparency) * 655.36 );
823 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
824 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
825 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, nEscherColor );
826 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillOpacity, nEscherOpacity );
827 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x02FFFFFF );
828 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackOpacity, 0x00010000 );
829 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fNoFillHitTest, 0x001F001C );
832 break;
833 case cssd::FillStyle_GRADIENT:
835 // extract gradient from global gradient table
836 OUString aGradientName;
837 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
838 rGradHlp.ReadFromPropertySet( rPropSet );
839 rGradHlp >> eApiStyle >> aGradientName;
840 cssa::Gradient aGradient;
841 if( rGradientTable.GetObject( aGradientName ) >>= aGradient )
843 // convert to Escher properties
844 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
845 rEscherFmt.mxEscherSet->CreateGradientProperties( aGradient );
848 break;
849 case cssd::FillStyle_HATCH:
851 // extract hatch from global hatch table
852 OUString aHatchName;
853 bool bFillBackground;
854 ScfPropSetHelper& rHatchHlp = GetHatchHelper( ePropMode );
855 rHatchHlp.ReadFromPropertySet( rPropSet );
856 rHatchHlp >> eApiStyle >> aHatchName >> aColor >> bFillBackground;
857 cssd::Hatch aHatch;
858 if( rHatchTable.GetObject( aHatchName ) >>= aHatch )
860 // convert to Escher properties
861 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
862 rEscherFmt.mxEscherSet->CreateEmbeddedHatchProperties( aHatch, aColor, bFillBackground );
863 rPicFmt.mnBmpMode = EXC_CHPICFORMAT_STACK;
866 break;
867 case cssd::FillStyle_BITMAP:
869 // extract bitmap URL from global bitmap table
870 OUString aBitmapName;
871 cssd::BitmapMode eApiBmpMode;
872 maBitmapHlp.ReadFromPropertySet( rPropSet );
873 maBitmapHlp >> eApiStyle >> aBitmapName >> eApiBmpMode;
874 OUString aBitmapUrl;
875 if( rBitmapTable.GetObject( aBitmapName ) >>= aBitmapUrl )
877 // convert to Escher properties
878 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
879 rEscherFmt.mxEscherSet->CreateEmbeddedBitmapProperties( aBitmapUrl, eApiBmpMode );
880 rPicFmt.mnBmpMode = (eApiBmpMode == cssd::BitmapMode_REPEAT) ?
881 EXC_CHPICFORMAT_STACK : EXC_CHPICFORMAT_STRETCH;
884 break;
885 default:
886 DBG_ERRORFILE( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
890 void XclChPropSetHelper::ReadMarkerProperties(
891 XclChMarkerFormat& rMarkerFmt, const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
893 namespace cssc = ::com::sun::star::chart2;
894 namespace cssa = ::com::sun::star::awt;
895 cssc::Symbol aApiSymbol;
896 if( rPropSet.GetProperty( aApiSymbol, EXC_CHPROP_SYMBOL ) )
898 // clear automatic flag
899 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
901 // symbol style
902 switch( aApiSymbol.Style )
904 case cssc::SymbolStyle_NONE:
905 rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
906 break;
907 case cssc::SymbolStyle_STANDARD:
908 switch( aApiSymbol.StandardSymbol )
910 case 0: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_SQUARE; break; // square
911 case 1: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // diamond
912 case 2: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // arrow down
913 case 3: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_TRIANGLE; break; // arrow up
914 case 4: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CIRCLE; break; // arrow right
915 case 5: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // arrow left
916 case 6: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // bow tie
917 case 7: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // sand glass
918 default: rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
920 break;
921 default:
922 rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
924 bool bHasFillColor = XclChartHelper::HasMarkerFillColor( rMarkerFmt.mnMarkerType );
925 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOFILL, !bHasFillColor );
927 // symbol size
928 sal_Int32 nApiSize = (aApiSymbol.Size.Width + aApiSymbol.Size.Height + 1) / 2;
929 rMarkerFmt.mnMarkerSize = XclTools::GetTwipsFromHmm( nApiSize );
931 // symbol colors
932 rMarkerFmt.maLineColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.BorderColor );
933 rMarkerFmt.maFillColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.FillColor );
937 sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPropSet )
939 // chart2 handles rotation as double in the range [0,360)
940 double fAngle(0);
941 bool bStacked;
942 maRotationHlp.ReadFromPropertySet( rPropSet );
943 maRotationHlp >> fAngle >> bStacked;
944 return bStacked ? EXC_ROT_STACKED :
945 XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) );
948 void XclChPropSetHelper::ReadLegendProperties( XclChLegend& rLegend, const ScfPropertySet& rPropSet )
950 namespace cssc = ::com::sun::star::chart2;
951 namespace cssd = ::com::sun::star::drawing;
953 // read the properties
954 bool bShow;
955 cssc::LegendPosition eApiPos;
956 cssc::LegendExpansion eApiExpand;
957 Any aRelPosAny;
958 maLegendHlp.ReadFromPropertySet( rPropSet );
959 maLegendHlp >> bShow >> eApiPos >> eApiExpand >> aRelPosAny;
960 DBG_ASSERT( bShow, "XclChPropSetHelper::ReadLegendProperties - legend must be visible" );
962 // legend position
963 switch( eApiPos )
965 case cssc::LegendPosition_LINE_START: rLegend.mnDockMode = EXC_CHLEGEND_LEFT; break;
966 case cssc::LegendPosition_LINE_END: rLegend.mnDockMode = EXC_CHLEGEND_RIGHT; break;
967 case cssc::LegendPosition_PAGE_START: rLegend.mnDockMode = EXC_CHLEGEND_TOP; break;
968 case cssc::LegendPosition_PAGE_END: rLegend.mnDockMode = EXC_CHLEGEND_BOTTOM; break;
969 default: rLegend.mnDockMode = EXC_CHLEGEND_NOTDOCKED;
971 // legend expansion
972 ::set_flag( rLegend.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand != cssc::LegendExpansion_WIDE );
973 // legend position
974 if( rLegend.mnDockMode == EXC_CHLEGEND_NOTDOCKED )
976 cssc::RelativePosition aRelPos;
977 if( aRelPosAny >>= aRelPos )
979 rLegend.maRect.mnX = limit_cast< sal_Int32 >( aRelPos.Primary * 4000.0, 0, 4000 );
980 rLegend.maRect.mnY = limit_cast< sal_Int32 >( aRelPos.Secondary * 4000.0, 0, 4000 );
982 else
983 rLegend.mnDockMode = EXC_CHLEGEND_LEFT;
985 ::set_flag( rLegend.mnFlags, EXC_CHLEGEND_DOCKED, rLegend.mnDockMode != EXC_CHLEGEND_NOTDOCKED );
988 // write properties -----------------------------------------------------------
990 void XclChPropSetHelper::WriteLineProperties(
991 ScfPropertySet& rPropSet, XclChObjectTable& rDashTable,
992 const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode )
994 namespace cssd = ::com::sun::star::drawing;
996 // line width
997 sal_Int32 nApiWidth = 0; // 0 is the width of a hair line
998 switch( rLineFmt.mnWeight )
1000 case EXC_CHLINEFORMAT_SINGLE: nApiWidth = 35; break;
1001 case EXC_CHLINEFORMAT_DOUBLE: nApiWidth = 70; break;
1002 case EXC_CHLINEFORMAT_TRIPLE: nApiWidth = 105; break;
1005 // line style
1006 cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
1007 sal_Int16 nApiTrans = 0;
1008 sal_Int32 nDotLen = ::std::min< sal_Int32 >( rLineFmt.mnWeight + 105, 210 );
1009 cssd::LineDash aApiDash( cssd::DashStyle_RECT, 0, nDotLen, 0, 4 * nDotLen, nDotLen );
1011 switch( rLineFmt.mnPattern )
1013 case EXC_CHLINEFORMAT_SOLID:
1014 eApiStyle = cssd::LineStyle_SOLID;
1015 break;
1016 case EXC_CHLINEFORMAT_DARKTRANS:
1017 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 25;
1018 break;
1019 case EXC_CHLINEFORMAT_MEDTRANS:
1020 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 50;
1021 break;
1022 case EXC_CHLINEFORMAT_LIGHTTRANS:
1023 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 75;
1024 break;
1025 case EXC_CHLINEFORMAT_DASH:
1026 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1;
1027 break;
1028 case EXC_CHLINEFORMAT_DOT:
1029 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dots = 1;
1030 break;
1031 case EXC_CHLINEFORMAT_DASHDOT:
1032 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = aApiDash.Dots = 1;
1033 break;
1034 case EXC_CHLINEFORMAT_DASHDOTDOT:
1035 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1; aApiDash.Dots = 2;
1036 break;
1039 // line color
1040 sal_Int32 nApiColor = ScfApiHelper::ConvertToApiColor( rLineFmt.maColor );
1042 // try to insert the dash style and receive its name
1043 Any aDashNameAny;
1044 if( eApiStyle == cssd::LineStyle_DASH )
1046 OUString aDashName = rDashTable.InsertObject( ::com::sun::star::uno::makeAny( aApiDash ) );
1047 if( aDashName.getLength() )
1048 aDashNameAny <<= aDashName;
1051 // write the properties
1052 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
1053 rLineHlp.InitializeWrite();
1054 rLineHlp << eApiStyle << nApiWidth << nApiColor << nApiTrans << aDashNameAny;
1055 rLineHlp.WriteToPropertySet( rPropSet );
1058 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet& rPropSet,
1059 const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode )
1061 namespace cssd = ::com::sun::star::drawing;
1062 cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
1063 Color aColor;
1064 sal_Int16 nTransparency = 0;
1066 // fill color
1067 if( rAreaFmt.mnPattern != EXC_PATT_NONE )
1069 eFillStyle = cssd::FillStyle_SOLID;
1070 aColor = XclTools::GetPatternColor( rAreaFmt.maPattColor, rAreaFmt.maBackColor, rAreaFmt.mnPattern );
1073 // write the properties
1074 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
1075 rAreaHlp.InitializeWrite();
1076 rAreaHlp << eFillStyle << aColor << nTransparency;
1077 rAreaHlp.WriteToPropertySet( rPropSet );
1080 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet,
1081 XclChObjectTable& rGradientTable, XclChObjectTable& /*rHatchTable*/, XclChObjectTable& rBitmapTable,
1082 const XclChEscherFormat& rEscherFmt, const XclChPicFormat& rPicFmt,
1083 XclChPropertyMode ePropMode )
1085 if( rEscherFmt.mxItemSet.is() )
1087 if( const XFillStyleItem* pStyleItem = static_cast< const XFillStyleItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLSTYLE, FALSE ) ) )
1089 switch( pStyleItem->GetValue() )
1091 case XFILL_SOLID:
1092 // #i84812# Excel 2007 writes Escher properties for solid fill
1093 if( const XFillColorItem* pColorItem = static_cast< const XFillColorItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLCOLOR, FALSE ) ) )
1095 namespace cssd = ::com::sun::star::drawing;
1096 // get solid transparence too
1097 const XFillTransparenceItem* pTranspItem = static_cast< const XFillTransparenceItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLTRANSPARENCE, FALSE ) );
1098 sal_uInt16 nTransp = pTranspItem ? pTranspItem->GetValue() : 0;
1099 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
1100 rAreaHlp.InitializeWrite();
1101 rAreaHlp << cssd::FillStyle_SOLID << pColorItem->GetColorValue() << static_cast< sal_Int16 >( nTransp );
1102 rAreaHlp.WriteToPropertySet( rPropSet );
1104 break;
1105 case XFILL_GRADIENT:
1106 if( const XFillGradientItem* pGradItem = static_cast< const XFillGradientItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLGRADIENT, FALSE ) ) )
1108 Any aGradientAny;
1109 if( pGradItem->QueryValue( aGradientAny, MID_FILLGRADIENT ) )
1111 OUString aGradName = rGradientTable.InsertObject( aGradientAny );
1112 if( aGradName.getLength() )
1114 namespace cssd = ::com::sun::star::drawing;
1115 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
1116 rGradHlp.InitializeWrite();
1117 rGradHlp << cssd::FillStyle_GRADIENT << aGradName;
1118 rGradHlp.WriteToPropertySet( rPropSet );
1122 break;
1123 case XFILL_BITMAP:
1124 if( const XFillBitmapItem* pBmpItem = static_cast< const XFillBitmapItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLBITMAP, FALSE ) ) )
1126 Any aBitmapAny;
1127 if( pBmpItem->QueryValue( aBitmapAny, MID_GRAFURL ) )
1129 OUString aBmpName = rBitmapTable.InsertObject( aBitmapAny );
1130 if( aBmpName.getLength() )
1132 namespace cssd = ::com::sun::star::drawing;
1133 cssd::BitmapMode eApiBmpMode = (rPicFmt.mnBmpMode == EXC_CHPICFORMAT_STRETCH) ?
1134 cssd::BitmapMode_STRETCH : cssd::BitmapMode_REPEAT;
1135 maBitmapHlp.InitializeWrite();
1136 maBitmapHlp << cssd::FillStyle_BITMAP << aBmpName << eApiBmpMode;
1137 maBitmapHlp.WriteToPropertySet( rPropSet );
1141 break;
1142 default:
1143 DBG_ERRORFILE( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1149 void XclChPropSetHelper::WriteMarkerProperties(
1150 ScfPropertySet& rPropSet, const XclChMarkerFormat& rMarkerFmt )
1152 namespace cssc = ::com::sun::star::chart2;
1153 namespace cssa = ::com::sun::star::awt;
1155 // symbol style
1156 cssc::Symbol aApiSymbol;
1157 aApiSymbol.Style = cssc::SymbolStyle_STANDARD;
1158 switch( rMarkerFmt.mnMarkerType )
1160 case EXC_CHMARKERFORMAT_NOSYMBOL: aApiSymbol.Style = cssc::SymbolStyle_NONE; break;
1161 case EXC_CHMARKERFORMAT_SQUARE: aApiSymbol.StandardSymbol = 0; break; // square
1162 case EXC_CHMARKERFORMAT_DIAMOND: aApiSymbol.StandardSymbol = 1; break; // diamond
1163 case EXC_CHMARKERFORMAT_TRIANGLE: aApiSymbol.StandardSymbol = 3; break; // arrow up
1164 case EXC_CHMARKERFORMAT_CROSS: aApiSymbol.StandardSymbol = 6; break; // bow tie
1165 case EXC_CHMARKERFORMAT_STAR: aApiSymbol.StandardSymbol = 7; break; // sand glass
1166 case EXC_CHMARKERFORMAT_DOWJ: aApiSymbol.StandardSymbol = 4; break; // arrow right
1167 case EXC_CHMARKERFORMAT_STDDEV: aApiSymbol.StandardSymbol = 2; break; // arrow down
1168 case EXC_CHMARKERFORMAT_CIRCLE: aApiSymbol.StandardSymbol = 4; break; // arrow right
1169 case EXC_CHMARKERFORMAT_PLUS: aApiSymbol.StandardSymbol = 5; break; // arrow left
1172 // symbol size
1173 sal_Int32 nApiSize = XclTools::GetHmmFromTwips( rMarkerFmt.mnMarkerSize );
1174 aApiSymbol.Size = cssa::Size( nApiSize, nApiSize );
1176 // symbol colors
1177 aApiSymbol.FillColor = ScfApiHelper::ConvertToApiColor( rMarkerFmt.maFillColor );
1178 aApiSymbol.BorderColor = ::get_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOLINE ) ?
1179 aApiSymbol.FillColor : ScfApiHelper::ConvertToApiColor( rMarkerFmt.maLineColor );
1181 // set the property
1182 rPropSet.SetProperty( EXC_CHPROP_SYMBOL, aApiSymbol );
1185 void XclChPropSetHelper::WriteRotationProperties(
1186 ScfPropertySet& rPropSet, sal_uInt16 nRotation )
1188 if( nRotation != EXC_CHART_AUTOROTATION )
1190 // chart2 handles rotation as double in the range [0,360)
1191 double fAngle = XclTools::GetScRotation( nRotation, 0 ) / 100.0;
1192 bool bStacked = nRotation == EXC_ROT_STACKED;
1193 maRotationHlp.InitializeWrite();
1194 maRotationHlp << fAngle << bStacked;
1195 maRotationHlp.WriteToPropertySet( rPropSet );
1199 void XclChPropSetHelper::WriteLegendProperties(
1200 ScfPropertySet& rPropSet, const XclChLegend& rLegend )
1202 namespace cssc = ::com::sun::star::chart2;
1203 namespace cssd = ::com::sun::star::drawing;
1205 // legend position
1206 cssc::LegendPosition eApiPos = cssc::LegendPosition_CUSTOM;
1207 switch( rLegend.mnDockMode )
1209 case EXC_CHLEGEND_LEFT: eApiPos = cssc::LegendPosition_LINE_START; break;
1210 case EXC_CHLEGEND_RIGHT: eApiPos = cssc::LegendPosition_LINE_END; break;
1211 case EXC_CHLEGEND_TOP: eApiPos = cssc::LegendPosition_PAGE_START; break;
1212 case EXC_CHLEGEND_BOTTOM: eApiPos = cssc::LegendPosition_PAGE_END; break;
1214 // legend expansion
1215 cssc::LegendExpansion eApiExpand = ::get_flagvalue(
1216 rLegend.mnFlags, EXC_CHLEGEND_STACKED, cssc::LegendExpansion_HIGH, cssc::LegendExpansion_WIDE );
1217 // legend position
1218 Any aRelPosAny;
1219 if( eApiPos == cssc::LegendPosition_CUSTOM )
1221 // #i71697# it is not possible to set the size directly, do some magic here
1222 double fRatio = ((rLegend.maRect.mnWidth > 0) && (rLegend.maRect.mnHeight > 0)) ?
1223 (static_cast< double >( rLegend.maRect.mnWidth ) / rLegend.maRect.mnHeight) : 1.0;
1224 if( fRatio > 1.5 )
1225 eApiExpand = cssc::LegendExpansion_WIDE;
1226 else if( fRatio < 0.75 )
1227 eApiExpand = cssc::LegendExpansion_HIGH;
1228 else
1229 eApiExpand = cssc::LegendExpansion_BALANCED;
1230 // set position
1231 cssc::RelativePosition aRelPos;
1232 aRelPos.Primary = rLegend.maRect.mnX / 4000.0;
1233 aRelPos.Secondary = rLegend.maRect.mnY / 4000.0;
1234 aRelPos.Anchor = cssd::Alignment_TOP_LEFT;
1235 aRelPosAny <<= aRelPos;
1238 // write the properties
1239 maLegendHlp.InitializeWrite();
1240 maLegendHlp << true << eApiPos << eApiExpand << aRelPosAny;
1241 maLegendHlp.WriteToPropertySet( rPropSet );
1244 // private --------------------------------------------------------------------
1246 ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode )
1248 switch( ePropMode )
1250 case EXC_CHPROPMODE_COMMON: return maLineHlpCommon;
1251 case EXC_CHPROPMODE_LINEARSERIES: return maLineHlpLinear;
1252 case EXC_CHPROPMODE_FILLEDSERIES: return maLineHlpFilled;
1253 default: DBG_ERRORFILE( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1255 return maLineHlpCommon;
1258 ScfPropSetHelper& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode )
1260 switch( ePropMode )
1262 case EXC_CHPROPMODE_COMMON: return maAreaHlpCommon;
1263 case EXC_CHPROPMODE_FILLEDSERIES: return maAreaHlpFilled;
1264 default: DBG_ERRORFILE( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1266 return maAreaHlpCommon;
1269 ScfPropSetHelper& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode )
1271 switch( ePropMode )
1273 case EXC_CHPROPMODE_COMMON: return maGradHlpCommon;
1274 case EXC_CHPROPMODE_FILLEDSERIES: return maGradHlpFilled;
1275 default: DBG_ERRORFILE( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1277 return maGradHlpCommon;
1280 ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode )
1282 switch( ePropMode )
1284 case EXC_CHPROPMODE_COMMON: return maHatchHlpCommon;
1285 case EXC_CHPROPMODE_FILLEDSERIES: return maHatchHlpFilled;
1286 default: DBG_ERRORFILE( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1288 return maHatchHlpCommon;
1291 // ============================================================================
1293 XclChRootData::XclChRootData() :
1294 mxTypeInfoProv( new XclChTypeInfoProvider ),
1295 mxFmtInfoProv( new XclChFormatInfoProvider )
1299 XclChRootData::~XclChRootData()
1303 Reference< XChartDocument > XclChRootData::GetChartDoc() const
1305 DBG_ASSERT( mxChartDoc.is(), "XclChRootData::GetChartDoc - missing chart document" );
1306 return mxChartDoc;
1309 void XclChRootData::InitConversion( XChartDocRef xChartDoc )
1311 // remember chart document reference
1312 DBG_ASSERT( xChartDoc.is(), "XclChRootData::InitConversion - missing chart document" );
1313 mxChartDoc = xChartDoc;
1315 // create object tables
1316 Reference< XMultiServiceFactory > xFactory( mxChartDoc, UNO_QUERY );
1317 mxLineDashTable.reset( new XclChObjectTable(
1318 xFactory, SERVICE_DRAWING_DASHTABLE, CREATE_OUSTRING( "Excel line dash " ) ) );
1319 mxGradientTable.reset( new XclChObjectTable(
1320 xFactory, SERVICE_DRAWING_GRADIENTTABLE, CREATE_OUSTRING( "Excel gradient " ) ) );
1321 mxHatchTable.reset( new XclChObjectTable(
1322 xFactory, SERVICE_DRAWING_HATCHTABLE, CREATE_OUSTRING( "Excel hatch " ) ) );
1323 mxBitmapTable.reset( new XclChObjectTable(
1324 xFactory, SERVICE_DRAWING_BITMAPTABLE, CREATE_OUSTRING( "Excel bitmap " ) ) );
1327 void XclChRootData::FinishConversion()
1329 // forget formatting object tables
1330 mxBitmapTable.reset();
1331 mxHatchTable.reset();
1332 mxGradientTable.reset();
1333 mxLineDashTable.reset();
1334 // forget chart document reference
1335 mxChartDoc.clear();
1338 // ============================================================================