28 #include <tqtextcodec.h>
30 #include <tqprinter.h>
31 #include <tqdatetime.h>
32 #include <tqfileinfo.h>
35 #include "kcatalogue.h"
37 #include "kstandarddirs.h"
38 #include "ksimpleconfig.h"
39 #include "kinstance.h"
42 #include "kcalendarsystem.h"
43 #include "kcalendarsystemfactory.h"
50 static const char *
const SYSTEM_MESSAGES =
"kdelibs";
52 static const char *maincatalogue = 0;
59 bool dateMonthNamePossessive;
60 TQStringList languageList;
61 TQStringList catalogNames;
62 TQValueList<KCatalogue> catalogues;
64 TQTextCodec * codecForEncoding;
69 TQStringList langTwoAlpha;
72 TQString calendarType;
74 bool utf8FileEncoding;
77 char win32SystemEncoding[3+7];
79 bool useMainCatalogue;
82 static KLocale *this_klocale = 0;
86 d =
new KLocalePrivate;
90 d->formatInited =
false;
93 initFileNameEncoding(0);
101 d->appName = catalog;
102 initLanguageList( cfg, config == 0);
103 initMainCatalogues(catalog);
106 TQString KLocale::_initLanguage(
KConfigBase *config)
111 this_klocale->initLanguageList((
KConfig *) config,
true);
115 return TQString::null;
118 void KLocale::initMainCatalogues(
const TQString & catalog)
121 TQString mainCatalogue = catalog;
124 if (mainCatalogue.contains(
"desktop") == 0 || mainCatalogue.contains(
"kdesktop") == 1) {
126 mainCatalogue = TQString::fromLatin1(maincatalogue);
130 if (mainCatalogue.isEmpty()) {
131 kdDebug(173) <<
"KLocale instance created called without valid "
132 <<
"catalog! Give an argument or call setMainCatalogue "
133 <<
"before init" <<
endl;
137 d->catalogNames.append( mainCatalogue );
138 if (mainCatalogue.contains(
"desktop") == 0 || mainCatalogue.contains(
"kdesktop") == 1) {
139 d->catalogNames.append( SYSTEM_MESSAGES );
140 d->catalogNames.append(
"kio" );
141 d->catalogNames.append(
"xdg-user-dirs" );
147 void KLocale::initLanguageList(
KConfig * config,
bool useEnv)
151 m_country = config->
readEntry(
"Country" );
152 if ( m_country.isEmpty() )
158 languageList += TQStringList::split
159 (
':', TQFile::decodeName( ::getenv(
"KDE_LANG") ));
169 langs << TQFile::decodeName( ::getenv(
"LC_ALL") );
170 langs << TQFile::decodeName( ::getenv(
"LC_MESSAGES") );
171 langs << TQFile::decodeName( ::getenv(
"LANG") );
173 for ( TQStringList::Iterator it = langs.begin();
177 TQString ln, ct, chrset;
181 langs.insert(it, ln +
'_' + ct);
182 if (!chrset.isEmpty())
183 langs.insert(it, ln +
'_' + ct +
'.' + chrset);
186 langs.insert(it, ln);
189 languageList += langs;
196 void KLocale::initPluralTypes()
198 for ( TQValueList<KCatalogue>::Iterator it = d->catalogues.begin();
199 it != d->catalogues.end();
202 TQString
language = (*it).language();
203 int pt = pluralType( language );
204 (*it).setPluralType( pt );
209 int KLocale::pluralType(
const TQString & language )
211 for ( TQValueList<KCatalogue>::ConstIterator it = d->catalogues.begin();
212 it != d->catalogues.end();
215 if ( ((*it).name() == SYSTEM_MESSAGES ) && ((*it).language() ==
language )) {
216 return pluralType( *it );
223 int KLocale::pluralType(
const KCatalogue& catalog )
225 const char* pluralFormString =
226 I18N_NOOP(
"_: Dear translator, please do not translate this string "
227 "in any form, but pick the _right_ value out of "
228 "NoPlural/TwoForms/French... If not sure what to do mail "
229 "thd@kde.org and coolo@kde.org, they will tell you. "
230 "Better leave that out if unsure, the programs will "
231 "crash!!\nDefinition of PluralForm - to be set by the "
232 "translator of kdelibs.po");
233 TQString pf (catalog.
translate( pluralFormString));
234 if ( pf.isEmpty() ) {
237 else if ( pf ==
"NoPlural" )
239 else if ( pf ==
"TwoForms" )
241 else if ( pf ==
"French" )
243 else if ( pf ==
"OneTwoRest" )
245 else if ( pf ==
"Russian" )
247 else if ( pf ==
"Polish" )
249 else if ( pf ==
"Slovenian" )
251 else if ( pf ==
"Lithuanian" )
253 else if ( pf ==
"Czech" )
255 else if ( pf ==
"Slovak" )
257 else if ( pf ==
"Maltese" )
259 else if ( pf ==
"Arabic" )
261 else if ( pf ==
"Balcan" )
263 else if ( pf ==
"Macedonian" )
265 else if ( pf ==
"Gaeilge" )
268 kdWarning(173) <<
"Definition of PluralForm is none of "
283 <<
"Maltese: " << pf <<
endl;
288 void KLocale::doFormatInit()
const
290 if ( d->formatInited )
return;
295 d->formatInited =
true;
298 void KLocale::initFormat()
304 kdDebug(173) <<
"KLocale::initFormat" <<
endl;
309 KLocale *lsave = KGlobal::_locale;
310 KGlobal::_locale =
this;
315 TQString::fromLatin1(
"l10n/%1/entry.desktop")
316 .arg(m_country)),
true);
317 entry.setGroup(
"KCM Locale");
320 #define readConfigEntry(key, default, save) \
321 save = entry.readEntry(key, TQString::fromLatin1(default)); \
322 save = config->readEntry(key, save);
324 #define readConfigNumEntry(key, default, save, type) \
325 save = (type)entry.readNumEntry(key, default); \
326 save = (type)config->readNumEntry(key, save);
328 #define readConfigBoolEntry(key, default, save) \
329 save = entry.readBoolEntry(key, default); \
330 save = config->readBoolEntry(key, save);
332 readConfigEntry(
"DecimalSymbol",
".", m_decimalSymbol);
333 readConfigEntry(
"ThousandsSeparator",
",", m_thousandsSeparator);
334 m_thousandsSeparator.replace( TQString::fromLatin1(
"$0"), TQString() );
337 readConfigEntry(
"PositiveSign",
"", m_positiveSign);
338 readConfigEntry(
"NegativeSign",
"-", m_negativeSign);
341 readConfigEntry(
"CurrencySymbol",
"$", m_currencySymbol);
342 readConfigEntry(
"MonetaryDecimalSymbol",
".", m_monetaryDecimalSymbol);
343 readConfigEntry(
"MonetaryThousandsSeparator",
",",
344 m_monetaryThousandsSeparator);
345 m_monetaryThousandsSeparator.replace(TQString::fromLatin1(
"$0"), TQString());
347 readConfigNumEntry(
"FracDigits", 2, m_fracDigits,
int);
348 readConfigBoolEntry(
"PositivePrefixCurrencySymbol",
true,
349 m_positivePrefixCurrencySymbol);
350 readConfigBoolEntry(
"NegativePrefixCurrencySymbol",
true,
351 m_negativePrefixCurrencySymbol);
352 readConfigNumEntry(
"PositiveMonetarySignPosition", (
int)BeforeQuantityMoney,
354 readConfigNumEntry(
"NegativeMonetarySignPosition", (
int)ParensAround,
359 readConfigEntry(
"TimeFormat",
"%H:%M:%S", m_timeFormat);
360 readConfigEntry(
"DateFormat",
"%A %d %B %Y", m_dateFormat);
361 readConfigEntry(
"DateFormatShort",
"%Y-%m-%d", m_dateFormatShort);
362 readConfigNumEntry(
"WeekStartDay", 1, d->weekStartDay,
int);
365 readConfigNumEntry(
"PageSize", (
int)TQPrinter::A4, d->pageSize,
int);
366 readConfigNumEntry(
"MeasureSystem", (
int)Metric, d->measureSystem,
368 readConfigEntry(
"CalendarSystem",
"gregorian", d->calendarType);
375 TQString::fromLatin1(
"%1/entry.desktop")
376 .arg(m_language)),
true);
377 language.setGroup(
"KCM Locale");
378 #define read3ConfigBoolEntry(key, default, save) \
379 save = entry.readBoolEntry(key, default); \
380 save = language.readBoolEntry(key, save); \
381 save = config->readBoolEntry(key, save);
383 read3ConfigBoolEntry(
"NounDeclension",
false, d->nounDeclension);
384 read3ConfigBoolEntry(
"DateMonthNamePossessive",
false,
385 d->dateMonthNamePossessive);
388 KGlobal::_locale = lsave;
394 if ( country.isEmpty() )
399 d->formatInited =
false;
404 TQString KLocale::catalogueFileName(
const TQString & language,
407 TQString path = TQString::fromLatin1(
"%1/LC_MESSAGES/%2.mo")
409 .arg( catalog.
name() );
411 TQString fileName = locate(
"locale", path );
412 if (fileName.isEmpty())
413 fileName = locate(
"locale-bundle", path );
420 if ( d->languageList.contains( language ) ) {
421 d->languageList.remove( language );
423 d->languageList.prepend( language );
431 d->formatInited =
false;
449 for( TQStringList::Iterator it = languageList.fromLast();
450 it != languageList.begin(); --it )
453 bool bIsTranslated = isApplicationTranslatedInto( *it );
454 if ( languageList.contains(*it) > 1 || (*it).isEmpty() || (!bIsTranslated) ) {
456 it = languageList.remove( it );
462 if ( languageList.begin() != languageList.end() ) {
463 TQStringList::Iterator it = languageList.begin();
465 if( (*it).isEmpty() || !(isApplicationTranslatedInto( *it )) ) {
467 languageList.remove( it );
471 if ( languageList.isEmpty() ) {
475 m_language = languageList.first();
478 d->langTwoAlpha.clear();
487 bool KLocale::isApplicationTranslatedInto(
const TQString & language)
489 if ( language.isEmpty() ) {
498 TQString appName = d->appName;
500 appName = TQString::fromLatin1(maincatalogue);
508 TQString sFileName = TQString::fromLatin1(
"%1/LC_MESSAGES/%2.mo")
513 TQString sAbsFileName = locate(
"locale", sFileName );
514 if (sAbsFileName.isEmpty())
515 sAbsFileName = locate(
"locale-bundle", sFileName );
518 return ! sAbsFileName.isEmpty();
529 int f = str.find(
':');
533 country = TQString::null;
534 chrset = TQString::null;
535 language = TQString::null;
540 chrset = str.mid(f + 1);
547 country = str.mid(f + 1);
569 case 1:
return translate(
"January",
"Jan");
570 case 2:
return translate(
"February",
"Feb");
571 case 3:
return translate(
"March",
"Mar");
572 case 4:
return translate(
"April",
"Apr");
573 case 5:
return translate(
"May short",
"May");
576 case 8:
return translate(
"August",
"Aug");
577 case 9:
return translate(
"September",
"Sep");
578 case 10:
return translate(
"October",
"Oct");
579 case 11:
return translate(
"November",
"Nov");
580 case 12:
return translate(
"December",
"Dec");
589 case 5:
return translate(
"May long",
"May");
599 return TQString::null;
607 case 1:
return translate(
"of January",
"of Jan");
608 case 2:
return translate(
"of February",
"of Feb");
609 case 3:
return translate(
"of March",
"of Mar");
610 case 4:
return translate(
"of April",
"of Apr");
611 case 5:
return translate(
"of May short",
"of May");
612 case 6:
return translate(
"of June",
"of Jun");
613 case 7:
return translate(
"of July",
"of Jul");
614 case 8:
return translate(
"of August",
"of Aug");
615 case 9:
return translate(
"of September",
"of Sep");
616 case 10:
return translate(
"of October",
"of Oct");
617 case 11:
return translate(
"of November",
"of Nov");
618 case 12:
return translate(
"of December",
"of Dec");
627 case 5:
return translate(
"of May long",
"of May");
631 case 9:
return translate(
"of September");
633 case 11:
return translate(
"of November");
634 case 12:
return translate(
"of December");
637 return TQString::null;
647 if ( !d->catalogNames.contains( catalog) ) {
648 d->catalogNames.append( catalog );
653 void KLocale::updateCatalogues( )
668 for ( TQValueList<KCatalogue>::Iterator it = d->catalogues.begin();
669 it != d->catalogues.end(); )
671 it = d->catalogues.remove(it);
678 for ( TQStringList::ConstIterator itLangs = d->languageList.begin();
679 itLangs != d->languageList.end(); ++itLangs)
681 for ( TQStringList::ConstIterator itNames = d->catalogNames.begin();
682 itNames != d->catalogNames.end(); ++itNames)
685 d->catalogues.append( cat );
696 if ( d->catalogNames.contains( catalog )) {
697 d->catalogNames.remove( catalog );
698 if (KGlobal::_instance)
705 if ( d->catalogNames.contains( catalog ) ) {
706 d->catalogNames.remove( catalog );
707 d->catalogNames.prepend( catalog );
720 TQString KLocale::translate_priv(
const char *msgid,
721 const char *fallback,
722 const char **translated,
723 int* pluralType )
const
728 if (!msgid || !msgid[0])
730 kdWarning() <<
"KLocale: trying to look up \"\" in catalog. "
731 <<
"Fix the program" <<
endl;
732 return TQString::null;
735 if ( useDefaultLanguage() ) {
736 return TQString::fromUtf8( fallback );
739 for ( TQValueList<KCatalogue>::ConstIterator it = d->catalogues.begin();
740 it != d->catalogues.end();
747 return TQString::fromUtf8( fallback );
750 const char * text = (*it).translate( msgid );
759 *pluralType = (*it).pluralType();
761 return TQString::fromUtf8( text );
766 return TQString::fromUtf8( fallback );
771 return translate_priv(msgid, msgid);
776 if (!index || !index[0] || !fallback || !fallback[0])
778 kdDebug(173) <<
"KLocale: trying to look up \"\" in catalog. "
779 <<
"Fix the program" <<
endl;
780 return TQString::null;
783 if ( useDefaultLanguage() )
784 return TQString::fromUtf8( fallback );
786 char *newstring =
new char[strlen(index) + strlen(fallback) + 5];
787 sprintf(newstring,
"_: %s\n%s", index, fallback);
789 TQString r = translate_priv(newstring, fallback);
795 static TQString put_n_in(
const TQString &orig,
unsigned long n)
798 int index = ret.find(
"%n");
801 ret.replace(index, 2, TQString::number(n));
805 #define EXPECT_LENGTH(x) \
806 if (forms.count() != x) { \
807 kdError() << "translation of \"" << singular << "\" doesn't contain " << x << " different plural forms as expected\n"; \
808 return TQString( "BROKEN TRANSLATION %1" ).arg( singular ); }
811 unsigned long n )
const
813 if (!singular || !singular[0] || !plural || !plural[0])
815 kdWarning() <<
"KLocale: trying to look up \"\" in catalog. "
816 <<
"Fix the program" <<
endl;
817 return TQString::null;
820 char *newstring =
new char[strlen(singular) + strlen(plural) + 6];
821 sprintf(newstring,
"_n: %s\n%s", singular, plural);
824 TQString r = translate_priv(newstring, 0, 0, &pluralType);
827 if ( r.isEmpty() || useDefaultLanguage() || pluralType == -1) {
829 return put_n_in( TQString::fromUtf8( singular ), n );
831 TQString tmp = TQString::fromUtf8( plural );
833 if (tmp.find(
"%n") == -1) {
834 kdDebug() <<
"the message for i18n should contain a '%n'! " << plural <<
endl;
837 return put_n_in( tmp, n );
841 TQStringList forms = TQStringList::split(
"\n", r,
false );
842 switch ( pluralType ) {
845 return put_n_in( forms[0], n);
849 return put_n_in( forms[0], n);
851 return put_n_in( forms[1], n);
854 if ( n == 1 || n == 0 )
855 return put_n_in( forms[0], n);
857 return put_n_in( forms[1], n);
861 return put_n_in( forms[0], n);
863 return put_n_in( forms[1], n);
865 return put_n_in( forms[2], n);
868 if ( n%10 == 1 && n%100 != 11)
869 return put_n_in( forms[0], n);
870 else if (( n%10 >= 2 && n%10 <=4 ) && (n%100<10 || n%100>20))
871 return put_n_in( forms[1], n);
873 return put_n_in( forms[2], n);
877 return put_n_in( forms[0], n);
878 else if ( n%10 >= 2 && n%10 <=4 && (n%100<10 || n%100>=20) )
879 return put_n_in( forms[1], n);
881 return put_n_in( forms[2], n);
885 return put_n_in( forms[1], n);
886 else if ( n%100 == 2 )
887 return put_n_in( forms[2], n);
888 else if ( n%100 == 3 || n%100 == 4 )
889 return put_n_in( forms[3], n);
891 return put_n_in( forms[0], n);
894 if ( n%10 == 0 || (n%100>=11 && n%100<=19) )
895 return put_n_in( forms[2], n);
896 else if ( n%10 == 1 )
897 return put_n_in( forms[0], n);
899 return put_n_in( forms[1], n);
904 return put_n_in( forms[0], n);
905 else if (( n >= 2 ) && ( n <= 4 ))
906 return put_n_in( forms[1], n);
908 return put_n_in( forms[2], n);
912 return put_n_in( forms[0], n );
913 else if ( ( n == 0 ) || ( n%100 > 0 && n%100 <= 10 ) )
914 return put_n_in( forms[1], n );
915 else if ( n%100 > 10 && n%100 < 20 )
916 return put_n_in( forms[2], n );
918 return put_n_in( forms[3], n );
922 return put_n_in(forms[0], n);
924 return put_n_in(forms[1], n);
926 return put_n_in(forms[2], n);
928 return put_n_in(forms[3], n);
931 if (n != 11 && n % 10 == 1)
932 return put_n_in(forms[0], n);
933 else if (n / 10 != 1 && n % 10 >= 2 && n % 10 <= 4)
934 return put_n_in(forms[1], n);
936 return put_n_in(forms[2], n);
940 return put_n_in(forms[0], n);
941 else if (n % 10 == 2)
942 return put_n_in(forms[1], n);
944 return put_n_in(forms[2], n);
948 return put_n_in(forms[0], n);
950 return put_n_in(forms[1], n);
952 return put_n_in(forms[2], n);
954 return put_n_in(forms[3], n);
956 return put_n_in(forms[4], n);
958 kdFatal() <<
"The function should have been returned in another way\n";
960 return TQString::null;
964 const char *message)
const
966 if (!source || !source[0]) {
967 kdWarning() <<
"KLocale: trying to look up \"\" in catalog. "
968 <<
"Fix the program" <<
endl;
969 return TQString::null;
972 if ( useDefaultLanguage() ) {
973 return TQString::null;
977 const char *translation = 0;
980 if ( message && message[0]) {
981 char *newstring =
new char[strlen(source) + strlen(message) + 5];
982 sprintf(newstring,
"_: %s\n%s", source, message);
983 const char *translation = 0;
985 r = translate_priv(newstring, source, &translation);
991 if ( context && context[0] && message && message[0]) {
992 newstring =
new char[strlen(context) + strlen(message) + 5];
993 sprintf(newstring,
"_: %s\n%s", context, message);
995 r = translate_priv(newstring, source, &translation);
1001 r = translate_priv(source, source, &translation);
1004 return TQString::null;
1010 return d->nounDeclension;
1016 return d->dateMonthNamePossessive;
1022 return d->weekStartDay;
1028 return (d->weekStartDay==1);
1034 return m_decimalSymbol;
1040 return m_thousandsSeparator;
1046 return m_currencySymbol;
1052 return m_monetaryDecimalSymbol;
1058 return m_monetaryThousandsSeparator;
1064 return m_positiveSign;
1070 return m_negativeSign;
1076 return m_fracDigits;
1082 return m_positivePrefixCurrencySymbol;
1088 return m_negativePrefixCurrencySymbol;
1094 return m_positiveMonetarySignPosition;
1100 return m_negativeMonetarySignPosition;
1103 static inline void put_it_in( TQChar *buffer, uint& index,
const TQString &s )
1105 for ( uint l = 0; l < s.length(); l++ )
1106 buffer[index++] = s.at( l );
1109 static inline void put_it_in( TQChar *buffer, uint& index,
int number )
1111 buffer[index++] = number / 10 +
'0';
1112 buffer[index++] = number % 10 +
'0';
1116 static void _insertSeparator(TQString &str,
const TQString &separator,
1117 const TQString &decimalSymbol)
1120 TQString mainPart = str.section(decimalSymbol, 0, 0);
1121 TQString fracPart = str.section(decimalSymbol, 1, 1,
1122 TQString::SectionIncludeLeadingSep);
1124 for (
int pos = mainPart.length() - 3; pos > 0; pos -= 3)
1125 mainPart.insert(pos, separator);
1127 str = mainPart + fracPart;
1131 const TQString & symbol,
1132 int precision)
const
1135 TQString currency = symbol.isNull()
1142 TQString res = TQString::number(neg?-num:num,
'f', precision);
1164 case BeforeQuantityMoney:
1167 case AfterQuantityMoney:
1171 currency.prepend(sign);
1174 currency.append(sign);
1182 res.prepend(currency);
1185 res.append (currency);
1198 if (precision == -1) precision = 2;
1200 return formatNumber(TQString::number(num,
'f', precision),
false, 0);
1214 static void _inc_by_one(TQString &str,
int position)
1216 for (
int i = position; i >= 0; i--)
1218 char last_char = str[i].latin1();
1222 str[i] = (QChar)
'1';
1225 str[i] = (QChar)
'2';
1228 str[i] = (QChar)
'3';
1231 str[i] = (QChar)
'4';
1234 str[i] = (QChar)
'5';
1237 str[i] = (QChar)
'6';
1240 str[i] = (QChar)
'7';
1243 str[i] = (QChar)
'8';
1246 str[i] = (QChar)
'9';
1249 str[i] = (QChar)
'0';
1250 if (i == 0) str.prepend(
'1');
1260 static void _round(TQString &str,
int precision)
1262 int decimalSymbolPos = str.find(
'.');
1264 if (decimalSymbolPos == -1)
1265 if (precision == 0)
return;
1266 else if (precision > 0)
1269 decimalSymbolPos = str.length() - 1;
1273 str.append(TQString().fill(
'0', precision));
1276 char last_char = str[decimalSymbolPos + precision + 1].latin1();
1291 _inc_by_one(str, decimalSymbolPos + precision);
1297 decimalSymbolPos = str.find(
'.');
1298 str.truncate(decimalSymbolPos + precision + 1);
1301 if (precision == 0) str = str.section(
'.', 0, 0);
1305 int precision)
const
1307 TQString tmpString = numStr;
1308 if ((round && precision < 0) ||
1309 ! TQRegExp(
"^[+-]?\\d+(\\.\\d+)*(e[+-]?\\d+)?$").exactMatch(tmpString))
1314 bool neg = (tmpString[0] == (QChar)
'-');
1315 if (neg || tmpString[0] == (QChar)
'+') tmpString.remove(0, 1);
1318 TQString mantString = tmpString.section(
'e', 0, 0,
1319 TQString::SectionCaseInsensitiveSeps);
1320 TQString expString = tmpString.section(
'e', 1, 1,
1321 TQString::SectionCaseInsensitiveSeps |
1322 TQString::SectionIncludeLeadingSep);
1324 if (round) _round(mantString, precision);
1335 return mantString + expString;
1344 if ( ! pDate.isValid() )
return buffer;
1346 bool escape =
false;
1351 for ( uint format_index = 0; format_index < rst.length(); ++format_index )
1355 if ( (TQChar(rst.at( format_index )).unicode()) ==
'%' )
1358 buffer.append(rst.at(format_index));
1362 switch ( TQChar(rst.at( format_index )).unicode() )
1368 buffer.append(
calendar()->yearString(pDate,
false));
1371 buffer.append(
calendar()->yearString(pDate,
true));
1374 buffer.append(
calendar()->monthString(pDate,
true));
1377 buffer.append(
calendar()->dayString(pDate,
true));
1380 buffer.append(
calendar()->monthString(pDate,
false));
1383 if (d->nounDeclension && d->dateMonthNamePossessive)
1389 if (d->nounDeclension && d->dateMonthNamePossessive)
1395 buffer.append(
calendar()->dayString(pDate,
false));
1404 buffer.append(rst.at(format_index));
1415 maincatalogue = catalog;
1420 TQString str = _str.stripWhiteSpace();
1428 TQString exponentialPart;
1431 EPos = str.find(
'E', 0,
false);
1435 exponentialPart = str.mid(EPos);
1436 str = str.left(EPos);
1446 major = str.left(pos);
1456 int fromEnd = major.length() - pos;
1457 if ( fromEnd % (3+thlen) != 0
1458 || pos - lastpos > 3
1460 || (lastpos>0 && pos-lastpos!=3))
1462 if (ok) *ok =
false;
1467 major.remove( pos, thlen );
1469 if (lastpos>0 && major.length()-lastpos!=3)
1471 if (ok) *ok =
false;
1476 if (neg) tot = (QChar)
'-';
1478 tot += major +
'.' + minor + exponentialPart;
1480 return tot.toDouble(ok);
1485 TQString str = _str.stripWhiteSpace();
1487 bool currencyFound =
false;
1490 int pos = str.find(symbol);
1491 if ( pos == 0 || pos == (
int) str.length()-symbol.length() )
1493 str.remove(pos,symbol.length());
1494 str = str.stripWhiteSpace();
1495 currencyFound =
true;
1499 if (ok) *ok =
false;
1506 if (str[0] == (QChar)
'(' && str[str.length()-1] == (QChar)
')')
1509 str.remove(str.length()-1,1);
1516 if ( i1 == 0 || i1 == (
int) str.length()-1 )
1522 if (neg) str = str.stripWhiteSpace();
1526 if ( !currencyFound )
1528 pos = str.find(symbol);
1529 if ( pos == 0 || pos == (
int) str.length()-symbol.length() )
1531 str.remove(pos,symbol.length());
1532 str = str.stripWhiteSpace();
1544 major = str.left(pos);
1554 int fromEnd = major.length() - pos;
1555 if ( fromEnd % (3+thlen) != 0
1556 || pos - lastpos > 3
1558 || (lastpos>0 && pos-lastpos!=3))
1560 if (ok) *ok =
false;
1564 major.remove( pos, thlen );
1566 if (lastpos>0 && major.length()-lastpos!=3)
1568 if (ok) *ok =
false;
1573 if (neg) tot = (QChar)
'-';
1574 tot += major +
'.' + minior;
1575 return tot.toDouble(ok);
1584 static int readInt(
const TQString &str, uint &pos)
1586 if (!str.at(pos).isDigit())
return -1;
1588 for (; str.length() > pos && str.at(pos).isDigit(); pos++)
1591 result += str.at(pos).digitValue();
1600 date =
readDate(intstr, ShortFormat, ok);
1601 if (date.isValid())
return date;
1602 return readDate(intstr, NormalFormat, ok);
1608 return readDate( intstr, fmt, ok );
1614 TQString str = intstr.simplifyWhiteSpace().lower();
1615 int day = -1, month = -1;
1625 while (fmt.length() > fmtpos && str.length() > strpos && !error)
1628 TQChar c = fmt.at(fmtpos++);
1630 if (c != (QChar)
'%') {
1631 if (c.isSpace() && str.at(strpos).isSpace())
1633 else if (c != str.at(strpos++))
1640 if (str.length() > strpos && str.at(strpos).isSpace())
1643 c = fmt.at(fmtpos++);
1651 while (error && (j < 8)) {
1653 int len = s.length();
1654 if (str.mid(strpos, len) == s)
1666 if (d->nounDeclension && d->dateMonthNamePossessive) {
1668 while (error && (j < 13)) {
1670 int len = s.length();
1671 if (str.mid(strpos, len) == s) {
1680 while (error && (j < 13)) {
1682 int len = s.length();
1683 if (str.mid(strpos, len) == s) {
1696 error = iLength <= 0;
1704 error = iLength <= 0;
1712 error = iLength <= 0;
1720 if ( fmt.length() > fmtpos || str.length() > strpos )
1726 if ( year != -1 && month != -1 && day != -1 && !error)
1737 if (ok) *ok =
false;
1745 _time =
readTime(intstr, WithSeconds, ok);
1746 if (_time.isValid())
return _time;
1747 return readTime(intstr, WithoutSeconds, ok);
1752 TQString str = intstr.simplifyWhiteSpace().lower();
1753 TQString Format =
timeFormat().simplifyWhiteSpace();
1754 if (flags & WithoutSeconds)
1755 Format.remove(TQRegExp(
".%S"));
1757 int hour = -1, minute = -1;
1758 int second = ( (flags & WithoutSeconds) == 0 ) ? -1 : 0;
1764 while (Format.length() > Formatpos || str.length() > strpos)
1766 if ( !(Format.length() > Formatpos && str.length() > strpos) )
goto error;
1768 TQChar c = Format.at(Formatpos++);
1770 if (c != (QChar)
'%')
1774 else if (c != str.at(strpos++))
1780 if (str.length() > strpos && str.at(strpos).isSpace())
1783 c = Format.at(Formatpos++);
1790 int len = s.length();
1791 if (str.mid(strpos, len) == s)
1800 if (str.mid(strpos, len) == s) {
1813 hour = readInt(str, strpos);
1814 if (hour < 0 || hour > 23)
1822 hour = readInt(str, strpos);
1823 if (hour < 1 || hour > 12)
1829 minute = readInt(str, strpos);
1830 if (minute < 0 || minute > 59)
1836 second = readInt(str, strpos);
1837 if (second < 0 || second > 59)
1849 return TQTime(hour, minute, second);
1852 if (ok) *ok =
false;
1854 return TQTime(-1, -1, -1);
1860 return formatTime( pTime, includeSecs,
false );
1869 TQChar *buffer =
new TQChar[rst.length() * 3 / 2 + 30];
1872 bool escape =
false;
1875 for ( uint format_index = 0; format_index < rst.length(); format_index++ )
1879 if ( (TQChar(rst.at( format_index )).unicode()) ==
'%' )
1882 buffer[index++] = rst.at( format_index );
1886 switch ( TQChar(rst.at( format_index )).unicode() )
1889 buffer[index++] = (QChar)
'%';
1892 put_it_in( buffer, index, pTime.hour() );
1896 put_it_in( buffer, index, pTime.hour() );
1898 put_it_in( buffer, index, ( pTime.hour() + 11) % 12 + 1 );
1901 put_it_in( buffer, index, pTime.minute() );
1905 put_it_in( buffer, index, pTime.second() );
1906 else if ( index > 0 )
1915 number = pTime.hour();
1918 if ( (TQChar(rst.at( format_index )).unicode()) ==
'l' )
1919 number = isDuration ? pTime.hour() : (pTime.hour() + 11) % 12 + 1;
1921 buffer[index++] = number / 10 +
'0';
1922 buffer[index++] = number % 10 +
'0';
1928 if ( pTime.hour() >= 12 )
1929 put_it_in( buffer, index,
translate(
"pm") );
1931 put_it_in( buffer, index,
translate(
"am") );
1935 buffer[index++] = rst.at( format_index );
1941 TQString ret( buffer, index );
1944 return ret.stripWhiteSpace();
1951 if ((
timeFormat().contains(TQString::fromLatin1(
"%I")) > 0) ||
1952 (
timeFormat().contains(TQString::fromLatin1(
"%l")) > 0))
1960 return d->languageList.join( TQString::fromLatin1(
":") );
1965 return d->languageList;
1970 bool includeSeconds)
const
1972 return translate(
"concatenation of dates and time",
"%1 %2")
1973 .arg(
formatDate( TQT_TQDATE_OBJECT(pDateTime.date()), shortFormat ) )
1974 .arg(
formatTime( TQT_TQTIME_OBJECT(pDateTime.time()), includeSeconds ) );
1982 return TQString::fromUtf8(text);
1985 TQString
i18n(
const char* index,
const char *text)
1989 return instance->
translate(index, text);
1990 return TQString::fromUtf8(text);
1993 TQString
i18n(
const char* singular,
const char* plural,
unsigned long n)
1997 return instance->
translate(singular, plural, n);
1999 return put_n_in(TQString::fromUtf8(singular), n);
2001 return put_n_in(TQString::fromUtf8(plural), n);
2004 void KLocale::initInstance()
2006 if (KGlobal::_locale)
2017 kdDebug(173) <<
"no app name available using KLocale - nothing to do\n";
2022 TQStringList search;
2028 for (
int id=localDoc.count()-1;
id >= 0; --id)
2031 langs.append(
"en" );
2033 TQStringList::ConstIterator lang;
2034 for (lang = langs.begin(); lang != langs.end(); ++lang)
2035 search.append(TQString(
"%1%2/%3").arg(localDoc[
id]).arg(*lang).arg(fname));
2039 TQStringList::Iterator it;
2040 for (it = search.begin(); it != search.end(); ++it)
2042 kdDebug(173) <<
"Looking for help in: " << *it <<
endl;
2044 TQFileInfo info(*it);
2045 if (info.exists() && info.isFile() && info.isReadable())
2049 return TQString::null;
2052 bool KLocale::useDefaultLanguage()
const
2057 void KLocale::initEncoding(
KConfig *)
2059 const int mibDefault = 4;
2062 setEncoding( TQTextCodec::codecForLocale()->mibEnum() );
2064 if ( !d->codecForEncoding )
2066 kdWarning(173) <<
" Defaulting to ISO 8859-1 encoding." <<
endl;
2070 Q_ASSERT( d->codecForEncoding );
2073 void KLocale::initFileNameEncoding(
KConfig *)
2077 d->utf8FileEncoding = getenv(
"KDE_UTF8_FILENAMES") != 0;
2078 if (d->utf8FileEncoding)
2080 TQFile::setEncodingFunction(KLocale::encodeFileNameUTF8);
2081 TQFile::setDecodingFunction(KLocale::decodeFileNameUTF8);
2088 TQCString KLocale::encodeFileNameUTF8(
const TQString & fileName )
2091 QByteArray KLocale::encodeFileNameUTF8(
const QString & fileName )
2094 return TQString(fileName).utf8();
2098 TQString KLocale::decodeFileNameUTF8(
const TQCString & localFileName )
2101 QString KLocale::decodeFileNameUTF8(
const QByteArray & localFileName )
2104 return TQString::fromUtf8(localFileName);
2110 m_dateFormat = format.stripWhiteSpace();
2116 m_dateFormatShort = format.stripWhiteSpace();
2122 d->dateMonthNamePossessive = possessive;
2128 m_timeFormat = format.stripWhiteSpace();
2135 d->weekStartDay = 1;
2137 d->weekStartDay = 7;
2144 d->weekStartDay = 1;
2146 d->weekStartDay = day;
2152 return m_dateFormat;
2158 return m_dateFormatShort;
2164 return m_timeFormat;
2170 m_decimalSymbol = symbol.stripWhiteSpace();
2177 m_thousandsSeparator = separator;
2183 m_positiveSign = sign.stripWhiteSpace();
2189 m_negativeSign = sign.stripWhiteSpace();
2195 m_positiveMonetarySignPosition = signpos;
2201 m_negativeMonetarySignPosition = signpos;
2207 m_positivePrefixCurrencySymbol = prefix;
2213 m_negativePrefixCurrencySymbol = prefix;
2219 m_fracDigits = digits;
2226 m_monetaryThousandsSeparator = separator;
2232 m_monetaryDecimalSymbol = symbol.stripWhiteSpace();
2238 m_currencySymbol = symbol.stripWhiteSpace();
2257 return d->measureSystem;
2263 d->measureSystem = value;
2268 return TQString::fromLatin1(
"en_US");
2273 return TQString::fromLatin1(
"C");
2282 strcpy(d->win32SystemEncoding,
"cp ");
2283 if (GetLocaleInfoA( MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT),
2284 LOCALE_IDEFAULTANSICODEPAGE, d->win32SystemEncoding+3,
sizeof(d->win32SystemEncoding)-3-1 ))
2286 return d->win32SystemEncoding;
2300 if (d->utf8FileEncoding)
2307 return d->codecForEncoding;
2312 TQTextCodec * codec = TQTextCodec::codecForMib(mibEnum);
2314 d->codecForEncoding = codec;
2321 if (d->langTwoAlpha.count())
2322 return d->langTwoAlpha;
2324 const TQStringList &origList = languageList();
2326 TQStringList result;
2328 KConfig config(TQString::fromLatin1(
"language.codes"),
true,
false);
2331 for ( TQStringList::ConstIterator it = origList.begin();
2332 it != origList.end();
2335 TQString lang = *it;
2336 TQStringList langLst;
2337 if (config.
hasKey( lang ))
2341 int i = lang.find(
'_');
2347 for ( TQStringList::ConstIterator langIt = langLst.begin();
2348 langIt != langLst.end();
2351 if ( !(*langIt).isEmpty() && !result.contains( *langIt ) )
2355 d->langTwoAlpha = result;
2362 d->languages =
new KConfig(
"all_languages",
true,
false,
"locale");
2364 return d->languages->groupList();
2370 d->languages =
new KConfig(
"all_languages",
true,
false,
"locale");
2372 TQString groupName = code;
2373 const int i = groupName.find(
'_');
2374 groupName.replace(0, i, groupName.left(i).lower());
2376 d->languages->setGroup(groupName);
2377 return d->languages->readEntry(
"Name");
2382 TQStringList countries;
2384 for(TQStringList::ConstIterator it = paths.begin();
2385 it != paths.end(); ++it)
2387 TQString code = (*it).mid((*it).length()-16, 2);
2389 countries.append(code);
2396 KConfig cfg(
"l10n/"+code.lower()+
"/entry.desktop",
true,
false,
"locale");
2398 return cfg.readEntry(
"Name");
2405 d->calendarType = calType;
2415 return d->calendarType;
2431 d =
new KLocalePrivate;
2439 m_decimalSymbol = rhs.m_decimalSymbol;
2440 m_thousandsSeparator = rhs.m_thousandsSeparator;
2441 m_currencySymbol = rhs.m_currencySymbol;
2442 m_monetaryDecimalSymbol = rhs.m_monetaryDecimalSymbol;
2443 m_monetaryThousandsSeparator = rhs.m_monetaryThousandsSeparator;
2444 m_positiveSign = rhs.m_positiveSign;
2445 m_negativeSign = rhs.m_negativeSign;
2446 m_fracDigits = rhs.m_fracDigits;
2447 m_positivePrefixCurrencySymbol = rhs.m_positivePrefixCurrencySymbol;
2448 m_negativePrefixCurrencySymbol = rhs.m_negativePrefixCurrencySymbol;
2449 m_positiveMonetarySignPosition = rhs.m_positiveMonetarySignPosition;
2450 m_negativeMonetarySignPosition = rhs.m_negativeMonetarySignPosition;
2453 m_timeFormat = rhs.m_timeFormat;
2454 m_dateFormat = rhs.m_dateFormat;
2455 m_dateFormatShort = rhs.m_dateFormatShort;
2457 m_language = rhs.m_language;
2458 m_country = rhs.m_country;
2469 TQString
KLocale::charset()
const {
return TQString::fromLatin1(
"UTF-8"); }
2473 void nothing() {
i18n(
"&Next"); }