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