summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlocale_win.cpp
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2019-05-27 19:13:54 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2019-07-10 17:05:30 +0200
commita9aa206b7b8ac4e69f8c46233b4080e00e845ff5 (patch)
tree0d19cb1f1a3b9d79d322e6e63f6f72160977ca67 /src/corelib/tools/qlocale_win.cpp
parent85d3061c1cd4617ef09cb381320611c27da205a5 (diff)
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 <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/corelib/tools/qlocale_win.cpp')
-rw-r--r--src/corelib/tools/qlocale_win.cpp1143
1 files changed, 0 insertions, 1143 deletions
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 <qt_windows.h>
-# include <time.h>
-#endif
-
-#ifdef Q_OS_WINRT
-#include <qfunctions_winrt.h>
-
-#include <wrl.h>
-#include <windows.foundation.h>
-#include <windows.foundation.collections.h>
-#include <windows.system.userprofile.h>
-#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<wchar_t, 64> 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<ushort *>(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<wchar_t, 64> 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<wchar_t, 64> 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<const wchar_t *>(value.utf16()),
- pformat, out.data(), out.size());
- if (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- ret = getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()),
- pformat, out.data(), 0);
- out.resize(ret);
- getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(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<wchar_t, 64> 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<IGlobalizationPreferencesStatics> preferences;
- HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_UserProfile_GlobalizationPreferences).Get(), &preferences);
- if (FAILED(hr)) {
- qWarning("Could not obtain ApplicationLanguagesStatic");
- return QStringList();
- }
-
- ComPtr<ABI::Windows::Foundation::Collections::IVectorView<HSTRING> > 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<QSystemLocale::CurrencyToStringArgument>());
- 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