Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qlocale_android.cpp
Go to the documentation of this file.
1
// Copyright (C) 2026 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
// Qt-Security score:significant reason:default
4
5
#
include
"qlocale_p.h"
6
7
#
include
"qdatetime.h"
8
#
include
"qjniobject.h"
9
#
include
"qreadwritelock.h"
10
#
include
"qstringlist.h"
11
#
include
"qvariant.h"
12
13
#
include
<
QtCore
/
private
/
qjnihelpers_p
.
h
>
14
15
QT_BEGIN_NAMESPACE
16
17
#
ifndef
QT_NO_SYSTEMLOCALE
18
19
Q_DECLARE_JNI_CLASS(Locale,
"java/util/Locale"
)
20
Q_DECLARE_JNI_CLASS(Resources,
"android/content/res/Resources"
)
21
Q_DECLARE_JNI_CLASS(Configuration,
"android/content/res/Configuration"
)
22
Q_DECLARE_JNI_CLASS(LocaleList,
"android/os/LocaleList"
)
23
Q_DECLARE_JNI_CLASS(DateFormat,
"java/text/DateFormat"
)
24
25
namespace
{
26
27
using
namespace
Qt::StringLiterals;
28
using
namespace
QtJniTypes;
29
30
struct
LocaleInfo
31
{
32
QLocale
::
Language
language
=
QLocale
::
AnyLanguage
;
33
QLocale
::
Script
script
=
QLocale
::
AnyScript
;
34
QLocale
::
Territory
territory
=
QLocale
::
AnyTerritory
;
35
QString
timeFormatShort
;
36
QString
timeFormatLong
;
37
QString
dateFormatShort
;
38
QString
dateFormatLong
;
39
};
40
41
struct
QSystemLocaleData
42
{
43
void
readLocaleFromJava
();
44
LocaleInfo
snapshot
()
45
{
46
QReadLocker locker(&lock);
47
return
localeInfo;
48
}
49
50
QReadWriteLock
lock
;
51
LocaleInfo
localeInfo
;
52
};
53
54
// Translate the Java SimpleDateFormat tokens Qt doesn't accept to Qt's
55
// (E/EE/EEE → ddd, EEEE → dddd, y/yyy+ → yyyy; a → aP to keep the locale's
56
// own AM/PM casing rather than force lower-case). Other tokens pass through.
57
// See https://developer.android.com/reference/java/text/SimpleDateFormat
58
QString
qtPatternFromJava
(QStringView pattern)
59
{
60
QString out;
61
out.reserve(pattern.size());
62
bool
inQuoted =
false
;
63
while
(!pattern.isEmpty()) {
64
const
QChar ch = pattern.front();
65
qsizetype consumed = 1;
66
if
(ch == u'\'') {
67
inQuoted = !inQuoted;
68
out.append(ch);
69
}
else
if
(inQuoted) {
70
out.append(ch);
71
}
else
if
(ch == u'E' || ch == u'y' || ch == u'a') {
72
while
(consumed < pattern.size() && pattern[consumed] == ch)
73
++consumed;
74
if
(ch == u'E')
75
out.append(consumed >= 4 ?
"dddd"_L1
:
"ddd"_L1
);
76
else
if
(ch == u'y')
77
out.append(consumed == 2 ?
"yy"_L1
:
"yyyy"_L1
);
78
else
// 'a'
79
out.append(
"aP"_L1
);
80
}
else
{
81
out.append(ch);
82
}
83
pattern = pattern.sliced(consumed);
84
}
85
return
out;
86
}
87
88
// Qt pattern via java.text.DateFormat.get{Date,Time}Instance(style, locale).
89
QString
patternForStyle
(QSystemLocale::QueryType type,
const
Locale &locale)
90
{
91
// https://docs.oracle.com/javase/8/docs/api/java/text/DateFormat.html
92
constexpr
jint SHORT = 3;
93
constexpr
jint MEDIUM = 2;
94
constexpr
jint FULL = 0;
95
96
const
char
*factory =
nullptr
;
97
jint style = 0;
98
switch
(type) {
99
case
QSystemLocale::DateFormatShort: factory =
"getDateInstance"
; style = SHORT;
break
;
100
case
QSystemLocale::DateFormatLong: factory =
"getDateInstance"
; style = FULL;
break
;
101
case
QSystemLocale::TimeFormatShort: factory =
"getTimeInstance"
; style = SHORT;
break
;
102
case
QSystemLocale::TimeFormatLong: factory =
"getTimeInstance"
; style = MEDIUM;
break
;
103
default
: Q_UNREACHABLE();
break
;
104
}
105
106
const
auto
dateFormat = DateFormat::callStaticMethod<DateFormat>(factory, style, locale);
107
return
qtPatternFromJava(dateFormat.callMethod<QString>(
"toPattern"
));
108
}
109
110
void
QSystemLocaleData
::
readLocaleFromJava
()
111
{
112
const
QJniObject context = QtAndroidPrivate::context();
113
const
Locale androidLocale = [context]{
114
if
(context.isValid()) {
115
const
auto
resources = context.callMethod<Resources>(
"getResources"
);
116
const
auto
configuration = resources.callMethod<Configuration>(
"getConfiguration"
);
117
return
configuration.getField<Locale>(
"locale"
);
118
}
119
return
Locale::callStaticMethod<Locale>(
"getDefault"
);
120
}();
121
122
LocaleInfo
updated;
123
updated.language = QLocale::codeToLanguage(androidLocale.callMethod<QString>(
"getLanguage"
));
124
updated.script = QLocale::codeToScript(androidLocale.callMethod<QString>(
"getScript"
));
125
updated.territory = QLocale::codeToTerritory(androidLocale.callMethod<QString>(
"getCountry"
));
126
// QLocale does not yet support variants (QTBUG-81051)
127
// updated.variant = androidLocale.callMethod<QString>("getVariant");
128
129
updated.dateFormatShort = patternForStyle(QSystemLocale::DateFormatShort, androidLocale);
130
updated.dateFormatLong = patternForStyle(QSystemLocale::DateFormatLong, androidLocale);
131
updated.timeFormatShort = patternForStyle(QSystemLocale::TimeFormatShort, androidLocale);
132
updated.timeFormatLong = patternForStyle(QSystemLocale::TimeFormatLong, androidLocale);
133
// QTBUG-145605: locale-correct date/time gluing is possible with
134
// java.text.DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale).
135
// QLocale handles DateTimeFormat{Short,Long} gluing, so they are deliberately left out.
136
137
QWriteLocker locker(&lock);
138
localeInfo = updated;
139
}
140
141
Q_GLOBAL_STATIC(QSystemLocaleData, qSystemLocaleData)
142
143
}
// unnamed namespace
144
145
QLocale QSystemLocale::fallbackLocale()
const
146
{
147
QSystemLocaleData *d = qSystemLocaleData();
148
if
(!d)
149
return
QLocale(QLocale::C);
150
151
const
LocaleInfo info = d->snapshot();
152
return
QLocale(info.language, info.script, info.territory);
153
}
154
155
QVariant QSystemLocale::query(QueryType type, QVariant &&in)
const
156
{
157
Q_UNUSED(in);
158
QSystemLocaleData *d = qSystemLocaleData();
159
if
(!d)
160
return
QVariant();
161
162
if
(type == LocaleChanged) {
163
d->readLocaleFromJava();
164
return
QVariant();
165
}
166
167
const
LocaleInfo info = d->snapshot();
168
169
switch
(type) {
170
case
LanguageId:
171
return
QVariant::fromValue(
static_cast
<
int
>(info.language));
172
case
TerritoryId:
173
return
QVariant::fromValue(
static_cast
<
int
>(info.territory));
174
case
ScriptId:
175
return
QVariant::fromValue(
static_cast
<
int
>(info.script));
176
case
Collation:
177
return
QLocale(info.language, info.script, info.territory).name();
178
case
TimeFormatShort:
179
return
info.timeFormatShort;
180
case
TimeFormatLong:
181
return
info.timeFormatLong;
182
case
DateFormatShort:
183
return
info.dateFormatShort;
184
case
DateFormatLong:
185
return
info.dateFormatLong;
186
case
UILanguages: {
187
const
LocaleList localeList = LocaleList::callStaticMethod<LocaleList>(
"getDefault"
);
188
if
(!localeList.isValid())
189
return
QVariant();
190
QString tags = localeList.callMethod<QString>(
"toLanguageTags"
);
191
// Some devices wrap the list in [] - strip those if present.
192
if
(tags.startsWith(u'[') && tags.endsWith(u']'))
193
tags = tags.mid(1, tags.length() - 2);
194
return
tags.split(u',');
195
}
196
case
LocaleChanged:
197
Q_UNREACHABLE();
// handled before the switch
198
default
:
199
break
;
200
}
201
return
QVariant();
202
}
203
204
#
endif
// QT_NO_SYSTEMLOCALE
205
206
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QT_BEGIN_NAMESPACE::qtPatternFromJava
QString qtPatternFromJava(QStringView pattern)
Definition
qlocale_android.cpp:58
QT_BEGIN_NAMESPACE::patternForStyle
QString patternForStyle(QSystemLocale::QueryType type, const Locale &locale)
Definition
qlocale_android.cpp:89
QT_BEGIN_NAMESPACE::LocaleInfo
Definition
qlocale_android.cpp:31
QT_BEGIN_NAMESPACE::LocaleInfo::territory
QLocale::Territory territory
Definition
qlocale_android.cpp:34
QT_BEGIN_NAMESPACE::LocaleInfo::script
QLocale::Script script
Definition
qlocale_android.cpp:33
QT_BEGIN_NAMESPACE::LocaleInfo::dateFormatShort
QString dateFormatShort
Definition
qlocale_android.cpp:37
QT_BEGIN_NAMESPACE::LocaleInfo::language
QLocale::Language language
Definition
qlocale_android.cpp:32
QT_BEGIN_NAMESPACE::LocaleInfo::timeFormatLong
QString timeFormatLong
Definition
qlocale_android.cpp:36
QT_BEGIN_NAMESPACE::LocaleInfo::dateFormatLong
QString dateFormatLong
Definition
qlocale_android.cpp:38
QT_BEGIN_NAMESPACE::LocaleInfo::timeFormatShort
QString timeFormatShort
Definition
qlocale_android.cpp:35
QT_BEGIN_NAMESPACE::QSystemLocaleData
Definition
qlocale_android.cpp:42
QT_BEGIN_NAMESPACE::QSystemLocaleData::readLocaleFromJava
void readLocaleFromJava()
Definition
qlocale_android.cpp:110
QT_BEGIN_NAMESPACE::QSystemLocaleData::localeInfo
LocaleInfo localeInfo
Definition
qlocale_android.cpp:51
QT_BEGIN_NAMESPACE::QSystemLocaleData::lock
QReadWriteLock lock
Definition
qlocale_android.cpp:50
QT_BEGIN_NAMESPACE::QSystemLocaleData::snapshot
LocaleInfo snapshot()
Definition
qlocale_android.cpp:44
qtbase
src
corelib
text
qlocale_android.cpp
Generated on
for Qt by
1.18.0