diff options
author | Henrique <henrique@sw.eng.br> | 2022-02-07 11:36:47 -0300 |
---|---|---|
committer | kali kaneko (leap communications) <kali@leap.se> | 2022-11-08 21:26:17 +0100 |
commit | c915eee76b74d2d28e0115f02f8659c7a827c255 (patch) | |
tree | 3d8d183b128e41d76a86888f6b8662664f5d6f11 | |
parent | dbc9327fc55302cc21ad7daac8a56b7a743a811b (diff) |
[i18n] add language selector in preferences menu
-rw-r--r-- | gui/components/Preferences.qml | 313 | ||||
-rw-r--r-- | gui/main.cpp | 34 |
2 files changed, 211 insertions, 136 deletions
diff --git a/gui/components/Preferences.qml b/gui/components/Preferences.qml index 4de2f95..225e35b 100644 --- a/gui/components/Preferences.qml +++ b/gui/components/Preferences.qml @@ -3,170 +3,213 @@ import QtQuick.Controls 2.2 import QtQuick.Layouts 1.14 import QtQuick.Controls.Material 2.1 import QtGraphicalEffects 1.0 +import Qt.labs.settings 1.0 import "../themes/themes.js" as Theme ThemedPage { title: qsTr("Preferences") - Rectangle { - anchors.horizontalCenter: parent.horizontalCenter - width: root.appWidth * 0.80 - // FIXME - just the needed height - height: getBoxHeight() - radius: 10 - color: "white" + Settings { + id: settings + property string locale: locale + } + ScrollView { + clip: true anchors { fill: parent - margins: 10 } - ColumnLayout { - id: prefCol + Rectangle { + implicitHeight: getBoxHeight() + 20 + implicitWidth: root.appWidth width: root.appWidth * 0.80 + // FIXME - just the needed height + height: getBoxHeight() + radius: 10 + color: "white" - Rectangle { - id: turnOffWarning - visible: false - height: 20 - width: parent.width - color: "white" - - Label { - color: "red" - text: qsTr("Turn off the VPN to make changes") - width: prefCol.width - } - Layout.topMargin: 10 - Layout.leftMargin: 10 - Layout.rightMargin: 10 + anchors { + // fill: parent + right: parent.right + left: parent.left + top: parent.top + margins: 10 } - Label { - id: circumLabel - text: qsTr("Censorship circumvention") - font.bold: true - Layout.topMargin: 10 - Layout.leftMargin: 10 - Layout.rightMargin: 10 - } + ColumnLayout { + id: prefCol + width: root.appWidth * 0.80 - Label { - text: qsTr("These techniques can bypass censorship, but are slower. Use them only when needed.") - color: Material.foreground - visible: true - wrapMode: Text.Wrap - font.pixelSize: Theme.fontSize - 3 - Layout.leftMargin: 10 - Layout.rightMargin: 10 - Layout.preferredWidth: 240 - } + Rectangle { + id: turnOffWarning + visible: false + height: 20 + width: parent.width + color: "white" - MaterialCheckBox { - id: useBridgesCheckBox - enabled: areBridgesAvailable() - checked: false - text: qsTr("Use obfs4 bridges") - // TODO refactor - this sets wrapMode on checkbox - contentItem: Label { - text: useBridgesCheckBox.text - font: useBridgesCheckBox.font - horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignVCenter - leftPadding: useBridgesCheckBox.indicator.width + useBridgesCheckBox.spacing - wrapMode: Label.Wrap + Label { + color: "red" + text: qsTr("Turn off the VPN to make changes") + width: prefCol.width + } + Layout.topMargin: 10 + Layout.leftMargin: 10 + Layout.rightMargin: 10 } - Layout.leftMargin: 10 - Layout.rightMargin: 10 - HoverHandler { - cursorShape: Qt.PointingHandCursor + + Label { + id: languageLabel + text: qsTr("Language") + font.bold: true + Layout.topMargin: 10 + Layout.leftMargin: 10 + Layout.rightMargin: 10 } - onClicked: { - // TODO there's a corner case that needs to be dealt with in the backend, - // if an user has a manual location selected and switches to bridges: - // we need to fallback to "auto" selection if such location does not - // offer bridges - useBridges(checked) - useUDP.enabled = !checked + + ComboBox { + id: languageComboBox + Layout.leftMargin: 10 + Layout.rightMargin: 10 + Layout.preferredWidth: 240 + model: locales + textRole: 'name' + valueRole: 'locale' + + Component.onCompleted: { + currentIndex = indexOfValue(settings.locale) + } + onActivated: { + backend.setLocale(currentValue) + } } - } - Label { - text: qsTr("Traffic is obfuscated to bypass blocks") - color: useBridgesCheckBox.enabled ? Material.foreground : Material.hintTextColor - visible: true - wrapMode: Text.Wrap - font.pixelSize: Theme.fontSize - 5 - Layout.leftMargin: 36 - Layout.rightMargin: 15 - Layout.bottomMargin: 5 - Layout.topMargin: -5 - Layout.preferredWidth: 220 - } + Label { + id: circumLabel + text: qsTr("Censorship circumvention") + font.bold: true + Layout.topMargin: 10 + Layout.leftMargin: 10 + Layout.rightMargin: 10 + } - MaterialCheckBox { - id: useSnowflake - text: qsTr("Use Snowflake") - enabled: false - checked: false - HoverHandler { - cursorShape: Qt.PointingHandCursor + Label { + text: qsTr("These techniques can bypass censorship, but are slower. Use them only when needed.") + color: Material.foreground + visible: true + wrapMode: Text.Wrap + font.pixelSize: Theme.fontSize - 3 + Layout.leftMargin: 10 + Layout.rightMargin: 10 + Layout.preferredWidth: 240 } - Layout.leftMargin: 10 - Layout.rightMargin: 10 - Layout.preferredWidth: 240 - onClicked: { - doUseSnowflake(checked) + + MaterialCheckBox { + id: useBridgesCheckBox + enabled: areBridgesAvailable() + checked: false + text: qsTr("Use obfs4 bridges") + // TODO refactor - this sets wrapMode on checkbox + contentItem: Label { + text: useBridgesCheckBox.text + font: useBridgesCheckBox.font + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + leftPadding: useBridgesCheckBox.indicator.width + useBridgesCheckBox.spacing + wrapMode: Label.Wrap + } + Layout.leftMargin: 10 + Layout.rightMargin: 10 + HoverHandler { + cursorShape: Qt.PointingHandCursor + } + onClicked: { + // TODO there's a corner case that needs to be dealt with in the backend, + // if an user has a manual location selected and switches to bridges: + // we need to fallback to "auto" selection if such location does not + // offer bridges + useBridges(checked) + useUDP.enabled = !checked + } } - } - Label { - text: qsTr("Snowflake needs Tor installed in your system") - color: useSnowflake.enabled ? Material.foreground : Material.hintTextColor - visible: true - wrapMode: Text.Wrap - font.pixelSize: Theme.fontSize - 5 - Layout.leftMargin: 36 - Layout.rightMargin: 15 - Layout.bottomMargin: 5 - Layout.topMargin: -5 - Layout.preferredWidth: 220 - } + Label { + text: qsTr("Traffic is obfuscated to bypass blocks") + color: useBridgesCheckBox.enabled ? Material.foreground : Material.hintTextColor + visible: true + wrapMode: Text.Wrap + font.pixelSize: Theme.fontSize - 5 + Layout.leftMargin: 36 + Layout.rightMargin: 15 + Layout.bottomMargin: 5 + Layout.topMargin: -5 + Layout.preferredWidth: 220 + } - Label { - text: qsTr("Transport") - font.bold: true - Layout.leftMargin: 10 - Layout.rightMargin: 10 - Layout.topMargin: 8 - } + MaterialCheckBox { + id: useSnowflake + text: qsTr("Use Snowflake") + enabled: false + checked: false + HoverHandler { + cursorShape: Qt.PointingHandCursor + } + Layout.leftMargin: 10 + Layout.rightMargin: 10 + Layout.preferredWidth: 240 + onClicked: { + doUseSnowflake(checked) + } + } - Label { - text: qsTr("UDP can make the VPN faster. It might be blocked on some networks.") - width: parent.width - color: Material.foreground - visible: true - wrapMode: Text.Wrap - font.pixelSize: Theme.fontSize - 3 - Layout.leftMargin: 10 - Layout.rightMargin: 10 - Layout.preferredWidth: 240 - } + Label { + text: qsTr("Snowflake needs Tor installed in your system") + color: useSnowflake.enabled ? Material.foreground : Material.hintTextColor + visible: true + wrapMode: Text.Wrap + font.pixelSize: Theme.fontSize - 5 + Layout.leftMargin: 36 + Layout.rightMargin: 15 + Layout.bottomMargin: 5 + Layout.topMargin: -5 + Layout.preferredWidth: 220 + } - MaterialCheckBox { - id: useUDP - text: qsTr("Use UDP if available") - enabled: false - checked: false - Layout.leftMargin: 10 - Layout.rightMargin: 10 - HoverHandler { - cursorShape: Qt.PointingHandCursor + Label { + text: qsTr("Transport") + font.bold: true + Layout.leftMargin: 10 + Layout.rightMargin: 10 + Layout.topMargin: 8 } - onClicked: { - doUseUDP(checked) - useBridgesCheckBox.enabled = areBridgesAvailable() + + Label { + text: qsTr("UDP can make the VPN faster. It might be blocked on some networks.") + width: parent.width + color: Material.foreground + visible: true + wrapMode: Text.Wrap + font.pixelSize: Theme.fontSize - 3 + Layout.leftMargin: 10 + Layout.rightMargin: 10 + Layout.preferredWidth: 240 + } + + MaterialCheckBox { + id: useUDP + text: qsTr("Use UDP if available") + enabled: false + checked: false + Layout.leftMargin: 10 + Layout.rightMargin: 10 + HoverHandler { + cursorShape: Qt.PointingHandCursor + } + onClicked: { + doUseUDP(checked) + useBridgesCheckBox.enabled = areBridgesAvailable() + } } } } diff --git a/gui/main.cpp b/gui/main.cpp index affbabd..3436a86 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -43,7 +43,38 @@ QString getProviderConfig(QJsonValue info, QString provider, QString key, QStrin return item[key].toString(); } } - return "BitmaskVPN"; + return defaultValue; +} + +QList<QVariant> getAvailableLocales() { + QString localePath = ":/i18n"; + QDir dir(localePath); + QStringList fileNames = dir.entryList(QStringList("*.qm")); + + QList<QVariant> locales; + for (int i = 0; i < fileNames.size(); ++i) { + // get locale extracted by filename + QString localeName; + localeName = fileNames[i]; // "de.qm" + localeName.truncate(localeName.lastIndexOf('.')); // "de" + + if (localeName == "base") { + localeName = "en"; + } else { + // remove main_ prefix + localeName = localeName.mid(5); + } + + + QLocale locale = QLocale(localeName); + QString name = QLocale::languageToString(locale.language()); + QVariantMap localeObject; + localeObject.insert("locale", localeName); + localeObject.insert("name", name); + locales.push_back(localeObject); + } + + return locales; } auto handler = [](int sig) -> void { @@ -238,6 +269,7 @@ int main(int argc, char **argv) { ctx->setContextProperty("systrayVisible", !hideSystray); ctx->setContextProperty("systrayAvailable", availableSystray); ctx->setContextProperty("qmlDebug", debug == "1"); + ctx->setContextProperty("locales", getAvailableLocales()); //XXX we're doing configuration via config file, but this is a mechanism //to change to Dark Theme if desktop has it. |