summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique <henrique@sw.eng.br>2022-02-07 11:36:47 -0300
committerkali kaneko (leap communications) <kali@leap.se>2022-11-08 21:26:17 +0100
commitc915eee76b74d2d28e0115f02f8659c7a827c255 (patch)
tree3d8d183b128e41d76a86888f6b8662664f5d6f11
parentdbc9327fc55302cc21ad7daac8a56b7a743a811b (diff)
[i18n] add language selector in preferences menu
-rw-r--r--gui/components/Preferences.qml313
-rw-r--r--gui/main.cpp34
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.