diff --git a/.gitignore b/.gitignore index e89a2150b..5fb34c4c6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ compile_commands.json .cache/ .vscode/ kate.project.ctags.* +*.user diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ac5cb3ac4..7a02f9046 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -140,6 +140,7 @@ if(ANDROID) "edit-copy" "gtk-quit" "compass" + "computer" "network-connect" "list-remove-user" "org.kde.neochat" diff --git a/src/controller.cpp b/src/controller.cpp index d77ea32f9..7c4e0bbb5 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,8 @@ Controller::Controller(QObject *parent) Connection::setRoomType(); Connection::setUserType(); + setApplicationProxy(); + #ifndef Q_OS_ANDROID if (NeoChatConfig::self()->systemTray()) { m_trayIcon = new TrayIcon(this); @@ -784,3 +787,29 @@ void Controller::forceRefreshTextDocument(QQuickTextDocument *textDocument, QQui // HACK: Workaround bug QTBUG 93281 connect(textDocument->textDocument(), SIGNAL(imagesLoaded()), item, SLOT(updateWholeDocument())); } + +void Controller::setApplicationProxy() +{ + NeoChatConfig *cfg = NeoChatConfig::self(); + QNetworkProxy proxy; + + // type match to ProxyType from neochatconfig.kcfg + switch (cfg->proxyType()) { + case 1: // HTTP + proxy.setType(QNetworkProxy::HttpProxy); + proxy.setHostName(cfg->proxyHost()); + proxy.setPort(cfg->proxyPort()); + break; + case 2: // SOCKS 5 + proxy.setType(QNetworkProxy::Socks5Proxy); + proxy.setHostName(cfg->proxyHost()); + proxy.setPort(cfg->proxyPort()); + break; + case 0: // System Default + default: + // do nothing + break; + } + + QNetworkProxy::setApplicationProxy(proxy); +} diff --git a/src/controller.h b/src/controller.h index c3069f2aa..9364788fe 100644 --- a/src/controller.h +++ b/src/controller.h @@ -99,6 +99,8 @@ public: Q_INVOKABLE void forceRefreshTextDocument(QQuickTextDocument *textDocument, QQuickItem *item); + Q_INVOKABLE void setApplicationProxy(); + private: explicit Controller(QObject *parent = nullptr); diff --git a/src/neochatconfig.kcfg b/src/neochatconfig.kcfg index 4c7e923eb..3743e3cc9 100644 --- a/src/neochatconfig.kcfg +++ b/src/neochatconfig.kcfg @@ -98,5 +98,30 @@ true + + + + + + + + + + + + + + System + + + + + 127.0.0.1 + + + + 1080 + + diff --git a/src/qml/Settings/NetworkProxyPage.qml b/src/qml/Settings/NetworkProxyPage.qml new file mode 100644 index 000000000..dd9169b11 --- /dev/null +++ b/src/qml/Settings/NetworkProxyPage.qml @@ -0,0 +1,97 @@ +// SPDX-FileCopyrightText: 2022 Gary Wang +// SPDX-License-Identifier: GPL-2.0-or-later OR LicenseRef-KDE-Accepted-LGPL + +import QtQuick 2.15 +import QtQuick.Controls 2.15 as QQC2 +import QtQuick.Layouts 1.15 + +import org.kde.kirigami 2.15 as Kirigami + +import org.kde.neochat 1.0 + +Kirigami.ScrollablePage { + title: i18nc("@title:window", "General") + property int currentType + property bool proxyConfigChanged: false + + ColumnLayout { + Kirigami.FormLayout { + Layout.fillWidth: true + + QQC2.RadioButton { + Kirigami.FormData.label: i18n("Network Proxy") + text: i18n("System Default") + checked: currentType === 0 + enabled: !Config.isProxyTypeImmutable + onToggled: { + currentType = 0 + } + } + QQC2.RadioButton { + text: i18n("HTTP") + checked: currentType === 1 + enabled: !Config.isProxyTypeImmutable + onToggled: { + currentType = 1 + } + } + QQC2.RadioButton { + text: i18n("Socks5") + checked: currentType === 2 + enabled: !Config.isProxyTypeImmutable + onToggled: { + currentType = 2 + } + } + QQC2.TextField { + id: hostField + Kirigami.FormData.label: i18n("Proxy Host") + text: Config.proxyHost + inputMethodHints: Qt.ImhUrlCharactersOnly + onEditingFinished: { + proxyConfigChanged = true + } + } + QQC2.SpinBox { + id: portField + Kirigami.FormData.label: i18n("Proxy Port") + value: Config.proxyPort + from: 0 + to: 65536 + validator: IntValidator {bottom: from; top: to} + textFromValue: function(value, locale) { + return value // it will add a thousands separator if we don't do this, not sure why + } + onValueChanged: { + proxyConfigChanged = true + } + } + } + } + + footer: QQC2.ToolBar { + height: visible ? implicitHeight : 0 + contentItem: RowLayout { + Item { + Layout.fillWidth: true + } + + QQC2.Button { + text: i18n("Apply") + enabled: currentType !== Config.proxyType || proxyConfigChanged + onClicked: { + Config.proxyType = currentType + Config.proxyHost = hostField.text + Config.proxyPort = portField.value + Config.save() + proxyConfigChanged = false + Controller.setApplicationProxy() + } + } + } + } + + Component.onCompleted: { + currentType = Config.proxyType + } +} diff --git a/src/qml/Settings/SettingsPage.qml b/src/qml/Settings/SettingsPage.qml index 0313d2c31..9a97d8ae3 100644 --- a/src/qml/Settings/SettingsPage.qml +++ b/src/qml/Settings/SettingsPage.qml @@ -34,8 +34,13 @@ Kirigami.CategorizedSettings { page: Qt.resolvedUrl("SonnetConfigPage.qml") }, Kirigami.SettingAction { - text: i18n("Devices") + text: i18n("Network Proxy") iconName: "network-connect" + page: Qt.resolvedUrl("NetworkProxyPage.qml") + }, + Kirigami.SettingAction { + text: i18n("Devices") + iconName: "computer" page: Qt.resolvedUrl("DevicesPage.qml") }, Kirigami.SettingAction { diff --git a/src/res.qrc b/src/res.qrc index f57e4a56a..c43f5b415 100644 --- a/src/res.qrc +++ b/src/res.qrc @@ -83,5 +83,6 @@ qml/Settings/DevicesPage.qml qml/Settings/About.qml qml/Settings/SonnetConfigPage.qml + qml/Settings/NetworkProxyPage.qml