From a9aa206b7b8ac4e69f8c46233b4080e00e845ff5 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 27 May 2019 19:13:54 +0200 Subject: Move text-related code out of corelib/tools/ to corelib/text/ This includes byte array, string, char, unicode, locale, collation and regular expressions. Change-Id: I8b125fa52c8c513eb57a0f1298b91910e5a0d786 Reviewed-by: Volker Hilsheimer --- src/corelib/tools/qlocale_win.cpp | 1143 ------------------------------------- 1 file changed, 1143 deletions(-) delete mode 100644 src/corelib/tools/qlocale_win.cpp (limited to 'src/corelib/tools/qlocale_win.cpp') diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp deleted file mode 100644 index dc904ad02d..0000000000 --- a/src/corelib/tools/qlocale_win.cpp +++ /dev/null @@ -1,1143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qlocale_p.h" -#include "qlocale_tools_p.h" - -#include "qstringlist.h" -#include "qvariant.h" -#include "qdatetime.h" -#include "qdebug.h" - -#ifdef Q_OS_WIN -# include -# include -#endif - -#ifdef Q_OS_WINRT -#include - -#include -#include -#include -#include -#endif // Q_OS_WINRT - -QT_BEGIN_NAMESPACE - -#ifndef Q_OS_WINRT -static QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT); -static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT); -static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT); -#else // !Q_OS_WINRT -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::System::UserProfile; - -static QByteArray getWinLocaleName(LPWSTR id = LOCALE_NAME_USER_DEFAULT); -static const char *winLangCodeToIsoName(int code); -static QString winIso639LangName(LPWSTR id = LOCALE_NAME_USER_DEFAULT); -static QString winIso3116CtryName(LPWSTR id = LOCALE_NAME_USER_DEFAULT); -#endif // Q_OS_WINRT - -#ifndef QT_NO_SYSTEMLOCALE - -#ifndef MUI_LANGUAGE_NAME -#define MUI_LANGUAGE_NAME 0x8 -#endif -#ifndef LOCALE_SSHORTESTDAYNAME1 -# define LOCALE_SSHORTESTDAYNAME1 0x0060 -# define LOCALE_SSHORTESTDAYNAME2 0x0061 -# define LOCALE_SSHORTESTDAYNAME3 0x0062 -# define LOCALE_SSHORTESTDAYNAME4 0x0063 -# define LOCALE_SSHORTESTDAYNAME5 0x0064 -# define LOCALE_SSHORTESTDAYNAME6 0x0065 -# define LOCALE_SSHORTESTDAYNAME7 0x0066 -#endif -#ifndef LOCALE_SNATIVELANGUAGENAME -# define LOCALE_SNATIVELANGUAGENAME 0x00000004 -#endif -#ifndef LOCALE_SNATIVECOUNTRYNAME -# define LOCALE_SNATIVECOUNTRYNAME 0x00000008 -#endif -#ifndef LOCALE_SSHORTTIME -# define LOCALE_SSHORTTIME 0x00000079 -#endif - -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 collation(); - QVariant amText(); - QVariant pmText(); - QVariant firstDayOfWeek(); - QVariant currencySymbol(QLocale::CurrencySymbolFormat); - QVariant toCurrencyString(const QSystemLocale::CurrencyToStringArgument &); - QVariant uiLanguages(); - QVariant nativeLanguageName(); - QVariant nativeCountryName(); - - void update(); - -private: - enum SubstitutionType { - SUnknown, - SContext, - SAlways, - SNever - }; - - // cached values: -#ifndef Q_OS_WINRT - LCID lcid; -#else - WCHAR lcName[LOCALE_NAME_MAX_LENGTH]; -#endif - SubstitutionType substitutionType; - QChar zero; - - int getLocaleInfo(LCTYPE type, LPWSTR data, int size); - QString getLocaleInfo(LCTYPE type, int maxlen = 0); - int getLocaleInfo_int(LCTYPE type, int maxlen = 0); - QChar getLocaleInfo_qchar(LCTYPE type); - - int getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size); - int getDateFormat(DWORD flags, const SYSTEMTIME * date, LPCWSTR format, LPWSTR data, int size); - int getTimeFormat(DWORD flags, const SYSTEMTIME *date, LPCWSTR format, LPWSTR data, int size); - - SubstitutionType substitution(); - QString &substituteDigits(QString &string); - - static QString winToQtFormat(QStringView sys_fmt); - -}; -Q_GLOBAL_STATIC(QSystemLocalePrivate, systemLocalePrivate) - -QSystemLocalePrivate::QSystemLocalePrivate() - : substitutionType(SUnknown) -{ -#ifndef Q_OS_WINRT - lcid = GetUserDefaultLCID(); -#else - GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH); -#endif -} - -inline int QSystemLocalePrivate::getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size) -{ -#ifndef Q_OS_WINRT - return GetCurrencyFormat(lcid, flags, value, format, data, size); -#else - return GetCurrencyFormatEx(lcName, flags, value, format, data, size); -#endif -} - -inline int QSystemLocalePrivate::getDateFormat(DWORD flags, const SYSTEMTIME * date, LPCWSTR format, LPWSTR data, int size) -{ -#ifndef Q_OS_WINRT - return GetDateFormat(lcid, flags, date, format, data, size); -#else - return GetDateFormatEx(lcName, flags, date, format, data, size, NULL); -#endif -} - -inline int QSystemLocalePrivate::getTimeFormat(DWORD flags, const SYSTEMTIME *date, LPCWSTR format, LPWSTR data, int size) -{ -#ifndef Q_OS_WINRT - return GetTimeFormat(lcid, flags, date, format, data, size); -#else - return GetTimeFormatEx(lcName, flags, date, format, data, size); -#endif -} - -inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int size) -{ -#ifndef Q_OS_WINRT - return GetLocaleInfo(lcid, type, data, size); -#else - return GetLocaleInfoEx(lcName, type, data, size); -#endif -} - -QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) -{ - QVarLengthArray buf(maxlen ? maxlen : 64); - if (!getLocaleInfo(type, buf.data(), buf.size())) - return QString(); - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - int cnt = getLocaleInfo(type, 0, 0); - if (cnt == 0) - return QString(); - buf.resize(cnt); - if (!getLocaleInfo(type, buf.data(), buf.size())) - return QString(); - } - return QString::fromWCharArray(buf.data()); -} - -int QSystemLocalePrivate::getLocaleInfo_int(LCTYPE type, int maxlen) -{ - QString str = getLocaleInfo(type, maxlen); - bool ok = false; - int v = str.toInt(&ok); - return ok ? v : 0; -} - -QChar QSystemLocalePrivate::getLocaleInfo_qchar(LCTYPE type) -{ - QString str = getLocaleInfo(type); - return str.isEmpty() ? QChar() : str.at(0); -} - -QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution() -{ - if (substitutionType == SUnknown) { - wchar_t buf[8]; - if (!getLocaleInfo(LOCALE_IDIGITSUBSTITUTION, buf, 8)) { - substitutionType = QSystemLocalePrivate::SNever; - return substitutionType; - } - if (buf[0] == '1') - substitutionType = QSystemLocalePrivate::SNever; - else if (buf[0] == '0') - substitutionType = QSystemLocalePrivate::SContext; - else if (buf[0] == '2') - substitutionType = QSystemLocalePrivate::SAlways; - else { - wchar_t digits[11]; - if (!getLocaleInfo(LOCALE_SNATIVEDIGITS, digits, 11)) { - substitutionType = QSystemLocalePrivate::SNever; - return substitutionType; - } - const wchar_t zero = digits[0]; - if (buf[0] == zero + 2) - substitutionType = QSystemLocalePrivate::SAlways; - else - substitutionType = QSystemLocalePrivate::SNever; - } - } - return substitutionType; -} - -QString &QSystemLocalePrivate::substituteDigits(QString &string) -{ - ushort zero = zeroDigit().unicode(); - ushort *qch = reinterpret_cast(string.data()); - for (ushort *end = qch + string.size(); qch != end; ++qch) { - if (*qch >= '0' && *qch <= '9') - *qch = zero + (*qch - '0'); - } - return string; -} - -QChar QSystemLocalePrivate::zeroDigit() -{ - if (zero.isNull()) - zero = getLocaleInfo_qchar(LOCALE_SNATIVEDIGITS); - return zero; -} - -QChar QSystemLocalePrivate::decimalPoint() -{ - return getLocaleInfo_qchar(LOCALE_SDECIMAL); -} - -QChar QSystemLocalePrivate::groupSeparator() -{ - return getLocaleInfo_qchar(LOCALE_STHOUSAND); -} - -QChar QSystemLocalePrivate::negativeSign() -{ - return getLocaleInfo_qchar(LOCALE_SNEGATIVESIGN); -} - -QChar QSystemLocalePrivate::positiveSign() -{ - return getLocaleInfo_qchar(LOCALE_SPOSITIVESIGN); -} - -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 QVariant(); -} - -QVariant QSystemLocalePrivate::timeFormat(QLocale::FormatType type) -{ - switch (type) { - case QLocale::ShortFormat: - return winToQtFormat(getLocaleInfo(LOCALE_SSHORTTIME)); - case QLocale::LongFormat: - return winToQtFormat(getLocaleInfo(LOCALE_STIMEFORMAT)); - case QLocale::NarrowFormat: - break; - } - return QVariant(); -} - -QVariant QSystemLocalePrivate::dateTimeFormat(QLocale::FormatType type) -{ - return QString(dateFormat(type).toString() + QLatin1Char(' ') + timeFormat(type).toString()); -} - -QVariant QSystemLocalePrivate::dayName(int day, QLocale::FormatType type) -{ - if (day < 1 || day > 7) - return QString(); - - static const LCTYPE short_day_map[] - = { LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, - LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, - LOCALE_SABBREVDAYNAME6, LOCALE_SABBREVDAYNAME7 }; - - static const LCTYPE long_day_map[] - = { LOCALE_SDAYNAME1, LOCALE_SDAYNAME2, - LOCALE_SDAYNAME3, LOCALE_SDAYNAME4, LOCALE_SDAYNAME5, - LOCALE_SDAYNAME6, LOCALE_SDAYNAME7 }; - - static const LCTYPE narrow_day_map[] - = { LOCALE_SSHORTESTDAYNAME1, LOCALE_SSHORTESTDAYNAME2, - LOCALE_SSHORTESTDAYNAME3, LOCALE_SSHORTESTDAYNAME4, - LOCALE_SSHORTESTDAYNAME5, LOCALE_SSHORTESTDAYNAME6, - LOCALE_SSHORTESTDAYNAME7 }; - - day -= 1; - - if (type == QLocale::LongFormat) - return getLocaleInfo(long_day_map[day]); - if (type == QLocale::NarrowFormat) - return getLocaleInfo(narrow_day_map[day]); - return getLocaleInfo(short_day_map[day]); -} - -QVariant QSystemLocalePrivate::monthName(int month, QLocale::FormatType type) -{ - static const LCTYPE short_month_map[] - = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3, - LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, - LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9, - LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 }; - - static const LCTYPE long_month_map[] - = { LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3, - LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6, - LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME9, - LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12 }; - - month -= 1; - if (month < 0 || month > 11) - return QString(); - - LCTYPE lctype = (type == QLocale::ShortFormat || type == QLocale::NarrowFormat) - ? short_month_map[month] : long_month_map[month]; - return getLocaleInfo(lctype); -} - -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(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; - // keep the same conditional as timeFormat() above - if (type == QLocale::ShortFormat) - flags = TIME_NOSECONDS; - - wchar_t buf[255]; - if (getTimeFormat(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() -{ - wchar_t output[2]; - - if (getLocaleInfo(LOCALE_IMEASURE, output, 2)) { - QString iMeasure = QString::fromWCharArray(output); - if (iMeasure == QLatin1String("1")) { - return QLocale::ImperialSystem; - } - } - - return QLocale::MetricSystem; -} - -QVariant QSystemLocalePrivate::collation() -{ - return getLocaleInfo(LOCALE_SSORTLOCALE); -} - -QVariant QSystemLocalePrivate::amText() -{ - wchar_t output[15]; // maximum length including terminating zero character for Win2003+ - - if (getLocaleInfo(LOCALE_S1159, output, 15)) { - return QString::fromWCharArray(output); - } - - return QVariant(); -} - -QVariant QSystemLocalePrivate::pmText() -{ - wchar_t output[15]; // maximum length including terminating zero character for Win2003+ - - if (getLocaleInfo(LOCALE_S2359, output, 15)) { - return QString::fromWCharArray(output); - } - - return QVariant(); -} - -QVariant QSystemLocalePrivate::firstDayOfWeek() -{ - wchar_t output[4]; // maximum length including terminating zero character for Win2003+ - - if (getLocaleInfo(LOCALE_IFIRSTDAYOFWEEK, output, 4)) - return QString::fromWCharArray(output).toUInt()+1; - - return 1; -} - -QVariant QSystemLocalePrivate::currencySymbol(QLocale::CurrencySymbolFormat format) -{ - wchar_t buf[13]; - switch (format) { - case QLocale::CurrencySymbol: - if (getLocaleInfo(LOCALE_SCURRENCY, buf, 13)) - return QString::fromWCharArray(buf); - break; - case QLocale::CurrencyIsoCode: - if (getLocaleInfo(LOCALE_SINTLSYMBOL, buf, 9)) - return QString::fromWCharArray(buf); - break; - case QLocale::CurrencyDisplayName: { - QVarLengthArray buf(64); - if (!getLocaleInfo(LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) { - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - break; - buf.resize(255); // should be large enough, right? - if (!getLocaleInfo(LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) - break; - } - return QString::fromWCharArray(buf.data()); - } - default: - break; - } - return QVariant(); -} - -QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToStringArgument &arg) -{ - QString value; - switch (arg.value.type()) { - case QVariant::Int: - value = QLocaleData::longLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'), QLatin1Char('-'), - arg.value.toInt(), -1, 10, -1, QLocale::OmitGroupSeparator); - break; - case QVariant::UInt: - value = QLocaleData::unsLongLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'), - arg.value.toUInt(), -1, 10, -1, QLocale::OmitGroupSeparator); - break; - case QVariant::Double: - value = QLocaleData::doubleToString(QLatin1Char('0'), QLatin1Char('+'), QLatin1Char('-'), - QLatin1Char(' '), QLatin1Char(','), QLatin1Char('.'), - arg.value.toDouble(), -1, QLocaleData::DFDecimal, -1, QLocale::OmitGroupSeparator); - break; - case QVariant::LongLong: - value = QLocaleData::longLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'), QLatin1Char('-'), - arg.value.toLongLong(), -1, 10, -1, QLocale::OmitGroupSeparator); - break; - case QVariant::ULongLong: - value = QLocaleData::unsLongLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'), - arg.value.toULongLong(), -1, 10, -1, QLocale::OmitGroupSeparator); - break; - default: - return QVariant(); - } - - QVarLengthArray out(64); - - QString decimalSep; - QString thousandSep; - CURRENCYFMT format; - CURRENCYFMT *pformat = NULL; - if (!arg.symbol.isEmpty()) { - format.NumDigits = getLocaleInfo_int(LOCALE_ICURRDIGITS); - format.LeadingZero = getLocaleInfo_int(LOCALE_ILZERO); - decimalSep = getLocaleInfo(LOCALE_SMONDECIMALSEP); - format.lpDecimalSep = (wchar_t *)decimalSep.utf16(); - thousandSep = getLocaleInfo(LOCALE_SMONTHOUSANDSEP); - format.lpThousandSep = (wchar_t *)thousandSep.utf16(); - format.NegativeOrder = getLocaleInfo_int(LOCALE_INEGCURR); - format.PositiveOrder = getLocaleInfo_int(LOCALE_ICURRENCY); - format.lpCurrencySymbol = (wchar_t *)arg.symbol.utf16(); - - // grouping is complicated and ugly: - // int(0) == "123456789.00" == string("0") - // int(3) == "123,456,789.00" == string("3;0") - // 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 = getLocaleInfo(LOCALE_SMONGROUPING); - format.Grouping = groupingStr.remove(QLatin1Char(';')).toInt(); - if (format.Grouping % 10 == 0) // magic - format.Grouping /= 10; - else - format.Grouping *= 10; - pformat = &format; - } - - int ret = getCurrencyFormat(0, reinterpret_cast(value.utf16()), - pformat, out.data(), out.size()); - if (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - ret = getCurrencyFormat(0, reinterpret_cast(value.utf16()), - pformat, out.data(), 0); - out.resize(ret); - getCurrencyFormat(0, reinterpret_cast(value.utf16()), - pformat, out.data(), out.size()); - } - - value = QString::fromWCharArray(out.data()); - if (substitution() == SAlways) - substituteDigits( value); - return value; -} - -QVariant QSystemLocalePrivate::uiLanguages() -{ -#ifndef Q_OS_WINRT - unsigned long cnt = 0; - QVarLengthArray buf(64); -# if !defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE) // Not present in MinGW 4.9/bootstrap builds. - unsigned long size = buf.size(); - if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size)) { - size = 0; - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && - GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &cnt, NULL, &size)) { - buf.resize(size); - if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size)) - return QStringList(); - } - } -# endif // !QT_BOOTSTRAPPED && !QT_BUILD_QMAKE - QStringList result; - result.reserve(cnt); - const wchar_t *str = buf.constData(); - for (; cnt > 0; --cnt) { - QString s = QString::fromWCharArray(str); - if (s.isEmpty()) - break; // something is wrong - result.append(s); - str += s.size() + 1; - } - return result; -#else // !Q_OS_WINRT - QStringList result; - - ComPtr preferences; - HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_UserProfile_GlobalizationPreferences).Get(), &preferences); - if (FAILED(hr)) { - qWarning("Could not obtain ApplicationLanguagesStatic"); - return QStringList(); - } - - ComPtr > languageList; - // Languages is a ranked list of "long names" (e.g. en-US) of preferred languages - hr = preferences->get_Languages(&languageList); - Q_ASSERT_SUCCEEDED(hr); - unsigned int size; - hr = languageList->get_Size(&size); - Q_ASSERT_SUCCEEDED(hr); - result.reserve(size); - for (unsigned int i = 0; i < size; ++i) { - HString language; - hr = languageList->GetAt(i, language.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - UINT32 length; - PCWSTR rawString = language.GetRawBuffer(&length); - result << QString::fromWCharArray(rawString, length); - } - - return result; -#endif // Q_OS_WINRT -} - -QVariant QSystemLocalePrivate::nativeLanguageName() -{ - return getLocaleInfo(LOCALE_SNATIVELANGUAGENAME); -} - -QVariant QSystemLocalePrivate::nativeCountryName() -{ - return getLocaleInfo(LOCALE_SNATIVECOUNTRYNAME); -} - - -void QSystemLocalePrivate::update() -{ -#ifndef Q_OS_WINRT - lcid = GetUserDefaultLCID(); -#else - GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH); -#endif - substitutionType = SUnknown; - zero = QChar(); -} - -QString QSystemLocalePrivate::winToQtFormat(QStringView sys_fmt) -{ - QString result; - int i = 0; - - while (i < sys_fmt.size()) { - if (sys_fmt.at(i).unicode() == QLatin1Char('\'')) { - QString text = qt_readEscapedFormatString(sys_fmt, &i); - if (text == QLatin1String("'")) - result += QLatin1String("''"); - else - result += QLatin1Char('\'') + text + QLatin1Char('\''); - continue; - } - - QChar c = sys_fmt.at(i); - int repeat = qt_repeatCount(sys_fmt.mid(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::fallbackUiLocale() const -{ - return QLocale(QString::fromLatin1(getWinLocaleName())); -} - -QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const -{ - QSystemLocalePrivate *d = systemLocalePrivate(); - switch(type) { - case DecimalPoint: - return d->decimalPoint(); - case GroupSeparator: - return d->groupSeparator(); - case NegativeSign: - return d->negativeSign(); - case PositiveSign: - return d->positiveSign(); - case DateFormatLong: - return d->dateFormat(QLocale::LongFormat); - case DateFormatShort: - return d->dateFormat(QLocale::ShortFormat); - case TimeFormatLong: - return d->timeFormat(QLocale::LongFormat); - case TimeFormatShort: - return d->timeFormat(QLocale::ShortFormat); - case DateTimeFormatLong: - return d->dateTimeFormat(QLocale::LongFormat); - case DateTimeFormatShort: - return d->dateTimeFormat(QLocale::ShortFormat); - case DayNameLong: - return d->dayName(in.toInt(), QLocale::LongFormat); - case DayNameShort: - return d->dayName(in.toInt(), QLocale::ShortFormat); - case MonthNameLong: - case StandaloneMonthNameLong: - return d->monthName(in.toInt(), QLocale::LongFormat); - case MonthNameShort: - case StandaloneMonthNameShort: - return d->monthName(in.toInt(), QLocale::ShortFormat); - case DateToStringShort: - return d->toString(in.toDate(), QLocale::ShortFormat); - case DateToStringLong: - return d->toString(in.toDate(), QLocale::LongFormat); - case TimeToStringShort: - return d->toString(in.toTime(), QLocale::ShortFormat); - case TimeToStringLong: - return d->toString(in.toTime(), QLocale::LongFormat); - case DateTimeToStringShort: - return d->toString(in.toDateTime(), QLocale::ShortFormat); - case DateTimeToStringLong: - return d->toString(in.toDateTime(), QLocale::LongFormat); - case ZeroDigit: - return d->zeroDigit(); - case LanguageId: - case CountryId: { - QString locale = QString::fromLatin1(getWinLocaleName()); - QLocale::Language lang; - QLocale::Script script; - QLocale::Country cntry; - QLocalePrivate::getLangAndCountry(locale, lang, script, cntry); - if (type == LanguageId) - return lang; - if (cntry == QLocale::AnyCountry) - return fallbackUiLocale().country(); - return cntry; - } - case ScriptId: - return QVariant(QLocale::AnyScript); - case MeasurementSystem: - return d->measurementSystem(); - case Collation: - return d->collation(); - case AMText: - return d->amText(); - case PMText: - return d->pmText(); - case FirstDayOfWeek: - return d->firstDayOfWeek(); - case CurrencySymbol: - return d->currencySymbol(QLocale::CurrencySymbolFormat(in.toUInt())); - case CurrencyToString: - return d->toCurrencyString(in.value()); - case UILanguages: - return d->uiLanguages(); - case LocaleChanged: - d->update(); - break; - case NativeLanguageName: - return d->nativeLanguageName(); - case NativeCountryName: - return d->nativeCountryName(); - default: - break; - } - return QVariant(); -} -#endif // QT_NO_SYSTEMLOCALE - -struct WindowsToISOListElt { - ushort windows_code; - char iso_name[6]; -}; - -/* NOTE: This array should be sorted by the first column! */ -static const WindowsToISOListElt windows_to_iso_list[] = { - { 0x0401, "ar_SA" }, - { 0x0402, "bg\0 " }, - { 0x0403, "ca\0 " }, - { 0x0404, "zh_TW" }, - { 0x0405, "cs\0 " }, - { 0x0406, "da\0 " }, - { 0x0407, "de\0 " }, - { 0x0408, "el\0 " }, - { 0x0409, "en_US" }, - { 0x040a, "es\0 " }, - { 0x040b, "fi\0 " }, - { 0x040c, "fr\0 " }, - { 0x040d, "he\0 " }, - { 0x040e, "hu\0 " }, - { 0x040f, "is\0 " }, - { 0x0410, "it\0 " }, - { 0x0411, "ja\0 " }, - { 0x0412, "ko\0 " }, - { 0x0413, "nl\0 " }, - { 0x0414, "no\0 " }, - { 0x0415, "pl\0 " }, - { 0x0416, "pt_BR" }, - { 0x0418, "ro\0 " }, - { 0x0419, "ru\0 " }, - { 0x041a, "hr\0 " }, - { 0x041c, "sq\0 " }, - { 0x041d, "sv\0 " }, - { 0x041e, "th\0 " }, - { 0x041f, "tr\0 " }, - { 0x0420, "ur\0 " }, - { 0x0421, "in\0 " }, - { 0x0422, "uk\0 " }, - { 0x0423, "be\0 " }, - { 0x0425, "et\0 " }, - { 0x0426, "lv\0 " }, - { 0x0427, "lt\0 " }, - { 0x0429, "fa\0 " }, - { 0x042a, "vi\0 " }, - { 0x042d, "eu\0 " }, - { 0x042f, "mk\0 " }, - { 0x0436, "af\0 " }, - { 0x0438, "fo\0 " }, - { 0x0439, "hi\0 " }, - { 0x043e, "ms\0 " }, - { 0x0458, "mt\0 " }, - { 0x0801, "ar_IQ" }, - { 0x0804, "zh_CN" }, - { 0x0807, "de_CH" }, - { 0x0809, "en_GB" }, - { 0x080a, "es_MX" }, - { 0x080c, "fr_BE" }, - { 0x0810, "it_CH" }, - { 0x0812, "ko\0 " }, - { 0x0813, "nl_BE" }, - { 0x0814, "no\0 " }, - { 0x0816, "pt\0 " }, - { 0x081a, "sr\0 " }, - { 0x081d, "sv_FI" }, - { 0x0c01, "ar_EG" }, - { 0x0c04, "zh_HK" }, - { 0x0c07, "de_AT" }, - { 0x0c09, "en_AU" }, - { 0x0c0a, "es\0 " }, - { 0x0c0c, "fr_CA" }, - { 0x0c1a, "sr\0 " }, - { 0x1001, "ar_LY" }, - { 0x1004, "zh_SG" }, - { 0x1007, "de_LU" }, - { 0x1009, "en_CA" }, - { 0x100a, "es_GT" }, - { 0x100c, "fr_CH" }, - { 0x1401, "ar_DZ" }, - { 0x1407, "de_LI" }, - { 0x1409, "en_NZ" }, - { 0x140a, "es_CR" }, - { 0x140c, "fr_LU" }, - { 0x1801, "ar_MA" }, - { 0x1809, "en_IE" }, - { 0x180a, "es_PA" }, - { 0x1c01, "ar_TN" }, - { 0x1c09, "en_ZA" }, - { 0x1c0a, "es_DO" }, - { 0x2001, "ar_OM" }, - { 0x2009, "en_JM" }, - { 0x200a, "es_VE" }, - { 0x2401, "ar_YE" }, - { 0x2409, "en\0 " }, - { 0x240a, "es_CO" }, - { 0x2801, "ar_SY" }, - { 0x2809, "en_BZ" }, - { 0x280a, "es_PE" }, - { 0x2c01, "ar_JO" }, - { 0x2c09, "en_TT" }, - { 0x2c0a, "es_AR" }, - { 0x3001, "ar_LB" }, - { 0x300a, "es_EC" }, - { 0x3401, "ar_KW" }, - { 0x340a, "es_CL" }, - { 0x3801, "ar_AE" }, - { 0x380a, "es_UY" }, - { 0x3c01, "ar_BH" }, - { 0x3c0a, "es_PY" }, - { 0x4001, "ar_QA" }, - { 0x400a, "es_BO" }, - { 0x440a, "es_SV" }, - { 0x480a, "es_HN" }, - { 0x4c0a, "es_NI" }, - { 0x500a, "es_PR" } -}; - -static const int windows_to_iso_count - = sizeof(windows_to_iso_list)/sizeof(WindowsToISOListElt); - -static const char *winLangCodeToIsoName(int code) -{ - int cmp = code - windows_to_iso_list[0].windows_code; - if (cmp < 0) - return 0; - - if (cmp == 0) - return windows_to_iso_list[0].iso_name; - - int begin = 0; - int end = windows_to_iso_count; - - while (end - begin > 1) { - uint mid = (begin + end)/2; - - const WindowsToISOListElt *elt = windows_to_iso_list + mid; - int cmp = code - elt->windows_code; - if (cmp < 0) - end = mid; - else if (cmp > 0) - begin = mid; - else - return elt->iso_name; - } - - return 0; - -} - -LCID qt_inIsoNametoLCID(const char *name) -{ - // handle norwegian manually, the list above will fail - if (!strncmp(name, "nb", 2)) - return 0x0414; - if (!strncmp(name, "nn", 2)) - return 0x0814; - - char n[64]; - strncpy(n, name, sizeof(n)); - n[sizeof(n)-1] = 0; - char *c = n; - while (*c) { - if (*c == '-') - *c = '_'; - ++c; - } - - for (const WindowsToISOListElt &i : windows_to_iso_list) { - if (!strcmp(n, i.iso_name)) - return i.windows_code; - } - return LOCALE_USER_DEFAULT; -} - - -#ifndef Q_OS_WINRT -static QString winIso639LangName(LCID id) -#else -static QString winIso639LangName(LPWSTR id) -#endif -{ - QString result; - - // Windows returns the wrong ISO639 for some languages, we need to detect them here using - // the language code - QString lang_code; - wchar_t out[256]; -#ifndef Q_OS_WINRT - if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255)) -#else - if (GetLocaleInfoEx(id, LOCALE_ILANGUAGE, out, 255)) -#endif - lang_code = QString::fromWCharArray(out); - - if (!lang_code.isEmpty()) { - const char *endptr; - bool ok; - QByteArray latin1_lang_code = std::move(lang_code).toLatin1(); - int i = qstrtoull(latin1_lang_code, &endptr, 16, &ok); - if (ok && *endptr == '\0') { - switch (i) { - case 0x814: - result = QLatin1String("nn"); // Nynorsk - break; - default: - break; - } - } - } - - if (!result.isEmpty()) - return result; - - // not one of the problematic languages - do the usual lookup -#ifndef Q_OS_WINRT - if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME, out, 255)) -#else - if (GetLocaleInfoEx(id, LOCALE_SISO639LANGNAME, out, 255)) -#endif - result = QString::fromWCharArray(out); - - return result; -} - -#ifndef Q_OS_WINRT -static QString winIso3116CtryName(LCID id) -#else -static QString winIso3116CtryName(LPWSTR id) -#endif -{ - QString result; - - wchar_t out[256]; -#ifndef Q_OS_WINRT - if (GetLocaleInfo(id, LOCALE_SISO3166CTRYNAME, out, 255)) -#else - if (GetLocaleInfoEx(id, LOCALE_SISO3166CTRYNAME, out, 255)) -#endif - result = QString::fromWCharArray(out); - - return result; -} - -#ifndef Q_OS_WINRT -static QByteArray getWinLocaleName(LCID id) -#else -static QByteArray getWinLocaleName(LPWSTR id) -#endif -{ - QByteArray result; -#ifndef Q_OS_WINRT - if (id == LOCALE_USER_DEFAULT) { -#else - if (QString::fromWCharArray(id) == QString::fromWCharArray(LOCALE_NAME_USER_DEFAULT)) { -#endif - static QByteArray langEnvVar = qgetenv("LANG"); - result = langEnvVar; - QString lang, script, cntry; - if ( result == "C" || (!result.isEmpty() - && qt_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; - return winLangCodeToIsoName(int(id)); - } - } - -#ifndef Q_OS_WINRT - if (id == LOCALE_USER_DEFAULT) - id = GetUserDefaultLCID(); -#else // !Q_OS_WINRT - WCHAR lcName[LOCALE_NAME_MAX_LENGTH]; - if (QString::fromWCharArray(id) == QString::fromWCharArray(LOCALE_NAME_USER_DEFAULT)) { - GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH); - id = lcName; - } -#endif // Q_OS_WINRT - QString resultusage = winIso639LangName(id); - QString country = winIso3116CtryName(id); - if (!country.isEmpty()) - resultusage += QLatin1Char('_') + country; - - return std::move(resultusage).toLatin1(); -} - -Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id) -{ -#ifndef Q_OS_WINRT - return QLocale(QString::fromLatin1(getWinLocaleName(id))); -#else // !Q_OS_WINRT - WCHAR name[LOCALE_NAME_MAX_LENGTH]; - LCIDToLocaleName(id, name, LOCALE_NAME_MAX_LENGTH, 0); - return QLocale(QString::fromLatin1(getWinLocaleName(name))); -#endif // Q_OS_WINRT -} - -QT_END_NAMESPACE -- cgit v1.2.3