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 "DateScaling.hxx"
27 #include <com/sun/star/chart/TimeUnit.hpp>
28 #include <rtl/math.hxx>
29 #include "com/sun/star/uno/RuntimeException.hpp"
30
31 namespace
32 {
33
34 static const ::rtl::OUString lcl_aServiceName_DateScaling(
35 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.DateScaling" ));
36 static const ::rtl::OUString lcl_aServiceName_InverseDateScaling(
37 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.InverseDateScaling" ));
38
39 static const ::rtl::OUString lcl_aImplementationName_DateScaling(
40 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.DateScaling" ));
41 static const ::rtl::OUString lcl_aImplementationName_InverseDateScaling(
42 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.InverseDateScaling" ));
43
44 static const double lcl_fNumberOfMonths = 12.0;//todo: this needs to be offered by basic tools Date class if it should be more generic
45 }
46
47 //.............................................................................
48 namespace chart
49 {
50 //.............................................................................
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::chart2;
53 using ::com::sun::star::chart::TimeUnit::DAY;
54 using ::com::sun::star::chart::TimeUnit::MONTH;
55 using ::com::sun::star::chart::TimeUnit::YEAR;
56
DateScaling(const Date & rNullDate,sal_Int32 nTimeUnit,bool bShifted)57 DateScaling::DateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
58 : m_aNullDate( rNullDate )
59 , m_nTimeUnit( nTimeUnit )
60 , m_bShifted( bShifted )
61 {
62 }
63
~DateScaling()64 DateScaling::~DateScaling()
65 {
66 }
67
doScaling(double value)68 double SAL_CALL DateScaling::doScaling( double value )
69 throw (uno::RuntimeException)
70 {
71 double fResult(value);
72 if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
73 ::rtl::math::setNan( & fResult );
74 else
75 {
76 Date aDate(m_aNullDate);
77 aDate += static_cast<long>(::rtl::math::approxFloor(value));
78 switch( m_nTimeUnit )
79 {
80 case DAY:
81 fResult = value;
82 if(m_bShifted)
83 fResult+=0.5;
84 break;
85 case YEAR:
86 case MONTH:
87 default:
88 fResult = aDate.GetYear();
89 fResult *= lcl_fNumberOfMonths;//asssuming equal count of months in each year
90 fResult += aDate.GetMonth();
91
92 double fDayOfMonth = aDate.GetDay();
93 fDayOfMonth -= 1.0;
94 double fDaysInMonth = aDate.GetDaysInMonth();
95 fResult += fDayOfMonth/fDaysInMonth;
96 if(m_bShifted)
97 {
98 if( YEAR==m_nTimeUnit )
99 fResult += 0.5*lcl_fNumberOfMonths;
100 else
101 fResult += 0.5;
102 }
103 break;
104 }
105 }
106 return fResult;
107 }
108
getInverseScaling()109 uno::Reference< XScaling > SAL_CALL DateScaling::getInverseScaling()
110 throw (uno::RuntimeException)
111 {
112 return new InverseDateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
113 }
114
getServiceName()115 ::rtl::OUString SAL_CALL DateScaling::getServiceName()
116 throw (uno::RuntimeException)
117 {
118 return lcl_aServiceName_DateScaling;
119 }
120
getSupportedServiceNames_Static()121 uno::Sequence< ::rtl::OUString > DateScaling::getSupportedServiceNames_Static()
122 {
123 return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_DateScaling, 1 );
124 }
125
126 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL(DateScaling,lcl_aServiceName_DateScaling)127 APPHELPER_XSERVICEINFO_IMPL( DateScaling, lcl_aServiceName_DateScaling )
128
129 // ----------------------------------------
130
131 InverseDateScaling::InverseDateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
132 : m_aNullDate( rNullDate )
133 , m_nTimeUnit( nTimeUnit )
134 , m_bShifted( bShifted )
135 {
136 }
137
~InverseDateScaling()138 InverseDateScaling::~InverseDateScaling()
139 {
140 }
141
doScaling(double value)142 double SAL_CALL InverseDateScaling::doScaling( double value )
143 throw (uno::RuntimeException)
144 {
145 double fResult(value);
146 if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
147 ::rtl::math::setNan( & fResult );
148 else
149 {
150 switch( m_nTimeUnit )
151 {
152 case DAY:
153 if(m_bShifted)
154 value -= 0.5;
155 fResult = value;
156 break;
157 case YEAR:
158 case MONTH:
159 default:
160 //Date aDate(m_aNullDate);
161 if(m_bShifted)
162 {
163 if( YEAR==m_nTimeUnit )
164 value -= 0.5*lcl_fNumberOfMonths;
165 else
166 value -= 0.5;
167 }
168 Date aDate;
169 double fYear = ::rtl::math::approxFloor(value/lcl_fNumberOfMonths);
170 double fMonth = ::rtl::math::approxFloor(value-(fYear*lcl_fNumberOfMonths));
171 if( fMonth==0.0 )
172 {
173 fYear--;
174 fMonth=12.0;
175 }
176 aDate.SetYear( static_cast<sal_uInt16>(fYear) );
177 aDate.SetMonth( static_cast<sal_uInt16>(fMonth) );
178 aDate.SetDay( 1 );
179 double fMonthCount = (fYear*lcl_fNumberOfMonths)+fMonth;
180 double fDay = (value-fMonthCount)*aDate.GetDaysInMonth();
181 fDay += 1.0;
182 aDate.SetDay( static_cast<sal_uInt16>(::rtl::math::round(fDay)) );
183 fResult = aDate - m_aNullDate;
184 break;
185 }
186 }
187 return fResult;
188 }
189
getInverseScaling()190 uno::Reference< XScaling > SAL_CALL InverseDateScaling::getInverseScaling()
191 throw (uno::RuntimeException)
192 {
193 return new DateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
194 }
195
getServiceName()196 ::rtl::OUString SAL_CALL InverseDateScaling::getServiceName()
197 throw (uno::RuntimeException)
198 {
199 return lcl_aServiceName_InverseDateScaling;
200 }
201
getSupportedServiceNames_Static()202 uno::Sequence< ::rtl::OUString > InverseDateScaling::getSupportedServiceNames_Static()
203 {
204 return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_InverseDateScaling, 1 );
205 }
206
207 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
208 APPHELPER_XSERVICEINFO_IMPL( InverseDateScaling, lcl_aServiceName_InverseDateScaling )
209
210 //.............................................................................
211 } //namespace chart
212 //.............................................................................
213