Diffstat (limited to 'microkde/kdecore/klocale.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | microkde/kdecore/klocale.cpp | 881 |
1 files changed, 881 insertions, 0 deletions
diff --git a/microkde/kdecore/klocale.cpp b/microkde/kdecore/klocale.cpp new file mode 100644 index 0000000..d77e251 --- a/dev/null +++ b/microkde/kdecore/klocale.cpp | |||
@@ -0,0 +1,881 @@ | |||
1 | #include <qregexp.h> | ||
2 | #include <qapplication.h> | ||
3 | |||
4 | #include "kdebug.h" | ||
5 | #include "kcalendarsystemgregorian.h" | ||
6 | |||
7 | #include "klocale.h" | ||
8 | |||
9 | |||
10 | QDict<QString> *mLocaleDict = 0; | ||
11 | void setLocaleDict( QDict<QString> * dict ) | ||
12 | { | ||
13 | mLocaleDict = dict; | ||
14 | |||
15 | } | ||
16 | QString i18n(const char *text) | ||
17 | { | ||
18 | if ( ! mLocaleDict ) | ||
19 | return QString( text ); | ||
20 | else { | ||
21 | QString* ret = mLocaleDict->find(QString(text)) ; | ||
22 | if ( ret == 0 ) { | ||
23 | return QString( text ); | ||
24 | } | ||
25 | else { | ||
26 | if ( (*ret).isEmpty() ) | ||
27 | return QString( text ); | ||
28 | else | ||
29 | return (*ret); | ||
30 | } | ||
31 | } | ||
32 | |||
33 | } | ||
34 | |||
35 | QString i18n(const char *,const char *text) | ||
36 | { | ||
37 | return i18n( text ); | ||
38 | } | ||
39 | |||
40 | QString i18n(const char *text1, const char *textn, int num) | ||
41 | { | ||
42 | if ( num == 1 ) return i18n( text1 ); | ||
43 | else { | ||
44 | QString text = i18n( textn ); | ||
45 | int pos = text.find( "%n" ); | ||
46 | if ( pos >= 0 ) text.replace( pos, 2, QString::number( num ) ); | ||
47 | return text; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | inline void put_it_in( QChar *buffer, uint& index, const QString &s ) | ||
52 | { | ||
53 | for ( uint l = 0; l < s.length(); l++ ) | ||
54 | buffer[index++] = s.at( l ); | ||
55 | } | ||
56 | |||
57 | inline void put_it_in( QChar *buffer, uint& index, int number ) | ||
58 | { | ||
59 | buffer[index++] = number / 10 + '0'; | ||
60 | buffer[index++] = number % 10 + '0'; | ||
61 | } | ||
62 | |||
63 | static int readInt(const QString &str, uint &pos) | ||
64 | { | ||
65 | if (!str.at(pos).isDigit()) return -1; | ||
66 | int result = 0; | ||
67 | for (; str.length() > pos && str.at(pos).isDigit(); pos++) | ||
68 | { | ||
69 | result *= 10; | ||
70 | result += str.at(pos).digitValue(); | ||
71 | } | ||
72 | |||
73 | return result; | ||
74 | } | ||
75 | |||
76 | KLocale::KLocale() : mCalendarSystem( 0 ) | ||
77 | { | ||
78 | |||
79 | m_decimalSymbol = "."; | ||
80 | m_positiveSign = ""; | ||
81 | m_negativeSign = "-"; | ||
82 | m_thousandsSeparator = ","; | ||
83 | |||
84 | |||
85 | |||
86 | |||
87 | mWeekStartsMonday = true; | ||
88 | mHourF24Format = true; | ||
89 | mIntDateFormat = 0; | ||
90 | mLanguage = 0; | ||
91 | mDateFormat = "%a %Y %b %d"; | ||
92 | mDateFormatShort = "%Y-%m-%d"; | ||
93 | mTimeZoneList << i18n ("-11:00 US/Samoa") | ||
94 | << i18n ("-10:00 US/Hawaii") | ||
95 | << i18n ("-09:00 US/Alaska") | ||
96 | << i18n ("-08:00 US/Pacific") | ||
97 | << i18n ("-07:00 US/Mountain") | ||
98 | << i18n ("-06:00 US/Central") | ||
99 | << i18n ("-05:00 US/Eastern") | ||
100 | << i18n ("-04:00 Brazil/West") | ||
101 | << i18n ("-03:00 Brazil/East") | ||
102 | << i18n ("-02:00 Brazil/DeNoronha") | ||
103 | << i18n ("-01:00 Atlantic/Azores") | ||
104 | << i18n (" 00:00 Europe/London(UTC)") | ||
105 | << i18n ("+01:00 Europe/Oslo(CET)") | ||
106 | << i18n ("+02:00 Europe/Helsinki") | ||
107 | << i18n ("+03:00 Europe/Moscow") | ||
108 | << i18n ("+04:00 Indian/Mauritius") | ||
109 | << i18n ("+05:00 Indian/Maldives") | ||
110 | << i18n ("+06:00 Indian/Chagos") | ||
111 | << i18n ("+07:00 Asia/Bangkok") | ||
112 | << i18n ("+08:00 Asia/Hongkong") | ||
113 | << i18n ("+09:00 Asia/Tokyo") | ||
114 | << i18n ("+10:00 Asia/Vladivostok") | ||
115 | << i18n ("+11:00 Asia/Magadan") | ||
116 | << i18n ("+12:00 Asia/Kamchatka") | ||
117 | // << i18n (" xx:xx User defined offset") | ||
118 | << i18n (" Local Time"); | ||
119 | mSouthDaylight = false; | ||
120 | mTimeZoneOffset = 0; | ||
121 | daylightEnabled = false; | ||
122 | } | ||
123 | |||
124 | void KLocale::setDateFormat( QString s ) | ||
125 | { | ||
126 | mDateFormat = s; | ||
127 | } | ||
128 | |||
129 | void KLocale::setDateFormatShort( QString s ) | ||
130 | { | ||
131 | mDateFormatShort = s; | ||
132 | } | ||
133 | |||
134 | void KLocale::setHore24Format ( bool b ) | ||
135 | { | ||
136 | mHourF24Format = b; | ||
137 | } | ||
138 | void KLocale::setWeekStartMonday( bool b ) | ||
139 | { | ||
140 | mWeekStartsMonday = b; | ||
141 | } | ||
142 | int KLocale::getIntDateFormat( ) | ||
143 | { | ||
144 | return mIntDateFormat ; | ||
145 | |||
146 | } | ||
147 | void KLocale::setIntDateFormat( int i ) | ||
148 | { | ||
149 | mIntDateFormat = i; | ||
150 | } | ||
151 | void KLocale::setLanguage( int i ) | ||
152 | { | ||
153 | mLanguage = i; | ||
154 | } | ||
155 | QString KLocale::translate( const char *index ) const | ||
156 | { | ||
157 | return i18n( index ); | ||
158 | } | ||
159 | |||
160 | QString KLocale::translate( const char *, const char *fallback) const | ||
161 | { | ||
162 | return i18n( fallback ); | ||
163 | } | ||
164 | |||
165 | QString KLocale::formatTime(const QTime &pTime, bool includeSecs) const | ||
166 | { | ||
167 | const QString rst = timeFormat(); | ||
168 | |||
169 | // only "pm/am" here can grow, the rest shrinks, but | ||
170 | // I'm rather safe than sorry | ||
171 | QChar *buffer = new QChar[rst.length() * 3 / 2 + 30]; | ||
172 | |||
173 | uint index = 0; | ||
174 | bool escape = false; | ||
175 | int number = 0; | ||
176 | |||
177 | for ( uint format_index = 0; format_index < rst.length(); format_index++ ) | ||
178 | { | ||
179 | if ( !escape ) | ||
180 | { | ||
181 | if ( rst.at( format_index ).unicode() == '%' ) | ||
182 | escape = true; | ||
183 | else | ||
184 | buffer[index++] = rst.at( format_index ); | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | switch ( rst.at( format_index ).unicode() ) | ||
189 | { | ||
190 | case '%': | ||
191 | buffer[index++] = '%'; | ||
192 | break; | ||
193 | case 'H': | ||
194 | put_it_in( buffer, index, pTime.hour() ); | ||
195 | break; | ||
196 | case 'I': | ||
197 | put_it_in( buffer, index, ( pTime.hour() + 11) % 12 + 1 ); | ||
198 | break; | ||
199 | case 'M': | ||
200 | put_it_in( buffer, index, pTime.minute() ); | ||
201 | break; | ||
202 | case 'S': | ||
203 | if (includeSecs) | ||
204 | put_it_in( buffer, index, pTime.second() ); | ||
205 | else | ||
206 | { | ||
207 | // we remove the seperator sign before the seconds and | ||
208 | // assume that works everywhere | ||
209 | --index; | ||
210 | break; | ||
211 | } | ||
212 | break; | ||
213 | case 'k': | ||
214 | number = pTime.hour(); | ||
215 | case 'l': | ||
216 | // to share the code | ||
217 | if ( rst.at( format_index ).unicode() == 'l' ) | ||
218 | number = (pTime.hour() + 11) % 12 + 1; | ||
219 | if ( number / 10 ) | ||
220 | buffer[index++] = number / 10 + '0'; | ||
221 | buffer[index++] = number % 10 + '0'; | ||
222 | break; | ||
223 | case 'p': | ||
224 | { | ||
225 | QString s; | ||
226 | if ( pTime.hour() >= 12 ) | ||
227 | put_it_in( buffer, index, i18n("pm") ); | ||
228 | else | ||
229 | put_it_in( buffer, index, i18n("am") ); | ||
230 | break; | ||
231 | } | ||
232 | default: | ||
233 | buffer[index++] = rst.at( format_index ); | ||
234 | break; | ||
235 | } | ||
236 | escape = false; | ||
237 | } | ||
238 | } | ||
239 | QString ret( buffer, index ); | ||
240 | delete [] buffer; | ||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | QString KLocale::formatDate(const QDate &pDate, bool shortFormat) const | ||
245 | { | ||
246 | const QString rst = shortFormat?dateFormatShort():dateFormat(); | ||
247 | |||
248 | // I'm rather safe than sorry | ||
249 | QChar *buffer = new QChar[rst.length() * 3 / 2 + 50]; | ||
250 | |||
251 | unsigned int index = 0; | ||
252 | bool escape = false; | ||
253 | int number = 0; | ||
254 | |||
255 | for ( uint format_index = 0; format_index < rst.length(); ++format_index ) | ||
256 | { | ||
257 | if ( !escape ) | ||
258 | { | ||
259 | if ( rst.at( format_index ).unicode() == '%' ) | ||
260 | escape = true; | ||
261 | else | ||
262 | buffer[index++] = rst.at( format_index ); | ||
263 | } | ||
264 | else | ||
265 | { | ||
266 | switch ( rst.at( format_index ).unicode() ) | ||
267 | { | ||
268 | case '%': | ||
269 | buffer[index++] = '%'; | ||
270 | break; | ||
271 | case 'Y': | ||
272 | put_it_in( buffer, index, pDate.year() / 100 ); | ||
273 | case 'y': | ||
274 | put_it_in( buffer, index, pDate.year() % 100 ); | ||
275 | break; | ||
276 | case 'n': | ||
277 | number = pDate.month(); | ||
278 | case 'e': | ||
279 | // to share the code | ||
280 | if ( rst.at( format_index ).unicode() == 'e' ) | ||
281 | number = pDate.day(); | ||
282 | if ( number / 10 ) | ||
283 | buffer[index++] = number / 10 + '0'; | ||
284 | buffer[index++] = number % 10 + '0'; | ||
285 | break; | ||
286 | case 'm': | ||
287 | put_it_in( buffer, index, pDate.month() ); | ||
288 | break; | ||
289 | case 'b': | ||
290 | put_it_in( buffer, index, monthName(pDate.month(), true) ); | ||
291 | break; | ||
292 | case 'B': | ||
293 | put_it_in( buffer, index, monthName(pDate.month(), false) ); | ||
294 | break; | ||
295 | case 'd': | ||
296 | put_it_in( buffer, index, pDate.day() ); | ||
297 | break; | ||
298 | case 'a': | ||
299 | put_it_in( buffer, index, weekDayName(pDate.dayOfWeek(), true) ); | ||
300 | break; | ||
301 | case 'A': | ||
302 | put_it_in( buffer, index, weekDayName(pDate.dayOfWeek(), false) ); | ||
303 | break; | ||
304 | default: | ||
305 | buffer[index++] = rst.at( format_index ); | ||
306 | break; | ||
307 | } | ||
308 | escape = false; | ||
309 | } | ||
310 | } | ||
311 | QString ret( buffer, index ); | ||
312 | delete [] buffer; | ||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | QString KLocale::formatDateTime(const QDateTime &pDateTime, | ||
317 | bool shortFormat, | ||
318 | bool includeSeconds) const | ||
319 | { | ||
320 | return QString( "%1 %2") | ||
321 | .arg( formatDate( pDateTime.date(), shortFormat ) ) | ||
322 | .arg( formatTime( pDateTime.time(), includeSeconds ) ); | ||
323 | } | ||
324 | |||
325 | QString KLocale::formatDateTime(const QDateTime &pDateTime) const | ||
326 | { | ||
327 | return formatDateTime(pDateTime, true); | ||
328 | } | ||
329 | |||
330 | QDate KLocale::readDate(const QString &intstr, bool* ok) const | ||
331 | { | ||
332 | QDate date; | ||
333 | date = readDate(intstr, true, ok); | ||
334 | if (date.isValid()) return date; | ||
335 | return readDate(intstr, false, ok); | ||
336 | } | ||
337 | |||
338 | QDate KLocale::readDate(const QString &intstr, bool shortFormat, bool* ok) const | ||
339 | { | ||
340 | QString fmt = (shortFormat ? dateFormatShort() : dateFormat()).simplifyWhiteSpace(); | ||
341 | return readDate( intstr, fmt, ok ); | ||
342 | } | ||
343 | |||
344 | QDate KLocale::readDate(const QString &intstr, const QString &fmt, bool* ok) const | ||
345 | { | ||
346 | //kdDebug(173) << "KLocale::readDate intstr=" << intstr << " fmt=" << fmt << endl; | ||
347 | QString str = intstr.simplifyWhiteSpace().lower(); | ||
348 | int day = -1, month = -1; | ||
349 | // allow the year to be omitted if not in the format | ||
350 | int year = QDate::currentDate().year(); | ||
351 | uint strpos = 0; | ||
352 | uint fmtpos = 0; | ||
353 | |||
354 | while (fmt.length() > fmtpos || str.length() > strpos) | ||
355 | { | ||
356 | if ( !(fmt.length() > fmtpos && str.length() > strpos) ) | ||
357 | goto error; | ||
358 | |||
359 | QChar c = fmt.at(fmtpos++); | ||
360 | |||
361 | if (c != '%') { | ||
362 | if (c.isSpace()) | ||
363 | strpos++; | ||
364 | else if (c != str.at(strpos++)) | ||
365 | goto error; | ||
366 | continue; | ||
367 | } | ||
368 | |||
369 | // remove space at the begining | ||
370 | if (str.length() > strpos && str.at(strpos).isSpace()) | ||
371 | strpos++; | ||
372 | |||
373 | c = fmt.at(fmtpos++); | ||
374 | switch (c) | ||
375 | { | ||
376 | case 'a': | ||
377 | case 'A': | ||
378 | // this will just be ignored | ||
379 | { // Cristian Tache: porting to Win: Block added because of "j" redefinition | ||
380 | for (int j = 1; j < 8; j++) { | ||
381 | QString s = weekDayName(j, c == 'a').lower(); | ||
382 | int len = s.length(); | ||
383 | if (str.mid(strpos, len) == s) | ||
384 | strpos += len; | ||
385 | } | ||
386 | break; | ||
387 | } | ||
388 | case 'b': | ||
389 | case 'B': | ||
390 | { // Cristian Tache: porting to Win: Block added because of "j" redefinition | ||
391 | for (int j = 1; j < 13; j++) { | ||
392 | QString s = monthName(j, c == 'b').lower(); | ||
393 | int len = s.length(); | ||
394 | if (str.mid(strpos, len) == s) { | ||
395 | month = j; | ||
396 | strpos += len; | ||
397 | } | ||
398 | } | ||
399 | break; | ||
400 | } | ||
401 | case 'd': | ||
402 | case 'e': | ||
403 | day = readInt(str, strpos); | ||
404 | if (day < 1 || day > 31) | ||
405 | goto error; | ||
406 | |||
407 | break; | ||
408 | |||
409 | case 'n': | ||
410 | case 'm': | ||
411 | month = readInt(str, strpos); | ||
412 | if (month < 1 || month > 12) | ||
413 | goto error; | ||
414 | |||
415 | break; | ||
416 | |||
417 | case 'Y': | ||
418 | case 'y': | ||
419 | year = readInt(str, strpos); | ||
420 | if (year < 0) | ||
421 | goto error; | ||
422 | // Qt treats a year in the range 0-100 as 1900-1999. | ||
423 | // It is nicer for the user if we treat 0-68 as 2000-2068 | ||
424 | if (year < 69) | ||
425 | year += 2000; | ||
426 | else if (c == 'y') | ||
427 | year += 1900; | ||
428 | |||
429 | break; | ||
430 | } | ||
431 | } | ||
432 | //kdDebug(173) << "KLocale::readDate day=" << day << " month=" << month << " year=" << year << endl; | ||
433 | if ( year != -1 && month != -1 && day != -1 ) | ||
434 | { | ||
435 | if (ok) *ok = true; | ||
436 | return QDate(year, month, day); | ||
437 | } | ||
438 | error: | ||
439 | if (ok) *ok = false; | ||
440 | return QDate(); // invalid date | ||
441 | } | ||
442 | |||
443 | QTime KLocale::readTime(const QString &intstr, bool *ok) const | ||
444 | { | ||
445 | QTime _time; | ||
446 | _time = readTime(intstr, true, ok); | ||
447 | if (_time.isValid()) return _time; | ||
448 | return readTime(intstr, false, ok); | ||
449 | } | ||
450 | |||
451 | QTime KLocale::readTime(const QString &intstr, bool seconds, bool *ok) const | ||
452 | { | ||
453 | QString str = intstr.simplifyWhiteSpace().lower(); | ||
454 | QString Format = timeFormat().simplifyWhiteSpace(); | ||
455 | if (!seconds) | ||
456 | Format.replace(QRegExp(QString::fromLatin1(".%S")), QString::null); | ||
457 | |||
458 | int hour = -1, minute = -1, second = seconds ? -1 : 0; // don't require seconds | ||
459 | bool g_12h = false; | ||
460 | bool pm = false; | ||
461 | uint strpos = 0; | ||
462 | uint Formatpos = 0; | ||
463 | |||
464 | while (Format.length() > Formatpos || str.length() > strpos) | ||
465 | { | ||
466 | if ( !(Format.length() > Formatpos && str.length() > strpos) ) goto error; | ||
467 | |||
468 | QChar c = Format.at(Formatpos++); | ||
469 | |||
470 | if (c != '%') | ||
471 | { | ||
472 | if (c.isSpace()) | ||
473 | strpos++; | ||
474 | else if (c != str.at(strpos++)) | ||
475 | goto error; | ||
476 | continue; | ||
477 | } | ||
478 | |||
479 | // remove space at the begining | ||
480 | if (str.length() > strpos && str.at(strpos).isSpace()) | ||
481 | strpos++; | ||
482 | |||
483 | c = Format.at(Formatpos++); | ||
484 | switch (c) | ||
485 | { | ||
486 | case 'p': | ||
487 | { | ||
488 | QString s; | ||
489 | s = i18n("pm").lower(); | ||
490 | int len = s.length(); | ||
491 | if (str.mid(strpos, len) == s) | ||
492 | { | ||
493 | pm = true; | ||
494 | strpos += len; | ||
495 | } | ||
496 | else | ||
497 | { | ||
498 | s = i18n("am").lower(); | ||
499 | len = s.length(); | ||
500 | if (str.mid(strpos, len) == s) { | ||
501 | pm = false; | ||
502 | strpos += len; | ||
503 | } | ||
504 | else | ||
505 | goto error; | ||
506 | } | ||
507 | } | ||
508 | break; | ||
509 | |||
510 | case 'k': | ||
511 | case 'H': | ||
512 | g_12h = false; | ||
513 | hour = readInt(str, strpos); | ||
514 | if (hour < 0 || hour > 23) | ||
515 | goto error; | ||
516 | |||
517 | break; | ||
518 | |||
519 | case 'l': | ||
520 | case 'I': | ||
521 | g_12h = true; | ||
522 | hour = readInt(str, strpos); | ||
523 | if (hour < 1 || hour > 12) | ||
524 | goto error; | ||
525 | |||
526 | break; | ||
527 | |||
528 | case 'M': | ||
529 | minute = readInt(str, strpos); | ||
530 | if (minute < 0 || minute > 59) | ||
531 | goto error; | ||
532 | |||
533 | break; | ||
534 | |||
535 | case 'S': | ||
536 | second = readInt(str, strpos); | ||
537 | if (second < 0 || second > 59) | ||
538 | goto error; | ||
539 | |||
540 | break; | ||
541 | } | ||
542 | } | ||
543 | if (g_12h) | ||
544 | { | ||
545 | hour %= 12; | ||
546 | if (pm) hour += 12; | ||
547 | } | ||
548 | |||
549 | if (ok) *ok = true; | ||
550 | return QTime(hour, minute, second); | ||
551 | |||
552 | error: | ||
553 | if (ok) *ok = false; | ||
554 | return QTime(-1, -1, -1); // return invalid date if it didn't work | ||
555 | // This will be removed in the near future, since it gives a warning on stderr. | ||
556 | // The presence of the bool* (since KDE-3.0) removes the need for an invalid QTime. | ||
557 | } | ||
558 | |||
559 | bool KLocale::use12Clock() const | ||
560 | { | ||
561 | return !mHourF24Format ;; | ||
562 | } | ||
563 | |||
564 | bool KLocale::weekStartsMonday() const | ||
565 | { | ||
566 | return mWeekStartsMonday; | ||
567 | } | ||
568 | |||
569 | int KLocale::weekStartDay() const | ||
570 | { | ||
571 | if ( mWeekStartsMonday ) | ||
572 | return 1; | ||
573 | return 7; | ||
574 | } | ||
575 | |||
576 | QString KLocale::weekDayName(int i,bool shortName) const | ||
577 | { | ||
578 | if ( shortName ) | ||
579 | switch ( i ) | ||
580 | { | ||
581 | case 1: return i18n("Monday", "Mon"); | ||
582 | case 2: return i18n("Tuesday", "Tue"); | ||
583 | case 3: return i18n("Wednesday", "Wed"); | ||
584 | case 4: return i18n("Thursday", "Thu"); | ||
585 | case 5: return i18n("Friday", "Fri"); | ||
586 | case 6: return i18n("Saturday", "Sat"); | ||
587 | case 7: return i18n("Sunday", "Sun"); | ||
588 | } | ||
589 | else | ||
590 | switch ( i ) | ||
591 | { | ||
592 | case 1: return i18n("Monday"); | ||
593 | case 2: return i18n("Tuesday"); | ||
594 | case 3: return i18n("Wednesday"); | ||
595 | case 4: return i18n("Thursday"); | ||
596 | case 5: return i18n("Friday"); | ||
597 | case 6: return i18n("Saturday"); | ||
598 | case 7: return i18n("Sunday"); | ||
599 | } | ||
600 | |||
601 | return QString::null; | ||
602 | } | ||
603 | |||
604 | QString KLocale::monthName(int i,bool shortName) const | ||
605 | { | ||
606 | if ( shortName ) | ||
607 | switch ( i ) | ||
608 | { | ||
609 | case 1: return i18n("January", "Jan"); | ||
610 | case 2: return i18n("February", "Feb"); | ||
611 | case 3: return i18n("March", "Mar"); | ||
612 | case 4: return i18n("April", "Apr"); | ||
613 | case 5: return i18n("May short", "May"); | ||
614 | case 6: return i18n("June", "Jun"); | ||
615 | case 7: return i18n("July", "Jul"); | ||
616 | case 8: return i18n("August", "Aug"); | ||
617 | case 9: return i18n("September", "Sep"); | ||
618 | case 10: return i18n("October", "Oct"); | ||
619 | case 11: return i18n("November", "Nov"); | ||
620 | case 12: return i18n("December", "Dec"); | ||
621 | } | ||
622 | else | ||
623 | switch (i) | ||
624 | { | ||
625 | case 1: return i18n("January"); | ||
626 | case 2: return i18n("February"); | ||
627 | case 3: return i18n("March"); | ||
628 | case 4: return i18n("April"); | ||
629 | case 5: return i18n("May long", "May"); | ||
630 | case 6: return i18n("June"); | ||
631 | case 7: return i18n("July"); | ||
632 | case 8: return i18n("August"); | ||
633 | case 9: return i18n("September"); | ||
634 | case 10: return i18n("October"); | ||
635 | case 11: return i18n("November"); | ||
636 | case 12: return i18n("December"); | ||
637 | } | ||
638 | |||
639 | return QString::null; | ||
640 | } | ||
641 | |||
642 | QString KLocale::country() const | ||
643 | { | ||
644 | return QString::null; | ||
645 | } | ||
646 | |||
647 | QString KLocale::dateFormat() const | ||
648 | { | ||
649 | if ( QApplication::desktop()->width() < 480 ) { | ||
650 | if ( mIntDateFormat == 0 ) | ||
651 | return "%a %d %b %Y"; | ||
652 | else if ( mIntDateFormat == 1 ) | ||
653 | return "%a %b %d %Y"; | ||
654 | else if ( mIntDateFormat == 2 ) | ||
655 | return "%a %Y %b %d"; | ||
656 | } else { | ||
657 | |||
658 | if ( mIntDateFormat == 0 ) | ||
659 | return "%A %d %B %Y"; | ||
660 | else if ( mIntDateFormat == 1 ) | ||
661 | return "%A %B %d %Y"; | ||
662 | else if ( mIntDateFormat == 2 ) | ||
663 | return "%A %Y %B %d"; | ||
664 | } | ||
665 | return mDateFormat ; | ||
666 | } | ||
667 | |||
668 | QString KLocale::dateFormatShort() const | ||
669 | { | ||
670 | |||
671 | if ( mIntDateFormat == 0 ) | ||
672 | return "%d.%m.%Y"; | ||
673 | else if ( mIntDateFormat == 1 ) | ||
674 | return "%m.%d.%Y"; | ||
675 | else if ( mIntDateFormat == 2 ) | ||
676 | return "%Y-%m-%d"; | ||
677 | return mDateFormatShort ; | ||
678 | |||
679 | } | ||
680 | |||
681 | |||
682 | QString KLocale::timeFormat() const | ||
683 | { | ||
684 | if ( mHourF24Format) | ||
685 | return "%H:%M:%S"; | ||
686 | return "%I:%M:%S%p"; | ||
687 | } | ||
688 | |||
689 | void KLocale::insertCatalogue ( const QString & ) | ||
690 | { | ||
691 | } | ||
692 | |||
693 | KCalendarSystem *KLocale::calendar() | ||
694 | { | ||
695 | if ( !mCalendarSystem ) { | ||
696 | mCalendarSystem = new KCalendarSystemGregorian; | ||
697 | } | ||
698 | |||
699 | return mCalendarSystem; | ||
700 | } | ||
701 | |||
702 | int KLocale::timezoneOffset( QString timeZone ) | ||
703 | { | ||
704 | int ret = 1001; | ||
705 | int index = mTimeZoneList.findIndex( timeZone ); | ||
706 | if ( index < 24 ) | ||
707 | ret = ( index-11 ) * 60 ; | ||
708 | return ret; | ||
709 | } | ||
710 | |||
711 | QStringList KLocale::timeZoneList() const | ||
712 | { | ||
713 | return mTimeZoneList; | ||
714 | } | ||
715 | void KLocale::setTimezone( const QString &timeZone ) | ||
716 | { | ||
717 | mTimeZoneOffset = timezoneOffset( timeZone ); | ||
718 | } | ||
719 | |||
720 | void KLocale::setDaylightSaving( bool b, int start , int end ) | ||
721 | { | ||
722 | daylightEnabled = b; | ||
723 | daylightStart = start; | ||
724 | daylightEnd = end; | ||
725 | mSouthDaylight = (end < start); | ||
726 | // qDebug("klocale daylight %d %d %d ", b, start , end ); | ||
727 | } | ||
728 | |||
729 | int KLocale::localTimeOffset( const QDateTime &dt ) | ||
730 | { | ||
731 | bool addDaylight = false; | ||
732 | if ( daylightEnabled ) { | ||
733 | int d_end, d_start; | ||
734 | int dayofyear = dt.date().dayOfYear(); | ||
735 | int year = dt.date().year(); | ||
736 | int add = 0; | ||
737 | if ( QDate::leapYear(year) ) | ||
738 | add = 1; | ||
739 | QDate date ( year,1,1 ); | ||
740 | if ( daylightEnd > 59 ) | ||
741 | d_end = daylightEnd +add; | ||
742 | else | ||
743 | d_end = daylightEnd; | ||
744 | if ( daylightStart > 59 ) | ||
745 | d_start = daylightStart +add; | ||
746 | else | ||
747 | d_start = daylightStart; | ||
748 | QDate s_date = date.addDays( d_start -1 ); | ||
749 | QDate e_date = date.addDays( d_end -1 ); | ||
750 | int dof = s_date.dayOfWeek(); | ||
751 | if ( dof < 7 ) | ||
752 | s_date = s_date.addDays( -dof ); | ||
753 | dof = e_date.dayOfWeek(); | ||
754 | if ( dof < 7 ) | ||
755 | e_date = e_date.addDays( -dof ); | ||
756 | QTime startTime ( 3,0,0 ); | ||
757 | QDateTime startDt( s_date, startTime ); | ||
758 | QDateTime endDt( e_date, startTime ); | ||
759 | //qDebug("dayligt saving start %s end %s ",startDt.toString().latin1(),endDt.toString().latin1( )); | ||
760 | if ( mSouthDaylight ) { | ||
761 | if ( ! ( endDt < dt && dt < startDt) ) | ||
762 | addDaylight = true; | ||
763 | } else { | ||
764 | if ( startDt < dt && dt < endDt ) | ||
765 | addDaylight = true; | ||
766 | |||
767 | |||
768 | } | ||
769 | } | ||
770 | int addMin = 0; | ||
771 | if ( addDaylight ) | ||
772 | addMin = 60; | ||
773 | return mTimeZoneOffset + addMin; | ||
774 | } | ||
775 | // ****************************************************************** | ||
776 | // added LR | ||
777 | QString KLocale::formatNumber(double num, int precision) const | ||
778 | { | ||
779 | bool neg = num < 0; | ||
780 | if (precision == -1) precision = 2; | ||
781 | QString res = QString::number(neg?-num:num, 'f', precision); | ||
782 | int pos = res.find('.'); | ||
783 | if (pos == -1) pos = res.length(); | ||
784 | else res.replace(pos, 1, decimalSymbol()); | ||
785 | |||
786 | while (0 < (pos -= 3)) | ||
787 | res.insert(pos, thousandsSeparator()); // thousand sep | ||
788 | |||
789 | // How can we know where we should put the sign? | ||
790 | res.prepend(neg?negativeSign():positiveSign()); | ||
791 | |||
792 | return res; | ||
793 | } | ||
794 | QString KLocale::formatNumber(const QString &numStr) const | ||
795 | { | ||
796 | return formatNumber(numStr.toDouble()); | ||
797 | } | ||
798 | double KLocale::readNumber(const QString &_str, bool * ok) const | ||
799 | { | ||
800 | QString str = _str.stripWhiteSpace(); | ||
801 | bool neg = str.find(negativeSign()) == 0; | ||
802 | if (neg) | ||
803 | str.remove( 0, negativeSign().length() ); | ||
804 | |||
805 | /* will hold the scientific notation portion of the number. | ||
806 | Example, with 2.34E+23, exponentialPart == "E+23" | ||
807 | */ | ||
808 | QString exponentialPart; | ||
809 | int EPos; | ||
810 | |||
811 | EPos = str.find('E', 0, false); | ||
812 | |||
813 | if (EPos != -1) | ||
814 | { | ||
815 | exponentialPart = str.mid(EPos); | ||
816 | str = str.left(EPos); | ||
817 | } | ||
818 | |||
819 | int pos = str.find(decimalSymbol()); | ||
820 | QString major; | ||
821 | QString minor; | ||
822 | if ( pos == -1 ) | ||
823 | major = str; | ||
824 | else | ||
825 | { | ||
826 | major = str.left(pos); | ||
827 | minor = str.mid(pos + decimalSymbol().length()); | ||
828 | } | ||
829 | |||
830 | // Remove thousand separators | ||
831 | int thlen = thousandsSeparator().length(); | ||
832 | int lastpos = 0; | ||
833 | while ( ( pos = major.find( thousandsSeparator() ) ) > 0 ) | ||
834 | { | ||
835 | // e.g. 12,,345,,678,,922 Acceptable positions (from the end) are 5, 10, 15... i.e. (3+thlen)*N | ||
836 | int fromEnd = major.length() - pos; | ||
837 | if ( fromEnd % (3+thlen) != 0 // Needs to be a multiple, otherwise it's an error | ||
838 | || pos - lastpos > 3 // More than 3 digits between two separators -> error | ||
839 | || pos == 0 // Can't start with a separator | ||
840 | || (lastpos>0 && pos-lastpos!=3)) // Must have exactly 3 digits between two separators | ||
841 | { | ||
842 | if (ok) *ok = false; | ||
843 | return 0.0; | ||
844 | } | ||
845 | |||
846 | lastpos = pos; | ||
847 | major.remove( pos, thlen ); | ||
848 | } | ||
849 | if (lastpos>0 && major.length()-lastpos!=3) // Must have exactly 3 digits after the last separator | ||
850 | { | ||
851 | if (ok) *ok = false; | ||
852 | return 0.0; | ||
853 | } | ||
854 | |||
855 | QString tot; | ||
856 | if (neg) tot = '-'; | ||
857 | |||
858 | tot += major + '.' + minor + exponentialPart; | ||
859 | |||
860 | return tot.toDouble(ok); | ||
861 | } | ||
862 | QString KLocale::decimalSymbol() const | ||
863 | { | ||
864 | |||
865 | return m_decimalSymbol; | ||
866 | } | ||
867 | |||
868 | QString KLocale::thousandsSeparator() const | ||
869 | { | ||
870 | |||
871 | return m_thousandsSeparator; | ||
872 | } | ||
873 | QString KLocale::positiveSign() const | ||
874 | { | ||
875 | return m_positiveSign; | ||
876 | } | ||
877 | |||
878 | QString KLocale::negativeSign() const | ||
879 | { | ||
880 | return m_negativeSign; | ||
881 | } | ||