bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / filter / excel / xlchart.cxx
blob20965db3ace47e00fc9a899fce246a64c9ac2d40
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "xlchart.hxx"
23 #include <com/sun/star/container/XNameContainer.hpp>
24 #include <com/sun/star/awt/Size.hpp>
25 #include <com/sun/star/awt/Gradient.hpp>
26 #include <com/sun/star/drawing/Hatch.hpp>
27 #include <com/sun/star/drawing/LineDash.hpp>
28 #include <com/sun/star/drawing/LineStyle.hpp>
29 #include <com/sun/star/drawing/FillStyle.hpp>
30 #include <com/sun/star/drawing/BitmapMode.hpp>
31 #include <com/sun/star/chart/DataLabelPlacement.hpp>
32 #include <com/sun/star/chart/XAxisXSupplier.hpp>
33 #include <com/sun/star/chart/XAxisYSupplier.hpp>
34 #include <com/sun/star/chart/XAxisZSupplier.hpp>
35 #include <com/sun/star/chart/XChartDocument.hpp>
36 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
37 #include <com/sun/star/chart2/Symbol.hpp>
39 #include <sal/macros.h>
40 #include <rtl/math.hxx>
41 #include <svl/itemset.hxx>
42 #include <svx/xfillit0.hxx>
43 #include <svx/xflclit.hxx>
44 #include <svx/xfltrit.hxx>
45 #include <svx/xflgrit.hxx>
46 #include <svx/xbtmpit.hxx>
47 #include <svx/unomid.hxx>
48 #include <filter/msfilter/escherex.hxx>
49 #include <editeng/memberids.hrc>
50 #include "global.hxx"
51 #include "xlroot.hxx"
52 #include "xlstyle.hxx"
54 using ::com::sun::star::uno::Any;
55 using ::com::sun::star::uno::Reference;
56 using ::com::sun::star::uno::UNO_QUERY;
57 using ::com::sun::star::uno::Exception;
58 using ::com::sun::star::lang::XMultiServiceFactory;
59 using ::com::sun::star::chart2::XChartDocument;
60 using ::com::sun::star::drawing::XShape;
62 namespace cssc = ::com::sun::star::chart;
64 // Common =====================================================================
66 XclChRectangle::XclChRectangle() :
67 mnX( 0 ),
68 mnY( 0 ),
69 mnWidth( 0 ),
70 mnHeight( 0 )
74 // ----------------------------------------------------------------------------
76 XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx, sal_uInt16 nPointIdx ) :
77 mnSeriesIdx( nSeriesIdx ),
78 mnPointIdx( nPointIdx )
82 bool operator<( const XclChDataPointPos& rL, const XclChDataPointPos& rR )
84 return (rL.mnSeriesIdx < rR.mnSeriesIdx) ||
85 ((rL.mnSeriesIdx == rR.mnSeriesIdx) && (rL.mnPointIdx < rR.mnPointIdx));
88 // ----------------------------------------------------------------------------
90 XclChFrBlock::XclChFrBlock( sal_uInt16 nType ) :
91 mnType( nType ),
92 mnContext( 0 ),
93 mnValue1( 0 ),
94 mnValue2( 0 )
98 // Frame formatting ===========================================================
100 XclChFramePos::XclChFramePos() :
101 mnTLMode( EXC_CHFRAMEPOS_PARENT ),
102 mnBRMode( EXC_CHFRAMEPOS_PARENT )
106 // ----------------------------------------------------------------------------
108 XclChLineFormat::XclChLineFormat() :
109 maColor( COL_BLACK ),
110 mnPattern( EXC_CHLINEFORMAT_SOLID ),
111 mnWeight( EXC_CHLINEFORMAT_SINGLE ),
112 mnFlags( EXC_CHLINEFORMAT_AUTO )
116 // ----------------------------------------------------------------------------
118 XclChAreaFormat::XclChAreaFormat() :
119 maPattColor( COL_WHITE ),
120 maBackColor( COL_BLACK ),
121 mnPattern( EXC_PATT_SOLID ),
122 mnFlags( EXC_CHAREAFORMAT_AUTO )
126 // ----------------------------------------------------------------------------
128 XclChEscherFormat::XclChEscherFormat()
132 XclChEscherFormat::~XclChEscherFormat()
136 // ----------------------------------------------------------------------------
138 XclChPicFormat::XclChPicFormat() :
139 mnBmpMode( EXC_CHPICFORMAT_NONE ),
140 mnFlags( EXC_CHPICFORMAT_TOPBOTTOM | EXC_CHPICFORMAT_FRONTBACK | EXC_CHPICFORMAT_LEFTRIGHT ),
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 XclChFrLabelProps::XclChFrLabelProps() :
173 mnFlags( 0 )
177 // ----------------------------------------------------------------------------
179 XclChText::XclChText() :
180 maTextColor( COL_BLACK ),
181 mnHAlign( EXC_CHTEXT_ALIGN_CENTER ),
182 mnVAlign( EXC_CHTEXT_ALIGN_CENTER ),
183 mnBackMode( EXC_CHTEXT_TRANSPARENT ),
184 mnFlags( EXC_CHTEXT_AUTOCOLOR | EXC_CHTEXT_AUTOFILL ),
185 mnFlags2( EXC_CHTEXT_POS_DEFAULT ),
186 mnRotation( EXC_ROT_NONE )
190 // Data series ================================================================
192 XclChMarkerFormat::XclChMarkerFormat() :
193 maLineColor( COL_BLACK ),
194 maFillColor( COL_WHITE ),
195 mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE ),
196 mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL ),
197 mnFlags( EXC_CHMARKERFORMAT_AUTO )
201 // ----------------------------------------------------------------------------
203 XclCh3dDataFormat::XclCh3dDataFormat() :
204 mnBase( EXC_CH3DDATAFORMAT_RECT ),
205 mnTop( EXC_CH3DDATAFORMAT_STRAIGHT )
209 // ----------------------------------------------------------------------------
211 XclChDataFormat::XclChDataFormat() :
212 mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT ),
213 mnFlags( 0 )
217 // ----------------------------------------------------------------------------
219 XclChSerTrendLine::XclChSerTrendLine() :
220 mfForecastFor( 0.0 ),
221 mfForecastBack( 0.0 ),
222 mnLineType( EXC_CHSERTREND_POLYNOMIAL ),
223 mnOrder( 1 ),
224 mnShowEquation( 0 ),
225 mnShowRSquared( 0 )
227 /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
228 there is no interception point. Cannot use ::rtl::math::setNan() here
229 cause it misses the sign bit. */
230 sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &mfIntercept );
231 pDouble->w32_parts.msw = pDouble->w32_parts.lsw = 0xFFFFFFFF;
234 // ----------------------------------------------------------------------------
236 XclChSerErrorBar::XclChSerErrorBar() :
237 mfValue( 0.0 ),
238 mnValueCount( 1 ),
239 mnBarType( EXC_CHSERERR_NONE ),
240 mnSourceType( EXC_CHSERERR_FIXED ),
241 mnLineEnd( EXC_CHSERERR_END_TSHAPE )
245 // ----------------------------------------------------------------------------
247 XclChSeries::XclChSeries() :
248 mnCategType( EXC_CHSERIES_NUMERIC ),
249 mnValueType( EXC_CHSERIES_NUMERIC ),
250 mnBubbleType( EXC_CHSERIES_NUMERIC ),
251 mnCategCount( 0 ),
252 mnValueCount( 0 ),
253 mnBubbleCount( 0 )
257 // Chart type groups ==========================================================
259 XclChType::XclChType() :
260 mnOverlap( 0 ),
261 mnGap( 150 ),
262 mnRotation( 0 ),
263 mnPieHole( 0 ),
264 mnBubbleSize( 100 ),
265 mnBubbleType( EXC_CHSCATTER_AREA ),
266 mnFlags( 0 )
270 // ----------------------------------------------------------------------------
272 XclChChart3d::XclChChart3d() :
273 mnRotation( 20 ),
274 mnElevation( 15 ),
275 mnEyeDist( 30 ),
276 mnRelHeight( 100 ),
277 mnRelDepth( 100 ),
278 mnDepthGap( 150 ),
279 mnFlags( EXC_CHCHART3D_AUTOHEIGHT )
283 // ----------------------------------------------------------------------------
285 XclChLegend::XclChLegend() :
286 mnDockMode( EXC_CHLEGEND_RIGHT ),
287 mnSpacing( EXC_CHLEGEND_MEDIUM ),
288 mnFlags( EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOSERIES |
289 EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY | EXC_CHLEGEND_STACKED )
293 // ----------------------------------------------------------------------------
295 XclChTypeGroup::XclChTypeGroup() :
296 mnFlags( 0 ),
297 mnGroupIdx( EXC_CHSERGROUP_NONE )
301 // ----------------------------------------------------------------------------
303 XclChProperties::XclChProperties() :
304 mnFlags( 0 ),
305 mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP )
309 // Axes =======================================================================
311 XclChLabelRange::XclChLabelRange() :
312 mnCross( 1 ),
313 mnLabelFreq( 1 ),
314 mnTickFreq( 1 ),
315 mnFlags( 0 )
319 // ----------------------------------------------------------------------------
321 XclChDateRange::XclChDateRange() :
322 mnMinDate( 0 ),
323 mnMaxDate( 0 ),
324 mnMajorStep( 0 ),
325 mnMajorUnit( EXC_CHDATERANGE_DAYS ),
326 mnMinorStep( 0 ),
327 mnMinorUnit( EXC_CHDATERANGE_DAYS ),
328 mnBaseUnit( EXC_CHDATERANGE_DAYS ),
329 mnCross( 0 ),
330 mnFlags( EXC_CHDATERANGE_AUTOMIN | EXC_CHDATERANGE_AUTOMAX |
331 EXC_CHDATERANGE_AUTOMAJOR | EXC_CHDATERANGE_AUTOMINOR |
332 EXC_CHDATERANGE_AUTOBASE | EXC_CHDATERANGE_AUTOCROSS |
333 EXC_CHDATERANGE_AUTODATE )
337 // ----------------------------------------------------------------------------
339 XclChValueRange::XclChValueRange() :
340 mfMin( 0.0 ),
341 mfMax( 0.0 ),
342 mfMajorStep( 0.0 ),
343 mfMinorStep( 0.0 ),
344 mfCross( 0.0 ),
345 mnFlags( EXC_CHVALUERANGE_AUTOMIN | EXC_CHVALUERANGE_AUTOMAX |
346 EXC_CHVALUERANGE_AUTOMAJOR | EXC_CHVALUERANGE_AUTOMINOR |
347 EXC_CHVALUERANGE_AUTOCROSS | EXC_CHVALUERANGE_BIT8 )
351 // ----------------------------------------------------------------------------
353 XclChTick::XclChTick() :
354 maTextColor( COL_BLACK ),
355 mnMajor( EXC_CHTICK_INSIDE | EXC_CHTICK_OUTSIDE ),
356 mnMinor( 0 ),
357 mnLabelPos( EXC_CHTICK_NEXT ),
358 mnBackMode( EXC_CHTICK_TRANSPARENT ),
359 mnFlags( EXC_CHTICK_AUTOCOLOR | EXC_CHTICK_AUTOROT ),
360 mnRotation( EXC_ROT_NONE )
364 // ----------------------------------------------------------------------------
366 XclChAxis::XclChAxis() :
367 mnType( EXC_CHAXIS_NONE )
371 sal_Int32 XclChAxis::GetApiAxisDimension() const
373 sal_Int32 nApiAxisDim = EXC_CHART_AXIS_NONE;
374 switch( mnType )
376 case EXC_CHAXIS_X: nApiAxisDim = EXC_CHART_AXIS_X; break;
377 case EXC_CHAXIS_Y: nApiAxisDim = EXC_CHART_AXIS_Y; break;
378 case EXC_CHAXIS_Z: nApiAxisDim = EXC_CHART_AXIS_Z; break;
380 return nApiAxisDim;
383 // ----------------------------------------------------------------------------
385 XclChAxesSet::XclChAxesSet() :
386 mnAxesSetId( EXC_CHAXESSET_PRIMARY )
390 sal_Int32 XclChAxesSet::GetApiAxesSetIndex() const
392 sal_Int32 nApiAxesSetIdx = EXC_CHART_AXESSET_NONE;
393 switch( mnAxesSetId )
395 case EXC_CHAXESSET_PRIMARY: nApiAxesSetIdx = EXC_CHART_AXESSET_PRIMARY; break;
396 case EXC_CHAXESSET_SECONDARY: nApiAxesSetIdx = EXC_CHART_AXESSET_SECONDARY; break;
398 return nApiAxesSetIdx;
401 // Static helper functions ====================================================
403 sal_uInt16 XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx )
405 static const sal_uInt16 spnLineColors[] =
407 32, 33, 34, 35, 36, 37, 38, 39,
408 40, 41, 42, 43, 44, 45, 46, 47,
409 48, 49, 50, 51, 52, 53, 54, 55,
410 56, 57, 58, 59, 60, 61, 62, 8,
411 9, 10, 11, 12, 13, 14, 15, 16,
412 17, 18, 19, 20, 21, 22, 23, 24,
413 25, 26, 27, 28, 29, 30, 31, 63
415 return spnLineColors[ nFormatIdx % SAL_N_ELEMENTS( spnLineColors ) ];
418 sal_uInt16 XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx )
420 static const sal_uInt16 spnFillColors[] =
422 24, 25, 26, 27, 28, 29, 30, 31,
423 32, 33, 34, 35, 36, 37, 38, 39,
424 40, 41, 42, 43, 44, 45, 46, 47,
425 48, 49, 50, 51, 52, 53, 54, 55,
426 56, 57, 58, 59, 60, 61, 62, 63,
427 8, 9, 10, 11, 12, 13, 14, 15,
428 16, 17, 18, 19, 20, 21, 22, 23
430 return spnFillColors[ nFormatIdx % SAL_N_ELEMENTS( spnFillColors ) ];
433 sal_uInt8 XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx )
435 static const sal_uInt8 spnTrans[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
436 return spnTrans[ (nFormatIdx / 56) % SAL_N_ELEMENTS( spnTrans ) ];
439 sal_uInt16 XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx )
441 static const sal_uInt16 spnSymbols[] = {
442 EXC_CHMARKERFORMAT_DIAMOND, EXC_CHMARKERFORMAT_SQUARE, EXC_CHMARKERFORMAT_TRIANGLE,
443 EXC_CHMARKERFORMAT_CROSS, EXC_CHMARKERFORMAT_STAR, EXC_CHMARKERFORMAT_CIRCLE,
444 EXC_CHMARKERFORMAT_PLUS, EXC_CHMARKERFORMAT_DOWJ, EXC_CHMARKERFORMAT_STDDEV };
445 return spnSymbols[ nFormatIdx % SAL_N_ELEMENTS( spnSymbols ) ];
448 bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType )
450 static const bool spbFilled[] = {
451 false, true, true, true, false, false, false, false, true, false };
452 return (nMarkerType < SAL_N_ELEMENTS( spbFilled )) && spbFilled[ nMarkerType ];
455 OUString XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType )
457 switch( nBarType )
459 case EXC_CHSERERR_XPLUS: return OUString( EXC_CHPROP_ROLE_ERRORBARS_POSX );
460 case EXC_CHSERERR_XMINUS: return OUString( EXC_CHPROP_ROLE_ERRORBARS_NEGX );
461 case EXC_CHSERERR_YPLUS: return OUString( EXC_CHPROP_ROLE_ERRORBARS_POSY );
462 case EXC_CHSERERR_YMINUS: return OUString( EXC_CHPROP_ROLE_ERRORBARS_NEGY );
463 default: OSL_FAIL( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
465 return OUString();
468 // Chart formatting info provider =============================================
470 namespace {
472 static const XclChFormatInfo spFmtInfos[] =
474 // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
475 { EXC_CHOBJTYPE_BACKGROUND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
476 { EXC_CHOBJTYPE_PLOTFRAME, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
477 { EXC_CHOBJTYPE_WALL3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, false, true },
478 { EXC_CHOBJTYPE_FLOOR3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, 23, EXC_CHFRAMETYPE_AUTO, true, false, true },
479 { EXC_CHOBJTYPE_TEXT, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, true },
480 { EXC_CHOBJTYPE_LEGEND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, true, true },
481 { EXC_CHOBJTYPE_LINEARSERIES, EXC_CHPROPMODE_LINEARSERIES, 0xFFFF, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
482 { EXC_CHOBJTYPE_FILLEDSERIES, EXC_CHPROPMODE_FILLEDSERIES, EXC_COLOR_CHBORDERAUTO, EXC_CHLINEFORMAT_SINGLE, 0xFFFF, EXC_CHFRAMETYPE_AUTO, false, false, true },
483 { EXC_CHOBJTYPE_AXISLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
484 { EXC_CHOBJTYPE_GRIDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, false },
485 { EXC_CHOBJTYPE_TRENDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_DOUBLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
486 { EXC_CHOBJTYPE_ERRORBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
487 { EXC_CHOBJTYPE_CONNECTLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
488 { EXC_CHOBJTYPE_HILOLINE, EXC_CHPROPMODE_LINEARSERIES, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
489 { EXC_CHOBJTYPE_WHITEDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, true },
490 { EXC_CHOBJTYPE_BLACKDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWTEXT, EXC_CHFRAMETYPE_INVISIBLE, false, false, true }
495 // ----------------------------------------------------------------------------
497 XclChFormatInfoProvider::XclChFormatInfoProvider()
499 const XclChFormatInfo* pEnd = STATIC_ARRAY_END( spFmtInfos );
500 for( const XclChFormatInfo* pIt = spFmtInfos; pIt != pEnd; ++pIt )
501 maInfoMap[ pIt->meObjType ] = pIt;
504 const XclChFormatInfo& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType ) const
506 XclFmtInfoMap::const_iterator aIt = maInfoMap.find( eObjType );
507 OSL_ENSURE( aIt != maInfoMap.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
508 return (aIt == maInfoMap.end()) ? *spFmtInfos : *aIt->second;
511 // Chart type info provider ===================================================
513 namespace {
515 // chart type service names
516 const sal_Char SERVICE_CHART2_AREA[] = "com.sun.star.chart2.AreaChartType";
517 const sal_Char SERVICE_CHART2_CANDLE[] = "com.sun.star.chart2.CandleStickChartType";
518 const sal_Char SERVICE_CHART2_COLUMN[] = "com.sun.star.chart2.ColumnChartType";
519 const sal_Char SERVICE_CHART2_LINE[] = "com.sun.star.chart2.LineChartType";
520 const sal_Char SERVICE_CHART2_NET[] = "com.sun.star.chart2.NetChartType";
521 const sal_Char SERVICE_CHART2_FILLEDNET[] = "com.sun.star.chart2.FilledNetChartType";
522 const sal_Char SERVICE_CHART2_PIE[] = "com.sun.star.chart2.PieChartType";
523 const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType";
524 const sal_Char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType";
525 const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
527 namespace csscd = cssc::DataLabelPlacement;
529 static const XclChTypeInfo spTypeInfos[] =
531 // 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
532 { 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 },
533 { 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 },
534 { 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 },
535 { 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 },
536 { 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 },
537 { 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 },
538 { 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 },
539 { 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 },
540 { EXC_CHTYPEID_DONUT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, false, true, false, false, false, false },
541 { 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 },
542 { 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 },
543 { 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 },
544 { 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 },
545 { 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 }
548 } // namespace
550 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo ) :
551 XclChTypeInfo( rTypeInfo ),
552 mb3dChart( false ),
553 mbSpline( false )
557 void XclChExtTypeInfo::Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline )
559 static_cast< XclChTypeInfo& >( *this ) = rTypeInfo;
560 mb3dChart = mbSupports3d && b3dChart;
561 mbSpline = bSpline;
564 // ----------------------------------------------------------------------------
566 XclChTypeInfoProvider::XclChTypeInfoProvider()
568 const XclChTypeInfo* pEnd = STATIC_ARRAY_END( spTypeInfos );
569 for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
570 maInfoMap[ pIt->meTypeId ] = pIt;
573 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId ) const
575 XclChTypeInfoMap::const_iterator aIt = maInfoMap.find( eTypeId );
576 OSL_ENSURE( aIt != maInfoMap.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
577 return (aIt == maInfoMap.end()) ? *maInfoMap.rbegin()->second : *aIt->second;
580 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId ) const
582 const XclChTypeInfo* pEnd = STATIC_ARRAY_END( spTypeInfos );
583 for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
584 if( pIt->mnRecId == nRecId )
585 return *pIt;
586 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
587 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
590 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString& rServiceName ) const
592 const XclChTypeInfo* pEnd = STATIC_ARRAY_END( spTypeInfos );
593 for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt )
594 if( rServiceName.equalsAscii( pIt->mpcServiceName ) )
595 return *pIt;
596 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
597 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
600 // Property helpers ===========================================================
602 XclChObjectTable::XclChObjectTable( Reference< XMultiServiceFactory > xFactory,
603 const OUString& rServiceName, const OUString& rObjNameBase ) :
604 mxFactory( xFactory ),
605 maServiceName( rServiceName ),
606 maObjNameBase( rObjNameBase ),
607 mnIndex( 0 )
611 Any XclChObjectTable::GetObject( const OUString& rObjName )
613 // get object table
614 if( !mxContainer.is() )
615 mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
616 OSL_ENSURE( mxContainer.is(), "XclChObjectTable::GetObject - container not found" );
618 Any aObj;
619 if( mxContainer.is() )
621 // get object from container
624 aObj = mxContainer->getByName( rObjName );
626 catch( Exception& )
628 OSL_FAIL( "XclChObjectTable::GetObject - object not found" );
631 return aObj;
634 OUString XclChObjectTable::InsertObject( const Any& rObj )
637 // create object table
638 if( !mxContainer.is() )
639 mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
640 OSL_ENSURE( mxContainer.is(), "XclChObjectTable::InsertObject - container not found" );
642 OUString aObjName;
643 if( mxContainer.is() )
645 // create new unused identifier
648 aObjName = maObjNameBase + OUString::valueOf( ++mnIndex );
650 while( mxContainer->hasByName( aObjName ) );
652 // insert object
655 mxContainer->insertByName( aObjName, rObj );
657 catch( Exception& )
659 OSL_FAIL( "XclChObjectTable::InsertObject - cannot insert object" );
660 aObjName = OUString();
663 return aObjName;
666 // Property names -------------------------------------------------------------
668 namespace {
670 /** Property names for line style in common objects. */
671 const sal_Char* const sppcLineNamesCommon[] =
672 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", 0 };
673 /** Property names for line style in linear series objects. */
674 const sal_Char* const sppcLineNamesLinear[] =
675 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", 0 };
676 /** Property names for line style in filled series objects. */
677 const sal_Char* const sppcLineNamesFilled[] =
678 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", 0 };
680 /** Property names for solid area style in common objects. */
681 const sal_Char* const sppcAreaNamesCommon[] = { "FillStyle", "FillColor", "FillTransparence", 0 };
682 /** Property names for solid area style in filled series objects. */
683 const sal_Char* const sppcAreaNamesFilled[] = { "FillStyle", "Color", "Transparency", 0 };
684 /** Property names for gradient area style in common objects. */
685 const sal_Char* const sppcGradNamesCommon[] = { "FillStyle", "FillGradientName", 0 };
686 /** Property names for gradient area style in filled series objects. */
687 const sal_Char* const sppcGradNamesFilled[] = { "FillStyle", "GradientName", 0 };
688 /** Property names for hatch area style in common objects. */
689 const sal_Char* const sppcHatchNamesCommon[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", 0 };
690 /** Property names for hatch area style in filled series objects. */
691 const sal_Char* const sppcHatchNamesFilled[] = { "FillStyle", "HatchName", "Color", "FillBackground", 0 };
692 /** Property names for bitmap area style. */
693 const sal_Char* const sppcBitmapNames[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 };
695 } // namespace
697 // ----------------------------------------------------------------------------
699 XclChPropSetHelper::XclChPropSetHelper() :
700 maLineHlpCommon( sppcLineNamesCommon ),
701 maLineHlpLinear( sppcLineNamesLinear ),
702 maLineHlpFilled( sppcLineNamesFilled ),
703 maAreaHlpCommon( sppcAreaNamesCommon ),
704 maAreaHlpFilled( sppcAreaNamesFilled ),
705 maGradHlpCommon( sppcGradNamesCommon ),
706 maGradHlpFilled( sppcGradNamesFilled ),
707 maHatchHlpCommon( sppcHatchNamesCommon ),
708 maHatchHlpFilled( sppcHatchNamesFilled ),
709 maBitmapHlp( sppcBitmapNames )
713 // read properties ------------------------------------------------------------
715 void XclChPropSetHelper::ReadLineProperties(
716 XclChLineFormat& rLineFmt, XclChObjectTable& rDashTable,
717 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
719 namespace cssd = ::com::sun::star::drawing;
721 // read properties from property set
722 cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
723 sal_Int32 nApiWidth = 0;
724 sal_Int16 nApiTrans = 0;
725 Any aDashNameAny;
727 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
728 rLineHlp.ReadFromPropertySet( rPropSet );
729 rLineHlp >> eApiStyle >> nApiWidth >> rLineFmt.maColor >> nApiTrans >> aDashNameAny;
731 // clear automatic flag
732 ::set_flag( rLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
734 // line width
735 if( nApiWidth <= 0 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
736 else if( nApiWidth <= 35 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE;
737 else if( nApiWidth <= 70 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE;
738 else rLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE;
740 // line style
741 switch( eApiStyle )
743 case cssd::LineStyle_NONE:
744 rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
745 break;
746 case cssd::LineStyle_SOLID:
748 if( nApiTrans < 13 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
749 else if( nApiTrans < 38 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS;
750 else if( nApiTrans < 63 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS;
751 else if( nApiTrans < 100 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS;
752 else rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
754 break;
755 case cssd::LineStyle_DASH:
757 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
758 OUString aDashName;
759 cssd::LineDash aApiDash;
760 if( (aDashNameAny >>= aDashName) && (rDashTable.GetObject( aDashName ) >>= aApiDash) )
762 // reorder dashes that are shorter than dots
763 if( (aApiDash.Dashes == 0) || (aApiDash.DashLen < aApiDash.DotLen) )
765 ::std::swap( aApiDash.Dashes, aApiDash.Dots );
766 ::std::swap( aApiDash.DashLen, aApiDash.DotLen );
768 // ignore dots that are nearly equal to dashes
769 if( aApiDash.DotLen * 3 > aApiDash.DashLen * 2 )
770 aApiDash.Dots = 0;
772 // convert line dash to predefined Excel dash types
773 if( (aApiDash.Dashes == 1) && (aApiDash.Dots >= 1) )
774 // one dash and one or more dots
775 rLineFmt.mnPattern = (aApiDash.Dots == 1) ?
776 EXC_CHLINEFORMAT_DASHDOT : EXC_CHLINEFORMAT_DASHDOTDOT;
777 else if( aApiDash.Dashes >= 1 )
778 // one or more dashes and no dots (also: dash-dash-dot)
779 rLineFmt.mnPattern = (aApiDash.DashLen < 250) ?
780 EXC_CHLINEFORMAT_DOT : EXC_CHLINEFORMAT_DASH;
783 break;
784 default:
785 OSL_FAIL( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
786 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
790 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat& rAreaFmt,
791 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
793 namespace cssd = ::com::sun::star::drawing;
795 // read properties from property set
796 cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
797 sal_Int16 nTransparency = 0;
799 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
800 rAreaHlp.ReadFromPropertySet( rPropSet );
801 rAreaHlp >> eApiStyle >> rAreaFmt.maPattColor >> nTransparency;
803 // clear automatic flag
804 ::set_flag( rAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
806 // set fill style transparent or solid (set solid for anything but transparent)
807 rAreaFmt.mnPattern = (eApiStyle == cssd::FillStyle_NONE) ? EXC_PATT_NONE : EXC_PATT_SOLID;
809 // return true to indicate complex fill (gradient, bitmap, solid transparency)
810 return (eApiStyle != cssd::FillStyle_NONE) && ((eApiStyle != cssd::FillStyle_SOLID) || (nTransparency > 0));
813 void XclChPropSetHelper::ReadEscherProperties(
814 XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
815 XclChObjectTable& rGradientTable, XclChObjectTable& rHatchTable, XclChObjectTable& rBitmapTable,
816 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
818 namespace cssd = ::com::sun::star::drawing;
819 namespace cssa = ::com::sun::star::awt;
821 // read style and transparency properties from property set
822 cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
823 Color aColor;
824 sal_Int16 nTransparency = 0;
826 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
827 rAreaHlp.ReadFromPropertySet( rPropSet );
828 rAreaHlp >> eApiStyle >> aColor >> nTransparency;
830 switch( eApiStyle )
832 case cssd::FillStyle_SOLID:
834 OSL_ENSURE( nTransparency > 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
835 if( (0 < nTransparency) && (nTransparency <= 100) )
837 // convert to Escher properties
838 sal_uInt32 nEscherColor = 0x02000000;
839 ::insert_value( nEscherColor, aColor.GetBlue(), 16, 8 );
840 ::insert_value( nEscherColor, aColor.GetGreen(), 8, 8 );
841 ::insert_value( nEscherColor, aColor.GetRed(), 0, 8 );
842 sal_uInt32 nEscherOpacity = static_cast< sal_uInt32 >( (100 - nTransparency) * 655.36 );
843 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
844 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
845 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, nEscherColor );
846 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillOpacity, nEscherOpacity );
847 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x02FFFFFF );
848 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackOpacity, 0x00010000 );
849 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fNoFillHitTest, 0x001F001C );
852 break;
853 case cssd::FillStyle_GRADIENT:
855 // extract gradient from global gradient table
856 OUString aGradientName;
857 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
858 rGradHlp.ReadFromPropertySet( rPropSet );
859 rGradHlp >> eApiStyle >> aGradientName;
860 cssa::Gradient aGradient;
861 if( rGradientTable.GetObject( aGradientName ) >>= aGradient )
863 // convert to Escher properties
864 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
865 rEscherFmt.mxEscherSet->CreateGradientProperties( aGradient );
868 break;
869 case cssd::FillStyle_HATCH:
871 // extract hatch from global hatch table
872 OUString aHatchName;
873 bool bFillBackground;
874 ScfPropSetHelper& rHatchHlp = GetHatchHelper( ePropMode );
875 rHatchHlp.ReadFromPropertySet( rPropSet );
876 rHatchHlp >> eApiStyle >> aHatchName >> aColor >> bFillBackground;
877 cssd::Hatch aHatch;
878 if( rHatchTable.GetObject( aHatchName ) >>= aHatch )
880 // convert to Escher properties
881 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
882 rEscherFmt.mxEscherSet->CreateEmbeddedHatchProperties( aHatch, aColor, bFillBackground );
883 rPicFmt.mnBmpMode = EXC_CHPICFORMAT_STACK;
886 break;
887 case cssd::FillStyle_BITMAP:
889 // extract bitmap URL from global bitmap table
890 OUString aBitmapName;
891 cssd::BitmapMode eApiBmpMode;
892 maBitmapHlp.ReadFromPropertySet( rPropSet );
893 maBitmapHlp >> eApiStyle >> aBitmapName >> eApiBmpMode;
894 OUString aBitmapUrl;
895 if( rBitmapTable.GetObject( aBitmapName ) >>= aBitmapUrl )
897 // convert to Escher properties
898 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
899 rEscherFmt.mxEscherSet->CreateEmbeddedBitmapProperties( aBitmapUrl, eApiBmpMode );
900 rPicFmt.mnBmpMode = (eApiBmpMode == cssd::BitmapMode_REPEAT) ?
901 EXC_CHPICFORMAT_STACK : EXC_CHPICFORMAT_STRETCH;
904 break;
905 default:
906 OSL_FAIL( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
910 void XclChPropSetHelper::ReadMarkerProperties(
911 XclChMarkerFormat& rMarkerFmt, const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
913 namespace cssc = ::com::sun::star::chart2;
914 namespace cssa = ::com::sun::star::awt;
915 cssc::Symbol aApiSymbol;
916 if( rPropSet.GetProperty( aApiSymbol, EXC_CHPROP_SYMBOL ) )
918 // clear automatic flag
919 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
921 // symbol style
922 switch( aApiSymbol.Style )
924 case cssc::SymbolStyle_NONE:
925 rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
926 break;
927 case cssc::SymbolStyle_STANDARD:
928 switch( aApiSymbol.StandardSymbol )
930 case 0: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_SQUARE; break; // square
931 case 1: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // diamond
932 case 2: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // arrow down
933 case 3: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_TRIANGLE; break; // arrow up
934 case 4: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DOWJ; break; // arrow right, same as import
935 case 5: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // arrow left
936 case 6: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // bow tie
937 case 7: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // sand glass
938 case 8: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CIRCLE; break; // circle new in LibO3.5
939 case 9: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // star new in LibO3.5
940 case 10: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // X new in LibO3.5
941 case 11: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // plus new in LibO3.5
942 case 12: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // asterisk new in LibO3.5
943 case 13: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // horizontal bar new in LibO3.5
944 case 14: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // vertical bar new in LibO3.5
945 default: rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
947 break;
948 default:
949 rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
951 bool bHasFillColor = XclChartHelper::HasMarkerFillColor( rMarkerFmt.mnMarkerType );
952 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOFILL, !bHasFillColor );
954 // symbol size
955 sal_Int32 nApiSize = (aApiSymbol.Size.Width + aApiSymbol.Size.Height + 1) / 2;
956 rMarkerFmt.mnMarkerSize = XclTools::GetTwipsFromHmm( nApiSize );
958 // symbol colors
959 rMarkerFmt.maLineColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.BorderColor );
960 rMarkerFmt.maFillColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.FillColor );
964 sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPropSet, bool bSupportsStacked )
966 // chart2 handles rotation as double in the range [0,360)
967 double fAngle = 0.0;
968 rPropSet.GetProperty( fAngle, EXC_CHPROP_TEXTROTATION );
969 bool bStacked = bSupportsStacked && rPropSet.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS );
970 return bStacked ? EXC_ROT_STACKED :
971 XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) );
974 // write properties -----------------------------------------------------------
976 void XclChPropSetHelper::WriteLineProperties(
977 ScfPropertySet& rPropSet, XclChObjectTable& rDashTable,
978 const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode )
980 namespace cssd = ::com::sun::star::drawing;
982 // line width
983 sal_Int32 nApiWidth = 0; // 0 is the width of a hair line
984 switch( rLineFmt.mnWeight )
986 case EXC_CHLINEFORMAT_SINGLE: nApiWidth = 35; break;
987 case EXC_CHLINEFORMAT_DOUBLE: nApiWidth = 70; break;
988 case EXC_CHLINEFORMAT_TRIPLE: nApiWidth = 105; break;
991 // line style
992 cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
993 sal_Int16 nApiTrans = 0;
994 sal_Int32 nDotLen = ::std::min< sal_Int32 >( rLineFmt.mnWeight + 105, 210 );
995 cssd::LineDash aApiDash( cssd::DashStyle_RECT, 0, nDotLen, 0, 4 * nDotLen, nDotLen );
997 switch( rLineFmt.mnPattern )
999 case EXC_CHLINEFORMAT_SOLID:
1000 eApiStyle = cssd::LineStyle_SOLID;
1001 break;
1002 case EXC_CHLINEFORMAT_DARKTRANS:
1003 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 25;
1004 break;
1005 case EXC_CHLINEFORMAT_MEDTRANS:
1006 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 50;
1007 break;
1008 case EXC_CHLINEFORMAT_LIGHTTRANS:
1009 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 75;
1010 break;
1011 case EXC_CHLINEFORMAT_DASH:
1012 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1;
1013 break;
1014 case EXC_CHLINEFORMAT_DOT:
1015 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dots = 1;
1016 break;
1017 case EXC_CHLINEFORMAT_DASHDOT:
1018 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = aApiDash.Dots = 1;
1019 break;
1020 case EXC_CHLINEFORMAT_DASHDOTDOT:
1021 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1; aApiDash.Dots = 2;
1022 break;
1025 // line color
1026 sal_Int32 nApiColor = ScfApiHelper::ConvertToApiColor( rLineFmt.maColor );
1028 // try to insert the dash style and receive its name
1029 Any aDashNameAny;
1030 if( eApiStyle == cssd::LineStyle_DASH )
1032 OUString aDashName = rDashTable.InsertObject( ::com::sun::star::uno::makeAny( aApiDash ) );
1033 if( !aDashName.isEmpty() )
1034 aDashNameAny <<= aDashName;
1037 // write the properties
1038 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
1039 rLineHlp.InitializeWrite();
1040 rLineHlp << eApiStyle << nApiWidth << nApiColor << nApiTrans << aDashNameAny;
1041 rLineHlp.WriteToPropertySet( rPropSet );
1044 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet& rPropSet,
1045 const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode )
1047 namespace cssd = ::com::sun::star::drawing;
1048 cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
1049 Color aColor;
1050 sal_Int16 nTransparency = 0;
1052 // fill color
1053 if( rAreaFmt.mnPattern != EXC_PATT_NONE )
1055 eFillStyle = cssd::FillStyle_SOLID;
1056 aColor = XclTools::GetPatternColor( rAreaFmt.maPattColor, rAreaFmt.maBackColor, rAreaFmt.mnPattern );
1059 // write the properties
1060 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
1061 rAreaHlp.InitializeWrite();
1062 rAreaHlp << eFillStyle << aColor << nTransparency;
1063 rAreaHlp.WriteToPropertySet( rPropSet );
1066 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet,
1067 XclChObjectTable& rGradientTable, XclChObjectTable& /*rHatchTable*/, XclChObjectTable& rBitmapTable,
1068 const XclChEscherFormat& rEscherFmt, const XclChPicFormat* pPicFmt,
1069 sal_uInt32 nDffFillType, XclChPropertyMode ePropMode )
1071 if( rEscherFmt.mxItemSet )
1073 if( const XFillStyleItem* pStyleItem = static_cast< const XFillStyleItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLSTYLE, false ) ) )
1075 switch( pStyleItem->GetValue() )
1077 case XFILL_SOLID:
1078 // #i84812# Excel 2007 writes Escher properties for solid fill
1079 if( const XFillColorItem* pColorItem = static_cast< const XFillColorItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLCOLOR, false ) ) )
1081 namespace cssd = ::com::sun::star::drawing;
1082 // get solid transparence too
1083 const XFillTransparenceItem* pTranspItem = static_cast< const XFillTransparenceItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLTRANSPARENCE, false ) );
1084 sal_uInt16 nTransp = pTranspItem ? pTranspItem->GetValue() : 0;
1085 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
1086 rAreaHlp.InitializeWrite();
1087 rAreaHlp << cssd::FillStyle_SOLID << pColorItem->GetColorValue() << static_cast< sal_Int16 >( nTransp );
1088 rAreaHlp.WriteToPropertySet( rPropSet );
1090 break;
1091 case XFILL_GRADIENT:
1092 if( const XFillGradientItem* pGradItem = static_cast< const XFillGradientItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLGRADIENT, false ) ) )
1094 Any aGradientAny;
1095 if( pGradItem->QueryValue( aGradientAny, MID_FILLGRADIENT ) )
1097 OUString aGradName = rGradientTable.InsertObject( aGradientAny );
1098 if( !aGradName.isEmpty() )
1100 namespace cssd = ::com::sun::star::drawing;
1101 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
1102 rGradHlp.InitializeWrite();
1103 rGradHlp << cssd::FillStyle_GRADIENT << aGradName;
1104 rGradHlp.WriteToPropertySet( rPropSet );
1108 break;
1109 case XFILL_BITMAP:
1110 if( const XFillBitmapItem* pBmpItem = static_cast< const XFillBitmapItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLBITMAP, false ) ) )
1112 Any aBitmapAny;
1113 if( pBmpItem->QueryValue( aBitmapAny, MID_GRAFURL ) )
1115 OUString aBmpName = rBitmapTable.InsertObject( aBitmapAny );
1116 if( !aBmpName.isEmpty() )
1118 namespace cssd = ::com::sun::star::drawing;
1119 /* #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode.
1120 If not passed, detect fill mode from the DFF property 'fill-type'. */
1121 bool bStretch = pPicFmt ? (pPicFmt->mnBmpMode == EXC_CHPICFORMAT_STRETCH) : (nDffFillType == mso_fillPicture);
1122 cssd::BitmapMode eApiBmpMode = bStretch ? cssd::BitmapMode_STRETCH : cssd::BitmapMode_REPEAT;
1123 maBitmapHlp.InitializeWrite();
1124 maBitmapHlp << cssd::FillStyle_BITMAP << aBmpName << eApiBmpMode;
1125 maBitmapHlp.WriteToPropertySet( rPropSet );
1129 break;
1130 default:
1131 OSL_FAIL( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1137 void XclChPropSetHelper::WriteMarkerProperties(
1138 ScfPropertySet& rPropSet, const XclChMarkerFormat& rMarkerFmt )
1140 namespace cssc = ::com::sun::star::chart2;
1141 namespace cssa = ::com::sun::star::awt;
1143 // symbol style
1144 cssc::Symbol aApiSymbol;
1145 aApiSymbol.Style = cssc::SymbolStyle_STANDARD;
1146 switch( rMarkerFmt.mnMarkerType )
1148 case EXC_CHMARKERFORMAT_NOSYMBOL: aApiSymbol.Style = cssc::SymbolStyle_NONE; break;
1149 case EXC_CHMARKERFORMAT_SQUARE: aApiSymbol.StandardSymbol = 0; break; // square
1150 case EXC_CHMARKERFORMAT_DIAMOND: aApiSymbol.StandardSymbol = 1; break; // diamond
1151 case EXC_CHMARKERFORMAT_TRIANGLE: aApiSymbol.StandardSymbol = 3; break; // arrow up
1152 case EXC_CHMARKERFORMAT_CROSS: aApiSymbol.StandardSymbol = 10; break; // X, legacy bow tie
1153 case EXC_CHMARKERFORMAT_STAR: aApiSymbol.StandardSymbol = 12; break; // asterisk, legacy sand glass
1154 case EXC_CHMARKERFORMAT_DOWJ: aApiSymbol.StandardSymbol = 4; break; // arrow right, same as export
1155 case EXC_CHMARKERFORMAT_STDDEV: aApiSymbol.StandardSymbol = 13; break; // horizontal bar, legacy arrow down
1156 case EXC_CHMARKERFORMAT_CIRCLE: aApiSymbol.StandardSymbol = 8; break; // circle, legacy arrow right
1157 case EXC_CHMARKERFORMAT_PLUS: aApiSymbol.StandardSymbol = 11; break; // plus, legacy arrow left
1158 default: break;
1161 // symbol size
1162 sal_Int32 nApiSize = XclTools::GetHmmFromTwips( rMarkerFmt.mnMarkerSize );
1163 aApiSymbol.Size = cssa::Size( nApiSize, nApiSize );
1165 // symbol colors
1166 aApiSymbol.FillColor = ScfApiHelper::ConvertToApiColor( rMarkerFmt.maFillColor );
1167 aApiSymbol.BorderColor = ::get_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOLINE ) ?
1168 aApiSymbol.FillColor : ScfApiHelper::ConvertToApiColor( rMarkerFmt.maLineColor );
1170 // set the property
1171 rPropSet.SetProperty( EXC_CHPROP_SYMBOL, aApiSymbol );
1174 void XclChPropSetHelper::WriteRotationProperties(
1175 ScfPropertySet& rPropSet, sal_uInt16 nRotation, bool bSupportsStacked )
1177 if( nRotation != EXC_CHART_AUTOROTATION )
1179 // chart2 handles rotation as double in the range [0,360)
1180 double fAngle = XclTools::GetScRotation( nRotation, 0 ) / 100.0;
1181 rPropSet.SetProperty( EXC_CHPROP_TEXTROTATION, fAngle );
1182 if( bSupportsStacked )
1183 rPropSet.SetProperty( EXC_CHPROP_STACKCHARACTERS, nRotation == EXC_ROT_STACKED );
1187 // private --------------------------------------------------------------------
1189 ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode )
1191 switch( ePropMode )
1193 case EXC_CHPROPMODE_COMMON: return maLineHlpCommon;
1194 case EXC_CHPROPMODE_LINEARSERIES: return maLineHlpLinear;
1195 case EXC_CHPROPMODE_FILLEDSERIES: return maLineHlpFilled;
1196 default: OSL_FAIL( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1198 return maLineHlpCommon;
1201 ScfPropSetHelper& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode )
1203 switch( ePropMode )
1205 case EXC_CHPROPMODE_COMMON: return maAreaHlpCommon;
1206 case EXC_CHPROPMODE_FILLEDSERIES: return maAreaHlpFilled;
1207 default: OSL_FAIL( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1209 return maAreaHlpCommon;
1212 ScfPropSetHelper& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode )
1214 switch( ePropMode )
1216 case EXC_CHPROPMODE_COMMON: return maGradHlpCommon;
1217 case EXC_CHPROPMODE_FILLEDSERIES: return maGradHlpFilled;
1218 default: OSL_FAIL( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1220 return maGradHlpCommon;
1223 ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode )
1225 switch( ePropMode )
1227 case EXC_CHPROPMODE_COMMON: return maHatchHlpCommon;
1228 case EXC_CHPROPMODE_FILLEDSERIES: return maHatchHlpFilled;
1229 default: OSL_FAIL( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1231 return maHatchHlpCommon;
1234 // ============================================================================
1236 namespace {
1238 /* The following local functions implement getting the XShape interface of all
1239 supported title objects (chart and axes). This needs some effort due to the
1240 design of the old Chart1 API used to access these objects. */
1242 /** A code fragment that returns a shape object from the passed shape supplier
1243 using the specified interface function. Checks a boolean property first. */
1244 #define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
1245 ScfPropertySet aPropSet( shape_supplier ); \
1246 if( shape_supplier.is() && aPropSet.GetBoolProperty( #property_name ) ) \
1247 return shape_supplier->supplier_func(); \
1248 return Reference< XShape >(); \
1250 /** Implements a function returning the drawing shape of an axis title, if
1251 existing, using the specified API interface and its function. */
1252 #define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
1253 Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
1255 Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
1256 EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
1259 /** Returns the drawing shape of the main title, if existing. */
1260 Reference< XShape > lclGetMainTitleShape( const Reference< cssc::XChartDocument >& rxChart1Doc )
1262 EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle )
1265 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle )
1266 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle )
1267 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle )
1268 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle )
1269 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle )
1271 #undef EXC_DEFINEFUNC_GETAXISTITLESHAPE
1272 #undef EXC_IMPLEMENT_GETTITLESHAPE
1274 } // namespace
1276 // ----------------------------------------------------------------------------
1278 XclChRootData::XclChRootData() :
1279 mxTypeInfoProv( new XclChTypeInfoProvider ),
1280 mxFmtInfoProv( new XclChFormatInfoProvider ),
1281 mnBorderGapX( 0 ),
1282 mnBorderGapY( 0 )
1284 // remember some title shape getter functions
1285 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ] = lclGetMainTitleShape;
1286 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_X ) ] = lclGetXAxisTitleShape;
1287 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Y ) ] = lclGetYAxisTitleShape;
1288 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Z ) ] = lclGetZAxisTitleShape;
1289 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_X ) ] = lclGetSecXAxisTitleShape;
1290 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_Y ) ] = lclGetSecYAxisTitleShape;
1293 XclChRootData::~XclChRootData()
1297 void XclChRootData::InitConversion( const XclRoot& rRoot, const Reference< XChartDocument >& rxChartDoc, const Rectangle& rChartRect )
1299 // remember chart document reference and chart shape position/size
1300 OSL_ENSURE( rxChartDoc.is(), "XclChRootData::InitConversion - missing chart document" );
1301 mxChartDoc = rxChartDoc;
1302 maChartRect = rChartRect;
1304 // Excel excludes a border of 5 pixels in each direction from chart area
1305 mnBorderGapX = rRoot.GetHmmFromPixelX( 5.0 );
1306 mnBorderGapY = rRoot.GetHmmFromPixelY( 5.0 );
1308 // size of a chart unit in 1/100 mm
1309 mfUnitSizeX = ::std::max< double >( maChartRect.GetWidth() - 2 * mnBorderGapX, mnBorderGapX ) / EXC_CHART_TOTALUNITS;
1310 mfUnitSizeY = ::std::max< double >( maChartRect.GetHeight() - 2 * mnBorderGapY, mnBorderGapY ) / EXC_CHART_TOTALUNITS;
1312 // create object tables
1313 Reference< XMultiServiceFactory > xFactory( mxChartDoc, UNO_QUERY );
1314 mxLineDashTable.reset( new XclChObjectTable(
1315 xFactory, SERVICE_DRAWING_DASHTABLE, "Excel line dash " ) );
1316 mxGradientTable.reset( new XclChObjectTable(
1317 xFactory, SERVICE_DRAWING_GRADIENTTABLE, "Excel gradient " ) );
1318 mxHatchTable.reset( new XclChObjectTable(
1319 xFactory, SERVICE_DRAWING_HATCHTABLE, "Excel hatch " ) );
1320 mxBitmapTable.reset( new XclChObjectTable(
1321 xFactory, SERVICE_DRAWING_BITMAPTABLE, "Excel bitmap " ) );
1324 void XclChRootData::FinishConversion()
1326 // forget formatting object tables
1327 mxBitmapTable.reset();
1328 mxHatchTable.reset();
1329 mxGradientTable.reset();
1330 mxLineDashTable.reset();
1331 // forget chart document reference
1332 mxChartDoc.clear();
1335 Reference< XShape > XclChRootData::GetTitleShape( const XclChTextKey& rTitleKey ) const
1337 XclChGetShapeFuncMap::const_iterator aIt = maGetShapeFuncs.find( rTitleKey );
1338 OSL_ENSURE( aIt != maGetShapeFuncs.end(), "XclChRootData::GetTitleShape - invalid title key" );
1339 Reference< cssc::XChartDocument > xChart1Doc( mxChartDoc, UNO_QUERY );
1340 Reference< XShape > xTitleShape;
1341 if( xChart1Doc.is() && (aIt != maGetShapeFuncs.end()) )
1342 xTitleShape = (aIt->second)( xChart1Doc );
1343 return xTitleShape;
1346 // ============================================================================
1348 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */