Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/i18npool/source/calendar/calendarImpl.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 <calendarImpl.hxx>
21
#include <calendar_gregorian.hxx>
22
#include <localedata.hxx>
23
#include <comphelper/processfactory.hxx>
24
#include <cppuhelper/supportsservice.hxx>
25
26
#include <com/sun/star/uno/XComponentContext.hpp>
27
28
using namespace ::com::sun::star::uno;
29
using namespace ::com::sun::star::i18n;
30
31
namespace i18npool {
32
33
27.9k
CalendarImpl::CalendarImpl() : m_xContext(comphelper::getProcessComponentContext())
34
27.9k
{
35
27.9k
}
36
37
70.6k
CalendarImpl::CalendarImpl(const Reference< XComponentContext > &rxContext) : m_xContext(rxContext)
38
70.6k
{
39
70.6k
    if (!m_xContext.is())
40
0
        throw RuntimeException(u"CalendarImpl::CalendarImpl: empty m_xContext"_ustr);
41
70.6k
}
42
43
CalendarImpl::~CalendarImpl()
44
98.3k
{
45
98.3k
}
46
47
void SAL_CALL
48
CalendarImpl::loadDefaultCalendarTZ( const css::lang::Locale& rLocale, const OUString& rTimeZone )
49
128k
{
50
128k
    const Sequence< Calendar2 > xC = LocaleDataImpl::get()->getAllCalendars2(rLocale);
51
128k
    auto pCal = std::find_if(xC.begin(), xC.end(), [](const Calendar2& rCal) { return rCal.Default; });
52
128k
    if (pCal == xC.end())
53
0
        throw RuntimeException(u"CalendarImpl::loadDefaultCalendarTZ: no default calendar found for this locale"_ustr);
54
128k
    loadCalendarTZ(pCal->Name, rLocale, rTimeZone);
55
128k
}
56
57
void SAL_CALL
58
CalendarImpl::loadCalendarTZ( const OUString& uniqueID, const css::lang::Locale& rLocale, const OUString& rTimeZone )
59
236k
{
60
236k
    Reference < XCalendar4 > xOldCalendar( xCalendar );  // backup
61
236k
    const OUString aCacheID( uniqueID + "_" + rTimeZone);
62
236k
    bool bTimeZone = true;
63
236k
    sal_Int32 i;
64
65
294k
    for (i = 0; i < sal::static_int_cast<sal_Int32>(lookupTable.size()); i++) {
66
168k
        lookupTableItem &listItem = lookupTable[i];
67
168k
        if (aCacheID == listItem.m_aCacheID) {
68
110k
            xCalendar = listItem.xCalendar;
69
110k
            break;
70
110k
        }
71
168k
    }
72
73
236k
    if (i >= sal::static_int_cast<sal_Int32>(lookupTable.size())) {
74
125k
        Reference < XInterface > xI = m_xContext->getServiceManager()->createInstanceWithContext(
75
125k
                  "com.sun.star.i18n.Calendar_" + uniqueID, m_xContext);
76
77
125k
        if ( ! xI.is() ) {
78
            // check if the calendar is defined in localedata, load gregorian calendar service.
79
66
            const Sequence< Calendar2 > xC = LocaleDataImpl::get()->getAllCalendars2(rLocale);
80
132
            if (std::any_of(xC.begin(), xC.end(), [&uniqueID](const Calendar2& rCal) { return uniqueID == rCal.Name; }))
81
0
                xI = m_xContext->getServiceManager()->createInstanceWithContext(u"com.sun.star.i18n.Calendar_gregorian"_ustr, m_xContext);
82
66
        }
83
84
125k
        if ( !xI.is() )
85
66
            throw RuntimeException(u"CalendarImpl::loadCalendarTZ: no calendar found for this locale"_ustr);
86
125k
        xCalendar.set(xI, UNO_QUERY);
87
88
125k
        if (!rTimeZone.isEmpty())
89
27.9k
        {
90
            /* XXX NOTE: currently (2019-06-19) calendar implementations derive
91
             * from Calendar_gregorian, even Hijri and Jewish. If that should
92
             * change in future this should be adapted. */
93
27.9k
            Calendar_gregorian* pCal = dynamic_cast<Calendar_gregorian*>(xCalendar.get());
94
27.9k
            bTimeZone = (pCal && pCal->setTimeZone(rTimeZone));
95
27.9k
        }
96
97
125k
        lookupTable.emplace_back( aCacheID, xCalendar );
98
125k
    }
99
100
236k
    if ( !xCalendar.is() )
101
0
    {
102
0
        xCalendar = xOldCalendar;
103
0
        throw RuntimeException(u"CalendarImpl::loadCalendarTZ: no calendar found for this locale, should use old one?"_ustr);
104
0
    }
105
106
236k
    try
107
236k
    {
108
236k
        xCalendar->loadCalendar(uniqueID, rLocale);
109
236k
    }
110
236k
    catch ( Exception& )
111
236k
    {   // restore previous calendar and re-throw
112
1.86k
        xCalendar = std::move(xOldCalendar);
113
1.86k
        throw;
114
1.86k
    }
115
116
136k
    if (!bTimeZone)
117
        // The calendar is usable but is not in the expected time zone.
118
0
        throw RuntimeException(u"CalendarImpl::loadCalendarTZ: the calendar is usable but is not in the expected time zone"_ustr);
119
136k
}
120
121
Calendar2 SAL_CALL
122
CalendarImpl::getLoadedCalendar2()
123
0
{
124
0
    if (!xCalendar.is())
125
0
        throw RuntimeException(u"CalendarImpl::getLoadedCalendar2: no calendar"_ustr);
126
0
    return xCalendar->getLoadedCalendar2();
127
0
}
128
129
::css::i18n::Calendar SAL_CALL
130
CalendarImpl::getLoadedCalendar()
131
0
{
132
0
    if (!xCalendar.is())
133
0
        throw RuntimeException(u"CalendarImpl::getLoadedCalendar: no calendar"_ustr);
134
0
    return xCalendar->getLoadedCalendar();
135
0
}
136
137
Sequence< OUString > SAL_CALL
138
CalendarImpl::getAllCalendars( const css::lang::Locale& rLocale )
139
49.9k
{
140
49.9k
    const Sequence< Calendar2 > xC = LocaleDataImpl::get()->getAllCalendars2(rLocale);
141
49.9k
    Sequence< OUString > xSeq( xC.getLength() );
142
49.9k
    std::transform(xC.begin(), xC.end(), xSeq.getArray(),
143
99.9k
        [](const Calendar2& rCal) { return rCal.Name; });
144
49.9k
    return xSeq;
145
49.9k
}
146
147
void SAL_CALL
148
CalendarImpl::setDateTime( double fTimeInDays )
149
76.3k
{
150
76.3k
    if (!xCalendar.is())
151
0
        throw RuntimeException(u"CalendarImpl::setDateTime: no calendar"_ustr);
152
76.3k
    xCalendar->setDateTime( fTimeInDays );
153
76.3k
}
154
155
double SAL_CALL
156
CalendarImpl::getDateTime()
157
31.4k
{
158
31.4k
    if (!xCalendar.is())
159
0
        throw RuntimeException(u"CalendarImpl::getDateTime: no calendar"_ustr);
160
31.4k
    return xCalendar->getDateTime();
161
31.4k
}
162
163
void SAL_CALL
164
CalendarImpl::setLocalDateTime( double fTimeInDays )
165
523k
{
166
523k
    if (!xCalendar.is())
167
62.7k
        throw RuntimeException(u"CalendarImpl::setLocalDateTime: no calendar"_ustr);
168
461k
    xCalendar->setLocalDateTime( fTimeInDays );
169
461k
}
170
171
double SAL_CALL
172
CalendarImpl::getLocalDateTime()
173
53.0k
{
174
53.0k
    if (!xCalendar.is())
175
0
        throw RuntimeException(u"CalendarImpl::getLocalDateTime: no calendar"_ustr);
176
53.0k
    return xCalendar->getLocalDateTime();
177
53.0k
}
178
179
void SAL_CALL CalendarImpl::loadDefaultCalendar( const css::lang::Locale& rLocale )
180
0
{
181
0
    loadDefaultCalendarTZ( rLocale, OUString());
182
0
}
183
184
void SAL_CALL CalendarImpl::loadCalendar( const OUString& uniqueID, const css::lang::Locale& rLocale )
185
0
{
186
0
    loadCalendarTZ( uniqueID, rLocale, OUString());
187
0
}
188
189
OUString SAL_CALL
190
CalendarImpl::getUniqueID()
191
816k
{
192
816k
    if (!xCalendar.is())
193
0
        throw RuntimeException(u"CalendarImpl::getUniqueID: no calendar"_ustr);
194
816k
    return xCalendar->getUniqueID();
195
816k
}
196
197
void SAL_CALL
198
CalendarImpl::setValue( sal_Int16 fieldIndex, sal_Int16 value )
199
664k
{
200
664k
    if (!xCalendar.is())
201
269k
        throw RuntimeException(u"CalendarImpl::setValue: no calendar"_ustr);
202
395k
    xCalendar->setValue( fieldIndex, value );
203
395k
}
204
205
sal_Int16 SAL_CALL
206
CalendarImpl::getValue( sal_Int16 fieldIndex )
207
372k
{
208
372k
    if (!xCalendar.is())
209
0
        throw RuntimeException(u"CalendarImpl::getValue: no calendar"_ustr);
210
372k
    return xCalendar->getValue( fieldIndex );
211
372k
}
212
213
void SAL_CALL
214
CalendarImpl::addValue( sal_Int16 fieldIndex, sal_Int32 amount )
215
0
{
216
0
    if (!xCalendar.is())
217
0
        throw RuntimeException(u"CalendarImpl::addValue: no calendar"_ustr);
218
0
    xCalendar->addValue( fieldIndex, amount);
219
0
}
220
221
sal_Int16 SAL_CALL
222
CalendarImpl::getFirstDayOfWeek()
223
0
{
224
0
    if (!xCalendar.is())
225
0
        throw RuntimeException(u"CalendarImpl::getFirstDayOfWeek: no calendar"_ustr);
226
0
    return xCalendar->getFirstDayOfWeek();
227
0
}
228
229
void SAL_CALL
230
CalendarImpl::setFirstDayOfWeek( sal_Int16 day )
231
0
{
232
0
    if (!xCalendar.is())
233
0
        throw RuntimeException(u"CalendarImpl::setFirstDayOfWeek: no calendar"_ustr);
234
0
    xCalendar->setFirstDayOfWeek(day);
235
0
}
236
237
void SAL_CALL
238
CalendarImpl::setMinimumNumberOfDaysForFirstWeek( sal_Int16 days )
239
0
{
240
0
    if (!xCalendar.is())
241
0
        throw RuntimeException(u"CalendarImpl::setMinimumNumberOfDaysForFirstWeek: no calendar"_ustr);
242
0
    xCalendar->setMinimumNumberOfDaysForFirstWeek(days);
243
0
}
244
245
sal_Int16 SAL_CALL
246
CalendarImpl::getMinimumNumberOfDaysForFirstWeek()
247
0
{
248
0
    if (!xCalendar.is())
249
0
        throw RuntimeException(u"CalendarImpl::getMinimumNumberOfDaysForFirstWeek: no calendar"_ustr);
250
0
    return xCalendar->getMinimumNumberOfDaysForFirstWeek();
251
0
}
252
253
254
OUString SAL_CALL
255
CalendarImpl::getDisplayName( sal_Int16 displayIndex, sal_Int16 idx, sal_Int16 nameType )
256
980
{
257
980
    if (!xCalendar.is())
258
0
        throw RuntimeException(u"CalendarImpl::getDisplayName: no calendar"_ustr);
259
980
    return xCalendar->getDisplayName( displayIndex, idx, nameType );
260
980
}
261
262
sal_Int16 SAL_CALL
263
CalendarImpl::getNumberOfMonthsInYear()
264
3.72M
{
265
3.72M
    if (!xCalendar.is())
266
1.68M
        throw RuntimeException(u"CalendarImpl::setDisplayName: no calendar"_ustr);
267
2.03M
    return xCalendar->getNumberOfMonthsInYear();
268
3.72M
}
269
270
271
sal_Int16 SAL_CALL
272
CalendarImpl::getNumberOfDaysInWeek()
273
739k
{
274
739k
    if (!xCalendar.is())
275
374k
        throw RuntimeException(u"CalendarImpl::getNumberOfDaysInWeek: no calendar"_ustr);
276
365k
    return xCalendar->getNumberOfDaysInWeek();
277
739k
}
278
279
280
Sequence< CalendarItem > SAL_CALL
281
CalendarImpl::getDays()
282
0
{
283
0
    if (!xCalendar.is())
284
0
        throw RuntimeException(u"CalendarImpl::setNumberOfDaysInWeek: no calendar"_ustr);
285
0
    return xCalendar->getDays();
286
0
}
287
288
289
Sequence< CalendarItem > SAL_CALL
290
CalendarImpl::getMonths()
291
0
{
292
0
    if (!xCalendar.is())
293
0
        throw RuntimeException(u"CalendarImpl::getMonths: no calendar"_ustr);
294
0
    return xCalendar->getMonths();
295
0
}
296
297
298
Sequence< CalendarItem2 > SAL_CALL
299
CalendarImpl::getDays2()
300
159k
{
301
159k
    if (!xCalendar.is())
302
125k
        throw RuntimeException(u"CalendarImpl::getDays2: no calendar"_ustr);
303
33.8k
    return xCalendar->getDays2();
304
159k
}
305
306
307
Sequence< CalendarItem2 > SAL_CALL
308
CalendarImpl::getMonths2()
309
159k
{
310
159k
    if (!xCalendar.is())
311
125k
        throw RuntimeException(u"CalendarImpl::getMonths2: no calendar"_ustr);
312
33.8k
    return xCalendar->getMonths2();
313
159k
}
314
315
316
Sequence< CalendarItem2 > SAL_CALL
317
CalendarImpl::getGenitiveMonths2()
318
159k
{
319
159k
    if (!xCalendar.is())
320
125k
        throw RuntimeException(u"CalendarImpl::getGenitiveMonths2: no calendar"_ustr);
321
33.8k
    return xCalendar->getGenitiveMonths2();
322
159k
}
323
324
325
Sequence< CalendarItem2 > SAL_CALL
326
CalendarImpl::getPartitiveMonths2()
327
159k
{
328
159k
    if (!xCalendar.is())
329
125k
        throw RuntimeException(u"CalendarImpl::getPartitiveMonths2: no calendar"_ustr);
330
33.8k
    return xCalendar->getPartitiveMonths2();
331
159k
}
332
333
334
sal_Bool SAL_CALL
335
CalendarImpl::isValid()
336
182k
{
337
182k
    if (!xCalendar.is())
338
86.1k
        throw RuntimeException(u"CalendarImpl::isValid: no calendar"_ustr);
339
96.1k
    return xCalendar->isValid();
340
182k
}
341
342
OUString SAL_CALL
343
CalendarImpl::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_Int16 nNativeNumberMode )
344
1.08M
{
345
1.08M
    if (!xCalendar.is())
346
0
        throw RuntimeException(u"CalendarImpl::getDisplayString: no calendar"_ustr);
347
1.08M
    return xCalendar->getDisplayString(nCalendarDisplayCode, nNativeNumberMode);
348
1.08M
}
349
350
OUString SAL_CALL
351
CalendarImpl::getImplementationName()
352
0
{
353
0
    return u"com.sun.star.i18n.CalendarImpl"_ustr;
354
0
}
355
356
sal_Bool SAL_CALL
357
CalendarImpl::supportsService(const OUString& rServiceName)
358
0
{
359
0
    return cppu::supportsService(this, rServiceName);
360
0
}
361
362
Sequence< OUString > SAL_CALL
363
CalendarImpl::getSupportedServiceNames()
364
0
{
365
0
    return { u"com.sun.star.i18n.LocaleCalendar"_ustr, u"com.sun.star.i18n.LocaleCalendar2"_ustr };
366
0
}
367
368
}
369
370
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */