Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / filter / excel / xlchart.cxx
blob1daed0f0d31d7f1dc0d3ba89ece1ff50d69c0cd0
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 .
20 #include "xlchart.hxx"
22 #include <com/sun/star/container/XNameContainer.hpp>
23 #include <com/sun/star/awt/Size.hpp>
24 #include <com/sun/star/awt/Gradient.hpp>
25 #include <com/sun/star/drawing/Hatch.hpp>
26 #include <com/sun/star/drawing/LineDash.hpp>
27 #include <com/sun/star/drawing/LineStyle.hpp>
28 #include <com/sun/star/drawing/FillStyle.hpp>
29 #include <com/sun/star/drawing/BitmapMode.hpp>
30 #include <com/sun/star/chart/DataLabelPlacement.hpp>
31 #include <com/sun/star/chart/XAxisXSupplier.hpp>
32 #include <com/sun/star/chart/XAxisYSupplier.hpp>
33 #include <com/sun/star/chart/XAxisZSupplier.hpp>
34 #include <com/sun/star/chart/XChartDocument.hpp>
35 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
36 #include <com/sun/star/chart2/Symbol.hpp>
38 #include <sal/macros.h>
39 #include <rtl/math.hxx>
40 #include <svl/itemset.hxx>
41 #include <svx/xfillit0.hxx>
42 #include <svx/xflclit.hxx>
43 #include <svx/xfltrit.hxx>
44 #include <svx/xflgrit.hxx>
45 #include <svx/xbtmpit.hxx>
46 #include <svx/unomid.hxx>
47 #include <filter/msfilter/escherex.hxx>
48 #include <editeng/memberids.hrc>
49 #include "global.hxx"
50 #include "xlroot.hxx"
51 #include "xlstyle.hxx"
53 using namespace com::sun::star;
54 using ::com::sun::star::uno::Any;
55 using ::com::sun::star::uno::Reference;
56 using ::com::sun::star::uno::UNO_QUERY;
57 using ::com::sun::star::uno::Exception;
58 using ::com::sun::star::lang::XMultiServiceFactory;
59 using ::com::sun::star::chart2::XChartDocument;
60 using ::com::sun::star::drawing::XShape;
62 namespace cssc = ::com::sun::star::chart;
64 // Common =====================================================================
66 XclChRectangle::XclChRectangle() :
67 mnX( 0 ),
68 mnY( 0 ),
69 mnWidth( 0 ),
70 mnHeight( 0 )
74 XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx, sal_uInt16 nPointIdx ) :
75 mnSeriesIdx( nSeriesIdx ),
76 mnPointIdx( nPointIdx )
80 bool operator<( const XclChDataPointPos& rL, const XclChDataPointPos& rR )
82 return (rL.mnSeriesIdx < rR.mnSeriesIdx) ||
83 ((rL.mnSeriesIdx == rR.mnSeriesIdx) && (rL.mnPointIdx < rR.mnPointIdx));
86 XclChFrBlock::XclChFrBlock( sal_uInt16 nType ) :
87 mnType( nType ),
88 mnContext( 0 ),
89 mnValue1( 0 ),
90 mnValue2( 0 )
94 // Frame formatting ===========================================================
96 XclChFramePos::XclChFramePos() :
97 mnTLMode( EXC_CHFRAMEPOS_PARENT ),
98 mnBRMode( EXC_CHFRAMEPOS_PARENT )
102 XclChLineFormat::XclChLineFormat() :
103 maColor( COL_BLACK ),
104 mnPattern( EXC_CHLINEFORMAT_SOLID ),
105 mnWeight( EXC_CHLINEFORMAT_SINGLE ),
106 mnFlags( EXC_CHLINEFORMAT_AUTO )
110 XclChAreaFormat::XclChAreaFormat() :
111 maPattColor( COL_WHITE ),
112 maBackColor( COL_BLACK ),
113 mnPattern( EXC_PATT_SOLID ),
114 mnFlags( EXC_CHAREAFORMAT_AUTO )
118 XclChEscherFormat::XclChEscherFormat()
122 XclChEscherFormat::~XclChEscherFormat()
126 XclChPicFormat::XclChPicFormat() :
127 mnBmpMode( EXC_CHPICFORMAT_NONE ),
128 mnFlags( EXC_CHPICFORMAT_TOPBOTTOM | EXC_CHPICFORMAT_FRONTBACK | EXC_CHPICFORMAT_LEFTRIGHT ),
129 mfScale( 0.5 )
133 XclChFrame::XclChFrame() :
134 mnFormat( EXC_CHFRAME_STANDARD ),
135 mnFlags( EXC_CHFRAME_AUTOSIZE | EXC_CHFRAME_AUTOPOS )
139 // Source links ===============================================================
141 XclChSourceLink::XclChSourceLink() :
142 mnDestType( EXC_CHSRCLINK_TITLE ),
143 mnLinkType( EXC_CHSRCLINK_DEFAULT ),
144 mnFlags( 0 ),
145 mnNumFmtIdx( 0 )
149 // Text =======================================================================
151 XclChObjectLink::XclChObjectLink() :
152 mnTarget( EXC_CHOBJLINK_NONE )
156 XclChFrLabelProps::XclChFrLabelProps() :
157 mnFlags( 0 )
161 XclChText::XclChText() :
162 maTextColor( COL_BLACK ),
163 mnHAlign( EXC_CHTEXT_ALIGN_CENTER ),
164 mnVAlign( EXC_CHTEXT_ALIGN_CENTER ),
165 mnBackMode( EXC_CHTEXT_TRANSPARENT ),
166 mnFlags( EXC_CHTEXT_AUTOCOLOR | EXC_CHTEXT_AUTOFILL ),
167 mnFlags2( EXC_CHTEXT_POS_DEFAULT ),
168 mnRotation( EXC_ROT_NONE )
172 // Data series ================================================================
174 XclChMarkerFormat::XclChMarkerFormat() :
175 maLineColor( COL_BLACK ),
176 maFillColor( COL_WHITE ),
177 mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE ),
178 mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL ),
179 mnFlags( EXC_CHMARKERFORMAT_AUTO )
183 XclCh3dDataFormat::XclCh3dDataFormat() :
184 mnBase( EXC_CH3DDATAFORMAT_RECT ),
185 mnTop( EXC_CH3DDATAFORMAT_STRAIGHT )
189 XclChDataFormat::XclChDataFormat() :
190 mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT ),
191 mnFlags( 0 )
195 XclChSerTrendLine::XclChSerTrendLine() :
196 mfForecastFor( 0.0 ),
197 mfForecastBack( 0.0 ),
198 mnLineType( EXC_CHSERTREND_POLYNOMIAL ),
199 mnOrder( 1 ),
200 mnShowEquation( 0 ),
201 mnShowRSquared( 0 )
203 /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
204 there is no interception point. Cannot use ::rtl::math::setNan() here
205 cause it misses the sign bit. */
206 sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &mfIntercept );
207 pDouble->w32_parts.msw = pDouble->w32_parts.lsw = 0xFFFFFFFF;
210 XclChSerErrorBar::XclChSerErrorBar() :
211 mfValue( 0.0 ),
212 mnValueCount( 1 ),
213 mnBarType( EXC_CHSERERR_NONE ),
214 mnSourceType( EXC_CHSERERR_FIXED ),
215 mnLineEnd( EXC_CHSERERR_END_TSHAPE )
219 XclChSeries::XclChSeries() :
220 mnCategType( EXC_CHSERIES_NUMERIC ),
221 mnValueType( EXC_CHSERIES_NUMERIC ),
222 mnBubbleType( EXC_CHSERIES_NUMERIC ),
223 mnCategCount( 0 ),
224 mnValueCount( 0 ),
225 mnBubbleCount( 0 )
229 // Chart type groups ==========================================================
231 XclChType::XclChType() :
232 mnOverlap( 0 ),
233 mnGap( 150 ),
234 mnRotation( 0 ),
235 mnPieHole( 0 ),
236 mnBubbleSize( 100 ),
237 mnBubbleType( EXC_CHSCATTER_AREA ),
238 mnFlags( 0 )
242 XclChChart3d::XclChChart3d() :
243 mnRotation( 20 ),
244 mnElevation( 15 ),
245 mnEyeDist( 30 ),
246 mnRelHeight( 100 ),
247 mnRelDepth( 100 ),
248 mnDepthGap( 150 ),
249 mnFlags( EXC_CHCHART3D_AUTOHEIGHT )
253 XclChLegend::XclChLegend() :
254 mnDockMode( EXC_CHLEGEND_RIGHT ),
255 mnSpacing( EXC_CHLEGEND_MEDIUM ),
256 mnFlags( EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOSERIES |
257 EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY | EXC_CHLEGEND_STACKED )
261 XclChTypeGroup::XclChTypeGroup() :
262 mnFlags( 0 ),
263 mnGroupIdx( EXC_CHSERGROUP_NONE )
267 XclChProperties::XclChProperties() :
268 mnFlags( 0 ),
269 mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP )
273 // Axes =======================================================================
275 XclChLabelRange::XclChLabelRange() :
276 mnCross( 1 ),
277 mnLabelFreq( 1 ),
278 mnTickFreq( 1 ),
279 mnFlags( 0 )
283 XclChDateRange::XclChDateRange() :
284 mnMinDate( 0 ),
285 mnMaxDate( 0 ),
286 mnMajorStep( 0 ),
287 mnMajorUnit( EXC_CHDATERANGE_DAYS ),
288 mnMinorStep( 0 ),
289 mnMinorUnit( EXC_CHDATERANGE_DAYS ),
290 mnBaseUnit( EXC_CHDATERANGE_DAYS ),
291 mnCross( 0 ),
292 mnFlags( EXC_CHDATERANGE_AUTOMIN | EXC_CHDATERANGE_AUTOMAX |
293 EXC_CHDATERANGE_AUTOMAJOR | EXC_CHDATERANGE_AUTOMINOR |
294 EXC_CHDATERANGE_AUTOBASE | EXC_CHDATERANGE_AUTOCROSS |
295 EXC_CHDATERANGE_AUTODATE )
299 XclChValueRange::XclChValueRange() :
300 mfMin( 0.0 ),
301 mfMax( 0.0 ),
302 mfMajorStep( 0.0 ),
303 mfMinorStep( 0.0 ),
304 mfCross( 0.0 ),
305 mnFlags( EXC_CHVALUERANGE_AUTOMIN | EXC_CHVALUERANGE_AUTOMAX |
306 EXC_CHVALUERANGE_AUTOMAJOR | EXC_CHVALUERANGE_AUTOMINOR |
307 EXC_CHVALUERANGE_AUTOCROSS | EXC_CHVALUERANGE_BIT8 )
311 XclChTick::XclChTick() :
312 maTextColor( COL_BLACK ),
313 mnMajor( EXC_CHTICK_INSIDE | EXC_CHTICK_OUTSIDE ),
314 mnMinor( 0 ),
315 mnLabelPos( EXC_CHTICK_NEXT ),
316 mnBackMode( EXC_CHTICK_TRANSPARENT ),
317 mnFlags( EXC_CHTICK_AUTOCOLOR | EXC_CHTICK_AUTOROT ),
318 mnRotation( EXC_ROT_NONE )
322 XclChAxis::XclChAxis() :
323 mnType( EXC_CHAXIS_NONE )
327 sal_Int32 XclChAxis::GetApiAxisDimension() const
329 sal_Int32 nApiAxisDim = EXC_CHART_AXIS_NONE;
330 switch( mnType )
332 case EXC_CHAXIS_X: nApiAxisDim = EXC_CHART_AXIS_X; break;
333 case EXC_CHAXIS_Y: nApiAxisDim = EXC_CHART_AXIS_Y; break;
334 case EXC_CHAXIS_Z: nApiAxisDim = EXC_CHART_AXIS_Z; break;
336 return nApiAxisDim;
339 XclChAxesSet::XclChAxesSet() :
340 mnAxesSetId( EXC_CHAXESSET_PRIMARY )
344 sal_Int32 XclChAxesSet::GetApiAxesSetIndex() const
346 sal_Int32 nApiAxesSetIdx = EXC_CHART_AXESSET_NONE;
347 switch( mnAxesSetId )
349 case EXC_CHAXESSET_PRIMARY: nApiAxesSetIdx = EXC_CHART_AXESSET_PRIMARY; break;
350 case EXC_CHAXESSET_SECONDARY: nApiAxesSetIdx = EXC_CHART_AXESSET_SECONDARY; break;
352 return nApiAxesSetIdx;
355 // Static helper functions ====================================================
357 sal_uInt16 XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx )
359 static const sal_uInt16 spnLineColors[] =
361 32, 33, 34, 35, 36, 37, 38, 39,
362 40, 41, 42, 43, 44, 45, 46, 47,
363 48, 49, 50, 51, 52, 53, 54, 55,
364 56, 57, 58, 59, 60, 61, 62, 8,
365 9, 10, 11, 12, 13, 14, 15, 16,
366 17, 18, 19, 20, 21, 22, 23, 24,
367 25, 26, 27, 28, 29, 30, 31, 63
369 return spnLineColors[ nFormatIdx % SAL_N_ELEMENTS( spnLineColors ) ];
372 sal_uInt16 XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx )
374 static const sal_uInt16 spnFillColors[] =
376 24, 25, 26, 27, 28, 29, 30, 31,
377 32, 33, 34, 35, 36, 37, 38, 39,
378 40, 41, 42, 43, 44, 45, 46, 47,
379 48, 49, 50, 51, 52, 53, 54, 55,
380 56, 57, 58, 59, 60, 61, 62, 63,
381 8, 9, 10, 11, 12, 13, 14, 15,
382 16, 17, 18, 19, 20, 21, 22, 23
384 return spnFillColors[ nFormatIdx % SAL_N_ELEMENTS( spnFillColors ) ];
387 sal_uInt8 XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx )
389 static const sal_uInt8 spnTrans[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
390 return spnTrans[ (nFormatIdx / 56) % SAL_N_ELEMENTS( spnTrans ) ];
393 sal_uInt16 XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx )
395 static const sal_uInt16 spnSymbols[] = {
396 EXC_CHMARKERFORMAT_DIAMOND, EXC_CHMARKERFORMAT_SQUARE, EXC_CHMARKERFORMAT_TRIANGLE,
397 EXC_CHMARKERFORMAT_CROSS, EXC_CHMARKERFORMAT_STAR, EXC_CHMARKERFORMAT_CIRCLE,
398 EXC_CHMARKERFORMAT_PLUS, EXC_CHMARKERFORMAT_DOWJ, EXC_CHMARKERFORMAT_STDDEV };
399 return spnSymbols[ nFormatIdx % SAL_N_ELEMENTS( spnSymbols ) ];
402 bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType )
404 static const bool spbFilled[] = {
405 false, true, true, true, false, false, false, false, true, false };
406 return (nMarkerType < SAL_N_ELEMENTS( spbFilled )) && spbFilled[ nMarkerType ];
409 OUString XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType )
411 switch( nBarType )
413 case EXC_CHSERERR_XPLUS: return OUString( EXC_CHPROP_ROLE_ERRORBARS_POSX );
414 case EXC_CHSERERR_XMINUS: return OUString( EXC_CHPROP_ROLE_ERRORBARS_NEGX );
415 case EXC_CHSERERR_YPLUS: return OUString( EXC_CHPROP_ROLE_ERRORBARS_POSY );
416 case EXC_CHSERERR_YMINUS: return OUString( EXC_CHPROP_ROLE_ERRORBARS_NEGY );
417 default: OSL_FAIL( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
419 return OUString();
422 // Chart formatting info provider =============================================
424 namespace {
426 static const XclChFormatInfo spFmtInfos[] =
428 // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
429 { EXC_CHOBJTYPE_BACKGROUND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
430 { EXC_CHOBJTYPE_PLOTFRAME, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
431 { EXC_CHOBJTYPE_WALL3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, false, true },
432 { EXC_CHOBJTYPE_FLOOR3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, 23, EXC_CHFRAMETYPE_AUTO, true, false, true },
433 { EXC_CHOBJTYPE_TEXT, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, true },
434 { EXC_CHOBJTYPE_LEGEND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, true, true },
435 { EXC_CHOBJTYPE_LINEARSERIES, EXC_CHPROPMODE_LINEARSERIES, 0xFFFF, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
436 { EXC_CHOBJTYPE_FILLEDSERIES, EXC_CHPROPMODE_FILLEDSERIES, EXC_COLOR_CHBORDERAUTO, EXC_CHLINEFORMAT_SINGLE, 0xFFFF, EXC_CHFRAMETYPE_AUTO, false, false, true },
437 { EXC_CHOBJTYPE_AXISLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
438 { EXC_CHOBJTYPE_GRIDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, false },
439 { EXC_CHOBJTYPE_TRENDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_DOUBLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
440 { EXC_CHOBJTYPE_ERRORBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
441 { EXC_CHOBJTYPE_CONNECTLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
442 { EXC_CHOBJTYPE_HILOLINE, EXC_CHPROPMODE_LINEARSERIES, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
443 { EXC_CHOBJTYPE_WHITEDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, true },
444 { EXC_CHOBJTYPE_BLACKDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWTEXT, EXC_CHFRAMETYPE_INVISIBLE, false, false, true }
449 XclChFormatInfoProvider::XclChFormatInfoProvider()
451 for(auto const &rIt : spFmtInfos)
452 maInfoMap[ rIt.meObjType ] = &rIt;
455 const XclChFormatInfo& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType ) const
457 XclFmtInfoMap::const_iterator aIt = maInfoMap.find( eObjType );
458 OSL_ENSURE( aIt != maInfoMap.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
459 return (aIt == maInfoMap.end()) ? *spFmtInfos : *aIt->second;
462 // Chart type info provider ===================================================
464 namespace {
466 // chart type service names
467 const sal_Char SERVICE_CHART2_AREA[] = "com.sun.star.chart2.AreaChartType";
468 const sal_Char SERVICE_CHART2_CANDLE[] = "com.sun.star.chart2.CandleStickChartType";
469 const sal_Char SERVICE_CHART2_COLUMN[] = "com.sun.star.chart2.ColumnChartType";
470 const sal_Char SERVICE_CHART2_LINE[] = "com.sun.star.chart2.LineChartType";
471 const sal_Char SERVICE_CHART2_NET[] = "com.sun.star.chart2.NetChartType";
472 const sal_Char SERVICE_CHART2_FILLEDNET[] = "com.sun.star.chart2.FilledNetChartType";
473 const sal_Char SERVICE_CHART2_PIE[] = "com.sun.star.chart2.PieChartType";
474 const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType";
475 const sal_Char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType";
476 const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
478 namespace csscd = cssc::DataLabelPlacement;
480 static const XclChTypeInfo spTypeInfos[] =
482 // 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
483 { 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 },
484 { 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 },
485 { 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 },
486 { 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 },
487 { 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 },
488 { 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 },
489 { 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 },
490 { 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 },
491 { 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 },
492 { 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 },
493 { 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 },
494 { 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 },
495 { 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 },
496 { 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 }
499 } // namespace
501 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo ) :
502 XclChTypeInfo( rTypeInfo ),
503 mb3dChart( false ),
504 mbSpline( false )
508 void XclChExtTypeInfo::Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline )
510 static_cast< XclChTypeInfo& >( *this ) = rTypeInfo;
511 mb3dChart = mbSupports3d && b3dChart;
512 mbSpline = bSpline;
515 XclChTypeInfoProvider::XclChTypeInfoProvider()
517 for(const auto &rIt : spTypeInfos)
518 maInfoMap[ rIt.meTypeId ] = &rIt;
521 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId ) const
523 XclChTypeInfoMap::const_iterator aIt = maInfoMap.find( eTypeId );
524 OSL_ENSURE( aIt != maInfoMap.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
525 return (aIt == maInfoMap.end()) ? *maInfoMap.rbegin()->second : *aIt->second;
528 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId ) const
530 for(const auto &rIt : spTypeInfos)
532 if(rIt.mnRecId == nRecId)
533 return rIt;
535 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
536 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
539 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString& rServiceName ) const
541 for(auto const &rIt : spTypeInfos)
542 if( rServiceName.equalsAscii( rIt.mpcServiceName ) )
543 return rIt;
544 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
545 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
548 // Property helpers ===========================================================
550 XclChObjectTable::XclChObjectTable( Reference< XMultiServiceFactory > xFactory,
551 const OUString& rServiceName, const OUString& rObjNameBase ) :
552 mxFactory( xFactory ),
553 maServiceName( rServiceName ),
554 maObjNameBase( rObjNameBase ),
555 mnIndex( 0 )
559 Any XclChObjectTable::GetObject( const OUString& rObjName )
561 // get object table
562 if( !mxContainer.is() )
563 mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
564 OSL_ENSURE( mxContainer.is(), "XclChObjectTable::GetObject - container not found" );
566 Any aObj;
567 if( mxContainer.is() )
569 // get object from container
572 aObj = mxContainer->getByName( rObjName );
574 catch( Exception& )
576 OSL_FAIL( "XclChObjectTable::GetObject - object not found" );
579 return aObj;
582 OUString XclChObjectTable::InsertObject( const Any& rObj )
585 // create object table
586 if( !mxContainer.is() )
587 mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY );
588 OSL_ENSURE( mxContainer.is(), "XclChObjectTable::InsertObject - container not found" );
590 OUString aObjName;
591 if( mxContainer.is() )
593 // create new unused identifier
596 aObjName = maObjNameBase + OUString::number( ++mnIndex );
598 while( mxContainer->hasByName( aObjName ) );
600 // insert object
603 mxContainer->insertByName( aObjName, rObj );
605 catch( Exception& )
607 OSL_FAIL( "XclChObjectTable::InsertObject - cannot insert object" );
608 aObjName.clear();
611 return aObjName;
614 // Property names -------------------------------------------------------------
616 namespace {
618 /** Property names for line style in common objects. */
619 const sal_Char* const sppcLineNamesCommon[] =
620 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", nullptr };
621 /** Property names for line style in linear series objects. */
622 const sal_Char* const sppcLineNamesLinear[] =
623 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", nullptr };
624 /** Property names for line style in filled series objects. */
625 const sal_Char* const sppcLineNamesFilled[] =
626 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", nullptr };
628 /** Property names for solid area style in common objects. */
629 const sal_Char* const sppcAreaNamesCommon[] = { "FillStyle", "FillColor", "FillTransparence", nullptr };
630 /** Property names for solid area style in filled series objects. */
631 const sal_Char* const sppcAreaNamesFilled[] = { "FillStyle", "Color", "Transparency", nullptr };
632 /** Property names for gradient area style in common objects. */
633 const sal_Char* const sppcGradNamesCommon[] = { "FillStyle", "FillGradientName", nullptr };
634 /** Property names for gradient area style in filled series objects. */
635 const sal_Char* const sppcGradNamesFilled[] = { "FillStyle", "GradientName", nullptr };
636 /** Property names for hatch area style in common objects. */
637 const sal_Char* const sppcHatchNamesCommon[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", nullptr };
638 /** Property names for hatch area style in filled series objects. */
639 const sal_Char* const sppcHatchNamesFilled[] = { "FillStyle", "HatchName", "Color", "FillBackground", nullptr };
640 /** Property names for bitmap area style. */
641 const sal_Char* const sppcBitmapNames[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", nullptr };
643 } // namespace
645 XclChPropSetHelper::XclChPropSetHelper() :
646 maLineHlpCommon( sppcLineNamesCommon ),
647 maLineHlpLinear( sppcLineNamesLinear ),
648 maLineHlpFilled( sppcLineNamesFilled ),
649 maAreaHlpCommon( sppcAreaNamesCommon ),
650 maAreaHlpFilled( sppcAreaNamesFilled ),
651 maGradHlpCommon( sppcGradNamesCommon ),
652 maGradHlpFilled( sppcGradNamesFilled ),
653 maHatchHlpCommon( sppcHatchNamesCommon ),
654 maHatchHlpFilled( sppcHatchNamesFilled ),
655 maBitmapHlp( sppcBitmapNames )
659 // read properties ------------------------------------------------------------
661 void XclChPropSetHelper::ReadLineProperties(
662 XclChLineFormat& rLineFmt, XclChObjectTable& rDashTable,
663 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
665 namespace cssd = ::com::sun::star::drawing;
667 // read properties from property set
668 cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
669 sal_Int32 nApiWidth = 0;
670 sal_Int16 nApiTrans = 0;
671 Any aDashNameAny;
673 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
674 rLineHlp.ReadFromPropertySet( rPropSet );
675 rLineHlp >> eApiStyle >> nApiWidth >> rLineFmt.maColor >> nApiTrans >> aDashNameAny;
677 // clear automatic flag
678 ::set_flag( rLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
680 // line width
681 if( nApiWidth <= 0 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
682 else if( nApiWidth <= 35 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE;
683 else if( nApiWidth <= 70 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE;
684 else rLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE;
686 // line style
687 switch( eApiStyle )
689 case cssd::LineStyle_NONE:
690 rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
691 break;
692 case cssd::LineStyle_SOLID:
694 if( nApiTrans < 13 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
695 else if( nApiTrans < 38 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS;
696 else if( nApiTrans < 63 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS;
697 else if( nApiTrans < 100 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS;
698 else rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
700 break;
701 case cssd::LineStyle_DASH:
703 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
704 OUString aDashName;
705 cssd::LineDash aApiDash;
706 if( (aDashNameAny >>= aDashName) && (rDashTable.GetObject( aDashName ) >>= aApiDash) )
708 // reorder dashes that are shorter than dots
709 if( (aApiDash.Dashes == 0) || (aApiDash.DashLen < aApiDash.DotLen) )
711 ::std::swap( aApiDash.Dashes, aApiDash.Dots );
712 ::std::swap( aApiDash.DashLen, aApiDash.DotLen );
714 // ignore dots that are nearly equal to dashes
715 if( aApiDash.DotLen * 3 > aApiDash.DashLen * 2 )
716 aApiDash.Dots = 0;
718 // convert line dash to predefined Excel dash types
719 if( (aApiDash.Dashes == 1) && (aApiDash.Dots >= 1) )
720 // one dash and one or more dots
721 rLineFmt.mnPattern = (aApiDash.Dots == 1) ?
722 EXC_CHLINEFORMAT_DASHDOT : EXC_CHLINEFORMAT_DASHDOTDOT;
723 else if( aApiDash.Dashes >= 1 )
724 // one or more dashes and no dots (also: dash-dash-dot)
725 rLineFmt.mnPattern = (aApiDash.DashLen < 250) ?
726 EXC_CHLINEFORMAT_DOT : EXC_CHLINEFORMAT_DASH;
729 break;
730 default:
731 OSL_FAIL( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
732 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
736 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat& rAreaFmt,
737 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
739 namespace cssd = ::com::sun::star::drawing;
741 // read properties from property set
742 cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
743 sal_Int16 nTransparency = 0;
745 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
746 rAreaHlp.ReadFromPropertySet( rPropSet );
747 rAreaHlp >> eApiStyle >> rAreaFmt.maPattColor >> nTransparency;
749 // clear automatic flag
750 ::set_flag( rAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
752 // set fill style transparent or solid (set solid for anything but transparent)
753 rAreaFmt.mnPattern = (eApiStyle == cssd::FillStyle_NONE) ? EXC_PATT_NONE : EXC_PATT_SOLID;
755 // return true to indicate complex fill (gradient, bitmap, solid transparency)
756 return (eApiStyle != cssd::FillStyle_NONE) && ((eApiStyle != cssd::FillStyle_SOLID) || (nTransparency > 0));
759 void XclChPropSetHelper::ReadEscherProperties(
760 XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
761 XclChObjectTable& rGradientTable, XclChObjectTable& rHatchTable, XclChObjectTable& rBitmapTable,
762 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
764 namespace cssd = ::com::sun::star::drawing;
765 namespace cssa = ::com::sun::star::awt;
767 // read style and transparency properties from property set
768 cssd::FillStyle eApiStyle = cssd::FillStyle_NONE;
769 Color aColor;
770 sal_Int16 nTransparency = 0;
772 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
773 rAreaHlp.ReadFromPropertySet( rPropSet );
774 rAreaHlp >> eApiStyle >> aColor >> nTransparency;
776 switch( eApiStyle )
778 case cssd::FillStyle_SOLID:
780 OSL_ENSURE( nTransparency > 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
781 if( (0 < nTransparency) && (nTransparency <= 100) )
783 // convert to Escher properties
784 sal_uInt32 nEscherColor = 0x02000000;
785 ::insert_value( nEscherColor, aColor.GetBlue(), 16, 8 );
786 ::insert_value( nEscherColor, aColor.GetGreen(), 8, 8 );
787 ::insert_value( nEscherColor, aColor.GetRed(), 0, 8 );
788 sal_uInt32 nEscherOpacity = static_cast< sal_uInt32 >( (100 - nTransparency) * 655.36 );
789 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
790 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
791 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, nEscherColor );
792 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillOpacity, nEscherOpacity );
793 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x02FFFFFF );
794 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackOpacity, 0x00010000 );
795 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fNoFillHitTest, 0x001F001C );
798 break;
799 case cssd::FillStyle_GRADIENT:
801 // extract gradient from global gradient table
802 OUString aGradientName;
803 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
804 rGradHlp.ReadFromPropertySet( rPropSet );
805 rGradHlp >> eApiStyle >> aGradientName;
806 cssa::Gradient aGradient;
807 if( rGradientTable.GetObject( aGradientName ) >>= aGradient )
809 // convert to Escher properties
810 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
811 rEscherFmt.mxEscherSet->CreateGradientProperties( aGradient );
814 break;
815 case cssd::FillStyle_HATCH:
817 // extract hatch from global hatch table
818 OUString aHatchName;
819 bool bFillBackground;
820 ScfPropSetHelper& rHatchHlp = GetHatchHelper( ePropMode );
821 rHatchHlp.ReadFromPropertySet( rPropSet );
822 rHatchHlp >> eApiStyle >> aHatchName >> aColor >> bFillBackground;
823 cssd::Hatch aHatch;
824 if( rHatchTable.GetObject( aHatchName ) >>= aHatch )
826 // convert to Escher properties
827 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
828 rEscherFmt.mxEscherSet->CreateEmbeddedHatchProperties( aHatch, aColor, bFillBackground );
829 rPicFmt.mnBmpMode = EXC_CHPICFORMAT_STACK;
832 break;
833 case cssd::FillStyle_BITMAP:
835 // extract bitmap URL from global bitmap table
836 OUString aBitmapName;
837 cssd::BitmapMode eApiBmpMode;
838 maBitmapHlp.ReadFromPropertySet( rPropSet );
839 maBitmapHlp >> eApiStyle >> aBitmapName >> eApiBmpMode;
840 OUString aBitmapUrl;
841 if( rBitmapTable.GetObject( aBitmapName ) >>= aBitmapUrl )
843 // convert to Escher properties
844 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
845 rEscherFmt.mxEscherSet->CreateEmbeddedBitmapProperties( aBitmapUrl, eApiBmpMode );
846 rPicFmt.mnBmpMode = (eApiBmpMode == cssd::BitmapMode_REPEAT) ?
847 EXC_CHPICFORMAT_STACK : EXC_CHPICFORMAT_STRETCH;
850 break;
851 default:
852 OSL_FAIL( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
856 void XclChPropSetHelper::ReadMarkerProperties(
857 XclChMarkerFormat& rMarkerFmt, const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
859 namespace cssc = ::com::sun::star::chart2;
860 cssc::Symbol aApiSymbol;
861 if( rPropSet.GetProperty( aApiSymbol, EXC_CHPROP_SYMBOL ) )
863 // clear automatic flag
864 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
866 // symbol style
867 switch( aApiSymbol.Style )
869 case cssc::SymbolStyle_NONE:
870 rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
871 break;
872 case cssc::SymbolStyle_STANDARD:
873 switch( aApiSymbol.StandardSymbol )
875 case 0: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_SQUARE; break; // square
876 case 1: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // diamond
877 case 2: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // arrow down
878 case 3: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_TRIANGLE; break; // arrow up
879 case 4: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DOWJ; break; // arrow right, same as import
880 case 5: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // arrow left
881 case 6: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // bow tie
882 case 7: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // sand glass
883 case 8: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CIRCLE; break; // circle new in LibO3.5
884 case 9: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // star new in LibO3.5
885 case 10: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // X new in LibO3.5
886 case 11: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // plus new in LibO3.5
887 case 12: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // asterisk new in LibO3.5
888 case 13: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // horizontal bar new in LibO3.5
889 case 14: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // vertical bar new in LibO3.5
890 default: rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
892 break;
893 default:
894 rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
896 bool bHasFillColor = XclChartHelper::HasMarkerFillColor( rMarkerFmt.mnMarkerType );
897 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOFILL, !bHasFillColor );
899 // symbol size
900 sal_Int32 nApiSize = (aApiSymbol.Size.Width + aApiSymbol.Size.Height + 1) / 2;
901 rMarkerFmt.mnMarkerSize = XclTools::GetTwipsFromHmm( nApiSize );
903 // symbol colors
904 rMarkerFmt.maLineColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.BorderColor );
905 rMarkerFmt.maFillColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.FillColor );
909 sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPropSet, bool bSupportsStacked )
911 // chart2 handles rotation as double in the range [0,360)
912 double fAngle = 0.0;
913 rPropSet.GetProperty( fAngle, EXC_CHPROP_TEXTROTATION );
914 bool bStacked = bSupportsStacked && rPropSet.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS );
915 return bStacked ? EXC_ROT_STACKED :
916 XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) );
919 // write properties -----------------------------------------------------------
921 void XclChPropSetHelper::WriteLineProperties(
922 ScfPropertySet& rPropSet, XclChObjectTable& rDashTable,
923 const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode )
925 namespace cssd = ::com::sun::star::drawing;
927 // line width
928 sal_Int32 nApiWidth = 0; // 0 is the width of a hair line
929 switch( rLineFmt.mnWeight )
931 case EXC_CHLINEFORMAT_SINGLE: nApiWidth = 35; break;
932 case EXC_CHLINEFORMAT_DOUBLE: nApiWidth = 70; break;
933 case EXC_CHLINEFORMAT_TRIPLE: nApiWidth = 105; break;
936 // line style
937 cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
938 sal_Int16 nApiTrans = 0;
939 sal_Int32 nDotLen = ::std::min< sal_Int32 >( rLineFmt.mnWeight + 105, 210 );
940 cssd::LineDash aApiDash( cssd::DashStyle_RECT, 0, nDotLen, 0, 4 * nDotLen, nDotLen );
942 switch( rLineFmt.mnPattern )
944 case EXC_CHLINEFORMAT_SOLID:
945 eApiStyle = cssd::LineStyle_SOLID;
946 break;
947 case EXC_CHLINEFORMAT_DARKTRANS:
948 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 25;
949 break;
950 case EXC_CHLINEFORMAT_MEDTRANS:
951 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 50;
952 break;
953 case EXC_CHLINEFORMAT_LIGHTTRANS:
954 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 75;
955 break;
956 case EXC_CHLINEFORMAT_DASH:
957 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1;
958 break;
959 case EXC_CHLINEFORMAT_DOT:
960 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dots = 1;
961 break;
962 case EXC_CHLINEFORMAT_DASHDOT:
963 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = aApiDash.Dots = 1;
964 break;
965 case EXC_CHLINEFORMAT_DASHDOTDOT:
966 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1; aApiDash.Dots = 2;
967 break;
970 // line color
971 sal_Int32 nApiColor = ScfApiHelper::ConvertToApiColor( rLineFmt.maColor );
973 // try to insert the dash style and receive its name
974 Any aDashNameAny;
975 if( eApiStyle == cssd::LineStyle_DASH )
977 OUString aDashName = rDashTable.InsertObject( css::uno::makeAny( aApiDash ) );
978 if( !aDashName.isEmpty() )
979 aDashNameAny <<= aDashName;
982 // write the properties
983 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
984 rLineHlp.InitializeWrite();
985 rLineHlp << eApiStyle << nApiWidth << nApiColor << nApiTrans << aDashNameAny;
986 rLineHlp.WriteToPropertySet( rPropSet );
989 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet& rPropSet,
990 const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode )
992 namespace cssd = ::com::sun::star::drawing;
993 cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
994 Color aColor;
995 sal_Int16 nTransparency = 0;
997 // fill color
998 if( rAreaFmt.mnPattern != EXC_PATT_NONE )
1000 eFillStyle = cssd::FillStyle_SOLID;
1001 aColor = XclTools::GetPatternColor( rAreaFmt.maPattColor, rAreaFmt.maBackColor, rAreaFmt.mnPattern );
1004 // write the properties
1005 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
1006 rAreaHlp.InitializeWrite();
1007 rAreaHlp << eFillStyle << aColor << nTransparency;
1008 rAreaHlp.WriteToPropertySet( rPropSet );
1011 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet,
1012 XclChObjectTable& rGradientTable, XclChObjectTable& /*rHatchTable*/, XclChObjectTable& rBitmapTable,
1013 const XclChEscherFormat& rEscherFmt, const XclChPicFormat* pPicFmt,
1014 sal_uInt32 nDffFillType, XclChPropertyMode ePropMode )
1016 if( rEscherFmt.mxItemSet )
1018 if( const XFillStyleItem* pStyleItem = static_cast< const XFillStyleItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLSTYLE, false ) ) )
1020 switch( pStyleItem->GetValue() )
1022 case drawing::FillStyle_SOLID:
1023 // #i84812# Excel 2007 writes Escher properties for solid fill
1024 if( const XFillColorItem* pColorItem = static_cast< const XFillColorItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLCOLOR, false ) ) )
1026 namespace cssd = ::com::sun::star::drawing;
1027 // get solid transparence too
1028 const XFillTransparenceItem* pTranspItem = static_cast< const XFillTransparenceItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLTRANSPARENCE, false ) );
1029 sal_uInt16 nTransp = pTranspItem ? pTranspItem->GetValue() : 0;
1030 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
1031 rAreaHlp.InitializeWrite();
1032 rAreaHlp << cssd::FillStyle_SOLID << pColorItem->GetColorValue() << static_cast< sal_Int16 >( nTransp );
1033 rAreaHlp.WriteToPropertySet( rPropSet );
1035 break;
1036 case drawing::FillStyle_GRADIENT:
1037 if( const XFillGradientItem* pGradItem = static_cast< const XFillGradientItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLGRADIENT, false ) ) )
1039 Any aGradientAny;
1040 if( pGradItem->QueryValue( aGradientAny, MID_FILLGRADIENT ) )
1042 OUString aGradName = rGradientTable.InsertObject( aGradientAny );
1043 if( !aGradName.isEmpty() )
1045 namespace cssd = ::com::sun::star::drawing;
1046 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
1047 rGradHlp.InitializeWrite();
1048 rGradHlp << cssd::FillStyle_GRADIENT << aGradName;
1049 rGradHlp.WriteToPropertySet( rPropSet );
1053 break;
1054 case drawing::FillStyle_BITMAP:
1055 if( const XFillBitmapItem* pBmpItem = static_cast< const XFillBitmapItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLBITMAP, false ) ) )
1057 Any aBitmapAny;
1058 if( pBmpItem->QueryValue( aBitmapAny, MID_GRAFURL ) )
1060 OUString aBmpName = rBitmapTable.InsertObject( aBitmapAny );
1061 if( !aBmpName.isEmpty() )
1063 namespace cssd = ::com::sun::star::drawing;
1064 /* #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode.
1065 If not passed, detect fill mode from the DFF property 'fill-type'. */
1066 bool bStretch = pPicFmt ? (pPicFmt->mnBmpMode == EXC_CHPICFORMAT_STRETCH) : (nDffFillType == mso_fillPicture);
1067 cssd::BitmapMode eApiBmpMode = bStretch ? cssd::BitmapMode_STRETCH : cssd::BitmapMode_REPEAT;
1068 maBitmapHlp.InitializeWrite();
1069 maBitmapHlp << cssd::FillStyle_BITMAP << aBmpName << eApiBmpMode;
1070 maBitmapHlp.WriteToPropertySet( rPropSet );
1074 break;
1075 default:
1076 OSL_FAIL( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1082 void XclChPropSetHelper::WriteMarkerProperties(
1083 ScfPropertySet& rPropSet, const XclChMarkerFormat& rMarkerFmt )
1085 namespace cssc = ::com::sun::star::chart2;
1086 namespace cssa = ::com::sun::star::awt;
1088 // symbol style
1089 cssc::Symbol aApiSymbol;
1090 aApiSymbol.Style = cssc::SymbolStyle_STANDARD;
1091 switch( rMarkerFmt.mnMarkerType )
1093 case EXC_CHMARKERFORMAT_NOSYMBOL: aApiSymbol.Style = cssc::SymbolStyle_NONE; break;
1094 case EXC_CHMARKERFORMAT_SQUARE: aApiSymbol.StandardSymbol = 0; break; // square
1095 case EXC_CHMARKERFORMAT_DIAMOND: aApiSymbol.StandardSymbol = 1; break; // diamond
1096 case EXC_CHMARKERFORMAT_TRIANGLE: aApiSymbol.StandardSymbol = 3; break; // arrow up
1097 case EXC_CHMARKERFORMAT_CROSS: aApiSymbol.StandardSymbol = 10; break; // X, legacy bow tie
1098 case EXC_CHMARKERFORMAT_STAR: aApiSymbol.StandardSymbol = 12; break; // asterisk, legacy sand glass
1099 case EXC_CHMARKERFORMAT_DOWJ: aApiSymbol.StandardSymbol = 4; break; // arrow right, same as export
1100 case EXC_CHMARKERFORMAT_STDDEV: aApiSymbol.StandardSymbol = 13; break; // horizontal bar, legacy arrow down
1101 case EXC_CHMARKERFORMAT_CIRCLE: aApiSymbol.StandardSymbol = 8; break; // circle, legacy arrow right
1102 case EXC_CHMARKERFORMAT_PLUS: aApiSymbol.StandardSymbol = 11; break; // plus, legacy arrow left
1103 default: break;
1106 // symbol size
1107 sal_Int32 nApiSize = XclTools::GetHmmFromTwips( rMarkerFmt.mnMarkerSize );
1108 aApiSymbol.Size = cssa::Size( nApiSize, nApiSize );
1110 // symbol colors
1111 aApiSymbol.FillColor = ScfApiHelper::ConvertToApiColor( rMarkerFmt.maFillColor );
1112 aApiSymbol.BorderColor = ::get_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOLINE ) ?
1113 aApiSymbol.FillColor : ScfApiHelper::ConvertToApiColor( rMarkerFmt.maLineColor );
1115 // set the property
1116 rPropSet.SetProperty( EXC_CHPROP_SYMBOL, aApiSymbol );
1119 void XclChPropSetHelper::WriteRotationProperties(
1120 ScfPropertySet& rPropSet, sal_uInt16 nRotation, bool bSupportsStacked )
1122 if( nRotation != EXC_CHART_AUTOROTATION )
1124 // chart2 handles rotation as double in the range [0,360)
1125 double fAngle = XclTools::GetScRotation( nRotation, 0 ) / 100.0;
1126 rPropSet.SetProperty( EXC_CHPROP_TEXTROTATION, fAngle );
1127 if( bSupportsStacked )
1128 rPropSet.SetProperty( EXC_CHPROP_STACKCHARACTERS, nRotation == EXC_ROT_STACKED );
1132 // private --------------------------------------------------------------------
1134 ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode )
1136 switch( ePropMode )
1138 case EXC_CHPROPMODE_COMMON: return maLineHlpCommon;
1139 case EXC_CHPROPMODE_LINEARSERIES: return maLineHlpLinear;
1140 case EXC_CHPROPMODE_FILLEDSERIES: return maLineHlpFilled;
1141 default: OSL_FAIL( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1143 return maLineHlpCommon;
1146 ScfPropSetHelper& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode )
1148 switch( ePropMode )
1150 case EXC_CHPROPMODE_COMMON: return maAreaHlpCommon;
1151 case EXC_CHPROPMODE_FILLEDSERIES: return maAreaHlpFilled;
1152 default: OSL_FAIL( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1154 return maAreaHlpCommon;
1157 ScfPropSetHelper& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode )
1159 switch( ePropMode )
1161 case EXC_CHPROPMODE_COMMON: return maGradHlpCommon;
1162 case EXC_CHPROPMODE_FILLEDSERIES: return maGradHlpFilled;
1163 default: OSL_FAIL( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1165 return maGradHlpCommon;
1168 ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode )
1170 switch( ePropMode )
1172 case EXC_CHPROPMODE_COMMON: return maHatchHlpCommon;
1173 case EXC_CHPROPMODE_FILLEDSERIES: return maHatchHlpFilled;
1174 default: OSL_FAIL( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1176 return maHatchHlpCommon;
1179 namespace {
1181 /* The following local functions implement getting the XShape interface of all
1182 supported title objects (chart and axes). This needs some effort due to the
1183 design of the old Chart1 API used to access these objects. */
1185 /** A code fragment that returns a shape object from the passed shape supplier
1186 using the specified interface function. Checks a boolean property first. */
1187 #define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
1188 ScfPropertySet aPropSet( shape_supplier ); \
1189 if( shape_supplier.is() && aPropSet.GetBoolProperty( #property_name ) ) \
1190 return shape_supplier->supplier_func(); \
1191 return Reference< XShape >(); \
1193 /** Implements a function returning the drawing shape of an axis title, if
1194 existing, using the specified API interface and its function. */
1195 #define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
1196 Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
1198 Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
1199 EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
1202 /** Returns the drawing shape of the main title, if existing. */
1203 Reference< XShape > lclGetMainTitleShape( const Reference< cssc::XChartDocument >& rxChart1Doc )
1205 EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle )
1208 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle )
1209 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle )
1210 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle )
1211 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle )
1212 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle )
1214 #undef EXC_DEFINEFUNC_GETAXISTITLESHAPE
1215 #undef EXC_IMPLEMENT_GETTITLESHAPE
1217 } // namespace
1219 XclChRootData::XclChRootData()
1220 : mxTypeInfoProv(new XclChTypeInfoProvider)
1221 , mxFmtInfoProv(new XclChFormatInfoProvider)
1222 , mnBorderGapX(0)
1223 , mnBorderGapY(0)
1224 , mfUnitSizeX(0.0)
1225 , mfUnitSizeY(0.0)
1227 // remember some title shape getter functions
1228 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ] = lclGetMainTitleShape;
1229 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_X ) ] = lclGetXAxisTitleShape;
1230 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Y ) ] = lclGetYAxisTitleShape;
1231 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Z ) ] = lclGetZAxisTitleShape;
1232 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_X ) ] = lclGetSecXAxisTitleShape;
1233 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_Y ) ] = lclGetSecYAxisTitleShape;
1236 XclChRootData::~XclChRootData()
1240 void XclChRootData::InitConversion( const XclRoot& rRoot, const Reference< XChartDocument >& rxChartDoc, const Rectangle& rChartRect )
1242 // remember chart document reference and chart shape position/size
1243 OSL_ENSURE( rxChartDoc.is(), "XclChRootData::InitConversion - missing chart document" );
1244 mxChartDoc = rxChartDoc;
1245 maChartRect = rChartRect;
1247 // Excel excludes a border of 5 pixels in each direction from chart area
1248 mnBorderGapX = rRoot.GetHmmFromPixelX( 5.0 );
1249 mnBorderGapY = rRoot.GetHmmFromPixelY( 5.0 );
1251 // size of a chart unit in 1/100 mm
1252 mfUnitSizeX = ::std::max< double >( maChartRect.GetWidth() - 2 * mnBorderGapX, mnBorderGapX ) / EXC_CHART_TOTALUNITS;
1253 mfUnitSizeY = ::std::max< double >( maChartRect.GetHeight() - 2 * mnBorderGapY, mnBorderGapY ) / EXC_CHART_TOTALUNITS;
1255 // create object tables
1256 Reference< XMultiServiceFactory > xFactory( mxChartDoc, UNO_QUERY );
1257 mxLineDashTable.reset( new XclChObjectTable(
1258 xFactory, SERVICE_DRAWING_DASHTABLE, "Excel line dash " ) );
1259 mxGradientTable.reset( new XclChObjectTable(
1260 xFactory, SERVICE_DRAWING_GRADIENTTABLE, "Excel gradient " ) );
1261 mxHatchTable.reset( new XclChObjectTable(
1262 xFactory, SERVICE_DRAWING_HATCHTABLE, "Excel hatch " ) );
1263 mxBitmapTable.reset( new XclChObjectTable(
1264 xFactory, SERVICE_DRAWING_BITMAPTABLE, "Excel bitmap " ) );
1267 void XclChRootData::FinishConversion()
1269 // forget formatting object tables
1270 mxBitmapTable.reset();
1271 mxHatchTable.reset();
1272 mxGradientTable.reset();
1273 mxLineDashTable.reset();
1274 // forget chart document reference
1275 mxChartDoc.clear();
1278 Reference< XShape > XclChRootData::GetTitleShape( const XclChTextKey& rTitleKey ) const
1280 XclChGetShapeFuncMap::const_iterator aIt = maGetShapeFuncs.find( rTitleKey );
1281 OSL_ENSURE( aIt != maGetShapeFuncs.end(), "XclChRootData::GetTitleShape - invalid title key" );
1282 Reference< cssc::XChartDocument > xChart1Doc( mxChartDoc, UNO_QUERY );
1283 Reference< XShape > xTitleShape;
1284 if( xChart1Doc.is() && (aIt != maGetShapeFuncs.end()) )
1285 xTitleShape = (aIt->second)( xChart1Doc );
1286 return xTitleShape;
1289 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */