diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2011-03-07 16:05:08 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2011-03-17 16:38:02 (GMT) |
commit | bb86e77cc437b92d49692bb7026c57626d77079f (patch) | |
tree | 95e590f98e8f905426f0eeaf4c4673c2cfdef6cc /src/corelib | |
parent | 0ddf35198fa789c4c1b479e09241fff850a08442 (diff) | |
download | Qt-bb86e77cc437b92d49692bb7026c57626d77079f.zip Qt-bb86e77cc437b92d49692bb7026c57626d77079f.tar.gz Qt-bb86e77cc437b92d49692bb7026c57626d77079f.tar.bz2 |
Refactored QLocale on Windows.
Added LocaleChanged system locale enum that is queried whenever we detect that
the system locale is changed. This should make it easier to have cached values
in the system locale implementations.
Reviewed-by: Zeno Albisser
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/tools/qlocale.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qlocale.h | 3 | ||||
-rw-r--r-- | src/corelib/tools/qlocale_win.cpp | 625 |
3 files changed, 358 insertions, 274 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 4c0b154..31cf85b 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -477,6 +477,10 @@ void QLocalePrivate::updateSystemPrivate() const QSystemLocale *sys_locale = systemLocale(); if (!system_lp) system_lp = globalLocalePrivate(); + + // tell the object that the system locale has changed. + sys_locale->query(QSystemLocale::LocaleChanged, QVariant()); + *system_lp = *sys_locale->fallbackLocale().d(); #if defined(Q_OS_SYMBIAN) diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index 4af6e82..bd50e82 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -113,7 +113,8 @@ public: UILanguages, // QStringList StringToStandardQuotation, // QString in: QStringRef to quote StringToAlternateQuotation, // QString in: QStringRef to quote - ScriptId // uint + ScriptId, // uint + LocaleChanged // system locale changed }; virtual QVariant query(QueryType type, QVariant in) const; virtual QLocale fallbackLocale() const; diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp index 8789e33..905ecd9 100644 --- a/src/corelib/tools/qlocale_win.cpp +++ b/src/corelib/tools/qlocale_win.cpp @@ -57,127 +57,128 @@ QT_BEGIN_NAMESPACE +static QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT); +static const char *winLangCodeToIsoName(int code); +static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT); +static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT); + +#ifndef QT_NO_SYSTEMLOCALE + #ifndef MUI_LANGUAGE_NAME #define MUI_LANGUAGE_NAME 0x8 #endif -static const char *winLangCodeToIsoName(int code); -static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT); -static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT); +struct QSystemLocalePrivate +{ + QSystemLocalePrivate(); + + QChar zeroDigit(); + QChar decimalPoint(); + QChar groupSeparator(); + QChar negativeSign(); + QChar positiveSign(); + QVariant dateFormat(QLocale::FormatType); + QVariant timeFormat(QLocale::FormatType); + QVariant dateTimeFormat(QLocale::FormatType); + QVariant dayName(int, QLocale::FormatType); + QVariant monthName(int, QLocale::FormatType); + QVariant toString(const QDate &, QLocale::FormatType); + QVariant toString(const QTime &, QLocale::FormatType); + QVariant toString(const QDateTime &, QLocale::FormatType); + QVariant measurementSystem(); + QVariant amText(); + QVariant pmText(); + QVariant firstDayOfWeek(); + QVariant currencySymbol(QLocale::CurrencySymbolFormat); + QVariant toCurrencyString(const QSystemLocale::CurrencyToStringArgument &); + QVariant uiLanguages(); + + void update(); + +private: + QByteArray langEnvVar; + + // cached values: + LCID lcid; + + QString getLocaleInfo(LCTYPE type, int maxlen = 0); + int getLocaleInfo_int(LCTYPE type, int maxlen = 0); + QChar getLocaleInfo_qchar(LCTYPE type); + + enum SubstitutionType { + SContext, + SAlways, + SNever + }; + + SubstitutionType substitution(); + QString &substituteDigits(QString &string); + + static QString winToQtFormat(const QString &sys_fmt); -static QString qt_getLocaleInfo(LCID lcid, LCTYPE type, int maxlen = 0) +}; +Q_GLOBAL_STATIC(QSystemLocalePrivate, systemLocalePrivate) + +QSystemLocalePrivate::QSystemLocalePrivate() +{ + langEnvVar = qgetenv("LANG"); + lcid = GetUserDefaultLCID(); +} + +QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) { QVarLengthArray<wchar_t, 64> buf(maxlen ? maxlen : 64); if (!GetLocaleInfo(lcid, type, buf.data(), buf.size())) return QString(); + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + int cnt = GetLocaleInfo(lcid, type, 0, 0); + if (cnt == 0) + return QString(); + buf.resize(cnt); + if (!GetLocaleInfo(lcid, type, buf.data(), buf.size())) + return QString(); + } return QString::fromWCharArray(buf.data()); } -static int qt_getLocaleInfo_int(LCID lcid, LCTYPE type, int maxlen = 0) + +int QSystemLocalePrivate::getLocaleInfo_int(LCTYPE type, int maxlen) { - QString str = qt_getLocaleInfo(lcid, type, maxlen); + QString str = getLocaleInfo(type, maxlen); bool ok = false; int v = str.toInt(&ok); return ok ? v : 0; } -static QString getWinLocaleInfo(LCTYPE type) -{ - LCID id = GetUserDefaultLCID(); - int cnt = GetLocaleInfo(id, type, 0, 0) * 2; - - if (cnt == 0) { - qWarning("QLocale: empty windows locale info (%d)", (int)type); - return QString(); - } - - QByteArray buff(cnt, 0); - - cnt = GetLocaleInfo(id, type, reinterpret_cast<wchar_t*>(buff.data()), buff.size() / 2); - - if (cnt == 0) { - qWarning("QLocale: empty windows locale info (%d)", (int)type); - return QString(); - } - - return QString::fromWCharArray(reinterpret_cast<const wchar_t *>(buff.data())); -} - -static QByteArray envVarLocale() +QChar QSystemLocalePrivate::getLocaleInfo_qchar(LCTYPE type) { - static QByteArray lang = qgetenv("LANG"); - return lang; + QString str = getLocaleInfo(type); + return str.isEmpty() ? QChar() : str.at(0); } -QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT) -{ - QByteArray result; - if (id == LOCALE_USER_DEFAULT) { - result = envVarLocale(); - QString lang, script, cntry; - if ( result == "C" || (!result.isEmpty() - && splitLocaleName(QString::fromLocal8Bit(result), lang, script, cntry)) ) { - long id = 0; - bool ok = false; - id = qstrtoll(result.data(), 0, 0, &ok); - if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX ) - return result; - else - return winLangCodeToIsoName( (int)id ); - } - } - -#if defined(Q_OS_WINCE) - result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID()); -#else - if (id == LOCALE_USER_DEFAULT) - id = GetUserDefaultLCID(); - QString resultuage = winIso639LangName(id); - QString country = winIso3116CtryName(id); - result = resultuage.toLatin1(); - if (!country.isEmpty()) { - result += '_'; - result += country.toLatin1(); - } -#endif - - return result; -} - -Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id) -{ - return QLocale(QString::fromLatin1(getWinLocaleName(id))); -} - -enum SubstitutionType { - SContext, - SAlways, - SNever -}; - -static SubstitutionType substitution(LCID lcid) +QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution() { wchar_t buf[8]; - if (!GetLocaleInfo(lcid, LOCALE_IDIGITSUBSTITUTION, buf, 8)) - return SNever; + if (!GetLocaleInfo(lcid, LOCALE_IDIGITSUBSTITUTION, buf, 8)) // ### + return QSystemLocalePrivate::SNever; if (buf[0] == '1') - return SNever; + return QSystemLocalePrivate::SNever; if (buf[0] == '0') - return SContext; + return QSystemLocalePrivate::SContext; if (buf[0] == '2') - return SAlways; + return QSystemLocalePrivate::SAlways; wchar_t digits[11]; if (!GetLocaleInfo(lcid, LOCALE_SNATIVEDIGITS, digits, 11)) - return SNever; + return QSystemLocalePrivate::SNever; const wchar_t zero = digits[0]; if (buf[0] == zero + 2) - return SAlways; - return SNever; + return QSystemLocalePrivate::SAlways; + return QSystemLocalePrivate::SNever; } -static QString &substituteDigits(LCID lcid, QString &string) +QString &QSystemLocalePrivate::substituteDigits(QString &string) { wchar_t buf[11]; - if (!GetLocaleInfo(lcid, LOCALE_SNATIVEDIGITS, buf, 11)) + if (!GetLocaleInfo(lcid, LOCALE_SNATIVEDIGITS, buf, 11)) // ### return string; ushort zero = (ushort)buf[0]; ushort *qch = (ushort *)string.data(); @@ -188,117 +189,63 @@ static QString &substituteDigits(LCID lcid, QString &string) return string; } -static QString winToQtFormat(const QString &sys_fmt) +QChar QSystemLocalePrivate::zeroDigit() { - QString result; - int i = 0; - - while (i < sys_fmt.size()) { - if (sys_fmt.at(i).unicode() == QLatin1Char('\'')) { - QString text = readEscapedFormatString(sys_fmt, &i); - if (text == QLatin1String("'")) - result += QLatin1String("''"); - else - result += QString(QLatin1Char('\'') + text + QLatin1Char('\'')); - continue; - } - - QChar c = sys_fmt.at(i); - int repeat = repeatCount(sys_fmt, i); - - switch (c.unicode()) { - // Date - case 'y': - if (repeat > 5) - repeat = 5; - else if (repeat == 3) - repeat = 2; - switch (repeat) { - case 1: - result += QLatin1String("yy"); // "y" unsupported by Qt, use "yy" - break; - case 5: - result += QLatin1String("yyyy"); // "yyyyy" same as "yyyy" on Windows - break; - default: - result += QString(repeat, QLatin1Char('y')); - break; - } - break; - case 'g': - if (repeat > 2) - repeat = 2; - switch (repeat) { - case 2: - break; // no equivalent of "gg" in Qt - default: - result += QLatin1Char('g'); - break; - } - break; - case 't': - if (repeat > 2) - repeat = 2; - result += QLatin1String("AP"); // "t" unsupported, use "AP" - break; - default: - result += QString(repeat, c); - break; - } + return getLocaleInfo_qchar(LOCALE_SNATIVEDIGITS); +} - i += repeat; - } +QChar QSystemLocalePrivate::decimalPoint() +{ + return getLocaleInfo_qchar(LOCALE_SDECIMAL); +} - return result; +QChar QSystemLocalePrivate::groupSeparator() +{ + return getLocaleInfo_qchar(LOCALE_STHOUSAND); } -static QString winDateToString(const QDate &date, DWORD flags) +QChar QSystemLocalePrivate::negativeSign() { - SYSTEMTIME st; - memset(&st, 0, sizeof(SYSTEMTIME)); - st.wYear = date.year(); - st.wMonth = date.month(); - st.wDay = date.day(); + return getLocaleInfo_qchar(LOCALE_SNEGATIVESIGN); +} - LCID id = GetUserDefaultLCID(); +QChar QSystemLocalePrivate::positiveSign() +{ + return getLocaleInfo_qchar(LOCALE_SPOSITIVESIGN); +} - wchar_t buf[255]; - if (GetDateFormat(id, flags, &st, NULL, buf, 255)) { - QString format = QString::fromWCharArray(buf); - if (substitution(id) == SAlways) - substituteDigits(id, format); - return format; +QVariant QSystemLocalePrivate::dateFormat(QLocale::FormatType type) +{ + switch (type) { + case QLocale::ShortFormat: + return winToQtFormat(getLocaleInfo(LOCALE_SSHORTDATE)); + case QLocale::LongFormat: + return winToQtFormat(getLocaleInfo(LOCALE_SLONGDATE)); + case QLocale::NarrowFormat: + break; } - return QString(); + return QVariant(); } -static QString winTimeToString(const QTime &time, bool longFormat) +QVariant QSystemLocalePrivate::timeFormat(QLocale::FormatType type) { - SYSTEMTIME st; - memset(&st, 0, sizeof(SYSTEMTIME)); - st.wHour = time.hour(); - st.wMinute = time.minute(); - st.wSecond = time.second(); - st.wMilliseconds = 0; - - DWORD flags = 0; - if (!longFormat && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) - flags = 2; // TIME_NOSECONDS - - LCID id = GetUserDefaultLCID(); - - wchar_t buf[255]; - if (GetTimeFormat(id, flags, &st, NULL, buf, 255)) { - QString format = QString::fromWCharArray(buf); - if (substitution(id) == SAlways) - substituteDigits(id, format); - return format; + switch (type) { + case QLocale::ShortFormat: + return winToQtFormat(getLocaleInfo(LOCALE_STIMEFORMAT)); //### + case QLocale::LongFormat: + return winToQtFormat(getLocaleInfo(LOCALE_STIMEFORMAT)); + case QLocale::NarrowFormat: + break; } + return QVariant(); +} - return QString(); +QVariant QSystemLocalePrivate::dateTimeFormat(QLocale::FormatType type) +{ + return QString(dateFormat(type).toString() + QLatin1Char(' ') + timeFormat(type).toString()); } -static QString winDayName(int day, bool short_format) +QVariant QSystemLocalePrivate::dayName(int day, QLocale::FormatType type) { static const LCTYPE short_day_map[] = { LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, @@ -312,12 +259,12 @@ static QString winDayName(int day, bool short_format) day -= 1; - LCTYPE type = short_format + LCTYPE lctype = (type == QLocale::ShortFormat || type == QLocale::NarrowFormat) ? short_day_map[day] : long_day_map[day]; - return getWinLocaleInfo(type); + return getLocaleInfo(lctype); } -static QString winMonthName(int month, bool short_format) +QVariant QSystemLocalePrivate::monthName(int month, QLocale::FormatType type) { static const LCTYPE short_month_map[] = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3, @@ -335,16 +282,63 @@ static QString winMonthName(int month, bool short_format) if (month < 0 || month > 11) return QString(); - LCTYPE type = short_format ? short_month_map[month] : long_month_map[month]; - return getWinLocaleInfo(type); + LCTYPE lctype = (type == QLocale::ShortFormat || type == QLocale::NarrowFormat) + ? short_month_map[month] : long_month_map[month]; + return getLocaleInfo(lctype); } -static QLocale::MeasurementSystem winSystemMeasurementSystem() +QVariant QSystemLocalePrivate::toString(const QDate &date, QLocale::FormatType type) +{ + SYSTEMTIME st; + memset(&st, 0, sizeof(SYSTEMTIME)); + st.wYear = date.year(); + st.wMonth = date.month(); + st.wDay = date.day(); + + DWORD flags = (type == QLocale::LongFormat ? DATE_LONGDATE : DATE_SHORTDATE); + wchar_t buf[255]; + if (GetDateFormat(lcid, flags, &st, NULL, buf, 255)) { + QString format = QString::fromWCharArray(buf); + if (substitution() == SAlways) + substituteDigits(format); + return format; + } + return QString(); +} + +QVariant QSystemLocalePrivate::toString(const QTime &time, QLocale::FormatType type) +{ + SYSTEMTIME st; + memset(&st, 0, sizeof(SYSTEMTIME)); + st.wHour = time.hour(); + st.wMinute = time.minute(); + st.wSecond = time.second(); + st.wMilliseconds = 0; + + DWORD flags = 0; + if (type != QLocale::LongFormat && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) + flags = 2; // TIME_NOSECONDS + + wchar_t buf[255]; + if (GetTimeFormat(lcid, flags, &st, NULL, buf, 255)) { + QString format = QString::fromWCharArray(buf); + if (substitution() == SAlways) + substituteDigits(format); + return format; + } + return QString(); +} + +QVariant QSystemLocalePrivate::toString(const QDateTime &dt, QLocale::FormatType type) +{ + return QString(toString(dt.date(), type).toString() + QLatin1Char(' ') + toString(dt.time(), type).toString()); +} + +QVariant QSystemLocalePrivate::measurementSystem() { - LCID id = GetUserDefaultLCID(); wchar_t output[2]; - if (GetLocaleInfo(id, LOCALE_IMEASURE, output, 2)) { + if (GetLocaleInfo(lcid, LOCALE_IMEASURE, output, 2)) { QString iMeasure = QString::fromWCharArray(output); if (iMeasure == QLatin1String("1")) { return QLocale::ImperialSystem; @@ -354,44 +348,40 @@ static QLocale::MeasurementSystem winSystemMeasurementSystem() return QLocale::MetricSystem; } -static QString winSystemAMText() +QVariant QSystemLocalePrivate::amText() { - LCID id = GetUserDefaultLCID(); wchar_t output[15]; // maximum length including terminating zero character for Win2003+ - if (GetLocaleInfo(id, LOCALE_S1159, output, 15)) { + if (GetLocaleInfo(lcid, LOCALE_S1159, output, 15)) { return QString::fromWCharArray(output); } - return QString(); + return QVariant(); } -static QString winSystemPMText() +QVariant QSystemLocalePrivate::pmText() { - LCID id = GetUserDefaultLCID(); wchar_t output[15]; // maximum length including terminating zero character for Win2003+ - if (GetLocaleInfo(id, LOCALE_S2359, output, 15)) { + if (GetLocaleInfo(lcid, LOCALE_S2359, output, 15)) { return QString::fromWCharArray(output); } - return QString(); + return QVariant(); } -static quint8 winSystemFirstDayOfWeek() +QVariant QSystemLocalePrivate::firstDayOfWeek() { - LCID id = GetUserDefaultLCID(); wchar_t output[4]; // maximum length including terminating zero character for Win2003+ - if (GetLocaleInfo(id, LOCALE_IFIRSTDAYOFWEEK, output, 4)) + if (GetLocaleInfo(lcid, LOCALE_IFIRSTDAYOFWEEK, output, 4)) return QString::fromWCharArray(output).toUInt()+1; return 1; } -QString winCurrencySymbol(QLocale::CurrencySymbolFormat format) +QVariant QSystemLocalePrivate::currencySymbol(QLocale::CurrencySymbolFormat format) { - LCID lcid = GetUserDefaultLCID(); wchar_t buf[13]; switch (format) { case QLocale::CurrencySymbol: @@ -416,11 +406,10 @@ QString winCurrencySymbol(QLocale::CurrencySymbolFormat format) default: break; } - return QString(); + return QVariant(); } -#ifndef QT_NO_SYSTEMLOCALE -static QString winFormatCurrency(const QSystemLocale::CurrencyToStringArgument &arg) +QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToStringArgument &arg) { QString value; switch (arg.value.type()) { @@ -446,25 +435,24 @@ static QString winFormatCurrency(const QSystemLocale::CurrencyToStringArgument & arg.value.toULongLong(), -1, 10, -1, QLocale::OmitGroupSeparator); break; default: - return QString(); + return QVariant(); } QVarLengthArray<wchar_t, 64> out(64); - LCID lcid = GetUserDefaultLCID(); QString decimalSep; QString thousandSep; CURRENCYFMT format; CURRENCYFMT *pformat = NULL; if (!arg.symbol.isEmpty()) { - format.NumDigits = qt_getLocaleInfo_int(lcid, LOCALE_ICURRDIGITS); - format.LeadingZero = qt_getLocaleInfo_int(lcid, LOCALE_ILZERO); - decimalSep = qt_getLocaleInfo(lcid, LOCALE_SMONDECIMALSEP); + format.NumDigits = getLocaleInfo_int(lcid, LOCALE_ICURRDIGITS); + format.LeadingZero = getLocaleInfo_int(lcid, LOCALE_ILZERO); + decimalSep = getLocaleInfo(lcid, LOCALE_SMONDECIMALSEP); format.lpDecimalSep = (wchar_t *)decimalSep.utf16(); - thousandSep = qt_getLocaleInfo(lcid, LOCALE_SMONTHOUSANDSEP); + thousandSep = getLocaleInfo(lcid, LOCALE_SMONTHOUSANDSEP); format.lpThousandSep = (wchar_t *)thousandSep.utf16(); - format.NegativeOrder = qt_getLocaleInfo_int(lcid, LOCALE_INEGCURR); - format.PositiveOrder = qt_getLocaleInfo_int(lcid, LOCALE_ICURRENCY); + format.NegativeOrder = getLocaleInfo_int(lcid, LOCALE_INEGCURR); + format.PositiveOrder = getLocaleInfo_int(lcid, LOCALE_ICURRENCY); format.lpCurrencySymbol = (wchar_t *)arg.symbol.utf16(); // grouping is complicated and ugly: @@ -473,7 +461,7 @@ static QString winFormatCurrency(const QSystemLocale::CurrencyToStringArgument & // int(30) == "123456,789.00" == string("3;0;0") // int(32) == "12,34,56,789.00" == string("3;2;0") // int(320)== "1234,56,789.00" == string("3;2") - QString groupingStr = qt_getLocaleInfo(lcid, LOCALE_SMONGROUPING); + QString groupingStr = getLocaleInfo(lcid, LOCALE_SMONGROUPING); format.Grouping = groupingStr.remove(QLatin1Char(';')).toInt(); if (format.Grouping % 10 == 0) // magic format.Grouping /= 10; @@ -493,12 +481,12 @@ static QString winFormatCurrency(const QSystemLocale::CurrencyToStringArgument & } value = QString::fromWCharArray(out.data()); - if (substitution(lcid) == SAlways) - substituteDigits(lcid, value); + if (substitution() == SAlways) + substituteDigits( value); return value; } -QStringList winUILanguages() +QVariant QSystemLocalePrivate::uiLanguages() { if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) { typedef BOOL (*GetUserPreferredUILanguagesFunc) ( @@ -543,6 +531,112 @@ QStringList winUILanguages() return QStringList(QString::fromLatin1(winLangCodeToIsoName(GetUserDefaultUILanguage()))); } +void QSystemLocalePrivate::update() +{ + lcid = GetUserDefaultLCID(); +} + + +static QByteArray getWinLocaleName(LCID id) +{ + QByteArray result; + if (id == LOCALE_USER_DEFAULT) { + static QByteArray langEnvVar = qgetenv("LANG"); + result = langEnvVar; + QString lang, script, cntry; + if ( result == "C" || (!result.isEmpty() + && splitLocaleName(QString::fromLocal8Bit(result), lang, script, cntry)) ) { + long id = 0; + bool ok = false; + id = qstrtoll(result.data(), 0, 0, &ok); + if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX ) + return result; + else + return winLangCodeToIsoName( (int)id ); + } + } + +#if defined(Q_OS_WINCE) + result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID()); +#else + if (id == LOCALE_USER_DEFAULT) + id = GetUserDefaultLCID(); + QString resultuage = winIso639LangName(id); + QString country = winIso3116CtryName(id); + result = resultuage.toLatin1(); + if (!country.isEmpty()) { + result += '_'; + result += country.toLatin1(); + } +#endif + + return result; +} + +QString QSystemLocalePrivate::winToQtFormat(const QString &sys_fmt) +{ + QString result; + int i = 0; + + while (i < sys_fmt.size()) { + if (sys_fmt.at(i).unicode() == QLatin1Char('\'')) { + QString text = readEscapedFormatString(sys_fmt, &i); + if (text == QLatin1String("'")) + result += QLatin1String("''"); + else + result += QString(QLatin1Char('\'') + text + QLatin1Char('\'')); + continue; + } + + QChar c = sys_fmt.at(i); + int repeat = repeatCount(sys_fmt, i); + + switch (c.unicode()) { + // Date + case 'y': + if (repeat > 5) + repeat = 5; + else if (repeat == 3) + repeat = 2; + switch (repeat) { + case 1: + result += QLatin1String("yy"); // "y" unsupported by Qt, use "yy" + break; + case 5: + result += QLatin1String("yyyy"); // "yyyyy" same as "yyyy" on Windows + break; + default: + result += QString(repeat, QLatin1Char('y')); + break; + } + break; + case 'g': + if (repeat > 2) + repeat = 2; + switch (repeat) { + case 2: + break; // no equivalent of "gg" in Qt + default: + result += QLatin1Char('g'); + break; + } + break; + case 't': + if (repeat > 2) + repeat = 2; + result += QLatin1String("AP"); // "t" unsupported, use "AP" + break; + default: + result += QString(repeat, c); + break; + } + + i += repeat; + } + + return result; +} + QLocale QSystemLocale::fallbackLocale() const { return QLocale(QString::fromLatin1(getWinLocaleName())); @@ -550,64 +644,50 @@ QLocale QSystemLocale::fallbackLocale() const QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const { - LCTYPE locale_info = 0; - bool format_string = false; - + QSystemLocalePrivate *d = systemLocalePrivate(); switch(type) { -// case Name: -// return getWinLocaleName(); case DecimalPoint: - locale_info = LOCALE_SDECIMAL; - break; + return d->decimalPoint(); case GroupSeparator: - locale_info = LOCALE_STHOUSAND; - break; + return d->groupSeparator(); case NegativeSign: - locale_info = LOCALE_SNEGATIVESIGN; - break; + return d->negativeSign(); case PositiveSign: - locale_info = LOCALE_SPOSITIVESIGN; - break; + return d->positiveSign(); case DateFormatLong: - locale_info = LOCALE_SLONGDATE; - format_string = true; - break; + return d->dateFormat(QLocale::LongFormat); case DateFormatShort: - locale_info = LOCALE_SSHORTDATE; - format_string = true; - break; + return d->dateFormat(QLocale::ShortFormat); case TimeFormatLong: + return d->timeFormat(QLocale::LongFormat); case TimeFormatShort: - locale_info = LOCALE_STIMEFORMAT; - format_string = true; - break; - + return d->timeFormat(QLocale::ShortFormat); case DateTimeFormatLong: + return d->dateTimeFormat(QLocale::LongFormat); case DateTimeFormatShort: - return QString(query(type == DateTimeFormatLong ? DateFormatLong : DateFormatShort).toString() - + QLatin1Char(' ') + query(type == DateTimeFormatLong ? TimeFormatLong : TimeFormatShort).toString()); + return d->dateTimeFormat(QLocale::ShortFormat); case DayNameLong: + return d->dayName(in.toInt(), QLocale::LongFormat); case DayNameShort: - return winDayName(in.toInt(), (type == DayNameShort)); + return d->dayName(in.toInt(), QLocale::ShortFormat); case MonthNameLong: + return d->monthName(in.toInt(), QLocale::LongFormat); case MonthNameShort: - return winMonthName(in.toInt(), (type == MonthNameShort)); + return d->monthName(in.toInt(), QLocale::ShortFormat); case DateToStringShort: + return d->toString(in.toDate(), QLocale::ShortFormat); case DateToStringLong: - return winDateToString(in.toDate(), type == DateToStringShort ? DATE_SHORTDATE : DATE_LONGDATE); + return d->toString(in.toDate(), QLocale::LongFormat); case TimeToStringShort: + return d->toString(in.toTime(), QLocale::ShortFormat); case TimeToStringLong: - return winTimeToString(in.toTime(), type == TimeToStringLong); + return d->toString(in.toTime(), QLocale::LongFormat); case DateTimeToStringShort: - case DateTimeToStringLong: { - const QDateTime dt = in.toDateTime(); - return QString(winDateToString(dt.date(), type == DateTimeToStringShort ? DATE_SHORTDATE : DATE_LONGDATE) - + QLatin1Char(' ') + winTimeToString(dt.time(), type == DateTimeToStringLong)); } - + return d->toString(in.toDateTime(), QLocale::ShortFormat); + case DateTimeToStringLong: + return d->toString(in.toDateTime(), QLocale::LongFormat); case ZeroDigit: - locale_info = LOCALE_SNATIVEDIGITS; - break; - + return d->zeroDigit(); case LanguageId: case CountryId: { QString locale = QString::fromLatin1(getWinLocaleName()); @@ -623,32 +703,26 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const } case ScriptId: return QVariant(QLocale::AnyScript); - case MeasurementSystem: - return QVariant(static_cast<int>(winSystemMeasurementSystem())); - + return d->measurementSystem(); case AMText: - return QVariant(winSystemAMText()); + return d->amText(); case PMText: - return QVariant(winSystemPMText()); + return d->pmText(); case FirstDayOfWeek: - return QVariant(winSystemFirstDayOfWeek()); + return d->firstDayOfWeek(); case CurrencySymbol: - return QVariant(winCurrencySymbol(QLocale::CurrencySymbolFormat(in.toUInt()))); + return d->currencySymbol(QLocale::CurrencySymbolFormat(in.toUInt())); case CurrencyToString: - return QVariant(winFormatCurrency(in.value<QSystemLocale::CurrencyToStringArgument>())); + return d->toCurrencyString(in.value<QSystemLocale::CurrencyToStringArgument>()); case UILanguages: - return QVariant(winUILanguages()); + return d->uiLanguages(); + case LocaleChanged: + d->update(); + break; default: break; } - if (locale_info) { - QString result = getWinLocaleInfo(locale_info); - if (format_string) - result = winToQtFormat(result); - if (!result.isEmpty()) - return result; - } return QVariant(); } #endif // QT_NO_SYSTEMLOCALE @@ -810,7 +884,7 @@ static QString winIso639LangName(LCID id) // the language code QString lang_code; wchar_t out[256]; - if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255)) + if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255)) // ### shouldn't use them according to msdn lang_code = QString::fromWCharArray(out); if (!lang_code.isEmpty()) { @@ -850,4 +924,9 @@ static QString winIso3116CtryName(LCID id) return result; } +Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id) +{ + return QLocale(QString::fromLatin1(getWinLocaleName(id))); +} + QT_END_NAMESPACE |