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_chart2.hxx"
26 #include "CharacterPropertyItemConverter.hxx"
27 #include "SchWhichPairs.hxx"
28 #include "macros.hxx"
29 #include "ItemPropertyMap.hxx"
30 #include "RelativeSizeHelper.hxx"
31 #include <editeng/memberids.hrc>
32 #include <editeng/eeitem.hxx>
33 #include <editeng/udlnitem.hxx>
34 #include <editeng/fontitem.hxx>
35 #include <editeng/crsditem.hxx>
36 #include <editeng/postitem.hxx>
37 #include <editeng/wghtitem.hxx>
38 #include <editeng/fhgtitem.hxx>
39 #include <svl/stritem.hxx>
40
41 #include <com/sun/star/beans/XPropertyState.hpp>
42 #include <com/sun/star/chart2/XFormattedString.hpp>
43
44 using namespace ::com::sun::star;
45
46 namespace
47 {
lcl_GetCharacterPropertyPropertyMap()48 ::comphelper::ItemPropertyMapType & lcl_GetCharacterPropertyPropertyMap()
49 {
50 static ::comphelper::ItemPropertyMapType aCharacterPropertyMap(
51 ::comphelper::MakeItemPropertyMap
52 IPM_MAP_ENTRY( EE_CHAR_COLOR, "CharColor", 0 )
53 IPM_MAP_ENTRY( EE_CHAR_LANGUAGE, "CharLocale", MID_LANG_LOCALE )
54 IPM_MAP_ENTRY( EE_CHAR_LANGUAGE_CJK, "CharLocaleAsian", MID_LANG_LOCALE )
55 IPM_MAP_ENTRY( EE_CHAR_LANGUAGE_CTL, "CharLocaleComplex", MID_LANG_LOCALE )
56 // IPM_MAP_ENTRY( EE_CHAR_FONTHEIGHT, "CharHeight", 0 )
57 // IPM_MAP_ENTRY( EE_CHAR_ITALIC, "CharPosture", 0 )
58 // IPM_MAP_ENTRY( EE_CHAR_WEIGHT, "CharWeight", 0 )
59
60 IPM_MAP_ENTRY( EE_CHAR_STRIKEOUT, "CharStrikeout", MID_CROSS_OUT )
61 IPM_MAP_ENTRY( EE_CHAR_WLM, "CharWordMode", 0 )
62 IPM_MAP_ENTRY( EE_CHAR_SHADOW, "CharShadowed", 0 )
63 IPM_MAP_ENTRY( EE_CHAR_RELIEF, "CharRelief", 0 )
64 IPM_MAP_ENTRY( EE_CHAR_OUTLINE, "CharContoured", 0 )
65 IPM_MAP_ENTRY( EE_CHAR_EMPHASISMARK, "CharEmphasis", 0 )
66
67 IPM_MAP_ENTRY( EE_PARA_WRITINGDIR, "WritingMode", 0 )
68
69 // IPM_MAP_ENTRY( EE_CHAR_FONTHEIGHT_CJK, "CharHeightAsian", 0 )
70 // IPM_MAP_ENTRY( EE_CHAR_FONTHEIGHT_CTL, "CharHeightComplex", 0 )
71 // IPM_MAP_ENTRY( EE_CHAR_WEIGHT_CJK, "CharWeightAsian", 0 )
72 // IPM_MAP_ENTRY( EE_CHAR_WEIGHT_CTL, "CharWeightComplex", 0 )
73 // IPM_MAP_ENTRY( EE_CHAR_ITALIC_CJK, "CharPostureAsian", 0 )
74 // IPM_MAP_ENTRY( EE_CHAR_ITALIC_CTL, "CharPostureComplex", 0 )
75 IPM_MAP_ENTRY( EE_PARA_ASIANCJKSPACING, "ParaIsCharacterDistance", 0 )
76 );
77
78 return aCharacterPropertyMap;
79 }
80 } // anonymous namespace
81
82 // ========================================
83
84 namespace chart
85 {
86 namespace wrapper
87 {
88
CharacterPropertyItemConverter(const uno::Reference<beans::XPropertySet> & rPropertySet,SfxItemPool & rItemPool)89 CharacterPropertyItemConverter::CharacterPropertyItemConverter(
90 const uno::Reference< beans::XPropertySet > & rPropertySet,
91 SfxItemPool& rItemPool ) :
92 ItemConverter( rPropertySet, rItemPool )
93 {}
94
CharacterPropertyItemConverter(const uno::Reference<beans::XPropertySet> & rPropertySet,SfxItemPool & rItemPool,::std::auto_ptr<awt::Size> pRefSize,const::rtl::OUString & rRefSizePropertyName,const uno::Reference<beans::XPropertySet> & rRefSizePropSet)95 CharacterPropertyItemConverter::CharacterPropertyItemConverter(
96 const uno::Reference< beans::XPropertySet > & rPropertySet,
97 SfxItemPool& rItemPool,
98 ::std::auto_ptr< awt::Size > pRefSize,
99 const ::rtl::OUString & rRefSizePropertyName,
100 const uno::Reference< beans::XPropertySet > & rRefSizePropSet ) :
101 ItemConverter( rPropertySet, rItemPool ),
102 m_pRefSize( pRefSize ),
103 m_aRefSizePropertyName( rRefSizePropertyName ),
104 m_xRefSizePropSet( rRefSizePropSet.is() ? rRefSizePropSet : rPropertySet )
105 {}
106
~CharacterPropertyItemConverter()107 CharacterPropertyItemConverter::~CharacterPropertyItemConverter()
108 {}
109
GetWhichPairs() const110 const sal_uInt16 * CharacterPropertyItemConverter::GetWhichPairs() const
111 {
112 return nCharacterPropertyWhichPairs;
113 }
114
GetItemProperty(tWhichIdType nWhichId,tPropertyNameWithMemberId & rOutProperty) const115 bool CharacterPropertyItemConverter::GetItemProperty( tWhichIdType nWhichId, tPropertyNameWithMemberId & rOutProperty ) const
116 {
117 ::comphelper::ItemPropertyMapType & rMap( lcl_GetCharacterPropertyPropertyMap());
118 ::comphelper::ItemPropertyMapType::const_iterator aIt( rMap.find( nWhichId ));
119
120 if( aIt == rMap.end())
121 return false;
122
123 rOutProperty =(*aIt).second;
124 return true;
125 }
126
FillSpecialItem(sal_uInt16 nWhichId,SfxItemSet & rOutItemSet) const127 void CharacterPropertyItemConverter::FillSpecialItem(
128 sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const
129 throw( uno::Exception )
130 {
131 switch( nWhichId )
132 {
133 case EE_CHAR_FONTINFO:
134 case EE_CHAR_FONTINFO_CJK:
135 case EE_CHAR_FONTINFO_CTL:
136 {
137 ::rtl::OUString aPostfix;
138 if( nWhichId == EE_CHAR_FONTINFO_CJK )
139 aPostfix = C2U( "Asian" );
140 else if( nWhichId == EE_CHAR_FONTINFO_CTL )
141 aPostfix = C2U( "Complex" );
142
143 SvxFontItem aItem( nWhichId );
144
145 aItem.PutValue( GetPropertySet()->getPropertyValue( C2U( "CharFontName" ) + aPostfix),
146 MID_FONT_FAMILY_NAME );
147 aItem.PutValue( GetPropertySet()->getPropertyValue( C2U( "CharFontFamily" ) + aPostfix),
148 MID_FONT_FAMILY );
149 aItem.PutValue( GetPropertySet()->getPropertyValue( C2U( "CharFontStyleName" ) + aPostfix),
150 MID_FONT_STYLE_NAME );
151 aItem.PutValue( GetPropertySet()->getPropertyValue( C2U( "CharFontCharSet" ) + aPostfix),
152 MID_FONT_CHAR_SET );
153 aItem.PutValue( GetPropertySet()->getPropertyValue( C2U( "CharFontPitch" ) + aPostfix),
154 MID_FONT_PITCH );
155
156 rOutItemSet.Put( aItem );
157 }
158 break;
159
160 case EE_CHAR_UNDERLINE:
161 {
162 SvxUnderlineItem aItem(UNDERLINE_NONE, EE_CHAR_UNDERLINE);
163 bool bModified = false;
164
165 uno::Any aValue( GetPropertySet()->getPropertyValue( C2U( "CharUnderline" )));
166 if( aValue.hasValue())
167 {
168 aItem.PutValue( aValue, MID_TL_STYLE );
169 bModified = true;
170 }
171
172 aValue = GetPropertySet()->getPropertyValue( C2U( "CharUnderlineHasColor" ));
173 if( aValue.hasValue() &&
174 ( *reinterpret_cast< const sal_Bool * >( aValue.getValue()) != sal_False ))
175 {
176 aItem.PutValue( aValue, MID_TL_HASCOLOR );
177 bModified = true;
178 }
179
180 aValue = GetPropertySet()->getPropertyValue( C2U( "CharUnderlineColor" ));
181 if( aValue.hasValue())
182 {
183 aItem.PutValue( aValue, MID_TL_COLOR );
184 bModified = true;
185 }
186
187 if( bModified )
188 rOutItemSet.Put( aItem );
189 }
190 break;
191
192 case EE_CHAR_OVERLINE:
193 {
194 SvxOverlineItem aItem( UNDERLINE_NONE, EE_CHAR_OVERLINE );
195 bool bModified = false;
196
197 uno::Any aValue( GetPropertySet()->getPropertyValue( C2U( "CharOverline" ) ) );
198 if ( aValue.hasValue() )
199 {
200 aItem.PutValue( aValue, MID_TL_STYLE );
201 bModified = true;
202 }
203
204 aValue = GetPropertySet()->getPropertyValue( C2U( "CharOverlineHasColor" ) );
205 if ( aValue.hasValue() &&
206 ( *reinterpret_cast< const sal_Bool* >( aValue.getValue() ) != sal_False ) )
207 {
208 aItem.PutValue( aValue, MID_TL_HASCOLOR );
209 bModified = true;
210 }
211
212 aValue = GetPropertySet()->getPropertyValue( C2U( "CharOverlineColor" ) );
213 if ( aValue.hasValue() )
214 {
215 aItem.PutValue( aValue, MID_TL_COLOR );
216 bModified = true;
217 }
218
219 if ( bModified )
220 {
221 rOutItemSet.Put( aItem );
222 }
223 }
224 break;
225
226 case EE_CHAR_ITALIC:
227 case EE_CHAR_ITALIC_CJK:
228 case EE_CHAR_ITALIC_CTL:
229 {
230 ::rtl::OUString aPostfix;
231 if( nWhichId == EE_CHAR_ITALIC_CJK )
232 aPostfix = C2U( "Asian" );
233 else if( nWhichId == EE_CHAR_ITALIC_CTL )
234 aPostfix = C2U( "Complex" );
235
236 SvxPostureItem aItem( ITALIC_NONE, nWhichId );
237
238 uno::Any aValue( GetPropertySet()->getPropertyValue( C2U( "CharPosture" ) + aPostfix));
239 if( aValue.hasValue())
240 {
241 aItem.PutValue( aValue, MID_POSTURE );
242 rOutItemSet.Put( aItem );
243 }
244 }
245 break;
246
247 case EE_CHAR_WEIGHT:
248 case EE_CHAR_WEIGHT_CJK:
249 case EE_CHAR_WEIGHT_CTL:
250 {
251 ::rtl::OUString aPostfix;
252 if( nWhichId == EE_CHAR_WEIGHT_CJK )
253 aPostfix = C2U( "Asian" );
254 else if( nWhichId == EE_CHAR_WEIGHT_CTL )
255 aPostfix = C2U( "Complex" );
256
257 SvxWeightItem aItem( WEIGHT_NORMAL, nWhichId );
258
259 uno::Any aValue( GetPropertySet()->getPropertyValue( C2U( "CharWeight" ) + aPostfix));
260 if( aValue.hasValue())
261 {
262 aItem.PutValue( aValue, MID_WEIGHT );
263 rOutItemSet.Put( aItem );
264 }
265 }
266 break;
267
268 case EE_CHAR_FONTHEIGHT:
269 case EE_CHAR_FONTHEIGHT_CJK:
270 case EE_CHAR_FONTHEIGHT_CTL:
271 {
272 ::rtl::OUString aPostfix;
273 if( nWhichId == EE_CHAR_FONTHEIGHT_CJK )
274 aPostfix = C2U( "Asian" );
275 else if( nWhichId == EE_CHAR_FONTHEIGHT_CTL )
276 aPostfix = C2U( "Complex" );
277
278 SvxFontHeightItem aItem( 240, 100, nWhichId );
279
280 try
281 {
282 uno::Any aValue( GetPropertySet()->getPropertyValue( C2U( "CharHeight" ) + aPostfix ));
283 float fHeight;
284 if( aValue >>= fHeight )
285 {
286 if( m_pRefSize.get())
287 {
288 awt::Size aOldRefSize;
289 if( GetRefSizePropertySet()->getPropertyValue( m_aRefSizePropertyName ) >>= aOldRefSize )
290 {
291 // calculate font height in view
292 fHeight = static_cast< float >(
293 RelativeSizeHelper::calculate( fHeight, aOldRefSize, *m_pRefSize ));
294 aValue <<= fHeight;
295 }
296 }
297
298 aItem.PutValue( aValue, MID_FONTHEIGHT );
299 rOutItemSet.Put( aItem );
300 }
301 }
302 catch( uno::Exception & ex )
303 {
304 ASSERT_EXCEPTION( ex );
305 }
306 }
307 break;
308
309 case SID_CHAR_DLG_PREVIEW_STRING:
310 {
311 uno::Reference< chart2::XFormattedString > xFormattedString( GetPropertySet(), uno::UNO_QUERY );
312 if( xFormattedString.is() )
313 {
314 ::rtl::OUString aString = xFormattedString->getString();
315 rOutItemSet.Put( SfxStringItem( nWhichId, aString ) );
316 }
317 else
318 rOutItemSet.Put( SfxStringItem( nWhichId, C2U( "" ) ) );
319 }
320 break;
321
322 case EE_PARA_FORBIDDENRULES:
323 case EE_PARA_HANGINGPUNCTUATION:
324 rOutItemSet.DisableItem( nWhichId );
325 break;
326 }
327 }
328
ApplySpecialItem(sal_uInt16 nWhichId,const SfxItemSet & rItemSet)329 bool CharacterPropertyItemConverter::ApplySpecialItem(
330 sal_uInt16 nWhichId, const SfxItemSet & rItemSet )
331 throw( uno::Exception )
332 {
333 bool bChanged = false;
334 uno::Any aValue;
335
336 switch( nWhichId )
337 {
338 case EE_CHAR_FONTINFO:
339 case EE_CHAR_FONTINFO_CJK:
340 case EE_CHAR_FONTINFO_CTL:
341 {
342 ::rtl::OUString aPostfix;
343 if( nWhichId == EE_CHAR_FONTINFO_CJK )
344 aPostfix = C2U( "Asian" );
345 else if( nWhichId == EE_CHAR_FONTINFO_CTL )
346 aPostfix = C2U( "Complex" );
347
348 const SvxFontItem & rItem =
349 static_cast< const SvxFontItem & >(
350 rItemSet.Get( nWhichId ));
351
352 if( rItem.QueryValue( aValue, MID_FONT_FAMILY_NAME ))
353 {
354 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharFontName" ) + aPostfix ))
355 {
356 GetPropertySet()->setPropertyValue( C2U( "CharFontName" ) + aPostfix, aValue );
357 bChanged = true;
358 }
359 }
360 if( rItem.QueryValue( aValue, MID_FONT_FAMILY ))
361 {
362 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharFontFamily" ) + aPostfix ))
363 {
364 GetPropertySet()->setPropertyValue( C2U( "CharFontFamily" ) + aPostfix, aValue );
365 bChanged = true;
366 }
367 }
368 if( rItem.QueryValue( aValue, MID_FONT_STYLE_NAME ))
369 {
370 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharFontStyleName" ) + aPostfix ))
371 {
372 GetPropertySet()->setPropertyValue( C2U( "CharFontStyleName" ) + aPostfix, aValue );
373 bChanged = true;
374 }
375 }
376 if( rItem.QueryValue( aValue, MID_FONT_CHAR_SET ))
377 {
378 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharFontCharSet" ) + aPostfix ))
379 {
380 GetPropertySet()->setPropertyValue( C2U( "CharFontCharSet" ) + aPostfix, aValue );
381 bChanged = true;
382 }
383 }
384 if( rItem.QueryValue( aValue, MID_FONT_PITCH ))
385 {
386 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharFontPitch" ) + aPostfix ))
387 {
388 GetPropertySet()->setPropertyValue( C2U( "CharFontPitch" ) + aPostfix, aValue );
389 bChanged = true;
390 }
391 }
392 }
393 break;
394
395 case EE_CHAR_UNDERLINE:
396 {
397 const SvxUnderlineItem & rItem =
398 static_cast< const SvxUnderlineItem & >(
399 rItemSet.Get( nWhichId ));
400
401 if( rItem.QueryValue( aValue, MID_TL_STYLE ))
402 {
403 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharUnderline" ) ))
404 {
405 GetPropertySet()->setPropertyValue( C2U( "CharUnderline" ), aValue );
406 bChanged = true;
407 }
408 }
409
410 if( rItem.QueryValue( aValue, MID_TL_COLOR ))
411 {
412 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharUnderlineColor" ) ))
413 {
414 GetPropertySet()->setPropertyValue( C2U( "CharUnderlineColor" ), aValue );
415 bChanged = true;
416 }
417 }
418
419 if( rItem.QueryValue( aValue, MID_TL_HASCOLOR ))
420 {
421 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharUnderlineHasColor" ) ))
422 {
423 GetPropertySet()->setPropertyValue( C2U( "CharUnderlineHasColor" ), aValue );
424 bChanged = true;
425 }
426 }
427 }
428 break;
429
430 case EE_CHAR_OVERLINE:
431 {
432 const SvxOverlineItem& rItem = static_cast< const SvxOverlineItem & >( rItemSet.Get( nWhichId ) );
433
434 if ( rItem.QueryValue( aValue, MID_TL_STYLE ) )
435 {
436 if ( aValue != GetPropertySet()->getPropertyValue( C2U( "CharOverline" ) ) )
437 {
438 GetPropertySet()->setPropertyValue( C2U( "CharOverline" ), aValue );
439 bChanged = true;
440 }
441 }
442
443 if ( rItem.QueryValue( aValue, MID_TL_COLOR ) )
444 {
445 if ( aValue != GetPropertySet()->getPropertyValue( C2U( "CharOverlineColor" ) ) )
446 {
447 GetPropertySet()->setPropertyValue( C2U( "CharOverlineColor" ), aValue );
448 bChanged = true;
449 }
450 }
451
452 if ( rItem.QueryValue( aValue, MID_TL_HASCOLOR ) )
453 {
454 if ( aValue != GetPropertySet()->getPropertyValue( C2U( "CharOverlineHasColor" ) ) )
455 {
456 GetPropertySet()->setPropertyValue( C2U( "CharOverlineHasColor" ), aValue );
457 bChanged = true;
458 }
459 }
460 }
461 break;
462
463 case EE_CHAR_ITALIC:
464 case EE_CHAR_ITALIC_CJK:
465 case EE_CHAR_ITALIC_CTL:
466 {
467 ::rtl::OUString aPostfix;
468 if( nWhichId == EE_CHAR_ITALIC_CJK )
469 aPostfix = C2U( "Asian" );
470 else if( nWhichId == EE_CHAR_ITALIC_CTL )
471 aPostfix = C2U( "Complex" );
472
473 const SvxPostureItem & rItem =
474 static_cast< const SvxPostureItem & >(
475 rItemSet.Get( nWhichId ));
476
477 if( rItem.QueryValue( aValue, MID_POSTURE ))
478 {
479 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharPosture" ) + aPostfix))
480 {
481 GetPropertySet()->setPropertyValue( C2U( "CharPosture" ) + aPostfix, aValue );
482 bChanged = true;
483 }
484 }
485 }
486 break;
487
488 case EE_CHAR_WEIGHT:
489 case EE_CHAR_WEIGHT_CJK:
490 case EE_CHAR_WEIGHT_CTL:
491 {
492 ::rtl::OUString aPostfix;
493 if( nWhichId == EE_CHAR_WEIGHT_CJK )
494 aPostfix = C2U( "Asian" );
495 else if( nWhichId == EE_CHAR_WEIGHT_CTL )
496 aPostfix = C2U( "Complex" );
497
498 const SvxWeightItem & rItem =
499 static_cast< const SvxWeightItem & >(
500 rItemSet.Get( nWhichId ));
501
502 if( rItem.QueryValue( aValue, MID_WEIGHT ))
503 {
504 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharWeight" ) + aPostfix))
505 {
506 GetPropertySet()->setPropertyValue( C2U( "CharWeight" ) + aPostfix, aValue );
507 bChanged = true;
508 }
509 }
510 }
511 break;
512
513 case EE_CHAR_FONTHEIGHT:
514 case EE_CHAR_FONTHEIGHT_CJK:
515 case EE_CHAR_FONTHEIGHT_CTL:
516 {
517 ::rtl::OUString aPostfix;
518 if( nWhichId == EE_CHAR_FONTHEIGHT_CJK )
519 aPostfix = C2U( "Asian" );
520 else if( nWhichId == EE_CHAR_FONTHEIGHT_CTL )
521 aPostfix = C2U( "Complex" );
522
523 const SvxFontHeightItem & rItem =
524 static_cast< const SvxFontHeightItem & >(
525 rItemSet.Get( nWhichId ));
526
527 try
528 {
529 if( rItem.QueryValue( aValue, MID_FONTHEIGHT ) )
530 {
531 bool bSetValue = false;
532 if( aValue != GetPropertySet()->getPropertyValue( C2U( "CharHeight" ) + aPostfix ))
533 bSetValue = true;
534 else
535 {
536 if( m_pRefSize.get() )
537 {
538 awt::Size aNewRefSize = *m_pRefSize;
539 awt::Size aOldRefSize;
540 if( GetRefSizePropertySet()->getPropertyValue( m_aRefSizePropertyName ) >>= aOldRefSize )
541 {
542 if( aNewRefSize.Width != aOldRefSize.Width
543 || aNewRefSize.Height != aOldRefSize.Height )
544 bSetValue = true;
545 }
546 }
547 }
548 if( bSetValue )
549 {
550 // set new reference size only if there was a reference size before (auto-scaling on)
551 if( m_pRefSize.get() &&
552 GetRefSizePropertySet()->getPropertyValue( m_aRefSizePropertyName ).hasValue())
553 {
554 GetRefSizePropertySet()->setPropertyValue( m_aRefSizePropertyName,
555 uno::makeAny( *m_pRefSize ));
556 }
557
558 GetPropertySet()->setPropertyValue( C2U( "CharHeight" ) + aPostfix, aValue );
559 bChanged = true;
560 }
561 }
562 }
563 catch( uno::Exception & ex )
564 {
565 ASSERT_EXCEPTION( ex );
566 }
567 }
568 break;
569 }
570
571 return bChanged;
572 }
573
574 uno::Reference< beans::XPropertySet >
GetRefSizePropertySet() const575 CharacterPropertyItemConverter::GetRefSizePropertySet() const
576 {
577 return m_xRefSizePropSet;
578 }
579
580 } // namespace wrapper
581 } // namespace chart
582