summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2011-02-18 16:58:47 (GMT)
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2011-02-23 14:16:49 (GMT)
commit81fe6eac7530ad508bf54e7996cbdc9e2f0cb5d1 (patch)
treed7f2d2163f2bc1170d805da928728a1bfdf37d44
parent400195768909f52dee30abff59dd9a5e03ea63dc (diff)
downloadQt-81fe6eac7530ad508bf54e7996cbdc9e2f0cb5d1.zip
Qt-81fe6eac7530ad508bf54e7996cbdc9e2f0cb5d1.tar.gz
Qt-81fe6eac7530ad508bf54e7996cbdc9e2f0cb5d1.tar.bz2
Added UI languages property to QLocale
The return value is a sorted list of locale names that could be used for presenting data to the user (i.e. for translations). Task-number: QTBUG-7329 Reviewed-by: Zeno Albisser
-rw-r--r--src/corelib/tools/qlocale.cpp133
-rw-r--r--src/corelib/tools/qlocale.h3
-rw-r--r--tests/auto/qlocale/tst_qlocale.cpp16
-rw-r--r--tests/manual/qlocale/languages.cpp62
-rw-r--r--tests/manual/qlocale/languages.h62
-rw-r--r--tests/manual/qlocale/qlocale.pro4
-rw-r--r--tests/manual/qlocale/window.cpp3
-rw-r--r--tests/manual/qlocale/window.h2
8 files changed, 279 insertions, 6 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 6f21633..ba9400c 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -69,6 +69,7 @@ QT_END_NAMESPACE
# include <CoreFoundation/CoreFoundation.h>
#endif
#include "private/qnumeric_p.h"
+#include "private/qsystemlibrary_p.h"
#include <ctype.h>
#include <float.h>
@@ -254,12 +255,18 @@ static const QLocalePrivate *findLocale(QLocale::Language language, QLocale::Cou
return locale_data + idx;
}
-static bool splitLocaleName(const QString &name, QChar *lang_begin, QChar *cntry_begin)
+static bool splitLocaleName(const QString &name,
+ QChar *lang_begin, QChar *cntry_begin,
+ int *lang_len = 0, int *cntry_len = 0)
{
for (int i = 0; i < 3; ++i)
lang_begin[i] = 0;
for (int i = 0; i < 3; ++i)
cntry_begin[i] = 0;
+ if (lang_len)
+ *lang_len = 0;
+ if (cntry_len)
+ *cntry_len = 0;
int l = name.length();
@@ -302,9 +309,13 @@ static bool splitLocaleName(const QString &name, QChar *lang_begin, QChar *cntry
++uc;
}
- int lang_len = lang - lang_begin;
+ if (lang_len)
+ *lang_len = lang - lang_begin;
+ if (cntry_len)
+ *cntry_len = cntry - cntry_begin;
- return lang_len == 2 || lang_len == 3;
+ int lang_length = lang - lang_begin;
+ return lang_length == 2 || lang_length == 3;
}
void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry)
@@ -733,6 +744,51 @@ static QString winFormatCurrency(const QVariant &in)
return QString::fromWCharArray(out.data());
}
+QStringList winUILanguages()
+{
+ if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) {
+ typedef BOOL (*GetUserPreferredUILanguagesFunc) (
+ DWORD dwFlags,
+ PULONG pulNumLanguages,
+ PWSTR pwszLanguagesBuffer,
+ PULONG pcchLanguagesBuffer);
+ static GetUserPreferredUILanguagesFunc GetUserPreferredUILanguages_ptr = 0;
+ if (!GetUserPreferredUILanguages_ptr) {
+ QSystemLibrary lib(QLatin1String("kernel32"));
+ if (lib.load())
+ GetUserPreferredUILanguages_ptr = (GetUserPreferredUILanguagesFunc)lib.resolve("GetUserPreferredUILanguages");
+ }
+ if (GetUserPreferredUILanguages_ptr) {
+ unsigned long cnt = 0;
+ QVarLengthArray<wchar_t, 64> buf(64);
+ unsigned long size = buf.size();
+ if (!GetUserPreferredUILanguages_ptr(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size)) {
+ size = 0;
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
+ GetUserPreferredUILanguages_ptr(MUI_LANGUAGE_NAME, &cnt, NULL, &size)) {
+ buf.resize(size);
+ if (!GetUserPreferredUILanguages_ptr(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size))
+ return QStringList();
+ }
+ }
+ QStringList result;
+ result.reserve(cnt);
+ const wchar_t *str = buf.constData();
+ for (; cnt > 0; --cnt) {
+ QString s = QString::fromWCharArray(str);
+ if (s.isEmpty())
+ break; // something is wrong
+ result.append(s);
+ str += s.size()+1;
+ }
+ return result;
+ }
+ }
+
+ // old Windows before Vista
+ return QStringList(QString::fromLatin1(winLangCodeToIsoName(GetUserDefaultUILanguage())));
+}
+
/*!
\since 4.6
Returns the fallback locale obtained from the system.
@@ -828,6 +884,8 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
return QVariant(winCurrencySymbol(QLocale::CurrencySymbolFormat(in.toUInt())));
case FormatCurrency:
return QVariant(winFormatCurrency(in));
+ case UILanguages:
+ return QVariant(winUILanguages());
default:
break;
}
@@ -1428,6 +1486,21 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
return QVariant(macCurrencySymbol(QLocale::CurrencySymbolFormat(in.toUInt())));
case FormatCurrency:
return macFormatCurrency(in);
+ case UILanguages: {
+ QCFType<CFArrayRef> languages = (CFArrayRef)CFPreferencesCopyValue(
+ CFSTR("AppleLanguages"),
+ kCFPreferencesAnyApplication,
+ kCFPreferencesCurrentUser,
+ kCFPreferencesAnyHost);
+ const int cnt = CFArrayGetCount(languages);
+ QStringList result;
+ result.reserve(cnt);
+ for (int i = 0; i < cnt; ++i) {
+ const QString lang = QCFString::toQString(
+ static_cast<CFStringRef>(CFArrayGetValueAtIndex(languages, i)));
+ result.append(lang);
+ }
+ return QVariant(result);
case QuotationBegin:
case QuotationEnd: {
return macQuotationSymbol(type,in);
@@ -1477,9 +1550,37 @@ QVariant QSystemLocale::query(QueryType type, QVariant /* in */) const
{
if (type == MeasurementSystem) {
return QVariant(unixGetSystemMeasurementSystem());
- } else {
+ } else if (type == UILanguages) {
+ QString languages = QString::fromLocal8Bit(qgetenv("LANGUAGE"));
+ if (!languages.isEmpty()) {
+ QStringList lst = languages.split(QLatin1Char(':'));
+ for (int i = 0; i < lst.size();) {
+ const QString &name = lst.at(i);
+ QChar lang[3];
+ QChar cntry[3];
+ if (name.isEmpty() || !splitLocaleName(name, lang, cntry))
+ lst.removeAt(i);
+ else
+ ++i;
+ }
+ return lst;
+ }
+ QString name = QString::fromLocal8Bit(qgetenv("LC_ALL"));
+ if (name.isEmpty()) {
+ name = QString::fromLocal8Bit(qgetenv("LC_MESSAGES"));
+ if (name.isEmpty())
+ name = QString::fromLocal8Bit(qgetenv("LANG"));
+ }
+ if (!name.isEmpty()) {
+ QChar lang[3];
+ QChar cntry[3];
+ int lang_len, cntry_len;
+ if (splitLocaleName(name, lang, cntry, &lang_len, &cntry_len))
+ return QStringList(QString::fromRawData(lang, lang_len) % QLatin1Char('-') % QString::fromRawData(cntry, cntry_len));
+ }
return QVariant();
}
+ return QVariant();
}
#elif !defined(Q_OS_SYMBIAN)
@@ -1574,6 +1675,7 @@ Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate)
\value FirstDayOfWeek a Qt::DayOfWeek enum specifiying the first day of the week
\value CurrencySymbol a string that represents a currency in a format QLocale::CurrencyFormat.
\value FormatCurrency a localized string representation of a number with a currency symbol.
+ \value UILanguages a list of strings representing locale names that could be used for UI translation.
\value QuotationBegin a QString specifying the start of a quotation. the in variant contains a QLocale::QuotationStyle
\value QuotationEnd a QString specifying the end of a quotation. the in variant contains a QLocale::QuotationStyle
*/
@@ -5078,6 +5180,29 @@ QString QLocale::toCurrencyString(double value) const
return format.arg(str, symbol);
}
+/*!
+ \since 4.8
+
+ Returns a sorted list of locale names that could be used for translation
+ of messages presented to the user.
+
+ \sa QTranslator
+*/
+QStringList QLocale::uiLanguages() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d() == systemPrivate()) {
+ QVariant res = systemLocale()->query(QSystemLocale::UILanguages, QVariant());
+ if (!res.isNull()) {
+ QStringList result = res.toStringList();
+ if (!result.isEmpty())
+ return result;
+ }
+ }
+#endif
+ return QStringList(name());
+}
+
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 924cb7b..18c6db3 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -98,6 +98,7 @@ public:
FirstDayOfWeek, // Qt::DayOfWeek
CurrencySymbol, // QString in: format
FormatCurrency, // QString in: qlonglong, qulonglong or double
+ UILanguages, // QStringList
QuotationBegin, // QString in: StandardQuotation or AlternateQuotation
QuotationEnd // QString in: StandardQuotation or AlternateQuotation
};
@@ -694,6 +695,8 @@ public:
QString toCurrencyString(double) const;
inline QString toCurrencyString(float) const;
+ QStringList uiLanguages() const;
+
inline bool operator==(const QLocale &other) const;
inline bool operator!=(const QLocale &other) const;
diff --git a/tests/auto/qlocale/tst_qlocale.cpp b/tests/auto/qlocale/tst_qlocale.cpp
index 250aac9..878a31e 100644
--- a/tests/auto/qlocale/tst_qlocale.cpp
+++ b/tests/auto/qlocale/tst_qlocale.cpp
@@ -142,6 +142,7 @@ private slots:
void ampm();
void currency();
void quoteString();
+ void uiLanguages();
private:
QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
@@ -2169,5 +2170,20 @@ void tst_QLocale::quoteString()
}
+void tst_QLocale::uiLanguages()
+{
+ const QLocale c(QLocale::C);
+ QCOMPARE(c.uiLanguages().size(), 1);
+ QCOMPARE(c.uiLanguages().at(0), QLatin1String("C"));
+
+ const QLocale en_US("en_US");
+ QCOMPARE(en_US.uiLanguages().size(), 1);
+ QCOMPARE(en_US.uiLanguages().at(0), QLatin1String("en_US"));
+
+ const QLocale ru_RU("ru_RU");
+ QCOMPARE(ru_RU.uiLanguages().size(), 1);
+ QCOMPARE(ru_RU.uiLanguages().at(0), QLatin1String("ru_RU"));
+}
+
QTEST_APPLESS_MAIN(tst_QLocale)
#include "tst_qlocale.moc"
diff --git a/tests/manual/qlocale/languages.cpp b/tests/manual/qlocale/languages.cpp
new file mode 100644
index 0000000..65029c3
--- /dev/null
+++ b/tests/manual/qlocale/languages.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "languages.h"
+
+LanguagesWidget::LanguagesWidget()
+{
+ QVBoxLayout *l = new QVBoxLayout(this);
+
+ languagesLabel = new QLabel("Preferred languages:");
+ languagesList = new QListWidget;
+
+ l->addWidget(languagesLabel);
+ l->addWidget(languagesList);
+
+ localeChanged(QLocale());
+}
+
+void LanguagesWidget::localeChanged(QLocale locale)
+{
+ languagesList->clear();
+ languagesList->addItems(locale.uiLanguages());
+}
+
+
diff --git a/tests/manual/qlocale/languages.h b/tests/manual/qlocale/languages.h
new file mode 100644
index 0000000..18e503f
--- /dev/null
+++ b/tests/manual/qlocale/languages.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LANGUAGES_H
+#define LANGUAGES_H
+
+#include <QtGui>
+
+class LanguagesWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ LanguagesWidget();
+
+private:
+ QLocale currentLocale;
+
+ QLabel *languagesLabel;
+ QListWidget *languagesList;
+
+private slots:
+ void localeChanged(QLocale locale);
+};
+
+#endif
diff --git a/tests/manual/qlocale/qlocale.pro b/tests/manual/qlocale/qlocale.pro
index 66d527b..46eaa16 100644
--- a/tests/manual/qlocale/qlocale.pro
+++ b/tests/manual/qlocale/qlocale.pro
@@ -4,5 +4,5 @@ DEPENDPATH += .
INCLUDEPATH += .
# Input
-HEADERS += currency.h calendar.h window.h miscellaneous.h
-SOURCES += currency.cpp main.cpp calendar.cpp window.cpp miscellaneous.cpp
+HEADERS += currency.h calendar.h languages.h window.h miscellaneous.h
+SOURCES += currency.cpp main.cpp calendar.cpp languages.cpp window.cpp miscellaneous.cpp
diff --git a/tests/manual/qlocale/window.cpp b/tests/manual/qlocale/window.cpp
index caafcee..ebe5ea9 100644
--- a/tests/manual/qlocale/window.cpp
+++ b/tests/manual/qlocale/window.cpp
@@ -67,6 +67,8 @@ Window::Window()
connect(this, SIGNAL(localeChanged(QLocale)), calendar, SLOT(localeChanged(QLocale)));
currency = new CurrencyWidget;
connect(this, SIGNAL(localeChanged(QLocale)), currency, SLOT(localeChanged(QLocale)));
+ languages = new LanguagesWidget;
+ connect(this, SIGNAL(localeChanged(QLocale)), languages, SLOT(localeChanged(QLocale)));
miscellaneous = new MiscWidget;
connect(this, SIGNAL(localeChanged(QLocale)), miscellaneous, SLOT(localeChanged(QLocale)));
@@ -83,6 +85,7 @@ Window::Window()
tabWidget->addTab(calendar, "Calendar");
tabWidget->addTab(currency, "Currency");
+ tabWidget->addTab(languages, "Languages");
tabWidget->addTab(miscellaneous, "Misc");
localeCombo->setCurrentIndex(0);
systemLocaleChanged();
diff --git a/tests/manual/qlocale/window.h b/tests/manual/qlocale/window.h
index c9a5480..35719ae 100644
--- a/tests/manual/qlocale/window.h
+++ b/tests/manual/qlocale/window.h
@@ -45,6 +45,7 @@
#include "calendar.h"
#include "currency.h"
+#include "languages.h"
#include "miscellaneous.h"
class Window : public QWidget
@@ -58,6 +59,7 @@ public:
QTabWidget *tabWidget;
CalendarWidget *calendar;
CurrencyWidget *currency;
+ LanguagesWidget *languages;
MiscWidget *miscellaneous;
private: