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