Diffstat (limited to 'microkde/kdecore/klocale_new.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | microkde/kdecore/klocale_new.cpp | 2441 |
1 files changed, 2441 insertions, 0 deletions
diff --git a/microkde/kdecore/klocale_new.cpp b/microkde/kdecore/klocale_new.cpp new file mode 100644 index 0000000..223b6c4 --- a/dev/null +++ b/microkde/kdecore/klocale_new.cpp | |||
@@ -0,0 +1,2441 @@ | |||
1 | // -*- c-basic-offset: 2 -*- | ||
2 | /* This file is part of the KDE libraries | ||
3 | Copyright (c) 1997,2001 Stephan Kulow <coolo@kde.org> | ||
4 | Copyright (c) 1999 Preston Brown <pbrown@kde.org> | ||
5 | Copyright (c) 1999-2002 Hans Petter Bieker <bieker@kde.org> | ||
6 | Copyright (c) 2002 Lukas Tinkl <lukas@kde.org> | ||
7 | |||
8 | This library is free software; you can redistribute it and/or | ||
9 | modify it under the terms of the GNU Library General Public | ||
10 | License as published by the Free Software Foundation; either | ||
11 | version 2 of the License, or (at your option) any later version. | ||
12 | |||
13 | This library is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | Library General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU Library General Public License | ||
19 | along with this library; see the file COPYING.LIB. If not, write to | ||
20 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
21 | Boston, MA 02111-1307, USA. | ||
22 | */ | ||
23 | |||
24 | //US#include <config.h> | ||
25 | |||
26 | #include <stdlib.h> // getenv | ||
27 | #include <assert.h> | ||
28 | |||
29 | #include <qtextcodec.h> | ||
30 | #include <qfile.h> | ||
31 | #include <qdict.h> | ||
32 | #include <qprinter.h> | ||
33 | #include <qdatetime.h> | ||
34 | #include <qfileinfo.h> | ||
35 | #include <qregexp.h> | ||
36 | |||
37 | #include "kcatalogue.h" | ||
38 | #include "kglobal.h" | ||
39 | #include "kstandarddirs.h" | ||
40 | #include "ksimpleconfig.h" | ||
41 | //US #include "kinstance.h" | ||
42 | #include "kconfig.h" | ||
43 | #include "kconfigbase.h" | ||
44 | #include "kdebug.h" | ||
45 | #include "kcalendarsystem.h" | ||
46 | |||
47 | //US we use no factory. Simply use the gregorian calendar | ||
48 | //US #include "kcalendarsystemfactory.h" | ||
49 | #include "kcalendarsystemgregorian.h" | ||
50 | |||
51 | #include "klocale.h" | ||
52 | |||
53 | static const char * const SYSTEM_MESSAGES = "kdelibs"; | ||
54 | |||
55 | static const char *maincatalogue = 0; | ||
56 | |||
57 | QDict<char> *mLocaleDict = 0; | ||
58 | |||
59 | void setLocaleDict( QDict<char> * dict ) | ||
60 | { | ||
61 | mLocaleDict = dict; | ||
62 | |||
63 | } | ||
64 | |||
65 | class KLocalePrivate | ||
66 | { | ||
67 | public: | ||
68 | int weekStartDay; | ||
69 | int plural_form; | ||
70 | bool nounDeclension; | ||
71 | bool dateMonthNamePossessive; | ||
72 | QStringList languageList; | ||
73 | QValueList<KCatalogue> catalogues; | ||
74 | QString encoding; | ||
75 | QTextCodec * codecForEncoding; | ||
76 | KConfig * config; | ||
77 | bool formatInited; | ||
78 | int /*QPrinter::PageSize*/ pageSize; | ||
79 | KLocale::MeasureSystem measureSystem; | ||
80 | QStringList langTwoAlpha; | ||
81 | KConfig *languages; | ||
82 | |||
83 | QString calendarType; | ||
84 | KCalendarSystem * calendar; | ||
85 | QString first_language; | ||
86 | bool utf8FileEncoding; | ||
87 | }; | ||
88 | |||
89 | static KLocale *this_klocale = 0; | ||
90 | |||
91 | KLocale::KLocale( const QString & catalogue, KConfig * config ) | ||
92 | { | ||
93 | d = new KLocalePrivate; | ||
94 | d->config = config; | ||
95 | d->languages = 0; | ||
96 | d->calendar = 0; | ||
97 | |||
98 | initCatalogue(catalogue); | ||
99 | initEncoding(0); | ||
100 | initFileNameEncoding(0); | ||
101 | |||
102 | KConfig *cfg = d->config; | ||
103 | this_klocale = this; | ||
104 | //US if (!cfg) cfg = KGlobal::instance()->config(); | ||
105 | if (!cfg) cfg = KGlobal::config(); | ||
106 | this_klocale = 0; | ||
107 | //US Q_ASSERT( cfg ); | ||
108 | ASSERT( cfg ); | ||
109 | |||
110 | if (m_language.isEmpty()) | ||
111 | initLanguage(cfg, config == 0); | ||
112 | |||
113 | |||
114 | /*US | ||
115 | //US mDateFormat = "%a %Y %b %d"; | ||
116 | //US mDateFormatShort = "%Y-%m-%d"; | ||
117 | mTimeZoneList << i18n ("-11:00 US/Samoa") | ||
118 | << i18n ("-10:00 US/Hawaii") | ||
119 | << i18n ("-09:00 US/Alaska") | ||
120 | << i18n ("-08:00 US/Pacific") | ||
121 | << i18n ("-07:00 US/Mountain") | ||
122 | << i18n ("-06:00 US/Central") | ||
123 | << i18n ("-05:00 US/Eastern") | ||
124 | << i18n ("-04:00 Brazil/West") | ||
125 | << i18n ("-03:00 Brazil/East") | ||
126 | << i18n ("-02:00 Brazil/DeNoronha") | ||
127 | << i18n ("-01:00 Atlantic/Azores") | ||
128 | << i18n (" 00:00 Europe/London(UTC)") | ||
129 | << i18n ("+01:00 Europe/Oslo(CET)") | ||
130 | << i18n ("+02:00 Europe/Helsinki") | ||
131 | << i18n ("+03:00 Europe/Moscow") | ||
132 | << i18n ("+04:00 Indian/Mauritius") | ||
133 | << i18n ("+05:00 Indian/Maldives") | ||
134 | << i18n ("+06:00 Indian/Chagos") | ||
135 | << i18n ("+07:00 Asia/Bangkok") | ||
136 | << i18n ("+08:00 Asia/Hongkong") | ||
137 | << i18n ("+09:00 Asia/Tokyo") | ||
138 | << i18n ("+10:00 Asia/Vladivostok") | ||
139 | << i18n ("+11:00 Asia/Magadan") | ||
140 | << i18n ("+12:00 Asia/Kamchatka") | ||
141 | // << i18n (" xx:xx User defined offset") | ||
142 | << i18n (" Local Time"); | ||
143 | */ | ||
144 | mTimeZoneList << "-11:00 US/Samoa" | ||
145 | << "-10:00 US/Hawaii" | ||
146 | << "-09:00 US/Alaska" | ||
147 | << "-08:00 US/Pacific" | ||
148 | << "-07:00 US/Mountain" | ||
149 | << "-06:00 US/Central" | ||
150 | << "-05:00 US/Eastern" | ||
151 | << "-04:00 Brazil/West" | ||
152 | << "-03:00 Brazil/East" | ||
153 | << "-02:00 Brazil/DeNoronha" | ||
154 | << "-01:00 Atlantic/Azores" | ||
155 | << " 00:00 Europe/London(UTC)" | ||
156 | << "+01:00 Europe/Oslo(CET)" | ||
157 | << "+02:00 Europe/Helsinki" | ||
158 | << "+03:00 Europe/Moscow" | ||
159 | << "+04:00 Indian/Mauritius" | ||
160 | << "+05:00 Indian/Maldives" | ||
161 | << "+06:00 Indian/Chagos" | ||
162 | << "+07:00 Asia/Bangkok" | ||
163 | << "+08:00 Asia/Hongkong" | ||
164 | << "+09:00 Asia/Tokyo" | ||
165 | << "+10:00 Asia/Vladivostok" | ||
166 | << "+11:00 Asia/Magadan" | ||
167 | << "+12:00 Asia/Kamchatka" | ||
168 | // << " xx:xx User defined offset" | ||
169 | << " Local Time"; | ||
170 | |||
171 | mSouthDaylight = false; | ||
172 | mTimeZoneOffset = 0; | ||
173 | daylightEnabled = false; | ||
174 | |||
175 | mWeekStartsMonday = true; | ||
176 | mHourF24Format = true; | ||
177 | mIntDateFormat = 0; | ||
178 | mLanguage = 0; | ||
179 | |||
180 | } | ||
181 | |||
182 | |||
183 | QString KLocale::_initLanguage(KConfigBase *config) | ||
184 | { | ||
185 | if (this_klocale) | ||
186 | { | ||
187 | // ### HPB Why this cast?? | ||
188 | this_klocale->initLanguage((KConfig *) config, true); | ||
189 | return this_klocale->language(); | ||
190 | } | ||
191 | return QString::null; | ||
192 | } | ||
193 | |||
194 | void KLocale::initCatalogue(const QString & catalogue) | ||
195 | { | ||
196 | // Use the first non-null string. | ||
197 | QString mainCatalogue = catalogue; | ||
198 | if (maincatalogue) | ||
199 | mainCatalogue = QString::fromLatin1(maincatalogue); | ||
200 | |||
201 | if (mainCatalogue.isEmpty()) { | ||
202 | kdDebug(173) << "KLocale instance created called without valid " | ||
203 | << "catalogue! Give an argument or call setMainCatalogue " | ||
204 | << "before init" << endl; | ||
205 | } | ||
206 | else | ||
207 | d->catalogues.append( KCatalogue(mainCatalogue ) ); | ||
208 | |||
209 | // always include kdelibs.mo | ||
210 | d->catalogues.append( KCatalogue( SYSTEM_MESSAGES ) ); | ||
211 | } | ||
212 | |||
213 | void KLocale::initLanguage(KConfig * config, bool useEnv) | ||
214 | { | ||
215 | KConfigGroupSaver saver(config, "Locale"); | ||
216 | |||
217 | m_country = config->readEntry( "Country" ); | ||
218 | if ( m_country.isEmpty() ) | ||
219 | m_country = defaultCountry(); | ||
220 | |||
221 | // Reset the list and add the new languages | ||
222 | QStringList languageList; | ||
223 | if ( useEnv ) | ||
224 | languageList += QStringList::split | ||
225 | (':', QFile::decodeName( ::getenv("KDE_LANG") )); | ||
226 | |||
227 | //US languageList += config->readListEntry("Language", ':'); | ||
228 | languageList += config->readListEntry("Language"); | ||
229 | |||
230 | // same order as setlocale use | ||
231 | if ( useEnv ) | ||
232 | { | ||
233 | // HPB: Only run splitLocale on the environment variables.. | ||
234 | QStringList langs; | ||
235 | |||
236 | langs << QFile::decodeName( ::getenv("LC_ALL") ); | ||
237 | langs << QFile::decodeName( ::getenv("LC_MESSAGES") ); | ||
238 | langs << QFile::decodeName( ::getenv("LANG") ); | ||
239 | langs << QFile::decodeName( ::getenv("LC_CTYPE") ); | ||
240 | |||
241 | for ( QStringList::Iterator it = langs.begin(); | ||
242 | it != langs.end(); | ||
243 | ++it ) | ||
244 | { | ||
245 | QString ln, ct, chrset; | ||
246 | splitLocale(*it, ln, ct, chrset); | ||
247 | |||
248 | if (!ct.isEmpty()) { | ||
249 | langs.insert(it, ln + '_' + ct); | ||
250 | if (!chrset.isEmpty()) | ||
251 | langs.insert(it, ln + '_' + ct + '.' + chrset); | ||
252 | } | ||
253 | |||
254 | langs.insert(it, ln); | ||
255 | } | ||
256 | |||
257 | languageList += langs; | ||
258 | } | ||
259 | |||
260 | // now we have a language list -- let's use the first OK language | ||
261 | setLanguage( languageList ); | ||
262 | } | ||
263 | |||
264 | void KLocale::doBindInit() | ||
265 | { | ||
266 | return; // LR | ||
267 | for ( QValueList<KCatalogue>::Iterator it = d->catalogues.begin(); | ||
268 | it != d->catalogues.end(); | ||
269 | ++it ) | ||
270 | initCatalogue( *it ); | ||
271 | |||
272 | if ( useDefaultLanguage() ) | ||
273 | d->plural_form = -1; | ||
274 | else | ||
275 | { | ||
276 | QString pf = translate_priv | ||
277 | ( I18N_NOOP("_: Dear translator, please do not translate this string " | ||
278 | "in any form, but pick the _right_ value out of " | ||
279 | "NoPlural/TwoForms/French... If not sure what to do mail " | ||
280 | "thd@kde.org and coolo@kde.org, they will tell you. " | ||
281 | "Better leave that out if unsure, the programs will " | ||
282 | "crash!!\nDefinition of PluralForm - to be set by the " | ||
283 | "translator of kdelibs.po"), 0); | ||
284 | if ( pf.isEmpty() ) { | ||
285 | kdWarning(173) << "found no definition of PluralForm for " << m_language << endl; | ||
286 | d->plural_form = -1; | ||
287 | } else if ( pf == "NoPlural" ) | ||
288 | d->plural_form = 0; | ||
289 | else if ( pf == "TwoForms" ) | ||
290 | d->plural_form = 1; | ||
291 | else if ( pf == "French" ) | ||
292 | d->plural_form = 2; | ||
293 | else if ( pf == "OneTwoRest" || pf == "Gaeilge" ) // Gaelige is the old name | ||
294 | d->plural_form = 3; | ||
295 | else if ( pf == "Russian" ) | ||
296 | d->plural_form = 4; | ||
297 | else if ( pf == "Polish" ) | ||
298 | d->plural_form = 5; | ||
299 | else if ( pf == "Slovenian" ) | ||
300 | d->plural_form = 6; | ||
301 | else if ( pf == "Lithuanian" ) | ||
302 | d->plural_form = 7; | ||
303 | else if ( pf == "Czech" ) | ||
304 | d->plural_form = 8; | ||
305 | else if ( pf == "Slovak" ) | ||
306 | d->plural_form = 9; | ||
307 | else if ( pf == "Maltese" ) | ||
308 | d->plural_form = 10; | ||
309 | else if ( pf == "Arabic" ) | ||
310 | d->plural_form = 11; | ||
311 | else if ( pf == "Balcan" ) | ||
312 | d->plural_form = 12; | ||
313 | else { | ||
314 | kdWarning(173) << "Definition of PluralForm is none of " | ||
315 | << "NoPlural/" | ||
316 | << "TwoForms/" | ||
317 | << "French/" | ||
318 | << "OneTwoRest/" | ||
319 | << "Russian/" | ||
320 | << "Polish/" | ||
321 | << "Slovenian/" | ||
322 | << "Lithuanian/" | ||
323 | << "Czech/" | ||
324 | << "Slovak/" | ||
325 | << "Arabic/" | ||
326 | << "Balcan/" | ||
327 | << "Maltese: " << pf << endl; | ||
328 | exit(1); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | d->formatInited = false; | ||
333 | } | ||
334 | |||
335 | void KLocale::doFormatInit() const | ||
336 | { | ||
337 | if ( d->formatInited ) return; | ||
338 | |||
339 | KLocale * that = const_cast<KLocale *>(this); | ||
340 | that->initFormat(); | ||
341 | |||
342 | d->formatInited = true; | ||
343 | } | ||
344 | |||
345 | void KLocale::initFormat() | ||
346 | { | ||
347 | KConfig *config = d->config; | ||
348 | //US if (!config) config = KGlobal::instance()->config(); | ||
349 | if (!config) config = KGlobal::config(); | ||
350 | ASSERT( config ); | ||
351 | |||
352 | kdDebug(173) << "KLocale::initFormat" << endl; | ||
353 | |||
354 | // make sure the config files are read using the correct locale | ||
355 | // ### Why not add a KConfigBase::setLocale( const KLocale * )? | ||
356 | // ### Then we could remove this hack | ||
357 | //US | ||
358 | //US KLocale *lsave = KGlobal::_locale; | ||
359 | //US KGlobal::_locale = this; | ||
360 | KLocale *lsave = KGlobal::locale(); | ||
361 | KGlobal::setLocale(this); | ||
362 | |||
363 | KConfigGroupSaver saver(config, "Locale"); | ||
364 | |||
365 | |||
366 | |||
367 | //US in kabc/adress.cpp we have a similar setup. Check there in case of problems | ||
368 | KSimpleConfig entry(locateLocal("locale", | ||
369 | QString::fromLatin1("l10n/%1/entry.desktop") | ||
370 | .arg(m_country)) ); | ||
371 | |||
372 | entry.setGroup("KCM Locale"); | ||
373 | |||
374 | // Numeric | ||
375 | #define readConfigEntry(key, default, save) \ | ||
376 | save = entry.readEntry(key, QString::fromLatin1(default)); \ | ||
377 | save = config->readEntry(key, save); | ||
378 | |||
379 | #define readConfigNumEntry(key, default, save, type) \ | ||
380 | save = (type)entry.readNumEntry(key, default); \ | ||
381 | save = (type)config->readNumEntry(key, save); | ||
382 | |||
383 | #define readConfigBoolEntry(key, default, save) \ | ||
384 | save = entry.readBoolEntry(key, default); \ | ||
385 | save = config->readBoolEntry(key, save); | ||
386 | |||
387 | readConfigEntry("DecimalSymbol", ".", m_decimalSymbol); | ||
388 | readConfigEntry("ThousandsSeparator", ",", m_thousandsSeparator); | ||
389 | m_thousandsSeparator.replace( QString::fromLatin1("$0"), QString::null ); | ||
390 | //kdDebug(173) << "m_thousandsSeparator=" << m_thousandsSeparator << endl; | ||
391 | |||
392 | readConfigEntry("PositiveSign", "", m_positiveSign); | ||
393 | readConfigEntry("NegativeSign", "-", m_negativeSign); | ||
394 | |||
395 | // Monetary | ||
396 | readConfigEntry("CurrencySymbol", "$", m_currencySymbol); | ||
397 | readConfigEntry("MonetaryDecimalSymbol", ".", m_monetaryDecimalSymbol); | ||
398 | readConfigEntry("MonetaryThousandsSeparator", ",", | ||
399 | m_monetaryThousandsSeparator); | ||
400 | m_monetaryThousandsSeparator.replace(QString::fromLatin1("$0"), QString::null); | ||
401 | |||
402 | readConfigNumEntry("FracDigits", 2, m_fracDigits, int); | ||
403 | readConfigBoolEntry("PositivePrefixCurrencySymbol", true, | ||
404 | m_positivePrefixCurrencySymbol); | ||
405 | readConfigBoolEntry("NegativePrefixCurrencySymbol", true, | ||
406 | m_negativePrefixCurrencySymbol); | ||
407 | readConfigNumEntry("PositiveMonetarySignPosition", (int)BeforeQuantityMoney, | ||
408 | m_positiveMonetarySignPosition, SignPosition); | ||
409 | readConfigNumEntry("NegativeMonetarySignPosition", (int)ParensAround, | ||
410 | m_negativeMonetarySignPosition, SignPosition); | ||
411 | |||
412 | //Grammatical | ||
413 | readConfigBoolEntry("NounDeclension", false, d->nounDeclension); | ||
414 | |||
415 | // Date and time | ||
416 | readConfigEntry("TimeFormat", "%H:%M:%S", m_timeFormat); | ||
417 | readConfigEntry("DateFormat", "%A %d %B %Y", m_dateFormat); | ||
418 | readConfigEntry("DateFormatShort", "%Y-%m-%d", m_dateFormatShort); | ||
419 | readConfigBoolEntry("DateMonthNamePossessive", false, | ||
420 | d->dateMonthNamePossessive); | ||
421 | readConfigNumEntry("WeekStartDay", 1, d->weekStartDay, int); | ||
422 | |||
423 | // other | ||
424 | //US readConfigNumEntry("PageSize", (int)QPrinter::A4, d->pageSize, int); | ||
425 | readConfigNumEntry("MeasureSystem", (int)Metric, d->measureSystem, | ||
426 | MeasureSystem); | ||
427 | readConfigEntry("CalendarSystem", "gregorian", d->calendarType); | ||
428 | delete d->calendar; | ||
429 | d->calendar = 0; // ### HPB Is this the correct place? | ||
430 | |||
431 | // end of hack | ||
432 | //US KGlobal::_locale = lsave; | ||
433 | KGlobal::setLocale(lsave); | ||
434 | } | ||
435 | |||
436 | bool KLocale::setCountry(const QString & country) | ||
437 | { | ||
438 | // Check if the file exists too?? | ||
439 | if ( country.isEmpty() ) | ||
440 | return false; | ||
441 | |||
442 | m_country = country; | ||
443 | |||
444 | d->formatInited = false; | ||
445 | |||
446 | return true; | ||
447 | } | ||
448 | |||
449 | QString KLocale::catalogueFileName(const QString & language, | ||
450 | const KCatalogue & catalogue) | ||
451 | { | ||
452 | QString path = QString::fromLatin1("%1/LC_MESSAGES/%2.mo") | ||
453 | .arg( language ) | ||
454 | .arg( catalogue.name() ); | ||
455 | |||
456 | return locate( "locale", path ); | ||
457 | } | ||
458 | |||
459 | bool KLocale::isLanguageInstalled(const QString & language) const | ||
460 | { | ||
461 | // Do not allow empty languages | ||
462 | if ( language.isEmpty() ) return false; | ||
463 | |||
464 | bool bRes = true; | ||
465 | if ( language != defaultLanguage() ) | ||
466 | for ( QValueList<KCatalogue>::ConstIterator it = d->catalogues.begin(); | ||
467 | it != d->catalogues.end() && bRes; | ||
468 | ++it ) | ||
469 | { | ||
470 | bRes = !catalogueFileName( language, *it ).isNull(); | ||
471 | if ( !bRes ) | ||
472 | kdDebug(173) << "message catalogue not found: " | ||
473 | << (*it).name() << endl; | ||
474 | } | ||
475 | |||
476 | return bRes; | ||
477 | } | ||
478 | |||
479 | bool KLocale::setLanguage(const QString & language) | ||
480 | { | ||
481 | bool bRes = true; | ||
482 | |||
483 | if (d->first_language.isNull() || language != d->first_language) | ||
484 | bRes = isLanguageInstalled( language ); | ||
485 | |||
486 | if ( bRes ) | ||
487 | { | ||
488 | m_language = language; | ||
489 | |||
490 | // remember our first time - it will be our true love | ||
491 | if (d->first_language.isNull()) | ||
492 | d->first_language = language; | ||
493 | |||
494 | doBindInit(); | ||
495 | } | ||
496 | |||
497 | return bRes; | ||
498 | } | ||
499 | |||
500 | bool KLocale::setLanguage(const QStringList & languages) | ||
501 | { | ||
502 | QStringList languageList(languages); | ||
503 | |||
504 | // Remove duplicate entries in reverse so that we | ||
505 | // can keep user's language preference order intact. (DA) | ||
506 | for( QStringList::Iterator it = languageList.fromLast(); | ||
507 | it != languageList.begin(); | ||
508 | --it ) | ||
509 | if ( languageList.contains(*it) > 1 || (*it).isEmpty() ) | ||
510 | it = languageList.remove( it ); | ||
511 | |||
512 | bool bRes = false; | ||
513 | for ( QStringList::ConstIterator it = languageList.begin(); | ||
514 | it != languageList.end(); | ||
515 | ++it ) | ||
516 | if ( bRes = setLanguage( *it ) ) | ||
517 | break; | ||
518 | |||
519 | if ( !bRes ) | ||
520 | setLanguage(defaultLanguage()); | ||
521 | |||
522 | d->languageList = languageList; | ||
523 | d->langTwoAlpha.clear(); // Flush cache | ||
524 | |||
525 | return bRes; | ||
526 | } | ||
527 | |||
528 | void KLocale::splitLocale(const QString & aStr, | ||
529 | QString & language, | ||
530 | QString & country, | ||
531 | QString & chrset) | ||
532 | { | ||
533 | QString str = aStr; | ||
534 | |||
535 | // just in case, there is another language appended | ||
536 | int f = str.find(':'); | ||
537 | if (f >= 0) | ||
538 | str.truncate(f); | ||
539 | |||
540 | country = QString::null; | ||
541 | chrset = QString::null; | ||
542 | language = QString::null; | ||
543 | |||
544 | f = str.find('.'); | ||
545 | if (f >= 0) | ||
546 | { | ||
547 | chrset = str.mid(f + 1); | ||
548 | str.truncate(f); | ||
549 | } | ||
550 | |||
551 | f = str.find('_'); | ||
552 | if (f >= 0) | ||
553 | { | ||
554 | country = str.mid(f + 1); | ||
555 | str.truncate(f); | ||
556 | } | ||
557 | |||
558 | language = str; | ||
559 | } | ||
560 | |||
561 | QString KLocale::language() const | ||
562 | { | ||
563 | return m_language; | ||
564 | } | ||
565 | |||
566 | QString KLocale::country() const | ||
567 | { | ||
568 | return m_country; | ||
569 | } | ||
570 | |||
571 | QString KLocale::monthName(int i, bool shortName) const | ||
572 | { | ||
573 | if ( shortName ) | ||
574 | switch ( i ) | ||
575 | { | ||
576 | case 1: return translate("January", "Jan"); | ||
577 | case 2: return translate("February", "Feb"); | ||
578 | case 3: return translate("March", "Mar"); | ||
579 | case 4: return translate("April", "Apr"); | ||
580 | case 5: return translate("May short", "May"); | ||
581 | case 6: return translate("June", "Jun"); | ||
582 | case 7: return translate("July", "Jul"); | ||
583 | case 8: return translate("August", "Aug"); | ||
584 | case 9: return translate("September", "Sep"); | ||
585 | case 10: return translate("October", "Oct"); | ||
586 | case 11: return translate("November", "Nov"); | ||
587 | case 12: return translate("December", "Dec"); | ||
588 | } | ||
589 | else | ||
590 | switch (i) | ||
591 | { | ||
592 | case 1: return translate("January"); | ||
593 | case 2: return translate("February"); | ||
594 | case 3: return translate("March"); | ||
595 | case 4: return translate("April"); | ||
596 | case 5: return translate("May long", "May"); | ||
597 | case 6: return translate("June"); | ||
598 | case 7: return translate("July"); | ||
599 | case 8: return translate("August"); | ||
600 | case 9: return translate("September"); | ||
601 | case 10: return translate("October"); | ||
602 | case 11: return translate("November"); | ||
603 | case 12: return translate("December"); | ||
604 | } | ||
605 | |||
606 | return QString::null; | ||
607 | } | ||
608 | |||
609 | QString KLocale::monthNamePossessive(int i, bool shortName) const | ||
610 | { | ||
611 | if ( shortName ) | ||
612 | switch ( i ) | ||
613 | { | ||
614 | case 1: return translate("of January", "of Jan"); | ||
615 | case 2: return translate("of February", "of Feb"); | ||
616 | case 3: return translate("of March", "of Mar"); | ||
617 | case 4: return translate("of April", "of Apr"); | ||
618 | case 5: return translate("of May short", "of May"); | ||
619 | case 6: return translate("of June", "of Jun"); | ||
620 | case 7: return translate("of July", "of Jul"); | ||
621 | case 8: return translate("of August", "of Aug"); | ||
622 | case 9: return translate("of September", "of Sep"); | ||
623 | case 10: return translate("of October", "of Oct"); | ||
624 | case 11: return translate("of November", "of Nov"); | ||
625 | case 12: return translate("of December", "of Dec"); | ||
626 | } | ||
627 | else | ||
628 | switch (i) | ||
629 | { | ||
630 | case 1: return translate("of January"); | ||
631 | case 2: return translate("of February"); | ||
632 | case 3: return translate("of March"); | ||
633 | case 4: return translate("of April"); | ||
634 | case 5: return translate("of May long", "of May"); | ||
635 | case 6: return translate("of June"); | ||
636 | case 7: return translate("of July"); | ||
637 | case 8: return translate("of August"); | ||
638 | case 9: return translate("of September"); | ||
639 | case 10: return translate("of October"); | ||
640 | case 11: return translate("of November"); | ||
641 | case 12: return translate("of December"); | ||
642 | } | ||
643 | |||
644 | return QString::null; | ||
645 | } | ||
646 | |||
647 | QString KLocale::weekDayName (int i, bool shortName) const | ||
648 | { | ||
649 | if ( shortName ) | ||
650 | switch ( i ) | ||
651 | { | ||
652 | case 1: return translate("Monday", "Mon"); | ||
653 | case 2: return translate("Tuesday", "Tue"); | ||
654 | case 3: return translate("Wednesday", "Wed"); | ||
655 | case 4: return translate("Thursday", "Thu"); | ||
656 | case 5: return translate("Friday", "Fri"); | ||
657 | case 6: return translate("Saturday", "Sat"); | ||
658 | case 7: return translate("Sunday", "Sun"); | ||
659 | } | ||
660 | else | ||
661 | switch ( i ) | ||
662 | { | ||
663 | case 1: return translate("Monday"); | ||
664 | case 2: return translate("Tuesday"); | ||
665 | case 3: return translate("Wednesday"); | ||
666 | case 4: return translate("Thursday"); | ||
667 | case 5: return translate("Friday"); | ||
668 | case 6: return translate("Saturday"); | ||
669 | case 7: return translate("Sunday"); | ||
670 | } | ||
671 | |||
672 | return QString::null; | ||
673 | } | ||
674 | |||
675 | void KLocale::insertCatalogue( const QString & catalogue ) | ||
676 | { | ||
677 | KCatalogue cat( catalogue ); | ||
678 | |||
679 | initCatalogue( cat ); | ||
680 | |||
681 | d->catalogues.append( cat ); | ||
682 | } | ||
683 | |||
684 | void KLocale::removeCatalogue(const QString &catalogue) | ||
685 | { | ||
686 | for ( QValueList<KCatalogue>::Iterator it = d->catalogues.begin(); | ||
687 | it != d->catalogues.end(); ) | ||
688 | if ((*it).name() == catalogue) { | ||
689 | it = d->catalogues.remove(it); | ||
690 | return; | ||
691 | } else | ||
692 | ++it; | ||
693 | } | ||
694 | |||
695 | void KLocale::setActiveCatalogue(const QString &catalogue) | ||
696 | { | ||
697 | for ( QValueList<KCatalogue>::Iterator it = d->catalogues.begin(); | ||
698 | it != d->catalogues.end(); ++it) | ||
699 | if ((*it).name() == catalogue) { | ||
700 | KCatalogue save = *it; | ||
701 | d->catalogues.remove(it); | ||
702 | d->catalogues.prepend(save); | ||
703 | return; | ||
704 | } | ||
705 | } | ||
706 | |||
707 | KLocale::~KLocale() | ||
708 | { | ||
709 | delete d->languages; | ||
710 | delete d; | ||
711 | } | ||
712 | |||
713 | QString KLocale::translate_priv(const char *msgid, | ||
714 | const char *fallback, | ||
715 | const char **translated) const | ||
716 | { | ||
717 | if (!msgid || !msgid[0]) | ||
718 | { | ||
719 | kdWarning() << "KLocale: trying to look up \"\" in catalogue. " | ||
720 | << "Fix the program" << endl; | ||
721 | return QString::null; | ||
722 | } | ||
723 | |||
724 | if ( useDefaultLanguage() ) | ||
725 | return QString::fromUtf8( fallback ); | ||
726 | |||
727 | for ( QValueList<KCatalogue>::ConstIterator it = d->catalogues.begin(); | ||
728 | it != d->catalogues.end(); | ||
729 | ++it ) | ||
730 | { | ||
731 | // kdDebug(173) << "translate " << msgid << " " << (*it).name() << " " << (!KGlobal::activeInstance() ? QCString("no instance") : KGlobal::activeInstance()->instanceName()) << endl; | ||
732 | const char * text = (*it).translate( msgid ); | ||
733 | |||
734 | if ( text ) | ||
735 | { | ||
736 | // we found it | ||
737 | if (translated) | ||
738 | *translated = text; | ||
739 | return QString::fromUtf8( text ); | ||
740 | } | ||
741 | } | ||
742 | |||
743 | // Always use UTF-8 if the string was not found | ||
744 | return QString::fromUtf8( fallback ); | ||
745 | } | ||
746 | |||
747 | QString KLocale::translate(const char* msgid) const | ||
748 | { | ||
749 | return translate_priv(msgid, msgid); | ||
750 | } | ||
751 | |||
752 | QString KLocale::translate( const char *index, const char *fallback) const | ||
753 | { | ||
754 | if (!index || !index[0] || !fallback || !fallback[0]) | ||
755 | { | ||
756 | kdDebug(173) << "KLocale: trying to look up \"\" in catalogue. " | ||
757 | << "Fix the program" << endl; | ||
758 | return QString::null; | ||
759 | } | ||
760 | |||
761 | if ( useDefaultLanguage() ) | ||
762 | return QString::fromUtf8( fallback ); | ||
763 | |||
764 | char *newstring = new char[strlen(index) + strlen(fallback) + 5]; | ||
765 | sprintf(newstring, "_: %s\n%s", index, fallback); | ||
766 | // as copying QString is very fast, it looks slower as it is ;/ | ||
767 | QString r = translate_priv(newstring, fallback); | ||
768 | delete [] newstring; | ||
769 | |||
770 | return r; | ||
771 | } | ||
772 | |||
773 | static QString put_n_in(const QString &orig, unsigned long n) | ||
774 | { | ||
775 | QString ret = orig; | ||
776 | int index = ret.find("%n"); | ||
777 | if (index == -1) | ||
778 | return ret; | ||
779 | ret.replace(index, 2, QString::number(n)); | ||
780 | return ret; | ||
781 | } | ||
782 | |||
783 | #define EXPECT_LENGTH(x) \ | ||
784 | if (forms.count() != x) { \ | ||
785 | kdError() << "translation of \"" << singular << "\" doesn't contain " << x << " different plural forms as expected\n"; \ | ||
786 | return QString( "BROKEN TRANSLATION %1" ).arg( singular ); } | ||
787 | |||
788 | QString KLocale::translate( const char *singular, const char *plural, | ||
789 | unsigned long n ) const | ||
790 | { | ||
791 | if (!singular || !singular[0] || !plural || !plural[0]) | ||
792 | { | ||
793 | kdWarning() << "KLocale: trying to look up \"\" in catalogue. " | ||
794 | << "Fix the program" << endl; | ||
795 | return QString::null; | ||
796 | } | ||
797 | |||
798 | char *newstring = new char[strlen(singular) + strlen(plural) + 6]; | ||
799 | sprintf(newstring, "_n: %s\n%s", singular, plural); | ||
800 | // as copying QString is very fast, it looks slower as it is ;/ | ||
801 | QString r = translate_priv(newstring, 0); | ||
802 | delete [] newstring; | ||
803 | |||
804 | if ( r.isEmpty() || useDefaultLanguage() || d->plural_form == -1) { | ||
805 | if ( n == 1 ) { | ||
806 | return put_n_in( QString::fromUtf8( singular ), n ); | ||
807 | } else { | ||
808 | QString tmp = QString::fromUtf8( plural ); | ||
809 | #ifndef NDEBUG | ||
810 | if (tmp.find("%n") == -1) { | ||
811 | kdWarning() << "the message for i18n should contain a '%n'! " << plural << endl; | ||
812 | } | ||
813 | #endif | ||
814 | return put_n_in( tmp, n ); | ||
815 | } | ||
816 | } | ||
817 | |||
818 | QStringList forms = QStringList::split( "\n", r, false ); | ||
819 | switch ( d->plural_form ) { | ||
820 | case 0: // NoPlural | ||
821 | EXPECT_LENGTH( 1 ); | ||
822 | return put_n_in( forms[0], n); | ||
823 | case 1: // TwoForms | ||
824 | EXPECT_LENGTH( 2 ); | ||
825 | if ( n == 1 ) | ||
826 | return put_n_in( forms[0], n); | ||
827 | else | ||
828 | return put_n_in( forms[1], n); | ||
829 | case 2: // French | ||
830 | EXPECT_LENGTH( 2 ); | ||
831 | if ( n == 1 || n == 0 ) | ||
832 | return put_n_in( forms[0], n); | ||
833 | else | ||
834 | return put_n_in( forms[1], n); | ||
835 | case 3: // Gaeilge | ||
836 | EXPECT_LENGTH( 3 ); | ||
837 | if ( n == 1 ) | ||
838 | return put_n_in( forms[0], n); | ||
839 | else if ( n == 2 ) | ||
840 | return put_n_in( forms[1], n); | ||
841 | else | ||
842 | return put_n_in( forms[2], n); | ||
843 | case 4: // Russian, corrected by mok | ||
844 | EXPECT_LENGTH( 3 ); | ||
845 | if ( n%10 == 1 && n%100 != 11) | ||
846 | return put_n_in( forms[0], n); // odin fail | ||
847 | else if (( n%10 >= 2 && n%10 <=4 ) && (n%100<10 || n%100>20)) | ||
848 | return put_n_in( forms[1], n); // dva faila | ||
849 | else | ||
850 | return put_n_in( forms[2], n); // desyat' failov | ||
851 | case 5: // Polish | ||
852 | EXPECT_LENGTH( 3 ); | ||
853 | if ( n == 1 ) | ||
854 | return put_n_in( forms[0], n); | ||
855 | else if ( n%10 >= 2 && n%10 <=4 && (n%100<10 || n%100>=20) ) | ||
856 | return put_n_in( forms[1], n); | ||
857 | else | ||
858 | return put_n_in( forms[2], n); | ||
859 | case 6: // Slovenian | ||
860 | EXPECT_LENGTH( 4 ); | ||
861 | if ( n%100 == 1 ) | ||
862 | return put_n_in( forms[1], n); // ena datoteka | ||
863 | else if ( n%100 == 2 ) | ||
864 | return put_n_in( forms[2], n); // dve datoteki | ||
865 | else if ( n%100 == 3 || n%100 == 4 ) | ||
866 | return put_n_in( forms[3], n); // tri datoteke | ||
867 | else | ||
868 | return put_n_in( forms[0], n); // sto datotek | ||
869 | case 7: // Lithuanian | ||
870 | EXPECT_LENGTH( 3 ); | ||
871 | if ( n%10 == 0 || (n%100>=11 && n%100<=19) ) | ||
872 | return put_n_in( forms[2], n); | ||
873 | else if ( n%10 == 1 ) | ||
874 | return put_n_in( forms[0], n); | ||
875 | else | ||
876 | return put_n_in( forms[1], n); | ||
877 | case 8: // Czech | ||
878 | EXPECT_LENGTH( 3 ); | ||
879 | if ( n%100 == 1 ) | ||
880 | return put_n_in( forms[0], n); | ||
881 | else if (( n%100 >= 2 ) && ( n%100 <= 4 )) | ||
882 | return put_n_in( forms[1], n); | ||
883 | else | ||
884 | return put_n_in( forms[2], n); | ||
885 | case 9: // Slovak | ||
886 | EXPECT_LENGTH( 3 ); | ||
887 | if ( n == 1 ) | ||
888 | return put_n_in( forms[0], n); | ||
889 | else if (( n >= 2 ) && ( n <= 4 )) | ||
890 | return put_n_in( forms[1], n); | ||
891 | else | ||
892 | return put_n_in( forms[2], n); | ||
893 | case 10: // Maltese | ||
894 | EXPECT_LENGTH( 4 ); | ||
895 | if ( n == 1 ) | ||
896 | return put_n_in( forms[0], n ); | ||
897 | else if ( ( n == 0 ) || ( n%100 > 0 && n%100 <= 10 ) ) | ||
898 | return put_n_in( forms[1], n ); | ||
899 | else if ( n%100 > 10 && n%100 < 20 ) | ||
900 | return put_n_in( forms[2], n ); | ||
901 | else | ||
902 | return put_n_in( forms[3], n ); | ||
903 | case 11: // Arabic | ||
904 | EXPECT_LENGTH( 4 ); | ||
905 | if (n == 1) | ||
906 | return put_n_in(forms[0], n); | ||
907 | else if (n == 2) | ||
908 | return put_n_in(forms[1], n); | ||
909 | else if ( n < 11) | ||
910 | return put_n_in(forms[2], n); | ||
911 | else | ||
912 | return put_n_in(forms[3], n); | ||
913 | case 12: // Balcan | ||
914 | EXPECT_LENGTH( 3 ); | ||
915 | if (n != 11 && n % 10 == 1) | ||
916 | return put_n_in(forms[0], n); | ||
917 | else if (n / 10 != 1 && n % 10 >= 2 && n % 10 <= 4) | ||
918 | return put_n_in(forms[1], n); | ||
919 | else | ||
920 | return put_n_in(forms[2], n); | ||
921 | } | ||
922 | kdError() << "The function should have been returned in another way\n"; | ||
923 | |||
924 | return QString::null; | ||
925 | } | ||
926 | |||
927 | QString KLocale::translateQt( const char *context, const char *source, | ||
928 | const char *message) const | ||
929 | { | ||
930 | if (!source || !source[0]) { | ||
931 | kdWarning() << "KLocale: trying to look up \"\" in catalogue. " | ||
932 | << "Fix the program" << endl; | ||
933 | return QString::null; | ||
934 | } | ||
935 | |||
936 | if ( useDefaultLanguage() ) { | ||
937 | return QString::null; | ||
938 | } | ||
939 | |||
940 | char *newstring = 0; | ||
941 | const char *translation = 0; | ||
942 | QString r; | ||
943 | |||
944 | if ( message && message[0]) { | ||
945 | char *newstring = new char[strlen(source) + strlen(message) + 5]; | ||
946 | sprintf(newstring, "_: %s\n%s", source, message); | ||
947 | const char *translation = 0; | ||
948 | // as copying QString is very fast, it looks slower as it is ;/ | ||
949 | r = translate_priv(newstring, source, &translation); | ||
950 | delete [] newstring; | ||
951 | if (translation) | ||
952 | return r; | ||
953 | } | ||
954 | |||
955 | if ( context && context[0] && message && message[0]) { | ||
956 | newstring = new char[strlen(context) + strlen(message) + 5]; | ||
957 | sprintf(newstring, "_: %s\n%s", context, message); | ||
958 | // as copying QString is very fast, it looks slower as it is ;/ | ||
959 | r = translate_priv(newstring, source, &translation); | ||
960 | delete [] newstring; | ||
961 | if (translation) | ||
962 | return r; | ||
963 | } | ||
964 | |||
965 | r = translate_priv(source, source, &translation); | ||
966 | if (translation) | ||
967 | return r; | ||
968 | return QString::null; | ||
969 | } | ||
970 | |||
971 | bool KLocale::nounDeclension() const | ||
972 | { | ||
973 | doFormatInit(); | ||
974 | return d->nounDeclension; | ||
975 | } | ||
976 | |||
977 | bool KLocale::dateMonthNamePossessive() const | ||
978 | { | ||
979 | doFormatInit(); | ||
980 | return d->dateMonthNamePossessive; | ||
981 | } | ||
982 | |||
983 | int KLocale::weekStartDay() const | ||
984 | { | ||
985 | doFormatInit(); | ||
986 | return d->weekStartDay; | ||
987 | } | ||
988 | |||
989 | bool KLocale::weekStartsMonday() const //deprecated | ||
990 | { | ||
991 | doFormatInit(); | ||
992 | return (d->weekStartDay==1); | ||
993 | } | ||
994 | |||
995 | QString KLocale::decimalSymbol() const | ||
996 | { | ||
997 | doFormatInit(); | ||
998 | return m_decimalSymbol; | ||
999 | } | ||
1000 | |||
1001 | QString KLocale::thousandsSeparator() const | ||
1002 | { | ||
1003 | doFormatInit(); | ||
1004 | return m_thousandsSeparator; | ||
1005 | } | ||
1006 | |||
1007 | QString KLocale::currencySymbol() const | ||
1008 | { | ||
1009 | doFormatInit(); | ||
1010 | return m_currencySymbol; | ||
1011 | } | ||
1012 | |||
1013 | QString KLocale::monetaryDecimalSymbol() const | ||
1014 | { | ||
1015 | doFormatInit(); | ||
1016 | return m_monetaryDecimalSymbol; | ||
1017 | } | ||
1018 | |||
1019 | QString KLocale::monetaryThousandsSeparator() const | ||
1020 | { | ||
1021 | doFormatInit(); | ||
1022 | return m_monetaryThousandsSeparator; | ||
1023 | } | ||
1024 | |||
1025 | QString KLocale::positiveSign() const | ||
1026 | { | ||
1027 | doFormatInit(); | ||
1028 | return m_positiveSign; | ||
1029 | } | ||
1030 | |||
1031 | QString KLocale::negativeSign() const | ||
1032 | { | ||
1033 | doFormatInit(); | ||
1034 | return m_negativeSign; | ||
1035 | } | ||
1036 | |||
1037 | int KLocale::fracDigits() const | ||
1038 | { | ||
1039 | doFormatInit(); | ||
1040 | return m_fracDigits; | ||
1041 | } | ||
1042 | |||
1043 | bool KLocale::positivePrefixCurrencySymbol() const | ||
1044 | { | ||
1045 | doFormatInit(); | ||
1046 | return m_positivePrefixCurrencySymbol; | ||
1047 | } | ||
1048 | |||
1049 | bool KLocale::negativePrefixCurrencySymbol() const | ||
1050 | { | ||
1051 | doFormatInit(); | ||
1052 | return m_negativePrefixCurrencySymbol; | ||
1053 | } | ||
1054 | |||
1055 | KLocale::SignPosition KLocale::positiveMonetarySignPosition() const | ||
1056 | { | ||
1057 | doFormatInit(); | ||
1058 | return m_positiveMonetarySignPosition; | ||
1059 | } | ||
1060 | |||
1061 | KLocale::SignPosition KLocale::negativeMonetarySignPosition() const | ||
1062 | { | ||
1063 | doFormatInit(); | ||
1064 | return m_negativeMonetarySignPosition; | ||
1065 | } | ||
1066 | |||
1067 | static inline void put_it_in( QChar *buffer, uint& index, const QString &s ) | ||
1068 | { | ||
1069 | for ( uint l = 0; l < s.length(); l++ ) | ||
1070 | buffer[index++] = s.at( l ); | ||
1071 | } | ||
1072 | |||
1073 | static inline void put_it_in( QChar *buffer, uint& index, int number ) | ||
1074 | { | ||
1075 | buffer[index++] = number / 10 + '0'; | ||
1076 | buffer[index++] = number % 10 + '0'; | ||
1077 | } | ||
1078 | |||
1079 | QString KLocale::formatMoney(double num, | ||
1080 | const QString & symbol, | ||
1081 | int precision) const | ||
1082 | { | ||
1083 | // some defaults | ||
1084 | QString currency = symbol.isNull() | ||
1085 | ? currencySymbol() | ||
1086 | : symbol; | ||
1087 | if (precision < 0) precision = fracDigits(); | ||
1088 | |||
1089 | // the number itself | ||
1090 | bool neg = num < 0; | ||
1091 | QString res = QString::number(neg?-num:num, 'f', precision); | ||
1092 | int pos = res.find('.'); | ||
1093 | if (pos == -1) pos = res.length(); | ||
1094 | else res.replace(pos, 1, monetaryDecimalSymbol()); | ||
1095 | |||
1096 | while (0 < (pos -= 3)) | ||
1097 | res.insert(pos, monetaryThousandsSeparator()); // thousend sep | ||
1098 | |||
1099 | // set some variables we need later | ||
1100 | int signpos = neg | ||
1101 | ? negativeMonetarySignPosition() | ||
1102 | : positiveMonetarySignPosition(); | ||
1103 | QString sign = neg | ||
1104 | ? negativeSign() | ||
1105 | : positiveSign(); | ||
1106 | |||
1107 | switch (signpos) | ||
1108 | { | ||
1109 | case ParensAround: | ||
1110 | res.prepend('('); | ||
1111 | res.append (')'); | ||
1112 | break; | ||
1113 | case BeforeQuantityMoney: | ||
1114 | res.prepend(sign); | ||
1115 | break; | ||
1116 | case AfterQuantityMoney: | ||
1117 | res.append(sign); | ||
1118 | break; | ||
1119 | case BeforeMoney: | ||
1120 | currency.prepend(sign); | ||
1121 | break; | ||
1122 | case AfterMoney: | ||
1123 | currency.append(sign); | ||
1124 | break; | ||
1125 | } | ||
1126 | |||
1127 | if (neg?negativePrefixCurrencySymbol(): | ||
1128 | positivePrefixCurrencySymbol()) | ||
1129 | { | ||
1130 | res.prepend(' '); | ||
1131 | res.prepend(currency); | ||
1132 | } else { | ||
1133 | res.append (' '); | ||
1134 | res.append (currency); | ||
1135 | } | ||
1136 | |||
1137 | return res; | ||
1138 | } | ||
1139 | |||
1140 | QString KLocale::formatMoney(const QString &numStr) const | ||
1141 | { | ||
1142 | return formatMoney(numStr.toDouble()); | ||
1143 | } | ||
1144 | |||
1145 | QString KLocale::formatNumber(double num, int precision) const | ||
1146 | { | ||
1147 | bool neg = num < 0; | ||
1148 | if (precision == -1) precision = 2; | ||
1149 | QString res = QString::number(neg?-num:num, 'f', precision); | ||
1150 | int pos = res.find('.'); | ||
1151 | if (pos == -1) pos = res.length(); | ||
1152 | else res.replace(pos, 1, decimalSymbol()); | ||
1153 | |||
1154 | while (0 < (pos -= 3)) | ||
1155 | res.insert(pos, thousandsSeparator()); // thousand sep | ||
1156 | |||
1157 | // How can we know where we should put the sign? | ||
1158 | res.prepend(neg?negativeSign():positiveSign()); | ||
1159 | |||
1160 | return res; | ||
1161 | } | ||
1162 | |||
1163 | QString KLocale::formatLong(long num) const | ||
1164 | { | ||
1165 | return formatNumber((double)num, 0); | ||
1166 | } | ||
1167 | |||
1168 | QString KLocale::formatNumber(const QString &numStr) const | ||
1169 | { | ||
1170 | return formatNumber(numStr.toDouble()); | ||
1171 | } | ||
1172 | |||
1173 | QString KLocale::formatDate(const QDate &pDate, bool shortFormat) const | ||
1174 | { | ||
1175 | const QString rst = shortFormat?dateFormatShort():dateFormat(); | ||
1176 | |||
1177 | // I'm rather safe than sorry | ||
1178 | QChar *buffer = new QChar[rst.length() * 3 / 2 + 50]; | ||
1179 | |||
1180 | unsigned int index = 0; | ||
1181 | bool escape = false; | ||
1182 | int number = 0; | ||
1183 | |||
1184 | int year = calendar()->year(pDate); | ||
1185 | int month = calendar()->month(pDate); | ||
1186 | int day = calendar()->day(pDate); | ||
1187 | |||
1188 | for ( uint format_index = 0; format_index < rst.length(); ++format_index ) | ||
1189 | { | ||
1190 | if ( !escape ) | ||
1191 | { | ||
1192 | if ( rst.at( format_index ).unicode() == '%' ) | ||
1193 | escape = true; | ||
1194 | else | ||
1195 | buffer[index++] = rst.at( format_index ); | ||
1196 | } | ||
1197 | else | ||
1198 | { | ||
1199 | switch ( rst.at( format_index ).unicode() ) | ||
1200 | { | ||
1201 | case '%': | ||
1202 | buffer[index++] = '%'; | ||
1203 | break; | ||
1204 | case 'Y': | ||
1205 | put_it_in( buffer, index, year / 100 ); | ||
1206 | case 'y': | ||
1207 | put_it_in( buffer, index, year % 100 ); | ||
1208 | break; | ||
1209 | case 'n': | ||
1210 | number = month; | ||
1211 | case 'e': | ||
1212 | // to share the code | ||
1213 | if ( rst.at( format_index ).unicode() == 'e' ) | ||
1214 | number = day; | ||
1215 | if ( number / 10 ) | ||
1216 | buffer[index++] = number / 10 + '0'; | ||
1217 | buffer[index++] = number % 10 + '0'; | ||
1218 | break; | ||
1219 | case 'm': | ||
1220 | put_it_in( buffer, index, month ); | ||
1221 | break; | ||
1222 | case 'b': | ||
1223 | if (d->nounDeclension && d->dateMonthNamePossessive) | ||
1224 | //US put_it_in( buffer, index, calendar()->monthNamePossessive(month, year, true) ); | ||
1225 | put_it_in( buffer, index, calendar()->monthNamePossessive(month, true) ); | ||
1226 | else | ||
1227 | //US put_it_in( buffer, index, calendar()->monthName(month, year, true) ); | ||
1228 | put_it_in( buffer, index, calendar()->monthName(month, true) ); | ||
1229 | break; | ||
1230 | case 'B': | ||
1231 | if (d->nounDeclension && d->dateMonthNamePossessive) | ||
1232 | //US put_it_in( buffer, index, calendar()->monthNamePossessive(month, year, false) ); | ||
1233 | put_it_in( buffer, index, calendar()->monthNamePossessive(month, false) ); | ||
1234 | else | ||
1235 | //US put_it_in( buffer, index, calendar()->monthName(month, year, false) ); | ||
1236 | put_it_in( buffer, index, calendar()->monthName(month, false) ); | ||
1237 | break; | ||
1238 | case 'd': | ||
1239 | put_it_in( buffer, index, day ); | ||
1240 | break; | ||
1241 | case 'a': | ||
1242 | put_it_in( buffer, index, calendar()->weekDayName(pDate, true) ); | ||
1243 | break; | ||
1244 | case 'A': | ||
1245 | put_it_in( buffer, index, calendar()->weekDayName(pDate, false) ); | ||
1246 | break; | ||
1247 | default: | ||
1248 | buffer[index++] = rst.at( format_index ); | ||
1249 | break; | ||
1250 | } | ||
1251 | escape = false; | ||
1252 | } | ||
1253 | } | ||
1254 | QString ret( buffer, index ); | ||
1255 | delete [] buffer; | ||
1256 | return ret; | ||
1257 | } | ||
1258 | |||
1259 | void KLocale::setMainCatalogue(const char *catalogue) | ||
1260 | { | ||
1261 | maincatalogue = catalogue; | ||
1262 | } | ||
1263 | |||
1264 | double KLocale::readNumber(const QString &_str, bool * ok) const | ||
1265 | { | ||
1266 | QString str = _str.stripWhiteSpace(); | ||
1267 | bool neg = str.find(negativeSign()) == 0; | ||
1268 | if (neg) | ||
1269 | str.remove( 0, negativeSign().length() ); | ||
1270 | |||
1271 | /* will hold the scientific notation portion of the number. | ||
1272 | Example, with 2.34E+23, exponentialPart == "E+23" | ||
1273 | */ | ||
1274 | QString exponentialPart; | ||
1275 | int EPos; | ||
1276 | |||
1277 | EPos = str.find('E', 0, false); | ||
1278 | |||
1279 | if (EPos != -1) | ||
1280 | { | ||
1281 | exponentialPart = str.mid(EPos); | ||
1282 | str = str.left(EPos); | ||
1283 | } | ||
1284 | |||
1285 | int pos = str.find(decimalSymbol()); | ||
1286 | QString major; | ||
1287 | QString minor; | ||
1288 | if ( pos == -1 ) | ||
1289 | major = str; | ||
1290 | else | ||
1291 | { | ||
1292 | major = str.left(pos); | ||
1293 | minor = str.mid(pos + decimalSymbol().length()); | ||
1294 | } | ||
1295 | |||
1296 | // Remove thousand separators | ||
1297 | int thlen = thousandsSeparator().length(); | ||
1298 | int lastpos = 0; | ||
1299 | while ( ( pos = major.find( thousandsSeparator() ) ) > 0 ) | ||
1300 | { | ||
1301 | // e.g. 12,,345,,678,,922 Acceptable positions (from the end) are 5, 10, 15... i.e. (3+thlen)*N | ||
1302 | int fromEnd = major.length() - pos; | ||
1303 | if ( fromEnd % (3+thlen) != 0 // Needs to be a multiple, otherwise it's an error | ||
1304 | || pos - lastpos > 3 // More than 3 digits between two separators -> error | ||
1305 | || pos == 0 // Can't start with a separator | ||
1306 | || (lastpos>0 && pos-lastpos!=3)) // Must have exactly 3 digits between two separators | ||
1307 | { | ||
1308 | if (ok) *ok = false; | ||
1309 | return 0.0; | ||
1310 | } | ||
1311 | |||
1312 | lastpos = pos; | ||
1313 | major.remove( pos, thlen ); | ||
1314 | } | ||
1315 | if (lastpos>0 && major.length()-lastpos!=3) // Must have exactly 3 digits after the last separator | ||
1316 | { | ||
1317 | if (ok) *ok = false; | ||
1318 | return 0.0; | ||
1319 | } | ||
1320 | |||
1321 | QString tot; | ||
1322 | if (neg) tot = '-'; | ||
1323 | |||
1324 | tot += major + '.' + minor + exponentialPart; | ||
1325 | |||
1326 | return tot.toDouble(ok); | ||
1327 | } | ||
1328 | |||
1329 | double KLocale::readMoney(const QString &_str, bool * ok) const | ||
1330 | { | ||
1331 | QString str = _str.stripWhiteSpace(); | ||
1332 | bool neg = false; | ||
1333 | bool currencyFound = false; | ||
1334 | // First try removing currency symbol from either end | ||
1335 | int pos = str.find(currencySymbol()); | ||
1336 | if ( pos == 0 || pos == (int) str.length()-1 ) | ||
1337 | { | ||
1338 | str.remove(pos,currencySymbol().length()); | ||
1339 | str = str.stripWhiteSpace(); | ||
1340 | currencyFound = true; | ||
1341 | } | ||
1342 | if (str.isEmpty()) | ||
1343 | { | ||
1344 | if (ok) *ok = false; | ||
1345 | return 0; | ||
1346 | } | ||
1347 | // Then try removing negative sign from either end | ||
1348 | // (with a special case for parenthesis) | ||
1349 | if (negativeMonetarySignPosition() == ParensAround) | ||
1350 | { | ||
1351 | if (str.at(0) == '(' && str.at(str.length()-1) == ')') | ||
1352 | { | ||
1353 | neg = true; | ||
1354 | str.remove(str.length()-1,1); | ||
1355 | str.remove(0,1); | ||
1356 | } | ||
1357 | } | ||
1358 | else | ||
1359 | { | ||
1360 | int i1 = str.find(negativeSign()); | ||
1361 | if ( i1 == 0 || i1 == (int) str.length()-1 ) | ||
1362 | { | ||
1363 | neg = true; | ||
1364 | str.remove(i1,negativeSign().length()); | ||
1365 | } | ||
1366 | } | ||
1367 | if (neg) str = str.stripWhiteSpace(); | ||
1368 | |||
1369 | // Finally try again for the currency symbol, if we didn't find | ||
1370 | // it already (because of the negative sign being in the way). | ||
1371 | if ( !currencyFound ) | ||
1372 | { | ||
1373 | pos = str.find(currencySymbol()); | ||
1374 | if ( pos == 0 || pos == (int) str.length()-1 ) | ||
1375 | { | ||
1376 | str.remove(pos,currencySymbol().length()); | ||
1377 | str = str.stripWhiteSpace(); | ||
1378 | } | ||
1379 | } | ||
1380 | |||
1381 | // And parse the rest as a number | ||
1382 | pos = str.find(monetaryDecimalSymbol()); | ||
1383 | QString major; | ||
1384 | QString minior; | ||
1385 | if (pos == -1) | ||
1386 | major = str; | ||
1387 | else | ||
1388 | { | ||
1389 | major = str.left(pos); | ||
1390 | minior = str.mid(pos + monetaryDecimalSymbol().length()); | ||
1391 | } | ||
1392 | |||
1393 | // Remove thousand separators | ||
1394 | int thlen = monetaryThousandsSeparator().length(); | ||
1395 | int lastpos = 0; | ||
1396 | while ( ( pos = major.find( monetaryThousandsSeparator() ) ) > 0 ) | ||
1397 | { | ||
1398 | // e.g. 12,,345,,678,,922 Acceptable positions (from the end) are 5, 10, 15... i.e. (3+thlen)*N | ||
1399 | int fromEnd = major.length() - pos; | ||
1400 | if ( fromEnd % (3+thlen) != 0 // Needs to be a multiple, otherwise it's an error | ||
1401 | || pos - lastpos > 3 // More than 3 digits between two separators -> error | ||
1402 | || pos == 0 // Can't start with a separator | ||
1403 | || (lastpos>0 && pos-lastpos!=3)) // Must have exactly 3 digits between two separators | ||
1404 | { | ||
1405 | if (ok) *ok = false; | ||
1406 | return 0.0; | ||
1407 | } | ||
1408 | lastpos = pos; | ||
1409 | major.remove( pos, thlen ); | ||
1410 | } | ||
1411 | if (lastpos>0 && major.length()-lastpos!=3) // Must have exactly 3 digits after the last separator | ||
1412 | { | ||
1413 | if (ok) *ok = false; | ||
1414 | return 0.0; | ||
1415 | } | ||
1416 | |||
1417 | QString tot; | ||
1418 | if (neg) tot = '-'; | ||
1419 | tot += major + '.' + minior; | ||
1420 | return tot.toDouble(ok); | ||
1421 | } | ||
1422 | |||
1423 | /** | ||
1424 | * helper function to read integers | ||
1425 | * @param str | ||
1426 | * @param pos the position to start at. It will be updated when we parse it. | ||
1427 | * @return the integer read in the string, or -1 if no string | ||
1428 | */ | ||
1429 | static int readInt(const QString &str, uint &pos) | ||
1430 | { | ||
1431 | if (!str.at(pos).isDigit()) return -1; | ||
1432 | int result = 0; | ||
1433 | for (; str.length() > pos && str.at(pos).isDigit(); pos++) | ||
1434 | { | ||
1435 | result *= 10; | ||
1436 | result += str.at(pos).digitValue(); | ||
1437 | } | ||
1438 | |||
1439 | return result; | ||
1440 | } | ||
1441 | |||
1442 | QDate KLocale::readDate(const QString &intstr, bool* ok) const | ||
1443 | { | ||
1444 | QDate date; | ||
1445 | date = readDate(intstr, ShortFormat, ok); | ||
1446 | if (date.isValid()) return date; | ||
1447 | return readDate(intstr, NormalFormat, ok); | ||
1448 | } | ||
1449 | |||
1450 | QDate KLocale::readDate(const QString &intstr, ReadDateFlags flags, bool* ok) const | ||
1451 | { | ||
1452 | QString fmt = ((flags & ShortFormat) ? dateFormatShort() : dateFormat()).simplifyWhiteSpace(); | ||
1453 | return readDate( intstr, fmt, ok ); | ||
1454 | } | ||
1455 | |||
1456 | QDate KLocale::readDate(const QString &intstr, const QString &fmt, bool* ok) const | ||
1457 | { | ||
1458 | //kdDebug() << "KLocale::readDate intstr=" << intstr << " fmt=" << fmt << endl; | ||
1459 | QString str = intstr.simplifyWhiteSpace().lower(); | ||
1460 | int day = -1, month = -1; | ||
1461 | // allow the year to be omitted if not in the format | ||
1462 | int year = calendar()->year(QDate::currentDate()); | ||
1463 | uint strpos = 0; | ||
1464 | uint fmtpos = 0; | ||
1465 | |||
1466 | bool error = false; | ||
1467 | |||
1468 | while (fmt.length() > fmtpos && str.length() > strpos && !error) | ||
1469 | { | ||
1470 | |||
1471 | QChar c = fmt.at(fmtpos++); | ||
1472 | |||
1473 | if (c != '%') { | ||
1474 | if (c.isSpace() && str.at(strpos).isSpace()) | ||
1475 | strpos++; | ||
1476 | else if (c != str.at(strpos++)) | ||
1477 | error = true; | ||
1478 | } | ||
1479 | else | ||
1480 | { | ||
1481 | int j; | ||
1482 | // remove space at the begining | ||
1483 | if (str.length() > strpos && str.at(strpos).isSpace()) | ||
1484 | strpos++; | ||
1485 | |||
1486 | c = fmt.at(fmtpos++); | ||
1487 | switch (c) | ||
1488 | { | ||
1489 | case 'a': | ||
1490 | case 'A': | ||
1491 | |||
1492 | error = true; | ||
1493 | j = 1; | ||
1494 | while (error && (j < 8)) { | ||
1495 | QString s = weekDayName(j, c == 'a').lower(); | ||
1496 | int len = s.length(); | ||
1497 | if (str.mid(strpos, len) == s) | ||
1498 | { | ||
1499 | strpos += len; | ||
1500 | error = false; | ||
1501 | } | ||
1502 | j++; | ||
1503 | } | ||
1504 | break; | ||
1505 | case 'b': | ||
1506 | case 'B': | ||
1507 | |||
1508 | error = true; | ||
1509 | if (d->nounDeclension && d->dateMonthNamePossessive) { | ||
1510 | j = 1; | ||
1511 | while (error && (j < 13)) { | ||
1512 | //US QString s = calendar()->monthNamePossessive(j, year, c == 'b').lower(); | ||
1513 | QString s = calendar()->monthNamePossessive(j, c == 'b').lower(); | ||
1514 | int len = s.length(); | ||
1515 | if (str.mid(strpos, len) == s) { | ||
1516 | month = j; | ||
1517 | strpos += len; | ||
1518 | error = false; | ||
1519 | } | ||
1520 | j++; | ||
1521 | } | ||
1522 | } | ||
1523 | j = 1; | ||
1524 | while (error && (j < 13)) { | ||
1525 | //US QString s = calendar()->monthName(j, year, c == 'b').lower(); | ||
1526 | QString s = calendar()->monthName(j, c == 'b').lower(); | ||
1527 | int len = s.length(); | ||
1528 | if (str.mid(strpos, len) == s) { | ||
1529 | month = j; | ||
1530 | strpos += len; | ||
1531 | error = false; | ||
1532 | } | ||
1533 | j++; | ||
1534 | } | ||
1535 | break; | ||
1536 | case 'd': | ||
1537 | case 'e': | ||
1538 | day = readInt(str, strpos); | ||
1539 | error = (day < 1 || day > 31); | ||
1540 | break; | ||
1541 | |||
1542 | case 'n': | ||
1543 | case 'm': | ||
1544 | month = readInt(str, strpos); | ||
1545 | error = (month < 1 || month > 12); | ||
1546 | break; | ||
1547 | |||
1548 | case 'Y': | ||
1549 | case 'y': | ||
1550 | year = readInt(str, strpos); | ||
1551 | error = (year < 0); | ||
1552 | // Qt treats a year in the range 0-100 as 1900-1999. | ||
1553 | // It is nicer for the user if we treat 0-68 as 2000-2068 | ||
1554 | if (c == 'y' && year < 69) | ||
1555 | // eg. gregorian += 2000 | ||
1556 | year += (calendar()->year(QDate::currentDate()) / 100) * 100; | ||
1557 | else if (c == 'y' && year < 100) | ||
1558 | // eg. gregorian += 1900 | ||
1559 | year += (calendar()->year(QDate::currentDate()) / 100) * 100 - 100; | ||
1560 | break; | ||
1561 | } | ||
1562 | } | ||
1563 | } | ||
1564 | |||
1565 | /* for a match, we should reach the end of both strings, not just one of | ||
1566 | them */ | ||
1567 | if ( fmt.length() > fmtpos || str.length() > strpos ) | ||
1568 | { | ||
1569 | error = true; | ||
1570 | } | ||
1571 | |||
1572 | //kdDebug(173) << "KLocale::readDate day=" << day << " month=" << month << " year=" << year << endl; | ||
1573 | if ( year != -1 && month != -1 && day != -1 && !error) | ||
1574 | { | ||
1575 | if (ok) *ok = true; | ||
1576 | |||
1577 | QDate result; | ||
1578 | calendar()->setYMD(result, year, month, day); | ||
1579 | |||
1580 | return result; | ||
1581 | } | ||
1582 | else | ||
1583 | { | ||
1584 | if (ok) *ok = false; | ||
1585 | return QDate(); // invalid date | ||
1586 | } | ||
1587 | } | ||
1588 | |||
1589 | QTime KLocale::readTime(const QString &intstr, bool *ok) const | ||
1590 | { | ||
1591 | QTime _time; | ||
1592 | _time = readTime(intstr, WithSeconds, ok); | ||
1593 | if (_time.isValid()) return _time; | ||
1594 | return readTime(intstr, WithoutSeconds, ok); | ||
1595 | } | ||
1596 | |||
1597 | QTime KLocale::readTime(const QString &intstr, ReadTimeFlags flags, bool *ok) const | ||
1598 | { | ||
1599 | QString str = intstr.simplifyWhiteSpace().lower(); | ||
1600 | QString Format = timeFormat().simplifyWhiteSpace(); | ||
1601 | if (flags & WithoutSeconds) | ||
1602 | { | ||
1603 | //US remove not available in my QT version | ||
1604 | //US Format.remove(QRegExp(".%S")); | ||
1605 | Format.replace(QRegExp(".%S"), ""); | ||
1606 | } | ||
1607 | |||
1608 | int hour = -1, minute = -1; | ||
1609 | int second = ( (flags & WithoutSeconds) == 0 ) ? -1 : 0; // don't require seconds | ||
1610 | bool g_12h = false; | ||
1611 | bool pm = false; | ||
1612 | uint strpos = 0; | ||
1613 | uint Formatpos = 0; | ||
1614 | |||
1615 | while (Format.length() > Formatpos || str.length() > strpos) | ||
1616 | { | ||
1617 | if ( !(Format.length() > Formatpos && str.length() > strpos) ) goto error; | ||
1618 | |||
1619 | QChar c = Format.at(Formatpos++); | ||
1620 | |||
1621 | if (c != '%') | ||
1622 | { | ||
1623 | if (c.isSpace()) | ||
1624 | strpos++; | ||
1625 | else if (c != str.at(strpos++)) | ||
1626 | goto error; | ||
1627 | continue; | ||
1628 | } | ||
1629 | |||
1630 | // remove space at the begining | ||
1631 | if (str.length() > strpos && str.at(strpos).isSpace()) | ||
1632 | strpos++; | ||
1633 | |||
1634 | c = Format.at(Formatpos++); | ||
1635 | switch (c) | ||
1636 | { | ||
1637 | case 'p': | ||
1638 | { | ||
1639 | QString s; | ||
1640 | s = translate("pm").lower(); | ||
1641 | int len = s.length(); | ||
1642 | if (str.mid(strpos, len) == s) | ||
1643 | { | ||
1644 | pm = true; | ||
1645 | strpos += len; | ||
1646 | } | ||
1647 | else | ||
1648 | { | ||
1649 | s = translate("am").lower(); | ||
1650 | len = s.length(); | ||
1651 | if (str.mid(strpos, len) == s) { | ||
1652 | pm = false; | ||
1653 | strpos += len; | ||
1654 | } | ||
1655 | else | ||
1656 | goto error; | ||
1657 | } | ||
1658 | } | ||
1659 | break; | ||
1660 | |||
1661 | case 'k': | ||
1662 | case 'H': | ||
1663 | g_12h = false; | ||
1664 | hour = readInt(str, strpos); | ||
1665 | if (hour < 0 || hour > 23) | ||
1666 | goto error; | ||
1667 | |||
1668 | break; | ||
1669 | |||
1670 | case 'l': | ||
1671 | case 'I': | ||
1672 | g_12h = true; | ||
1673 | hour = readInt(str, strpos); | ||
1674 | if (hour < 1 || hour > 12) | ||
1675 | goto error; | ||
1676 | |||
1677 | break; | ||
1678 | |||
1679 | case 'M': | ||
1680 | minute = readInt(str, strpos); | ||
1681 | if (minute < 0 || minute > 59) | ||
1682 | goto error; | ||
1683 | |||
1684 | break; | ||
1685 | |||
1686 | case 'S': | ||
1687 | second = readInt(str, strpos); | ||
1688 | if (second < 0 || second > 59) | ||
1689 | goto error; | ||
1690 | |||
1691 | break; | ||
1692 | } | ||
1693 | } | ||
1694 | if (g_12h) { | ||
1695 | hour %= 12; | ||
1696 | if (pm) hour += 12; | ||
1697 | } | ||
1698 | |||
1699 | if (ok) *ok = true; | ||
1700 | return QTime(hour, minute, second); | ||
1701 | |||
1702 | error: | ||
1703 | if (ok) *ok = false; | ||
1704 | return QTime(-1, -1, -1); // return invalid date if it didn't work | ||
1705 | } | ||
1706 | |||
1707 | QString KLocale::formatTime(const QTime &pTime, bool includeSecs) const | ||
1708 | { | ||
1709 | const QString rst = timeFormat(); | ||
1710 | |||
1711 | // only "pm/am" here can grow, the rest shrinks, but | ||
1712 | // I'm rather safe than sorry | ||
1713 | QChar *buffer = new QChar[rst.length() * 3 / 2 + 30]; | ||
1714 | |||
1715 | uint index = 0; | ||
1716 | bool escape = false; | ||
1717 | int number = 0; | ||
1718 | |||
1719 | for ( uint format_index = 0; format_index < rst.length(); format_index++ ) | ||
1720 | { | ||
1721 | if ( !escape ) | ||
1722 | { | ||
1723 | if ( rst.at( format_index ).unicode() == '%' ) | ||
1724 | escape = true; | ||
1725 | else | ||
1726 | buffer[index++] = rst.at( format_index ); | ||
1727 | } | ||
1728 | else | ||
1729 | { | ||
1730 | switch ( rst.at( format_index ).unicode() ) | ||
1731 | { | ||
1732 | case '%': | ||
1733 | buffer[index++] = '%'; | ||
1734 | break; | ||
1735 | case 'H': | ||
1736 | put_it_in( buffer, index, pTime.hour() ); | ||
1737 | break; | ||
1738 | case 'I': | ||
1739 | put_it_in( buffer, index, ( pTime.hour() + 11) % 12 + 1 ); | ||
1740 | break; | ||
1741 | case 'M': | ||
1742 | put_it_in( buffer, index, pTime.minute() ); | ||
1743 | break; | ||
1744 | case 'S': | ||
1745 | if (includeSecs) | ||
1746 | put_it_in( buffer, index, pTime.second() ); | ||
1747 | else if ( index > 0 ) | ||
1748 | { | ||
1749 | // we remove the seperator sign before the seconds and | ||
1750 | // assume that works everywhere | ||
1751 | --index; | ||
1752 | break; | ||
1753 | } | ||
1754 | break; | ||
1755 | case 'k': | ||
1756 | number = pTime.hour(); | ||
1757 | case 'l': | ||
1758 | // to share the code | ||
1759 | if ( rst.at( format_index ).unicode() == 'l' ) | ||
1760 | number = (pTime.hour() + 11) % 12 + 1; | ||
1761 | if ( number / 10 ) | ||
1762 | buffer[index++] = number / 10 + '0'; | ||
1763 | buffer[index++] = number % 10 + '0'; | ||
1764 | break; | ||
1765 | case 'p': | ||
1766 | { | ||
1767 | QString s; | ||
1768 | if ( pTime.hour() >= 12 ) | ||
1769 | put_it_in( buffer, index, translate("pm") ); | ||
1770 | else | ||
1771 | put_it_in( buffer, index, translate("am") ); | ||
1772 | break; | ||
1773 | } | ||
1774 | default: | ||
1775 | buffer[index++] = rst.at( format_index ); | ||
1776 | break; | ||
1777 | } | ||
1778 | escape = false; | ||
1779 | } | ||
1780 | } | ||
1781 | QString ret( buffer, index ); | ||
1782 | delete [] buffer; | ||
1783 | return ret; | ||
1784 | } | ||
1785 | |||
1786 | bool KLocale::use12Clock() const | ||
1787 | { | ||
1788 | if ((timeFormat().contains(QString::fromLatin1("%I")) > 0) || | ||
1789 | (timeFormat().contains(QString::fromLatin1("%l")) > 0)) | ||
1790 | return true; | ||
1791 | else | ||
1792 | return false; | ||
1793 | } | ||
1794 | |||
1795 | QString KLocale::languages() const | ||
1796 | { | ||
1797 | return d->languageList.join( QString::fromLatin1(":") ); | ||
1798 | } | ||
1799 | |||
1800 | QStringList KLocale::languageList() const | ||
1801 | { | ||
1802 | return d->languageList; | ||
1803 | } | ||
1804 | |||
1805 | QString KLocale::formatDateTime(const QDateTime &pDateTime, | ||
1806 | bool shortFormat, | ||
1807 | bool includeSeconds) const | ||
1808 | { | ||
1809 | return translate("concatenation of dates and time", "%1 %2") | ||
1810 | .arg( formatDate( pDateTime.date(), shortFormat ) ) | ||
1811 | .arg( formatTime( pDateTime.time(), includeSeconds ) ); | ||
1812 | } | ||
1813 | |||
1814 | QString i18n(const char* text) | ||
1815 | { | ||
1816 | /* | ||
1817 | register KLocale *instance = KGlobal::locale(); | ||
1818 | if (instance) | ||
1819 | return instance->translate(text); | ||
1820 | */ | ||
1821 | return QString::fromUtf8(text); | ||
1822 | } | ||
1823 | |||
1824 | QString i18n(const char* index, const char *text) | ||
1825 | { | ||
1826 | /* | ||
1827 | register KLocale *instance = KGlobal::locale(); | ||
1828 | if (instance) | ||
1829 | return instance->translate(index, text); | ||
1830 | */ | ||
1831 | return QString::fromUtf8(text); | ||
1832 | } | ||
1833 | |||
1834 | QString i18n(const char* singular, const char* plural, unsigned long n) | ||
1835 | { | ||
1836 | return (QString::fromUtf8(plural)); // hack! remove this line! | ||
1837 | register KLocale *instance = KGlobal::locale(); | ||
1838 | if (instance) | ||
1839 | return instance->translate(singular, plural, n); | ||
1840 | if (n == 1) | ||
1841 | return put_n_in(QString::fromUtf8(singular), n); | ||
1842 | else | ||
1843 | return put_n_in(QString::fromUtf8(plural), n); | ||
1844 | } | ||
1845 | |||
1846 | void KLocale::initInstance() | ||
1847 | { | ||
1848 | if (KGlobal::locale()) | ||
1849 | return; | ||
1850 | |||
1851 | /*US lets change the whole way how to create a KLocale | ||
1852 | KInstance *app = KGlobal::instance(); | ||
1853 | if (app) { | ||
1854 | KGlobal::_locale = new KLocale(QString::fromLatin1(app->instanceName())); | ||
1855 | |||
1856 | // only do this for the global instance | ||
1857 | QTextCodec::setCodecForLocale(KGlobal::_locale->codecForEncoding()); | ||
1858 | } | ||
1859 | else | ||
1860 | kdDebug(173) << "no app name available using KLocale - nothing to do\n"; | ||
1861 | */ | ||
1862 | //US new implementation | ||
1863 | QString appname = KGlobal::getAppName(); | ||
1864 | if (appname) { | ||
1865 | KLocale *l = new KLocale(appname); | ||
1866 | KGlobal::setLocale(l); | ||
1867 | |||
1868 | // only do this for the global instance | ||
1869 | //US | ||
1870 | //US QTextCodec::setCodecForLocale(KGlobal::locale())->codecForEncoding()); | ||
1871 | //US qt_set_locale_codec( KGlobal::locale()->codecForEncoding() ); | ||
1872 | qDebug("KLocale::initInstance we have to do here something !!!"); | ||
1873 | } | ||
1874 | else | ||
1875 | kdDebug(173) << "no app name available using KLocale - nothing to do\n"; | ||
1876 | |||
1877 | } | ||
1878 | |||
1879 | QString KLocale::langLookup(const QString &fname, const char *rtype) | ||
1880 | { | ||
1881 | QStringList search; | ||
1882 | |||
1883 | // assemble the local search paths | ||
1884 | //US we have only one resourcedir. So use it !! | ||
1885 | /*US original | ||
1886 | const QStringList localDoc = KGlobal::dirs()->resourceDirs(rtype); | ||
1887 | // look up the different languages | ||
1888 | for (int id=localDoc.count()-1; id >= 0; --id) | ||
1889 | { | ||
1890 | QStringList langs = KGlobal::locale()->languageList(); | ||
1891 | langs.append( "en" ); | ||
1892 | langs.remove( defaultLanguage() ); | ||
1893 | QStringList::ConstIterator lang; | ||
1894 | for (lang = langs.begin(); lang != langs.end(); ++lang) | ||
1895 | search.append(QString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(fname)); | ||
1896 | } | ||
1897 | */ | ||
1898 | //US new code | ||
1899 | //US What is here correct??? const QString localDoc = KGlobal::dirs()->findResourceDir(rtype); | ||
1900 | const QString localDoc = rtype; | ||
1901 | // look up the different languages | ||
1902 | QStringList langs = KGlobal::locale()->languageList(); | ||
1903 | langs.append( "en" ); | ||
1904 | langs.remove( defaultLanguage() ); | ||
1905 | QStringList::ConstIterator lang; | ||
1906 | for (lang = langs.begin(); lang != langs.end(); ++lang) | ||
1907 | search.append(QString("%1%2/%3").arg(localDoc).arg(*lang).arg(fname)); | ||
1908 | |||
1909 | // try to locate the file | ||
1910 | QStringList::Iterator it; | ||
1911 | for (it = search.begin(); it != search.end(); ++it) | ||
1912 | { | ||
1913 | kdDebug(173) << "Looking for help in: " << *it << endl; | ||
1914 | |||
1915 | QFileInfo info(*it); | ||
1916 | if (info.exists() && info.isFile() && info.isReadable()) | ||
1917 | return *it; | ||
1918 | } | ||
1919 | |||
1920 | return QString::null; | ||
1921 | } | ||
1922 | |||
1923 | bool KLocale::useDefaultLanguage() const | ||
1924 | { | ||
1925 | return language() == defaultLanguage(); | ||
1926 | } | ||
1927 | |||
1928 | void KLocale::initEncoding(KConfig *) | ||
1929 | { | ||
1930 | const int mibDefault = 4; // ISO 8859-1 | ||
1931 | |||
1932 | // This all made more sense when we still had the EncodingEnum config key. | ||
1933 | setEncoding( QTextCodec::codecForLocale()->mibEnum() ); | ||
1934 | |||
1935 | if ( !d->codecForEncoding ) | ||
1936 | { | ||
1937 | kdWarning(173) << " Defaulting to ISO 8859-1 encoding." << endl; | ||
1938 | setEncoding(mibDefault); | ||
1939 | } | ||
1940 | |||
1941 | ASSERT( d->codecForEncoding ); | ||
1942 | } | ||
1943 | |||
1944 | void KLocale::initFileNameEncoding(KConfig *) | ||
1945 | { | ||
1946 | // If the following environment variable is set, assume all filenames | ||
1947 | // are in UTF-8 regardless of the current C locale. | ||
1948 | d->utf8FileEncoding = getenv("KDE_UTF8_FILENAMES") != 0; | ||
1949 | if (d->utf8FileEncoding) | ||
1950 | { | ||
1951 | QFile::setEncodingFunction(KLocale::encodeFileNameUTF8); | ||
1952 | QFile::setDecodingFunction(KLocale::decodeFileNameUTF8); | ||
1953 | } | ||
1954 | // Otherwise, stay with QFile's default filename encoding functions | ||
1955 | // which, on Unix platforms, use the locale's codec. | ||
1956 | } | ||
1957 | |||
1958 | QCString KLocale::encodeFileNameUTF8( const QString & fileName ) | ||
1959 | { | ||
1960 | return fileName.utf8(); | ||
1961 | } | ||
1962 | |||
1963 | QString KLocale::decodeFileNameUTF8( const QCString & localFileName ) | ||
1964 | { | ||
1965 | return QString::fromUtf8(localFileName); | ||
1966 | } | ||
1967 | |||
1968 | void KLocale::initCatalogue( KCatalogue & catalogue ) | ||
1969 | { | ||
1970 | catalogue.setFileName( catalogueFileName( language(), catalogue ) ); | ||
1971 | } | ||
1972 | |||
1973 | void KLocale::setDateFormat(const QString & format) | ||
1974 | { | ||
1975 | doFormatInit(); | ||
1976 | m_dateFormat = format.stripWhiteSpace(); | ||
1977 | } | ||
1978 | |||
1979 | void KLocale::setDateFormatShort(const QString & format) | ||
1980 | { | ||
1981 | doFormatInit(); | ||
1982 | m_dateFormatShort = format.stripWhiteSpace(); | ||
1983 | } | ||
1984 | |||
1985 | void KLocale::setDateMonthNamePossessive(bool possessive) | ||
1986 | { | ||
1987 | doFormatInit(); | ||
1988 | d->dateMonthNamePossessive = possessive; | ||
1989 | } | ||
1990 | |||
1991 | void KLocale::setTimeFormat(const QString & format) | ||
1992 | { | ||
1993 | doFormatInit(); | ||
1994 | m_timeFormat = format.stripWhiteSpace(); | ||
1995 | } | ||
1996 | |||
1997 | void KLocale::setWeekStartsMonday(bool start) //deprecated | ||
1998 | { | ||
1999 | doFormatInit(); | ||
2000 | if (start) | ||
2001 | d->weekStartDay = 1; | ||
2002 | else | ||
2003 | d->weekStartDay = 7; | ||
2004 | } | ||
2005 | |||
2006 | void KLocale::setWeekStartDay(int day) | ||
2007 | { | ||
2008 | doFormatInit(); | ||
2009 | if (day>7 || day<1) | ||
2010 | d->weekStartDay = 1; //Monday is default | ||
2011 | else | ||
2012 | d->weekStartDay = day; | ||
2013 | } | ||
2014 | |||
2015 | QString KLocale::dateFormat() const | ||
2016 | { | ||
2017 | doFormatInit(); | ||
2018 | return m_dateFormat; | ||
2019 | } | ||
2020 | |||
2021 | QString KLocale::dateFormatShort() const | ||
2022 | { | ||
2023 | doFormatInit(); | ||
2024 | return m_dateFormatShort; | ||
2025 | } | ||
2026 | |||
2027 | QString KLocale::timeFormat() const | ||
2028 | { | ||
2029 | doFormatInit(); | ||
2030 | return m_timeFormat; | ||
2031 | } | ||
2032 | |||
2033 | void KLocale::setDecimalSymbol(const QString & symbol) | ||
2034 | { | ||
2035 | doFormatInit(); | ||
2036 | m_decimalSymbol = symbol.stripWhiteSpace(); | ||
2037 | } | ||
2038 | |||
2039 | void KLocale::setThousandsSeparator(const QString & separator) | ||
2040 | { | ||
2041 | doFormatInit(); | ||
2042 | // allow spaces here | ||
2043 | m_thousandsSeparator = separator; | ||
2044 | } | ||
2045 | |||
2046 | void KLocale::setPositiveSign(const QString & sign) | ||
2047 | { | ||
2048 | doFormatInit(); | ||
2049 | m_positiveSign = sign.stripWhiteSpace(); | ||
2050 | } | ||
2051 | |||
2052 | void KLocale::setNegativeSign(const QString & sign) | ||
2053 | { | ||
2054 | doFormatInit(); | ||
2055 | m_negativeSign = sign.stripWhiteSpace(); | ||
2056 | } | ||
2057 | |||
2058 | void KLocale::setPositiveMonetarySignPosition(SignPosition signpos) | ||
2059 | { | ||
2060 | doFormatInit(); | ||
2061 | m_positiveMonetarySignPosition = signpos; | ||
2062 | } | ||
2063 | |||
2064 | void KLocale::setNegativeMonetarySignPosition(SignPosition signpos) | ||
2065 | { | ||
2066 | doFormatInit(); | ||
2067 | m_negativeMonetarySignPosition = signpos; | ||
2068 | } | ||
2069 | |||
2070 | void KLocale::setPositivePrefixCurrencySymbol(bool prefix) | ||
2071 | { | ||
2072 | doFormatInit(); | ||
2073 | m_positivePrefixCurrencySymbol = prefix; | ||
2074 | } | ||
2075 | |||
2076 | void KLocale::setNegativePrefixCurrencySymbol(bool prefix) | ||
2077 | { | ||
2078 | doFormatInit(); | ||
2079 | m_negativePrefixCurrencySymbol = prefix; | ||
2080 | } | ||
2081 | |||
2082 | void KLocale::setFracDigits(int digits) | ||
2083 | { | ||
2084 | doFormatInit(); | ||
2085 | m_fracDigits = digits; | ||
2086 | } | ||
2087 | |||
2088 | void KLocale::setMonetaryThousandsSeparator(const QString & separator) | ||
2089 | { | ||
2090 | doFormatInit(); | ||
2091 | // allow spaces here | ||
2092 | m_monetaryThousandsSeparator = separator; | ||
2093 | } | ||
2094 | |||
2095 | void KLocale::setMonetaryDecimalSymbol(const QString & symbol) | ||
2096 | { | ||
2097 | doFormatInit(); | ||
2098 | m_monetaryDecimalSymbol = symbol.stripWhiteSpace(); | ||
2099 | } | ||
2100 | |||
2101 | void KLocale::setCurrencySymbol(const QString & symbol) | ||
2102 | { | ||
2103 | doFormatInit(); | ||
2104 | m_currencySymbol = symbol.stripWhiteSpace(); | ||
2105 | } | ||
2106 | |||
2107 | int KLocale::pageSize() const | ||
2108 | { | ||
2109 | doFormatInit(); | ||
2110 | return d->pageSize; | ||
2111 | } | ||
2112 | |||
2113 | void KLocale::setPageSize(int pageSize) | ||
2114 | { | ||
2115 | // #### check if it's in range?? | ||
2116 | doFormatInit(); | ||
2117 | d->pageSize = pageSize; | ||
2118 | } | ||
2119 | |||
2120 | KLocale::MeasureSystem KLocale::measureSystem() const | ||
2121 | { | ||
2122 | doFormatInit(); | ||
2123 | return d->measureSystem; | ||
2124 | } | ||
2125 | |||
2126 | void KLocale::setMeasureSystem(MeasureSystem value) | ||
2127 | { | ||
2128 | doFormatInit(); | ||
2129 | d->measureSystem = value; | ||
2130 | } | ||
2131 | |||
2132 | QString KLocale::defaultLanguage() | ||
2133 | { | ||
2134 | return QString::fromLatin1("en_US"); | ||
2135 | } | ||
2136 | |||
2137 | QString KLocale::defaultCountry() | ||
2138 | { | ||
2139 | return QString::fromLatin1("C"); | ||
2140 | } | ||
2141 | |||
2142 | const char * KLocale::encoding() const | ||
2143 | { | ||
2144 | return codecForEncoding()->name(); | ||
2145 | } | ||
2146 | |||
2147 | int KLocale::encodingMib() const | ||
2148 | { | ||
2149 | return codecForEncoding()->mibEnum(); | ||
2150 | } | ||
2151 | |||
2152 | int KLocale::fileEncodingMib() const | ||
2153 | { | ||
2154 | if (d->utf8FileEncoding) | ||
2155 | return 106; | ||
2156 | return codecForEncoding()->mibEnum(); | ||
2157 | } | ||
2158 | |||
2159 | QTextCodec * KLocale::codecForEncoding() const | ||
2160 | { | ||
2161 | return d->codecForEncoding; | ||
2162 | } | ||
2163 | |||
2164 | bool KLocale::setEncoding(int mibEnum) | ||
2165 | { | ||
2166 | QTextCodec * codec = QTextCodec::codecForMib(mibEnum); | ||
2167 | if (codec) | ||
2168 | d->codecForEncoding = codec; | ||
2169 | |||
2170 | return codec != 0; | ||
2171 | } | ||
2172 | |||
2173 | QStringList KLocale::languagesTwoAlpha() const | ||
2174 | { | ||
2175 | if (d->langTwoAlpha.count()) | ||
2176 | return d->langTwoAlpha; | ||
2177 | |||
2178 | const QStringList &origList = languageList(); | ||
2179 | |||
2180 | QStringList result; | ||
2181 | |||
2182 | //US KConfig config(QString::fromLatin1("language.codes"), true, false); | ||
2183 | KConfig config(locateLocal("config", QString::fromLatin1("language.codes"))); | ||
2184 | config.setGroup("TwoLetterCodes"); | ||
2185 | |||
2186 | for ( QStringList::ConstIterator it = origList.begin(); | ||
2187 | it != origList.end(); | ||
2188 | ++it ) | ||
2189 | { | ||
2190 | QString lang = *it; | ||
2191 | QStringList langLst; | ||
2192 | |||
2193 | /*US I changed the following code, because hasKey is not available. | ||
2194 | !!! check if my version is correct | ||
2195 | if (config.hasKey( lang )) | ||
2196 | langLst = config.readListEntry( lang ); | ||
2197 | else | ||
2198 | { | ||
2199 | int i = lang.find('_'); | ||
2200 | if (i >= 0) | ||
2201 | lang.truncate(i); | ||
2202 | langLst << lang; | ||
2203 | } | ||
2204 | */ | ||
2205 | langLst = config.readListEntry( lang ); | ||
2206 | if (langLst.isEmpty()) | ||
2207 | { | ||
2208 | int i = lang.find('_'); | ||
2209 | if (i >= 0) | ||
2210 | lang.truncate(i); | ||
2211 | langLst << lang; | ||
2212 | } | ||
2213 | |||
2214 | |||
2215 | for ( QStringList::ConstIterator langIt = langLst.begin(); | ||
2216 | langIt != langLst.end(); | ||
2217 | ++langIt ) | ||
2218 | { | ||
2219 | if ( !(*langIt).isEmpty() && !result.contains( *langIt ) ) | ||
2220 | result += *langIt; | ||
2221 | } | ||
2222 | } | ||
2223 | d->langTwoAlpha = result; | ||
2224 | return result; | ||
2225 | } | ||
2226 | |||
2227 | QStringList KLocale::allLanguagesTwoAlpha() const | ||
2228 | { | ||
2229 | if (!d->languages) | ||
2230 | //US d->languages = new KConfig("all_languages", true, false, "locale"); | ||
2231 | d->languages = new KConfig(locateLocal( "locale", "all_languages")); | ||
2232 | |||
2233 | //US return d->languages->groupList(); | ||
2234 | qDebug("KLocale::allLanguagesTwoAlpha has to be fixed."); | ||
2235 | return *(new QStringList()); | ||
2236 | |||
2237 | } | ||
2238 | |||
2239 | QString KLocale::twoAlphaToLanguageName(const QString &code) const | ||
2240 | { | ||
2241 | if (!d->languages) | ||
2242 | //US d->languages = new KConfig("all_languages", true, false, "locale"); | ||
2243 | d->languages = new KConfig(locateLocal( "locale", "all_languages")); | ||
2244 | |||
2245 | d->languages->setGroup(code.lower()); | ||
2246 | return d->languages->readEntry("Name"); | ||
2247 | } | ||
2248 | |||
2249 | QStringList KLocale::allCountriesTwoAlpha() const | ||
2250 | { | ||
2251 | QStringList countries; | ||
2252 | |||
2253 | qDebug("KLocale::allCountriesTwoAlpha has to be fixed."); | ||
2254 | //US QStringList paths = KGlobal::dirs()->findAllResources("locale", "l10n/*/entry.desktop"); | ||
2255 | QStringList paths = KGlobal::dirs()->findAllResources("locale", "l10n/*/entry.desktop", true, true); | ||
2256 | |||
2257 | for(QStringList::ConstIterator it = paths.begin(); | ||
2258 | it != paths.end(); ++it) | ||
2259 | { | ||
2260 | QString code = (*it).mid((*it).length()-16, 2); | ||
2261 | if (code != "/C") | ||
2262 | countries.append(code); | ||
2263 | } | ||
2264 | return countries; | ||
2265 | } | ||
2266 | |||
2267 | QString KLocale::twoAlphaToCountryName(const QString &code) const | ||
2268 | { | ||
2269 | //US KConfig cfg("l10n/"+code.lower()+"/entry.desktop", true, false, "locale"); | ||
2270 | KConfig cfg(locateLocal("locale", "l10n/"+code.lower()+"/entry.desktop")); | ||
2271 | cfg.setGroup("KCM Locale"); | ||
2272 | return cfg.readEntry("Name"); | ||
2273 | } | ||
2274 | |||
2275 | void KLocale::setCalendar(const QString & calType) | ||
2276 | { | ||
2277 | doFormatInit(); | ||
2278 | |||
2279 | d->calendarType = calType; | ||
2280 | |||
2281 | delete d->calendar; | ||
2282 | d->calendar = 0; | ||
2283 | } | ||
2284 | |||
2285 | QString KLocale::calendarType() const | ||
2286 | { | ||
2287 | doFormatInit(); | ||
2288 | |||
2289 | return d->calendarType; | ||
2290 | } | ||
2291 | |||
2292 | const KCalendarSystem * KLocale::calendar() const | ||
2293 | { | ||
2294 | doFormatInit(); | ||
2295 | |||
2296 | // Check if it's the correct calendar?!? | ||
2297 | //US we are always using the gregorian calendar | ||
2298 | //US if ( !d->calendar ) | ||
2299 | //US d->calendar = KCalendarSystemFactory::create( d->calendarType, this ); | ||
2300 | if ( !d->calendar ) | ||
2301 | d->calendar = new KCalendarSystemGregorian; | ||
2302 | |||
2303 | return d->calendar; | ||
2304 | } | ||
2305 | |||
2306 | KLocale::KLocale(const KLocale & rhs) | ||
2307 | { | ||
2308 | d = new KLocalePrivate; | ||
2309 | |||
2310 | *this = rhs; | ||
2311 | } | ||
2312 | |||
2313 | KLocale & KLocale::operator=(const KLocale & rhs) | ||
2314 | { | ||
2315 | // Numbers and money | ||
2316 | m_decimalSymbol = rhs.m_decimalSymbol; | ||
2317 | m_thousandsSeparator = rhs.m_thousandsSeparator; | ||
2318 | m_currencySymbol = rhs.m_currencySymbol; | ||
2319 | m_monetaryDecimalSymbol = rhs.m_monetaryDecimalSymbol; | ||
2320 | m_monetaryThousandsSeparator = rhs.m_monetaryThousandsSeparator; | ||
2321 | m_positiveSign = rhs.m_positiveSign; | ||
2322 | m_negativeSign = rhs.m_negativeSign; | ||
2323 | m_fracDigits = rhs.m_fracDigits; | ||
2324 | m_positivePrefixCurrencySymbol = rhs.m_positivePrefixCurrencySymbol; | ||
2325 | m_negativePrefixCurrencySymbol = rhs.m_negativePrefixCurrencySymbol; | ||
2326 | m_positiveMonetarySignPosition = rhs.m_positiveMonetarySignPosition; | ||
2327 | m_negativeMonetarySignPosition = rhs.m_negativeMonetarySignPosition; | ||
2328 | |||
2329 | // Date and time | ||
2330 | m_timeFormat = rhs.m_timeFormat; | ||
2331 | m_dateFormat = rhs.m_dateFormat; | ||
2332 | m_dateFormatShort = rhs.m_dateFormatShort; | ||
2333 | |||
2334 | m_language = rhs.m_language; | ||
2335 | m_country = rhs.m_country; | ||
2336 | |||
2337 | // the assignment operator works here | ||
2338 | *d = *rhs.d; | ||
2339 | d->languages = 0; // Don't copy languages | ||
2340 | d->calendar = 0; // Don't copy the calendar | ||
2341 | |||
2342 | return *this; | ||
2343 | } | ||
2344 | |||
2345 | bool KLocale::setCharset(const QString & ) { return true; } | ||
2346 | QString KLocale::charset() const { return QString::fromLatin1("UTF-8"); } | ||
2347 | |||
2348 | |||
2349 | int KLocale::timezoneOffset( QString timeZone ) | ||
2350 | { | ||
2351 | int ret = 1001; | ||
2352 | int index = mTimeZoneList.findIndex( timeZone ); | ||
2353 | if ( index < 24 ) | ||
2354 | ret = ( index-11 ) * 60 ; | ||
2355 | return ret; | ||
2356 | } | ||
2357 | |||
2358 | QStringList KLocale::timeZoneList() const | ||
2359 | { | ||
2360 | return mTimeZoneList; | ||
2361 | } | ||
2362 | void KLocale::setTimezone( const QString &timeZone ) | ||
2363 | { | ||
2364 | mTimeZoneOffset = timezoneOffset( timeZone ); | ||
2365 | } | ||
2366 | |||
2367 | void KLocale::setDaylightSaving( bool b, int start , int end ) | ||
2368 | { | ||
2369 | daylightEnabled = b; | ||
2370 | daylightStart = start; | ||
2371 | daylightEnd = end; | ||
2372 | mSouthDaylight = (end < start); | ||
2373 | // qDebug("klocale daylight %d %d %d ", b, start , end ); | ||
2374 | } | ||
2375 | |||
2376 | int KLocale::localTimeOffset( const QDateTime &dt ) | ||
2377 | { | ||
2378 | bool addDaylight = false; | ||
2379 | if ( daylightEnabled ) { | ||
2380 | int d_end, d_start; | ||
2381 | int dayofyear = dt.date().dayOfYear(); | ||
2382 | int year = dt.date().year(); | ||
2383 | int add = 0; | ||
2384 | if ( QDate::leapYear(year) ) | ||
2385 | add = 1; | ||
2386 | QDate date ( year,1,1 ); | ||
2387 | if ( daylightEnd > 59 ) | ||
2388 | d_end = daylightEnd +add; | ||
2389 | else | ||
2390 | d_end = daylightEnd; | ||
2391 | if ( daylightStart > 59 ) | ||
2392 | d_start = daylightStart +add; | ||
2393 | else | ||
2394 | d_start = daylightStart; | ||
2395 | QDate s_date = date.addDays( d_start -1 ); | ||
2396 | QDate e_date = date.addDays( d_end -1 ); | ||
2397 | int dof = s_date.dayOfWeek(); | ||
2398 | if ( dof < 7 ) | ||
2399 | s_date = s_date.addDays( -dof ); | ||
2400 | dof = e_date.dayOfWeek(); | ||
2401 | if ( dof < 7 ) | ||
2402 | e_date = e_date.addDays( -dof ); | ||
2403 | QTime startTime ( 3,0,0 ); | ||
2404 | QDateTime startDt( s_date, startTime ); | ||
2405 | QDateTime endDt( e_date, startTime ); | ||
2406 | //qDebug("dayligt saving start %s end %s ",startDt.toString().latin1(),endDt.toString().latin1( )); | ||
2407 | if ( mSouthDaylight ) { | ||
2408 | if ( ! ( endDt < dt && dt < startDt) ) | ||
2409 | addDaylight = true; | ||
2410 | } else { | ||
2411 | if ( startDt < dt && dt < endDt ) | ||
2412 | addDaylight = true; | ||
2413 | |||
2414 | |||
2415 | } | ||
2416 | } | ||
2417 | int addMin = 0; | ||
2418 | if ( addDaylight ) | ||
2419 | addMin = 60; | ||
2420 | return mTimeZoneOffset + addMin; | ||
2421 | } | ||
2422 | |||
2423 | void KLocale::setHore24Format ( bool b ) | ||
2424 | { | ||
2425 | mHourF24Format = b; | ||
2426 | } | ||
2427 | void KLocale::setWeekStartMonday( bool b ) | ||
2428 | { | ||
2429 | mWeekStartsMonday = b; | ||
2430 | } | ||
2431 | void KLocale::setIntDateFormat( int i ) | ||
2432 | { | ||
2433 | mIntDateFormat = i; | ||
2434 | } | ||
2435 | void KLocale::setLanguage( int i ) | ||
2436 | { | ||
2437 | mLanguage = i; | ||
2438 | } | ||
2439 | |||
2440 | |||
2441 | |||