1*cde9e8dcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*cde9e8dcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*cde9e8dcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*cde9e8dcSAndrew Rist  * distributed with this work for additional information
6*cde9e8dcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*cde9e8dcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*cde9e8dcSAndrew Rist  * "License"); you may not use this file except in compliance
9*cde9e8dcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*cde9e8dcSAndrew Rist  *
11*cde9e8dcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*cde9e8dcSAndrew Rist  *
13*cde9e8dcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*cde9e8dcSAndrew Rist  * software distributed under the License is distributed on an
15*cde9e8dcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*cde9e8dcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*cde9e8dcSAndrew Rist  * specific language governing permissions and limitations
18*cde9e8dcSAndrew Rist  * under the License.
19*cde9e8dcSAndrew Rist  *
20*cde9e8dcSAndrew Rist  *************************************************************/
21*cde9e8dcSAndrew Rist 
22*cde9e8dcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_chart2.hxx"
26cdf0e10cSrcweir #include "DateScaling.hxx"
27cdf0e10cSrcweir #include <com/sun/star/chart/TimeUnit.hpp>
28cdf0e10cSrcweir #include <rtl/math.hxx>
29cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir namespace
32cdf0e10cSrcweir {
33cdf0e10cSrcweir 
34cdf0e10cSrcweir static const ::rtl::OUString lcl_aServiceName_DateScaling(
35cdf0e10cSrcweir     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.DateScaling" ));
36cdf0e10cSrcweir static const ::rtl::OUString lcl_aServiceName_InverseDateScaling(
37cdf0e10cSrcweir     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.InverseDateScaling" ));
38cdf0e10cSrcweir 
39cdf0e10cSrcweir static const ::rtl::OUString lcl_aImplementationName_DateScaling(
40cdf0e10cSrcweir     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.DateScaling" ));
41cdf0e10cSrcweir static const ::rtl::OUString lcl_aImplementationName_InverseDateScaling(
42cdf0e10cSrcweir     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.InverseDateScaling" ));
43cdf0e10cSrcweir 
44cdf0e10cSrcweir static const double lcl_fNumberOfMonths = 12.0;//todo: this needs to be offered by basic tools Date class if it should be more generic
45cdf0e10cSrcweir }
46cdf0e10cSrcweir 
47cdf0e10cSrcweir //.............................................................................
48cdf0e10cSrcweir namespace chart
49cdf0e10cSrcweir {
50cdf0e10cSrcweir //.............................................................................
51cdf0e10cSrcweir using namespace ::com::sun::star;
52cdf0e10cSrcweir using namespace ::com::sun::star::chart2;
53cdf0e10cSrcweir using ::com::sun::star::chart::TimeUnit::DAY;
54cdf0e10cSrcweir using ::com::sun::star::chart::TimeUnit::MONTH;
55cdf0e10cSrcweir using ::com::sun::star::chart::TimeUnit::YEAR;
56cdf0e10cSrcweir 
DateScaling(const Date & rNullDate,sal_Int32 nTimeUnit,bool bShifted)57cdf0e10cSrcweir DateScaling::DateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
58cdf0e10cSrcweir         : m_aNullDate( rNullDate )
59cdf0e10cSrcweir         , m_nTimeUnit( nTimeUnit )
60cdf0e10cSrcweir         , m_bShifted( bShifted )
61cdf0e10cSrcweir {
62cdf0e10cSrcweir }
63cdf0e10cSrcweir 
~DateScaling()64cdf0e10cSrcweir DateScaling::~DateScaling()
65cdf0e10cSrcweir {
66cdf0e10cSrcweir }
67cdf0e10cSrcweir 
doScaling(double value)68cdf0e10cSrcweir double SAL_CALL DateScaling::doScaling( double value )
69cdf0e10cSrcweir     throw (uno::RuntimeException)
70cdf0e10cSrcweir {
71cdf0e10cSrcweir     double fResult(value);
72cdf0e10cSrcweir     if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
73cdf0e10cSrcweir         ::rtl::math::setNan( & fResult );
74cdf0e10cSrcweir     else
75cdf0e10cSrcweir     {
76cdf0e10cSrcweir         Date aDate(m_aNullDate);
77cdf0e10cSrcweir         aDate += static_cast<long>(::rtl::math::approxFloor(value));
78cdf0e10cSrcweir         switch( m_nTimeUnit )
79cdf0e10cSrcweir         {
80cdf0e10cSrcweir             case DAY:
81cdf0e10cSrcweir                 fResult = value;
82cdf0e10cSrcweir                 if(m_bShifted)
83cdf0e10cSrcweir                     fResult+=0.5;
84cdf0e10cSrcweir                 break;
85cdf0e10cSrcweir             case YEAR:
86cdf0e10cSrcweir             case MONTH:
87cdf0e10cSrcweir             default:
88cdf0e10cSrcweir                 fResult = aDate.GetYear();
89cdf0e10cSrcweir                 fResult *= lcl_fNumberOfMonths;//asssuming equal count of months in each year
90cdf0e10cSrcweir                 fResult += aDate.GetMonth();
91cdf0e10cSrcweir 
92cdf0e10cSrcweir                 double fDayOfMonth = aDate.GetDay();
93cdf0e10cSrcweir                 fDayOfMonth -= 1.0;
94cdf0e10cSrcweir                 double fDaysInMonth = aDate.GetDaysInMonth();
95cdf0e10cSrcweir                 fResult += fDayOfMonth/fDaysInMonth;
96cdf0e10cSrcweir                 if(m_bShifted)
97cdf0e10cSrcweir                 {
98cdf0e10cSrcweir                     if( YEAR==m_nTimeUnit )
99cdf0e10cSrcweir                         fResult += 0.5*lcl_fNumberOfMonths;
100cdf0e10cSrcweir                     else
101cdf0e10cSrcweir                         fResult += 0.5;
102cdf0e10cSrcweir                 }
103cdf0e10cSrcweir                 break;
104cdf0e10cSrcweir         }
105cdf0e10cSrcweir     }
106cdf0e10cSrcweir     return fResult;
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
getInverseScaling()109cdf0e10cSrcweir uno::Reference< XScaling > SAL_CALL DateScaling::getInverseScaling()
110cdf0e10cSrcweir     throw (uno::RuntimeException)
111cdf0e10cSrcweir {
112cdf0e10cSrcweir     return new InverseDateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
113cdf0e10cSrcweir }
114cdf0e10cSrcweir 
getServiceName()115cdf0e10cSrcweir ::rtl::OUString SAL_CALL DateScaling::getServiceName()
116cdf0e10cSrcweir     throw (uno::RuntimeException)
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     return lcl_aServiceName_DateScaling;
119cdf0e10cSrcweir }
120cdf0e10cSrcweir 
getSupportedServiceNames_Static()121cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > DateScaling::getSupportedServiceNames_Static()
122cdf0e10cSrcweir {
123cdf0e10cSrcweir     return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_DateScaling, 1 );
124cdf0e10cSrcweir }
125cdf0e10cSrcweir 
126cdf0e10cSrcweir // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL(DateScaling,lcl_aServiceName_DateScaling)127cdf0e10cSrcweir APPHELPER_XSERVICEINFO_IMPL( DateScaling, lcl_aServiceName_DateScaling )
128cdf0e10cSrcweir 
129cdf0e10cSrcweir // ----------------------------------------
130cdf0e10cSrcweir 
131cdf0e10cSrcweir InverseDateScaling::InverseDateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
132cdf0e10cSrcweir         : m_aNullDate( rNullDate )
133cdf0e10cSrcweir         , m_nTimeUnit( nTimeUnit )
134cdf0e10cSrcweir         , m_bShifted( bShifted )
135cdf0e10cSrcweir {
136cdf0e10cSrcweir }
137cdf0e10cSrcweir 
~InverseDateScaling()138cdf0e10cSrcweir InverseDateScaling::~InverseDateScaling()
139cdf0e10cSrcweir {
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
doScaling(double value)142cdf0e10cSrcweir double SAL_CALL InverseDateScaling::doScaling( double value )
143cdf0e10cSrcweir     throw (uno::RuntimeException)
144cdf0e10cSrcweir {
145cdf0e10cSrcweir     double fResult(value);
146cdf0e10cSrcweir     if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
147cdf0e10cSrcweir         ::rtl::math::setNan( & fResult );
148cdf0e10cSrcweir     else
149cdf0e10cSrcweir     {
150cdf0e10cSrcweir         switch( m_nTimeUnit )
151cdf0e10cSrcweir         {
152cdf0e10cSrcweir             case DAY:
153cdf0e10cSrcweir                 if(m_bShifted)
154cdf0e10cSrcweir                     value -= 0.5;
155cdf0e10cSrcweir                 fResult = value;
156cdf0e10cSrcweir                 break;
157cdf0e10cSrcweir             case YEAR:
158cdf0e10cSrcweir             case MONTH:
159cdf0e10cSrcweir             default:
160cdf0e10cSrcweir                 //Date aDate(m_aNullDate);
161cdf0e10cSrcweir                 if(m_bShifted)
162cdf0e10cSrcweir                 {
163cdf0e10cSrcweir                     if( YEAR==m_nTimeUnit )
164cdf0e10cSrcweir                         value -= 0.5*lcl_fNumberOfMonths;
165cdf0e10cSrcweir                     else
166cdf0e10cSrcweir                         value -= 0.5;
167cdf0e10cSrcweir                 }
168cdf0e10cSrcweir                 Date aDate;
169cdf0e10cSrcweir                 double fYear = ::rtl::math::approxFloor(value/lcl_fNumberOfMonths);
170cdf0e10cSrcweir                 double fMonth = ::rtl::math::approxFloor(value-(fYear*lcl_fNumberOfMonths));
171cdf0e10cSrcweir                 if( fMonth==0.0 )
172cdf0e10cSrcweir                 {
173cdf0e10cSrcweir                     fYear--;
174cdf0e10cSrcweir                     fMonth=12.0;
175cdf0e10cSrcweir                 }
176cdf0e10cSrcweir                 aDate.SetYear( static_cast<sal_uInt16>(fYear) );
177cdf0e10cSrcweir                 aDate.SetMonth( static_cast<sal_uInt16>(fMonth) );
178cdf0e10cSrcweir                 aDate.SetDay( 1 );
179cdf0e10cSrcweir                 double fMonthCount = (fYear*lcl_fNumberOfMonths)+fMonth;
180cdf0e10cSrcweir                 double fDay = (value-fMonthCount)*aDate.GetDaysInMonth();
181cdf0e10cSrcweir                 fDay += 1.0;
182cdf0e10cSrcweir                 aDate.SetDay( static_cast<sal_uInt16>(::rtl::math::round(fDay)) );
183cdf0e10cSrcweir                 fResult = aDate - m_aNullDate;
184cdf0e10cSrcweir                 break;
185cdf0e10cSrcweir         }
186cdf0e10cSrcweir     }
187cdf0e10cSrcweir     return fResult;
188cdf0e10cSrcweir }
189cdf0e10cSrcweir 
getInverseScaling()190cdf0e10cSrcweir uno::Reference< XScaling > SAL_CALL InverseDateScaling::getInverseScaling()
191cdf0e10cSrcweir     throw (uno::RuntimeException)
192cdf0e10cSrcweir {
193cdf0e10cSrcweir     return new DateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
getServiceName()196cdf0e10cSrcweir ::rtl::OUString SAL_CALL InverseDateScaling::getServiceName()
197cdf0e10cSrcweir     throw (uno::RuntimeException)
198cdf0e10cSrcweir {
199cdf0e10cSrcweir     return lcl_aServiceName_InverseDateScaling;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
getSupportedServiceNames_Static()202cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > InverseDateScaling::getSupportedServiceNames_Static()
203cdf0e10cSrcweir {
204cdf0e10cSrcweir     return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_InverseDateScaling, 1 );
205cdf0e10cSrcweir }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
208cdf0e10cSrcweir APPHELPER_XSERVICEINFO_IMPL( InverseDateScaling, lcl_aServiceName_InverseDateScaling )
209cdf0e10cSrcweir 
210cdf0e10cSrcweir //.............................................................................
211cdf0e10cSrcweir } //namespace chart
212cdf0e10cSrcweir //.............................................................................
213