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