Fixed Chinese language selection on iOS
For language "Traditional Chinese" on iOS with region "US", the logic was formerly to attempt a match on country/language/script (fail), followed by country/language (which would result in script defaulting to "Simplified"). Now, the logic is to try language/script first if script is specified. Failing that, language/country will be attempted. Task-number: QTBUG-39639 Change-Id: I75a774b1e66686e95167ff221458a97a7ea2660d Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jason Erb <jason.erb@sparist.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
858c1afb7a
commit
ae42bf0f9b
@ -334,33 +334,17 @@ QByteArray QLocalePrivate::bcp47Name(char separator) const
|
||||
return localeId.withLikelySubtagsRemoved().name(separator);
|
||||
}
|
||||
|
||||
const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country)
|
||||
static const QLocaleData *findLocaleDataById(const QLocaleId &localeId)
|
||||
{
|
||||
QLocaleId localeId = QLocaleId::fromIds(language, script, country);
|
||||
localeId = localeId.withLikelySubtagsAdded();
|
||||
|
||||
uint idx = locale_index[localeId.language_id];
|
||||
const uint idx = locale_index[localeId.language_id];
|
||||
|
||||
const QLocaleData *data = locale_data + idx;
|
||||
|
||||
if (idx == 0) // default language has no associated country
|
||||
if (idx == 0) // default language has no associated script or country
|
||||
return data;
|
||||
|
||||
Q_ASSERT(data->m_language_id == localeId.language_id);
|
||||
|
||||
if (localeId.script_id != QLocale::AnyScript && localeId.country_id != QLocale::AnyCountry) {
|
||||
// both script and country are explicitly specified
|
||||
do {
|
||||
if (data->m_script_id == localeId.script_id && data->m_country_id == localeId.country_id)
|
||||
return data;
|
||||
++data;
|
||||
} while (data->m_language_id == localeId.language_id);
|
||||
|
||||
// no match; try again with default script
|
||||
localeId.script_id = QLocale::AnyScript;
|
||||
data = locale_data + idx;
|
||||
}
|
||||
|
||||
if (localeId.script_id == QLocale::AnyScript && localeId.country_id == QLocale::AnyCountry)
|
||||
return data;
|
||||
|
||||
@ -369,15 +353,72 @@ const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLoca
|
||||
if (data->m_country_id == localeId.country_id)
|
||||
return data;
|
||||
++data;
|
||||
} while (data->m_language_id == localeId.language_id);
|
||||
} while (data->m_language_id && data->m_language_id == localeId.language_id);
|
||||
} else if (localeId.country_id == QLocale::AnyCountry) {
|
||||
do {
|
||||
if (data->m_script_id == localeId.script_id)
|
||||
return data;
|
||||
++data;
|
||||
} while (data->m_language_id == localeId.language_id);
|
||||
} while (data->m_language_id && data->m_language_id == localeId.language_id);
|
||||
} else {
|
||||
do {
|
||||
if (data->m_script_id == localeId.script_id && data->m_country_id == localeId.country_id)
|
||||
return data;
|
||||
++data;
|
||||
} while (data->m_language_id && data->m_language_id == localeId.language_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country)
|
||||
{
|
||||
QLocaleId localeId = QLocaleId::fromIds(language, script, country);
|
||||
localeId = localeId.withLikelySubtagsAdded();
|
||||
|
||||
const uint idx = locale_index[localeId.language_id];
|
||||
|
||||
// Try a straight match
|
||||
if (const QLocaleData *const data = findLocaleDataById(localeId))
|
||||
return data;
|
||||
QList<QLocaleId> tried;
|
||||
tried.push_back(localeId);
|
||||
|
||||
// No match; try again with likely country
|
||||
localeId = QLocaleId::fromIds(language, script, QLocale::AnyCountry);
|
||||
localeId = localeId.withLikelySubtagsAdded();
|
||||
if (!tried.contains(localeId)) {
|
||||
if (const QLocaleData *const data = findLocaleDataById(localeId))
|
||||
return data;
|
||||
tried.push_back(localeId);
|
||||
}
|
||||
|
||||
// No match; try again with any country
|
||||
localeId = QLocaleId::fromIds(language, script, QLocale::AnyCountry);
|
||||
if (!tried.contains(localeId)) {
|
||||
if (const QLocaleData *const data = findLocaleDataById(localeId))
|
||||
return data;
|
||||
tried.push_back(localeId);
|
||||
}
|
||||
|
||||
// No match; try again with likely script
|
||||
localeId = QLocaleId::fromIds(language, QLocale::AnyScript, country);
|
||||
localeId = localeId.withLikelySubtagsAdded();
|
||||
if (!tried.contains(localeId)) {
|
||||
if (const QLocaleData *const data = findLocaleDataById(localeId))
|
||||
return data;
|
||||
tried.push_back(localeId);
|
||||
}
|
||||
|
||||
// No match; try again with any script
|
||||
localeId = QLocaleId::fromIds(language, QLocale::AnyScript, country);
|
||||
if (!tried.contains(localeId)) {
|
||||
if (const QLocaleData *const data = findLocaleDataById(localeId))
|
||||
return data;
|
||||
tried.push_back(localeId);
|
||||
}
|
||||
|
||||
// No match; return data at original index
|
||||
return locale_data + idx;
|
||||
}
|
||||
|
||||
|
@ -186,12 +186,50 @@ void tst_QLocale::ctor()
|
||||
QVERIFY(l.country() == default_country);
|
||||
}
|
||||
|
||||
#define TEST_CTOR(req_lang, req_script, req_country, exp_lang, exp_script, exp_country) \
|
||||
{ \
|
||||
QLocale l(QLocale::req_lang, QLocale::req_script, QLocale::req_country); \
|
||||
QCOMPARE((int)l.language(), (int)exp_lang); \
|
||||
QCOMPARE((int)l.script(), (int)exp_script); \
|
||||
QCOMPARE((int)l.country(), (int)exp_country); \
|
||||
}
|
||||
|
||||
// Exact matches
|
||||
TEST_CTOR(Chinese, SimplifiedHanScript, China, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
|
||||
TEST_CTOR(Chinese, TraditionalHanScript, Taiwan, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
|
||||
TEST_CTOR(Chinese, TraditionalHanScript, HongKong, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong);
|
||||
|
||||
// Best match for AnyCountry
|
||||
TEST_CTOR(Chinese, SimplifiedHanScript, AnyCountry, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
|
||||
TEST_CTOR(Chinese, TraditionalHanScript, AnyCountry, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
|
||||
|
||||
// Best match for AnyScript (and change country to supported one, if necessary)
|
||||
TEST_CTOR(Chinese, AnyScript, China, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
|
||||
TEST_CTOR(Chinese, AnyScript, Taiwan, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
|
||||
TEST_CTOR(Chinese, AnyScript, HongKong, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong);
|
||||
TEST_CTOR(Chinese, AnyScript, UnitedStates, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
|
||||
|
||||
// Fully-specified not found; find best alternate country
|
||||
TEST_CTOR(Chinese, SimplifiedHanScript, Taiwan, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
|
||||
TEST_CTOR(Chinese, SimplifiedHanScript, UnitedStates, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
|
||||
TEST_CTOR(Chinese, TraditionalHanScript, China, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
|
||||
TEST_CTOR(Chinese, TraditionalHanScript, UnitedStates, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
|
||||
|
||||
// Fully-specified not found; find best alternate script
|
||||
TEST_CTOR(Chinese, LatinScript, China, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
|
||||
TEST_CTOR(Chinese, LatinScript, Taiwan, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
|
||||
|
||||
// Fully-specified not found; find best alternate country and script
|
||||
TEST_CTOR(Chinese, LatinScript, UnitedStates, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
|
||||
|
||||
#undef TEST_CTOR
|
||||
#define TEST_CTOR(req_lang, req_country, exp_lang, exp_country) \
|
||||
{ \
|
||||
QLocale l(QLocale::req_lang, QLocale::req_country); \
|
||||
QCOMPARE((int)l.language(), (int)exp_lang); \
|
||||
QCOMPARE((int)l.country(), (int)exp_country); \
|
||||
}
|
||||
|
||||
{
|
||||
QLocale l(QLocale::C, QLocale::AnyCountry);
|
||||
QCOMPARE(l.language(), QLocale::C);
|
||||
@ -295,7 +333,6 @@ void tst_QLocale::ctor()
|
||||
TEST_CTOR(Uzbek, AnyCountry, QLocale::Uzbek, QLocale::Uzbekistan)
|
||||
|
||||
#undef TEST_CTOR
|
||||
|
||||
#define TEST_CTOR(req_lc, exp_lang, exp_country) \
|
||||
{ \
|
||||
QLocale l(req_lc); \
|
||||
|
Loading…
Reference in New Issue
Block a user