xref: /aoo42x/main/sc/source/filter/excel/xlchart.cxx (revision b77af630)
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_scfilt.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