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