Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "DateScaling.hxx"
21 : #include <com/sun/star/chart/TimeUnit.hpp>
22 : #include <rtl/math.hxx>
23 : #include "com/sun/star/uno/RuntimeException.hpp"
24 : #include <cppuhelper/supportsservice.hxx>
25 :
26 : namespace
27 : {
28 :
29 : static const char lcl_aServiceName_DateScaling[] = "com.sun.star.chart2.DateScaling";
30 : static const char lcl_aServiceName_InverseDateScaling[] = "com.sun.star.chart2.InverseDateScaling";
31 :
32 : static const double lcl_fNumberOfMonths = 12.0;//todo: this needs to be offered by basic tools Date class if it should be more generic
33 : }
34 :
35 : namespace chart
36 : {
37 : using namespace ::com::sun::star;
38 : using namespace ::com::sun::star::chart2;
39 : using ::com::sun::star::chart::TimeUnit::DAY;
40 : using ::com::sun::star::chart::TimeUnit::MONTH;
41 : using ::com::sun::star::chart::TimeUnit::YEAR;
42 :
43 0 : DateScaling::DateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
44 : : m_aNullDate( rNullDate )
45 : , m_nTimeUnit( nTimeUnit )
46 0 : , m_bShifted( bShifted )
47 : {
48 0 : }
49 :
50 0 : DateScaling::~DateScaling()
51 : {
52 0 : }
53 :
54 0 : double SAL_CALL DateScaling::doScaling( double value )
55 : throw (uno::RuntimeException, std::exception)
56 : {
57 0 : double fResult(value);
58 0 : if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
59 0 : ::rtl::math::setNan( & fResult );
60 : else
61 : {
62 0 : Date aDate(m_aNullDate);
63 0 : aDate += static_cast<long>(::rtl::math::approxFloor(value));
64 0 : switch( m_nTimeUnit )
65 : {
66 : case DAY:
67 0 : fResult = value;
68 0 : if(m_bShifted)
69 0 : fResult+=0.5;
70 0 : break;
71 : case YEAR:
72 : case MONTH:
73 : default:
74 0 : fResult = aDate.GetYear();
75 0 : fResult *= lcl_fNumberOfMonths;//asssuming equal count of months in each year
76 0 : fResult += aDate.GetMonth();
77 :
78 0 : double fDayOfMonth = aDate.GetDay();
79 0 : fDayOfMonth -= 1.0;
80 0 : double fDaysInMonth = aDate.GetDaysInMonth();
81 0 : fResult += fDayOfMonth/fDaysInMonth;
82 0 : if(m_bShifted)
83 : {
84 0 : if( YEAR==m_nTimeUnit )
85 0 : fResult += 0.5*lcl_fNumberOfMonths;
86 : else
87 0 : fResult += 0.5;
88 : }
89 0 : break;
90 : }
91 : }
92 0 : return fResult;
93 : }
94 :
95 0 : uno::Reference< XScaling > SAL_CALL DateScaling::getInverseScaling()
96 : throw (uno::RuntimeException, std::exception)
97 : {
98 0 : return new InverseDateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
99 : }
100 :
101 0 : OUString SAL_CALL DateScaling::getServiceName()
102 : throw (uno::RuntimeException, std::exception)
103 : {
104 0 : return OUString(lcl_aServiceName_DateScaling);
105 : }
106 :
107 0 : uno::Sequence< OUString > DateScaling::getSupportedServiceNames_Static()
108 : {
109 0 : uno::Sequence< OUString > aSeq(1);
110 0 : aSeq.getArray()[0] = lcl_aServiceName_DateScaling;
111 0 : return aSeq;
112 : }
113 :
114 : // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
115 0 : OUString SAL_CALL DateScaling::getImplementationName()
116 : throw( css::uno::RuntimeException, std::exception )
117 : {
118 0 : return getImplementationName_Static();
119 : }
120 :
121 0 : OUString DateScaling::getImplementationName_Static()
122 : {
123 0 : return OUString(lcl_aServiceName_DateScaling);
124 : }
125 :
126 0 : sal_Bool SAL_CALL DateScaling::supportsService( const OUString& rServiceName )
127 : throw( css::uno::RuntimeException, std::exception )
128 : {
129 0 : return cppu::supportsService(this, rServiceName);
130 : }
131 :
132 0 : css::uno::Sequence< OUString > SAL_CALL DateScaling::getSupportedServiceNames()
133 : throw( css::uno::RuntimeException, std::exception )
134 : {
135 0 : return getSupportedServiceNames_Static();
136 : }
137 :
138 0 : InverseDateScaling::InverseDateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
139 : : m_aNullDate( rNullDate )
140 : , m_nTimeUnit( nTimeUnit )
141 0 : , m_bShifted( bShifted )
142 : {
143 0 : }
144 :
145 0 : InverseDateScaling::~InverseDateScaling()
146 : {
147 0 : }
148 :
149 0 : double SAL_CALL InverseDateScaling::doScaling( double value )
150 : throw (uno::RuntimeException, std::exception)
151 : {
152 0 : double fResult(value);
153 0 : if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
154 0 : ::rtl::math::setNan( & fResult );
155 : else
156 : {
157 0 : switch( m_nTimeUnit )
158 : {
159 : case DAY:
160 0 : if(m_bShifted)
161 0 : value -= 0.5;
162 0 : fResult = value;
163 0 : break;
164 : case YEAR:
165 : case MONTH:
166 : default:
167 : //Date aDate(m_aNullDate);
168 0 : if(m_bShifted)
169 : {
170 0 : if( YEAR==m_nTimeUnit )
171 0 : value -= 0.5*lcl_fNumberOfMonths;
172 : else
173 0 : value -= 0.5;
174 : }
175 0 : Date aDate( Date::EMPTY );
176 0 : double fYear = ::rtl::math::approxFloor(value/lcl_fNumberOfMonths);
177 0 : double fMonth = ::rtl::math::approxFloor(value-(fYear*lcl_fNumberOfMonths));
178 0 : if( fMonth==0.0 )
179 : {
180 0 : fYear--;
181 0 : fMonth=12.0;
182 : }
183 0 : aDate.SetYear( static_cast<sal_uInt16>(fYear) );
184 0 : aDate.SetMonth( static_cast<sal_uInt16>(fMonth) );
185 0 : aDate.SetDay( 1 );
186 0 : double fMonthCount = (fYear*lcl_fNumberOfMonths)+fMonth;
187 0 : double fDay = (value-fMonthCount)*aDate.GetDaysInMonth();
188 0 : fDay += 1.0;
189 0 : aDate.SetDay( static_cast<sal_uInt16>(::rtl::math::round(fDay)) );
190 0 : fResult = aDate - m_aNullDate;
191 0 : break;
192 : }
193 : }
194 0 : return fResult;
195 : }
196 :
197 0 : uno::Reference< XScaling > SAL_CALL InverseDateScaling::getInverseScaling()
198 : throw (uno::RuntimeException, std::exception)
199 : {
200 0 : return new DateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
201 : }
202 :
203 0 : OUString SAL_CALL InverseDateScaling::getServiceName()
204 : throw (uno::RuntimeException, std::exception)
205 : {
206 0 : return OUString(lcl_aServiceName_InverseDateScaling);
207 : }
208 :
209 0 : uno::Sequence< OUString > InverseDateScaling::getSupportedServiceNames_Static()
210 : {
211 0 : uno::Sequence< OUString > aSeq( 1 );
212 0 : aSeq.getArray()[0] = lcl_aServiceName_InverseDateScaling;
213 0 : return aSeq;
214 : }
215 :
216 : // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
217 0 : OUString SAL_CALL InverseDateScaling::getImplementationName()
218 : throw( css::uno::RuntimeException, std::exception )
219 : {
220 0 : return getImplementationName_Static();
221 : }
222 :
223 0 : OUString InverseDateScaling::getImplementationName_Static()
224 : {
225 0 : return OUString(lcl_aServiceName_InverseDateScaling);
226 : }
227 :
228 0 : sal_Bool SAL_CALL InverseDateScaling::supportsService( const OUString& rServiceName )
229 : throw( css::uno::RuntimeException, std::exception )
230 : {
231 0 : return cppu::supportsService(this, rServiceName);
232 : }
233 :
234 0 : css::uno::Sequence< OUString > SAL_CALL InverseDateScaling::getSupportedServiceNames()
235 : throw( css::uno::RuntimeException, std::exception )
236 : {
237 0 : return getSupportedServiceNames_Static();
238 : }
239 :
240 : } //namespace chart
241 :
242 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|