Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/chart2/source/view/axes/DateScaling.cxx
Line
Count
Source
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 <cppuhelper/supportsservice.hxx>
24
25
#include <limits>
26
27
namespace
28
{
29
30
constexpr OUString lcl_aServiceName_DateScaling = u"com.sun.star.chart2.DateScaling"_ustr;
31
constexpr OUString lcl_aServiceName_InverseDateScaling
32
    = u"com.sun.star.chart2.InverseDateScaling"_ustr;
33
34
const double lcl_fNumberOfMonths = 12.0;//todo: this needs to be offered by basic tools Date class if it should be more generic
35
}
36
37
namespace chart
38
{
39
using namespace ::com::sun::star;
40
using namespace ::com::sun::star::chart2;
41
using ::com::sun::star::chart::TimeUnit::DAY;
42
using ::com::sun::star::chart::TimeUnit::MONTH;
43
using ::com::sun::star::chart::TimeUnit::YEAR;
44
45
DateScaling::DateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
46
0
        : m_aNullDate( rNullDate )
47
0
        , m_nTimeUnit( nTimeUnit )
48
0
        , m_bShifted( bShifted )
49
0
{
50
0
}
51
52
DateScaling::~DateScaling()
53
0
{
54
0
}
55
56
double SAL_CALL DateScaling::doScaling( double value )
57
0
{
58
0
    double fResult(value);
59
0
    if( std::isnan( value ) || std::isinf( value ) )
60
0
        return std::numeric_limits<double>::quiet_NaN();
61
0
    switch( m_nTimeUnit )
62
0
    {
63
0
        case DAY:
64
0
            fResult = value;
65
0
            if(m_bShifted)
66
0
                fResult+=0.5;
67
0
            break;
68
0
        case YEAR:
69
0
        case MONTH:
70
0
        default:
71
0
        {
72
0
            Date aDate(m_aNullDate);
73
0
            aDate.AddDays(::rtl::math::approxFloor(value));
74
0
            fResult = aDate.GetYear();
75
0
            fResult *= lcl_fNumberOfMonths;//assuming 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
0
            {
84
0
                if( m_nTimeUnit==YEAR )
85
0
                    fResult += 0.5*lcl_fNumberOfMonths;
86
0
                else
87
0
                    fResult += 0.5;
88
0
            }
89
0
            break;
90
0
        }
91
0
    }
92
0
    return fResult;
93
0
}
94
95
uno::Reference< XScaling > SAL_CALL DateScaling::getInverseScaling()
96
0
{
97
0
    return new InverseDateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
98
0
}
99
100
OUString SAL_CALL DateScaling::getServiceName()
101
0
{
102
0
    return lcl_aServiceName_DateScaling;
103
0
}
104
105
OUString SAL_CALL DateScaling::getImplementationName()
106
0
{
107
0
    return lcl_aServiceName_DateScaling;
108
0
}
109
110
sal_Bool SAL_CALL DateScaling::supportsService( const OUString& rServiceName )
111
0
{
112
0
    return cppu::supportsService(this, rServiceName);
113
0
}
114
115
css::uno::Sequence< OUString > SAL_CALL DateScaling::getSupportedServiceNames()
116
0
{
117
0
    return { lcl_aServiceName_DateScaling };
118
0
}
119
120
InverseDateScaling::InverseDateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
121
0
        : m_aNullDate( rNullDate )
122
0
        , m_nTimeUnit( nTimeUnit )
123
0
        , m_bShifted( bShifted )
124
0
{
125
0
}
126
127
InverseDateScaling::~InverseDateScaling()
128
0
{
129
0
}
130
131
double SAL_CALL InverseDateScaling::doScaling( double value )
132
0
{
133
0
    double fResult(value);
134
0
    if( std::isnan( value ) || std::isinf( value ) )
135
0
        return std::numeric_limits<double>::quiet_NaN();
136
0
    else
137
0
    {
138
0
        switch( m_nTimeUnit )
139
0
        {
140
0
            case DAY:
141
0
                if(m_bShifted)
142
0
                    value -= 0.5;
143
0
                fResult = value;
144
0
                break;
145
0
            case YEAR:
146
0
            case MONTH:
147
0
            default:
148
                //Date aDate(m_aNullDate);
149
0
                if(m_bShifted)
150
0
                {
151
0
                    if( m_nTimeUnit==YEAR )
152
0
                        value -= 0.5*lcl_fNumberOfMonths;
153
0
                    else
154
0
                        value -= 0.5;
155
0
                }
156
0
                Date aDate( Date::EMPTY );
157
0
                double fYear = ::rtl::math::approxFloor(value/lcl_fNumberOfMonths);
158
0
                double fMonth = ::rtl::math::approxFloor(value-(fYear*lcl_fNumberOfMonths));
159
0
                if( fMonth==0.0 )
160
0
                {
161
0
                    fYear--;
162
0
                    fMonth=12.0;
163
0
                }
164
0
                aDate.SetYear( static_cast<sal_uInt16>(fYear) );
165
0
                aDate.SetMonth( static_cast<sal_uInt16>(fMonth) );
166
0
                aDate.SetDay( 1 );
167
0
                double fMonthCount = (fYear*lcl_fNumberOfMonths)+fMonth;
168
0
                double fDay = (value-fMonthCount)*aDate.GetDaysInMonth();
169
0
                fDay += 1.0;
170
0
                aDate.SetDay( static_cast<sal_uInt16>(::rtl::math::round(fDay)) );
171
0
                fResult = aDate - m_aNullDate;
172
0
                break;
173
0
        }
174
0
    }
175
0
    return fResult;
176
0
}
177
178
uno::Reference< XScaling > SAL_CALL InverseDateScaling::getInverseScaling()
179
0
{
180
0
    return new DateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
181
0
}
182
183
OUString SAL_CALL InverseDateScaling::getServiceName()
184
0
{
185
0
    return lcl_aServiceName_InverseDateScaling;
186
0
}
187
188
OUString SAL_CALL InverseDateScaling::getImplementationName()
189
0
{
190
0
    return lcl_aServiceName_InverseDateScaling;
191
0
}
192
193
sal_Bool SAL_CALL InverseDateScaling::supportsService( const OUString& rServiceName )
194
0
{
195
0
    return cppu::supportsService(this, rServiceName);
196
0
}
197
198
css::uno::Sequence< OUString > SAL_CALL InverseDateScaling::getSupportedServiceNames()
199
0
{
200
0
    return { lcl_aServiceName_InverseDateScaling };
201
0
}
202
203
} //namespace chart
204
205
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */