xref: /trunk/main/sc/source/filter/excel/xlchart.cxx (revision b3f79822)
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 
72 XclChRectangle::XclChRectangle() :
73     mnX( 0 ),
74     mnY( 0 ),
75     mnWidth( 0 ),
76     mnHeight( 0 )
77 {
78 }
79 
80 // ----------------------------------------------------------------------------
81 
82 XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx, sal_uInt16 nPointIdx ) :
83     mnSeriesIdx( nSeriesIdx ),
84     mnPointIdx( nPointIdx )
85 {
86 }
87 
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 
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 
106 XclChFramePos::XclChFramePos() :
107     mnTLMode( EXC_CHFRAMEPOS_PARENT ),
108     mnBRMode( EXC_CHFRAMEPOS_PARENT )
109 {
110 }
111 
112 // ----------------------------------------------------------------------------
113 
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 
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 
134 XclChEscherFormat::XclChEscherFormat()
135 {
136 }
137 
138 XclChEscherFormat::~XclChEscherFormat()
139 {
140 }
141 
142 // ----------------------------------------------------------------------------
143 
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 
153 XclChFrame::XclChFrame() :
154     mnFormat( EXC_CHFRAME_STANDARD ),
155     mnFlags( EXC_CHFRAME_AUTOSIZE | EXC_CHFRAME_AUTOPOS )
156 {
157 }
158 
159 // Source links ===============================================================
160 
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 
171 XclChObjectLink::XclChObjectLink() :
172     mnTarget( EXC_CHOBJLINK_NONE )
173 {
174 }
175 
176 // ----------------------------------------------------------------------------
177 
178 XclChFrLabelProps::XclChFrLabelProps() :
179     mnFlags( 0 )
180 {
181 }
182 
183 // ----------------------------------------------------------------------------
184 
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 
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 
209 XclCh3dDataFormat::XclCh3dDataFormat() :
210     mnBase( EXC_CH3DDATAFORMAT_RECT ),
211     mnTop( EXC_CH3DDATAFORMAT_STRAIGHT )
212 {
213 }
214 
215 // ----------------------------------------------------------------------------
216 
217 XclChDataFormat::XclChDataFormat() :
218     mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT ),
219     mnFlags( 0 )
220 {
221 }
222 
223 // ----------------------------------------------------------------------------
224 
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 
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 
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 
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 
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 
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 
301 XclChTypeGroup::XclChTypeGroup() :
302     mnFlags( 0 ),
303     mnGroupIdx( EXC_CHSERGROUP_NONE )
304 {
305 }
306 
307 // ----------------------------------------------------------------------------
308 
309 XclChProperties::XclChProperties() :
310     mnFlags( 0 ),
311     mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP )
312 {
313 }
314 
315 // Axes =======================================================================
316 
317 XclChLabelRange::XclChLabelRange() :
318     mnCross( 1 ),
319     mnLabelFreq( 1 ),
320     mnTickFreq( 1 ),
321     mnFlags( 0 )
322 {
323 }
324 
325 // ----------------------------------------------------------------------------
326 
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 
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 
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 
372 XclChAxis::XclChAxis() :
373     mnType( EXC_CHAXIS_NONE )
374 {
375 }
376 
377 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 
391 XclChAxesSet::XclChAxesSet() :
392     mnAxesSetId( EXC_CHAXESSET_PRIMARY )
393 {
394 }
395 
396 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 
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 
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 
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 
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 
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 
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 
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 
510 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 
556 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo ) :
557     XclChTypeInfo( rTypeInfo ),
558     mb3dChart( false ),
559     mbSpline( false )
560 {
561 }
562 
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 
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 
579 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 
586 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 
596 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 
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 
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 
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 
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 
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 
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 
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 
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_CIRCLE;    break;  // arrow right
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                     default:    rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
945                 }
946             break;
947             default:
948                 rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx );
949         }
950         bool bHasFillColor = XclChartHelper::HasMarkerFillColor( rMarkerFmt.mnMarkerType );
951         ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOFILL, !bHasFillColor );
952 
953         // symbol size
954         sal_Int32 nApiSize = (aApiSymbol.Size.Width + aApiSymbol.Size.Height + 1) / 2;
955         rMarkerFmt.mnMarkerSize = XclTools::GetTwipsFromHmm( nApiSize );
956 
957         // symbol colors
958         rMarkerFmt.maLineColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.BorderColor );
959         rMarkerFmt.maFillColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.FillColor );
960     }
961 }
962 
963 sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPropSet, bool bSupportsStacked )
964 {
965     // chart2 handles rotation as double in the range [0,360)
966     double fAngle = 0.0;
967     rPropSet.GetProperty( fAngle, EXC_CHPROP_TEXTROTATION );
968     bool bStacked = bSupportsStacked && rPropSet.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS );
969     return bStacked ? EXC_ROT_STACKED :
970         XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) );
971 }
972 
973 // write properties -----------------------------------------------------------
974 
975 void XclChPropSetHelper::WriteLineProperties(
976         ScfPropertySet& rPropSet, XclChObjectTable& rDashTable,
977         const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode )
978 {
979     namespace cssd = ::com::sun::star::drawing;
980 
981     // line width
982     sal_Int32 nApiWidth = 0;    // 0 is the width of a hair line
983     switch( rLineFmt.mnWeight )
984     {
985         case EXC_CHLINEFORMAT_SINGLE:   nApiWidth = 35;     break;
986         case EXC_CHLINEFORMAT_DOUBLE:   nApiWidth = 70;     break;
987         case EXC_CHLINEFORMAT_TRIPLE:   nApiWidth = 105;    break;
988     }
989 
990     // line style
991     cssd::LineStyle eApiStyle = cssd::LineStyle_NONE;
992     sal_Int16 nApiTrans = 0;
993     sal_Int32 nDotLen = ::std::min< sal_Int32 >( rLineFmt.mnWeight + 105, 210 );
994     cssd::LineDash aApiDash( cssd::DashStyle_RECT, 0, nDotLen, 0, 4 * nDotLen, nDotLen );
995 
996     switch( rLineFmt.mnPattern )
997     {
998         case EXC_CHLINEFORMAT_SOLID:
999             eApiStyle = cssd::LineStyle_SOLID;
1000         break;
1001         case EXC_CHLINEFORMAT_DARKTRANS:
1002             eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 25;
1003         break;
1004         case EXC_CHLINEFORMAT_MEDTRANS:
1005             eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 50;
1006         break;
1007         case EXC_CHLINEFORMAT_LIGHTTRANS:
1008             eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 75;
1009         break;
1010         case EXC_CHLINEFORMAT_DASH:
1011             eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1;
1012         break;
1013         case EXC_CHLINEFORMAT_DOT:
1014             eApiStyle = cssd::LineStyle_DASH; aApiDash.Dots = 1;
1015         break;
1016         case EXC_CHLINEFORMAT_DASHDOT:
1017             eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = aApiDash.Dots = 1;
1018         break;
1019         case EXC_CHLINEFORMAT_DASHDOTDOT:
1020             eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1; aApiDash.Dots = 2;
1021         break;
1022     }
1023 
1024     // line color
1025     sal_Int32 nApiColor = ScfApiHelper::ConvertToApiColor( rLineFmt.maColor );
1026 
1027     // try to insert the dash style and receive its name
1028     Any aDashNameAny;
1029     if( eApiStyle == cssd::LineStyle_DASH )
1030     {
1031         OUString aDashName = rDashTable.InsertObject( ::com::sun::star::uno::makeAny( aApiDash ) );
1032         if( aDashName.getLength() )
1033             aDashNameAny <<= aDashName;
1034     }
1035 
1036     // write the properties
1037     ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode );
1038     rLineHlp.InitializeWrite();
1039     rLineHlp << eApiStyle << nApiWidth << nApiColor << nApiTrans << aDashNameAny;
1040     rLineHlp.WriteToPropertySet( rPropSet );
1041 }
1042 
1043 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet& rPropSet,
1044         const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode )
1045 {
1046     namespace cssd = ::com::sun::star::drawing;
1047     cssd::FillStyle eFillStyle = cssd::FillStyle_NONE;
1048     Color aColor;
1049     sal_Int16 nTransparency = 0;
1050 
1051     // fill color
1052     if( rAreaFmt.mnPattern != EXC_PATT_NONE )
1053     {
1054         eFillStyle = cssd::FillStyle_SOLID;
1055         aColor = XclTools::GetPatternColor( rAreaFmt.maPattColor, rAreaFmt.maBackColor, rAreaFmt.mnPattern );
1056     }
1057 
1058     // write the properties
1059     ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
1060     rAreaHlp.InitializeWrite();
1061     rAreaHlp << eFillStyle << aColor << nTransparency;
1062     rAreaHlp.WriteToPropertySet( rPropSet );
1063 }
1064 
1065 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet,
1066         XclChObjectTable& rGradientTable, XclChObjectTable& /*rHatchTable*/, XclChObjectTable& rBitmapTable,
1067         const XclChEscherFormat& rEscherFmt, const XclChPicFormat* pPicFmt,
1068         sal_uInt32 nDffFillType, XclChPropertyMode ePropMode )
1069 {
1070     if( rEscherFmt.mxItemSet.is() )
1071     {
1072         if( const XFillStyleItem* pStyleItem = static_cast< const XFillStyleItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLSTYLE, sal_False ) ) )
1073         {
1074             switch( pStyleItem->GetValue() )
1075             {
1076                 case XFILL_SOLID:
1077                     // #i84812# Excel 2007 writes Escher properties for solid fill
1078                     if( const XFillColorItem* pColorItem = static_cast< const XFillColorItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLCOLOR, sal_False ) ) )
1079                     {
1080                         namespace cssd = ::com::sun::star::drawing;
1081                         // get solid transparence too
1082                         const XFillTransparenceItem* pTranspItem = static_cast< const XFillTransparenceItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLTRANSPARENCE, sal_False ) );
1083                         sal_uInt16 nTransp = pTranspItem ? pTranspItem->GetValue() : 0;
1084                         ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode );
1085                         rAreaHlp.InitializeWrite();
1086                         rAreaHlp << cssd::FillStyle_SOLID << pColorItem->GetColorValue() << static_cast< sal_Int16 >( nTransp );
1087                         rAreaHlp.WriteToPropertySet( rPropSet );
1088                     }
1089                 break;
1090                 case XFILL_GRADIENT:
1091                     if( const XFillGradientItem* pGradItem = static_cast< const XFillGradientItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLGRADIENT, sal_False ) ) )
1092                     {
1093                         Any aGradientAny;
1094                         if( pGradItem->QueryValue( aGradientAny, MID_FILLGRADIENT ) )
1095                         {
1096                             OUString aGradName = rGradientTable.InsertObject( aGradientAny );
1097                             if( aGradName.getLength() )
1098                             {
1099                                 namespace cssd = ::com::sun::star::drawing;
1100                                 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode );
1101                                 rGradHlp.InitializeWrite();
1102                                 rGradHlp << cssd::FillStyle_GRADIENT << aGradName;
1103                                 rGradHlp.WriteToPropertySet( rPropSet );
1104                             }
1105                         }
1106                     }
1107                 break;
1108                 case XFILL_BITMAP:
1109                     if( const XFillBitmapItem* pBmpItem = static_cast< const XFillBitmapItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLBITMAP, sal_False ) ) )
1110                     {
1111                         Any aBitmapAny;
1112                         if( pBmpItem->QueryValue( aBitmapAny, MID_GRAFURL ) )
1113                         {
1114                             OUString aBmpName = rBitmapTable.InsertObject( aBitmapAny );
1115                             if( aBmpName.getLength() )
1116                             {
1117                                 namespace cssd = ::com::sun::star::drawing;
1118                                 /*  #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode.
1119                                     If not passed, detect fill mode from the DFF property 'fill-type'. */
1120                                 bool bStretch = pPicFmt ? (pPicFmt->mnBmpMode == EXC_CHPICFORMAT_STRETCH) : (nDffFillType == mso_fillPicture);
1121                                 cssd::BitmapMode eApiBmpMode = bStretch ? cssd::BitmapMode_STRETCH : cssd::BitmapMode_REPEAT;
1122                                 maBitmapHlp.InitializeWrite();
1123                                 maBitmapHlp << cssd::FillStyle_BITMAP << aBmpName << eApiBmpMode;
1124                                 maBitmapHlp.WriteToPropertySet( rPropSet );
1125                             }
1126                         }
1127                     }
1128                 break;
1129                 default:
1130                     DBG_ERRORFILE( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" );
1131             }
1132         }
1133     }
1134 }
1135 
1136 void XclChPropSetHelper::WriteMarkerProperties(
1137         ScfPropertySet& rPropSet, const XclChMarkerFormat& rMarkerFmt )
1138 {
1139     namespace cssc = ::com::sun::star::chart2;
1140     namespace cssa = ::com::sun::star::awt;
1141 
1142     // symbol style
1143     cssc::Symbol aApiSymbol;
1144     aApiSymbol.Style = cssc::SymbolStyle_STANDARD;
1145     switch( rMarkerFmt.mnMarkerType )
1146     {
1147         case EXC_CHMARKERFORMAT_NOSYMBOL:   aApiSymbol.Style = cssc::SymbolStyle_NONE;  break;
1148         case EXC_CHMARKERFORMAT_SQUARE:     aApiSymbol.StandardSymbol = 0;              break;  // square
1149         case EXC_CHMARKERFORMAT_DIAMOND:    aApiSymbol.StandardSymbol = 1;              break;  // diamond
1150         case EXC_CHMARKERFORMAT_TRIANGLE:   aApiSymbol.StandardSymbol = 3;              break;  // arrow up
1151         case EXC_CHMARKERFORMAT_CROSS:      aApiSymbol.StandardSymbol = 6;              break;  // bow tie
1152         case EXC_CHMARKERFORMAT_STAR:       aApiSymbol.StandardSymbol = 7;              break;  // sand glass
1153         case EXC_CHMARKERFORMAT_DOWJ:       aApiSymbol.StandardSymbol = 4;              break;  // arrow right
1154         case EXC_CHMARKERFORMAT_STDDEV:     aApiSymbol.StandardSymbol = 2;              break;  // arrow down
1155         case EXC_CHMARKERFORMAT_CIRCLE:     aApiSymbol.StandardSymbol = 4;              break;  // arrow right
1156         case EXC_CHMARKERFORMAT_PLUS:       aApiSymbol.StandardSymbol = 5;              break;  // arrow left
1157     }
1158 
1159     // symbol size
1160     sal_Int32 nApiSize = XclTools::GetHmmFromTwips( rMarkerFmt.mnMarkerSize );
1161     aApiSymbol.Size = cssa::Size( nApiSize, nApiSize );
1162 
1163     // symbol colors
1164     aApiSymbol.FillColor = ScfApiHelper::ConvertToApiColor( rMarkerFmt.maFillColor );
1165     aApiSymbol.BorderColor = ::get_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOLINE ) ?
1166         aApiSymbol.FillColor : ScfApiHelper::ConvertToApiColor( rMarkerFmt.maLineColor );
1167 
1168     // set the property
1169     rPropSet.SetProperty( EXC_CHPROP_SYMBOL, aApiSymbol );
1170 }
1171 
1172 void XclChPropSetHelper::WriteRotationProperties(
1173         ScfPropertySet& rPropSet, sal_uInt16 nRotation, bool bSupportsStacked )
1174 {
1175     if( nRotation != EXC_CHART_AUTOROTATION )
1176     {
1177         // chart2 handles rotation as double in the range [0,360)
1178         double fAngle = XclTools::GetScRotation( nRotation, 0 ) / 100.0;
1179         rPropSet.SetProperty( EXC_CHPROP_TEXTROTATION, fAngle );
1180         if( bSupportsStacked )
1181             rPropSet.SetProperty( EXC_CHPROP_STACKCHARACTERS, nRotation == EXC_ROT_STACKED );
1182     }
1183 }
1184 
1185 // private --------------------------------------------------------------------
1186 
1187 ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode )
1188 {
1189     switch( ePropMode )
1190     {
1191         case EXC_CHPROPMODE_COMMON:         return maLineHlpCommon;
1192         case EXC_CHPROPMODE_LINEARSERIES:   return maLineHlpLinear;
1193         case EXC_CHPROPMODE_FILLEDSERIES:   return maLineHlpFilled;
1194         default: DBG_ERRORFILE( "XclChPropSetHelper::GetLineHelper - unknown property mode" );
1195     }
1196     return maLineHlpCommon;
1197 }
1198 
1199 ScfPropSetHelper& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode )
1200 {
1201     switch( ePropMode )
1202     {
1203         case EXC_CHPROPMODE_COMMON:         return maAreaHlpCommon;
1204         case EXC_CHPROPMODE_FILLEDSERIES:   return maAreaHlpFilled;
1205         default:    DBG_ERRORFILE( "XclChPropSetHelper::GetAreaHelper - unknown property mode" );
1206     }
1207     return maAreaHlpCommon;
1208 }
1209 
1210 ScfPropSetHelper& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode )
1211 {
1212     switch( ePropMode )
1213     {
1214         case EXC_CHPROPMODE_COMMON:         return maGradHlpCommon;
1215         case EXC_CHPROPMODE_FILLEDSERIES:   return maGradHlpFilled;
1216         default:    DBG_ERRORFILE( "XclChPropSetHelper::GetGradientHelper - unknown property mode" );
1217     }
1218     return maGradHlpCommon;
1219 }
1220 
1221 ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode )
1222 {
1223     switch( ePropMode )
1224     {
1225         case EXC_CHPROPMODE_COMMON:         return maHatchHlpCommon;
1226         case EXC_CHPROPMODE_FILLEDSERIES:   return maHatchHlpFilled;
1227         default:    DBG_ERRORFILE( "XclChPropSetHelper::GetHatchHelper - unknown property mode" );
1228     }
1229     return maHatchHlpCommon;
1230 }
1231 
1232 // ============================================================================
1233 
1234 namespace {
1235 
1236 /*  The following local functions implement getting the XShape interface of all
1237     supported title objects (chart and axes). This needs some effort due to the
1238     design of the old Chart1 API used to access these objects. */
1239 
1240 /** A code fragment that returns a shape object from the passed shape supplier
1241     using the specified interface function. Checks a boolean property first. */
1242 #define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
1243     ScfPropertySet aPropSet( shape_supplier ); \
1244     if( shape_supplier.is() && aPropSet.GetBoolProperty( CREATE_OUSTRING( #property_name ) ) ) \
1245         return shape_supplier->supplier_func(); \
1246     return Reference< XShape >(); \
1247 
1248 /** Implements a function returning the drawing shape of an axis title, if
1249     existing, using the specified API interface and its function. */
1250 #define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
1251 Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
1252 { \
1253     Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
1254     EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
1255 }
1256 
1257 /** Returns the drawing shape of the main title, if existing. */
1258 Reference< XShape > lclGetMainTitleShape( const Reference< cssc::XChartDocument >& rxChart1Doc )
1259 {
1260     EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle )
1261 }
1262 
1263 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle )
1264 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle )
1265 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle )
1266 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle )
1267 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle )
1268 
1269 #undef EXC_DEFINEFUNC_GETAXISTITLESHAPE
1270 #undef EXC_IMPLEMENT_GETTITLESHAPE
1271 
1272 } // namespace
1273 
1274 // ----------------------------------------------------------------------------
1275 
1276 XclChRootData::XclChRootData() :
1277     mxTypeInfoProv( new XclChTypeInfoProvider ),
1278     mxFmtInfoProv( new XclChFormatInfoProvider ),
1279     mnBorderGapX( 0 ),
1280     mnBorderGapY( 0 )
1281 {
1282     // remember some title shape getter functions
1283     maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ] = lclGetMainTitleShape;
1284     maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_X ) ] = lclGetXAxisTitleShape;
1285     maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Y ) ] = lclGetYAxisTitleShape;
1286     maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Z ) ] = lclGetZAxisTitleShape;
1287     maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_X ) ] = lclGetSecXAxisTitleShape;
1288     maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_Y ) ] = lclGetSecYAxisTitleShape;
1289 }
1290 
1291 XclChRootData::~XclChRootData()
1292 {
1293 }
1294 
1295 void XclChRootData::InitConversion( const XclRoot& rRoot, const Reference< XChartDocument >& rxChartDoc, const Rectangle& rChartRect )
1296 {
1297     // remember chart document reference and chart shape position/size
1298     DBG_ASSERT( rxChartDoc.is(), "XclChRootData::InitConversion - missing chart document" );
1299     mxChartDoc = rxChartDoc;
1300     maChartRect = rChartRect;
1301 
1302     // Excel excludes a border of 5 pixels in each direction from chart area
1303     mnBorderGapX = rRoot.GetHmmFromPixelX( 5.0 );
1304     mnBorderGapY = rRoot.GetHmmFromPixelY( 5.0 );
1305 
1306     // size of a chart unit in 1/100 mm
1307     mfUnitSizeX = ::std::max< double >( maChartRect.GetWidth() - 2 * mnBorderGapX, mnBorderGapX ) / EXC_CHART_TOTALUNITS;
1308     mfUnitSizeY = ::std::max< double >( maChartRect.GetHeight() - 2 * mnBorderGapY, mnBorderGapY ) / EXC_CHART_TOTALUNITS;
1309 
1310     // create object tables
1311     Reference< XMultiServiceFactory > xFactory( mxChartDoc, UNO_QUERY );
1312     mxLineDashTable.reset( new XclChObjectTable(
1313         xFactory, SERVICE_DRAWING_DASHTABLE, CREATE_OUSTRING( "Excel line dash " ) ) );
1314     mxGradientTable.reset( new XclChObjectTable(
1315         xFactory, SERVICE_DRAWING_GRADIENTTABLE, CREATE_OUSTRING( "Excel gradient " ) ) );
1316     mxHatchTable.reset( new XclChObjectTable(
1317         xFactory, SERVICE_DRAWING_HATCHTABLE, CREATE_OUSTRING( "Excel hatch " ) ) );
1318     mxBitmapTable.reset( new XclChObjectTable(
1319         xFactory, SERVICE_DRAWING_BITMAPTABLE, CREATE_OUSTRING( "Excel bitmap " ) ) );
1320 }
1321 
1322 void XclChRootData::FinishConversion()
1323 {
1324     // forget formatting object tables
1325     mxBitmapTable.reset();
1326     mxHatchTable.reset();
1327     mxGradientTable.reset();
1328     mxLineDashTable.reset();
1329     // forget chart document reference
1330     mxChartDoc.clear();
1331 }
1332 
1333 Reference< XShape > XclChRootData::GetTitleShape( const XclChTextKey& rTitleKey ) const
1334 {
1335     XclChGetShapeFuncMap::const_iterator aIt = maGetShapeFuncs.find( rTitleKey );
1336     OSL_ENSURE( aIt != maGetShapeFuncs.end(), "XclChRootData::GetTitleShape - invalid title key" );
1337     Reference< cssc::XChartDocument > xChart1Doc( mxChartDoc, UNO_QUERY );
1338     Reference< XShape > xTitleShape;
1339     if( xChart1Doc.is() && (aIt != maGetShapeFuncs.end()) )
1340         xTitleShape = (aIt->second)( xChart1Doc );
1341     return xTitleShape;
1342 }
1343 
1344 // ============================================================================
1345