1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <xlchart.hxx>
21
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>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38
39 #include <sal/macros.h>
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 <xlroot.hxx>
49 #include <xlstyle.hxx>
50 #include <xltools.hxx>
51
52 using namespace css;
53
54 // Common =====================================================================
55
XclChRectangle()56 XclChRectangle::XclChRectangle() :
57 mnX( 0 ),
58 mnY( 0 ),
59 mnWidth( 0 ),
60 mnHeight( 0 )
61 {
62 }
63
XclChDataPointPos(sal_uInt16 nSeriesIdx,sal_uInt16 nPointIdx)64 XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx, sal_uInt16 nPointIdx ) :
65 mnSeriesIdx( nSeriesIdx ),
66 mnPointIdx( nPointIdx )
67 {
68 }
69
operator <(const XclChDataPointPos & rL,const XclChDataPointPos & rR)70 bool operator<( const XclChDataPointPos& rL, const XclChDataPointPos& rR )
71 {
72 return (rL.mnSeriesIdx < rR.mnSeriesIdx) ||
73 ((rL.mnSeriesIdx == rR.mnSeriesIdx) && (rL.mnPointIdx < rR.mnPointIdx));
74 }
75
XclChFrBlock(sal_uInt16 nType)76 XclChFrBlock::XclChFrBlock( sal_uInt16 nType ) :
77 mnType( nType ),
78 mnContext( 0 ),
79 mnValue1( 0 ),
80 mnValue2( 0 )
81 {
82 }
83
84 // Frame formatting ===========================================================
85
XclChFramePos()86 XclChFramePos::XclChFramePos() :
87 mnTLMode( EXC_CHFRAMEPOS_PARENT ),
88 mnBRMode( EXC_CHFRAMEPOS_PARENT )
89 {
90 }
91
XclChLineFormat()92 XclChLineFormat::XclChLineFormat() :
93 maColor( COL_BLACK ),
94 mnPattern( EXC_CHLINEFORMAT_SOLID ),
95 mnWeight( EXC_CHLINEFORMAT_SINGLE ),
96 mnFlags( EXC_CHLINEFORMAT_AUTO )
97 {
98 }
99
XclChAreaFormat()100 XclChAreaFormat::XclChAreaFormat() :
101 maPattColor( COL_WHITE ),
102 maBackColor( COL_BLACK ),
103 mnPattern( EXC_PATT_SOLID ),
104 mnFlags( EXC_CHAREAFORMAT_AUTO )
105 {
106 }
107
XclChEscherFormat()108 XclChEscherFormat::XclChEscherFormat()
109 {
110 }
111
~XclChEscherFormat()112 XclChEscherFormat::~XclChEscherFormat()
113 {
114 }
115
XclChPicFormat()116 XclChPicFormat::XclChPicFormat() :
117 mnBmpMode( EXC_CHPICFORMAT_NONE ),
118 mnFlags( EXC_CHPICFORMAT_TOPBOTTOM | EXC_CHPICFORMAT_FRONTBACK | EXC_CHPICFORMAT_LEFTRIGHT ),
119 mfScale( 0.5 )
120 {
121 }
122
XclChFrame()123 XclChFrame::XclChFrame() :
124 mnFormat( EXC_CHFRAME_STANDARD ),
125 mnFlags( EXC_CHFRAME_AUTOSIZE | EXC_CHFRAME_AUTOPOS )
126 {
127 }
128
129 // Source links ===============================================================
130
XclChSourceLink()131 XclChSourceLink::XclChSourceLink() :
132 mnDestType( EXC_CHSRCLINK_TITLE ),
133 mnLinkType( EXC_CHSRCLINK_DEFAULT ),
134 mnFlags( 0 ),
135 mnNumFmtIdx( 0 )
136 {
137 }
138
139 // Text =======================================================================
140
XclChObjectLink()141 XclChObjectLink::XclChObjectLink() :
142 mnTarget( EXC_CHOBJLINK_NONE )
143 {
144 }
145
XclChFrLabelProps()146 XclChFrLabelProps::XclChFrLabelProps() :
147 mnFlags( 0 )
148 {
149 }
150
XclChText()151 XclChText::XclChText() :
152 maTextColor( COL_BLACK ),
153 mnHAlign( EXC_CHTEXT_ALIGN_CENTER ),
154 mnVAlign( EXC_CHTEXT_ALIGN_CENTER ),
155 mnBackMode( EXC_CHTEXT_TRANSPARENT ),
156 mnFlags( EXC_CHTEXT_AUTOCOLOR | EXC_CHTEXT_AUTOFILL ),
157 mnFlags2( EXC_CHTEXT_POS_DEFAULT ),
158 mnRotation( EXC_ROT_NONE )
159 {
160 }
161
162 // Data series ================================================================
163
XclChMarkerFormat()164 XclChMarkerFormat::XclChMarkerFormat() :
165 maLineColor( COL_BLACK ),
166 maFillColor( COL_WHITE ),
167 mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE ),
168 mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL ),
169 mnFlags( EXC_CHMARKERFORMAT_AUTO )
170 {
171 };
172
XclCh3dDataFormat()173 XclCh3dDataFormat::XclCh3dDataFormat() :
174 mnBase( EXC_CH3DDATAFORMAT_RECT ),
175 mnTop( EXC_CH3DDATAFORMAT_STRAIGHT )
176 {
177 }
178
XclChDataFormat()179 XclChDataFormat::XclChDataFormat() :
180 mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT ),
181 mnFlags( 0 )
182 {
183 }
184
XclChSerTrendLine()185 XclChSerTrendLine::XclChSerTrendLine() :
186 mfForecastFor( 0.0 ),
187 mfForecastBack( 0.0 ),
188 mnLineType( EXC_CHSERTREND_POLYNOMIAL ),
189 mnOrder( 1 ),
190 mnShowEquation( 0 ),
191 mnShowRSquared( 0 )
192 {
193 /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that
194 there is no interception point. Cannot use ::rtl::math::setNan() here
195 cause it misses the sign bit. */
196 sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &mfIntercept );
197 pDouble->w32_parts.msw = pDouble->w32_parts.lsw = 0xFFFFFFFF;
198 }
199
XclChSerErrorBar()200 XclChSerErrorBar::XclChSerErrorBar() :
201 mfValue( 0.0 ),
202 mnValueCount( 1 ),
203 mnBarType( EXC_CHSERERR_NONE ),
204 mnSourceType( EXC_CHSERERR_FIXED ),
205 mnLineEnd( EXC_CHSERERR_END_TSHAPE )
206 {
207 }
208
XclChSeries()209 XclChSeries::XclChSeries() :
210 mnCategType( EXC_CHSERIES_NUMERIC ),
211 mnValueType( EXC_CHSERIES_NUMERIC ),
212 mnBubbleType( EXC_CHSERIES_NUMERIC ),
213 mnCategCount( 0 ),
214 mnValueCount( 0 ),
215 mnBubbleCount( 0 )
216 {
217 }
218
219 // Chart type groups ==========================================================
220
XclChType()221 XclChType::XclChType() :
222 mnOverlap( 0 ),
223 mnGap( 150 ),
224 mnRotation( 0 ),
225 mnPieHole( 0 ),
226 mnBubbleSize( 100 ),
227 mnBubbleType( EXC_CHSCATTER_AREA ),
228 mnFlags( 0 )
229 {
230 }
231
XclChChart3d()232 XclChChart3d::XclChChart3d() :
233 mnRotation( 20 ),
234 mnElevation( 15 ),
235 mnEyeDist( 30 ),
236 mnRelHeight( 100 ),
237 mnRelDepth( 100 ),
238 mnDepthGap( 150 ),
239 mnFlags( EXC_CHCHART3D_AUTOHEIGHT )
240 {
241 }
242
XclChLegend()243 XclChLegend::XclChLegend() :
244 mnDockMode( EXC_CHLEGEND_RIGHT ),
245 mnSpacing( EXC_CHLEGEND_MEDIUM ),
246 mnFlags( EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOSERIES |
247 EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY | EXC_CHLEGEND_STACKED )
248 {
249 }
250
XclChTypeGroup()251 XclChTypeGroup::XclChTypeGroup() :
252 mnFlags( 0 ),
253 mnGroupIdx( EXC_CHSERGROUP_NONE )
254 {
255 }
256
XclChProperties()257 XclChProperties::XclChProperties() :
258 mnFlags( 0 ),
259 mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP )
260 {
261 }
262
263 // Axes =======================================================================
264
XclChLabelRange()265 XclChLabelRange::XclChLabelRange() :
266 mnCross( 1 ),
267 mnLabelFreq( 1 ),
268 mnTickFreq( 1 ),
269 mnFlags( 0 )
270 {
271 }
272
XclChDateRange()273 XclChDateRange::XclChDateRange() :
274 mnMinDate( 0 ),
275 mnMaxDate( 0 ),
276 mnMajorStep( 0 ),
277 mnMajorUnit( EXC_CHDATERANGE_DAYS ),
278 mnMinorStep( 0 ),
279 mnMinorUnit( EXC_CHDATERANGE_DAYS ),
280 mnBaseUnit( EXC_CHDATERANGE_DAYS ),
281 mnCross( 0 ),
282 mnFlags( EXC_CHDATERANGE_AUTOMIN | EXC_CHDATERANGE_AUTOMAX |
283 EXC_CHDATERANGE_AUTOMAJOR | EXC_CHDATERANGE_AUTOMINOR |
284 EXC_CHDATERANGE_AUTOBASE | EXC_CHDATERANGE_AUTOCROSS |
285 EXC_CHDATERANGE_AUTODATE )
286 {
287 }
288
XclChValueRange()289 XclChValueRange::XclChValueRange() :
290 mfMin( 0.0 ),
291 mfMax( 0.0 ),
292 mfMajorStep( 0.0 ),
293 mfMinorStep( 0.0 ),
294 mfCross( 0.0 ),
295 mnFlags( EXC_CHVALUERANGE_AUTOMIN | EXC_CHVALUERANGE_AUTOMAX |
296 EXC_CHVALUERANGE_AUTOMAJOR | EXC_CHVALUERANGE_AUTOMINOR |
297 EXC_CHVALUERANGE_AUTOCROSS | EXC_CHVALUERANGE_BIT8 )
298 {
299 }
300
XclChTick()301 XclChTick::XclChTick() :
302 maTextColor( COL_BLACK ),
303 mnMajor( EXC_CHTICK_INSIDE | EXC_CHTICK_OUTSIDE ),
304 mnMinor( 0 ),
305 mnLabelPos( EXC_CHTICK_NEXT ),
306 mnBackMode( EXC_CHTICK_TRANSPARENT ),
307 mnFlags( EXC_CHTICK_AUTOCOLOR | EXC_CHTICK_AUTOROT ),
308 mnRotation( EXC_ROT_NONE )
309 {
310 }
311
XclChAxis()312 XclChAxis::XclChAxis() :
313 mnType( EXC_CHAXIS_NONE )
314 {
315 }
316
GetApiAxisDimension() const317 sal_Int32 XclChAxis::GetApiAxisDimension() const
318 {
319 sal_Int32 nApiAxisDim = EXC_CHART_AXIS_NONE;
320 switch( mnType )
321 {
322 case EXC_CHAXIS_X: nApiAxisDim = EXC_CHART_AXIS_X; break;
323 case EXC_CHAXIS_Y: nApiAxisDim = EXC_CHART_AXIS_Y; break;
324 case EXC_CHAXIS_Z: nApiAxisDim = EXC_CHART_AXIS_Z; break;
325 }
326 return nApiAxisDim;
327 }
328
XclChAxesSet()329 XclChAxesSet::XclChAxesSet() :
330 mnAxesSetId( EXC_CHAXESSET_PRIMARY )
331 {
332 }
333
GetApiAxesSetIndex() const334 sal_Int32 XclChAxesSet::GetApiAxesSetIndex() const
335 {
336 sal_Int32 nApiAxesSetIdx = EXC_CHART_AXESSET_NONE;
337 switch( mnAxesSetId )
338 {
339 case EXC_CHAXESSET_PRIMARY: nApiAxesSetIdx = EXC_CHART_AXESSET_PRIMARY; break;
340 case EXC_CHAXESSET_SECONDARY: nApiAxesSetIdx = EXC_CHART_AXESSET_SECONDARY; break;
341 }
342 return nApiAxesSetIdx;
343 }
344
345 // Static helper functions ====================================================
346
GetSeriesLineAutoColorIdx(sal_uInt16 nFormatIdx)347 sal_uInt16 XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx )
348 {
349 static const sal_uInt16 spnLineColors[] =
350 {
351 32, 33, 34, 35, 36, 37, 38, 39,
352 40, 41, 42, 43, 44, 45, 46, 47,
353 48, 49, 50, 51, 52, 53, 54, 55,
354 56, 57, 58, 59, 60, 61, 62, 8,
355 9, 10, 11, 12, 13, 14, 15, 16,
356 17, 18, 19, 20, 21, 22, 23, 24,
357 25, 26, 27, 28, 29, 30, 31, 63
358 };
359 return spnLineColors[ nFormatIdx % SAL_N_ELEMENTS( spnLineColors ) ];
360 }
361
GetSeriesFillAutoColorIdx(sal_uInt16 nFormatIdx)362 sal_uInt16 XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx )
363 {
364 static const sal_uInt16 spnFillColors[] =
365 {
366 24, 25, 26, 27, 28, 29, 30, 31,
367 32, 33, 34, 35, 36, 37, 38, 39,
368 40, 41, 42, 43, 44, 45, 46, 47,
369 48, 49, 50, 51, 52, 53, 54, 55,
370 56, 57, 58, 59, 60, 61, 62, 63,
371 8, 9, 10, 11, 12, 13, 14, 15,
372 16, 17, 18, 19, 20, 21, 22, 23
373 };
374 return spnFillColors[ nFormatIdx % SAL_N_ELEMENTS( spnFillColors ) ];
375 }
376
GetSeriesFillAutoTransp(sal_uInt16 nFormatIdx)377 sal_uInt8 XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx )
378 {
379 static const sal_uInt8 spnTrans[] = { 0x00, 0x40, 0x20, 0x60, 0x70 };
380 return spnTrans[ (nFormatIdx / 56) % SAL_N_ELEMENTS( spnTrans ) ];
381 }
382
GetAutoMarkerType(sal_uInt16 nFormatIdx)383 sal_uInt16 XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx )
384 {
385 static const sal_uInt16 spnSymbols[] = {
386 EXC_CHMARKERFORMAT_DIAMOND, EXC_CHMARKERFORMAT_SQUARE, EXC_CHMARKERFORMAT_TRIANGLE,
387 EXC_CHMARKERFORMAT_CROSS, EXC_CHMARKERFORMAT_STAR, EXC_CHMARKERFORMAT_CIRCLE,
388 EXC_CHMARKERFORMAT_PLUS, EXC_CHMARKERFORMAT_DOWJ, EXC_CHMARKERFORMAT_STDDEV };
389 return spnSymbols[ nFormatIdx % SAL_N_ELEMENTS( spnSymbols ) ];
390 }
391
HasMarkerFillColor(sal_uInt16 nMarkerType)392 bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType )
393 {
394 static const bool spbFilled[] = {
395 false, true, true, true, false, false, false, false, true, false };
396 return (nMarkerType < SAL_N_ELEMENTS( spbFilled )) && spbFilled[ nMarkerType ];
397 }
398
GetErrorBarValuesRole(sal_uInt8 nBarType)399 OUString XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType )
400 {
401 switch( nBarType )
402 {
403 case EXC_CHSERERR_XPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSX;
404 case EXC_CHSERERR_XMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGX;
405 case EXC_CHSERERR_YPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSY;
406 case EXC_CHSERERR_YMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGY;
407 default: OSL_FAIL( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" );
408 }
409 return OUString();
410 }
411
412 // Chart formatting info provider =============================================
413
414 namespace {
415
416 static const XclChFormatInfo spFmtInfos[] =
417 {
418 // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe
419 { EXC_CHOBJTYPE_BACKGROUND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
420 { EXC_CHOBJTYPE_PLOTFRAME, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true },
421 { EXC_CHOBJTYPE_WALL3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, false, true },
422 { EXC_CHOBJTYPE_FLOOR3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, 23, EXC_CHFRAMETYPE_AUTO, true, false, true },
423 { EXC_CHOBJTYPE_TEXT, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, true },
424 { EXC_CHOBJTYPE_LEGEND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, true, true },
425 { EXC_CHOBJTYPE_LINEARSERIES, EXC_CHPROPMODE_LINEARSERIES, 0xFFFF, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
426 { EXC_CHOBJTYPE_FILLEDSERIES, EXC_CHPROPMODE_FILLEDSERIES, EXC_COLOR_CHBORDERAUTO, EXC_CHLINEFORMAT_SINGLE, 0xFFFF, EXC_CHFRAMETYPE_AUTO, false, false, true },
427 { EXC_CHOBJTYPE_AXISLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false },
428 { EXC_CHOBJTYPE_GRIDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, false },
429 { EXC_CHOBJTYPE_TRENDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_DOUBLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
430 { EXC_CHOBJTYPE_ERRORBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
431 { EXC_CHOBJTYPE_CONNECTLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
432 { EXC_CHOBJTYPE_HILOLINE, EXC_CHPROPMODE_LINEARSERIES, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false },
433 { EXC_CHOBJTYPE_WHITEDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, true },
434 { EXC_CHOBJTYPE_BLACKDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWTEXT, EXC_CHFRAMETYPE_INVISIBLE, false, false, true }
435 };
436
437 }
438
XclChFormatInfoProvider()439 XclChFormatInfoProvider::XclChFormatInfoProvider()
440 {
441 for(auto const &rIt : spFmtInfos)
442 maInfoMap[ rIt.meObjType ] = &rIt;
443 }
444
GetFormatInfo(XclChObjectType eObjType) const445 const XclChFormatInfo& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType ) const
446 {
447 XclFmtInfoMap::const_iterator aIt = maInfoMap.find( eObjType );
448 OSL_ENSURE( aIt != maInfoMap.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" );
449 return (aIt == maInfoMap.end()) ? *spFmtInfos : *aIt->second;
450 }
451
452 // Chart type info provider ===================================================
453
454 namespace {
455
456 // chart type service names
457 const sal_Char SERVICE_CHART2_AREA[] = "com.sun.star.chart2.AreaChartType";
458 const sal_Char SERVICE_CHART2_CANDLE[] = "com.sun.star.chart2.CandleStickChartType";
459 const sal_Char SERVICE_CHART2_COLUMN[] = "com.sun.star.chart2.ColumnChartType";
460 const sal_Char SERVICE_CHART2_LINE[] = "com.sun.star.chart2.LineChartType";
461 const sal_Char SERVICE_CHART2_NET[] = "com.sun.star.chart2.NetChartType";
462 const sal_Char SERVICE_CHART2_FILLEDNET[] = "com.sun.star.chart2.FilledNetChartType";
463 const sal_Char SERVICE_CHART2_PIE[] = "com.sun.star.chart2.PieChartType";
464 const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType";
465 const sal_Char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType";
466 const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
467
468 namespace csscd = css::chart::DataLabelPlacement;
469
470 static const XclChTypeInfo spTypeInfos[] =
471 {
472 // 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
473 { 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 },
474 { 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 },
475 { 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 },
476 { 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 },
477 { 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 },
478 { 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 },
479 { 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 },
480 { 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 },
481 { 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 },
482 { 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 },
483 { 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 },
484 { 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 },
485 { 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 },
486 { 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 }
487 };
488
489 } // namespace
490
XclChExtTypeInfo(const XclChTypeInfo & rTypeInfo)491 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo ) :
492 XclChTypeInfo( rTypeInfo ),
493 mb3dChart( false ),
494 mbSpline( false )
495 {
496 }
497
Set(const XclChTypeInfo & rTypeInfo,bool b3dChart,bool bSpline)498 void XclChExtTypeInfo::Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline )
499 {
500 static_cast< XclChTypeInfo& >( *this ) = rTypeInfo;
501 mb3dChart = mbSupports3d && b3dChart;
502 mbSpline = bSpline;
503 }
504
XclChTypeInfoProvider()505 XclChTypeInfoProvider::XclChTypeInfoProvider()
506 {
507 for(const auto &rIt : spTypeInfos)
508 maInfoMap[ rIt.meTypeId ] = &rIt;
509 }
510
GetTypeInfo(XclChTypeId eTypeId) const511 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId ) const
512 {
513 XclChTypeInfoMap::const_iterator aIt = maInfoMap.find( eTypeId );
514 OSL_ENSURE( aIt != maInfoMap.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" );
515 return (aIt == maInfoMap.end()) ? *maInfoMap.rbegin()->second : *aIt->second;
516 }
517
GetTypeInfoFromRecId(sal_uInt16 nRecId) const518 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId ) const
519 {
520 for(const auto &rIt : spTypeInfos)
521 {
522 if(rIt.mnRecId == nRecId)
523 return rIt;
524 }
525 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" );
526 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
527 }
528
GetTypeInfoFromService(const OUString & rServiceName) const529 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString& rServiceName ) const
530 {
531 for(auto const &rIt : spTypeInfos)
532 if( rServiceName.equalsAscii( rIt.mpcServiceName ) )
533 return rIt;
534 OSL_FAIL( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" );
535 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN );
536 }
537
538 // Property helpers ===========================================================
539
XclChObjectTable(uno::Reference<lang::XMultiServiceFactory> const & xFactory,const OUString & rServiceName,const OUString & rObjNameBase)540 XclChObjectTable::XclChObjectTable(uno::Reference<lang::XMultiServiceFactory> const & xFactory,
541 const OUString& rServiceName, const OUString& rObjNameBase ) :
542 mxFactory( xFactory ),
543 maServiceName( rServiceName ),
544 maObjNameBase( rObjNameBase ),
545 mnIndex( 0 )
546 {
547 }
548
GetObject(const OUString & rObjName)549 uno::Any XclChObjectTable::GetObject( const OUString& rObjName )
550 {
551 // get object table
552 if( !mxContainer.is() )
553 mxContainer.set(ScfApiHelper::CreateInstance( mxFactory, maServiceName ), uno::UNO_QUERY);
554 OSL_ENSURE( mxContainer.is(), "XclChObjectTable::GetObject - container not found" );
555
556 uno::Any aObj;
557 if( mxContainer.is() )
558 {
559 // get object from container
560 try
561 {
562 aObj = mxContainer->getByName( rObjName );
563 }
564 catch (uno::Exception &)
565 {
566 OSL_FAIL( "XclChObjectTable::GetObject - object not found" );
567 }
568 }
569 return aObj;
570 }
571
InsertObject(const uno::Any & rObj)572 OUString XclChObjectTable::InsertObject(const uno::Any& rObj)
573 {
574
575 // create object table
576 if( !mxContainer.is() )
577 mxContainer.set(ScfApiHelper::CreateInstance( mxFactory, maServiceName ), uno::UNO_QUERY);
578 OSL_ENSURE( mxContainer.is(), "XclChObjectTable::InsertObject - container not found" );
579
580 OUString aObjName;
581 if( mxContainer.is() )
582 {
583 // create new unused identifier
584 do
585 {
586 aObjName = maObjNameBase + OUString::number( ++mnIndex );
587 }
588 while( mxContainer->hasByName( aObjName ) );
589
590 // insert object
591 try
592 {
593 mxContainer->insertByName( aObjName, rObj );
594 }
595 catch (uno::Exception &)
596 {
597 OSL_FAIL( "XclChObjectTable::InsertObject - cannot insert object" );
598 aObjName.clear();
599 }
600 }
601 return aObjName;
602 }
603
604 // Property names -------------------------------------------------------------
605
606 namespace {
607
608 /** Property names for line style in common objects. */
609 const sal_Char* const sppcLineNamesCommon[] =
610 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", nullptr };
611 /** Property names for line style in linear series objects. */
612 const sal_Char* const sppcLineNamesLinear[] =
613 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", nullptr };
614 /** Property names for line style in filled series objects. */
615 const sal_Char* const sppcLineNamesFilled[] =
616 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", nullptr };
617
618 /** Property names for solid area style in common objects. */
619 const sal_Char* const sppcAreaNamesCommon[] = { "FillStyle", "FillColor", "FillTransparence", nullptr };
620 /** Property names for solid area style in filled series objects. */
621 const sal_Char* const sppcAreaNamesFilled[] = { "FillStyle", "Color", "Transparency", nullptr };
622 /** Property names for gradient area style in common objects. */
623 const sal_Char* const sppcGradNamesCommon[] = { "FillStyle", "FillGradientName", nullptr };
624 /** Property names for gradient area style in filled series objects. */
625 const sal_Char* const sppcGradNamesFilled[] = { "FillStyle", "GradientName", nullptr };
626 /** Property names for hatch area style in common objects. */
627 const sal_Char* const sppcHatchNamesCommon[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", nullptr };
628 /** Property names for hatch area style in filled series objects. */
629 const sal_Char* const sppcHatchNamesFilled[] = { "FillStyle", "HatchName", "Color", "FillBackground", nullptr };
630 /** Property names for bitmap area style. */
631 const sal_Char* const sppcBitmapNames[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", nullptr };
632
633 } // namespace
634
XclChPropSetHelper()635 XclChPropSetHelper::XclChPropSetHelper() :
636 maLineHlpCommon( sppcLineNamesCommon ),
637 maLineHlpLinear( sppcLineNamesLinear ),
638 maLineHlpFilled( sppcLineNamesFilled ),
639 maAreaHlpCommon( sppcAreaNamesCommon ),
640 maAreaHlpFilled( sppcAreaNamesFilled ),
641 maGradHlpCommon( sppcGradNamesCommon ),
642 maGradHlpFilled( sppcGradNamesFilled ),
643 maHatchHlpCommon( sppcHatchNamesCommon ),
644 maHatchHlpFilled( sppcHatchNamesFilled ),
645 maBitmapHlp( sppcBitmapNames )
646 {
647 }
648
649 // read properties ------------------------------------------------------------
650
ReadLineProperties(XclChLineFormat & rLineFmt,XclChObjectTable & rDashTable,const ScfPropertySet & rPropSet,XclChPropertyMode ePropMode)651 void XclChPropSetHelper::ReadLineProperties(
652 XclChLineFormat& rLineFmt, XclChObjectTable& rDashTable,
653 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
654 {
655 // read properties from property set
656 drawing::LineStyle eApiStyle = drawing::LineStyle_NONE;
657 sal_Int32 nApiWidth = 0;
658 sal_Int16 nApiTrans = 0;
659 uno::Any aDashNameAny;
660
661 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
662 rLineHlp.ReadFromPropertySet( rPropSet );
663 rLineHlp >> eApiStyle >> nApiWidth >> rLineFmt.maColor >> nApiTrans >> aDashNameAny;
664
665 // clear automatic flag
666 ::set_flag( rLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false );
667
668 // line width
669 if( nApiWidth <= 0 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR;
670 else if( nApiWidth <= 35 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE;
671 else if( nApiWidth <= 70 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE;
672 else rLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE;
673
674 // line style
675 switch( eApiStyle )
676 {
677 case drawing::LineStyle_NONE:
678 rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
679 break;
680 case drawing::LineStyle_SOLID:
681 {
682 if( nApiTrans < 13 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
683 else if( nApiTrans < 38 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS;
684 else if( nApiTrans < 63 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS;
685 else if( nApiTrans < 100 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS;
686 else rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE;
687 }
688 break;
689 case drawing::LineStyle_DASH:
690 {
691 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
692 OUString aDashName;
693 drawing::LineDash aApiDash;
694 if( (aDashNameAny >>= aDashName) && (rDashTable.GetObject( aDashName ) >>= aApiDash) )
695 {
696 // reorder dashes that are shorter than dots
697 if( (aApiDash.Dashes == 0) || (aApiDash.DashLen < aApiDash.DotLen) )
698 {
699 ::std::swap( aApiDash.Dashes, aApiDash.Dots );
700 ::std::swap( aApiDash.DashLen, aApiDash.DotLen );
701 }
702 // ignore dots that are nearly equal to dashes
703 if( aApiDash.DotLen * 3 > aApiDash.DashLen * 2 )
704 aApiDash.Dots = 0;
705
706 // convert line dash to predefined Excel dash types
707 if( (aApiDash.Dashes == 1) && (aApiDash.Dots >= 1) )
708 // one dash and one or more dots
709 rLineFmt.mnPattern = (aApiDash.Dots == 1) ?
710 EXC_CHLINEFORMAT_DASHDOT : EXC_CHLINEFORMAT_DASHDOTDOT;
711 else if( aApiDash.Dashes >= 1 )
712 // one or more dashes and no dots (also: dash-dash-dot)
713 rLineFmt.mnPattern = (aApiDash.DashLen < 250) ?
714 EXC_CHLINEFORMAT_DOT : EXC_CHLINEFORMAT_DASH;
715 }
716 }
717 break;
718 default:
719 OSL_FAIL( "XclChPropSetHelper::ReadLineProperties - unknown line style" );
720 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID;
721 }
722 }
723
ReadAreaProperties(XclChAreaFormat & rAreaFmt,const ScfPropertySet & rPropSet,XclChPropertyMode ePropMode)724 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat& rAreaFmt,
725 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
726 {
727 // read properties from property set
728 drawing::FillStyle eApiStyle = drawing::FillStyle_NONE;
729 sal_Int16 nTransparency = 0;
730
731 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
732 rAreaHlp.ReadFromPropertySet( rPropSet );
733 rAreaHlp >> eApiStyle >> rAreaFmt.maPattColor >> nTransparency;
734
735 // clear automatic flag
736 ::set_flag( rAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false );
737
738 // set fill style transparent or solid (set solid for anything but transparent)
739 rAreaFmt.mnPattern = (eApiStyle == drawing::FillStyle_NONE) ? EXC_PATT_NONE : EXC_PATT_SOLID;
740
741 // return true to indicate complex fill (gradient, bitmap, solid transparency)
742 return (eApiStyle != drawing::FillStyle_NONE) && ((eApiStyle != drawing::FillStyle_SOLID) || (nTransparency > 0));
743 }
744
ReadEscherProperties(XclChEscherFormat & rEscherFmt,XclChPicFormat & rPicFmt,XclChObjectTable & rGradientTable,XclChObjectTable & rHatchTable,XclChObjectTable & rBitmapTable,const ScfPropertySet & rPropSet,XclChPropertyMode ePropMode)745 void XclChPropSetHelper::ReadEscherProperties(
746 XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt,
747 XclChObjectTable& rGradientTable, XclChObjectTable& rHatchTable, XclChObjectTable& rBitmapTable,
748 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode )
749 {
750 // read style and transparency properties from property set
751 drawing::FillStyle eApiStyle = drawing::FillStyle_NONE;
752 Color aColor;
753 sal_Int16 nTransparency = 0;
754
755 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
756 rAreaHlp.ReadFromPropertySet( rPropSet );
757 rAreaHlp >> eApiStyle >> aColor >> nTransparency;
758
759 switch( eApiStyle )
760 {
761 case drawing::FillStyle_SOLID:
762 {
763 OSL_ENSURE( nTransparency > 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" );
764 if( (0 < nTransparency) && (nTransparency <= 100) )
765 {
766 // convert to Escher properties
767 sal_uInt32 nEscherColor = 0x02000000;
768 ::insert_value( nEscherColor, aColor.GetBlue(), 16, 8 );
769 ::insert_value( nEscherColor, aColor.GetGreen(), 8, 8 );
770 ::insert_value( nEscherColor, aColor.GetRed(), 0, 8 );
771 sal_uInt32 nEscherOpacity = static_cast< sal_uInt32 >( (100 - nTransparency) * 655.36 );
772 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
773 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
774 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, nEscherColor );
775 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillOpacity, nEscherOpacity );
776 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x02FFFFFF );
777 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackOpacity, 0x00010000 );
778 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fNoFillHitTest, 0x001F001C );
779 }
780 }
781 break;
782 case drawing::FillStyle_GRADIENT:
783 {
784 // extract gradient from global gradient table
785 OUString aGradientName;
786 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
787 rGradHlp.ReadFromPropertySet( rPropSet );
788 rGradHlp >> eApiStyle >> aGradientName;
789 awt::Gradient aGradient;
790 if( rGradientTable.GetObject( aGradientName ) >>= aGradient )
791 {
792 // convert to Escher properties
793 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
794 rEscherFmt.mxEscherSet->CreateGradientProperties( aGradient );
795 }
796 }
797 break;
798 case drawing::FillStyle_HATCH:
799 {
800 // extract hatch from global hatch table
801 OUString aHatchName;
802 bool bFillBackground;
803 ScfPropSetHelper& rHatchHlp = GetHatchHelper( ePropMode );
804 rHatchHlp.ReadFromPropertySet( rPropSet );
805 rHatchHlp >> eApiStyle >> aHatchName >> aColor >> bFillBackground;
806 drawing::Hatch aHatch;
807 if( rHatchTable.GetObject( aHatchName ) >>= aHatch )
808 {
809 // convert to Escher properties
810 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
811 rEscherFmt.mxEscherSet->CreateEmbeddedHatchProperties( aHatch, aColor, bFillBackground );
812 rPicFmt.mnBmpMode = EXC_CHPICFORMAT_STACK;
813 }
814 }
815 break;
816 case drawing::FillStyle_BITMAP:
817 {
818 // extract bitmap URL from global bitmap table
819 OUString aBitmapName;
820 drawing::BitmapMode eApiBmpMode;
821 maBitmapHlp.ReadFromPropertySet( rPropSet );
822 maBitmapHlp >> eApiStyle >> aBitmapName >> eApiBmpMode;
823 uno::Reference<awt::XBitmap> xBitmap;
824 if (rBitmapTable.GetObject( aBitmapName ) >>= xBitmap)
825 {
826 // convert to Escher properties
827 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer );
828 rEscherFmt.mxEscherSet->CreateEmbeddedBitmapProperties( xBitmap, eApiBmpMode );
829 rPicFmt.mnBmpMode = (eApiBmpMode == drawing::BitmapMode_REPEAT) ?
830 EXC_CHPICFORMAT_STACK : EXC_CHPICFORMAT_STRETCH;
831 }
832 }
833 break;
834 default:
835 OSL_FAIL( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" );
836 }
837 }
838
ReadMarkerProperties(XclChMarkerFormat & rMarkerFmt,const ScfPropertySet & rPropSet,sal_uInt16 nFormatIdx)839 void XclChPropSetHelper::ReadMarkerProperties(
840 XclChMarkerFormat& rMarkerFmt, const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx )
841 {
842 chart2::Symbol aApiSymbol;
843 if( rPropSet.GetProperty( aApiSymbol, EXC_CHPROP_SYMBOL ) )
844 {
845 // clear automatic flag
846 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_AUTO, false );
847
848 // symbol style
849 switch( aApiSymbol.Style )
850 {
851 case chart2::SymbolStyle_NONE:
852 rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL;
853 break;
854 case chart2::SymbolStyle_STANDARD:
855 switch( aApiSymbol.StandardSymbol )
856 {
857 case 0: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_SQUARE; break; // square
858 case 1: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // diamond
859 case 2: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // arrow down
860 case 3: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_TRIANGLE; break; // arrow up
861 case 4: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DOWJ; break; // arrow right, same as import
862 case 5: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // arrow left
863 case 6: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // bow tie
864 case 7: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // sand glass
865 case 8: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CIRCLE; break; // circle new in LibO3.5
866 case 9: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // star new in LibO3.5
867 case 10: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // X new in LibO3.5
868 case 11: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // plus new in LibO3.5
869 case 12: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // asterisk new in LibO3.5
870 case 13: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // horizontal bar new in LibO3.5
871 case 14: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // vertical bar new in LibO3.5
872 default: rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
873 }
874 break;
875 default:
876 rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
877 }
878 bool bHasFillColor = XclChartHelper::HasMarkerFillColor( rMarkerFmt.mnMarkerType );
879 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOFILL, !bHasFillColor );
880
881 // symbol size
882 sal_Int32 nApiSize = (aApiSymbol.Size.Width + aApiSymbol.Size.Height + 1) / 2;
883 rMarkerFmt.mnMarkerSize = XclTools::GetTwipsFromHmm( nApiSize );
884
885 // symbol colors
886 rMarkerFmt.maLineColor = Color( aApiSymbol.BorderColor );
887 rMarkerFmt.maFillColor = Color( aApiSymbol.FillColor );
888 }
889 }
890
ReadRotationProperties(const ScfPropertySet & rPropSet,bool bSupportsStacked)891 sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPropSet, bool bSupportsStacked )
892 {
893 // chart2 handles rotation as double in the range [0,360)
894 double fAngle = 0.0;
895 rPropSet.GetProperty( fAngle, EXC_CHPROP_TEXTROTATION );
896 bool bStacked = bSupportsStacked && rPropSet.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS );
897 return bStacked ? EXC_ROT_STACKED :
898 XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) );
899 }
900
901 // write properties -----------------------------------------------------------
902
WriteLineProperties(ScfPropertySet & rPropSet,XclChObjectTable & rDashTable,const XclChLineFormat & rLineFmt,XclChPropertyMode ePropMode)903 void XclChPropSetHelper::WriteLineProperties(
904 ScfPropertySet& rPropSet, XclChObjectTable& rDashTable,
905 const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode )
906 {
907 // line width
908 sal_Int32 nApiWidth = 0; // 0 is the width of a hair line
909 switch( rLineFmt.mnWeight )
910 {
911 case EXC_CHLINEFORMAT_SINGLE: nApiWidth = 35; break;
912 case EXC_CHLINEFORMAT_DOUBLE: nApiWidth = 70; break;
913 case EXC_CHLINEFORMAT_TRIPLE: nApiWidth = 105; break;
914 }
915
916 // line style
917 drawing::LineStyle eApiStyle = drawing::LineStyle_NONE;
918 sal_Int16 nApiTrans = 0;
919 sal_Int32 nDotLen = ::std::min< sal_Int32 >( rLineFmt.mnWeight + 105, 210 );
920 drawing::LineDash aApiDash( drawing::DashStyle_RECT, 0, nDotLen, 0, 4 * nDotLen, nDotLen );
921
922 switch( rLineFmt.mnPattern )
923 {
924 case EXC_CHLINEFORMAT_SOLID:
925 eApiStyle = drawing::LineStyle_SOLID;
926 break;
927 case EXC_CHLINEFORMAT_DARKTRANS:
928 eApiStyle = drawing::LineStyle_SOLID; nApiTrans = 25;
929 break;
930 case EXC_CHLINEFORMAT_MEDTRANS:
931 eApiStyle = drawing::LineStyle_SOLID; nApiTrans = 50;
932 break;
933 case EXC_CHLINEFORMAT_LIGHTTRANS:
934 eApiStyle = drawing::LineStyle_SOLID; nApiTrans = 75;
935 break;
936 case EXC_CHLINEFORMAT_DASH:
937 eApiStyle = drawing::LineStyle_DASH; aApiDash.Dashes = 1;
938 break;
939 case EXC_CHLINEFORMAT_DOT:
940 eApiStyle = drawing::LineStyle_DASH; aApiDash.Dots = 1;
941 break;
942 case EXC_CHLINEFORMAT_DASHDOT:
943 eApiStyle = drawing::LineStyle_DASH; aApiDash.Dashes = aApiDash.Dots = 1;
944 break;
945 case EXC_CHLINEFORMAT_DASHDOTDOT:
946 eApiStyle = drawing::LineStyle_DASH; aApiDash.Dashes = 1; aApiDash.Dots = 2;
947 break;
948 }
949
950 // line color
951 sal_Int32 nApiColor = sal_Int32( rLineFmt.maColor );
952
953 // try to insert the dash style and receive its name
954 uno::Any aDashNameAny;
955 if( eApiStyle == drawing::LineStyle_DASH )
956 {
957 OUString aDashName = rDashTable.InsertObject( uno::makeAny( aApiDash ) );
958 if( !aDashName.isEmpty() )
959 aDashNameAny <<= aDashName;
960 }
961
962 // write the properties
963 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
964 rLineHlp.InitializeWrite();
965 rLineHlp << eApiStyle << nApiWidth << nApiColor << nApiTrans << aDashNameAny;
966 rLineHlp.WriteToPropertySet( rPropSet );
967 }
968
WriteAreaProperties(ScfPropertySet & rPropSet,const XclChAreaFormat & rAreaFmt,XclChPropertyMode ePropMode)969 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet& rPropSet,
970 const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode )
971 {
972 drawing::FillStyle eFillStyle = drawing::FillStyle_NONE;
973 Color aColor;
974
975 // fill color
976 if( rAreaFmt.mnPattern != EXC_PATT_NONE )
977 {
978 eFillStyle = drawing::FillStyle_SOLID;
979 aColor = XclTools::GetPatternColor( rAreaFmt.maPattColor, rAreaFmt.maBackColor, rAreaFmt.mnPattern );
980 }
981
982 // write the properties
983 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
984 rAreaHlp.InitializeWrite();
985 rAreaHlp << eFillStyle << aColor << sal_Int16(0)/*nTransparency*/;
986 rAreaHlp.WriteToPropertySet( rPropSet );
987 }
988
WriteEscherProperties(ScfPropertySet & rPropSet,XclChObjectTable & rGradientTable,XclChObjectTable & rBitmapTable,const XclChEscherFormat & rEscherFmt,const XclChPicFormat * pPicFmt,sal_uInt32 nDffFillType,XclChPropertyMode ePropMode)989 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet,
990 XclChObjectTable& rGradientTable, XclChObjectTable& rBitmapTable,
991 const XclChEscherFormat& rEscherFmt, const XclChPicFormat* pPicFmt,
992 sal_uInt32 nDffFillType, XclChPropertyMode ePropMode )
993 {
994 if( rEscherFmt.mxItemSet )
995 {
996 if( const XFillStyleItem* pStyleItem = rEscherFmt.mxItemSet->GetItem<XFillStyleItem>( XATTR_FILLSTYLE, false ) )
997 {
998 switch( pStyleItem->GetValue() )
999 {
1000 case drawing::FillStyle_SOLID:
1001 // #i84812# Excel 2007 writes Escher properties for solid fill
1002 if( const XFillColorItem* pColorItem = rEscherFmt.mxItemSet->GetItem<XFillColorItem>( XATTR_FILLCOLOR, false ) )
1003 {
1004 // get solid transparence too
1005 const XFillTransparenceItem* pTranspItem = rEscherFmt.mxItemSet->GetItem<XFillTransparenceItem>( XATTR_FILLTRANSPARENCE, false );
1006 sal_uInt16 nTransp = pTranspItem ? pTranspItem->GetValue() : 0;
1007 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
1008 rAreaHlp.InitializeWrite();
1009 rAreaHlp << drawing::FillStyle_SOLID << pColorItem->GetColorValue() << static_cast< sal_Int16 >( nTransp );
1010 rAreaHlp.WriteToPropertySet( rPropSet );
1011 }
1012 break;
1013 case drawing::FillStyle_GRADIENT:
1014 if( const XFillGradientItem* pGradItem = rEscherFmt.mxItemSet->GetItem<XFillGradientItem>( XATTR_FILLGRADIENT, false ) )
1015 {
1016 uno::Any aGradientAny;
1017 if( pGradItem->QueryValue( aGradientAny, MID_FILLGRADIENT ) )
1018 {
1019 OUString aGradName = rGradientTable.InsertObject( aGradientAny );
1020 if( !aGradName.isEmpty() )
1021 {
1022 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
1023 rGradHlp.InitializeWrite();
1024 rGradHlp << drawing::FillStyle_GRADIENT << aGradName;
1025 rGradHlp.WriteToPropertySet( rPropSet );
1026 }
1027 }
1028 }
1029 break;
1030 case drawing::FillStyle_BITMAP:
1031 if( const XFillBitmapItem* pBmpItem = rEscherFmt.mxItemSet->GetItem<XFillBitmapItem>( XATTR_FILLBITMAP, false ) )
1032 {
1033 uno::Any aBitmapAny;
1034 if (pBmpItem->QueryValue(aBitmapAny, MID_BITMAP))
1035 {
1036 OUString aBmpName = rBitmapTable.InsertObject( aBitmapAny );
1037 if( !aBmpName.isEmpty() )
1038 {
1039 /* #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode.
1040 If not passed, detect fill mode from the DFF property 'fill-type'. */
1041 bool bStretch = pPicFmt ? (pPicFmt->mnBmpMode == EXC_CHPICFORMAT_STRETCH) : (nDffFillType == mso_fillPicture);
1042 drawing::BitmapMode eApiBmpMode = bStretch ? drawing::BitmapMode_STRETCH : drawing::BitmapMode_REPEAT;
1043 maBitmapHlp.InitializeWrite();
1044 maBitmapHlp << drawing::FillStyle_BITMAP << aBmpName << eApiBmpMode;
1045 maBitmapHlp.WriteToPropertySet( rPropSet );
1046 }
1047 }
1048 }
1049 break;
1050 default:
1051 OSL_FAIL( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1052 }
1053 }
1054 }
1055 }
1056
WriteMarkerProperties(ScfPropertySet & rPropSet,const XclChMarkerFormat & rMarkerFmt)1057 void XclChPropSetHelper::WriteMarkerProperties(
1058 ScfPropertySet& rPropSet, const XclChMarkerFormat& rMarkerFmt )
1059 {
1060 // symbol style
1061 chart2::Symbol aApiSymbol;
1062 aApiSymbol.Style = chart2::SymbolStyle_STANDARD;
1063 switch( rMarkerFmt.mnMarkerType )
1064 {
1065 case EXC_CHMARKERFORMAT_NOSYMBOL: aApiSymbol.Style = chart2::SymbolStyle_NONE; break;
1066 case EXC_CHMARKERFORMAT_SQUARE: aApiSymbol.StandardSymbol = 0; break; // square
1067 case EXC_CHMARKERFORMAT_DIAMOND: aApiSymbol.StandardSymbol = 1; break; // diamond
1068 case EXC_CHMARKERFORMAT_TRIANGLE: aApiSymbol.StandardSymbol = 3; break; // arrow up
1069 case EXC_CHMARKERFORMAT_CROSS: aApiSymbol.StandardSymbol = 10; break; // X, legacy bow tie
1070 case EXC_CHMARKERFORMAT_STAR: aApiSymbol.StandardSymbol = 12; break; // asterisk, legacy sand glass
1071 case EXC_CHMARKERFORMAT_DOWJ: aApiSymbol.StandardSymbol = 4; break; // arrow right, same as export
1072 case EXC_CHMARKERFORMAT_STDDEV: aApiSymbol.StandardSymbol = 13; break; // horizontal bar, legacy arrow down
1073 case EXC_CHMARKERFORMAT_CIRCLE: aApiSymbol.StandardSymbol = 8; break; // circle, legacy arrow right
1074 case EXC_CHMARKERFORMAT_PLUS: aApiSymbol.StandardSymbol = 11; break; // plus, legacy arrow left
1075 default: break;
1076 }
1077
1078 // symbol size
1079 sal_Int32 nApiSize = XclTools::GetHmmFromTwips( rMarkerFmt.mnMarkerSize );
1080 aApiSymbol.Size = awt::Size( nApiSize, nApiSize );
1081
1082 // symbol colors
1083 aApiSymbol.FillColor = sal_Int32( rMarkerFmt.maFillColor );
1084 aApiSymbol.BorderColor = ::get_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOLINE ) ?
1085 aApiSymbol.FillColor : sal_Int32( rMarkerFmt.maLineColor );
1086
1087 // set the property
1088 rPropSet.SetProperty( EXC_CHPROP_SYMBOL, aApiSymbol );
1089 }
1090
WriteRotationProperties(ScfPropertySet & rPropSet,sal_uInt16 nRotation,bool bSupportsStacked)1091 void XclChPropSetHelper::WriteRotationProperties(
1092 ScfPropertySet& rPropSet, sal_uInt16 nRotation, bool bSupportsStacked )
1093 {
1094 if( nRotation != EXC_CHART_AUTOROTATION )
1095 {
1096 // chart2 handles rotation as double in the range [0,360)
1097 double fAngle = XclTools::GetScRotation( nRotation, 0 ) / 100.0;
1098 rPropSet.SetProperty( EXC_CHPROP_TEXTROTATION, fAngle );
1099 if( bSupportsStacked )
1100 rPropSet.SetProperty( EXC_CHPROP_STACKCHARACTERS, nRotation == EXC_ROT_STACKED );
1101 }
1102 }
1103
1104 // private --------------------------------------------------------------------
1105
GetLineHelper(XclChPropertyMode ePropMode)1106 ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode )
1107 {
1108 switch( ePropMode )
1109 {
1110 case EXC_CHPROPMODE_COMMON: return maLineHlpCommon;
1111 case EXC_CHPROPMODE_LINEARSERIES: return maLineHlpLinear;
1112 case EXC_CHPROPMODE_FILLEDSERIES: return maLineHlpFilled;
1113 default: OSL_FAIL( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1114 }
1115 return maLineHlpCommon;
1116 }
1117
GetAreaHelper(XclChPropertyMode ePropMode)1118 ScfPropSetHelper& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode )
1119 {
1120 switch( ePropMode )
1121 {
1122 case EXC_CHPROPMODE_COMMON: return maAreaHlpCommon;
1123 case EXC_CHPROPMODE_FILLEDSERIES: return maAreaHlpFilled;
1124 default: OSL_FAIL( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1125 }
1126 return maAreaHlpCommon;
1127 }
1128
GetGradientHelper(XclChPropertyMode ePropMode)1129 ScfPropSetHelper& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode )
1130 {
1131 switch( ePropMode )
1132 {
1133 case EXC_CHPROPMODE_COMMON: return maGradHlpCommon;
1134 case EXC_CHPROPMODE_FILLEDSERIES: return maGradHlpFilled;
1135 default: OSL_FAIL( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1136 }
1137 return maGradHlpCommon;
1138 }
1139
GetHatchHelper(XclChPropertyMode ePropMode)1140 ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode )
1141 {
1142 switch( ePropMode )
1143 {
1144 case EXC_CHPROPMODE_COMMON: return maHatchHlpCommon;
1145 case EXC_CHPROPMODE_FILLEDSERIES: return maHatchHlpFilled;
1146 default: OSL_FAIL( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1147 }
1148 return maHatchHlpCommon;
1149 }
1150
1151 namespace {
1152
1153 /* The following local functions implement getting the XShape interface of all
1154 supported title objects (chart and axes). This needs some effort due to the
1155 design of the old Chart1 API used to access these objects. */
1156
1157 /** Returns the drawing shape of the main title, if existing. */
lclGetMainTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)1158 uno::Reference<drawing::XShape> lclGetMainTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)
1159 {
1160 ScfPropertySet aPropSet(rxChart1Doc);
1161 if (rxChart1Doc.is() && aPropSet.GetBoolProperty("HasMainTitle"))
1162 return rxChart1Doc->getTitle();
1163 return uno::Reference<drawing::XShape>();
1164 }
1165
lclGetXAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)1166 uno::Reference<drawing::XShape> lclGetXAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)
1167 {
1168 uno::Reference<chart::XAxisXSupplier> xAxisSupp(rxChart1Doc->getDiagram(), uno::UNO_QUERY);
1169 ScfPropertySet aPropSet(xAxisSupp);
1170 if (xAxisSupp.is() && aPropSet.GetBoolProperty("HasXAxisTitle"))
1171 return xAxisSupp->getXAxisTitle();
1172 return uno::Reference<drawing::XShape>();
1173 }
1174
lclGetYAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)1175 uno::Reference<drawing::XShape> lclGetYAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc )
1176 {
1177 uno::Reference<chart::XAxisYSupplier> xAxisSupp(rxChart1Doc->getDiagram(), uno::UNO_QUERY);
1178 ScfPropertySet aPropSet(xAxisSupp);
1179 if (xAxisSupp.is() && aPropSet.GetBoolProperty("HasYAxisTitle"))
1180 return xAxisSupp->getYAxisTitle();
1181 return uno::Reference<drawing::XShape>();
1182 }
1183
lclGetZAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)1184 uno::Reference<drawing::XShape> lclGetZAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc )
1185 {
1186 uno::Reference<chart::XAxisZSupplier> xAxisSupp(rxChart1Doc->getDiagram(), uno::UNO_QUERY);
1187 ScfPropertySet aPropSet(xAxisSupp);
1188 if (xAxisSupp.is() && aPropSet.GetBoolProperty("HasZAxisTitle"))
1189 return xAxisSupp->getZAxisTitle();
1190 return uno::Reference<drawing::XShape>();
1191 }
1192
lclGetSecXAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)1193 uno::Reference<drawing::XShape> lclGetSecXAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)
1194 {
1195 uno::Reference<chart::XSecondAxisTitleSupplier> xAxisSupp(rxChart1Doc->getDiagram(), uno::UNO_QUERY);
1196 ScfPropertySet aPropSet(xAxisSupp);
1197 if (xAxisSupp.is() && aPropSet.GetBoolProperty("HasSecondaryXAxisTitle"))
1198 return xAxisSupp->getSecondXAxisTitle();
1199 return uno::Reference<drawing::XShape>();
1200 }
1201
lclGetSecYAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)1202 uno::Reference<drawing::XShape> lclGetSecYAxisTitleShape(const uno::Reference<chart::XChartDocument> & rxChart1Doc)
1203 {
1204 uno::Reference<chart::XSecondAxisTitleSupplier> xAxisSupp(rxChart1Doc->getDiagram(), uno::UNO_QUERY);
1205 ScfPropertySet aPropSet(xAxisSupp);
1206 if (xAxisSupp.is() && aPropSet.GetBoolProperty("HasSecondaryYAxisTitle"))
1207 return xAxisSupp->getSecondYAxisTitle();
1208 return uno::Reference<drawing::XShape>();
1209 }
1210
1211 } // namespace
1212
XclChRootData()1213 XclChRootData::XclChRootData()
1214 : mxTypeInfoProv(new XclChTypeInfoProvider)
1215 , mxFmtInfoProv(new XclChFormatInfoProvider)
1216 , mnBorderGapX(0)
1217 , mnBorderGapY(0)
1218 , mfUnitSizeX(0.0)
1219 , mfUnitSizeY(0.0)
1220 {
1221 // remember some title shape getter functions
1222 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ] = lclGetMainTitleShape;
1223 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_X ) ] = lclGetXAxisTitleShape;
1224 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Y ) ] = lclGetYAxisTitleShape;
1225 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Z ) ] = lclGetZAxisTitleShape;
1226 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_X ) ] = lclGetSecXAxisTitleShape;
1227 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_Y ) ] = lclGetSecYAxisTitleShape;
1228 }
1229
~XclChRootData()1230 XclChRootData::~XclChRootData()
1231 {
1232 }
1233
InitConversion(const XclRoot & rRoot,const uno::Reference<chart2::XChartDocument> & rxChartDoc,const tools::Rectangle & rChartRect)1234 void XclChRootData::InitConversion(const XclRoot& rRoot, const uno::Reference<chart2::XChartDocument> & rxChartDoc, const tools::Rectangle& rChartRect)
1235 {
1236 // remember chart document reference and chart shape position/size
1237 OSL_ENSURE( rxChartDoc.is(), "XclChRootData::InitConversion - missing chart document" );
1238 mxChartDoc = rxChartDoc;
1239 maChartRect = rChartRect;
1240
1241 // Excel excludes a border of 5 pixels in each direction from chart area
1242 mnBorderGapX = rRoot.GetHmmFromPixelX( 5.0 );
1243 mnBorderGapY = rRoot.GetHmmFromPixelY( 5.0 );
1244
1245 // size of a chart unit in 1/100 mm
1246 mfUnitSizeX = std::max<double>( maChartRect.GetWidth() - 2 * mnBorderGapX, mnBorderGapX ) / EXC_CHART_TOTALUNITS;
1247 mfUnitSizeY = std::max<double>( maChartRect.GetHeight() - 2 * mnBorderGapY, mnBorderGapY ) / EXC_CHART_TOTALUNITS;
1248
1249 // create object tables
1250 uno::Reference<lang::XMultiServiceFactory> xFactory(mxChartDoc, uno::UNO_QUERY);
1251 mxLineDashTable.reset(new XclChObjectTable(xFactory, SERVICE_DRAWING_DASHTABLE, "Excel line dash "));
1252 mxGradientTable.reset(new XclChObjectTable(xFactory, SERVICE_DRAWING_GRADIENTTABLE, "Excel gradient "));
1253 mxHatchTable.reset(new XclChObjectTable(xFactory, SERVICE_DRAWING_HATCHTABLE, "Excel hatch "));
1254 mxBitmapTable.reset(new XclChObjectTable(xFactory, SERVICE_DRAWING_BITMAPTABLE, "Excel bitmap "));
1255 }
1256
FinishConversion()1257 void XclChRootData::FinishConversion()
1258 {
1259 // forget formatting object tables
1260 mxBitmapTable.reset();
1261 mxHatchTable.reset();
1262 mxGradientTable.reset();
1263 mxLineDashTable.reset();
1264 // forget chart document reference
1265 mxChartDoc.clear();
1266 }
1267
GetTitleShape(const XclChTextKey & rTitleKey) const1268 uno::Reference<drawing::XShape> XclChRootData::GetTitleShape(const XclChTextKey& rTitleKey) const
1269 {
1270 XclChGetShapeFuncMap::const_iterator aIt = maGetShapeFuncs.find( rTitleKey );
1271 OSL_ENSURE( aIt != maGetShapeFuncs.end(), "XclChRootData::GetTitleShape - invalid title key" );
1272 uno::Reference<chart::XChartDocument> xChart1Doc( mxChartDoc, uno::UNO_QUERY );
1273 uno::Reference<drawing::XShape> xTitleShape;
1274 if (xChart1Doc.is() && (aIt != maGetShapeFuncs.end()))
1275 xTitleShape = (aIt->second)(xChart1Doc);
1276 return xTitleShape;
1277 }
1278
1279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1280