Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qlocale_unix.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qlocale_p.h"
5
6#include "qstringbuilder.h"
7#include "qdatetime.h"
8#include "qstringlist.h"
9#include "qvariant.h"
10#include "qreadwritelock.h"
11
13
14using namespace Qt::StringLiterals;
15
16#ifndef QT_NO_SYSTEMLOCALE
41
43{
44 QWriteLocker locker(&lock);
45
46 // See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_02
47 // for the semantics of each of these:
48 QByteArray all = qgetenv("LC_ALL");
49 QByteArray numeric = all.isEmpty() ? qgetenv("LC_NUMERIC") : all;
50 QByteArray time = all.isEmpty() ? qgetenv("LC_TIME") : all;
51 QByteArray monetary = all.isEmpty() ? qgetenv("LC_MONETARY") : all;
52 lc_messages_var = all.isEmpty() ? qgetenv("LC_MESSAGES") : all;
53 lc_measurement_var = all.isEmpty() ? qgetenv("LC_MEASUREMENT") : all;
54 lc_collate_var = all.isEmpty() ? qgetenv("LC_COLLATE") : all;
55 QByteArray lang = qgetenv("LANG");
56 if (lang.isEmpty())
57 lang = QByteArray("C");
58 if (numeric.isEmpty())
59 numeric = lang;
60 if (time.isEmpty())
61 time = lang;
62 if (monetary.isEmpty())
63 monetary = lang;
65 lc_messages_var = lang;
67 lc_measurement_var = lang;
69 lc_collate_var = lang;
74}
75
76Q_GLOBAL_STATIC(QSystemLocaleData, qSystemLocaleData)
77
78#endif
79
80#ifndef QT_NO_SYSTEMLOCALE
81
82static bool contradicts(QStringView maybe, const QString &known)
83{
84 if (maybe.isEmpty())
85 return false;
86
87 /*
88 If \a known (our current best shot at deciding which language to use)
89 provides more information (e.g. script, country) than \a maybe (a
90 candidate to replace \a known) and \a maybe agrees with \a known in what
91 it does provide, we keep \a known; this happens when \a maybe comes from
92 LANGUAGE (usually a simple language code) and LANG includes script and/or
93 country. A textual comparison won't do because, for example, bn (Bengali)
94 isn't a prefix of ben_IN, but the latter is a refinement of the former.
95 (Meanwhile, bn is a prefix of bnt, Bantu; and a prefix of ben is be,
96 Belarusian. There are many more such prefixings between two- and
97 three-letter codes.)
98 */
99 QLocaleId knownId = QLocaleId::fromName(known);
100 QLocaleId maybeId = QLocaleId::fromName(maybe);
101 return !(maybeId.acceptLanguage(knownId.language_id) && maybeId.acceptScriptTerritory(knownId));
102}
103
105{
106 // See man 7 locale for precedence - LC_ALL beats LC_MESSAGES beats LANG:
107 QString lang = qEnvironmentVariable("LC_ALL");
108 if (lang.isEmpty())
109 lang = qEnvironmentVariable("LC_MESSAGES");
110 if (lang.isEmpty())
111 lang = qEnvironmentVariable("LANG");
112 // if the locale is the "C" locale, then we can return the language we found here:
113 if (lang.isEmpty() || lang == "C"_L1 || lang == "POSIX"_L1)
114 return QLocale(lang);
115
116 // ... otherwise, if the first part of LANGUAGE says more than or
117 // contradicts what we have, use that:
118 for (const auto &language : qEnvironmentVariable("LANGUAGE").tokenize(u':')) {
119 if (contradicts(language, lang))
120 return QLocale(language);
121 break; // We only look at the first entry.
122 }
123
124 return QLocale(lang);
125}
126
127QVariant QSystemLocale::query(QueryType type, QVariant &&in) const
128{
129 QSystemLocaleData *d = qSystemLocaleData();
130
131 if (type == LocaleChanged) {
132 d->readEnvironment();
133 return QVariant();
134 }
135
136 QReadLocker locker(&d->lock);
137
138 const QLocale &lc_numeric = d->lc_numeric;
139 const QLocale &lc_time = d->lc_time;
140 const QLocale &lc_monetary = d->lc_monetary;
141 const QLocale &lc_messages = d->lc_messages;
142
143 switch (type) {
144 case DecimalPoint:
145 return lc_numeric.decimalPoint();
146 case GroupSeparator:
147 return lc_numeric.groupSeparator();
148 case ZeroDigit:
149 return lc_numeric.zeroDigit();
150 case NegativeSign:
151 return lc_numeric.negativeSign();
152 case DateFormatLong:
153 return lc_time.dateFormat(QLocale::LongFormat);
154 case DateFormatShort:
155 return lc_time.dateFormat(QLocale::ShortFormat);
156 case TimeFormatLong:
157 return lc_time.timeFormat(QLocale::LongFormat);
158 case TimeFormatShort:
159 return lc_time.timeFormat(QLocale::ShortFormat);
160 case DayNameLong:
161 return lc_time.dayName(in.toInt(), QLocale::LongFormat);
162 case DayNameShort:
163 return lc_time.dayName(in.toInt(), QLocale::ShortFormat);
164 case DayNameNarrow:
165 return lc_time.dayName(in.toInt(), QLocale::NarrowFormat);
167 return lc_time.standaloneDayName(in.toInt(), QLocale::LongFormat);
169 return lc_time.standaloneDayName(in.toInt(), QLocale::ShortFormat);
171 return lc_time.standaloneDayName(in.toInt(), QLocale::NarrowFormat);
172 case MonthNameLong:
173 return lc_time.monthName(in.toInt(), QLocale::LongFormat);
174 case MonthNameShort:
175 return lc_time.monthName(in.toInt(), QLocale::ShortFormat);
176 case MonthNameNarrow:
177 return lc_time.monthName(in.toInt(), QLocale::NarrowFormat);
179 return lc_time.standaloneMonthName(in.toInt(), QLocale::LongFormat);
181 return lc_time.standaloneMonthName(in.toInt(), QLocale::ShortFormat);
183 return lc_time.standaloneMonthName(in.toInt(), QLocale::NarrowFormat);
184 case DateToStringLong:
185 return lc_time.toString(in.toDate(), QLocale::LongFormat);
187 return lc_time.toString(in.toDate(), QLocale::ShortFormat);
188 case TimeToStringLong:
189 return lc_time.toString(in.toTime(), QLocale::LongFormat);
191 return lc_time.toString(in.toTime(), QLocale::ShortFormat);
193 return lc_time.dateTimeFormat(QLocale::LongFormat);
195 return lc_time.dateTimeFormat(QLocale::ShortFormat);
197 return lc_time.toString(in.toDateTime(), QLocale::LongFormat);
199 return lc_time.toString(in.toDateTime(), QLocale::ShortFormat);
200 case PositiveSign:
201 return lc_numeric.positiveSign();
202 case AMText:
203 return lc_time.amText();
204 case PMText:
205 return lc_time.pmText();
206 case FirstDayOfWeek:
207 return lc_time.firstDayOfWeek();
208 case CurrencySymbol:
209 return lc_monetary.currencySymbol(QLocale::CurrencySymbolFormat(in.toUInt()));
210 case CurrencyToString: {
211 switch (in.userType()) {
212 case QMetaType::Int:
213 return lc_monetary.toCurrencyString(in.toInt());
214 case QMetaType::UInt:
215 return lc_monetary.toCurrencyString(in.toUInt());
216 case QMetaType::Double:
217 return lc_monetary.toCurrencyString(in.toDouble());
218 case QMetaType::LongLong:
219 return lc_monetary.toCurrencyString(in.toLongLong());
220 case QMetaType::ULongLong:
221 return lc_monetary.toCurrencyString(in.toULongLong());
222 default:
223 break;
224 }
225 return QString();
226 }
227 case MeasurementSystem: {
228 const QString meas_locale = QString::fromLatin1(d->lc_measurement_var);
229 if (meas_locale.compare("Metric"_L1, Qt::CaseInsensitive) == 0)
231 if (meas_locale.compare("Other"_L1, Qt::CaseInsensitive) == 0)
233 return QVariant((int)QLocale(meas_locale).measurementSystem());
234 }
235 case Collation:
236 return QString::fromLatin1(d->lc_collate_var);
237 case UILanguages: {
238 if (!d->uiLanguages.isEmpty())
239 return d->uiLanguages;
240 QString languages = QString::fromLatin1(qgetenv("LANGUAGE"));
241 QStringList lst;
242 if (languages.isEmpty())
243 lst.append(QString::fromLatin1(d->lc_messages_var));
244 else
245 lst = languages.split(u':');
246
247 for (const QString &e : std::as_const(lst)) {
248 QStringView language, script, territory;
249 if (qt_splitLocaleName(e, &language, &script, &territory)) {
250 QString joined = language.isEmpty() ? u"und"_s : language.toString();
251 if (!script.isEmpty())
252 joined += u'-' + script;
253 if (!territory.isEmpty())
254 joined += u'-' + territory;
255 d->uiLanguages.append(joined);
256 }
257 }
258 return d->uiLanguages.isEmpty() ? QVariant() : QVariant(d->uiLanguages);
259 }
261 return lc_messages.quoteString(qvariant_cast<QStringView>(std::move(in)));
263 return lc_messages.quoteString(qvariant_cast<QStringView>(std::move(in)),
266 return lc_messages.createSeparatedList(in.toStringList());
267 case LocaleChanged:
268 Q_ASSERT(false);
269 [[fallthrough]];
270 default:
271 break;
272 }
273 return QVariant();
274}
275#endif // QT_NO_SYSTEMLOCALE
276
\inmodule QtCore
Definition qbytearray.h:57
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
QString decimalPoint() const
Definition qlocale.cpp:2655
QString quoteString(const QString &str, QuotationStyle style=StandardQuotation) const
Definition qlocale.h:1161
QString dateTimeFormat(FormatType format=LongFormat) const
Definition qlocale.cpp:2396
QString zeroDigit() const
Definition qlocale.cpp:2710
QString dateFormat(FormatType format=LongFormat) const
Definition qlocale.cpp:2334
QString negativeSign() const
Definition qlocale.cpp:2727
Qt::DayOfWeek firstDayOfWeek() const
Definition qlocale.cpp:3272
@ AlternateQuotation
Definition qlocale.h:1159
QString dayName(int, FormatType format=LongFormat) const
Definition qlocale.cpp:2997
@ MetricSystem
Definition qlocale.h:868
CurrencySymbolFormat
Definition qlocale.h:896
@ LongFormat
Definition qlocale.h:875
@ NarrowFormat
Definition qlocale.h:875
@ ShortFormat
Definition qlocale.h:875
QString toCurrencyString(qlonglong, const QString &symbol=QString()) const
Definition qlocale.cpp:4580
QString timeFormat(FormatType format=LongFormat) const
Definition qlocale.cpp:2365
QString groupSeparator() const
Definition qlocale.cpp:2674
QString createSeparatedList(const QStringList &strl) const
Definition qlocale.cpp:1246
QString monthName(int, FormatType format=LongFormat) const
Definition qlocale.cpp:2963
QString amText() const
Definition qlocale.cpp:3439
QString pmText() const
Definition qlocale.cpp:3459
QString positiveSign() const
Definition qlocale.cpp:2744
QString toString(qlonglong i) const
Returns a localized string representation of i.
Definition qlocale.cpp:2052
QString standaloneMonthName(int, FormatType format=LongFormat) const
Definition qlocale.cpp:2979
QString standaloneDayName(int, FormatType format=LongFormat) const
Definition qlocale.cpp:3014
QString currencySymbol(CurrencySymbolFormat=CurrencySymbol) const
Definition qlocale.cpp:4548
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
Definition qstring.cpp:8218
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
@ StringToAlternateQuotation
Definition qlocale_p.h:160
@ DateTimeToStringShort
Definition qlocale_p.h:148
@ StandaloneMonthNameLong
Definition qlocale_p.h:166
@ ListToSeparatedString
Definition qlocale_p.h:162
@ StandaloneDayNameNarrow
Definition qlocale_p.h:171
@ StandaloneMonthNameNarrow
Definition qlocale_p.h:168
@ StringToStandardQuotation
Definition qlocale_p.h:159
@ StandaloneDayNameShort
Definition qlocale_p.h:170
@ StandaloneDayNameLong
Definition qlocale_p.h:169
@ StandaloneMonthNameShort
Definition qlocale_p.h:167
virtual QLocale fallbackLocale() const
virtual QVariant query(QueryType type, QVariant &&in=QVariant()) const
\inmodule QtCore
Definition qvariant.h:65
\inmodule QtCore
Combined button and popup list for selecting options.
@ CaseInsensitive
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
bool qt_splitLocaleName(QStringView name, QStringView *lang=nullptr, QStringView *script=nullptr, QStringView *cntry=nullptr)
Definition qlocale.cpp:567
static bool contradicts(QStringView maybe, const QString &known)
GLenum type
GLuint in
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
static Q_AUTOTEST_EXPORT QLocaleId fromName(QStringView name)
Definition qlocale.cpp:611
QStringList uiLanguages
QByteArray lc_messages_var
QByteArray lc_collate_var
QByteArray lc_measurement_var
QReadWriteLock lock