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 "AxisItemConverter.hxx"
27 #include "ItemPropertyMap.hxx"
28 #include "CharacterPropertyItemConverter.hxx"
29 #include "GraphicPropertyItemConverter.hxx"
30 #include "chartview/ChartSfxItemIds.hxx"
31 #include "chartview/ExplicitValueProvider.hxx"
32 #include "SchWhichPairs.hxx"
33 #include "macros.hxx"
34 #include "ChartModelHelper.hxx"
35 #include "AxisHelper.hxx"
36 #include "CommonConverters.hxx"
37 #include "ChartTypeHelper.hxx"
38 
39 #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
40 #include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
41 #include <com/sun/star/chart/ChartAxisPosition.hpp>
42 #include <com/sun/star/chart2/XAxis.hpp>
43 #include <com/sun/star/chart2/AxisOrientation.hpp>
44 #include <com/sun/star/chart2/AxisType.hpp>
45 
46 // for SfxBoolItem
47 #include <svl/eitem.hxx>
48 // for SvxDoubleItem
49 #include <svx/chrtitem.hxx>
50 // for SfxInt32Item
51 #include <svl/intitem.hxx>
52 #include <rtl/math.hxx>
53 
54 #include <algorithm>
55 
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::chart2;
58 using ::com::sun::star::uno::Reference;
59 using ::com::sun::star::chart::TimeInterval;
60 using ::com::sun::star::chart::TimeIncrement;
61 
62 namespace
63 {
lcl_GetAxisPropertyMap()64 ::comphelper::ItemPropertyMapType & lcl_GetAxisPropertyMap()
65 {
66     static ::comphelper::ItemPropertyMapType aAxisPropertyMap(
67         ::comphelper::MakeItemPropertyMap
68         IPM_MAP_ENTRY( SCHATTR_AXIS_SHOWDESCR,     "DisplayLabels",    0 )
69         IPM_MAP_ENTRY( SCHATTR_AXIS_TICKS,         "MajorTickmarks",   0 )
70         IPM_MAP_ENTRY( SCHATTR_AXIS_HELPTICKS,     "MinorTickmarks",   0 )
71         IPM_MAP_ENTRY( SCHATTR_AXIS_LABEL_ORDER,   "ArrangeOrder",     0 )
72         IPM_MAP_ENTRY( SCHATTR_TEXT_STACKED,       "StackCharacters",  0 )
73         IPM_MAP_ENTRY( SCHATTR_AXIS_LABEL_BREAK,   "TextBreak",        0 )
74         IPM_MAP_ENTRY( SCHATTR_AXIS_LABEL_OVERLAP, "TextOverlap",      0 )
75         );
76 
77     return aAxisPropertyMap;
78 };
79 } // anonymous namespace
80 
81 namespace chart
82 {
83 namespace wrapper
84 {
85 
AxisItemConverter(const Reference<beans::XPropertySet> & rPropertySet,SfxItemPool & rItemPool,SdrModel & rDrawModel,const Reference<chart2::XChartDocument> & xChartDoc,::chart::ExplicitScaleData * pScale,::chart::ExplicitIncrementData * pIncrement,::std::auto_ptr<awt::Size> pRefSize)86 AxisItemConverter::AxisItemConverter(
87     const Reference< beans::XPropertySet > & rPropertySet,
88     SfxItemPool& rItemPool,
89     SdrModel& rDrawModel,
90     const Reference< chart2::XChartDocument > & xChartDoc,
91     ::chart::ExplicitScaleData * pScale /* = NULL */,
92     ::chart::ExplicitIncrementData * pIncrement /* = NULL */,
93     ::std::auto_ptr< awt::Size > pRefSize /* = NULL */ ) :
94         ItemConverter( rPropertySet, rItemPool ),
95         m_xChartDoc( xChartDoc ),
96         m_pExplicitScale( NULL ),
97         m_pExplicitIncrement( NULL )
98 {
99     Reference< lang::XMultiServiceFactory > xNamedPropertyContainerFactory( xChartDoc, uno::UNO_QUERY );
100 
101     if( pScale )
102         m_pExplicitScale = new ::chart::ExplicitScaleData( *pScale );
103     if( pIncrement )
104         m_pExplicitIncrement = new ::chart::ExplicitIncrementData( *pIncrement );
105 
106     m_aConverters.push_back( new GraphicPropertyItemConverter(
107                                  rPropertySet, rItemPool, rDrawModel,
108                                  xNamedPropertyContainerFactory,
109                                  GraphicPropertyItemConverter::LINE_PROPERTIES ));
110     m_aConverters.push_back( new CharacterPropertyItemConverter( rPropertySet, rItemPool, pRefSize,
111                                                                  C2U( "ReferencePageSize" ) ));
112 
113     m_xAxis.set( Reference< chart2::XAxis >( rPropertySet, uno::UNO_QUERY ) );
114     OSL_ASSERT( m_xAxis.is());
115 }
116 
~AxisItemConverter()117 AxisItemConverter::~AxisItemConverter()
118 {
119     delete m_pExplicitScale;
120     delete m_pExplicitIncrement;
121 
122     ::std::for_each( m_aConverters.begin(), m_aConverters.end(),
123                      ::comphelper::DeleteItemConverterPtr() );
124 }
125 
FillItemSet(SfxItemSet & rOutItemSet) const126 void AxisItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const
127 {
128     ::std::for_each( m_aConverters.begin(), m_aConverters.end(),
129                      ::comphelper::FillItemSetFunc( rOutItemSet ));
130 
131     // own items
132     ItemConverter::FillItemSet( rOutItemSet );
133 }
134 
ApplyItemSet(const SfxItemSet & rItemSet)135 bool AxisItemConverter::ApplyItemSet( const SfxItemSet & rItemSet )
136 {
137     bool bResult = false;
138 
139     ::std::for_each( m_aConverters.begin(), m_aConverters.end(),
140                      ::comphelper::ApplyItemSetFunc( rItemSet, bResult ));
141 
142     // own items
143     return ItemConverter::ApplyItemSet( rItemSet ) || bResult;
144 }
145 
GetWhichPairs() const146 const sal_uInt16 * AxisItemConverter::GetWhichPairs() const
147 {
148     // must span all used items!
149     return nAxisWhichPairs;
150 }
151 
GetItemProperty(tWhichIdType nWhichId,tPropertyNameWithMemberId & rOutProperty) const152 bool AxisItemConverter::GetItemProperty( tWhichIdType nWhichId, tPropertyNameWithMemberId & rOutProperty ) const
153 {
154     ::comphelper::ItemPropertyMapType & rMap( lcl_GetAxisPropertyMap());
155     ::comphelper::ItemPropertyMapType::const_iterator aIt( rMap.find( nWhichId ));
156 
157     if( aIt == rMap.end())
158         return false;
159 
160     rOutProperty =(*aIt).second;
161 
162     return true;
163 }
164 
lcl_hasTimeIntervalValue(const uno::Any & rAny)165 bool lcl_hasTimeIntervalValue( const uno::Any& rAny )
166 {
167     bool bRet = false;
168     TimeInterval aValue;
169     if( rAny >>= aValue )
170         bRet = true;
171     return bRet;
172 }
173 
FillSpecialItem(sal_uInt16 nWhichId,SfxItemSet & rOutItemSet) const174 void AxisItemConverter::FillSpecialItem( sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const
175     throw( uno::Exception )
176 {
177     if( !m_xAxis.is() )
178         return;
179 
180     const chart2::ScaleData&     rScale( m_xAxis->getScaleData() );
181     const chart2::IncrementData& rIncrement( rScale.IncrementData );
182     const uno::Sequence< chart2::SubIncrement >& rSubIncrements( rScale.IncrementData.SubIncrements );
183     const TimeIncrement& rTimeIncrement( rScale.TimeIncrement );
184     bool bDateAxis = (chart2::AxisType::DATE == rScale.AxisType);
185     if( m_pExplicitScale )
186         bDateAxis = (chart2::AxisType::DATE == m_pExplicitScale->AxisType);
187 
188     switch( nWhichId )
189     {
190         case SCHATTR_AXIS_AUTO_MAX:
191                 rOutItemSet.Put( SfxBoolItem( nWhichId, !hasDoubleValue(rScale.Maximum) ) );
192             break;
193 
194         case SCHATTR_AXIS_MAX:
195             {
196                 double fMax = 10.0;
197                 if( rScale.Maximum >>= fMax )
198                     rOutItemSet.Put( SvxDoubleItem( fMax, nWhichId ) );
199                 else
200                 {
201                     if( m_pExplicitScale )
202                         fMax = m_pExplicitScale->Maximum;
203                     rOutItemSet.Put( SvxDoubleItem( fMax, nWhichId ) );
204                 }
205             }
206             break;
207 
208         case SCHATTR_AXIS_AUTO_MIN:
209                 rOutItemSet.Put( SfxBoolItem( nWhichId, !hasDoubleValue(rScale.Minimum) ) );
210             break;
211 
212         case SCHATTR_AXIS_MIN:
213             {
214                 double fMin = 0.0;
215                 if( rScale.Minimum >>= fMin )
216                     rOutItemSet.Put( SvxDoubleItem( fMin, nWhichId ) );
217                 else if( m_pExplicitScale )
218                     rOutItemSet.Put( SvxDoubleItem( m_pExplicitScale->Minimum, nWhichId ));
219             }
220             break;
221 
222         case SCHATTR_AXIS_LOGARITHM:
223             {
224                 sal_Bool bValue = AxisHelper::isLogarithmic( rScale.Scaling );
225                 rOutItemSet.Put( SfxBoolItem( nWhichId, bValue ));
226             }
227             break;
228 
229         case SCHATTR_AXIS_REVERSE:
230                 rOutItemSet.Put( SfxBoolItem( nWhichId, (AxisOrientation_REVERSE == rScale.Orientation) ));
231             break;
232 
233         // Increment
234         case SCHATTR_AXIS_AUTO_STEP_MAIN:
235             if( bDateAxis )
236                 rOutItemSet.Put( SfxBoolItem( nWhichId, !lcl_hasTimeIntervalValue(rTimeIncrement.MajorTimeInterval) ) );
237             else
238                 rOutItemSet.Put( SfxBoolItem( nWhichId, !hasDoubleValue(rIncrement.Distance) ) );
239             break;
240 
241         case SCHATTR_AXIS_MAIN_TIME_UNIT:
242             {
243                 TimeInterval aTimeInterval;
244                 if( rTimeIncrement.MajorTimeInterval >>= aTimeInterval )
245                     rOutItemSet.Put( SfxInt32Item( nWhichId, aTimeInterval.TimeUnit ) );
246                 else if( m_pExplicitIncrement )
247                     rOutItemSet.Put( SfxInt32Item( nWhichId, m_pExplicitIncrement->MajorTimeInterval.TimeUnit ) );
248             }
249             break;
250 
251         case SCHATTR_AXIS_STEP_MAIN:
252             if( bDateAxis )
253             {
254                 TimeInterval aTimeInterval;
255                 if( rTimeIncrement.MajorTimeInterval >>= aTimeInterval )
256                     rOutItemSet.Put( SvxDoubleItem(aTimeInterval.Number, nWhichId ));
257                 else if( m_pExplicitIncrement )
258                     rOutItemSet.Put( SvxDoubleItem( m_pExplicitIncrement->MajorTimeInterval.Number, nWhichId ));
259             }
260             else
261             {
262                 double fDistance = 1.0;
263                 if( rIncrement.Distance >>= fDistance )
264                     rOutItemSet.Put( SvxDoubleItem(fDistance, nWhichId ));
265                 else if( m_pExplicitIncrement )
266                     rOutItemSet.Put( SvxDoubleItem( m_pExplicitIncrement->Distance, nWhichId ));
267             }
268             break;
269 
270         // SubIncrement
271         case SCHATTR_AXIS_AUTO_STEP_HELP:
272             if( bDateAxis )
273                 rOutItemSet.Put( SfxBoolItem( nWhichId, !lcl_hasTimeIntervalValue(rTimeIncrement.MinorTimeInterval) ) );
274             else
275                 rOutItemSet.Put( SfxBoolItem( nWhichId,
276                     ! ( rSubIncrements.getLength() > 0 && rSubIncrements[0].IntervalCount.hasValue() )));
277             break;
278 
279         case SCHATTR_AXIS_HELP_TIME_UNIT:
280             {
281                 TimeInterval aTimeInterval;
282                 if( rTimeIncrement.MinorTimeInterval >>= aTimeInterval )
283                     rOutItemSet.Put( SfxInt32Item( nWhichId, aTimeInterval.TimeUnit ) );
284                 else if( m_pExplicitIncrement )
285                     rOutItemSet.Put( SfxInt32Item( nWhichId, m_pExplicitIncrement->MinorTimeInterval.TimeUnit ) );
286             }
287             break;
288 
289         case SCHATTR_AXIS_STEP_HELP:
290             if( bDateAxis )
291             {
292                 TimeInterval aTimeInterval;
293                 if( rTimeIncrement.MinorTimeInterval >>= aTimeInterval )
294                     rOutItemSet.Put( SfxInt32Item( nWhichId, aTimeInterval.Number ));
295                 else if( m_pExplicitIncrement )
296                     rOutItemSet.Put( SfxInt32Item( nWhichId, m_pExplicitIncrement->MinorTimeInterval.Number ));
297             }
298             else
299             {
300                 if( rSubIncrements.getLength() > 0 && rSubIncrements[0].IntervalCount.hasValue())
301                 {
302                     OSL_ASSERT( rSubIncrements[0].IntervalCount.getValueTypeClass() == uno::TypeClass_LONG );
303                     rOutItemSet.Put( SfxInt32Item( nWhichId,
304                             *reinterpret_cast< const sal_Int32 * >(
305                                 rSubIncrements[0].IntervalCount.getValue()) ));
306                 }
307                 else
308                 {
309                     if( m_pExplicitIncrement && !m_pExplicitIncrement->SubIncrements.empty() )
310                     {
311                         rOutItemSet.Put( SfxInt32Item( nWhichId,
312                                 m_pExplicitIncrement->SubIncrements[0].IntervalCount ));
313                     }
314                 }
315             }
316             break;
317 
318         case SCHATTR_AXIS_AUTO_TIME_RESOLUTION:
319             {
320                 rOutItemSet.Put( SfxBoolItem( nWhichId,
321                         !rTimeIncrement.TimeResolution.hasValue() ));
322             }
323             break;
324         case SCHATTR_AXIS_TIME_RESOLUTION:
325             {
326                 long nTimeResolution=0;
327                 if( rTimeIncrement.TimeResolution >>= nTimeResolution )
328                     rOutItemSet.Put( SfxInt32Item( nWhichId, nTimeResolution ) );
329                 else if( m_pExplicitScale )
330                     rOutItemSet.Put( SfxInt32Item( nWhichId, m_pExplicitScale->TimeResolution ) );
331             }
332             break;
333 
334         case SCHATTR_AXIS_AUTO_ORIGIN:
335         {
336             rOutItemSet.Put( SfxBoolItem( nWhichId, ( !hasDoubleValue(rScale.Origin) )));
337         }
338         break;
339 
340         case SCHATTR_AXIS_ORIGIN:
341         {
342             double fOrigin = 0.0;
343             if( !(rScale.Origin >>= fOrigin) )
344             {
345                 if( m_pExplicitScale )
346                     fOrigin = m_pExplicitScale->Origin;
347             }
348             rOutItemSet.Put( SvxDoubleItem( fOrigin, nWhichId ));
349         }
350         break;
351 
352         case SCHATTR_AXIS_POSITION:
353         {
354             ::com::sun::star::chart::ChartAxisPosition eAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO );
355             GetPropertySet()->getPropertyValue(C2U( "CrossoverPosition" )) >>= eAxisPos;
356             rOutItemSet.Put( SfxInt32Item( nWhichId, eAxisPos ) );
357         }
358         break;
359 
360         case SCHATTR_AXIS_POSITION_VALUE:
361         {
362             double fValue = 0.0;
363             if( GetPropertySet()->getPropertyValue(C2U( "CrossoverValue" )) >>= fValue )
364                 rOutItemSet.Put( SvxDoubleItem( fValue, nWhichId ) );
365         }
366         break;
367 
368         case SCHATTR_AXIS_CROSSING_MAIN_AXIS_NUMBERFORMAT:
369         {
370             //read only item
371             //necessary tp display the crossing value with an appropriate format
372 
373             Reference< chart2::XCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis(
374                 m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) );
375 
376             Reference< chart2::XAxis > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( m_xAxis, xCooSys ) );
377 
378             sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
379                 xCrossingMainAxis, xCooSys, Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY ) );
380 
381             rOutItemSet.Put( SfxUInt32Item( nWhichId, nFormatKey ));
382         }
383         break;
384 
385         case SCHATTR_AXIS_LABEL_POSITION:
386         {
387             ::com::sun::star::chart::ChartAxisLabelPosition ePos( ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS );
388             GetPropertySet()->getPropertyValue(C2U( "LabelPosition" )) >>= ePos;
389             rOutItemSet.Put( SfxInt32Item( nWhichId, ePos ) );
390         }
391         break;
392 
393         case SCHATTR_AXIS_MARK_POSITION:
394         {
395             ::com::sun::star::chart::ChartAxisMarkPosition ePos( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS );
396             GetPropertySet()->getPropertyValue(C2U( "MarkPosition" )) >>= ePos;
397             rOutItemSet.Put( SfxInt32Item( nWhichId, ePos ) );
398         }
399         break;
400 
401         case SCHATTR_TEXT_DEGREES:
402         {
403             // convert double to int (times 100)
404             double fVal = 0;
405 
406             if( GetPropertySet()->getPropertyValue( C2U( "TextRotation" )) >>= fVal )
407             {
408                 rOutItemSet.Put( SfxInt32Item( nWhichId, static_cast< sal_Int32 >(
409                                                    ::rtl::math::round( fVal * 100.0 ) ) ));
410             }
411         }
412         break;
413 
414         case SID_ATTR_NUMBERFORMAT_VALUE:
415         {
416             if( m_pExplicitScale )
417             {
418                 Reference< chart2::XCoordinateSystem > xCooSys(
419                         AxisHelper::getCoordinateSystemOfAxis(
420                               m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) );
421 
422                 sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
423                     m_xAxis, xCooSys, Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY ) );
424 
425                 rOutItemSet.Put( SfxUInt32Item( nWhichId, nFormatKey ));
426             }
427         }
428         break;
429 
430         case SID_ATTR_NUMBERFORMAT_SOURCE:
431         {
432             bool bNumberFormatIsSet = ( GetPropertySet()->getPropertyValue( C2U( "NumberFormat" )).hasValue());
433             rOutItemSet.Put( SfxBoolItem( nWhichId, ! bNumberFormatIsSet ));
434         }
435         break;
436 
437         case SCHATTR_AXISTYPE:
438             rOutItemSet.Put( SfxInt32Item( nWhichId, rScale.AxisType ));
439         break;
440 
441         case SCHATTR_AXIS_AUTO_DATEAXIS:
442             rOutItemSet.Put( SfxBoolItem( nWhichId, rScale.AutoDateAxis ));
443         break;
444 
445         case SCHATTR_AXIS_ALLOW_DATEAXIS:
446         {
447             Reference< chart2::XCoordinateSystem > xCooSys(
448                 AxisHelper::getCoordinateSystemOfAxis( m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) );
449             sal_Int32 nDimensionIndex=0; sal_Int32 nAxisIndex=0;
450             AxisHelper::getIndicesForAxis(m_xAxis, xCooSys, nDimensionIndex, nAxisIndex );
451             bool bChartTypeAllowsDateAxis = ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys, 0 ), 2, nDimensionIndex );
452             rOutItemSet.Put( SfxBoolItem( nWhichId, bChartTypeAllowsDateAxis ));
453         }
454         break;
455     }
456 }
457 
lcl_isDateAxis(const SfxItemSet & rItemSet)458 bool lcl_isDateAxis( const SfxItemSet & rItemSet )
459 {
460     sal_Int32 nAxisType = static_cast< const SfxInt32Item & >( rItemSet.Get( SCHATTR_AXISTYPE )).GetValue();//::com::sun::star::chart2::AxisType
461     return (chart2::AxisType::DATE == nAxisType);
462 }
463 
lcl_isAutoMajor(const SfxItemSet & rItemSet)464 bool lcl_isAutoMajor( const SfxItemSet & rItemSet )
465 {
466     bool bRet = static_cast< const SfxBoolItem & >( rItemSet.Get( SCHATTR_AXIS_AUTO_STEP_MAIN )).GetValue();
467     return bRet;
468 }
469 
lcl_isAutoMinor(const SfxItemSet & rItemSet)470 bool lcl_isAutoMinor( const SfxItemSet & rItemSet )
471 {
472     bool bRet = static_cast< const SfxBoolItem & >( rItemSet.Get( SCHATTR_AXIS_AUTO_STEP_HELP )).GetValue();
473     return bRet;
474 }
475 
ApplySpecialItem(sal_uInt16 nWhichId,const SfxItemSet & rItemSet)476 bool AxisItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxItemSet & rItemSet )
477     throw( uno::Exception )
478 {
479     if( !m_xAxis.is() )
480         return false;
481 
482     chart2::ScaleData     aScale( m_xAxis->getScaleData() );
483 
484     bool bSetScale    = false;
485     bool bChangedOtherwise = false;
486 
487     uno::Any aValue;
488 
489     switch( nWhichId )
490     {
491         case SCHATTR_AXIS_AUTO_MAX:
492             if( (static_cast< const SfxBoolItem & >(
493                      rItemSet.Get( nWhichId )).GetValue() ))
494             {
495                 aScale.Maximum.clear();
496                 bSetScale = true;
497             }
498             // else SCHATTR_AXIS_MAX must have some value
499             break;
500 
501         case SCHATTR_AXIS_MAX:
502             // only if auto if false
503             if( ! (static_cast< const SfxBoolItem & >(
504                        rItemSet.Get( SCHATTR_AXIS_AUTO_MAX )).GetValue() ))
505             {
506                 rItemSet.Get( nWhichId ).QueryValue( aValue );
507 
508                 if( aScale.Maximum != aValue )
509                 {
510                     aScale.Maximum = aValue;
511                     bSetScale = true;
512                 }
513             }
514             break;
515 
516         case SCHATTR_AXIS_AUTO_MIN:
517             if( (static_cast< const SfxBoolItem & >(
518                      rItemSet.Get( nWhichId )).GetValue() ))
519             {
520                 aScale.Minimum.clear();
521                 bSetScale = true;
522             }
523             // else SCHATTR_AXIS_MIN must have some value
524             break;
525 
526         case SCHATTR_AXIS_MIN:
527             // only if auto if false
528             if( ! (static_cast< const SfxBoolItem & >(
529                        rItemSet.Get( SCHATTR_AXIS_AUTO_MIN )).GetValue() ))
530             {
531                 rItemSet.Get( nWhichId ).QueryValue( aValue );
532 
533                 if( aScale.Minimum != aValue )
534                 {
535                     aScale.Minimum = aValue;
536                     bSetScale = true;
537                 }
538             }
539             break;
540 
541         case SCHATTR_AXIS_LOGARITHM:
542         {
543             bool bWasLogarithm = AxisHelper::isLogarithmic( aScale.Scaling );
544 
545             if( (static_cast< const SfxBoolItem & >(
546                      rItemSet.Get( nWhichId )).GetValue() ))
547             {
548                 // logarithm is true
549                 if( ! bWasLogarithm )
550                 {
551                     aScale.Scaling = AxisHelper::createLogarithmicScaling( 10.0 );
552                     bSetScale = true;
553                 }
554             }
555             else
556             {
557                 // logarithm is false => linear scaling
558                 if( bWasLogarithm )
559                 {
560                     aScale.Scaling = AxisHelper::createLinearScaling();
561                     bSetScale = true;
562                 }
563             }
564         }
565         break;
566 
567         case SCHATTR_AXIS_REVERSE:
568         {
569             bool bWasReverse = ( AxisOrientation_REVERSE == aScale.Orientation );
570             bool bNewReverse = (static_cast< const SfxBoolItem & >(
571                      rItemSet.Get( nWhichId )).GetValue() );
572             if( bWasReverse != bNewReverse )
573             {
574                 aScale.Orientation = bNewReverse ? AxisOrientation_REVERSE : AxisOrientation_MATHEMATICAL;
575                 bSetScale = true;
576             }
577         }
578         break;
579 
580         // Increment
581         case SCHATTR_AXIS_AUTO_STEP_MAIN:
582             if( lcl_isAutoMajor(rItemSet) )
583             {
584                 aScale.IncrementData.Distance.clear();
585                 aScale.TimeIncrement.MajorTimeInterval.clear();
586                 bSetScale = true;
587             }
588             // else SCHATTR_AXIS_STEP_MAIN must have some value
589             break;
590 
591         case SCHATTR_AXIS_MAIN_TIME_UNIT:
592             if( !lcl_isAutoMajor(rItemSet) )
593             {
594                 if( rItemSet.Get( nWhichId ).QueryValue( aValue ) )
595                 {
596                     TimeInterval aTimeInterval;
597                     aScale.TimeIncrement.MajorTimeInterval >>= aTimeInterval;
598                     aValue >>= aTimeInterval.TimeUnit;
599                     aScale.TimeIncrement.MajorTimeInterval = uno::makeAny( aTimeInterval );
600                     bSetScale = true;
601                 }
602             }
603             break;
604 
605         case SCHATTR_AXIS_STEP_MAIN:
606             // only if auto if false
607             if( !lcl_isAutoMajor(rItemSet) )
608             {
609                 rItemSet.Get( nWhichId ).QueryValue( aValue );
610                 if( lcl_isDateAxis(rItemSet) )
611                 {
612                     double fValue = 1.0;
613                     if( aValue >>= fValue )
614                     {
615                         TimeInterval aTimeInterval;
616                         aScale.TimeIncrement.MajorTimeInterval >>= aTimeInterval;
617                         aTimeInterval.Number = static_cast<sal_Int32>(fValue);
618                         aScale.TimeIncrement.MajorTimeInterval = uno::makeAny( aTimeInterval );
619                         bSetScale = true;
620                     }
621                 }
622                 else if( aScale.IncrementData.Distance != aValue )
623                 {
624                     aScale.IncrementData.Distance = aValue;
625                     bSetScale = true;
626                 }
627             }
628             break;
629 
630         // SubIncrement
631         case SCHATTR_AXIS_AUTO_STEP_HELP:
632             if( lcl_isAutoMinor(rItemSet) )
633             {
634                 if( aScale.IncrementData.SubIncrements.getLength() > 0 &&
635                     aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() )
636                 {
637                         aScale.IncrementData.SubIncrements[0].IntervalCount.clear();
638                         bSetScale = true;
639                 }
640                 if( aScale.TimeIncrement.MinorTimeInterval.hasValue() )
641                 {
642                     aScale.TimeIncrement.MinorTimeInterval.clear();
643                     bSetScale = true;
644                 }
645             }
646             // else SCHATTR_AXIS_STEP_MAIN must have some value
647             break;
648 
649         case SCHATTR_AXIS_HELP_TIME_UNIT:
650             if( !lcl_isAutoMinor(rItemSet) )
651             {
652                 if( rItemSet.Get( nWhichId ).QueryValue( aValue ) )
653                 {
654                     TimeInterval aTimeInterval;
655                     aScale.TimeIncrement.MinorTimeInterval >>= aTimeInterval;
656                     aValue >>= aTimeInterval.TimeUnit;
657                     aScale.TimeIncrement.MinorTimeInterval = uno::makeAny( aTimeInterval );
658                     bSetScale = true;
659                 }
660             }
661             break;
662 
663         case SCHATTR_AXIS_STEP_HELP:
664             // only if auto is false
665             if( !lcl_isAutoMinor(rItemSet) )
666             {
667                 rItemSet.Get( nWhichId ).QueryValue( aValue );
668                 if( lcl_isDateAxis(rItemSet) )
669                 {
670                     TimeInterval aTimeInterval;
671                     aScale.TimeIncrement.MinorTimeInterval >>= aTimeInterval;
672                     aValue >>= aTimeInterval.Number;
673                     aScale.TimeIncrement.MinorTimeInterval = uno::makeAny(aTimeInterval);
674                     bSetScale = true;
675                 }
676                 else if( aScale.IncrementData.SubIncrements.getLength() > 0 )
677                 {
678                     if( ! aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() ||
679                         aScale.IncrementData.SubIncrements[0].IntervalCount != aValue )
680                     {
681                         OSL_ASSERT( aValue.getValueTypeClass() == uno::TypeClass_LONG );
682                         aScale.IncrementData.SubIncrements[0].IntervalCount = aValue;
683                         bSetScale = true;
684                     }
685                 }
686             }
687             break;
688 
689         case SCHATTR_AXIS_AUTO_TIME_RESOLUTION:
690             if( (static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )).GetValue() ))
691             {
692                 aScale.TimeIncrement.TimeResolution.clear();
693                 bSetScale = true;
694             }
695             break;
696         case SCHATTR_AXIS_TIME_RESOLUTION:
697             // only if auto is false
698             if( ! (static_cast< const SfxBoolItem & >( rItemSet.Get( SCHATTR_AXIS_AUTO_TIME_RESOLUTION )).GetValue() ))
699             {
700                 rItemSet.Get( nWhichId ).QueryValue( aValue );
701 
702                 if( aScale.TimeIncrement.TimeResolution != aValue )
703                 {
704                     aScale.TimeIncrement.TimeResolution = aValue;
705                     bSetScale = true;
706                 }
707             }
708             break;
709 
710 
711         case SCHATTR_AXIS_AUTO_ORIGIN:
712         {
713             if( (static_cast< const SfxBoolItem & >(
714                      rItemSet.Get( nWhichId )).GetValue() ))
715             {
716                 aScale.Origin.clear();
717                 bSetScale = true;
718             }
719         }
720         break;
721 
722         case SCHATTR_AXIS_ORIGIN:
723         {
724             // only if auto is false
725             if( ! (static_cast< const SfxBoolItem & >(
726                        rItemSet.Get( SCHATTR_AXIS_AUTO_ORIGIN )).GetValue() ))
727             {
728                 rItemSet.Get( nWhichId ).QueryValue( aValue );
729 
730                 if( aScale.Origin != aValue )
731                 {
732                     aScale.Origin = aValue;
733                     bSetScale = true;
734 
735                     if( !AxisHelper::isAxisPositioningEnabled() )
736                     {
737                         //keep old and new settings for axis positioning in sync somehow
738                         Reference< chart2::XCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis(
739                             m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) );
740 
741                         sal_Int32 nDimensionIndex=0;
742                         sal_Int32 nAxisIndex=0;
743                         if( AxisHelper::getIndicesForAxis( m_xAxis, xCooSys, nDimensionIndex, nAxisIndex ) && nAxisIndex==0 )
744                         {
745                             Reference< beans::XPropertySet > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( m_xAxis, xCooSys ), uno::UNO_QUERY );
746                             if( xCrossingMainAxis.is() )
747                             {
748                                 double fValue = 0.0;
749                                 if( aValue >>= fValue )
750                                 {
751                                     xCrossingMainAxis->setPropertyValue( C2U( "CrossoverPosition" ), uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_VALUE ));
752                                     xCrossingMainAxis->setPropertyValue( C2U( "CrossoverValue" ), uno::makeAny( fValue ));
753                                 }
754                                 else
755                                     xCrossingMainAxis->setPropertyValue( C2U( "CrossoverPosition" ), uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START ));
756                             }
757                         }
758                     }
759                 }
760             }
761         }
762         break;
763 
764         case SCHATTR_AXIS_POSITION:
765         {
766             ::com::sun::star::chart::ChartAxisPosition eAxisPos =
767                 (::com::sun::star::chart::ChartAxisPosition)
768                 static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue();
769 
770             ::com::sun::star::chart::ChartAxisPosition eOldAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO );
771             bool bPropExisted = ( GetPropertySet()->getPropertyValue(C2U( "CrossoverPosition" )) >>= eOldAxisPos );
772 
773             if( !bPropExisted || ( eOldAxisPos != eAxisPos ))
774             {
775                 GetPropertySet()->setPropertyValue( C2U( "CrossoverPosition" ), uno::makeAny( eAxisPos ));
776                 bChangedOtherwise = true;
777 
778                 //move the parallel axes to the other side if necessary
779                 if( eAxisPos==::com::sun::star::chart::ChartAxisPosition_START || eAxisPos==::com::sun::star::chart::ChartAxisPosition_END )
780                 {
781                     Reference< beans::XPropertySet > xParallelAxis( AxisHelper::getParallelAxis( m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ), uno::UNO_QUERY );
782                     if( xParallelAxis.is() )
783                     {
784                         ::com::sun::star::chart::ChartAxisPosition eOtherPos;
785                         if( xParallelAxis->getPropertyValue( C2U( "CrossoverPosition" ) ) >>= eOtherPos )
786                         {
787                             if( eOtherPos == eAxisPos )
788                             {
789                                 ::com::sun::star::chart::ChartAxisPosition eOppositePos =
790                                     (eAxisPos==::com::sun::star::chart::ChartAxisPosition_START)
791                                     ? ::com::sun::star::chart::ChartAxisPosition_END
792                                     : ::com::sun::star::chart::ChartAxisPosition_START;
793                                 xParallelAxis->setPropertyValue( C2U( "CrossoverPosition" ), uno::makeAny( eOppositePos ));
794                             }
795                         }
796                     }
797                 }
798             }
799         }
800         break;
801 
802         case SCHATTR_AXIS_POSITION_VALUE:
803         {
804             double fValue = static_cast< const SvxDoubleItem & >( rItemSet.Get( nWhichId )).GetValue();
805 
806             double fOldValue = 0.0;
807             bool bPropExisted = ( GetPropertySet()->getPropertyValue(C2U( "CrossoverValue" )) >>= fOldValue );
808 
809             if( !bPropExisted || ( fOldValue != fValue ))
810             {
811                 GetPropertySet()->setPropertyValue( C2U( "CrossoverValue" ), uno::makeAny( fValue ));
812                 bChangedOtherwise = true;
813 
814                 //keep old and new settings for axis positioning in sync somehow
815                 {
816                     Reference< chart2::XCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis(
817                         m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) );
818 
819                     sal_Int32 nDimensionIndex=0;
820                     sal_Int32 nAxisIndex=0;
821                     if( AxisHelper::getIndicesForAxis( m_xAxis, xCooSys, nDimensionIndex, nAxisIndex ) && nAxisIndex==0 && nDimensionIndex==0 )
822                     {
823                         Reference< chart2::XAxis > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( m_xAxis, xCooSys ) );
824                         if( xCrossingMainAxis.is() )
825                         {
826                             ScaleData aCrossingScale( xCrossingMainAxis->getScaleData() );
827                             aCrossingScale.Origin = uno::makeAny(fValue);
828                             xCrossingMainAxis->setScaleData(aCrossingScale);
829                         }
830                     }
831                 }
832             }
833         }
834         break;
835 
836         case SCHATTR_AXIS_LABEL_POSITION:
837         {
838             ::com::sun::star::chart::ChartAxisLabelPosition ePos =
839                 (::com::sun::star::chart::ChartAxisLabelPosition)
840                 static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue();
841 
842             ::com::sun::star::chart::ChartAxisLabelPosition eOldPos( ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS );
843             bool bPropExisted = ( GetPropertySet()->getPropertyValue(C2U( "LabelPosition" )) >>= eOldPos );
844 
845             if( !bPropExisted || ( eOldPos != ePos ))
846             {
847                 GetPropertySet()->setPropertyValue( C2U( "LabelPosition" ), uno::makeAny( ePos ));
848                 bChangedOtherwise = true;
849 
850                 //move the parallel axes to the other side if necessary
851                 if( ePos==::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START || ePos==::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END )
852                 {
853                     Reference< beans::XPropertySet > xParallelAxis( AxisHelper::getParallelAxis( m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ), uno::UNO_QUERY );
854                     if( xParallelAxis.is() )
855                     {
856                         ::com::sun::star::chart::ChartAxisLabelPosition eOtherPos;
857                         if( xParallelAxis->getPropertyValue( C2U( "LabelPosition" ) ) >>= eOtherPos )
858                         {
859                             if( eOtherPos == ePos )
860                             {
861                                 ::com::sun::star::chart::ChartAxisLabelPosition eOppositePos =
862                                     (ePos==::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START)
863                                     ? ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END
864                                     : ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START;
865                                 xParallelAxis->setPropertyValue( C2U( "LabelPosition" ), uno::makeAny( eOppositePos ));
866                             }
867                         }
868                     }
869                 }
870             }
871         }
872         break;
873 
874         case SCHATTR_AXIS_MARK_POSITION:
875         {
876             ::com::sun::star::chart::ChartAxisMarkPosition ePos =
877                 (::com::sun::star::chart::ChartAxisMarkPosition)
878                 static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue();
879 
880             ::com::sun::star::chart::ChartAxisMarkPosition eOldPos( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS );
881             bool bPropExisted = ( GetPropertySet()->getPropertyValue(C2U( "MarkPosition" )) >>= eOldPos );
882 
883             if( !bPropExisted || ( eOldPos != ePos ))
884             {
885                 GetPropertySet()->setPropertyValue( C2U( "MarkPosition" ), uno::makeAny( ePos ));
886                 bChangedOtherwise = true;
887             }
888         }
889         break;
890 
891         case SCHATTR_TEXT_DEGREES:
892         {
893             // convert int to double (divided by 100)
894             double fVal = static_cast< double >(
895                 static_cast< const SfxInt32Item & >(
896                     rItemSet.Get( nWhichId )).GetValue()) / 100.0;
897             double fOldVal = 0.0;
898             bool bPropExisted =
899                 ( GetPropertySet()->getPropertyValue( C2U( "TextRotation" )) >>= fOldVal );
900 
901             if( ! bPropExisted ||
902                 ( bPropExisted && fOldVal != fVal ))
903             {
904                 GetPropertySet()->setPropertyValue( C2U( "TextRotation" ), uno::makeAny( fVal ));
905                 bChangedOtherwise = true;
906             }
907         }
908         break;
909 
910         case SID_ATTR_NUMBERFORMAT_VALUE:
911         {
912             if( m_pExplicitScale )
913             {
914                 bool bUseSourceFormat =
915                     (static_cast< const SfxBoolItem & >(
916                         rItemSet.Get( SID_ATTR_NUMBERFORMAT_SOURCE )).GetValue() );
917 
918                 if( ! bUseSourceFormat )
919                 {
920                     sal_Int32 nFmt = static_cast< sal_Int32 >(
921                         static_cast< const SfxUInt32Item & >(
922                             rItemSet.Get( nWhichId )).GetValue());
923 
924                     aValue = uno::makeAny(nFmt);
925                     if( GetPropertySet()->getPropertyValue( C2U( "NumberFormat" )) != aValue )
926                     {
927                         GetPropertySet()->setPropertyValue( C2U( "NumberFormat" ), aValue );
928                         bChangedOtherwise = true;
929                     }
930                 }
931             }
932         }
933         break;
934 
935         case SID_ATTR_NUMBERFORMAT_SOURCE:
936         {
937             bool bUseSourceFormat =
938                 (static_cast< const SfxBoolItem & >(
939                     rItemSet.Get( nWhichId )).GetValue() );
940             bool bNumberFormatIsSet = ( GetPropertySet()->getPropertyValue( C2U( "NumberFormat" )).hasValue());
941 
942             bChangedOtherwise = (bUseSourceFormat == bNumberFormatIsSet);
943             if( bChangedOtherwise )
944             {
945                 if( ! bUseSourceFormat )
946                 {
947                     SfxItemState aState = rItemSet.GetItemState( SID_ATTR_NUMBERFORMAT_VALUE );
948                     if( aState == SFX_ITEM_SET )
949                     {
950                         sal_Int32 nFormatKey = static_cast< sal_Int32 >(
951                         static_cast< const SfxUInt32Item & >(
952                             rItemSet.Get( SID_ATTR_NUMBERFORMAT_VALUE )).GetValue());
953                         aValue <<= nFormatKey;
954                     }
955                     else
956                     {
957                         Reference< chart2::XCoordinateSystem > xCooSys(
958                         AxisHelper::getCoordinateSystemOfAxis(
959                               m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) );
960 
961                         sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
962                             m_xAxis, xCooSys, Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY ) );
963 
964                         aValue <<= nFormatKey;
965                     }
966                 }
967                 // else set a void Any
968                 GetPropertySet()->setPropertyValue( C2U( "NumberFormat" ), aValue );
969             }
970         }
971         break;
972 
973         case SCHATTR_AXISTYPE:
974         {
975             sal_Int32 nNewAxisType = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue();//::com::sun::star::chart2::AxisType
976             aScale.AxisType = nNewAxisType;
977             bSetScale = true;
978         }
979         break;
980 
981         case SCHATTR_AXIS_AUTO_DATEAXIS:
982         {
983             bool bNewValue = static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )).GetValue();
984             bool bOldValue = aScale.AutoDateAxis;
985             if( bOldValue != bNewValue )
986             {
987                 aScale.AutoDateAxis = bNewValue;
988                 bSetScale = true;
989             }
990         }
991         break;
992     }
993 
994     if( bSetScale )
995         m_xAxis->setScaleData( aScale );
996 
997     return (bSetScale || bChangedOtherwise);
998 }
999 
1000 } //  namespace wrapper
1001 } //  namespace chart
1002