Skip to content
Snippets Groups Projects
Commit 68a5837a authored by Sébastien Blin's avatar Sébastien Blin
Browse files

settings: add a settings to change the language of the app

Move installTranslator into the settings manager and add a settings
in the SystemSettings to be able to dynamically change the language
of jami-qt.

jami-project#1342

Change-Id: I4f720fa50d5e313356dbdf1b8acb4e98d74401e4
parent 4f6d70d6
No related branches found
No related tags found
No related merge requests found
......@@ -20,6 +20,11 @@
#include "appsettingsmanager.h"
#include <QCoreApplication>
#include <QLibraryInfo>
#include <locale.h>
const QString defaultDownloadPath = QStandardPaths::writableLocation(
QStandardPaths::DownloadLocation);
......@@ -51,3 +56,73 @@ AppSettingsManager::setValue(const Settings::Key key, const QVariant& value)
{
settings_->setValue(Settings::toString(key), value);
}
void
AppSettingsManager::loadTranslations()
{
#if defined(Q_OS_LINUX) && defined(JAMI_INSTALL_PREFIX)
QString appDir = JAMI_INSTALL_PREFIX;
#else
QString appDir = qApp->applicationDirPath() + QDir::separator() + "share";
#endif
// Remove previously installed translators
for (auto* tr : installedTr_)
qApp->removeTranslator(tr);
installedTr_.clear();
auto pref = getValue(Settings::Key::LANG).toString();
QString locale_name = pref == "SYSTEM" ? QLocale::system().name() : pref;
qDebug() << QString("Using locale: %1").arg(locale_name);
QString locale_lang = locale_name.split('_')[0];
QTranslator* qtTranslator_lang = new QTranslator(qApp);
QTranslator* qtTranslator_name = new QTranslator(qApp);
if (locale_name != locale_lang) {
if (qtTranslator_lang->load("qt_" + locale_lang,
QLibraryInfo::path(QLibraryInfo::TranslationsPath)))
qApp->installTranslator(qtTranslator_lang);
installedTr_.append(qtTranslator_lang);
}
if (qtTranslator_name->load("qt_" + locale_name,
QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
qApp->installTranslator(qtTranslator_name);
installedTr_.append(qtTranslator_name);
}
QTranslator* lrcTranslator_lang = new QTranslator(qApp);
QTranslator* lrcTranslator_name = new QTranslator(qApp);
if (locale_name != locale_lang) {
if (lrcTranslator_lang->load(appDir + QDir::separator() + "libringclient" + QDir::separator()
+ "translations" + QDir::separator() + "lrc_" + locale_lang)) {
qApp->installTranslator(lrcTranslator_lang);
installedTr_.append(lrcTranslator_lang);
}
}
if (lrcTranslator_name->load(appDir + QDir::separator() + "libringclient" + QDir::separator()
+ "translations" + QDir::separator() + "lrc_" + locale_name)) {
qApp->installTranslator(lrcTranslator_name);
installedTr_.append(lrcTranslator_name);
}
QTranslator* mainTranslator_lang = new QTranslator(qApp);
QTranslator* mainTranslator_name = new QTranslator(qApp);
if (locale_name != locale_lang) {
if (mainTranslator_lang->load(appDir + QDir::separator() + "ring" + QDir::separator()
+ "translations" + QDir::separator() + "ring_client_windows_"
+ locale_lang)) {
qApp->installTranslator(mainTranslator_lang);
installedTr_.append(mainTranslator_lang);
}
}
if (mainTranslator_name->load(appDir + QDir::separator() + "ring" + QDir::separator()
+ "translations" + QDir::separator() + "ring_client_windows_"
+ locale_name)) {
qApp->installTranslator(mainTranslator_name);
installedTr_.append(mainTranslator_name);
}
Q_EMIT retranslate();
}
\ No newline at end of file
......@@ -28,6 +28,8 @@
#include <QStandardPaths>
#include <QWindow> // for QWindow::AutomaticVisibility
#include <QTranslator>
extern const QString defaultDownloadPath;
// clang-format off
......@@ -47,7 +49,8 @@ extern const QString defaultDownloadPath;
X(ShowChatviewHorizontally, true) \
X(NeverShowMeAgain, false) \
X(WindowGeometry, QRectF(qQNaN(), qQNaN(), 0., 0.)) \
X(WindowState, QWindow::AutomaticVisibility)
X(WindowState, QWindow::AutomaticVisibility) \
X(LANG, "SYSTEM")
/*
* A class to expose settings keys in both c++ and QML.
......@@ -102,6 +105,12 @@ public:
Q_INVOKABLE QVariant getValue(const Settings::Key key);
Q_INVOKABLE void setValue(const Settings::Key key, const QVariant& value);
void loadTranslations();
Q_SIGNALS:
void retranslate();
private:
QSettings* settings_;
QVector<QTranslator*> installedTr_ {};
};
......@@ -376,6 +376,7 @@ Item {
property string enableTypingIndicator: qsTr("Enable typing indicators")
property string displayHyperlinkPreviews: qsTr("Display hyperlink previews in the chatview")
property string chatviewPositionInCall: qsTr("Chatview's position in calls")
property string language: qsTr("User interface language")
property string bottomOpt: qsTr("Bottom")
property string rightOpt: qsTr("Right")
......
......@@ -148,6 +148,10 @@ MainApplication::MainApplication(int& argc, char** argv)
: QApplication(argc, argv)
{
QObject::connect(this, &QApplication::aboutToQuit, [this] { cleanup(); });
QObject::connect(settingsManager_.get(),
&AppSettingsManager::retranslate,
this,
&MainApplication::retranslate);
}
MainApplication::~MainApplication()
......@@ -181,7 +185,7 @@ MainApplication::init()
}
Utils::removeOldVersions();
loadTranslations();
settingsManager_->loadTranslations();
setApplicationFont();
#if defined _MSC_VER
......@@ -262,57 +266,9 @@ MainApplication::restoreApp()
}
void
MainApplication::loadTranslations()
MainApplication::retranslate()
{
#if defined(Q_OS_LINUX) && defined(JAMI_INSTALL_PREFIX)
QString appDir = JAMI_INSTALL_PREFIX;
#else
QString appDir = qApp->applicationDirPath() + QDir::separator() + "share";
#endif
QString locale_name = QLocale::system().name();
QString locale_lang = locale_name.split('_')[0];
QTranslator* qtTranslator_lang = new QTranslator(this);
QTranslator* qtTranslator_name = new QTranslator(this);
if (locale_name != locale_lang) {
if (qtTranslator_lang->load("qt_" + locale_lang,
QLibraryInfo::path(QLibraryInfo::TranslationsPath)))
installTranslator(qtTranslator_lang);
}
if (qtTranslator_name->load("qt_" + locale_name,
QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
installTranslator(qtTranslator_name);
}
QTranslator* lrcTranslator_lang = new QTranslator(this);
QTranslator* lrcTranslator_name = new QTranslator(this);
if (locale_name != locale_lang) {
if (lrcTranslator_lang->load(appDir + QDir::separator() + "libringclient" + QDir::separator()
+ "translations" + QDir::separator() + "lrc_" + locale_lang)) {
installTranslator(lrcTranslator_lang);
}
}
if (lrcTranslator_name->load(appDir + QDir::separator() + "libringclient" + QDir::separator()
+ "translations" + QDir::separator() + "lrc_" + locale_name)) {
installTranslator(lrcTranslator_name);
}
QTranslator* mainTranslator_lang = new QTranslator(this);
QTranslator* mainTranslator_name = new QTranslator(this);
if (locale_name != locale_lang) {
if (mainTranslator_lang->load(appDir + QDir::separator() + "ring" + QDir::separator()
+ "translations" + QDir::separator() + "ring_client_windows_"
+ locale_lang)) {
installTranslator(mainTranslator_lang);
}
}
if (mainTranslator_name->load(appDir + QDir::separator() + "ring" + QDir::separator()
+ "translations" + QDir::separator() + "ring_client_windows_"
+ locale_name)) {
installTranslator(mainTranslator_name);
}
engine_->retranslate();
}
void
......
......@@ -72,7 +72,6 @@ private:
void vsConsoleDebug();
void fileDebug(QFile* debugFile);
void loadTranslations();
void initLrc(const QString& downloadUrl, ConnectivityMonitor* cm, bool logDaemon);
const QVariantMap parseArguments();
void setApplicationFont();
......@@ -80,6 +79,9 @@ private:
void initSystray();
void cleanup();
public Q_SLOTS:
void retranslate();
private:
QScopedPointer<QFile> debugFile_;
QScopedPointer<QQmlApplicationEngine> engine_;
......
......@@ -160,4 +160,33 @@ ColumnLayout {
onClicked: downloadPathDialog.open()
}
}
SettingsComboBox {
id: langComboBoxSetting
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.leftMargin: JamiTheme.preferredMarginSize
labelText: JamiStrings.language
fontPointSize: JamiTheme.settingsFontSize
comboModel: ListModel {
Component.onCompleted: {
var supported = UtilsAdapter.supportedLang();
var keys = Object.keys(supported);
var currentKey = UtilsAdapter.getAppValue(Settings.Key.LANG);
for (var i = 0 ; i < keys.length ; ++i) {
append({ textDisplay: supported[keys[i]], id: keys[i] })
if (keys[i] == currentKey)
langComboBoxSetting.modelIndex = i
}
}
}
widthOfComboBox: itemWidth
role: "textDisplay"
onActivated: {
UtilsAdapter.setAppValue(Settings.Key.LANG, comboModel.get(modelIndex).id)
}
}
}
......@@ -33,6 +33,7 @@
#include <QApplication>
#include <QClipboard>
#include <QFileInfo>
#include <QRegExp>
UtilsAdapter::UtilsAdapter(AppSettingsManager* settingsManager,
SystemTray* systemTray,
......@@ -338,6 +339,9 @@ void
UtilsAdapter::setAppValue(const Settings::Key key, const QVariant& value)
{
settingsManager_->setValue(key, value);
// If we change the lang preference, reload the translations
if (key == Settings::Key::LANG)
settingsManager_->loadTranslations();
}
QString
......@@ -411,6 +415,39 @@ UtilsAdapter::clearInteractionsCache(const QString& accountId, const QString& co
auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
auto& convModel = accInfo.conversationModel;
convModel->clearInteractionsCache(convId);
} catch (...) {}
} catch (...) {
}
}
}
QVariantMap
UtilsAdapter::supportedLang()
{
#if defined(Q_OS_LINUX) && defined(JAMI_INSTALL_PREFIX)
QString appDir = JAMI_INSTALL_PREFIX;
#else
QString appDir = qApp->applicationDirPath() + QDir::separator() + "share";
#endif
auto trDir = QDir(appDir + QDir::separator() + "ring" + QDir::separator() + "translations");
QStringList trFiles = trDir.entryList(QStringList() << "ring_client_windows_*.qm", QDir::Files);
QVariantMap result;
result["SYSTEM"] = tr("System");
// Get available locales
QRegExp regex("ring_client_windows_(.*).qm");
QSet<QString> nativeNames;
for (const auto& f : trFiles) {
auto match = regex.indexIn(f);
if (regex.capturedTexts().size() == 2) {
const auto& l = regex.capturedTexts()[1];
auto nativeName = QLocale(l).nativeLanguageName();
if (nativeName.isEmpty()) // If a locale doesn't have any nativeLanguageName, ignore it.
continue;
// Avoid to show potential duplicates.
if (!nativeNames.contains(nativeName)) {
result[l] = nativeName;
nativeNames.insert(nativeName);
}
}
}
return result;
}
......@@ -90,6 +90,7 @@ public:
Q_INVOKABLE void setDownloadPath(QString dir);
Q_INVOKABLE void monitor(const bool& continuous);
Q_INVOKABLE void clearInteractionsCache(const QString& accountId, const QString& convUid);
Q_INVOKABLE QVariantMap supportedLang();
Q_SIGNALS:
void debugMessageReceived(const QString& message);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment