00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025
00026 #include <stdlib.h>
00027
00028 #include <tqtextcodec.h>
00029 #include <tqfile.h>
00030 #include <tqprinter.h>
00031 #include <tqdatetime.h>
00032 #include <tqfileinfo.h>
00033 #include <tqregexp.h>
00034
00035 #include "kcatalogue.h"
00036 #include "tdeglobal.h"
00037 #include "kstandarddirs.h"
00038 #include "ksimpleconfig.h"
00039 #include "kinstance.h"
00040 #include "tdeconfig.h"
00041 #include "kdebug.h"
00042 #include "kcalendarsystem.h"
00043 #include "kcalendarsystemfactory.h"
00044 #include "tdelocale.h"
00045
00046 #ifdef Q_WS_WIN
00047 #include <windows.h>
00048 #endif
00049
00050 static const char * const SYSTEM_MESSAGES = "tdelibs";
00051
00052 static const char *maincatalogue = 0;
00053
00054 class TDELocalePrivate
00055 {
00056 public:
00057 int weekStartDay;
00058 bool nounDeclension;
00059 bool dateMonthNamePossessive;
00060 TQStringList languageList;
00061 TQStringList catalogNames;
00062 TQValueList<KCatalogue> catalogues;
00063 TQString encoding;
00064 TQTextCodec * codecForEncoding;
00065 TDEConfig * config;
00066 bool formatInited;
00067 int pageSize;
00068 TDELocale::MeasureSystem measureSystem;
00069 TQStringList langTwoAlpha;
00070 TDEConfig *languages;
00071
00072 TQString calendarType;
00073 KCalendarSystem * calendar;
00074 bool utf8FileEncoding;
00075 TQString appName;
00076 #ifdef Q_WS_WIN
00077 char win32SystemEncoding[3+7];
00078 #endif
00079 bool useMainCatalogue;
00080 };
00081
00082 static TDELocale *this_klocale = 0;
00083
00084 TDELocale::TDELocale( const TQString & catalog, TDEConfig * config )
00085 {
00086 d = new TDELocalePrivate;
00087 d->config = config;
00088 d->languages = 0;
00089 d->calendar = 0;
00090 d->formatInited = false;
00091
00092 initEncoding(0);
00093 initFileNameEncoding(0);
00094
00095 TDEConfig *cfg = d->config;
00096 this_klocale = this;
00097 if (!cfg) cfg = TDEGlobal::instance()->config();
00098 this_klocale = 0;
00099 Q_ASSERT( cfg );
00100
00101 d->appName = catalog;
00102 initLanguageList( cfg, config == 0);
00103 initMainCatalogues(catalog);
00104 }
00105
00106 TQString TDELocale::_initLanguage(TDEConfigBase *config)
00107 {
00108 if (this_klocale)
00109 {
00110
00111 this_klocale->initLanguageList((TDEConfig *) config, true);
00112
00113 return this_klocale->language();
00114 }
00115 return TQString::null;
00116 }
00117
00118 void TDELocale::initMainCatalogues(const TQString & catalog)
00119 {
00120
00121 TQString mainCatalogue = catalog;
00122
00123
00124 if (mainCatalogue.contains("desktop") == 0 || mainCatalogue.contains("kdesktop") == 1) {
00125 if (maincatalogue) {
00126 mainCatalogue = TQString::fromLatin1(maincatalogue);
00127 }
00128 }
00129
00130 if (mainCatalogue.isEmpty()) {
00131 kdDebug(173) << "TDELocale instance created called without valid "
00132 << "catalog! Give an argument or call setMainCatalogue "
00133 << "before init" << endl;
00134 }
00135 else {
00136
00137 d->catalogNames.append( mainCatalogue );
00138 if (mainCatalogue.contains("desktop") == 0 || mainCatalogue.contains("kdesktop") == 1) {
00139 d->catalogNames.append( SYSTEM_MESSAGES );
00140 d->catalogNames.append( "tdeio" );
00141 d->catalogNames.append( "xdg-user-dirs" );
00142 }
00143 updateCatalogues();
00144 }
00145 }
00146
00147 void TDELocale::initLanguageList(TDEConfig * config, bool useEnv)
00148 {
00149 TDEConfigGroupSaver saver(config, "Locale");
00150
00151 m_country = config->readEntry( "Country" );
00152 if ( m_country.isEmpty() )
00153 m_country = defaultCountry();
00154
00155
00156 TQStringList languageList;
00157 if ( useEnv )
00158 languageList += TQStringList::split
00159 (':', TQFile::decodeName( ::getenv("TDE_LANG") ));
00160
00161 languageList += config->readListEntry("Language", ':');
00162
00163
00164 if ( useEnv )
00165 {
00166
00167 TQStringList langs;
00168
00169 langs << TQFile::decodeName( ::getenv("LC_ALL") );
00170 langs << TQFile::decodeName( ::getenv("LC_MESSAGES") );
00171 langs << TQFile::decodeName( ::getenv("LANG") );
00172
00173 for ( TQStringList::Iterator it = langs.begin();
00174 it != langs.end();
00175 ++it )
00176 {
00177 TQString ln, ct, chrset;
00178 splitLocale(*it, ln, ct, chrset);
00179
00180 if (!ct.isEmpty()) {
00181 langs.insert(it, ln + '_' + ct);
00182 if (!chrset.isEmpty())
00183 langs.insert(it, ln + '_' + ct + '.' + chrset);
00184 }
00185
00186 langs.insert(it, ln);
00187 }
00188
00189 languageList += langs;
00190 }
00191
00192
00193 setLanguage( languageList );
00194 }
00195
00196 void TDELocale::initPluralTypes()
00197 {
00198 for ( TQValueList<KCatalogue>::Iterator it = d->catalogues.begin();
00199 it != d->catalogues.end();
00200 ++it )
00201 {
00202 TQString language = (*it).language();
00203 int pt = pluralType( language );
00204 (*it).setPluralType( pt );
00205 }
00206 }
00207
00208
00209 int TDELocale::pluralType( const TQString & language )
00210 {
00211 for ( TQValueList<KCatalogue>::ConstIterator it = d->catalogues.begin();
00212 it != d->catalogues.end();
00213 ++it )
00214 {
00215 if ( ((*it).name() == SYSTEM_MESSAGES ) && ((*it).language() == language )) {
00216 return pluralType( *it );
00217 }
00218 }
00219
00220 return -1;
00221 }
00222
00223 int TDELocale::pluralType( const KCatalogue& catalog )
00224 {
00225 const char* pluralFormString =
00226 I18N_NOOP("_: Dear translator, please do not translate this string "
00227 "in any form, but pick the _right_ value out of "
00228 "NoPlural/TwoForms/French... If not sure what to do mail "
00229 "thd@kde.org and coolo@kde.org, they will tell you. "
00230 "Better leave that out if unsure, the programs will "
00231 "crash!!\nDefinition of PluralForm - to be set by the "
00232 "translator of tdelibs.po");
00233 TQString pf (catalog.translate( pluralFormString));
00234 if ( pf.isEmpty() ) {
00235 return -1;
00236 }
00237 else if ( pf == "NoPlural" )
00238 return 0;
00239 else if ( pf == "TwoForms" )
00240 return 1;
00241 else if ( pf == "French" )
00242 return 2;
00243 else if ( pf == "OneTwoRest" )
00244 return 3;
00245 else if ( pf == "Russian" )
00246 return 4;
00247 else if ( pf == "Polish" )
00248 return 5;
00249 else if ( pf == "Slovenian" )
00250 return 6;
00251 else if ( pf == "Lithuanian" )
00252 return 7;
00253 else if ( pf == "Czech" )
00254 return 8;
00255 else if ( pf == "Slovak" )
00256 return 9;
00257 else if ( pf == "Maltese" )
00258 return 10;
00259 else if ( pf == "Arabic" )
00260 return 11;
00261 else if ( pf == "Balcan" )
00262 return 12;
00263 else if ( pf == "Macedonian" )
00264 return 13;
00265 else if ( pf == "Gaeilge" )
00266 return 14;
00267 else {
00268 kdWarning(173) << "Definition of PluralForm is none of "
00269 << "NoPlural/"
00270 << "TwoForms/"
00271 << "French/"
00272 << "OneTwoRest/"
00273 << "Russian/"
00274 << "Polish/"
00275 << "Slovenian/"
00276 << "Lithuanian/"
00277 << "Czech/"
00278 << "Slovak/"
00279 << "Arabic/"
00280 << "Balcan/"
00281 << "Macedonian/"
00282 << "Gaeilge/"
00283 << "Maltese: " << pf << endl;
00284 exit(1);
00285 }
00286 }
00287
00288 void TDELocale::doFormatInit() const
00289 {
00290 if ( d->formatInited ) return;
00291
00292 TDELocale * that = const_cast<TDELocale *>(this);
00293 that->initFormat();
00294
00295 d->formatInited = true;
00296 }
00297
00298 void TDELocale::initFormat()
00299 {
00300 TDEConfig *config = d->config;
00301 if (!config) config = TDEGlobal::instance()->config();
00302 Q_ASSERT( config );
00303
00304 kdDebug(173) << "TDELocale::initFormat" << endl;
00305
00306
00307
00308
00309 TDELocale *lsave = TDEGlobal::_locale;
00310 TDEGlobal::_locale = this;
00311
00312 TDEConfigGroupSaver saver(config, "Locale");
00313
00314 KSimpleConfig entry(locate("locale",
00315 TQString::fromLatin1("l10n/%1/entry.desktop")
00316 .arg(m_country)), true);
00317 entry.setGroup("KCM Locale");
00318
00319
00320 #define readConfigEntry(key, default, save) \
00321 save = entry.readEntry(key, TQString::fromLatin1(default)); \
00322 save = config->readEntry(key, save);
00323
00324 #define readConfigNumEntry(key, default, save, type) \
00325 save = (type)entry.readNumEntry(key, default); \
00326 save = (type)config->readNumEntry(key, save);
00327
00328 #define readConfigBoolEntry(key, default, save) \
00329 save = entry.readBoolEntry(key, default); \
00330 save = config->readBoolEntry(key, save);
00331
00332 readConfigEntry("DecimalSymbol", ".", m_decimalSymbol);
00333 readConfigEntry("ThousandsSeparator", ",", m_thousandsSeparator);
00334 m_thousandsSeparator.replace( TQString::fromLatin1("$0"), TQString() );
00335
00336
00337 readConfigEntry("PositiveSign", "", m_positiveSign);
00338 readConfigEntry("NegativeSign", "-", m_negativeSign);
00339
00340
00341 readConfigEntry("CurrencySymbol", "$", m_currencySymbol);
00342 readConfigEntry("MonetaryDecimalSymbol", ".", m_monetaryDecimalSymbol);
00343 readConfigEntry("MonetaryThousandsSeparator", ",",
00344 m_monetaryThousandsSeparator);
00345 m_monetaryThousandsSeparator.replace(TQString::fromLatin1("$0"), TQString());
00346
00347 readConfigNumEntry("FracDigits", 2, m_fracDigits, int);
00348 readConfigBoolEntry("PositivePrefixCurrencySymbol", true,
00349 m_positivePrefixCurrencySymbol);
00350 readConfigBoolEntry("NegativePrefixCurrencySymbol", true,
00351 m_negativePrefixCurrencySymbol);
00352 readConfigNumEntry("PositiveMonetarySignPosition", (int)BeforeQuantityMoney,
00353 m_positiveMonetarySignPosition, SignPosition);
00354 readConfigNumEntry("NegativeMonetarySignPosition", (int)ParensAround,
00355 m_negativeMonetarySignPosition, SignPosition);
00356
00357
00358
00359 readConfigEntry("TimeFormat", "%H:%M:%S", m_timeFormat);
00360 readConfigEntry("DateFormat", "%A %d %B %Y", m_dateFormat);
00361 readConfigEntry("DateFormatShort", "%Y-%m-%d", m_dateFormatShort);
00362 readConfigNumEntry("WeekStartDay", 1, d->weekStartDay, int);
00363
00364
00365 readConfigNumEntry("PageSize", (int)TQPrinter::A4, d->pageSize, int);
00366 readConfigNumEntry("MeasureSystem", (int)Metric, d->measureSystem,
00367 MeasureSystem);
00368 readConfigEntry("CalendarSystem", "gregorian", d->calendarType);
00369 delete d->calendar;
00370 d->calendar = 0;
00371
00372
00373
00374 KSimpleConfig language(locate("locale",
00375 TQString::fromLatin1("%1/entry.desktop")
00376 .arg(m_language)), true);
00377 language.setGroup("KCM Locale");
00378 #define read3ConfigBoolEntry(key, default, save) \
00379 save = entry.readBoolEntry(key, default); \
00380 save = language.readBoolEntry(key, save); \
00381 save = config->readBoolEntry(key, save);
00382
00383 read3ConfigBoolEntry("NounDeclension", false, d->nounDeclension);
00384 read3ConfigBoolEntry("DateMonthNamePossessive", false,
00385 d->dateMonthNamePossessive);
00386
00387
00388 TDEGlobal::_locale = lsave;
00389 }
00390
00391 bool TDELocale::setCountry(const TQString & country)
00392 {
00393
00394 if ( country.isEmpty() )
00395 return false;
00396
00397 m_country = country;
00398
00399 d->formatInited = false;
00400
00401 return true;
00402 }
00403
00404 TQString TDELocale::catalogueFileName(const TQString & language,
00405 const KCatalogue & catalog)
00406 {
00407 TQString path = TQString::fromLatin1("%1/LC_MESSAGES/%2.mo")
00408 .arg( language )
00409 .arg( catalog.name() );
00410
00411 TQString fileName = locate( "locale", path );
00412 if (fileName.isEmpty())
00413 fileName = locate( "locale-bundle", path );
00414
00415 return fileName;
00416 }
00417
00418 bool TDELocale::setLanguage(const TQString & language)
00419 {
00420 if ( d->languageList.contains( language ) ) {
00421 d->languageList.remove( language );
00422 }
00423 d->languageList.prepend( language );
00424
00425 m_language = language;
00426
00427
00428
00429 updateCatalogues();
00430
00431 d->formatInited = false;
00432
00433 return true;
00434 }
00435
00436 bool TDELocale::setLanguage(const TQStringList & languages)
00437 {
00438 TQStringList languageList( languages );
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 for( TQStringList::Iterator it = languageList.fromLast();
00450 it != languageList.begin(); --it )
00451 {
00452
00453 bool bIsTranslated = isApplicationTranslatedInto( *it );
00454 if ( languageList.contains(*it) > 1 || (*it).isEmpty() || (!bIsTranslated) ) {
00455
00456 it = languageList.remove( it );
00457 }
00458 }
00459
00460
00461
00462 if ( languageList.begin() != languageList.end() ) {
00463 TQStringList::Iterator it = languageList.begin();
00464
00465 if( (*it).isEmpty() || !(isApplicationTranslatedInto( *it )) ) {
00466
00467 languageList.remove( it );
00468 }
00469 }
00470
00471 if ( languageList.isEmpty() ) {
00472
00473 languageList.append( defaultLanguage() );
00474 }
00475 m_language = languageList.first();
00476
00477 d->languageList = languageList;
00478 d->langTwoAlpha.clear();
00479
00480
00481
00482 updateCatalogues();
00483
00484 return true;
00485 }
00486
00487 bool TDELocale::isApplicationTranslatedInto( const TQString & language)
00488 {
00489 if ( language.isEmpty() ) {
00490 return false;
00491 }
00492
00493 if ( language == defaultLanguage() ) {
00494
00495 return true;
00496 }
00497
00498 TQString appName = d->appName;
00499 if (maincatalogue) {
00500 appName = TQString::fromLatin1(maincatalogue);
00501 }
00502
00503
00504
00505
00506
00507
00508 TQString sFileName = TQString::fromLatin1("%1/LC_MESSAGES/%2.mo")
00509 .arg( language )
00510 .arg( appName );
00511
00512
00513 TQString sAbsFileName = locate( "locale", sFileName );
00514 if (sAbsFileName.isEmpty())
00515 sAbsFileName = locate( "locale-bundle", sFileName );
00516
00517
00518 return ! sAbsFileName.isEmpty();
00519 }
00520
00521 void TDELocale::splitLocale(const TQString & aStr,
00522 TQString & language,
00523 TQString & country,
00524 TQString & chrset)
00525 {
00526 TQString str = aStr;
00527
00528
00529 int f = str.find(':');
00530 if (f >= 0)
00531 str.truncate(f);
00532
00533 country = TQString::null;
00534 chrset = TQString::null;
00535 language = TQString::null;
00536
00537 f = str.find('.');
00538 if (f >= 0)
00539 {
00540 chrset = str.mid(f + 1);
00541 str.truncate(f);
00542 }
00543
00544 f = str.find('_');
00545 if (f >= 0)
00546 {
00547 country = str.mid(f + 1);
00548 str.truncate(f);
00549 }
00550
00551 language = str;
00552 }
00553
00554 TQString TDELocale::language() const
00555 {
00556 return m_language;
00557 }
00558
00559 TQString TDELocale::country() const
00560 {
00561 return m_country;
00562 }
00563
00564 TQString TDELocale::monthName(int i, bool shortName) const
00565 {
00566 if ( shortName )
00567 switch ( i )
00568 {
00569 case 1: return translate("January", "Jan");
00570 case 2: return translate("February", "Feb");
00571 case 3: return translate("March", "Mar");
00572 case 4: return translate("April", "Apr");
00573 case 5: return translate("May short", "May");
00574 case 6: return translate("June", "Jun");
00575 case 7: return translate("July", "Jul");
00576 case 8: return translate("August", "Aug");
00577 case 9: return translate("September", "Sep");
00578 case 10: return translate("October", "Oct");
00579 case 11: return translate("November", "Nov");
00580 case 12: return translate("December", "Dec");
00581 }
00582 else
00583 switch (i)
00584 {
00585 case 1: return translate("January");
00586 case 2: return translate("February");
00587 case 3: return translate("March");
00588 case 4: return translate("April");
00589 case 5: return translate("May long", "May");
00590 case 6: return translate("June");
00591 case 7: return translate("July");
00592 case 8: return translate("August");
00593 case 9: return translate("September");
00594 case 10: return translate("October");
00595 case 11: return translate("November");
00596 case 12: return translate("December");
00597 }
00598
00599 return TQString::null;
00600 }
00601
00602 TQString TDELocale::monthNamePossessive(int i, bool shortName) const
00603 {
00604 if ( shortName )
00605 switch ( i )
00606 {
00607 case 1: return translate("of January", "of Jan");
00608 case 2: return translate("of February", "of Feb");
00609 case 3: return translate("of March", "of Mar");
00610 case 4: return translate("of April", "of Apr");
00611 case 5: return translate("of May short", "of May");
00612 case 6: return translate("of June", "of Jun");
00613 case 7: return translate("of July", "of Jul");
00614 case 8: return translate("of August", "of Aug");
00615 case 9: return translate("of September", "of Sep");
00616 case 10: return translate("of October", "of Oct");
00617 case 11: return translate("of November", "of Nov");
00618 case 12: return translate("of December", "of Dec");
00619 }
00620 else
00621 switch (i)
00622 {
00623 case 1: return translate("of January");
00624 case 2: return translate("of February");
00625 case 3: return translate("of March");
00626 case 4: return translate("of April");
00627 case 5: return translate("of May long", "of May");
00628 case 6: return translate("of June");
00629 case 7: return translate("of July");
00630 case 8: return translate("of August");
00631 case 9: return translate("of September");
00632 case 10: return translate("of October");
00633 case 11: return translate("of November");
00634 case 12: return translate("of December");
00635 }
00636
00637 return TQString::null;
00638 }
00639
00640 TQString TDELocale::weekDayName (int i, bool shortName) const
00641 {
00642 return calendar()->weekDayName(i, shortName);
00643 }
00644
00645 void TDELocale::insertCatalogue( const TQString & catalog )
00646 {
00647 if ( !d->catalogNames.contains( catalog) ) {
00648 d->catalogNames.append( catalog );
00649 }
00650 updateCatalogues( );
00651 }
00652
00653 void TDELocale::updateCatalogues( )
00654 {
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 for ( TQValueList<KCatalogue>::Iterator it = d->catalogues.begin();
00669 it != d->catalogues.end(); )
00670 {
00671 it = d->catalogues.remove(it);
00672 }
00673
00674
00675
00676
00677
00678 for ( TQStringList::ConstIterator itLangs = d->languageList.begin();
00679 itLangs != d->languageList.end(); ++itLangs)
00680 {
00681 for ( TQStringList::ConstIterator itNames = d->catalogNames.begin();
00682 itNames != d->catalogNames.end(); ++itNames)
00683 {
00684 KCatalogue cat( *itNames, *itLangs );
00685 d->catalogues.append( cat );
00686 }
00687 }
00688 initPluralTypes();
00689 }
00690
00691
00692
00693
00694 void TDELocale::removeCatalogue(const TQString &catalog)
00695 {
00696 if ( d->catalogNames.contains( catalog )) {
00697 d->catalogNames.remove( catalog );
00698 if (TDEGlobal::_instance)
00699 updateCatalogues();
00700 }
00701 }
00702
00703 void TDELocale::setActiveCatalogue(const TQString &catalog)
00704 {
00705 if ( d->catalogNames.contains( catalog ) ) {
00706 d->catalogNames.remove( catalog );
00707 d->catalogNames.prepend( catalog );
00708 updateCatalogues();
00709 }
00710 }
00711
00712 TDELocale::~TDELocale()
00713 {
00714 delete d->calendar;
00715 delete d->languages;
00716 delete d;
00717 d = 0L;
00718 }
00719
00720 TQString TDELocale::translate_priv(const char *msgid,
00721 const char *fallback,
00722 const char **translated,
00723 int* pluralType ) const
00724 {
00725 if ( pluralType) {
00726 *pluralType = -1;
00727 }
00728 if (!msgid || !msgid[0])
00729 {
00730 kdWarning() << "TDELocale: trying to look up \"\" in catalog. "
00731 << "Fix the program" << endl;
00732 return TQString::null;
00733 }
00734
00735 if ( useDefaultLanguage() ) {
00736 return TQString::fromUtf8( fallback );
00737 }
00738
00739 for ( TQValueList<KCatalogue>::ConstIterator it = d->catalogues.begin();
00740 it != d->catalogues.end();
00741 ++it )
00742 {
00743
00744
00745
00746 if ( (*it).language() == defaultLanguage() ) {
00747 return TQString::fromUtf8( fallback );
00748 }
00749
00750 const char * text = (*it).translate( msgid );
00751
00752 if ( text )
00753 {
00754
00755 if (translated) {
00756 *translated = text;
00757 }
00758 if ( pluralType) {
00759 *pluralType = (*it).pluralType();
00760 }
00761 return TQString::fromUtf8( text );
00762 }
00763 }
00764
00765
00766 return TQString::fromUtf8( fallback );
00767 }
00768
00769 TQString TDELocale::translate(const char* msgid) const
00770 {
00771 return translate_priv(msgid, msgid);
00772 }
00773
00774 TQString TDELocale::translate( const char *index, const char *fallback) const
00775 {
00776 if (!index || !index[0] || !fallback || !fallback[0])
00777 {
00778 kdDebug(173) << "TDELocale: trying to look up \"\" in catalog. "
00779 << "Fix the program" << endl;
00780 return TQString::null;
00781 }
00782
00783 if ( useDefaultLanguage() )
00784 return TQString::fromUtf8( fallback );
00785
00786 char *newstring = new char[strlen(index) + strlen(fallback) + 5];
00787 sprintf(newstring, "_: %s\n%s", index, fallback);
00788
00789 TQString r = translate_priv(newstring, fallback);
00790 delete [] newstring;
00791
00792 return r;
00793 }
00794
00795 static TQString put_n_in(const TQString &orig, unsigned long n)
00796 {
00797 TQString ret = orig;
00798 int index = ret.find("%n");
00799 if (index == -1)
00800 return ret;
00801 ret.replace(index, 2, TQString::number(n));
00802 return ret;
00803 }
00804
00805 #define EXPECT_LENGTH(x) \
00806 if (forms.count() != x) { \
00807 kdError() << "translation of \"" << singular << "\" doesn't contain " << x << " different plural forms as expected\n"; \
00808 return TQString( "BROKEN TRANSLATION %1" ).arg( singular ); }
00809
00810 TQString TDELocale::translate( const char *singular, const char *plural,
00811 unsigned long n ) const
00812 {
00813 if (!singular || !singular[0] || !plural || !plural[0])
00814 {
00815 kdWarning() << "TDELocale: trying to look up \"\" in catalog. "
00816 << "Fix the program" << endl;
00817 return TQString::null;
00818 }
00819
00820 char *newstring = new char[strlen(singular) + strlen(plural) + 6];
00821 sprintf(newstring, "_n: %s\n%s", singular, plural);
00822
00823 int pluralType = -1;
00824 TQString r = translate_priv(newstring, 0, 0, &pluralType);
00825 delete [] newstring;
00826
00827 if ( r.isEmpty() || useDefaultLanguage() || pluralType == -1) {
00828 if ( n == 1 ) {
00829 return put_n_in( TQString::fromUtf8( singular ), n );
00830 } else {
00831 TQString tmp = TQString::fromUtf8( plural );
00832 #ifndef NDEBUG
00833 if (tmp.find("%n") == -1) {
00834 kdDebug() << "the message for i18n should contain a '%n'! " << plural << endl;
00835 }
00836 #endif
00837 return put_n_in( tmp, n );
00838 }
00839 }
00840
00841 TQStringList forms = TQStringList::split( "\n", r, false );
00842 switch ( pluralType ) {
00843 case 0:
00844 EXPECT_LENGTH( 1 );
00845 return put_n_in( forms[0], n);
00846 case 1:
00847 EXPECT_LENGTH( 2 );
00848 if ( n == 1 )
00849 return put_n_in( forms[0], n);
00850 else
00851 return put_n_in( forms[1], n);
00852 case 2:
00853 EXPECT_LENGTH( 2 );
00854 if ( n == 1 || n == 0 )
00855 return put_n_in( forms[0], n);
00856 else
00857 return put_n_in( forms[1], n);
00858 case 3:
00859 EXPECT_LENGTH( 3 );
00860 if ( n == 1 )
00861 return put_n_in( forms[0], n);
00862 else if ( n == 2 )
00863 return put_n_in( forms[1], n);
00864 else
00865 return put_n_in( forms[2], n);
00866 case 4:
00867 EXPECT_LENGTH( 3 );
00868 if ( n%10 == 1 && n%100 != 11)
00869 return put_n_in( forms[0], n);
00870 else if (( n%10 >= 2 && n%10 <=4 ) && (n%100<10 || n%100>20))
00871 return put_n_in( forms[1], n);
00872 else
00873 return put_n_in( forms[2], n);
00874 case 5:
00875 EXPECT_LENGTH( 3 );
00876 if ( n == 1 )
00877 return put_n_in( forms[0], n);
00878 else if ( n%10 >= 2 && n%10 <=4 && (n%100<10 || n%100>=20) )
00879 return put_n_in( forms[1], n);
00880 else
00881 return put_n_in( forms[2], n);
00882 case 6:
00883 EXPECT_LENGTH( 4 );
00884 if ( n%100 == 1 )
00885 return put_n_in( forms[1], n);
00886 else if ( n%100 == 2 )
00887 return put_n_in( forms[2], n);
00888 else if ( n%100 == 3 || n%100 == 4 )
00889 return put_n_in( forms[3], n);
00890 else
00891 return put_n_in( forms[0], n);
00892 case 7:
00893 EXPECT_LENGTH( 3 );
00894 if ( n%10 == 0 || (n%100>=11 && n%100<=19) )
00895 return put_n_in( forms[2], n);
00896 else if ( n%10 == 1 )
00897 return put_n_in( forms[0], n);
00898 else
00899 return put_n_in( forms[1], n);
00900 case 8:
00901 case 9:
00902 EXPECT_LENGTH( 3 );
00903 if ( n == 1 )
00904 return put_n_in( forms[0], n);
00905 else if (( n >= 2 ) && ( n <= 4 ))
00906 return put_n_in( forms[1], n);
00907 else
00908 return put_n_in( forms[2], n);
00909 case 10:
00910 EXPECT_LENGTH( 4 );
00911 if ( n == 1 )
00912 return put_n_in( forms[0], n );
00913 else if ( ( n == 0 ) || ( n%100 > 0 && n%100 <= 10 ) )
00914 return put_n_in( forms[1], n );
00915 else if ( n%100 > 10 && n%100 < 20 )
00916 return put_n_in( forms[2], n );
00917 else
00918 return put_n_in( forms[3], n );
00919 case 11:
00920 EXPECT_LENGTH( 4 );
00921 if (n == 1)
00922 return put_n_in(forms[0], n);
00923 else if (n == 2)
00924 return put_n_in(forms[1], n);
00925 else if ( n < 11)
00926 return put_n_in(forms[2], n);
00927 else
00928 return put_n_in(forms[3], n);
00929 case 12:
00930 EXPECT_LENGTH( 3 );
00931 if (n != 11 && n % 10 == 1)
00932 return put_n_in(forms[0], n);
00933 else if (n / 10 != 1 && n % 10 >= 2 && n % 10 <= 4)
00934 return put_n_in(forms[1], n);
00935 else
00936 return put_n_in(forms[2], n);
00937 case 13:
00938 EXPECT_LENGTH(3);
00939 if (n % 10 == 1)
00940 return put_n_in(forms[0], n);
00941 else if (n % 10 == 2)
00942 return put_n_in(forms[1], n);
00943 else
00944 return put_n_in(forms[2], n);
00945 case 14:
00946 EXPECT_LENGTH(5);
00947 if (n == 1)
00948 return put_n_in(forms[0], n);
00949 else if (n == 2)
00950 return put_n_in(forms[1], n);
00951 else if (n < 7)
00952 return put_n_in(forms[2], n);
00953 else if (n < 11)
00954 return put_n_in(forms[3], n);
00955 else
00956 return put_n_in(forms[4], n);
00957 }
00958 kdFatal() << "The function should have been returned in another way\n";
00959
00960 return TQString::null;
00961 }
00962
00963 TQString TDELocale::translateQt( const char *context, const char *source,
00964 const char *message) const
00965 {
00966 if (!source || !source[0]) {
00967 kdWarning() << "TDELocale: trying to look up \"\" in catalog. "
00968 << "Fix the program" << endl;
00969 return TQString::null;
00970 }
00971
00972 if ( useDefaultLanguage() ) {
00973 return TQString::null;
00974 }
00975
00976 char *newstring = 0;
00977 const char *translation = 0;
00978 TQString r;
00979
00980 if ( message && message[0]) {
00981 char *newstring = new char[strlen(source) + strlen(message) + 5];
00982 sprintf(newstring, "_: %s\n%s", source, message);
00983 const char *translation = 0;
00984
00985 r = translate_priv(newstring, source, &translation);
00986 delete [] newstring;
00987 if (translation)
00988 return r;
00989 }
00990
00991 if ( context && context[0] && message && message[0]) {
00992 newstring = new char[strlen(context) + strlen(message) + 5];
00993 sprintf(newstring, "_: %s\n%s", context, message);
00994
00995 r = translate_priv(newstring, source, &translation);
00996 delete [] newstring;
00997 if (translation)
00998 return r;
00999 }
01000
01001 r = translate_priv(source, source, &translation);
01002 if (translation)
01003 return r;
01004 return TQString::null;
01005 }
01006
01007 bool TDELocale::nounDeclension() const
01008 {
01009 doFormatInit();
01010 return d->nounDeclension;
01011 }
01012
01013 bool TDELocale::dateMonthNamePossessive() const
01014 {
01015 doFormatInit();
01016 return d->dateMonthNamePossessive;
01017 }
01018
01019 int TDELocale::weekStartDay() const
01020 {
01021 doFormatInit();
01022 return d->weekStartDay;
01023 }
01024
01025 bool TDELocale::weekStartsMonday() const
01026 {
01027 doFormatInit();
01028 return (d->weekStartDay==1);
01029 }
01030
01031 TQString TDELocale::decimalSymbol() const
01032 {
01033 doFormatInit();
01034 return m_decimalSymbol;
01035 }
01036
01037 TQString TDELocale::thousandsSeparator() const
01038 {
01039 doFormatInit();
01040 return m_thousandsSeparator;
01041 }
01042
01043 TQString TDELocale::currencySymbol() const
01044 {
01045 doFormatInit();
01046 return m_currencySymbol;
01047 }
01048
01049 TQString TDELocale::monetaryDecimalSymbol() const
01050 {
01051 doFormatInit();
01052 return m_monetaryDecimalSymbol;
01053 }
01054
01055 TQString TDELocale::monetaryThousandsSeparator() const
01056 {
01057 doFormatInit();
01058 return m_monetaryThousandsSeparator;
01059 }
01060
01061 TQString TDELocale::positiveSign() const
01062 {
01063 doFormatInit();
01064 return m_positiveSign;
01065 }
01066
01067 TQString TDELocale::negativeSign() const
01068 {
01069 doFormatInit();
01070 return m_negativeSign;
01071 }
01072
01073 int TDELocale::fracDigits() const
01074 {
01075 doFormatInit();
01076 return m_fracDigits;
01077 }
01078
01079 bool TDELocale::positivePrefixCurrencySymbol() const
01080 {
01081 doFormatInit();
01082 return m_positivePrefixCurrencySymbol;
01083 }
01084
01085 bool TDELocale::negativePrefixCurrencySymbol() const
01086 {
01087 doFormatInit();
01088 return m_negativePrefixCurrencySymbol;
01089 }
01090
01091 TDELocale::SignPosition TDELocale::positiveMonetarySignPosition() const
01092 {
01093 doFormatInit();
01094 return m_positiveMonetarySignPosition;
01095 }
01096
01097 TDELocale::SignPosition TDELocale::negativeMonetarySignPosition() const
01098 {
01099 doFormatInit();
01100 return m_negativeMonetarySignPosition;
01101 }
01102
01103 static inline void put_it_in( TQChar *buffer, uint& index, const TQString &s )
01104 {
01105 for ( uint l = 0; l < s.length(); l++ )
01106 buffer[index++] = s.at( l );
01107 }
01108
01109 static inline void put_it_in( TQChar *buffer, uint& index, int number )
01110 {
01111 buffer[index++] = number / 10 + '0';
01112 buffer[index++] = number % 10 + '0';
01113 }
01114
01115
01116 static void _insertSeparator(TQString &str, const TQString &separator,
01117 const TQString &decimalSymbol)
01118 {
01119
01120 TQString mainPart = str.section(decimalSymbol, 0, 0);
01121 TQString fracPart = str.section(decimalSymbol, 1, 1,
01122 TQString::SectionIncludeLeadingSep);
01123
01124 for (int pos = mainPart.length() - 3; pos > 0; pos -= 3)
01125 mainPart.insert(pos, separator);
01126
01127 str = mainPart + fracPart;
01128 }
01129
01130 TQString TDELocale::formatMoney(double num,
01131 const TQString & symbol,
01132 int precision) const
01133 {
01134
01135 TQString currency = symbol.isNull()
01136 ? currencySymbol()
01137 : symbol;
01138 if (precision < 0) precision = fracDigits();
01139
01140
01141 bool neg = num < 0;
01142 TQString res = TQString::number(neg?-num:num, 'f', precision);
01143
01144
01145 res.replace(TQChar('.'), monetaryDecimalSymbol());
01146
01147
01148 _insertSeparator(res, monetaryThousandsSeparator(), monetaryDecimalSymbol());
01149
01150
01151 int signpos = neg
01152 ? negativeMonetarySignPosition()
01153 : positiveMonetarySignPosition();
01154 TQString sign = neg
01155 ? negativeSign()
01156 : positiveSign();
01157
01158 switch (signpos)
01159 {
01160 case ParensAround:
01161 res.prepend('(');
01162 res.append (')');
01163 break;
01164 case BeforeQuantityMoney:
01165 res.prepend(sign);
01166 break;
01167 case AfterQuantityMoney:
01168 res.append(sign);
01169 break;
01170 case BeforeMoney:
01171 currency.prepend(sign);
01172 break;
01173 case AfterMoney:
01174 currency.append(sign);
01175 break;
01176 }
01177
01178 if (neg?negativePrefixCurrencySymbol():
01179 positivePrefixCurrencySymbol())
01180 {
01181 res.prepend(' ');
01182 res.prepend(currency);
01183 } else {
01184 res.append (' ');
01185 res.append (currency);
01186 }
01187
01188 return res;
01189 }
01190
01191 TQString TDELocale::formatMoney(const TQString &numStr) const
01192 {
01193 return formatMoney(numStr.toDouble());
01194 }
01195
01196 TQString TDELocale::formatNumber(double num, int precision) const
01197 {
01198 if (precision == -1) precision = 2;
01199
01200 return formatNumber(TQString::number(num, 'f', precision), false, 0);
01201 }
01202
01203 TQString TDELocale::formatLong(long num) const
01204 {
01205 return formatNumber((double)num, 0);
01206 }
01207
01208 TQString TDELocale::formatNumber(const TQString &numStr) const
01209 {
01210 return formatNumber(numStr, true, 2);
01211 }
01212
01213
01214 static void _inc_by_one(TQString &str, int position)
01215 {
01216 for (int i = position; i >= 0; i--)
01217 {
01218 char last_char = str[i].latin1();
01219 switch(last_char)
01220 {
01221 case '0':
01222 str[i] = (QChar)'1';
01223 break;
01224 case '1':
01225 str[i] = (QChar)'2';
01226 break;
01227 case '2':
01228 str[i] = (QChar)'3';
01229 break;
01230 case '3':
01231 str[i] = (QChar)'4';
01232 break;
01233 case '4':
01234 str[i] = (QChar)'5';
01235 break;
01236 case '5':
01237 str[i] = (QChar)'6';
01238 break;
01239 case '6':
01240 str[i] = (QChar)'7';
01241 break;
01242 case '7':
01243 str[i] = (QChar)'8';
01244 break;
01245 case '8':
01246 str[i] = (QChar)'9';
01247 break;
01248 case '9':
01249 str[i] = (QChar)'0';
01250 if (i == 0) str.prepend('1');
01251 continue;
01252 case '.':
01253 continue;
01254 }
01255 break;
01256 }
01257 }
01258
01259
01260 static void _round(TQString &str, int precision)
01261 {
01262 int decimalSymbolPos = str.find('.');
01263
01264 if (decimalSymbolPos == -1)
01265 if (precision == 0) return;
01266 else if (precision > 0)
01267 {
01268 str.append('.');
01269 decimalSymbolPos = str.length() - 1;
01270 }
01271
01272
01273 str.append(TQString().fill('0', precision));
01274
01275
01276 char last_char = str[decimalSymbolPos + precision + 1].latin1();
01277 switch (last_char)
01278 {
01279 case '0':
01280 case '1':
01281 case '2':
01282 case '3':
01283 case '4':
01284
01285 break;
01286 case '5':
01287 case '6':
01288 case '7':
01289 case '8':
01290 case '9':
01291 _inc_by_one(str, decimalSymbolPos + precision);
01292 break;
01293 default:
01294 break;
01295 }
01296
01297 decimalSymbolPos = str.find('.');
01298 str.truncate(decimalSymbolPos + precision + 1);
01299
01300
01301 if (precision == 0) str = str.section('.', 0, 0);
01302 }
01303
01304 TQString TDELocale::formatNumber(const TQString &numStr, bool round,
01305 int precision) const
01306 {
01307 TQString tmpString = numStr;
01308 if ((round && precision < 0) ||
01309 ! TQRegExp("^[+-]?\\d+(\\.\\d+)*(e[+-]?\\d+)?$").exactMatch(tmpString))
01310 return numStr;
01311
01312
01313
01314 bool neg = (tmpString[0] == (QChar)'-');
01315 if (neg || tmpString[0] == (QChar)'+') tmpString.remove(0, 1);
01316
01317
01318 TQString mantString = tmpString.section('e', 0, 0,
01319 TQString::SectionCaseInsensitiveSeps);
01320 TQString expString = tmpString.section('e', 1, 1,
01321 TQString::SectionCaseInsensitiveSeps |
01322 TQString::SectionIncludeLeadingSep);
01323
01324 if (round) _round(mantString, precision);
01325
01326
01327 mantString.replace(TQChar('.'), decimalSymbol());
01328
01329
01330 _insertSeparator(mantString, thousandsSeparator(), decimalSymbol());
01331
01332
01333 mantString.prepend(neg?negativeSign():positiveSign());
01334
01335 return mantString + expString;
01336 }
01337
01338 TQString TDELocale::formatDate(const TQDate &pDate, bool shortFormat) const
01339 {
01340 const TQString rst = shortFormat?dateFormatShort():dateFormat();
01341
01342 TQString buffer;
01343
01344 if ( ! pDate.isValid() ) return buffer;
01345
01346 bool escape = false;
01347
01348 int year = calendar()->year(pDate);
01349 int month = calendar()->month(pDate);
01350
01351 for ( uint format_index = 0; format_index < rst.length(); ++format_index )
01352 {
01353 if ( !escape )
01354 {
01355 if ( (TQChar(rst.at( format_index )).unicode()) == '%' )
01356 escape = true;
01357 else
01358 buffer.append(rst.at(format_index));
01359 }
01360 else
01361 {
01362 switch ( TQChar(rst.at( format_index )).unicode() )
01363 {
01364 case '%':
01365 buffer.append('%');
01366 break;
01367 case 'Y':
01368 buffer.append(calendar()->yearString(pDate, false));
01369 break;
01370 case 'y':
01371 buffer.append(calendar()->yearString(pDate, true));
01372 break;
01373 case 'n':
01374 buffer.append(calendar()->monthString(pDate, true));
01375 break;
01376 case 'e':
01377 buffer.append(calendar()->dayString(pDate, true));
01378 break;
01379 case 'm':
01380 buffer.append(calendar()->monthString(pDate, false));
01381 break;
01382 case 'b':
01383 if (d->nounDeclension && d->dateMonthNamePossessive)
01384 buffer.append(calendar()->monthNamePossessive(month, year, true));
01385 else
01386 buffer.append(calendar()->monthName(month, year, true));
01387 break;
01388 case 'B':
01389 if (d->nounDeclension && d->dateMonthNamePossessive)
01390 buffer.append(calendar()->monthNamePossessive(month, year, false));
01391 else
01392 buffer.append(calendar()->monthName(month, year, false));
01393 break;
01394 case 'd':
01395 buffer.append(calendar()->dayString(pDate, false));
01396 break;
01397 case 'a':
01398 buffer.append(calendar()->weekDayName(pDate, true));
01399 break;
01400 case 'A':
01401 buffer.append(calendar()->weekDayName(pDate, false));
01402 break;
01403 default:
01404 buffer.append(rst.at(format_index));
01405 break;
01406 }
01407 escape = false;
01408 }
01409 }
01410 return buffer;
01411 }
01412
01413 void TDELocale::setMainCatalogue(const char *catalog)
01414 {
01415 maincatalogue = catalog;
01416 }
01417
01418 double TDELocale::readNumber(const TQString &_str, bool * ok) const
01419 {
01420 TQString str = _str.stripWhiteSpace();
01421 bool neg = str.find(negativeSign()) == 0;
01422 if (neg)
01423 str.remove( 0, negativeSign().length() );
01424
01425
01426
01427
01428 TQString exponentialPart;
01429 int EPos;
01430
01431 EPos = str.find('E', 0, false);
01432
01433 if (EPos != -1)
01434 {
01435 exponentialPart = str.mid(EPos);
01436 str = str.left(EPos);
01437 }
01438
01439 int pos = str.find(decimalSymbol());
01440 TQString major;
01441 TQString minor;
01442 if ( pos == -1 )
01443 major = str;
01444 else
01445 {
01446 major = str.left(pos);
01447 minor = str.mid(pos + decimalSymbol().length());
01448 }
01449
01450
01451 int thlen = thousandsSeparator().length();
01452 int lastpos = 0;
01453 while ( ( pos = major.find( thousandsSeparator() ) ) > 0 )
01454 {
01455
01456 int fromEnd = major.length() - pos;
01457 if ( fromEnd % (3+thlen) != 0
01458 || pos - lastpos > 3
01459 || pos == 0
01460 || (lastpos>0 && pos-lastpos!=3))
01461 {
01462 if (ok) *ok = false;
01463 return 0.0;
01464 }
01465
01466 lastpos = pos;
01467 major.remove( pos, thlen );
01468 }
01469 if (lastpos>0 && major.length()-lastpos!=3)
01470 {
01471 if (ok) *ok = false;
01472 return 0.0;
01473 }
01474
01475 TQString tot;
01476 if (neg) tot = (QChar)'-';
01477
01478 tot += major + '.' + minor + exponentialPart;
01479
01480 return tot.toDouble(ok);
01481 }
01482
01483 double TDELocale::readMoney(const TQString &_str, bool * ok) const
01484 {
01485 TQString str = _str.stripWhiteSpace();
01486 bool neg = false;
01487 bool currencyFound = false;
01488 TQString symbol = currencySymbol();
01489
01490 int pos = str.find(symbol);
01491 if ( pos == 0 || pos == (int) str.length()-symbol.length() )
01492 {
01493 str.remove(pos,symbol.length());
01494 str = str.stripWhiteSpace();
01495 currencyFound = true;
01496 }
01497 if (str.isEmpty())
01498 {
01499 if (ok) *ok = false;
01500 return 0;
01501 }
01502
01503
01504 if (negativeMonetarySignPosition() == ParensAround)
01505 {
01506 if (str[0] == (QChar)'(' && str[str.length()-1] == (QChar)')')
01507 {
01508 neg = true;
01509 str.remove(str.length()-1,1);
01510 str.remove(0,1);
01511 }
01512 }
01513 else
01514 {
01515 int i1 = str.find(negativeSign());
01516 if ( i1 == 0 || i1 == (int) str.length()-1 )
01517 {
01518 neg = true;
01519 str.remove(i1,negativeSign().length());
01520 }
01521 }
01522 if (neg) str = str.stripWhiteSpace();
01523
01524
01525
01526 if ( !currencyFound )
01527 {
01528 pos = str.find(symbol);
01529 if ( pos == 0 || pos == (int) str.length()-symbol.length() )
01530 {
01531 str.remove(pos,symbol.length());
01532 str = str.stripWhiteSpace();
01533 }
01534 }
01535
01536
01537 pos = str.find(monetaryDecimalSymbol());
01538 TQString major;
01539 TQString minior;
01540 if (pos == -1)
01541 major = str;
01542 else
01543 {
01544 major = str.left(pos);
01545 minior = str.mid(pos + monetaryDecimalSymbol().length());
01546 }
01547
01548
01549 int thlen = monetaryThousandsSeparator().length();
01550 int lastpos = 0;
01551 while ( ( pos = major.find( monetaryThousandsSeparator() ) ) > 0 )
01552 {
01553
01554 int fromEnd = major.length() - pos;
01555 if ( fromEnd % (3+thlen) != 0
01556 || pos - lastpos > 3
01557 || pos == 0
01558 || (lastpos>0 && pos-lastpos!=3))
01559 {
01560 if (ok) *ok = false;
01561 return 0.0;
01562 }
01563 lastpos = pos;
01564 major.remove( pos, thlen );
01565 }
01566 if (lastpos>0 && major.length()-lastpos!=3)
01567 {
01568 if (ok) *ok = false;
01569 return 0.0;
01570 }
01571
01572 TQString tot;
01573 if (neg) tot = (QChar)'-';
01574 tot += major + '.' + minior;
01575 return tot.toDouble(ok);
01576 }
01577
01584 static int readInt(const TQString &str, uint &pos)
01585 {
01586 if (!str.at(pos).isDigit()) return -1;
01587 int result = 0;
01588 for (; str.length() > pos && str.at(pos).isDigit(); pos++)
01589 {
01590 result *= 10;
01591 result += str.at(pos).digitValue();
01592 }
01593
01594 return result;
01595 }
01596
01597 TQDate TDELocale::readDate(const TQString &intstr, bool* ok) const
01598 {
01599 TQDate date;
01600 date = readDate(intstr, ShortFormat, ok);
01601 if (date.isValid()) return date;
01602 return readDate(intstr, NormalFormat, ok);
01603 }
01604
01605 TQDate TDELocale::readDate(const TQString &intstr, ReadDateFlags flags, bool* ok) const
01606 {
01607 TQString fmt = ((flags & ShortFormat) ? dateFormatShort() : dateFormat()).simplifyWhiteSpace();
01608 return readDate( intstr, fmt, ok );
01609 }
01610
01611 TQDate TDELocale::readDate(const TQString &intstr, const TQString &fmt, bool* ok) const
01612 {
01613
01614 TQString str = intstr.simplifyWhiteSpace().lower();
01615 int day = -1, month = -1;
01616
01617 int year = calendar()->year(TQDate::currentDate());
01618 uint strpos = 0;
01619 uint fmtpos = 0;
01620
01621 int iLength;
01622
01623 bool error = false;
01624
01625 while (fmt.length() > fmtpos && str.length() > strpos && !error)
01626 {
01627
01628 TQChar c = fmt.at(fmtpos++);
01629
01630 if (c != (QChar)'%') {
01631 if (c.isSpace() && str.at(strpos).isSpace())
01632 strpos++;
01633 else if (c != str.at(strpos++))
01634 error = true;
01635 }
01636 else
01637 {
01638 int j;
01639
01640 if (str.length() > strpos && str.at(strpos).isSpace())
01641 strpos++;
01642
01643 c = fmt.at(fmtpos++);
01644 switch (c)
01645 {
01646 case 'a':
01647 case 'A':
01648
01649 error = true;
01650 j = 1;
01651 while (error && (j < 8)) {
01652 TQString s = calendar()->weekDayName(j, c == (QChar)'a').lower();
01653 int len = s.length();
01654 if (str.mid(strpos, len) == s)
01655 {
01656 strpos += len;
01657 error = false;
01658 }
01659 j++;
01660 }
01661 break;
01662 case 'b':
01663 case 'B':
01664
01665 error = true;
01666 if (d->nounDeclension && d->dateMonthNamePossessive) {
01667 j = 1;
01668 while (error && (j < 13)) {
01669 TQString s = calendar()->monthNamePossessive(j, year, c == (QChar)'b').lower();
01670 int len = s.length();
01671 if (str.mid(strpos, len) == s) {
01672 month = j;
01673 strpos += len;
01674 error = false;
01675 }
01676 j++;
01677 }
01678 }
01679 j = 1;
01680 while (error && (j < 13)) {
01681 TQString s = calendar()->monthName(j, year, c == (QChar)'b').lower();
01682 int len = s.length();
01683 if (str.mid(strpos, len) == s) {
01684 month = j;
01685 strpos += len;
01686 error = false;
01687 }
01688 j++;
01689 }
01690 break;
01691 case 'd':
01692 case 'e':
01693 day = calendar()->dayStringToInteger(str.mid(strpos), iLength);
01694 strpos += iLength;
01695
01696 error = iLength <= 0;
01697 break;
01698
01699 case 'n':
01700 case 'm':
01701 month = calendar()->monthStringToInteger(str.mid(strpos), iLength);
01702 strpos += iLength;
01703
01704 error = iLength <= 0;
01705 break;
01706
01707 case 'Y':
01708 case 'y':
01709 year = calendar()->yearStringToInteger(str.mid(strpos), iLength);
01710 strpos += iLength;
01711
01712 error = iLength <= 0;
01713 break;
01714 }
01715 }
01716 }
01717
01718
01719
01720 if ( fmt.length() > fmtpos || str.length() > strpos )
01721 {
01722 error = true;
01723 }
01724
01725
01726 if ( year != -1 && month != -1 && day != -1 && !error)
01727 {
01728 if (ok) *ok = true;
01729
01730 TQDate result;
01731 calendar()->setYMD(result, year, month, day);
01732
01733 return result;
01734 }
01735 else
01736 {
01737 if (ok) *ok = false;
01738 return TQDate();
01739 }
01740 }
01741
01742 TQTime TDELocale::readTime(const TQString &intstr, bool *ok) const
01743 {
01744 TQTime _time;
01745 _time = readTime(intstr, WithSeconds, ok);
01746 if (_time.isValid()) return _time;
01747 return readTime(intstr, WithoutSeconds, ok);
01748 }
01749
01750 TQTime TDELocale::readTime(const TQString &intstr, ReadTimeFlags flags, bool *ok) const
01751 {
01752 TQString str = intstr.simplifyWhiteSpace().lower();
01753 TQString Format = timeFormat().simplifyWhiteSpace();
01754 if (flags & WithoutSeconds)
01755 Format.remove(TQRegExp(".%S"));
01756
01757 int hour = -1, minute = -1;
01758 int second = ( (flags & WithoutSeconds) == 0 ) ? -1 : 0;
01759 bool g_12h = false;
01760 bool pm = false;
01761 uint strpos = 0;
01762 uint Formatpos = 0;
01763
01764 while (Format.length() > Formatpos || str.length() > strpos)
01765 {
01766 if ( !(Format.length() > Formatpos && str.length() > strpos) ) goto error;
01767
01768 TQChar c = Format.at(Formatpos++);
01769
01770 if (c != (QChar)'%')
01771 {
01772 if (c.isSpace())
01773 strpos++;
01774 else if (c != str.at(strpos++))
01775 goto error;
01776 continue;
01777 }
01778
01779
01780 if (str.length() > strpos && str.at(strpos).isSpace())
01781 strpos++;
01782
01783 c = Format.at(Formatpos++);
01784 switch (c)
01785 {
01786 case 'p':
01787 {
01788 TQString s;
01789 s = translate("pm").lower();
01790 int len = s.length();
01791 if (str.mid(strpos, len) == s)
01792 {
01793 pm = true;
01794 strpos += len;
01795 }
01796 else
01797 {
01798 s = translate("am").lower();
01799 len = s.length();
01800 if (str.mid(strpos, len) == s) {
01801 pm = false;
01802 strpos += len;
01803 }
01804 else
01805 goto error;
01806 }
01807 }
01808 break;
01809
01810 case 'k':
01811 case 'H':
01812 g_12h = false;
01813 hour = readInt(str, strpos);
01814 if (hour < 0 || hour > 23)
01815 goto error;
01816
01817 break;
01818
01819 case 'l':
01820 case 'I':
01821 g_12h = true;
01822 hour = readInt(str, strpos);
01823 if (hour < 1 || hour > 12)
01824 goto error;
01825
01826 break;
01827
01828 case 'M':
01829 minute = readInt(str, strpos);
01830 if (minute < 0 || minute > 59)
01831 goto error;
01832
01833 break;
01834
01835 case 'S':
01836 second = readInt(str, strpos);
01837 if (second < 0 || second > 59)
01838 goto error;
01839
01840 break;
01841 }
01842 }
01843 if (g_12h) {
01844 hour %= 12;
01845 if (pm) hour += 12;
01846 }
01847
01848 if (ok) *ok = true;
01849 return TQTime(hour, minute, second);
01850
01851 error:
01852 if (ok) *ok = false;
01853
01854 return TQTime(-1, -1, -1);
01855 }
01856
01857
01858 TQString TDELocale::formatTime(const TQTime &pTime, bool includeSecs) const
01859 {
01860 return formatTime( pTime, includeSecs, false );
01861 }
01862
01863 TQString TDELocale::formatTime(const TQTime &pTime, bool includeSecs, bool isDuration) const
01864 {
01865 const TQString rst = timeFormat();
01866
01867
01868
01869 TQChar *buffer = new TQChar[rst.length() * 3 / 2 + 30];
01870
01871 uint index = 0;
01872 bool escape = false;
01873 int number = 0;
01874
01875 for ( uint format_index = 0; format_index < rst.length(); format_index++ )
01876 {
01877 if ( !escape )
01878 {
01879 if ( (TQChar(rst.at( format_index )).unicode()) == '%' )
01880 escape = true;
01881 else
01882 buffer[index++] = rst.at( format_index );
01883 }
01884 else
01885 {
01886 switch ( TQChar(rst.at( format_index )).unicode() )
01887 {
01888 case '%':
01889 buffer[index++] = (QChar)'%';
01890 break;
01891 case 'H':
01892 put_it_in( buffer, index, pTime.hour() );
01893 break;
01894 case 'I':
01895 if ( isDuration )
01896 put_it_in( buffer, index, pTime.hour() );
01897 else
01898 put_it_in( buffer, index, ( pTime.hour() + 11) % 12 + 1 );
01899 break;
01900 case 'M':
01901 put_it_in( buffer, index, pTime.minute() );
01902 break;
01903 case 'S':
01904 if (includeSecs)
01905 put_it_in( buffer, index, pTime.second() );
01906 else if ( index > 0 )
01907 {
01908
01909
01910 --index;
01911 break;
01912 }
01913 break;
01914 case 'k':
01915 number = pTime.hour();
01916 case 'l':
01917
01918 if ( (TQChar(rst.at( format_index )).unicode()) == 'l' )
01919 number = isDuration ? pTime.hour() : (pTime.hour() + 11) % 12 + 1;
01920 if ( number / 10 )
01921 buffer[index++] = number / 10 + '0';
01922 buffer[index++] = number % 10 + '0';
01923 break;
01924 case 'p':
01925 if ( !isDuration )
01926 {
01927 TQString s;
01928 if ( pTime.hour() >= 12 )
01929 put_it_in( buffer, index, translate("pm") );
01930 else
01931 put_it_in( buffer, index, translate("am") );
01932 }
01933 break;
01934 default:
01935 buffer[index++] = rst.at( format_index );
01936 break;
01937 }
01938 escape = false;
01939 }
01940 }
01941 TQString ret( buffer, index );
01942 delete [] buffer;
01943 if ( isDuration )
01944 return ret.stripWhiteSpace();
01945 else
01946 return ret;
01947 }
01948
01949 bool TDELocale::use12Clock() const
01950 {
01951 if ((timeFormat().contains(TQString::fromLatin1("%I")) > 0) ||
01952 (timeFormat().contains(TQString::fromLatin1("%l")) > 0))
01953 return true;
01954 else
01955 return false;
01956 }
01957
01958 TQString TDELocale::languages() const
01959 {
01960 return d->languageList.join( TQString::fromLatin1(":") );
01961 }
01962
01963 TQStringList TDELocale::languageList() const
01964 {
01965 return d->languageList;
01966 }
01967
01968 TQString TDELocale::formatDateTime(const TQDateTime &pDateTime,
01969 bool shortFormat,
01970 bool includeSeconds) const
01971 {
01972 return translate("concatenation of dates and time", "%1 %2")
01973 .arg( formatDate( TQT_TQDATE_OBJECT(pDateTime.date()), shortFormat ) )
01974 .arg( formatTime( TQT_TQTIME_OBJECT(pDateTime.time()), includeSeconds ) );
01975 }
01976
01977 TQString i18n(const char* text)
01978 {
01979 register TDELocale *instance = TDEGlobal::locale();
01980 if (instance)
01981 return instance->translate(text);
01982 return TQString::fromUtf8(text);
01983 }
01984
01985 TQString i18n(const char* index, const char *text)
01986 {
01987 register TDELocale *instance = TDEGlobal::locale();
01988 if (instance)
01989 return instance->translate(index, text);
01990 return TQString::fromUtf8(text);
01991 }
01992
01993 TQString i18n(const char* singular, const char* plural, unsigned long n)
01994 {
01995 register TDELocale *instance = TDEGlobal::locale();
01996 if (instance)
01997 return instance->translate(singular, plural, n);
01998 if (n == 1)
01999 return put_n_in(TQString::fromUtf8(singular), n);
02000 else
02001 return put_n_in(TQString::fromUtf8(plural), n);
02002 }
02003
02004 void TDELocale::initInstance()
02005 {
02006 if (TDEGlobal::_locale)
02007 return;
02008
02009 TDEInstance *app = TDEGlobal::instance();
02010 if (app) {
02011 TDEGlobal::_locale = new TDELocale(TQString::fromLatin1(app->instanceName()));
02012
02013
02014 TQTextCodec::setCodecForLocale(TDEGlobal::_locale->codecForEncoding());
02015 }
02016 else
02017 kdDebug(173) << "no app name available using TDELocale - nothing to do\n";
02018 }
02019
02020 TQString TDELocale::langLookup(const TQString &fname, const char *rtype)
02021 {
02022 TQStringList search;
02023
02024
02025 const TQStringList localDoc = TDEGlobal::dirs()->resourceDirs(rtype);
02026
02027
02028 for (int id=localDoc.count()-1; id >= 0; --id)
02029 {
02030 TQStringList langs = TDEGlobal::locale()->languageList();
02031 langs.append( "en" );
02032 langs.remove( defaultLanguage() );
02033 TQStringList::ConstIterator lang;
02034 for (lang = langs.begin(); lang != langs.end(); ++lang)
02035 search.append(TQString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(fname));
02036 }
02037
02038
02039 TQStringList::Iterator it;
02040 for (it = search.begin(); it != search.end(); ++it)
02041 {
02042 kdDebug(173) << "Looking for help in: " << *it << endl;
02043
02044 TQFileInfo info(*it);
02045 if (info.exists() && info.isFile() && info.isReadable())
02046 return *it;
02047 }
02048
02049 return TQString::null;
02050 }
02051
02052 bool TDELocale::useDefaultLanguage() const
02053 {
02054 return language() == defaultLanguage();
02055 }
02056
02057 void TDELocale::initEncoding(TDEConfig *)
02058 {
02059 const int mibDefault = 4;
02060
02061
02062 setEncoding( TQTextCodec::codecForLocale()->mibEnum() );
02063
02064 if ( !d->codecForEncoding )
02065 {
02066 kdWarning(173) << " Defaulting to ISO 8859-1 encoding." << endl;
02067 setEncoding(mibDefault);
02068 }
02069
02070 Q_ASSERT( d->codecForEncoding );
02071 }
02072
02073 void TDELocale::initFileNameEncoding(TDEConfig *)
02074 {
02075
02076
02077 d->utf8FileEncoding = getenv("TDE_UTF8_FILENAMES") != 0;
02078 if (d->utf8FileEncoding)
02079 {
02080 TQFile::setEncodingFunction(TDELocale::encodeFileNameUTF8);
02081 TQFile::setDecodingFunction(TDELocale::decodeFileNameUTF8);
02082 }
02083
02084
02085 }
02086
02087 #ifdef USE_QT3
02088 TQCString TDELocale::encodeFileNameUTF8( const TQString & fileName )
02089 #endif // USE_QT3
02090 #ifdef USE_QT4
02091 QByteArray TDELocale::encodeFileNameUTF8( const QString & fileName )
02092 #endif // USE_QT4
02093 {
02094 return TQString(fileName).utf8();
02095 }
02096
02097 #ifdef USE_QT3
02098 TQString TDELocale::decodeFileNameUTF8( const TQCString & localFileName )
02099 #endif // USE_QT3
02100 #ifdef USE_QT4
02101 QString TDELocale::decodeFileNameUTF8( const QByteArray & localFileName )
02102 #endif // USE_QT4
02103 {
02104 return TQString::fromUtf8(localFileName);
02105 }
02106
02107 void TDELocale::setDateFormat(const TQString & format)
02108 {
02109 doFormatInit();
02110 m_dateFormat = format.stripWhiteSpace();
02111 }
02112
02113 void TDELocale::setDateFormatShort(const TQString & format)
02114 {
02115 doFormatInit();
02116 m_dateFormatShort = format.stripWhiteSpace();
02117 }
02118
02119 void TDELocale::setDateMonthNamePossessive(bool possessive)
02120 {
02121 doFormatInit();
02122 d->dateMonthNamePossessive = possessive;
02123 }
02124
02125 void TDELocale::setTimeFormat(const TQString & format)
02126 {
02127 doFormatInit();
02128 m_timeFormat = format.stripWhiteSpace();
02129 }
02130
02131 void TDELocale::setWeekStartsMonday(bool start)
02132 {
02133 doFormatInit();
02134 if (start)
02135 d->weekStartDay = 1;
02136 else
02137 d->weekStartDay = 7;
02138 }
02139
02140 void TDELocale::setWeekStartDay(int day)
02141 {
02142 doFormatInit();
02143 if (day>7 || day<1)
02144 d->weekStartDay = 1;
02145 else
02146 d->weekStartDay = day;
02147 }
02148
02149 TQString TDELocale::dateFormat() const
02150 {
02151 doFormatInit();
02152 return m_dateFormat;
02153 }
02154
02155 TQString TDELocale::dateFormatShort() const
02156 {
02157 doFormatInit();
02158 return m_dateFormatShort;
02159 }
02160
02161 TQString TDELocale::timeFormat() const
02162 {
02163 doFormatInit();
02164 return m_timeFormat;
02165 }
02166
02167 void TDELocale::setDecimalSymbol(const TQString & symbol)
02168 {
02169 doFormatInit();
02170 m_decimalSymbol = symbol.stripWhiteSpace();
02171 }
02172
02173 void TDELocale::setThousandsSeparator(const TQString & separator)
02174 {
02175 doFormatInit();
02176
02177 m_thousandsSeparator = separator;
02178 }
02179
02180 void TDELocale::setPositiveSign(const TQString & sign)
02181 {
02182 doFormatInit();
02183 m_positiveSign = sign.stripWhiteSpace();
02184 }
02185
02186 void TDELocale::setNegativeSign(const TQString & sign)
02187 {
02188 doFormatInit();
02189 m_negativeSign = sign.stripWhiteSpace();
02190 }
02191
02192 void TDELocale::setPositiveMonetarySignPosition(SignPosition signpos)
02193 {
02194 doFormatInit();
02195 m_positiveMonetarySignPosition = signpos;
02196 }
02197
02198 void TDELocale::setNegativeMonetarySignPosition(SignPosition signpos)
02199 {
02200 doFormatInit();
02201 m_negativeMonetarySignPosition = signpos;
02202 }
02203
02204 void TDELocale::setPositivePrefixCurrencySymbol(bool prefix)
02205 {
02206 doFormatInit();
02207 m_positivePrefixCurrencySymbol = prefix;
02208 }
02209
02210 void TDELocale::setNegativePrefixCurrencySymbol(bool prefix)
02211 {
02212 doFormatInit();
02213 m_negativePrefixCurrencySymbol = prefix;
02214 }
02215
02216 void TDELocale::setFracDigits(int digits)
02217 {
02218 doFormatInit();
02219 m_fracDigits = digits;
02220 }
02221
02222 void TDELocale::setMonetaryThousandsSeparator(const TQString & separator)
02223 {
02224 doFormatInit();
02225
02226 m_monetaryThousandsSeparator = separator;
02227 }
02228
02229 void TDELocale::setMonetaryDecimalSymbol(const TQString & symbol)
02230 {
02231 doFormatInit();
02232 m_monetaryDecimalSymbol = symbol.stripWhiteSpace();
02233 }
02234
02235 void TDELocale::setCurrencySymbol(const TQString & symbol)
02236 {
02237 doFormatInit();
02238 m_currencySymbol = symbol.stripWhiteSpace();
02239 }
02240
02241 int TDELocale::pageSize() const
02242 {
02243 doFormatInit();
02244 return d->pageSize;
02245 }
02246
02247 void TDELocale::setPageSize(int pageSize)
02248 {
02249
02250 doFormatInit();
02251 d->pageSize = pageSize;
02252 }
02253
02254 TDELocale::MeasureSystem TDELocale::measureSystem() const
02255 {
02256 doFormatInit();
02257 return d->measureSystem;
02258 }
02259
02260 void TDELocale::setMeasureSystem(MeasureSystem value)
02261 {
02262 doFormatInit();
02263 d->measureSystem = value;
02264 }
02265
02266 TQString TDELocale::defaultLanguage()
02267 {
02268 return TQString::fromLatin1("en_US");
02269 }
02270
02271 TQString TDELocale::defaultCountry()
02272 {
02273 return TQString::fromLatin1("C");
02274 }
02275
02276 const char * TDELocale::encoding() const
02277 {
02278 #ifdef Q_WS_WIN
02279 if (0==qstrcmp("System", codecForEncoding()->name()))
02280 {
02281
02282 strcpy(d->win32SystemEncoding, "cp ");
02283 if (GetLocaleInfoA( MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT),
02284 LOCALE_IDEFAULTANSICODEPAGE, d->win32SystemEncoding+3, sizeof(d->win32SystemEncoding)-3-1 ))
02285 {
02286 return d->win32SystemEncoding;
02287 }
02288 }
02289 #endif
02290 return codecForEncoding()->name();
02291 }
02292
02293 int TDELocale::encodingMib() const
02294 {
02295 return codecForEncoding()->mibEnum();
02296 }
02297
02298 int TDELocale::fileEncodingMib() const
02299 {
02300 if (d->utf8FileEncoding)
02301 return 106;
02302 return codecForEncoding()->mibEnum();
02303 }
02304
02305 TQTextCodec * TDELocale::codecForEncoding() const
02306 {
02307 return d->codecForEncoding;
02308 }
02309
02310 bool TDELocale::setEncoding(int mibEnum)
02311 {
02312 TQTextCodec * codec = TQTextCodec::codecForMib(mibEnum);
02313 if (codec)
02314 d->codecForEncoding = codec;
02315
02316 return codec != 0;
02317 }
02318
02319 TQStringList TDELocale::languagesTwoAlpha() const
02320 {
02321 if (d->langTwoAlpha.count())
02322 return d->langTwoAlpha;
02323
02324 const TQStringList &origList = languageList();
02325
02326 TQStringList result;
02327
02328 TDEConfig config(TQString::fromLatin1("language.codes"), true, false);
02329 config.setGroup("TwoLetterCodes");
02330
02331 for ( TQStringList::ConstIterator it = origList.begin();
02332 it != origList.end();
02333 ++it )
02334 {
02335 TQString lang = *it;
02336 TQStringList langLst;
02337 if (config.hasKey( lang ))
02338 langLst = config.readListEntry( lang );
02339 else
02340 {
02341 int i = lang.find('_');
02342 if (i >= 0)
02343 lang.truncate(i);
02344 langLst << lang;
02345 }
02346
02347 for ( TQStringList::ConstIterator langIt = langLst.begin();
02348 langIt != langLst.end();
02349 ++langIt )
02350 {
02351 if ( !(*langIt).isEmpty() && !result.contains( *langIt ) )
02352 result += *langIt;
02353 }
02354 }
02355 d->langTwoAlpha = result;
02356 return result;
02357 }
02358
02359 TQStringList TDELocale::allLanguagesTwoAlpha() const
02360 {
02361 if (!d->languages)
02362 d->languages = new TDEConfig("all_languages", true, false, "locale");
02363
02364 return d->languages->groupList();
02365 }
02366
02367 TQString TDELocale::twoAlphaToLanguageName(const TQString &code) const
02368 {
02369 if (!d->languages)
02370 d->languages = new TDEConfig("all_languages", true, false, "locale");
02371
02372 TQString groupName = code;
02373 const int i = groupName.find('_');
02374 groupName.replace(0, i, groupName.left(i).lower());
02375
02376 d->languages->setGroup(groupName);
02377 return d->languages->readEntry("Name");
02378 }
02379
02380 TQStringList TDELocale::allCountriesTwoAlpha() const
02381 {
02382 TQStringList countries;
02383 TQStringList paths = TDEGlobal::dirs()->findAllResources("locale", "l10n/*/entry.desktop");
02384 for(TQStringList::ConstIterator it = paths.begin();
02385 it != paths.end(); ++it)
02386 {
02387 TQString code = (*it).mid((*it).length()-16, 2);
02388 if (code != "/C")
02389 countries.append(code);
02390 }
02391 return countries;
02392 }
02393
02394 TQString TDELocale::twoAlphaToCountryName(const TQString &code) const
02395 {
02396 TDEConfig cfg("l10n/"+code.lower()+"/entry.desktop", true, false, "locale");
02397 cfg.setGroup("KCM Locale");
02398 return cfg.readEntry("Name");
02399 }
02400
02401 void TDELocale::setCalendar(const TQString & calType)
02402 {
02403 doFormatInit();
02404
02405 d->calendarType = calType;
02406
02407 delete d->calendar;
02408 d->calendar = 0;
02409 }
02410
02411 TQString TDELocale::calendarType() const
02412 {
02413 doFormatInit();
02414
02415 return d->calendarType;
02416 }
02417
02418 const KCalendarSystem * TDELocale::calendar() const
02419 {
02420 doFormatInit();
02421
02422
02423 if ( !d->calendar )
02424 d->calendar = KCalendarSystemFactory::create( d->calendarType, this );
02425
02426 return d->calendar;
02427 }
02428
02429 TDELocale::TDELocale(const TDELocale & rhs)
02430 {
02431 d = new TDELocalePrivate;
02432
02433 *this = rhs;
02434 }
02435
02436 TDELocale & TDELocale::operator=(const TDELocale & rhs)
02437 {
02438
02439 m_decimalSymbol = rhs.m_decimalSymbol;
02440 m_thousandsSeparator = rhs.m_thousandsSeparator;
02441 m_currencySymbol = rhs.m_currencySymbol;
02442 m_monetaryDecimalSymbol = rhs.m_monetaryDecimalSymbol;
02443 m_monetaryThousandsSeparator = rhs.m_monetaryThousandsSeparator;
02444 m_positiveSign = rhs.m_positiveSign;
02445 m_negativeSign = rhs.m_negativeSign;
02446 m_fracDigits = rhs.m_fracDigits;
02447 m_positivePrefixCurrencySymbol = rhs.m_positivePrefixCurrencySymbol;
02448 m_negativePrefixCurrencySymbol = rhs.m_negativePrefixCurrencySymbol;
02449 m_positiveMonetarySignPosition = rhs.m_positiveMonetarySignPosition;
02450 m_negativeMonetarySignPosition = rhs.m_negativeMonetarySignPosition;
02451
02452
02453 m_timeFormat = rhs.m_timeFormat;
02454 m_dateFormat = rhs.m_dateFormat;
02455 m_dateFormatShort = rhs.m_dateFormatShort;
02456
02457 m_language = rhs.m_language;
02458 m_country = rhs.m_country;
02459
02460
02461 *d = *rhs.d;
02462 d->languages = 0;
02463 d->calendar = 0;
02464
02465 return *this;
02466 }
02467
02468 bool TDELocale::setCharset(const TQString & ) { return true; }
02469 TQString TDELocale::charset() const { return TQString::fromLatin1("UTF-8"); }
02470
02471
02472 #if 0
02473 void nothing() { i18n("&Next"); }
02474 #endif