Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "PropertyMapper.hxx"
21 : #include "ContainerHelper.hxx"
22 : #include "macros.hxx"
23 :
24 : #include <com/sun/star/beans/XMultiPropertySet.hpp>
25 : #include <com/sun/star/drawing/LineStyle.hpp>
26 : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
27 : #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
28 : #include <com/sun/star/drawing/LineJoint.hpp>
29 :
30 : //.............................................................................
31 : namespace chart
32 : {
33 : //.............................................................................
34 : using namespace ::com::sun::star;
35 :
36 : namespace
37 : {
38 :
39 0 : void lcl_overwriteOrAppendValues(
40 : tPropertyNameValueMap &rMap, const tPropertyNameValueMap& rOverwriteMap )
41 : {
42 0 : tPropertyNameValueMap::const_iterator aIt( rOverwriteMap.begin() );
43 0 : tPropertyNameValueMap::const_iterator aEnd( rOverwriteMap.end() );
44 :
45 0 : for( ; aIt != aEnd; ++aIt )
46 0 : rMap[ aIt->first ] = aIt->second;
47 0 : }
48 :
49 : } // anonymous namespace
50 :
51 533 : void PropertyMapper::setMappedProperties(
52 : const uno::Reference< beans::XPropertySet >& xTarget
53 : , const uno::Reference< beans::XPropertySet >& xSource
54 : , const tPropertyNameMap& rMap
55 : , tPropertyNameValueMap* pOverwriteMap )
56 : {
57 533 : if( !xTarget.is() || !xSource.is() )
58 533 : return;
59 :
60 533 : tNameSequence aNames;
61 533 : tAnySequence aValues;
62 533 : getMultiPropertyLists(aNames, aValues, xSource, rMap );
63 533 : if(pOverwriteMap && (aNames.getLength() == aValues.getLength()))
64 : {
65 0 : tPropertyNameValueMap aNewMap;
66 0 : for( sal_Int32 nI=0; nI<aNames.getLength(); ++nI )
67 0 : aNewMap[ aNames[nI] ] = aValues[nI];
68 0 : lcl_overwriteOrAppendValues( aNewMap, *pOverwriteMap );
69 0 : aNames = ContainerHelper::MapKeysToSequence( aNewMap );
70 0 : aValues = ContainerHelper::MapValuesToSequence( aNewMap );
71 : }
72 :
73 533 : PropertyMapper::setMultiProperties( aNames, aValues, xTarget );
74 : }
75 :
76 943 : void PropertyMapper::getValueMap(
77 : tPropertyNameValueMap& rValueMap
78 : , const tPropertyNameMap& rNameMap
79 : , const uno::Reference< beans::XPropertySet >& xSourceProp
80 : )
81 : {
82 943 : tPropertyNameMap::const_iterator aIt( rNameMap.begin() );
83 943 : tPropertyNameMap::const_iterator aEnd( rNameMap.end() );
84 :
85 26855 : for( ; aIt != aEnd; ++aIt )
86 : {
87 25912 : rtl::OUString aTarget = aIt->first;
88 25912 : rtl::OUString aSource = aIt->second;
89 : try
90 : {
91 25912 : uno::Any aAny( xSourceProp->getPropertyValue(aSource) );
92 25912 : if( aAny.hasValue() )
93 21484 : rValueMap.insert( tPropertyNameValueMap::value_type( aTarget, aAny ) );
94 : }
95 0 : catch( const uno::Exception& e )
96 : {
97 : ASSERT_EXCEPTION( e );
98 : }
99 25912 : }
100 943 : }
101 :
102 533 : void PropertyMapper::getMultiPropertyLists(
103 : tNameSequence& rNames
104 : , tAnySequence& rValues
105 : , const uno::Reference< beans::XPropertySet >& xSourceProp
106 : , const tPropertyNameMap& rNameMap
107 : )
108 : {
109 533 : tPropertyNameValueMap aValueMap;
110 533 : getValueMap( aValueMap, rNameMap, xSourceProp );
111 533 : getMultiPropertyListsFromValueMap( rNames, rValues, aValueMap );
112 533 : }
113 :
114 943 : void PropertyMapper::getMultiPropertyListsFromValueMap(
115 : tNameSequence& rNames
116 : , tAnySequence& rValues
117 : , const tPropertyNameValueMap& rValueMap
118 : )
119 : {
120 943 : sal_Int32 nPropertyCount = rValueMap.size();
121 943 : rNames.realloc(nPropertyCount);
122 943 : rValues.realloc(nPropertyCount);
123 :
124 : //fill sequences
125 943 : tPropertyNameValueMap::const_iterator aValueIt( rValueMap.begin() );
126 943 : tPropertyNameValueMap::const_iterator aValueEnd( rValueMap.end() );
127 943 : sal_Int32 nN=0;
128 23452 : for( ; aValueIt != aValueEnd; ++aValueIt )
129 : {
130 22509 : const uno::Any& rAny = aValueIt->second;
131 22509 : if( rAny.hasValue() )
132 : {
133 : //do not set empty anys because of performance (otherwise SdrAttrObj::ItemChange will take much longer)
134 22509 : rNames[nN] = aValueIt->first;
135 22509 : rValues[nN] = rAny;
136 22509 : ++nN;
137 : }
138 : }
139 : //reduce to real property count
140 943 : rNames.realloc(nN);
141 943 : rValues.realloc(nN);
142 943 : }
143 :
144 820 : uno::Any* PropertyMapper::getValuePointer( tAnySequence& rPropValues
145 : , const tNameSequence& rPropNames
146 : , const rtl::OUString& rPropName )
147 : {
148 820 : sal_Int32 nCount = rPropNames.getLength();
149 27429 : for( sal_Int32 nN = 0; nN < nCount; nN++ )
150 : {
151 27265 : if(rPropNames[nN].equals(rPropName))
152 656 : return &rPropValues[nN];
153 : }
154 164 : return NULL;
155 : }
156 :
157 164 : uno::Any* PropertyMapper::getValuePointerForLimitedSpace( tAnySequence& rPropValues
158 : , const tNameSequence& rPropNames
159 : , bool bLimitedHeight)
160 : {
161 : return PropertyMapper::getValuePointer( rPropValues, rPropNames
162 164 : , bLimitedHeight ? C2U("TextMaximumFrameHeight") : C2U("TextMaximumFrameWidth") );
163 : }
164 :
165 205 : const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForCharacterProperties()
166 : {
167 : //shape property -- chart model object property
168 : static tMakePropertyNameMap m_aShapePropertyMapForCharacterProperties =
169 : tMakePropertyNameMap
170 : ( "CharColor", "CharColor" )
171 2 : ( "CharContoured", "CharContoured" )
172 3 : ( "CharEmphasis", "CharEmphasis" )//the service style::CharacterProperties describes a property called 'CharEmphasize' wich is nowhere implemented
173 :
174 3 : ( "CharFontFamily", "CharFontFamily" )
175 3 : ( "CharFontFamilyAsian", "CharFontFamilyAsian" )
176 3 : ( "CharFontFamilyComplex", "CharFontFamilyComplex" )
177 3 : ( "CharFontCharSet", "CharFontCharSet" )
178 3 : ( "CharFontCharSetAsian", "CharFontCharSetAsian" )
179 3 : ( "CharFontCharSetComplex", "CharFontCharSetComplex" )
180 3 : ( "CharFontName", "CharFontName" )
181 3 : ( "CharFontNameAsian", "CharFontNameAsian" )
182 3 : ( "CharFontNameComplex", "CharFontNameComplex" )
183 3 : ( "CharFontPitch", "CharFontPitch" )
184 3 : ( "CharFontPitchAsian", "CharFontPitchAsian" )
185 3 : ( "CharFontPitchComplex", "CharFontPitchComplex" )
186 3 : ( "CharFontStyleName", "CharFontStyleName" )
187 3 : ( "CharFontStyleNameAsian", "CharFontStyleNameAsian" )
188 3 : ( "CharFontStyleNameComplex", "CharFontStyleNameComplex" )
189 :
190 3 : ( "CharHeight", "CharHeight" )
191 3 : ( "CharHeightAsian", "CharHeightAsian" )
192 3 : ( "CharHeightComplex", "CharHeightComplex" )
193 3 : ( "CharKerning", "CharKerning" )
194 3 : ( "CharLocale", "CharLocale" )
195 3 : ( "CharLocaleAsian", "CharLocaleAsian" )
196 3 : ( "CharLocaleComplex", "CharLocaleComplex" )
197 3 : ( "CharPosture", "CharPosture" )
198 3 : ( "CharPostureAsian", "CharPostureAsian" )
199 3 : ( "CharPostureComplex", "CharPostureComplex" )
200 3 : ( "CharRelief", "CharRelief" )
201 3 : ( "CharShadowed", "CharShadowed" )
202 3 : ( "CharStrikeout", "CharStrikeout" )
203 3 : ( "CharUnderline", "CharUnderline" )
204 3 : ( "CharUnderlineColor", "CharUnderlineColor" )
205 3 : ( "CharUnderlineHasColor", "CharUnderlineHasColor" )
206 3 : ( "CharOverline", "CharOverline" )
207 3 : ( "CharOverlineColor", "CharOverlineColor" )
208 3 : ( "CharOverlineHasColor", "CharOverlineHasColor" )
209 3 : ( "CharWeight", "CharWeight" )
210 3 : ( "CharWeightAsian", "CharWeightAsian" )
211 3 : ( "CharWeightComplex", "CharWeightComplex" )
212 3 : ( "CharWordMode", "CharWordMode" )
213 :
214 3 : ( "WritingMode", "WritingMode" )
215 :
216 207 : ( "ParaIsCharacterDistance", "ParaIsCharacterDistance" )
217 : ;
218 205 : return m_aShapePropertyMapForCharacterProperties;
219 : }
220 :
221 0 : const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForParagraphProperties()
222 : {
223 : //shape property -- chart model object property
224 : static tMakePropertyNameMap m_aShapePropertyMapForParagraphProperties =
225 : tMakePropertyNameMap
226 : ( "ParaAdjust", "ParaAdjust" )
227 0 : ( "ParaBottomMargin", "ParaBottomMargin" )
228 0 : ( "ParaIsHyphenation", "ParaIsHyphenation" )
229 0 : ( "ParaLastLineAdjust", "ParaLastLineAdjust" )
230 0 : ( "ParaLeftMargin", "ParaLeftMargin" )
231 0 : ( "ParaRightMargin", "ParaRightMargin" )
232 0 : ( "ParaTopMargin", "ParaTopMargin" )
233 : ;
234 0 : return m_aShapePropertyMapForParagraphProperties;
235 : }
236 :
237 124 : const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForFillProperties()
238 : {
239 : //shape property -- chart model object property
240 : static tMakePropertyNameMap m_aShapePropertyMapForFillProperties =
241 : tMakePropertyNameMap
242 : ( "FillBackground", "FillBackground" )
243 2 : ( "FillBitmapName", "FillBitmapName" )
244 3 : ( "FillColor", "FillColor" )
245 3 : ( "FillGradientName", "FillGradientName" )
246 3 : ( "FillGradientStepCount", "FillGradientStepCount" )
247 3 : ( "FillHatchName", "FillHatchName" )
248 3 : ( "FillStyle", "FillStyle" )
249 3 : ( "FillTransparence", "FillTransparence" )
250 3 : ( "FillTransparenceGradientName", "FillTransparenceGradientName" )
251 : //bitmap properties
252 3 : ( "FillBitmapMode", "FillBitmapMode" )
253 3 : ( "FillBitmapSizeX", "FillBitmapSizeX" )
254 3 : ( "FillBitmapSizeY", "FillBitmapSizeY" )
255 3 : ( "FillBitmapLogicalSize", "FillBitmapLogicalSize" )
256 3 : ( "FillBitmapOffsetX", "FillBitmapOffsetX" )
257 3 : ( "FillBitmapOffsetY", "FillBitmapOffsetY" )
258 3 : ( "FillBitmapRectanglePoint", "FillBitmapRectanglePoint" )
259 3 : ( "FillBitmapPositionOffsetX", "FillBitmapPositionOffsetX" )
260 126 : ( "FillBitmapPositionOffsetY", "FillBitmapPositionOffsetY" )
261 : ;
262 124 : return m_aShapePropertyMapForFillProperties;
263 : }
264 :
265 124 : const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForLineProperties()
266 : {
267 : //shape property -- chart model object property
268 : static tMakePropertyNameMap m_aShapePropertyMapForLineProperties =
269 : tMakePropertyNameMap
270 : ( "LineColor", "LineColor" )
271 2 : ( "LineDashName", "LineDashName" )
272 3 : ( "LineJoint", "LineJoint" )
273 3 : ( "LineStyle", "LineStyle" )
274 3 : ( "LineTransparence", "LineTransparence" )
275 126 : ( "LineWidth", "LineWidth" )
276 : ;
277 124 : return m_aShapePropertyMapForLineProperties;
278 : }
279 :
280 246 : const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForFillAndLineProperties()
281 : {
282 : static tMakePropertyNameMap m_aShapePropertyMapForFillAndLineProperties =
283 : tMakePropertyNameMap
284 1 : ( PropertyMapper::getPropertyNameMapForFillProperties() )
285 247 : ( PropertyMapper::getPropertyNameMapForLineProperties() )
286 : ;
287 :
288 246 : return m_aShapePropertyMapForFillAndLineProperties;
289 : }
290 :
291 0 : const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForTextShapeProperties()
292 : {
293 : static tMakePropertyNameMap m_aShapePropertyMapForTextShapeProperties =
294 : tMakePropertyNameMap
295 0 : ( PropertyMapper::getPropertyNameMapForCharacterProperties() )
296 0 : ( PropertyMapper::getPropertyNameMapForFillProperties() )
297 0 : ( PropertyMapper::getPropertyNameMapForLineProperties() );
298 :
299 0 : return m_aShapePropertyMapForTextShapeProperties;
300 : }
301 :
302 123 : const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForLineSeriesProperties()
303 : {
304 : //shape property -- chart model object property
305 : static tMakePropertyNameMap m_aShapePropertyMapForLineSeriesProperties =
306 : tMakePropertyNameMap
307 : ( "LineColor", "Color" )
308 2 : ( "LineDashName", "LineDashName" )
309 3 : ( "LineStyle", "LineStyle" )
310 3 : ( "LineTransparence", "Transparency" )
311 125 : ( "LineWidth", "LineWidth" )
312 :
313 : ;
314 123 : return m_aShapePropertyMapForLineSeriesProperties;
315 : }
316 :
317 615 : const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForFilledSeriesProperties()
318 : {
319 : //shape property -- chart model object property
320 : static tMakePropertyNameMap m_aShapePropertyMapForFilledSeriesProperties =
321 : tMakePropertyNameMap
322 : ( "FillBackground", "FillBackground" )
323 2 : ( "FillBitmapName", "FillBitmapName" )
324 3 : ( "FillColor", "Color" )
325 3 : ( "FillGradientName", "GradientName" )
326 3 : ( "FillGradientStepCount", "GradientStepCount" )
327 3 : ( "FillHatchName", "HatchName" )
328 3 : ( "FillStyle", "FillStyle" )
329 3 : ( "FillTransparence", "Transparency" )
330 3 : ( "FillTransparenceGradientName", "TransparencyGradientName" )
331 : //bitmap properties
332 3 : ( "FillBitmapMode", "FillBitmapMode" )
333 3 : ( "FillBitmapSizeX", "FillBitmapSizeX" )
334 3 : ( "FillBitmapSizeY", "FillBitmapSizeY" )
335 3 : ( "FillBitmapLogicalSize", "FillBitmapLogicalSize" )
336 3 : ( "FillBitmapOffsetX", "FillBitmapOffsetX" )
337 3 : ( "FillBitmapOffsetY", "FillBitmapOffsetY" )
338 3 : ( "FillBitmapRectanglePoint", "FillBitmapRectanglePoint" )
339 3 : ( "FillBitmapPositionOffsetX", "FillBitmapPositionOffsetX" )
340 3 : ( "FillBitmapPositionOffsetY", "FillBitmapPositionOffsetY" )
341 : //line properties
342 3 : ( "LineColor", "BorderColor" )
343 3 : ( "LineDashName", "BorderDashName" )
344 3 : ( "LineStyle", "BorderStyle" )
345 3 : ( "LineTransparence", "BorderTransparency" )
346 617 : ( "LineWidth", "BorderWidth" )
347 : ;
348 615 : return m_aShapePropertyMapForFilledSeriesProperties;
349 : }
350 :
351 1640 : void PropertyMapper::setMultiProperties(
352 : const tNameSequence& rNames
353 : , const tAnySequence& rValues
354 : , const ::com::sun::star::uno::Reference<
355 : ::com::sun::star::beans::XPropertySet >& xTarget )
356 : {
357 1640 : bool bSuccess = false;
358 : try
359 : {
360 1640 : uno::Reference< beans::XMultiPropertySet > xShapeMultiProp( xTarget, uno::UNO_QUERY );
361 1640 : if( xShapeMultiProp.is() )
362 : {
363 1640 : xShapeMultiProp->setPropertyValues( rNames, rValues );
364 1640 : bSuccess = true;
365 1640 : }
366 : }
367 0 : catch( const uno::Exception& e )
368 : {
369 : ASSERT_EXCEPTION( e ); //if this occurs more often think of removing the XMultiPropertySet completly for better performance
370 : }
371 :
372 1640 : if(!bSuccess)
373 : try
374 : {
375 0 : sal_Int32 nCount = std::max( rNames.getLength(), rValues.getLength() );
376 0 : rtl::OUString aPropName;
377 0 : uno::Any aValue;
378 0 : for( sal_Int32 nN = 0; nN < nCount; nN++ )
379 : {
380 0 : aPropName = rNames[nN];
381 0 : aValue = rValues[nN];
382 :
383 : try
384 : {
385 0 : xTarget->setPropertyValue( aPropName, aValue );
386 : }
387 0 : catch( const uno::Exception& e )
388 : {
389 : ASSERT_EXCEPTION( e );
390 : }
391 0 : }
392 : }
393 0 : catch( const uno::Exception& e )
394 : {
395 : ASSERT_EXCEPTION( e );
396 : }
397 1640 : }
398 :
399 164 : void PropertyMapper::getTextLabelMultiPropertyLists(
400 : const uno::Reference< beans::XPropertySet >& xSourceProp
401 : , tNameSequence& rPropNames, tAnySequence& rPropValues
402 : , bool bName
403 : , sal_Int32 nLimitedSpace
404 : , bool bLimitedHeight )
405 : {
406 : //fill character properties into the ValueMap
407 164 : tPropertyNameValueMap aValueMap;
408 : PropertyMapper::getValueMap( aValueMap
409 164 : , PropertyMapper::getPropertyNameMapForCharacterProperties()
410 164 : , xSourceProp );
411 :
412 : //some more shape properties apart from character properties, position-matrix and label string
413 164 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("LineStyle"), uno::makeAny(drawing::LineStyle_NONE) ) ); // drawing::LineStyle
414 164 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextHorizontalAdjust"), uno::makeAny(drawing::TextHorizontalAdjust_CENTER) ) ); // drawing::TextHorizontalAdjust - needs to be overwritten
415 164 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextVerticalAdjust"), uno::makeAny(drawing::TextVerticalAdjust_CENTER) ) ); //drawing::TextVerticalAdjust - needs to be overwritten
416 164 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextAutoGrowHeight"), uno::makeAny(sal_True) ) ); // sal_Bool
417 164 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextAutoGrowWidth"), uno::makeAny(sal_True) ) ); // sal_Bool
418 164 : if( bName )
419 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("Name"), uno::makeAny( rtl::OUString() ) ) ); //CID rtl::OUString - needs to be overwritten for each point
420 :
421 164 : if( nLimitedSpace > 0 )
422 : {
423 0 : if(bLimitedHeight)
424 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextMaximumFrameHeight"), uno::makeAny(nLimitedSpace) ) ); //sal_Int32
425 : else
426 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextMaximumFrameWidth"), uno::makeAny(nLimitedSpace) ) ); //sal_Int32
427 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("ParaIsHyphenation"), uno::makeAny(sal_True) ) );
428 : }
429 :
430 164 : PropertyMapper::getMultiPropertyListsFromValueMap( rPropNames, rPropValues, aValueMap );
431 164 : }
432 :
433 0 : void PropertyMapper::getPreparedTextShapePropertyLists(
434 : const uno::Reference< beans::XPropertySet >& xSourceProp
435 : , tNameSequence& rPropNames, tAnySequence& rPropValues )
436 : {
437 : //fill character, line and fill properties into the ValueMap
438 0 : tPropertyNameValueMap aValueMap;
439 : PropertyMapper::getValueMap( aValueMap
440 0 : , PropertyMapper::getPropertyNameMapForTextShapeProperties()
441 0 : , xSourceProp );
442 :
443 : // auto-grow makes sure the shape has the correct size after setting text
444 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextHorizontalAdjust"), uno::makeAny( drawing::TextHorizontalAdjust_CENTER )));
445 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextVerticalAdjust"), uno::makeAny( drawing::TextVerticalAdjust_CENTER )));
446 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextAutoGrowHeight"), uno::makeAny( true )));
447 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextAutoGrowWidth"), uno::makeAny( true )));
448 :
449 : // set some distance to the border, in case it is shown
450 0 : const sal_Int32 nWidthDist = 250;
451 0 : const sal_Int32 nHeightDist = 125;
452 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextLeftDistance"), uno::makeAny( nWidthDist )));
453 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextRightDistance"), uno::makeAny( nWidthDist )));
454 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextUpperDistance"), uno::makeAny( nHeightDist )));
455 0 : aValueMap.insert( tPropertyNameValueMap::value_type( C2U("TextLowerDistance"), uno::makeAny( nHeightDist )));
456 :
457 : // use a line-joint showing the border of thick lines like two rectangles
458 : // filled in between.
459 0 : aValueMap[C2U("LineJoint")] <<= drawing::LineJoint_ROUND;
460 :
461 0 : PropertyMapper::getMultiPropertyListsFromValueMap( rPropNames, rPropValues, aValueMap );
462 0 : }
463 :
464 : //.............................................................................
465 : } //namespace chart
466 : //.............................................................................
467 :
468 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|