Branch data Line data Source code
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 : :
21 : : #include <rtl/strbuf.hxx>
22 : : #include <tools/string.hxx>
23 : : #include <tools/debug.hxx>
24 : : #include <unotools/calendarwrapper.hxx>
25 : : #include <instance.hxx>
26 : : #include <com/sun/star/i18n/CalendarFieldIndex.hpp>
27 : : #include <com/sun/star/i18n/XCalendar3.hpp>
28 : :
29 : : #define CALENDAR_SERVICENAME "com.sun.star.i18n.LocaleCalendar"
30 : :
31 : : using namespace ::com::sun::star;
32 : : using namespace ::com::sun::star::i18n;
33 : : using namespace ::com::sun::star::uno;
34 : :
35 : :
36 : : const double MILLISECONDS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0;
37 : :
38 : :
39 : 199 : CalendarWrapper::CalendarWrapper(
40 : : const Reference< lang::XMultiServiceFactory > & xSF
41 : : )
42 : : :
43 : : xSMgr( xSF ),
44 : 199 : aEpochStart( Date( 1, 1, 1970 ) )
45 : : {
46 [ + - ][ + - ]: 199 : xC = Reference< XCalendar3 >( intl_createInstance( xSMgr, CALENDAR_SERVICENAME, "CalendarWrapper" ), uno::UNO_QUERY );
[ + - ]
47 : 199 : }
48 : :
49 : 161 : CalendarWrapper::~CalendarWrapper()
50 : : {
51 : 161 : }
52 : :
53 : :
54 : 218 : void CalendarWrapper::loadDefaultCalendar( const ::com::sun::star::lang::Locale& rLocale )
55 : : {
56 : : try
57 : : {
58 [ + - ]: 218 : if ( xC.is() )
59 [ + - ][ + - ]: 218 : xC->loadDefaultCalendar( rLocale );
60 : : }
61 : 0 : catch (const Exception& e)
62 : : {
63 : : SAL_WARN( "unotools.i18n", "loadDefaultCalendar: Exception caught " << e.Message );
64 : : }
65 [ # # ]: 218 : }
66 : :
67 : :
68 : 0 : void CalendarWrapper::loadCalendar( const ::rtl::OUString& rUniqueID, const ::com::sun::star::lang::Locale& rLocale )
69 : : {
70 : : try
71 : : {
72 [ # # ]: 0 : if ( xC.is() )
73 [ # # ][ # # ]: 0 : xC->loadCalendar( rUniqueID, rLocale );
74 : : }
75 : 0 : catch (const Exception& e)
76 : : {
77 : : SAL_WARN( "unotools.i18n", "loadCalendar: Exception caught requested: "
78 : : << rUniqueID << " Locale: " << rLocale.Language << "_" << rLocale.Country << " " << e.Message );
79 : : }
80 [ # # ]: 0 : }
81 : :
82 : :
83 : 0 : ::com::sun::star::uno::Sequence< ::rtl::OUString > CalendarWrapper::getAllCalendars( const ::com::sun::star::lang::Locale& rLocale ) const
84 : : {
85 : : try
86 : : {
87 [ # # ]: 0 : if ( xC.is() )
88 [ # # ][ # # ]: 0 : return xC->getAllCalendars( rLocale );
89 : : }
90 : 0 : catch (const Exception& e)
91 : : {
92 : : SAL_WARN( "unotools.i18n", "getAllCalendars: Exception caught " << e.Message );
93 : : }
94 : :
95 [ # # ]: 0 : return ::com::sun::star::uno::Sequence< ::rtl::OUString > (0);
96 : : }
97 : :
98 : :
99 : 460 : ::rtl::OUString CalendarWrapper::getUniqueID() const
100 : : {
101 : : try
102 : : {
103 [ + - ]: 460 : if ( xC.is() )
104 [ + - ][ + - ]: 460 : return xC->getUniqueID();
105 : : }
106 : 0 : catch (const Exception& e)
107 : : {
108 : : SAL_WARN( "unotools.i18n", "getUniqueID: Exception caught " << e.Message );
109 : : }
110 [ # # ]: 460 : return ::rtl::OUString();
111 : : }
112 : :
113 : :
114 : 0 : void CalendarWrapper::setDateTime( double nTimeInDays )
115 : : {
116 : : try
117 : : {
118 [ # # ]: 0 : if ( xC.is() )
119 [ # # ][ # # ]: 0 : xC->setDateTime( nTimeInDays );
120 : : }
121 : 0 : catch (const Exception& e)
122 : : {
123 : : SAL_WARN( "unotools.i18n", "setDateTime: Exception caught " << e.Message );
124 : : }
125 [ # # ]: 0 : }
126 : :
127 : :
128 : 0 : double CalendarWrapper::getDateTime() const
129 : : {
130 : : try
131 : : {
132 [ # # ]: 0 : if ( xC.is() )
133 [ # # ][ # # ]: 0 : return xC->getDateTime();
134 : : }
135 : 0 : catch (const Exception& e)
136 : : {
137 : : SAL_WARN( "unotools.i18n", "getDateTime: Exception caught " << e.Message );
138 : : }
139 [ # # ]: 0 : return 0.0;
140 : : }
141 : :
142 : :
143 : 2236 : sal_Int32 CalendarWrapper::getCombinedOffsetInMillis(
144 : : sal_Int16 nParentFieldIndex, sal_Int16 nChildFieldIndex ) const
145 : : {
146 : 2236 : sal_Int32 nOffset = 0;
147 : : try
148 : : {
149 [ + - ]: 2236 : if ( xC.is() )
150 : : {
151 [ + - ][ + - ]: 2236 : nOffset = static_cast<sal_Int32>( xC->getValue( nParentFieldIndex )) * 60000;
152 [ + - ][ + - ]: 2236 : sal_Int16 nSecondMillis = xC->getValue( nChildFieldIndex );
153 [ - + ]: 2236 : if (nOffset < 0)
154 : 0 : nOffset -= static_cast<sal_uInt16>( nSecondMillis);
155 : : else
156 : 2236 : nOffset += static_cast<sal_uInt16>( nSecondMillis);
157 : : }
158 : : }
159 : 0 : catch (const Exception& e)
160 : : {
161 : : SAL_WARN( "unotools.i18n", "setLocalDateTime: Exception caught " << e.Message );
162 : : }
163 [ # # ]: 2236 : return nOffset;
164 : : }
165 : :
166 : :
167 : 1118 : sal_Int32 CalendarWrapper::getZoneOffsetInMillis() const
168 : : {
169 : : return getCombinedOffsetInMillis( CalendarFieldIndex::ZONE_OFFSET,
170 : 1118 : CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS);
171 : : }
172 : :
173 : :
174 : 1118 : sal_Int32 CalendarWrapper::getDSTOffsetInMillis() const
175 : : {
176 : : return getCombinedOffsetInMillis( CalendarFieldIndex::DST_OFFSET,
177 : 1118 : CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS);
178 : : }
179 : :
180 : :
181 : 481 : void CalendarWrapper::setLocalDateTime( double nTimeInDays )
182 : : {
183 : : try
184 : : {
185 [ + - ]: 481 : if ( xC.is() )
186 : : {
187 : : // First set a nearby value to obtain the timezone and DST offset.
188 : : // This is necessary to let ICU choose the corresponding
189 : : // OlsonTimeZone transitions. Since ICU incorporates also
190 : : // historical data even the timezone may differ for different
191 : : // dates! (Which was the cause for #i76623# when the timezone of a
192 : : // previously set date was used.) Timezone may also include
193 : : // seconds, so use milliseconds field as well.
194 [ + - ][ + - ]: 481 : xC->setDateTime( nTimeInDays );
195 [ + - ]: 481 : sal_Int32 nZone1 = getZoneOffsetInMillis();
196 [ + - ]: 481 : sal_Int32 nDST1 = getDSTOffsetInMillis();
197 : 481 : double nLoc = nTimeInDays - (double)(nZone1 + nDST1) / MILLISECONDS_PER_DAY;
198 [ + - ][ + - ]: 481 : xC->setDateTime( nLoc );
199 [ + - ]: 481 : sal_Int32 nZone2 = getZoneOffsetInMillis();
200 [ + - ]: 481 : sal_Int32 nDST2 = getDSTOffsetInMillis();
201 : : // If DSTs differ after calculation, we crossed boundaries. Do it
202 : : // again, this time using the DST corrected initial value for the
203 : : // real local time.
204 : : // See also localtime/gmtime conversion pitfalls at
205 : : // http://www.erack.de/download/timetest.c
206 [ - + ]: 481 : if ( nDST1 != nDST2 )
207 : : {
208 : 0 : nLoc = nTimeInDays - (double)(nZone2 + nDST2) / MILLISECONDS_PER_DAY;
209 [ # # ][ # # ]: 0 : xC->setDateTime( nLoc );
210 : : // #i17222# If the DST onset rule says to switch from 00:00 to
211 : : // 01:00 and we tried to set onsetDay 00:00 with DST, the
212 : : // result was onsetDay-1 23:00 and no DST, which is not what we
213 : : // want. So once again without DST, resulting in onsetDay
214 : : // 01:00 and DST. Yes, this seems to be weird, but logically
215 : : // correct.
216 [ # # ]: 0 : sal_Int32 nDST3 = getDSTOffsetInMillis();
217 [ # # ][ # # ]: 0 : if ( nDST2 != nDST3 && !nDST3 )
218 : : {
219 : 0 : nLoc = nTimeInDays - (double)(nZone2 + nDST3) / MILLISECONDS_PER_DAY;
220 [ # # ][ # # ]: 0 : xC->setDateTime( nLoc );
221 : : }
222 : : }
223 : : }
224 : : }
225 : 0 : catch (const Exception& e)
226 : : {
227 : : SAL_WARN( "unotools.i18n", "setLocalDateTime: Exception caught " << e.Message );
228 : : }
229 [ # # ]: 481 : }
230 : :
231 : :
232 : 156 : double CalendarWrapper::getLocalDateTime() const
233 : : {
234 : : try
235 : : {
236 [ + - ]: 156 : if ( xC.is() )
237 : : {
238 [ + - ][ + - ]: 156 : double nTimeInDays = xC->getDateTime();
239 [ + - ]: 156 : sal_Int32 nZone = getZoneOffsetInMillis();
240 [ + - ]: 156 : sal_Int32 nDST = getDSTOffsetInMillis();
241 : 156 : nTimeInDays += (double)(nZone + nDST) / MILLISECONDS_PER_DAY;
242 : 156 : return nTimeInDays;
243 : : }
244 : : }
245 : 0 : catch (const Exception& e)
246 : : {
247 : : SAL_WARN( "unotools.i18n", "getLocalDateTime: Exception caught " << e.Message );
248 : : }
249 [ # # ]: 156 : return 0.0;
250 : : }
251 : :
252 : :
253 : 624 : void CalendarWrapper::setValue( sal_Int16 nFieldIndex, sal_Int16 nValue )
254 : : {
255 : : try
256 : : {
257 [ + - ]: 624 : if ( xC.is() )
258 [ + - ][ + - ]: 624 : xC->setValue( nFieldIndex, nValue );
259 : : }
260 : 0 : catch (const Exception& e)
261 : : {
262 : : SAL_WARN( "unotools.i18n", "setValue: Exception caught " << e.Message );
263 : : }
264 [ # # ]: 624 : }
265 : :
266 : :
267 : 156 : sal_Bool CalendarWrapper::isValid() const
268 : : {
269 : : try
270 : : {
271 [ + - ]: 156 : if ( xC.is() )
272 [ + - ][ + - ]: 156 : return xC->isValid();
273 : : }
274 : 0 : catch (const Exception& e)
275 : : {
276 : : SAL_WARN( "unotools.i18n", "isValue: Exception caught " << e.Message );
277 : : }
278 [ # # ]: 156 : return sal_False;
279 : : }
280 : :
281 : :
282 : 380 : sal_Int16 CalendarWrapper::getValue( sal_Int16 nFieldIndex ) const
283 : : {
284 : : try
285 : : {
286 [ + - ]: 380 : if ( xC.is() )
287 [ + - ][ + - ]: 380 : return xC->getValue( nFieldIndex );
288 : : }
289 : 0 : catch (const Exception& e)
290 : : {
291 : : SAL_WARN( "unotools.i18n", "getValue: Exception caught " << e.Message );
292 : : }
293 [ # # ]: 380 : return 0;
294 : : }
295 : :
296 : :
297 : 0 : void CalendarWrapper::addValue( sal_Int16 nFieldIndex, sal_Int32 nAmount )
298 : : {
299 : : try
300 : : {
301 [ # # ]: 0 : if ( xC.is() )
302 [ # # ][ # # ]: 0 : xC->addValue( nFieldIndex, nAmount );
303 : : }
304 : 0 : catch (const Exception& e)
305 : : {
306 : : SAL_WARN( "unotools.i18n", "addValue: Exception caught " << e.Message );
307 : : }
308 [ # # ]: 0 : }
309 : :
310 : :
311 : 0 : sal_Int16 CalendarWrapper::getFirstDayOfWeek() const
312 : : {
313 : : try
314 : : {
315 [ # # ]: 0 : if ( xC.is() )
316 [ # # ][ # # ]: 0 : return xC->getFirstDayOfWeek();
317 : : }
318 : 0 : catch (const Exception& e)
319 : : {
320 : : SAL_WARN( "unotools.i18n", "getFirstDayOfWeek: Exception caught " << e.Message );
321 : : }
322 [ # # ]: 0 : return 0;
323 : : }
324 : :
325 : :
326 : 1231 : sal_Int16 CalendarWrapper::getNumberOfMonthsInYear() const
327 : : {
328 : : try
329 : : {
330 [ + - ]: 1231 : if ( xC.is() )
331 [ + - ][ + - ]: 1231 : return xC->getNumberOfMonthsInYear();
332 : : }
333 : 0 : catch (const Exception& e)
334 : : {
335 : : SAL_WARN( "unotools.i18n", "getNumberOfMonthsInYear: Exception caught " << e.Message );
336 : : }
337 [ # # ]: 1231 : return 0;
338 : : }
339 : :
340 : :
341 : 956 : sal_Int16 CalendarWrapper::getNumberOfDaysInWeek() const
342 : : {
343 : : try
344 : : {
345 [ + - ]: 956 : if ( xC.is() )
346 [ + - ][ + - ]: 956 : return xC->getNumberOfDaysInWeek();
347 : : }
348 : 0 : catch (const Exception& e)
349 : : {
350 : : SAL_WARN( "unotools.i18n", "getNumberOfDaysInWeek: Exception caught " << e.Message );
351 : : }
352 [ # # ]: 956 : return 0;
353 : : }
354 : :
355 : :
356 : 2801 : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getMonths() const
357 : : {
358 : : try
359 : : {
360 [ + - ]: 2801 : if ( xC.is() )
361 [ + - ][ + - ]: 2801 : return xC->getMonths2();
362 : : }
363 : 0 : catch (const Exception& e)
364 : : {
365 : : SAL_WARN( "unotools.i18n", "getMonths: Exception caught " << e.Message );
366 : : }
367 [ # # ]: 2801 : return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
368 : : }
369 : :
370 : :
371 : 124 : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getDays() const
372 : : {
373 : : try
374 : : {
375 [ + - ]: 124 : if ( xC.is() )
376 [ + - ][ + - ]: 124 : return xC->getDays2();
377 : : }
378 : 0 : catch (const Exception& e)
379 : : {
380 : : SAL_WARN( "unotools.i18n", "getDays: Exception caught " << e.Message );
381 : : }
382 [ # # ]: 124 : return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
383 : : }
384 : :
385 : :
386 : 274 : String CalendarWrapper::getDisplayName( sal_Int16 nCalendarDisplayIndex, sal_Int16 nIdx, sal_Int16 nNameType ) const
387 : : {
388 : : try
389 : : {
390 [ + - ]: 274 : if ( xC.is() )
391 [ + - ][ + - ]: 274 : return xC->getDisplayName( nCalendarDisplayIndex, nIdx, nNameType );
[ + - ][ # # ]
392 : : }
393 : 0 : catch (const Exception& e)
394 : : {
395 : : SAL_WARN( "unotools.i18n", "getDisplayName: Exception caught " << e.Message );
396 : : }
397 : 274 : return String();
398 : : }
399 : :
400 : :
401 : : // --- XExtendedCalendar -----------------------------------------------------
402 : :
403 : 690 : String CalendarWrapper::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_Int16 nNativeNumberMode ) const
404 : : {
405 : : try
406 : : {
407 [ + - ]: 690 : if ( xC.is() )
408 [ + - ][ + - ]: 690 : return xC->getDisplayString( nCalendarDisplayCode, nNativeNumberMode );
[ + - ][ # # ]
409 : : }
410 : 0 : catch (const Exception& e)
411 : : {
412 : : SAL_WARN( "unotools.i18n", "getDisplayString: Exception caught " << e.Message );
413 : : }
414 : 690 : return String();
415 : : }
416 : :
417 : :
418 : : // --- XCalendar3 ------------------------------------------------------------
419 : :
420 : 0 : ::com::sun::star::i18n::Calendar2 CalendarWrapper::getLoadedCalendar() const
421 : : {
422 : : try
423 : : {
424 [ # # ]: 0 : if ( xC.is() )
425 [ # # ][ # # ]: 0 : return xC->getLoadedCalendar2();
426 : : }
427 : 0 : catch (const Exception& e)
428 : : {
429 : : SAL_WARN( "unotools.i18n", "getLoadedCalendar2: Exception caught " << e.Message );
430 : : }
431 [ # # ]: 0 : return ::com::sun::star::i18n::Calendar2();
432 : : }
433 : :
434 : :
435 : 124 : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getGenitiveMonths() const
436 : : {
437 : : try
438 : : {
439 [ + - ]: 124 : if ( xC.is() )
440 [ + - ][ + - ]: 124 : return xC->getGenitiveMonths2();
441 : : }
442 : 0 : catch (const Exception& e)
443 : : {
444 : : SAL_WARN( "unotools.i18n", "getGenitiveMonths: Exception caught " << e.Message );
445 : : }
446 [ # # ]: 124 : return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
447 : : }
448 : :
449 : :
450 : 124 : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > CalendarWrapper::getPartitiveMonths() const
451 : : {
452 : : try
453 : : {
454 [ + - ]: 124 : if ( xC.is() )
455 [ + - ][ + - ]: 124 : return xC->getPartitiveMonths2();
456 : : }
457 : 0 : catch (const Exception& e)
458 : : {
459 : : SAL_WARN( "unotools.i18n", "getPartitiveMonths: Exception caught " << e.Message );
460 : : }
461 [ # # ]: 124 : return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > (0);
462 : : }
463 : :
464 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|