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