15using namespace Qt::StringLiterals;
17#ifndef QT_NO_SYSTEMLOCALE
19struct QSystemLocaleData
22 : lc_numeric(QLocale::C)
24 ,lc_monetary(QLocale::C)
25 ,lc_messages(QLocale::C)
27 initFromEnvironmentUnprotected();
30 void readEnvironment();
38 QByteArray lc_messages_var;
39 QByteArray lc_measurement_var;
40 QByteArray lc_collate_var;
41 QStringList uiLanguages;
44 void initFromEnvironmentUnprotected();
47void QSystemLocaleData::readEnvironment()
49 QWriteLocker locker(&lock);
50 initFromEnvironmentUnprotected();
53void QSystemLocaleData::initFromEnvironmentUnprotected()
57 QByteArray all = qgetenv(
"LC_ALL");
58 QByteArray numeric = all.isEmpty() ? qgetenv(
"LC_NUMERIC") : all;
59 QByteArray time = all.isEmpty() ? qgetenv(
"LC_TIME") : all;
60 QByteArray monetary = all.isEmpty() ? qgetenv(
"LC_MONETARY") : all;
61 lc_messages_var = all.isEmpty() ? qgetenv(
"LC_MESSAGES") : all;
62 lc_measurement_var = all.isEmpty() ? qgetenv(
"LC_MEASUREMENT") : all;
63 lc_collate_var = all.isEmpty() ? qgetenv(
"LC_COLLATE") : all;
64 QByteArray lang = qgetenv(
"LANG");
66 lang = QByteArray(
"C");
67 if (numeric.isEmpty())
71 if (monetary.isEmpty())
73 if (lc_messages_var.isEmpty())
74 lc_messages_var = lang;
75 if (lc_measurement_var.isEmpty())
76 lc_measurement_var = lang;
77 if (lc_collate_var.isEmpty())
78 lc_collate_var = lang;
79 lc_numeric = QLocale(QString::fromLatin1(numeric));
80 lc_time = QLocale(QString::fromLatin1(time));
81 lc_monetary = QLocale(QString::fromLatin1(monetary));
82 lc_messages = QLocale(QString::fromLatin1(lc_messages_var));
85Q_GLOBAL_STATIC(QSystemLocaleData, qSystemLocaleData)
89static bool contradicts(QStringView maybe,
const QString &known)
95
96
97
98
99
100
101
102
103
104
105
106 QLocaleId knownId = QLocaleId::fromName(known);
107 QLocaleId maybeId = QLocaleId::fromName(maybe);
108 return !(maybeId.acceptLanguage(knownId.language_id) && maybeId.acceptScriptTerritory(knownId));
111QLocale QSystemLocale::fallbackLocale()
const
114 QString lang = qEnvironmentVariable(
"LC_ALL");
116 lang = qEnvironmentVariable(
"LC_MESSAGES");
118 lang = qEnvironmentVariable(
"LANG");
120 if (lang.isEmpty() || lang ==
"C"_L1 || lang ==
"POSIX"_L1)
121 return QLocale(lang);
126 QString language = qEnvironmentVariable(
"LANGUAGE");
128 if (
const auto colon = language.indexOf(u':'); colon >= 0)
129 language.truncate(colon);
130 if (contradicts(language, lang))
131 return QLocale(language);
134 return QLocale(lang);
137QVariant QSystemLocale::query(QueryType type, QVariant &&in)
const
139 QSystemLocaleData *d = qSystemLocaleData();
143 if (type == LocaleChanged) {
144 d->readEnvironment();
148 QReadLocker locker(&d->lock);
150 const QLocale &lc_numeric = d->lc_numeric;
151 const QLocale &lc_time = d->lc_time;
152 const QLocale &lc_monetary = d->lc_monetary;
153 const QLocale &lc_messages = d->lc_messages;
157 return lc_numeric.decimalPoint();
159 return QVariant::fromValue(lc_numeric.d->m_data->groupSizes());
161 return lc_numeric.groupSeparator();
163 return lc_numeric.zeroDigit();
165 return lc_numeric.negativeSign();
167 return lc_time.dateFormat(QLocale::LongFormat);
168 case DateFormatShort:
169 return lc_time.dateFormat(QLocale::ShortFormat);
171 return lc_time.timeFormat(QLocale::LongFormat);
172 case TimeFormatShort:
173 return lc_time.timeFormat(QLocale::ShortFormat);
175 return lc_time.dayName(in.toInt(), QLocale::LongFormat);
177 return lc_time.dayName(in.toInt(), QLocale::ShortFormat);
179 return lc_time.dayName(in.toInt(), QLocale::NarrowFormat);
180 case StandaloneDayNameLong:
181 return lc_time.standaloneDayName(in.toInt(), QLocale::LongFormat);
182 case StandaloneDayNameShort:
183 return lc_time.standaloneDayName(in.toInt(), QLocale::ShortFormat);
184 case StandaloneDayNameNarrow:
185 return lc_time.standaloneDayName(in.toInt(), QLocale::NarrowFormat);
187 return lc_time.monthName(in.toInt(), QLocale::LongFormat);
189 return lc_time.monthName(in.toInt(), QLocale::ShortFormat);
190 case MonthNameNarrow:
191 return lc_time.monthName(in.toInt(), QLocale::NarrowFormat);
192 case StandaloneMonthNameLong:
193 return lc_time.standaloneMonthName(in.toInt(), QLocale::LongFormat);
194 case StandaloneMonthNameShort:
195 return lc_time.standaloneMonthName(in.toInt(), QLocale::ShortFormat);
196 case StandaloneMonthNameNarrow:
197 return lc_time.standaloneMonthName(in.toInt(), QLocale::NarrowFormat);
198 case DateToStringLong:
199 return lc_time.toString(in.toDate(), QLocale::LongFormat);
200 case DateToStringShort:
201 return lc_time.toString(in.toDate(), QLocale::ShortFormat);
202 case TimeToStringLong:
203 return lc_time.toString(in.toTime(), QLocale::LongFormat);
204 case TimeToStringShort:
205 return lc_time.toString(in.toTime(), QLocale::ShortFormat);
206 case DateTimeFormatLong:
207 return lc_time.dateTimeFormat(QLocale::LongFormat);
208 case DateTimeFormatShort:
209 return lc_time.dateTimeFormat(QLocale::ShortFormat);
210 case DateTimeToStringLong:
211 return lc_time.toString(in.toDateTime(), QLocale::LongFormat);
212 case DateTimeToStringShort:
213 return lc_time.toString(in.toDateTime(), QLocale::ShortFormat);
215 return lc_numeric.positiveSign();
217 return lc_time.amText();
219 return lc_time.pmText();
221 return lc_time.firstDayOfWeek();
223 return lc_monetary.currencySymbol(QLocale::CurrencySymbolFormat(in.toUInt()));
224 case CurrencyToString: {
225 switch (in.userType()) {
227 return lc_monetary.toCurrencyString(in.toInt());
228 case QMetaType::UInt:
229 return lc_monetary.toCurrencyString(in.toUInt());
230 case QMetaType::Double:
231 return lc_monetary.toCurrencyString(in.toDouble());
232 case QMetaType::LongLong:
233 return lc_monetary.toCurrencyString(in.toLongLong());
234 case QMetaType::ULongLong:
235 return lc_monetary.toCurrencyString(in.toULongLong());
241 case MeasurementSystem: {
242 const QString meas_locale = QString::fromLatin1(d->lc_measurement_var);
243 if (meas_locale.compare(
"Metric"_L1, Qt::CaseInsensitive) == 0)
244 return QLocale::MetricSystem;
245 if (meas_locale.compare(
"Other"_L1, Qt::CaseInsensitive) == 0)
246 return QLocale::MetricSystem;
247 return QVariant((
int)QLocale(meas_locale).measurementSystem());
250 return QString::fromLatin1(d->lc_collate_var);
252 if (!d->uiLanguages.isEmpty())
253 return d->uiLanguages;
254 QString languages = QString::fromLatin1(qgetenv(
"LANGUAGE"));
256 if (languages.isEmpty())
257 lst.append(QString::fromLatin1(d->lc_messages_var));
259 lst = languages.split(u':');
261 for (
const QString &e : std::as_const(lst)) {
262 QStringView language, script, territory;
263 if (qt_splitLocaleName(e, &language, &script, &territory)) {
264 QString joined = language.isEmpty() ? u"und"_s : language.toString();
265 if (!script.isEmpty())
266 joined += u'-' + script;
267 if (!territory.isEmpty())
268 joined += u'-' + territory;
269 d->uiLanguages.append(joined);
272 return d->uiLanguages.isEmpty() ? QVariant() : QVariant(d->uiLanguages);
274 case StringToStandardQuotation:
275 return lc_messages.quoteString(qvariant_cast<QStringView>(std::move(in)));
276 case StringToAlternateQuotation:
277 return lc_messages.quoteString(qvariant_cast<QStringView>(std::move(in)),
278 QLocale::AlternateQuotation);
279 case ListToSeparatedString:
280 return lc_messages.createSeparatedList(in.toStringList());
287 case NativeLanguageName:
288 case NativeTerritoryName: