1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_chart2.hxx"
30*cdf0e10cSrcweir #include "DateScaling.hxx"
31*cdf0e10cSrcweir #include <com/sun/star/chart/TimeUnit.hpp>
32*cdf0e10cSrcweir #include <rtl/math.hxx>
33*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir namespace
36*cdf0e10cSrcweir {
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir static const ::rtl::OUString lcl_aServiceName_DateScaling(
39*cdf0e10cSrcweir     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.DateScaling" ));
40*cdf0e10cSrcweir static const ::rtl::OUString lcl_aServiceName_InverseDateScaling(
41*cdf0e10cSrcweir     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.InverseDateScaling" ));
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir static const ::rtl::OUString lcl_aImplementationName_DateScaling(
44*cdf0e10cSrcweir     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.DateScaling" ));
45*cdf0e10cSrcweir static const ::rtl::OUString lcl_aImplementationName_InverseDateScaling(
46*cdf0e10cSrcweir     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.InverseDateScaling" ));
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir static const double lcl_fNumberOfMonths = 12.0;//todo: this needs to be offered by basic tools Date class if it should be more generic
49*cdf0e10cSrcweir }
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir //.............................................................................
52*cdf0e10cSrcweir namespace chart
53*cdf0e10cSrcweir {
54*cdf0e10cSrcweir //.............................................................................
55*cdf0e10cSrcweir using namespace ::com::sun::star;
56*cdf0e10cSrcweir using namespace ::com::sun::star::chart2;
57*cdf0e10cSrcweir using ::com::sun::star::chart::TimeUnit::DAY;
58*cdf0e10cSrcweir using ::com::sun::star::chart::TimeUnit::MONTH;
59*cdf0e10cSrcweir using ::com::sun::star::chart::TimeUnit::YEAR;
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir DateScaling::DateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
62*cdf0e10cSrcweir         : m_aNullDate( rNullDate )
63*cdf0e10cSrcweir         , m_nTimeUnit( nTimeUnit )
64*cdf0e10cSrcweir         , m_bShifted( bShifted )
65*cdf0e10cSrcweir {
66*cdf0e10cSrcweir }
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir DateScaling::~DateScaling()
69*cdf0e10cSrcweir {
70*cdf0e10cSrcweir }
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir double SAL_CALL DateScaling::doScaling( double value )
73*cdf0e10cSrcweir     throw (uno::RuntimeException)
74*cdf0e10cSrcweir {
75*cdf0e10cSrcweir     double fResult(value);
76*cdf0e10cSrcweir     if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
77*cdf0e10cSrcweir         ::rtl::math::setNan( & fResult );
78*cdf0e10cSrcweir     else
79*cdf0e10cSrcweir     {
80*cdf0e10cSrcweir         Date aDate(m_aNullDate);
81*cdf0e10cSrcweir         aDate += static_cast<long>(::rtl::math::approxFloor(value));
82*cdf0e10cSrcweir         switch( m_nTimeUnit )
83*cdf0e10cSrcweir         {
84*cdf0e10cSrcweir             case DAY:
85*cdf0e10cSrcweir                 fResult = value;
86*cdf0e10cSrcweir                 if(m_bShifted)
87*cdf0e10cSrcweir                     fResult+=0.5;
88*cdf0e10cSrcweir                 break;
89*cdf0e10cSrcweir             case YEAR:
90*cdf0e10cSrcweir             case MONTH:
91*cdf0e10cSrcweir             default:
92*cdf0e10cSrcweir                 fResult = aDate.GetYear();
93*cdf0e10cSrcweir                 fResult *= lcl_fNumberOfMonths;//asssuming equal count of months in each year
94*cdf0e10cSrcweir                 fResult += aDate.GetMonth();
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir                 double fDayOfMonth = aDate.GetDay();
97*cdf0e10cSrcweir                 fDayOfMonth -= 1.0;
98*cdf0e10cSrcweir                 double fDaysInMonth = aDate.GetDaysInMonth();
99*cdf0e10cSrcweir                 fResult += fDayOfMonth/fDaysInMonth;
100*cdf0e10cSrcweir                 if(m_bShifted)
101*cdf0e10cSrcweir                 {
102*cdf0e10cSrcweir                     if( YEAR==m_nTimeUnit )
103*cdf0e10cSrcweir                         fResult += 0.5*lcl_fNumberOfMonths;
104*cdf0e10cSrcweir                     else
105*cdf0e10cSrcweir                         fResult += 0.5;
106*cdf0e10cSrcweir                 }
107*cdf0e10cSrcweir                 break;
108*cdf0e10cSrcweir         }
109*cdf0e10cSrcweir     }
110*cdf0e10cSrcweir     return fResult;
111*cdf0e10cSrcweir }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir uno::Reference< XScaling > SAL_CALL DateScaling::getInverseScaling()
114*cdf0e10cSrcweir     throw (uno::RuntimeException)
115*cdf0e10cSrcweir {
116*cdf0e10cSrcweir     return new InverseDateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
117*cdf0e10cSrcweir }
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir ::rtl::OUString SAL_CALL DateScaling::getServiceName()
120*cdf0e10cSrcweir     throw (uno::RuntimeException)
121*cdf0e10cSrcweir {
122*cdf0e10cSrcweir     return lcl_aServiceName_DateScaling;
123*cdf0e10cSrcweir }
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > DateScaling::getSupportedServiceNames_Static()
126*cdf0e10cSrcweir {
127*cdf0e10cSrcweir     return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_DateScaling, 1 );
128*cdf0e10cSrcweir }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
131*cdf0e10cSrcweir APPHELPER_XSERVICEINFO_IMPL( DateScaling, lcl_aServiceName_DateScaling )
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir // ----------------------------------------
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir InverseDateScaling::InverseDateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
136*cdf0e10cSrcweir         : m_aNullDate( rNullDate )
137*cdf0e10cSrcweir         , m_nTimeUnit( nTimeUnit )
138*cdf0e10cSrcweir         , m_bShifted( bShifted )
139*cdf0e10cSrcweir {
140*cdf0e10cSrcweir }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir InverseDateScaling::~InverseDateScaling()
143*cdf0e10cSrcweir {
144*cdf0e10cSrcweir }
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir double SAL_CALL InverseDateScaling::doScaling( double value )
147*cdf0e10cSrcweir     throw (uno::RuntimeException)
148*cdf0e10cSrcweir {
149*cdf0e10cSrcweir     double fResult(value);
150*cdf0e10cSrcweir     if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
151*cdf0e10cSrcweir         ::rtl::math::setNan( & fResult );
152*cdf0e10cSrcweir     else
153*cdf0e10cSrcweir     {
154*cdf0e10cSrcweir         switch( m_nTimeUnit )
155*cdf0e10cSrcweir         {
156*cdf0e10cSrcweir             case DAY:
157*cdf0e10cSrcweir                 if(m_bShifted)
158*cdf0e10cSrcweir                     value -= 0.5;
159*cdf0e10cSrcweir                 fResult = value;
160*cdf0e10cSrcweir                 break;
161*cdf0e10cSrcweir             case YEAR:
162*cdf0e10cSrcweir             case MONTH:
163*cdf0e10cSrcweir             default:
164*cdf0e10cSrcweir                 //Date aDate(m_aNullDate);
165*cdf0e10cSrcweir                 if(m_bShifted)
166*cdf0e10cSrcweir                 {
167*cdf0e10cSrcweir                     if( YEAR==m_nTimeUnit )
168*cdf0e10cSrcweir                         value -= 0.5*lcl_fNumberOfMonths;
169*cdf0e10cSrcweir                     else
170*cdf0e10cSrcweir                         value -= 0.5;
171*cdf0e10cSrcweir                 }
172*cdf0e10cSrcweir                 Date aDate;
173*cdf0e10cSrcweir                 double fYear = ::rtl::math::approxFloor(value/lcl_fNumberOfMonths);
174*cdf0e10cSrcweir                 double fMonth = ::rtl::math::approxFloor(value-(fYear*lcl_fNumberOfMonths));
175*cdf0e10cSrcweir                 if( fMonth==0.0 )
176*cdf0e10cSrcweir                 {
177*cdf0e10cSrcweir                     fYear--;
178*cdf0e10cSrcweir                     fMonth=12.0;
179*cdf0e10cSrcweir                 }
180*cdf0e10cSrcweir                 aDate.SetYear( static_cast<sal_uInt16>(fYear) );
181*cdf0e10cSrcweir                 aDate.SetMonth( static_cast<sal_uInt16>(fMonth) );
182*cdf0e10cSrcweir                 aDate.SetDay( 1 );
183*cdf0e10cSrcweir                 double fMonthCount = (fYear*lcl_fNumberOfMonths)+fMonth;
184*cdf0e10cSrcweir                 double fDay = (value-fMonthCount)*aDate.GetDaysInMonth();
185*cdf0e10cSrcweir                 fDay += 1.0;
186*cdf0e10cSrcweir                 aDate.SetDay( static_cast<sal_uInt16>(::rtl::math::round(fDay)) );
187*cdf0e10cSrcweir                 fResult = aDate - m_aNullDate;
188*cdf0e10cSrcweir                 break;
189*cdf0e10cSrcweir         }
190*cdf0e10cSrcweir     }
191*cdf0e10cSrcweir     return fResult;
192*cdf0e10cSrcweir }
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir uno::Reference< XScaling > SAL_CALL InverseDateScaling::getInverseScaling()
195*cdf0e10cSrcweir     throw (uno::RuntimeException)
196*cdf0e10cSrcweir {
197*cdf0e10cSrcweir     return new DateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
198*cdf0e10cSrcweir }
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir ::rtl::OUString SAL_CALL InverseDateScaling::getServiceName()
201*cdf0e10cSrcweir     throw (uno::RuntimeException)
202*cdf0e10cSrcweir {
203*cdf0e10cSrcweir     return lcl_aServiceName_InverseDateScaling;
204*cdf0e10cSrcweir }
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > InverseDateScaling::getSupportedServiceNames_Static()
207*cdf0e10cSrcweir {
208*cdf0e10cSrcweir     return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_InverseDateScaling, 1 );
209*cdf0e10cSrcweir }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
212*cdf0e10cSrcweir APPHELPER_XSERVICEINFO_IMPL( InverseDateScaling, lcl_aServiceName_InverseDateScaling )
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir //.............................................................................
215*cdf0e10cSrcweir } //namespace chart
216*cdf0e10cSrcweir //.............................................................................
217