aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKuisma Salonen <kuisma.salonen@nokia.com>2011-01-05 18:05:41 +0200
committerMike FABIAN <mike.fabian@basyskom.de>2011-01-10 16:28:45 +0100
commit3cf7f1e33f9906a0ad1776dd1cea4ad53345c9f5 (patch)
tree894dbcff24f153a5fffb8b82b00be7a002b736f6
parent918243b9f20b982759479c710ccf6fa9c334d23c (diff)
Fixes: NB#217105
RevBy: TrustMe Details: Added two static methods to MLocale that allow to obtain endonym and primary script for a language. This is useful when one has to obtain a long list of these and instantiating MLocale each time is too heavy.
-rw-r--r--src/corelib/i18n/mlocale.cpp95
-rw-r--r--src/corelib/i18n/mlocale.h16
-rw-r--r--src/corelib/i18n/mlocale_p.h2
3 files changed, 111 insertions, 2 deletions
diff --git a/src/corelib/i18n/mlocale.cpp b/src/corelib/i18n/mlocale.cpp
index ef7e98d3..d29eb988 100644
--- a/src/corelib/i18n/mlocale.cpp
+++ b/src/corelib/i18n/mlocale.cpp
@@ -259,7 +259,7 @@ QStringList MLocalePrivate::translationPaths;
QStringList MLocalePrivate::dataPaths;
#ifdef HAVE_ICU
-bool MLocalePrivate::truncateLocaleName(QString *localeName) const
+bool MLocalePrivate::truncateLocaleName(QString *localeName)
{
// according to http://userguide.icu-project.org/locale the separators
// that specify the parts of a locale are "_", "@", and ";", e.g.
@@ -3086,6 +3086,99 @@ QStringList MLocale::dataPaths()
return MLocalePrivate::dataPaths;
}
+
+#ifdef HAVE_ICU
+QString MLocale::localeScript(const QString &locale)
+{
+ QString s = MLocalePrivate::parseScript(locale);
+
+ if(!s.isEmpty())
+ return s;
+
+ UErrorCode status = U_ZERO_ERROR;
+ UResourceBundle *res = ures_open(NULL, qPrintable(locale), &status);
+ if(U_FAILURE(status)) // TODO: error handling++
+ return QString();
+
+ res = ures_getByKey(res, "LocaleScript", res, &status);
+ if(U_FAILURE(status)) {
+ ures_close(res);
+ return QString();
+ }
+
+ QString ret("Zyyy");
+
+ qint32 len;
+ const UChar *v;
+ v = ures_getNextString(res, &len, NULL, &status);
+ if(v && U_SUCCESS(status))
+ ret = QString::fromUtf16(v, len);
+
+ ures_close(res);
+
+ return ret;
+}
+
+QString MLocale::languageEndonym(const QString &locale)
+{
+ QString resourceBundleLocaleName = locale;
+
+ do {
+ // Trying several resource bundles is a workaround for
+ // http://site.icu-project.org/design/resbund/issues
+ UErrorCode status = U_ZERO_ERROR;
+ UResourceBundle *res = ures_open(U_ICUDATA_NAME "-lang",
+ qPrintable(resourceBundleLocaleName),
+ &status);
+ if (U_FAILURE(status)) {
+ mDebug("MLocale") << "Error ures_open" << u_errorName(status);
+ ures_close(res);
+ return locale;
+ }
+ res = ures_getByKey(res, Languages, res, &status);
+ if (U_FAILURE(status)) {
+ mDebug("MLocale") << "Error ures_getByKey" << u_errorName(status);
+ ures_close(res);
+ return locale;
+ }
+ QString keyLocaleName = locale;
+ // it’s not nice if “zh_CN”, “zh_HK”, “zh_MO”, “zh_TW” all fall back to
+ // “zh” for the language endonym and display only “中文”.
+ // To make the fallbacks work better, insert the script:
+ if (keyLocaleName.startsWith(QLatin1String("zh_CN")))
+ keyLocaleName = "zh_Hans_CN";
+ else if (keyLocaleName.startsWith(QLatin1String("zh_SG")))
+ keyLocaleName = "zh_Hans_SG";
+ else if (keyLocaleName.startsWith(QLatin1String("zh_HK")))
+ keyLocaleName = "zh_Hant_HK";
+ else if (keyLocaleName.startsWith(QLatin1String("zh_MO")))
+ keyLocaleName = "zh_Hant_MO";
+ else if (keyLocaleName.startsWith(QLatin1String("zh_TW")))
+ keyLocaleName = "zh_Hant_TW";
+ do { // FIXME: this loop should probably be somewhere else
+ int len;
+ status = U_ZERO_ERROR;
+ const UChar *val = ures_getStringByKey(res,
+ qPrintable(keyLocaleName),
+ &len,
+ &status);
+ if (U_SUCCESS(status)) {
+ // found language endonym, return it:
+ ures_close(res);
+ return QString::fromUtf16(val, len);
+ }
+ } while (MLocalePrivate::truncateLocaleName(&keyLocaleName));
+ // no language endonym found in this resource bundle and there
+ // is no way to shorten keyLocaleName, try the next resource
+ // bundle:
+ ures_close(res);
+ } while (MLocalePrivate::truncateLocaleName(&resourceBundleLocaleName));
+ // no language endonym found at all, no other keys or resource
+ // bundles left to try, return the full locale name as a fallback:
+ return locale;
+}
+#endif
+
///////
// the static convenience methods for translation
diff --git a/src/corelib/i18n/mlocale.h b/src/corelib/i18n/mlocale.h
index c1ad7d32..25c9b5ca 100644
--- a/src/corelib/i18n/mlocale.h
+++ b/src/corelib/i18n/mlocale.h
@@ -1656,6 +1656,22 @@ public:
*/
void disconnectSettings();
+ /*!
+ * \brief Static method to obtain primary script of locale.
+ * Can be used to obtain primary script without instantiating MLocale,
+ * useful when obtaining a list of scripts for a lot of languages. Primary
+ * script means a script returned by script() or first item in
+ * languageScripts().
+ */
+ static QString localeScript(const QString &locale);
+
+ /*!
+ * \bried Static method to obtain endonym for locale.
+ * Can be used to obtain endonym without instantiating MLocale, useful
+ * when obtaining a list of endonyms for a lot of languages.
+ */
+ static QString languageEndonym(const QString &locale);
+
Q_SIGNALS:
void settingsChanged();
/*!
diff --git a/src/corelib/i18n/mlocale_p.h b/src/corelib/i18n/mlocale_p.h
index 8e08f4f1..84da4eaa 100644
--- a/src/corelib/i18n/mlocale_p.h
+++ b/src/corelib/i18n/mlocale_p.h
@@ -109,7 +109,7 @@ public:
* as the parameter is left unchanged. I.e. if false is returned
* there are no fallbacks left to try.
*/
- bool truncateLocaleName(QString *localeName) const;
+ static bool truncateLocaleName(QString *localeName);
// creates an icu::Locale for specific category
icu::Locale getCategoryLocale(MLocale::Category category) const;