diff options
Diffstat (limited to 'src/corelib/tools/qlocale.cpp')
-rw-r--r-- | src/corelib/tools/qlocale.cpp | 797 |
1 files changed, 3 insertions, 794 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index ee3e530..4d042ae 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -78,11 +78,6 @@ QT_END_NAMESPACE #include <qdebug.h> #include <time.h> -#if defined(Q_OS_SYMBIAN) -#include <e32std.h> -#include "private/qcore_symbian_p.h" -#endif - #if defined(Q_OS_LINUX) && !defined(__UCLIBC__) # include <fenv.h> #endif @@ -303,7 +298,7 @@ static bool splitLocaleName(const QString &name, QChar *lang_begin, QChar *cntry return lang_len == 2 || lang_len == 3; } -static void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry) +void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry) { lang = QLocale::C; cntry = QLocale::AnyCountry; @@ -1282,794 +1277,8 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const } return QVariant(); } -#elif defined(Q_OS_SYMBIAN) - -static TExtendedLocale _s60Locale; - -// Type definitions for runtime resolved function pointers -typedef void (*FormatFunc)(TTime&, TDes&, const TDesC&, const TLocale&); -typedef TPtrC (*FormatSpecFunc)(TExtendedLocale&); - -// Runtime resolved functions -static FormatFunc ptrTimeFormatL = NULL; -static FormatSpecFunc ptrGetTimeFormatSpec = NULL; -static FormatSpecFunc ptrGetLongDateFormatSpec = NULL; -static FormatSpecFunc ptrGetShortDateFormatSpec = NULL; - -// Default functions if functions cannot be resolved -static void defaultTimeFormatL(TTime&, TDes& des, const TDesC&, const TLocale&) -{ - des.Zero(); -} - -static TPtrC defaultFormatSpec(TExtendedLocale&) -{ - return TPtrC(KNullDesC); -} - -/*! - Definition of struct for mapping Symbian to ISO locale -*/ -struct symbianToISO { - int symbian_language; - char iso_name[8]; -}; - -/*! - Mapping from Symbian to ISO locale -*/ -static const symbianToISO symbian_to_iso_list[] = { - { ELangEnglish, "en_GB" }, - { ELangFrench, "fr_FR" }, - { ELangGerman, "de_DE" }, - { ELangSpanish, "es_ES" }, - { ELangItalian, "it_IT" }, - { ELangSwedish, "sv_SE" }, - { ELangDanish, "da_DK" }, - { ELangNorwegian, "no_NO" }, - { ELangFinnish, "fi_FI" }, - { ELangAmerican, "en_US" }, - { ELangPortuguese, "pt_PT" }, - { ELangTurkish, "tr_TR" }, - { ELangIcelandic, "is_IS" }, - { ELangRussian, "ru_RU" }, - { ELangHungarian, "hu_HU" }, - { ELangDutch, "nl_NL" }, - { ELangBelgianFlemish, "nl_BE" }, - { ELangCzech, "cs_CZ" }, - { ELangSlovak, "sk_SK" }, - { ELangPolish, "pl_PL" }, - { ELangSlovenian, "sl_SI" }, - { ELangTaiwanChinese, "zh_TW" }, - { ELangHongKongChinese, "zh_HK" }, - { ELangPrcChinese, "zh_CN" }, - { ELangJapanese, "ja_JP" }, - { ELangThai, "th_TH" }, - { ELangArabic, "ar_AE" }, - { ELangTagalog, "tl_PH" }, - { ELangBulgarian, "bg_BG" }, - { ELangCatalan, "ca_ES" }, - { ELangCroatian, "hr_HR" }, - { ELangEstonian, "et_EE" }, - { ELangFarsi, "fa_IR" }, - { ELangCanadianFrench, "fr_CA" }, - { ELangGreek, "el_GR" }, - { ELangHebrew, "he_IL" }, - { ELangHindi, "hi_IN" }, - { ELangIndonesian, "id_ID" }, - { ELangLatvian, "lv_LV" }, - { ELangLithuanian, "lt_LT" }, - { ELangMalay, "ms_MY" }, - { ELangBrazilianPortuguese, "pt_BR" }, - { ELangRomanian, "ro_RO" }, - { ELangSerbian, "sr_YU" }, - { ELangLatinAmericanSpanish, "es" }, - { ELangUkrainian, "uk_UA" }, - { ELangUrdu, "ur_PK" }, // India/Pakistan - { ELangVietnamese, "vi_VN" }, -#ifdef __E32LANG_H__ -// 5.0 - { ELangBasque, "eu_ES" }, - { ELangGalician, "gl_ES" }, -#endif -#if !defined(__SERIES60_31__) - { ELangEnglish_Apac, "en" }, - { ELangEnglish_Taiwan, "en_TW" }, - { ELangEnglish_HongKong, "en_HK" }, - { ELangEnglish_Prc, "en_CN" }, - { ELangEnglish_Japan, "en_JP"}, - { ELangEnglish_Thailand, "en_TH" }, - { ELangMalay_Apac, "ms" } -#endif -}; - -/*! - Returns ISO name corresponding to the Symbian locale code \a sys_fmt. -*/ -static QByteArray symbianLocaleName(int code) -{ - //Number of Symbian to ISO locale mappings - static const int symbian_to_iso_count - = sizeof(symbian_to_iso_list)/sizeof(symbianToISO); - - int cmp = code - symbian_to_iso_list[0].symbian_language; - if (cmp < 0) - return 0; - - if (cmp == 0) - return symbian_to_iso_list[0].iso_name; - - int begin = 0; - int end = symbian_to_iso_count; - - while (end - begin > 1) { - uint mid = (begin + end)/2; - - const symbianToISO *elt = symbian_to_iso_list + mid; - int cmp = code - elt->symbian_language; - if (cmp < 0) - end = mid; - else if (cmp > 0) - begin = mid; - else - return elt->iso_name; - } - - return 0; -} - - -// order is: normal, abbr, nmode, nmode+abbr -static const char *us_locale_dep[] = { - "MM", "dd", "yyyy", "MM", "dd", - "M", "d", "yy", "M", "d", - "MMMM", "dd", "yyyy", "MMMM", "dd", - "MMM", "d", "yy", "MMM", "d" }; - -static const char *eu_locale_dep[] = { - "dd", "MM", "yyyy", "dd", "MM", - "d", "M", "yy", "d", "M", - "dd", "MMMM", "yyyy", "dd", "MMMM", - "d", "MMM", "yy", "d", "MMM" }; - -static const char *jp_locale_dep[] = { - "yyyy", "MM", "dd", "MM", "dd", - "yy", "M", "d", "M", "d", - "yyyy", "MMMM", "dd", "MMMM", "dd", - "yy", "MMM", "d", "MMM", "d" }; - -/*! - Returns a Qt version of the given \a sys_fmt Symbian locale format string. -*/ -static QString s60ToQtFormat(const QString &sys_fmt) -{ - TLocale *locale = _s60Locale.GetLocale(); - - QString result; - QString other; - QString qtformatchars = QString::fromLatin1("adhmsyzAHM"); - - QChar c; - int i = 0; - bool open_escape = false; - bool abbrev_next = false; - bool locale_indep_ordering = false; - bool minus_mode = false; - bool plus_mode = false; - bool n_mode = false; - TTimeFormat tf = locale->TimeFormat(); - - while (i < sys_fmt.size()) { - - c = sys_fmt.at(i); - - // let formatting thru - if (c.unicode() == '%') { - // if we have gathered string, concat it - if (!other.isEmpty()) { - result += other; - other.clear(); - } - // if we have open escape, end it - if (open_escape) { - result += QLatin1Char('\''); - open_escape = false; - } - - ++i; - if (i >= sys_fmt.size()) - break; - - c = sys_fmt.at(i); - - // process specials - abbrev_next = c.unicode() == '*'; - plus_mode = c.unicode() == '+'; - minus_mode = c.unicode() == '-'; - - if (abbrev_next || plus_mode || minus_mode) { - ++i; - if (i >= sys_fmt.size()) - break; - - c = sys_fmt.at(i); - - if (plus_mode || minus_mode) { - // break on undefined plus/minus mode - if (c.unicode() != 'A' && c.unicode() != 'B') - break; - } - } - - switch (c.unicode()) { - case 'F': - // locale indep mode on - locale_indep_ordering = true; - break; - - case '/': - // date sep 0-3 - ++i; - if (i >= sys_fmt.size()) - break; - - c = sys_fmt.at(i); - if (c.isDigit() && c.digitValue() <= 3) { - TChar s = locale->DateSeparator(c.digitValue()); - TUint val = s; - // some indexes return zero for empty - if (val > 0) - result += QChar(val); - } - break; - - case 'D': - if (!locale_indep_ordering) - break; - - if (!abbrev_next) - result += QLatin1String("dd"); - else - result += QLatin1Char('d'); - - break; - - case 'M': - if (!locale_indep_ordering) - break; - - if (!n_mode) { - if (!abbrev_next) - result += QLatin1String("MM"); - else - result += QLatin1String("M"); - } else { - if (!abbrev_next) - result += QLatin1String("MMMM"); - else - result += QLatin1String("MMM"); - } - - break; - - case 'N': - n_mode = true; - - if (!locale_indep_ordering) - break; - - if (!abbrev_next) - result += QLatin1String("MMMM"); - else - result += QLatin1String("MMM"); - - break; - - case 'Y': - if (!locale_indep_ordering) - break; - - if (!abbrev_next) - result += QLatin1String("yyyy"); - else - result += QLatin1String("yy"); - - break; - - case 'E': - if (!abbrev_next) - result += QLatin1String("dddd"); - else - result += QLatin1String("ddd"); - - break; - - case ':': - // timesep 0-3 - ++i; - if (i >= sys_fmt.size()) - break; - - c = sys_fmt.at(i); - if (c.isDigit() && c.digitValue() <= 3) { - TChar s = locale->TimeSeparator(c.digitValue()); - TUint val = s; - // some indexes return zero for empty - if (val > 0) - result += QChar(val); - } - - break; - - case 'J': - if (tf == ETime24 && !abbrev_next) - result += QLatin1String("hh"); - else - result += QLatin1Char('h'); - - break; - - case 'H': - if (!abbrev_next) - result += QLatin1String("hh"); - else - result += QLatin1Char('h'); - - break; - - case 'I': - result += QLatin1Char('h'); - break; - - case 'T': - if (!abbrev_next) - result += QLatin1String("mm"); - else - result += QLatin1Char('m'); - - break; - - case 'S': - if (!abbrev_next) - result += QLatin1String("ss"); - else - result += QLatin1Char('s'); - - break; - - case 'B': - // only done for 12h clock - if (tf == ETime24) - break; - - // fallthru to A - case 'A': { - // quickie to get capitalization, can't use s60 string as is because Qt 'hh' format's am/pm logic - TAmPmName ampm = TAmPmName(); - TChar first(ampm[0]); - QString qtampm = QString::fromLatin1(first.IsUpper() ? "AP" : "ap"); - - int pos = locale->AmPmSymbolPosition(); - - if ((minus_mode && pos != ELocaleBefore) || - (plus_mode && pos != ELocaleAfter)) - break; - - if (!abbrev_next && locale->AmPmSpaceBetween()) { - if (pos == ELocaleBefore) - qtampm.append(QLatin1Char(' ')); - else - qtampm.prepend(QLatin1Char(' ')); - } - - result += qtampm; - } - break; - - case '.': { - // decimal sep - TChar s = locale->DecimalSeparator(); - TUint val = s; - if (val > 0) - result += QChar(val); - } - break; - - case 'C': - // six digits in s60, three digits in qt - if (!abbrev_next) { - result += QLatin1String("zzz"); - } else { - // next char is number from 0-6, how many digits to display - ++i; - if (i >= sys_fmt.size()) - break; - - c = sys_fmt.at(i); - - if (c.isDigit()) { - // try to match wanted digits - QChar val(c.digitValue()); - - if (val >= 3) { - result += QLatin1String("zzz"); - } else if (val > 0) { - result += QLatin1Char('z'); - } - } - } - break; - - // these cases fallthru - case '1': - case '2': - case '3': - case '4': - case '5': - - // shouldn't parse these with %F - if (locale_indep_ordering) - break; - - TDateFormat df = locale->DateFormat(); - - const char **locale_dep; - switch (df) { - default: // fallthru to american - case EDateAmerican: - locale_dep = us_locale_dep; - break; - case EDateEuropean: - locale_dep = eu_locale_dep; - break; - case EDateJapanese: - locale_dep = jp_locale_dep; - break; - } - int offset = 0; - if (abbrev_next) - offset += 5; - if (n_mode) - offset += 10; - - result += QLatin1String(locale_dep[offset + (c.digitValue()-1)]); - break; - - case '%': // fallthru percent - // any junk gets copied as is - default: - result += c; - break; - - case 'Z': // Qt doesn't support these :( - case 'X': - case 'W': - break; - } - } else { - // double any single quotes, don't begin escape - if (c.unicode() == '\'') { - // end open escape - if (open_escape) { - result += other; - other.clear(); - result += QLatin1Char('\''); - open_escape = false; - } - - other += c; - } - - // gather chars and escape them in one go if any format chars are found - if (!open_escape && qtformatchars.indexOf(c) != -1) { - result += QLatin1Char('\''); - open_escape = true; - } - other += c; - } - - ++i; - } - - if (!other.isEmpty()) - result += other; - if (open_escape) - result += QLatin1Char('\''); - - return result; -} - -/*! - Retrieves Symbian locale decimal separator. -*/ -static QString symbianDecimalPoint() -{ - TLocale *locale = _s60Locale.GetLocale(); - - TChar decPoint = locale->DecimalSeparator(); - int val = decPoint; - return QChar(val); -} - -/*! - Retrieves Symbian locale group separator. -*/ -static QString symbianGroupSeparator() -{ - TLocale *locale = _s60Locale.GetLocale(); - - TChar grpSep = locale->ThousandsSeparator(); - int val = grpSep; - return QChar(val); -} - -/*! - Retrieves Symbian locale zero digit. -*/ -static QString symbianZeroDigit() -{ - TLocale *locale = _s60Locale.GetLocale(); - - // TDigitType enumeration value returned by TLocale - // will always correspond to zero digit unicode value. - TDigitType digit = locale->DigitType(); - return QChar(digit); -} - -/*! - Retrieves a day name from Symbian locale. The \a day is an integer - from 1 to 7. When \a short_format is true the method returns - the day in short format. Otherwise it returns the day in a long format. -*/ -static QString symbianDayName(int day, bool short_format) -{ - day -= 1; - - if (day < 0 || day > 6) - return QString(); - - if (short_format) { - return qt_TDes2QStringL(TDayNameAbb(TDay(day))); - } else { - return qt_TDes2QStringL(TDayName(TDay(day))); - } -} - -/*! - Retrieves a month name from Symbian locale. The \a month is an integer - from 1 to 12. When \a short_format is true the method returns - the month in short format. Otherwise it returns the month in a long format. -*/ -static QString symbianMonthName(int month, bool short_format) -{ - month -= 1; - if (month < 0 || month > 11) - return QString(); - - if (short_format) { - return qt_TDes2QStringL(TMonthNameAbb(TMonth(month))); - } else { - return qt_TDes2QStringL(TMonthName(TMonth(month))); - } -} - -/*! - Retrieves date format from Symbian locale and - transforms it to Qt format. - - When \a short_format is true the method returns - short date format. Otherwise it returns the long format. -*/ -static QString symbianDateFormat(bool short_format) -{ - TPtrC dateFormat; - - if (short_format) { - dateFormat.Set(ptrGetShortDateFormatSpec(_s60Locale)); - } else { - dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale)); - } - - return s60ToQtFormat(qt_TDesC2QStringL(dateFormat)); -} - -/*! - Retrieves time format from Symbian locale and - transforms it to Qt format. -*/ -static QString symbianTimeFormat() -{ - return s60ToQtFormat(qt_TDesC2QStringL(ptrGetTimeFormatSpec(_s60Locale))); -} - -/*! - Returns localized string representation of given \a date - formatted with Symbian locale date format. - - If \a short_format is true the format will be a short version. - Otherwise it uses a longer version. -*/ -static QString symbianDateToString(const QDate &date, bool short_format) -{ - int month = date.month() - 1; - int day = date.day() - 1; - int year = date.year(); - - TDateTime dateTime; - dateTime.Set(year, TMonth(month), day, 0, 0, 0, 0); - - TTime timeStr(dateTime); - TBuf<KMaxLongDateFormatSpec*2> buffer; - - TPtrC dateFormat; - if (short_format) { - dateFormat.Set(ptrGetShortDateFormatSpec(_s60Locale)); - } else { - dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale)); - } - - TRAPD(err, ptrTimeFormatL(timeStr, buffer, dateFormat, *_s60Locale.GetLocale());) - - if (err == KErrNone) - return qt_TDes2QStringL(buffer); - else - return QString(); -} - -/*! - Returns localized string representation of given \a time - formatted with Symbian locale time format. -*/ -static QString symbianTimeToString(const QTime &time) -{ - int hour = time.hour(); - int minute = time.minute(); - int second = time.second(); - int milliseconds = 0; - - TDateTime dateTime; - dateTime.Set(0, TMonth(0), 0, hour, minute, second, milliseconds); - - TTime timeStr(dateTime); - TBuf<KMaxTimeFormatSpec*2> buffer; - - TRAPD(err, ptrTimeFormatL( - timeStr, - buffer, - ptrGetTimeFormatSpec(_s60Locale), - *_s60Locale.GetLocale()); - ) - - if (err == KErrNone) - return qt_TDes2QStringL(buffer); - else - return QString(); -} - -/*! - Returns the measurement system stored in Symbian locale - - \sa QLocale::MeasurementSystem -*/ -static QLocale::MeasurementSystem symbianMeasurementSystem() -{ - TLocale *locale = _s60Locale.GetLocale(); - - TUnitsFormat unitFormat = locale->UnitsGeneral(); - if (unitFormat == EUnitsImperial) - return QLocale::ImperialSystem; - else - return QLocale::MetricSystem; -} - -QLocale QSystemLocale::fallbackLocale() const -{ - // load system data before query calls - static bool initDone = false; - if (!initDone) { - _s60Locale.LoadSystemSettings(); - - // Initialize platform version dependent function pointers - ptrTimeFormatL = reinterpret_cast<FormatFunc> - (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL)); - ptrGetTimeFormatSpec = reinterpret_cast<FormatSpecFunc> - (qt_resolveS60PluginFunc(S60Plugin_GetTimeFormatSpec)); - ptrGetLongDateFormatSpec = reinterpret_cast<FormatSpecFunc> - (qt_resolveS60PluginFunc(S60Plugin_GetLongDateFormatSpec)); - ptrGetShortDateFormatSpec = reinterpret_cast<FormatSpecFunc> - (qt_resolveS60PluginFunc(S60Plugin_GetShortDateFormatSpec)); - if (!ptrTimeFormatL) - ptrTimeFormatL = &defaultTimeFormatL; - if (!ptrGetTimeFormatSpec) - ptrGetTimeFormatSpec = &defaultFormatSpec; - if (!ptrGetLongDateFormatSpec) - ptrGetLongDateFormatSpec = &defaultFormatSpec; - if (!ptrGetShortDateFormatSpec) - ptrGetShortDateFormatSpec = &defaultFormatSpec; - } - - TLanguage lang = User::Language(); - QString locale = symbianLocaleName(lang); - return QLocale(locale); -} - -/*! - Generic query method for locale data. Provides indirection. - Denotes the \a type of the query - with \a in as input data depending on the query. - - \sa QSystemLocale::QueryType -*/ -QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const -{ - switch(type) { - case DecimalPoint: - return symbianDecimalPoint(); - case GroupSeparator: - return symbianGroupSeparator(); - - case ZeroDigit: - return symbianZeroDigit(); - - case DayNameLong: - case DayNameShort: - return symbianDayName(in.toInt(), (type == DayNameShort) ); - - case MonthNameLong: - case MonthNameShort: - return symbianMonthName(in.toInt(), (type == MonthNameShort) ); - - case DateFormatLong: - case DateFormatShort: - return symbianDateFormat( (type == DateFormatShort) ); - case TimeFormatLong: - case TimeFormatShort: - return symbianTimeFormat(); - case DateTimeFormatLong: - case DateTimeFormatShort: - return symbianDateFormat( (type == DateTimeFormatShort) ) + QLatin1Char(' ') + symbianTimeFormat(); - case DateToStringShort: - case DateToStringLong: - return symbianDateToString(in.toDate(), (type == DateToStringShort) ); - case TimeToStringShort: - case TimeToStringLong: - return symbianTimeToString(in.toTime()); - case DateTimeToStringShort: - case DateTimeToStringLong: { - const QDateTime dt = in.toDateTime(); - return symbianDateToString(dt.date(), (type == DateTimeToStringShort) ) - + QLatin1Char(' ') + symbianTimeToString(dt.time()); - } - case MeasurementSystem: - return static_cast<int>(symbianMeasurementSystem()); - case LanguageId: - case CountryId: { - TLanguage language = User::Language(); - QString locale = symbianLocaleName(language); - QLocale::Language lang; - QLocale::Country cntry; - getLangAndCountry(locale, lang, cntry); - if (type == LanguageId) - return lang; - // few iso codes have no country and will use this - if (cntry == QLocale::AnyCountry) - return fallbackLocale().country(); - - return cntry; - } - case NegativeSign: - case PositiveSign: - case AMText: - case PMText: - break; - default: - break; - } - return QVariant(); -} - -#elif defined(Q_OS_UNIX) +#elif defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) static uint unixGetSystemMeasurementSystem() { @@ -2113,7 +1322,7 @@ QVariant QSystemLocale::query(QueryType type, QVariant /* in */) const } } -#else +#elif !defined(Q_OS_SYMBIAN) /*! Returns a fallback locale, that will get used for everything that |