From d9b9dd8cc1dc21a19a14f573c02831d6d3db6c04 Mon Sep 17 00:00:00 2001 From: "Leroy.H.Y" Date: Sun, 24 Nov 2019 20:35:43 +0800 Subject: [PATCH] [update] updated prefrence window UI and changed a config file entry Former-commit-id: 6b0d8e1c1405141e637459ffc11acd59c3bcf95b --- 3rdparty/qzxing_noTests | 2 +- 3rdparty/x2struct | 2 +- Build.Counter | 2 +- Qv2ray.pro | 1 + src/Qv2rayBase.hpp | 12 +- src/QvConfigUpgrade.cpp | 16 +- src/QvCoreConfigOperations_Generation.cpp | 24 +- src/QvCoreInteractions.cpp | 26 +- src/QvCoreInteractions.hpp | 6 +- src/QvUtils.cpp | 4 +- src/main.cpp | 2 +- src/ui/w_ImportConfig.cpp | 2 +- src/ui/w_MainWindow.cpp | 66 +-- src/ui/w_MainWindow.hpp | 2 +- src/ui/w_PrefrencesWindow.cpp | 172 ++++---- src/ui/w_PrefrencesWindow.hpp | 6 +- src/ui/w_PrefrencesWindow.ui | 465 ++++++++++---------- src/ui/w_RoutesEditor.cpp | 6 +- translations/en-US.ts | 503 ++++++++++++---------- 19 files changed, 712 insertions(+), 607 deletions(-) diff --git a/3rdparty/qzxing_noTests b/3rdparty/qzxing_noTests index 812fd390..c29307b6 160000 --- a/3rdparty/qzxing_noTests +++ b/3rdparty/qzxing_noTests @@ -1 +1 @@ -Subproject commit 812fd390ef9d6167555b364120773c9a9fe91023 +Subproject commit c29307b6124e012ba1287ba0906e8807424e45c2 diff --git a/3rdparty/x2struct b/3rdparty/x2struct index 61abc0a4..f2200a5f 160000 --- a/3rdparty/x2struct +++ b/3rdparty/x2struct @@ -1 +1 @@ -Subproject commit 61abc0a4df4b5b3d730b926231b05593560369c2 +Subproject commit f2200a5f662730f2c5e49bccb680edbd533f1ff8 diff --git a/Build.Counter b/Build.Counter index 3bee760d..4ab4c5d7 100644 --- a/Build.Counter +++ b/Build.Counter @@ -1 +1 @@ -742 +791 diff --git a/Qv2ray.pro b/Qv2ray.pro index 8c364579..b9c2b346 100644 --- a/Qv2ray.pro +++ b/Qv2ray.pro @@ -58,6 +58,7 @@ INCLUDEPATH += \ src/ui/ \ src/utils/ \ libs/gen/ + HEADERS += \ src/Qv2rayBase.hpp \ src/QvCoreConfigObjects.hpp \ diff --git a/src/Qv2rayBase.hpp b/src/Qv2rayBase.hpp index 0abda73d..4d1ac4b8 100644 --- a/src/Qv2rayBase.hpp +++ b/src/Qv2rayBase.hpp @@ -8,7 +8,7 @@ #include "QvCoreConfigObjects.hpp" #include "QObjectMessageProxy.hpp" -#define QV2RAY_CONFIG_VERSION 9 +#define QV2RAY_CONFIG_VERSION 11 // Linux DEs should handle the ui schemes themselves. // --> Or.. should we change this into a modifyable setting? @@ -138,7 +138,7 @@ namespace Qv2ray socksLocalIP = "0.0.0.0"; socksUDP = true; } - XTOSTRUCT(O(listenip, socks_port, socks_useAuth, socksAccount, socksUDP, socksLocalIP, http_port, http_useAuth, httpAccount)) + XTOSTRUCT(O(pacConfig, listenip, socks_port, socks_useAuth, socksAccount, socksUDP, socksLocalIP, http_port, http_useAuth, httpAccount)) }; struct Qv2rayUIConfig { @@ -173,7 +173,7 @@ namespace Qv2ray map subscribes; // Qv2rayUIConfig uiConfig; - Qv2rayInboundsConfig inBoundSettings; + Qv2rayInboundsConfig inboundConfig; Qv2rayToolBarConfig toolBarConfig; Qv2rayConfig(): @@ -193,7 +193,7 @@ namespace Qv2ray configs(), subscribes(), uiConfig(), - inBoundSettings(), + inboundConfig(), toolBarConfig() { } Qv2rayConfig(const string &assetsPath, int log, const Qv2rayInboundsConfig &_inBoundSettings): Qv2rayConfig() { @@ -201,7 +201,7 @@ namespace Qv2ray ignoredVersion = ""; autoStartConfig = ""; v2AssetsPath = assetsPath; - inBoundSettings = _inBoundSettings; + inboundConfig = _inBoundSettings; logLevel = log; tProxySupport = false; dnsList.push_back("8.8.8.8"); @@ -227,7 +227,7 @@ namespace Qv2ray bypassCN, withLocalDNS, dnsList, - inBoundSettings, + inboundConfig, configs, subscribes, toolBarConfig)) diff --git a/src/QvConfigUpgrade.cpp b/src/QvConfigUpgrade.cpp index 81eee249..768cfdcf 100644 --- a/src/QvConfigUpgrade.cpp +++ b/src/QvConfigUpgrade.cpp @@ -90,10 +90,24 @@ namespace Qv2ray auto lang = root["language"].toString(); QJsonObject uiSettings; uiSettings["language"] = lang; - root["UISettings"] = uiSettings; + root["uiConfig"] = uiSettings; UPDATELOG("Reconstructing config file.") break; } + + case 9: { + root["uiConfig"] = root["UISettings"]; + root.remove("UISettings"); + UPDATELOG("Renamed UISettings to uiConfig.") + break; + } + + case 10: { + root["inboundConfig"] = root["inBoundSettings"]; + root.remove("inBoundSettings"); + UPDATELOG("Renamed inBoundSettings to inboundConfig.") + break; + } } root["config_version"] = root["config_version"].toInt() + 1; diff --git a/src/QvCoreConfigOperations_Generation.cpp b/src/QvCoreConfigOperations_Generation.cpp index 07ef7da5..92a06b3f 100644 --- a/src/QvCoreConfigOperations_Generation.cpp +++ b/src/QvCoreConfigOperations_Generation.cpp @@ -195,15 +195,15 @@ namespace Qv2ray QJsonArray inboundsList; // HTTP InBound - if (gConf.inBoundSettings.http_port != 0) { + if (gConf.inboundConfig.http_port != 0) { QJsonObject httpInBoundObject; - httpInBoundObject.insert("listen", QString::fromStdString(gConf.inBoundSettings.listenip)); - httpInBoundObject.insert("port", gConf.inBoundSettings.http_port); + httpInBoundObject.insert("listen", QString::fromStdString(gConf.inboundConfig.listenip)); + httpInBoundObject.insert("port", gConf.inboundConfig.http_port); httpInBoundObject.insert("protocol", "http"); httpInBoundObject.insert("tag", "http_IN"); - if (gConf.inBoundSettings.http_useAuth) { - auto httpInSettings = GenerateHTTPIN(QList() << gConf.inBoundSettings.httpAccount); + if (gConf.inboundConfig.http_useAuth) { + auto httpInSettings = GenerateHTTPIN(QList() << gConf.inboundConfig.httpAccount); httpInBoundObject.insert("settings", httpInSettings); } @@ -211,16 +211,16 @@ namespace Qv2ray } // SOCKS InBound - if (gConf.inBoundSettings.socks_port != 0) { + if (gConf.inboundConfig.socks_port != 0) { QJsonObject socksInBoundObject; - socksInBoundObject.insert("listen", QString::fromStdString(gConf.inBoundSettings.listenip)); - socksInBoundObject.insert("port", gConf.inBoundSettings.socks_port); + socksInBoundObject.insert("listen", QString::fromStdString(gConf.inboundConfig.listenip)); + socksInBoundObject.insert("port", gConf.inboundConfig.socks_port); socksInBoundObject.insert("protocol", "socks"); socksInBoundObject.insert("tag", "socks_IN"); - auto socksInSettings = GenerateSocksIN(gConf.inBoundSettings.socks_useAuth ? "password" : "noauth", - QList() << gConf.inBoundSettings.socksAccount, - gConf.inBoundSettings.socksUDP, - QSTRING(gConf.inBoundSettings.socksLocalIP)); + auto socksInSettings = GenerateSocksIN(gConf.inboundConfig.socks_useAuth ? "password" : "noauth", + QList() << gConf.inboundConfig.socksAccount, + gConf.inboundConfig.socksUDP, + QSTRING(gConf.inboundConfig.socksLocalIP)); socksInBoundObject.insert("settings", socksInSettings); inboundsList.append(socksInBoundObject); } diff --git a/src/QvCoreInteractions.cpp b/src/QvCoreInteractions.cpp index 065cfcea..9d185b46 100644 --- a/src/QvCoreInteractions.cpp +++ b/src/QvCoreInteractions.cpp @@ -11,7 +11,7 @@ namespace Qv2ray { namespace QvInteration { - bool Qv2Instance::ValidateConfig(const QString *path) + bool ConnectionInstance::ValidateConfig(const QString *path) { if (ValidateKernal()) { QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); @@ -38,7 +38,7 @@ namespace Qv2ray return false; } - Qv2Instance::Qv2Instance(QWidget *parent) + ConnectionInstance::ConnectionInstance(QWidget *parent) { auto proc = new QProcess(); vProcess = proc; @@ -46,7 +46,7 @@ namespace Qv2ray VCoreStatus = STOPPED; } - void Qv2Instance::SetAPIPort(int port) + void ConnectionInstance::SetAPIPort(int port) { // Config API this->port = port; @@ -55,12 +55,12 @@ namespace Qv2ray Stub = service.NewStub(Channel); } - QString Qv2Instance::ReadProcessOutput() + QString ConnectionInstance::ReadProcessOutput() { return vProcess->readAllStandardOutput(); } - bool Qv2Instance::ValidateKernal() + bool ConnectionInstance::ValidateKernal() { if (!QFile::exists(QSTRING(GetGlobalConfig().v2CorePath))) { Utils::QvMessageBox(nullptr, QObject::tr("Cannot start v2ray"), @@ -72,7 +72,7 @@ namespace Qv2ray } else return true; } - bool Qv2Instance::StartVCore() + bool ConnectionInstance::StartVCore() { if (VCoreStatus != STOPPED) { return false; @@ -101,7 +101,7 @@ namespace Qv2ray } } - void Qv2Instance::StopVCore() + void ConnectionInstance::StopVCore() { vProcess->close(); totalDataTransfered = QMap(); @@ -109,13 +109,13 @@ namespace Qv2ray VCoreStatus = STOPPED; } - Qv2Instance::~Qv2Instance() + ConnectionInstance::~ConnectionInstance() { StopVCore(); delete vProcess; } - long Qv2Instance::CallStatsAPIByName(QString name) + long ConnectionInstance::CallStatsAPIByName(QString name) { GetStatsRequest request; request.set_name(name.toStdString()); @@ -131,7 +131,7 @@ namespace Qv2ray return response.stat().value(); } - long Qv2Instance::getTagLastUplink(QString tag) + long ConnectionInstance::getTagLastUplink(QString tag) { auto val = CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>uplink"); auto data = val - totalDataTransfered[tag + "_up"]; @@ -140,7 +140,7 @@ namespace Qv2ray return data; } - long Qv2Instance::getTagLastDownlink(QString tag) + long ConnectionInstance::getTagLastDownlink(QString tag) { auto val = CallStatsAPIByName("inbound>>>" + tag + ">>>traffic>>>downlink"); auto data = val - totalDataTransfered[tag + "_down"]; @@ -149,12 +149,12 @@ namespace Qv2ray return data; } - long Qv2Instance::getTagTotalUplink(QString tag) + long ConnectionInstance::getTagTotalUplink(QString tag) { return totalDataTransfered[tag + "_up"]; } - long Qv2Instance::getTagTotalDownlink(QString tag) + long ConnectionInstance::getTagTotalDownlink(QString tag) { return totalDataTransfered[tag + "_down"]; } diff --git a/src/QvCoreInteractions.hpp b/src/QvCoreInteractions.hpp index 94163954..0da315a3 100644 --- a/src/QvCoreInteractions.hpp +++ b/src/QvCoreInteractions.hpp @@ -24,10 +24,10 @@ namespace Qv2ray STARTED }; - class Qv2Instance + class ConnectionInstance { public: - explicit Qv2Instance(QWidget *parent = nullptr); + explicit ConnectionInstance(QWidget *parent = nullptr); void SetAPIPort(int port); long getTagTotalDownlink(QString tag); long getTagTotalUplink(QString tag); @@ -40,7 +40,7 @@ namespace Qv2ray static bool ValidateKernal(); QString ReadProcessOutput(); - ~Qv2Instance(); + ~ConnectionInstance(); QMap totalDataTransfered; QMap dataTransferSpeed; private: diff --git a/src/QvUtils.cpp b/src/QvUtils.cpp index 15df8809..117a34ae 100644 --- a/src/QvUtils.cpp +++ b/src/QvUtils.cpp @@ -21,8 +21,8 @@ namespace Qv2ray QString randomString; for (int i = 0; i < len; ++i) { - int index = static_cast(QRandomGenerator::system()->generate() % static_cast(possibleCharacters.length())); - QChar nextChar = possibleCharacters.at(index); + int index = static_cast(QRandomGenerator::system()->generate()) % possibleCharacters.length(); + QChar nextChar = possibleCharacters[index]; randomString.append(nextChar); } diff --git a/src/main.cpp b/src/main.cpp index ea82a5c0..12d83cb8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -256,7 +256,7 @@ int main(int argc, char *argv[]) #if QV2RAY_USE_BUILTIN_DARKTHEME LOG(MODULE_UI, "Using built-in theme.") - if (confObject.UISettings.useDarkTheme) { + if (confObject.uiConfig.useDarkTheme) { LOG(MODULE_UI, " --> Using built-in dark theme.") // From https://forum.qt.io/topic/101391/windows-10-dark-theme/4 _qApp.setStyle("Fusion"); diff --git a/src/ui/w_ImportConfig.cpp b/src/ui/w_ImportConfig.cpp index b90df9f1..06acb6a3 100644 --- a/src/ui/w_ImportConfig.cpp +++ b/src/ui/w_ImportConfig.cpp @@ -87,7 +87,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked() if (config.isEmpty()) { QvMessageBox(this, tr("Import config file"), tr("Import from file failed, for more information, please check the log file.")); return; - } else if (!Qv2Instance::ValidateConfig(&path)) { + } else if (!ConnectionInstance::ValidateConfig(&path)) { QvMessageBox(this, tr("Import config file"), tr("Failed to check the validity of the config file.")); return; } else { diff --git a/src/ui/w_MainWindow.cpp b/src/ui/w_MainWindow.cpp index 52e02678..1860d7e7 100644 --- a/src/ui/w_MainWindow.cpp +++ b/src/ui/w_MainWindow.cpp @@ -35,7 +35,7 @@ MainWindow::MainWindow(QWidget *parent) hTray(new QSystemTrayIcon(this)) { auto conf = GetGlobalConfig(); - vinstance = new Qv2Instance(this); + vinstance = new ConnectionInstance(this); setupUi(this); // this->setWindowIcon(QIcon(":/icons/qv2ray.png")); @@ -103,7 +103,6 @@ MainWindow::MainWindow(QWidget *parent) LoadConnections(); QObject::connect(&HTTPRequestHelper, &QvHttpRequestHelper::httpRequestFinished, this, &MainWindow::VersionUpdate); HTTPRequestHelper.get("https://api.github.com/repos/lhy0403/Qv2ray/releases/latest"); - bool hasAutoStart = false; // // For charts uploadSerie = new QSplineSeries(this); @@ -135,29 +134,27 @@ MainWindow::MainWindow(QWidget *parent) auto layout = new QHBoxLayout(speedChart); layout->addWidget(speedChartView); speedChart->setLayout(layout); - // - if (vinstance->ValidateKernal()) { + bool hasAutoStart = vinstance->ValidateKernal(); + + if (hasAutoStart) { + // At least kernal is ready. if (conf.autoStartConfig != "" && QList::fromStdList(conf.configs).contains(conf.autoStartConfig)) { + // Has auto start. CurrentConnectionName = QSTRING(conf.autoStartConfig); auto item = connectionListWidget->findItems(QSTRING(conf.autoStartConfig), Qt::MatchExactly).front(); item->setSelected(true); connectionListWidget->setCurrentItem(item); on_connectionListWidget_itemClicked(item); - on_startButton_clicked(); - hasAutoStart = true; trayMenu->actions()[0]->setText(tr("Show")); - } else { - if (connectionListWidget->count() != 0) { - // The first one is default. - connectionListWidget->setCurrentRow(0); - ShowAndSetConnection(connectionListWidget->item(0)->text(), true, false); - } + this->hide(); + on_startButton_clicked(); + } else if (connectionListWidget->count() != 0) { + // The first one is default. + connectionListWidget->setCurrentRow(0); + ShowAndSetConnection(connectionListWidget->item(0)->text(), true, false); + this->show(); } - } - - if (hasAutoStart) { - this->hide(); } else { this->show(); } @@ -175,7 +172,6 @@ void MainWindow::on_action_StartThis_triggered() CurrentConnectionName = connectionListWidget->currentItem()->text(); on_reconnectButton_clicked(); } - void MainWindow::VersionUpdate(QByteArray &data) { auto conf = GetGlobalConfig(); @@ -210,7 +206,6 @@ void MainWindow::VersionUpdate(QByteArray &data) } } } - void MainWindow::LoadConnections() { auto conf = GetGlobalConfig(); @@ -238,7 +233,6 @@ void MainWindow::LoadConnections() ShowAndSetConnection(CurrentConnectionName, false, false); } } - void MainWindow::OnConfigListChanged(bool need_restart) { auto statusText = statusLabel->text(); @@ -256,19 +250,16 @@ void MainWindow::OnConfigListChanged(bool need_restart) if (isRunning && need_restart) on_startButton_clicked(); } - MainWindow::~MainWindow() { hTray->hide(); delete this->hTray; delete this->vinstance; } - void MainWindow::UpdateLog() { logText->append(vinstance->ReadProcessOutput().trimmed()); } - void MainWindow::on_startButton_clicked() { if (vinstance->VCoreStatus != STARTED) { @@ -280,6 +271,7 @@ void MainWindow::on_startButton_clicked() downloadSerie->replace(i, 0, 0); } + // Check Selection if (CurrentConnectionName.isEmpty()) { QvMessageBox(this, tr("No connection selected!"), tr("Please select a config from the list.")); return; @@ -287,6 +279,7 @@ void MainWindow::on_startButton_clicked() LOG(MODULE_VCORE, ("Connecting to: " + CurrentConnectionName).toStdString()) logText->clear(); + // CurrentFullConfig = GenerateRuntimeConfig(connections[CurrentConnectionName]); StartPreparation(CurrentFullConfig); bool startFlag = this->vinstance->StartVCore(); @@ -300,6 +293,9 @@ void MainWindow::on_startButton_clicked() vinstance->SetAPIPort(GetGlobalConfig().statsPort); speedTimerId = startTimer(1000); } + } else { + // If failed, show mainwindow + this->show(); } trayMenu->actions()[2]->setEnabled(!startFlag); @@ -310,7 +306,6 @@ void MainWindow::on_startButton_clicked() stopButton->setEnabled(startFlag); } } - void MainWindow::on_stopButton_clicked() { if (vinstance->VCoreStatus != STOPPED) { @@ -331,14 +326,12 @@ void MainWindow::on_stopButton_clicked() dataamountLabel->setText("0.00 B\r\n0.00 B"); } } - void MainWindow::closeEvent(QCloseEvent *event) { this->hide(); trayMenu->actions()[0]->setText(tr("Show")); event->ignore(); } - void MainWindow::on_activatedTray(QSystemTrayIcon::ActivationReason reason) { switch (reason) { @@ -370,7 +363,6 @@ void MainWindow::on_activatedTray(QSystemTrayIcon::ActivationReason reason) break; } } - void MainWindow::ToggleVisibility() { if (this->isHidden()) { @@ -386,26 +378,22 @@ void MainWindow::ToggleVisibility() trayMenu->actions()[0]->setText(tr("Show")); } } - void MainWindow::quit() { Utils::NetSpeedPlugin::StopProcessingPlugins(); on_stopButton_clicked(); QApplication::quit(); } - void MainWindow::on_actionExit_triggered() { quit(); } - void MainWindow::QTextScrollToBottom() { auto bar = logText->verticalScrollBar(); if (bar->value() >= bar->maximum() - 10) bar->setValue(bar->maximum()); } - void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnection, bool ApplyConnection) { // Check empty again... @@ -452,7 +440,6 @@ void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnect on_reconnectButton_clicked(); } } - void MainWindow::on_connectionListWidget_itemClicked(QListWidgetItem *item) { Q_UNUSED(item) @@ -464,14 +451,12 @@ void MainWindow::on_connectionListWidget_itemClicked(QListWidgetItem *item) bool canSetConnection = !isRenamingInProgress && vinstance->VCoreStatus != STARTED; ShowAndSetConnection(currentText, canSetConnection, false); } - void MainWindow::on_prefrencesBtn_clicked() { PrefrencesWindow *w = new PrefrencesWindow(this); connect(w, &PrefrencesWindow::s_reload_config, this, &MainWindow::OnConfigListChanged); w->show(); } - void MainWindow::on_connectionListWidget_doubleClicked(const QModelIndex &index) { Q_UNUSED(index) @@ -482,25 +467,21 @@ void MainWindow::on_connectionListWidget_doubleClicked(const QModelIndex &index) QString currentText = connectionListWidget->currentItem()->text(); ShowAndSetConnection(currentText, true, true); } - void MainWindow::on_clearlogButton_clicked() { logText->clear(); } - void MainWindow::on_connectionListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) { Q_UNUSED(previous) isRenamingInProgress = false; on_connectionListWidget_itemClicked(current); } - void MainWindow::on_connectionListWidget_customContextMenuRequested(const QPoint &pos) { Q_UNUSED(pos) listMenu.popup(QCursor::pos()); } - void MainWindow::on_action_RenameConnection_triggered() { auto item = connectionListWidget->currentItem(); @@ -509,7 +490,6 @@ void MainWindow::on_action_RenameConnection_triggered() originalName = item->text(); isRenamingInProgress = true; } - void MainWindow::on_connectionListWidget_itemChanged(QListWidgetItem *item) { DEBUG(MODULE_UI, "A connection ListViewItem is changed.") @@ -553,7 +533,6 @@ void MainWindow::on_connectionListWidget_itemChanged(QListWidgetItem *item) } } } - void MainWindow::on_removeConfigButton_clicked() { if (connectionListWidget->currentIndex().row() < 0) return; @@ -580,14 +559,12 @@ void MainWindow::on_removeConfigButton_clicked() ShowAndSetConnection(CurrentConnectionName, false, false); } } - void MainWindow::on_importConfigButton_clicked() { ImportConfigWindow *w = new ImportConfigWindow(this); w->exec(); OnConfigListChanged(false); } - void MainWindow::on_editConfigButton_clicked() { // Check if we have a connection selected... @@ -624,13 +601,11 @@ void MainWindow::on_editConfigButton_clicked() ShowAndSetConnection(CurrentConnectionName, false, false); } } - void MainWindow::on_reconnectButton_clicked() { on_stopButton_clicked(); on_startButton_clicked(); } - void MainWindow::on_action_RCM_EditJson_triggered() { // Check if we have a connection selected... @@ -652,18 +627,15 @@ void MainWindow::on_action_RCM_EditJson_triggered() ShowAndSetConnection(CurrentConnectionName, false, false); } } - void MainWindow::on_editJsonBtn_clicked() { // See above. on_action_RCM_EditJson_triggered(); } - void MainWindow::on_pingTestBtn_clicked() { // Ping } - void MainWindow::on_shareBtn_clicked() { // Share QR @@ -687,12 +659,10 @@ void MainWindow::on_shareBtn_clicked() QvMessageBox(this, tr("Share Connection"), tr("There're no support of sharing configs other than vmess")); } } - void MainWindow::on_action_RCM_ShareQR_triggered(bool checked) { on_shareBtn_clicked(); } - void MainWindow::timerEvent(QTimerEvent *event) { Q_UNUSED(event) diff --git a/src/ui/w_MainWindow.hpp b/src/ui/w_MainWindow.hpp index aca8a00b..7be20161 100644 --- a/src/ui/w_MainWindow.hpp +++ b/src/ui/w_MainWindow.hpp @@ -69,7 +69,7 @@ class MainWindow : public QMainWindow, Ui::MainWindow public: QJsonObject CurrentFullConfig; QString CurrentConnectionName = ""; - Qv2Instance *vinstance; + ConnectionInstance *vinstance; QString totalDataUp; QString totalDataDown; QString totalSpeedUp; diff --git a/src/ui/w_PrefrencesWindow.cpp b/src/ui/w_PrefrencesWindow.cpp index 8949a790..858725af 100644 --- a/src/ui/w_PrefrencesWindow.cpp +++ b/src/ui/w_PrefrencesWindow.cpp @@ -46,36 +46,46 @@ PrefrencesWindow::PrefrencesWindow(QWidget *parent) : QDialog(parent), tProxyCheckBox->setChecked(CurrentConfig.tProxySupport); // // - listenIPTxt->setText(QSTRING(CurrentConfig.inBoundSettings.listenip)); + listenIPTxt->setText(QSTRING(CurrentConfig.inboundConfig.listenip)); + bool pacEnabled = CurrentConfig.inboundConfig.pacConfig.enablePAC; + enablePACCB->setChecked(pacEnabled); // - bool have_http = CurrentConfig.inBoundSettings.http_port != 0; + pacGroupBox->setEnabled(pacEnabled); + + if (pacEnabled) { + pacPortSB->setValue(CurrentConfig.inboundConfig.pacConfig.port); + gfwListCB->setCurrentIndex(CurrentConfig.inboundConfig.pacConfig.sourceId); + } + + // + bool have_http = CurrentConfig.inboundConfig.http_port != 0; httpCB->setChecked(have_http); - httpPortLE->setValue(CurrentConfig.inBoundSettings.http_port); - httpAuthCB->setChecked(CurrentConfig.inBoundSettings.http_useAuth); + httpGroupBox->setEnabled(have_http); + httpPortLE->setValue(CurrentConfig.inboundConfig.http_port); + httpAuthCB->setChecked(CurrentConfig.inboundConfig.http_useAuth); // - httpAuthCB->setEnabled(have_http); - httpAuthCB->setChecked(CurrentConfig.inBoundSettings.http_useAuth); - httpAuthUsernameTxt->setEnabled(have_http && CurrentConfig.inBoundSettings.http_useAuth); - httpAuthPasswordTxt->setEnabled(have_http && CurrentConfig.inBoundSettings.http_useAuth); - httpAuthUsernameTxt->setText(QSTRING(CurrentConfig.inBoundSettings.httpAccount.user)); - httpAuthPasswordTxt->setText(QSTRING(CurrentConfig.inBoundSettings.httpAccount.pass)); + httpAuthCB->setChecked(CurrentConfig.inboundConfig.http_useAuth); + httpAuthUsernameTxt->setEnabled(have_http && CurrentConfig.inboundConfig.http_useAuth); + httpAuthPasswordTxt->setEnabled(have_http && CurrentConfig.inboundConfig.http_useAuth); + httpAuthUsernameTxt->setText(QSTRING(CurrentConfig.inboundConfig.httpAccount.user)); + httpAuthPasswordTxt->setText(QSTRING(CurrentConfig.inboundConfig.httpAccount.pass)); // // - bool have_socks = CurrentConfig.inBoundSettings.socks_port != 0; + bool have_socks = CurrentConfig.inboundConfig.socks_port != 0; socksCB->setChecked(have_socks); - socksPortLE->setValue(CurrentConfig.inBoundSettings.socks_port); - socksAuthCB->setChecked(CurrentConfig.inBoundSettings.socks_useAuth); + socksGroupBox->setEnabled(have_socks); + socksPortLE->setValue(CurrentConfig.inboundConfig.socks_port); + socksAuthCB->setChecked(CurrentConfig.inboundConfig.socks_useAuth); // - socksAuthCB->setEnabled(have_socks); - socksAuthCB->setChecked(CurrentConfig.inBoundSettings.socks_useAuth); - socksAuthUsernameTxt->setEnabled(have_socks && CurrentConfig.inBoundSettings.socks_useAuth); - socksAuthPasswordTxt->setEnabled(have_socks && CurrentConfig.inBoundSettings.socks_useAuth); - socksAuthUsernameTxt->setText(QSTRING(CurrentConfig.inBoundSettings.socksAccount.user)); - socksAuthPasswordTxt->setText(QSTRING(CurrentConfig.inBoundSettings.socksAccount.pass)); + socksAuthCB->setChecked(CurrentConfig.inboundConfig.socks_useAuth); + socksAuthUsernameTxt->setEnabled(have_socks && CurrentConfig.inboundConfig.socks_useAuth); + socksAuthPasswordTxt->setEnabled(have_socks && CurrentConfig.inboundConfig.socks_useAuth); + socksAuthUsernameTxt->setText(QSTRING(CurrentConfig.inboundConfig.socksAccount.user)); + socksAuthPasswordTxt->setText(QSTRING(CurrentConfig.inboundConfig.socksAccount.pass)); // Socks UDP Options - socksUDPCB->setChecked(CurrentConfig.inBoundSettings.socksUDP); - socksUDPIP->setEnabled(CurrentConfig.inBoundSettings.socksUDP); - socksUDPIP->setText(QSTRING(CurrentConfig.inBoundSettings.socksLocalIP)); + socksUDPCB->setChecked(CurrentConfig.inboundConfig.socksUDP); + socksUDPIP->setEnabled(CurrentConfig.inboundConfig.socksUDP); + socksUDPIP->setText(QSTRING(CurrentConfig.inboundConfig.socksLocalIP)); // // vCorePathTxt->setText(QSTRING(CurrentConfig.v2CorePath)); @@ -149,13 +159,13 @@ void PrefrencesWindow::on_buttonBox_accepted() void PrefrencesWindow::on_httpCB_stateChanged(int checked) { NEEDRESTART - httpPortLE->setEnabled(checked == Qt::Checked); - httpAuthCB->setEnabled(checked == Qt::Checked); - httpAuthUsernameTxt->setEnabled(checked == Qt::Checked && httpAuthCB->isChecked()); - httpAuthPasswordTxt->setEnabled(checked == Qt::Checked && httpAuthCB->isChecked()); - CurrentConfig.inBoundSettings.http_port = checked == Qt::Checked ? CurrentConfig.inBoundSettings.http_port : 0; + bool enabled = checked == Qt::Checked; + httpGroupBox->setEnabled(enabled); + httpAuthUsernameTxt->setEnabled(enabled && httpAuthCB->isChecked()); + httpAuthPasswordTxt->setEnabled(enabled && httpAuthCB->isChecked()); + CurrentConfig.inboundConfig.http_port = enabled ? CurrentConfig.inboundConfig.http_port : 0; - if (checked != Qt::Checked) { + if (!enabled) { httpPortLE->setValue(0); } } @@ -163,13 +173,11 @@ void PrefrencesWindow::on_httpCB_stateChanged(int checked) void PrefrencesWindow::on_socksCB_stateChanged(int checked) { NEEDRESTART - socksPortLE->setEnabled(checked == Qt::Checked); - socksAuthCB->setEnabled(checked == Qt::Checked); - socksAuthUsernameTxt->setEnabled(checked == Qt::Checked && socksAuthCB->isChecked()); - socksAuthPasswordTxt->setEnabled(checked == Qt::Checked && socksAuthCB->isChecked()); - CurrentConfig.inBoundSettings.socks_port = checked == Qt::Checked ? CurrentConfig.inBoundSettings.socks_port : 0; + bool enabled = checked == Qt::Checked; + socksGroupBox->setEnabled(enabled); + CurrentConfig.inboundConfig.socks_port = enabled ? CurrentConfig.inboundConfig.socks_port : 0; - if (checked != Qt::Checked) { + if (!enabled) { socksPortLE->setValue(0); } } @@ -177,32 +185,39 @@ void PrefrencesWindow::on_socksCB_stateChanged(int checked) void PrefrencesWindow::on_httpAuthCB_stateChanged(int checked) { NEEDRESTART - httpAuthUsernameTxt->setEnabled(checked == Qt::Checked); - httpAuthPasswordTxt->setEnabled(checked == Qt::Checked); - CurrentConfig.inBoundSettings.http_useAuth = checked == Qt::Checked; + bool enabled = checked == Qt::Checked; + httpAuthUsernameTxt->setEnabled(enabled); + httpAuthPasswordTxt->setEnabled(enabled); + CurrentConfig.inboundConfig.http_useAuth = enabled; } void PrefrencesWindow::on_socksAuthCB_stateChanged(int checked) { NEEDRESTART - socksAuthUsernameTxt->setEnabled(checked == Qt::Checked); - socksAuthPasswordTxt->setEnabled(checked == Qt::Checked); - CurrentConfig.inBoundSettings.socks_useAuth = checked == Qt::Checked; + bool enabled = checked == Qt::Checked; + socksAuthUsernameTxt->setEnabled(enabled); + socksAuthPasswordTxt->setEnabled(enabled); + CurrentConfig.inboundConfig.socks_useAuth = enabled; } void PrefrencesWindow::on_languageComboBox_currentTextChanged(const QString &arg1) { - CurrentConfig.uiConfig.language = arg1.toStdString(); + LOADINGCHECK // // A strange bug prevents us to change the UI language online // https://github.com/lhy0403/Qv2ray/issues/34 // - //if (QApplication::installTranslator(getTranslator(&arg1))) { + CurrentConfig.uiConfig.language = arg1.toStdString(); + // + // + //if (QApplication::installTranslator(getTranslator(arg1))) { // LOG(MODULE_UI, "Loaded translations " + arg1.toStdString()) // retranslateUi(this); //} else { // QvMessageBox(this, tr("#Prefrences"), tr("#SwitchTranslationError")); //} + // + //emit retranslateUi(this); } void PrefrencesWindow::on_logLevelComboBox_currentIndexChanged(int index) @@ -220,32 +235,32 @@ void PrefrencesWindow::on_vCoreAssetsPathTxt_textEdited(const QString &arg1) void PrefrencesWindow::on_listenIPTxt_textEdited(const QString &arg1) { NEEDRESTART - CurrentConfig.inBoundSettings.listenip = arg1.toStdString(); - pacAddressLabel->setText("http://" + arg1 + ":"); + CurrentConfig.inboundConfig.listenip = arg1.toStdString(); + pacAccessPathTxt->setText("http://" + arg1 + ":" + QString::number(pacPortSB->value()) + "/pac.txt"); } void PrefrencesWindow::on_httpAuthUsernameTxt_textEdited(const QString &arg1) { NEEDRESTART - CurrentConfig.inBoundSettings.httpAccount.user = arg1.toStdString(); + CurrentConfig.inboundConfig.httpAccount.user = arg1.toStdString(); } void PrefrencesWindow::on_httpAuthPasswordTxt_textEdited(const QString &arg1) { NEEDRESTART - CurrentConfig.inBoundSettings.httpAccount.pass = arg1.toStdString(); + CurrentConfig.inboundConfig.httpAccount.pass = arg1.toStdString(); } void PrefrencesWindow::on_socksAuthUsernameTxt_textEdited(const QString &arg1) { NEEDRESTART - CurrentConfig.inBoundSettings.socksAccount.user = arg1.toStdString(); + CurrentConfig.inboundConfig.socksAccount.user = arg1.toStdString(); } void PrefrencesWindow::on_socksAuthPasswordTxt_textEdited(const QString &arg1) { NEEDRESTART - CurrentConfig.inBoundSettings.socksAccount.pass = arg1.toStdString(); + CurrentConfig.inboundConfig.socksAccount.pass = arg1.toStdString(); } void PrefrencesWindow::on_proxyDefaultCb_stateChanged(int arg1) @@ -439,26 +454,26 @@ void PrefrencesWindow::on_statsPortBox_valueChanged(int arg1) void PrefrencesWindow::on_socksPortLE_valueChanged(int arg1) { NEEDRESTART - CurrentConfig.inBoundSettings.socks_port = arg1; + CurrentConfig.inboundConfig.socks_port = arg1; } void PrefrencesWindow::on_httpPortLE_valueChanged(int arg1) { NEEDRESTART - CurrentConfig.inBoundSettings.http_port = arg1; + CurrentConfig.inboundConfig.http_port = arg1; } void PrefrencesWindow::on_socksUDPCB_stateChanged(int arg1) { NEEDRESTART - CurrentConfig.inBoundSettings.socksUDP = arg1 == Qt::Checked; + CurrentConfig.inboundConfig.socksUDP = arg1 == Qt::Checked; socksUDPIP->setEnabled(arg1 == Qt::Checked); } void PrefrencesWindow::on_socksUDPIP_textEdited(const QString &arg1) { NEEDRESTART - CurrentConfig.inBoundSettings.socksLocalIP = arg1.toStdString(); + CurrentConfig.inboundConfig.socksLocalIP = arg1.toStdString(); } // ------------------- NET SPEED PLUGIN OPERATIONS ----------------------------------------------------------------- @@ -634,45 +649,45 @@ void PrefrencesWindow::on_nsBarFontSizeSB_valueChanged(double arg1) SET_LINE_LIST_TEXT } -QString PrefrencesWindow::GetBarLineDescription(QvBarLine line) +QString PrefrencesWindow::GetBarLineDescription(QvBarLine barLine) { QString result = "Empty"; - result = NetSpeedPluginMessages[line.ContentType]; + result = NetSpeedPluginMessages[barLine.ContentType]; - if (line.ContentType == 0) { - result += " (" + QSTRING(line.Message) + ")"; + if (barLine.ContentType == 0) { + result += " (" + QSTRING(barLine.Message) + ")"; } - result = result.append(line.Bold ? ", " + tr("Bold") : ""); - result = result.append(line.Italic ? ", " + tr("Italic") : ""); + result = result.append(barLine.Bold ? ", " + tr("Bold") : ""); + result = result.append(barLine.Italic ? ", " + tr("Italic") : ""); return result; } -void PrefrencesWindow::ShowLineParameters(QvBarLine &line) +void PrefrencesWindow::ShowLineParameters(QvBarLine &barLine) { finishedLoading = false; - if (!line.Family.empty()) { - fontComboBox->setCurrentFont(QFont(QSTRING(line.Family))); + if (!barLine.Family.empty()) { + fontComboBox->setCurrentFont(QFont(QSTRING(barLine.Family))); } // Colors - nsBarFontASB->setValue(line.ColorA); - nsBarFontBSB->setValue(line.ColorB); - nsBarFontGSB->setValue(line.ColorG); - nsBarFontRSB->setValue(line.ColorR); + nsBarFontASB->setValue(barLine.ColorA); + nsBarFontBSB->setValue(barLine.ColorB); + nsBarFontGSB->setValue(barLine.ColorG); + nsBarFontRSB->setValue(barLine.ColorR); // - QColor color = QColor::fromRgb(line.ColorR, line.ColorG, line.ColorB, line.ColorA); + QColor color = QColor::fromRgb(barLine.ColorR, barLine.ColorG, barLine.ColorB, barLine.ColorA); QString s("background: #" + QString(color.red() < 16 ? "0" : "") + QString::number(color.red(), 16) + QString(color.green() < 16 ? "0" : "") + QString::number(color.green(), 16) + QString(color.blue() < 16 ? "0" : "") + QString::number(color.blue(), 16) + ";"); chooseColorBtn->setStyleSheet(s); - nsBarFontSizeSB->setValue(line.Size); - nsBarFontBoldCB->setChecked(line.Bold); - nsBarFontItalicCB->setChecked(line.Italic); - nsBarContentCombo->setCurrentText(NetSpeedPluginMessages[line.ContentType]); - nsBarTagTxt->setText(QSTRING(line.Message)); + nsBarFontSizeSB->setValue(barLine.Size); + nsBarFontBoldCB->setChecked(barLine.Bold); + nsBarFontItalicCB->setChecked(barLine.Italic); + nsBarContentCombo->setCurrentText(NetSpeedPluginMessages[barLine.ContentType]); + nsBarTagTxt->setText(QSTRING(barLine.Message)); finishedLoading = true; nsBarVerticalLayout->setEnabled(true); } @@ -740,5 +755,18 @@ void PrefrencesWindow::on_darkTrayCB_stateChanged(int arg1) void PrefrencesWindow::on_enablePACCB_stateChanged(int arg1) { - pacSettingsLayout_2->setEnabled(arg1 == Qt::Checked); + bool enabled = arg1 == Qt::Checked; + CurrentConfig.inboundConfig.pacConfig.enablePAC = enabled; + pacGroupBox->setEnabled(enabled); +} + +void PrefrencesWindow::on_pacGoBtn_clicked() +{ + // +} + +void PrefrencesWindow::on_pacPortSB_valueChanged(int arg1) +{ + CurrentConfig.inboundConfig.pacConfig.port = arg1; + pacAccessPathTxt->setText("http://" + listenIPTxt->text() + ":" + QString::number(arg1) + "/pac.txt"); } diff --git a/src/ui/w_PrefrencesWindow.hpp b/src/ui/w_PrefrencesWindow.hpp index 4d65a70a..9f255843 100644 --- a/src/ui/w_PrefrencesWindow.hpp +++ b/src/ui/w_PrefrencesWindow.hpp @@ -122,6 +122,10 @@ class PrefrencesWindow : public QDialog, private Ui::PrefrencesWindow void on_enablePACCB_stateChanged(int arg1); + void on_pacGoBtn_clicked(); + + void on_pacPortSB_valueChanged(int arg1); + private: // Set ui parameters for a line; void ShowLineParameters(QvBarLine &line); @@ -132,7 +136,7 @@ class PrefrencesWindow : public QDialog, private Ui::PrefrencesWindow // bool IsConnectionPropertyChanged = false; bool finishedLoading = false; - Qv2ray::QvConfigModels::Qv2rayConfig CurrentConfig; + Qv2rayConfig CurrentConfig; Ui::PrefrencesWindow *ui; }; #endif // HVCONF_H diff --git a/src/ui/w_PrefrencesWindow.ui b/src/ui/w_PrefrencesWindow.ui index b8d78c55..765b7ad4 100644 --- a/src/ui/w_PrefrencesWindow.ui +++ b/src/ui/w_PrefrencesWindow.ui @@ -39,7 +39,7 @@ QTabWidget::Rounded - 1 + 0 @@ -323,7 +323,7 @@ Inbound Settings - + @@ -340,152 +340,256 @@ + + + + Features + + + + + + + + + Qt::LeftToRight + + + HTTP + + + + + + + SOCKS + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + PAC Support + + + + + + + Enabled + + + + + - - - PAC Settings - - - - - - Enable PAC - - - - - - - Enabled - - - - - - - - - - Access Path - - - - - - - http://0.0.0.0: - - - - - - - 1 - - - 65535 - - - 8088 - - - - - - - /pac - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - GFWList Import Source - - - - - - - - Github - - - - - Mirror: Pagure - - - - - Mirror: Repo.or.cz - - - - - Mirror: Bitbucket - - - - - Mirror: Gitlab - - - - - Mirror: TuxFamily - - - - - GFWList File - - - - - - - - Go - - - - - - - - - - - - - + + + - SOCKS Inbound Settings + HTTP Settings - - - + + + + + Port + + + + + + + 1 + + + 65535 + + + 18001 + + + + + + + Authentication + + + + + Enabled + + + + Username + + + + + + + user + + + + + + + Password + + + + + + + pass + + + + + + + + + + PAC Settings + + + + + + GFWList Source + + + + + + + + + + Github + + + + + Mirror: Pagure + + + + + Mirror: Repo.or.cz + + + + + Mirror: Bitbucket + + + + + Mirror: Gitlab + + + + + Mirror: TuxFamily + + + + + GFWList File + + + + + + + + Go + + + + + + + + + Edit PAC + + + + + + + Open PAC Folder + + + + + + + Port + + + + + + + 1 + + + 65535 + + + 8088 + + + + + + + Access URL + + + + + + + true + + + + + + + + + + SOCKS Settings + + @@ -501,12 +605,15 @@ 65535 + + 1081 + - SOCKS UDP + UDP Support @@ -520,7 +627,7 @@ - Local IP + Local IP (For UDP) @@ -576,84 +683,6 @@ - - - - HTTP Inbound Settings - - - - - - Qt::LeftToRight - - - Enabled - - - - - - - Port - - - - - - - 1 - - - 65535 - - - - - - - Authentication - - - - - - - Enabled - - - - - - - Username - - - - - - - user - - - - - - - Password - - - - - - - pass - - - - - - diff --git a/src/ui/w_RoutesEditor.cpp b/src/ui/w_RoutesEditor.cpp index 8498967c..4065e12e 100644 --- a/src/ui/w_RoutesEditor.cpp +++ b/src/ui/w_RoutesEditor.cpp @@ -488,14 +488,16 @@ void RouteEditor::on_addRouteBtn_clicked() Balancers[bTag] = QStringList(); // routesTable->insertRow(routesTable->rowCount()); - // WARNING There will be an additional check on the final configuration generation process. + // There will be an additional check on the final configuration generation process. auto enabledItem = new QTableWidgetItem(tr("Enabled")); enabledItem->setCheckState(rule.QV2RAY_RULE_ENABLED ? Qt::Checked : Qt::Unchecked); + // routesTable->setItem(routesTable->rowCount() - 1, 0, enabledItem); routesTable->setItem(routesTable->rowCount() - 1, 1, new QTableWidgetItem(rule.inboundTag.size() > 0 ? Stringify(rule.inboundTag) : tr("Any"))); routesTable->setItem(routesTable->rowCount() - 1, 2, new QTableWidgetItem(QString::number(rule.domain.size() + rule.ip.size()) + " " + tr("Items"))); routesTable->setItem(routesTable->rowCount() - 1, 3, new QTableWidgetItem(QSTRING(rule.outboundTag))); rules.append(rule); + // currentRuleIndex = routesTable->rowCount() - 1; routesTable->setCurrentCell(currentRuleIndex, 0); ShowRuleDetail(CurrentRule); @@ -671,7 +673,7 @@ void RouteEditor::on_addDefaultBtn_clicked() // Add default connection from GlobalConfig auto conf = GetGlobalConfig(); // - auto _in = conf.inBoundSettings; + auto _in = conf.inboundConfig; // auto _in_httpConf = GenerateHTTPIN(QList() << _in.httpAccount); auto _in_socksConf = GenerateSocksIN((_in.socks_useAuth ? "password" : "noauth"), diff --git a/translations/en-US.ts b/translations/en-US.ts index 83819d6b..6ab13c0b 100644 --- a/translations/en-US.ts +++ b/translations/en-US.ts @@ -797,7 +797,7 @@ - + Hide @@ -828,106 +828,106 @@ - - + + Show - - + + No connection selected! - - + + Please select a config from the list. - + Update - + Found a new version: - + Download Link: - - - + + + Connected To Server: - + Connected - + Disconnected - - + + Rename a Connection - + The name cannot be empty - + The name has been used already, Please choose another. - - + + Removing this Connection - + Are you sure to remove this connection? - + Failed to delete connection file, please delete manually. - - + + No Config Selected - - + + Please Select a Config - + Share Connection - + There're no support of sharing configs other than vmess @@ -1174,10 +1174,10 @@ PrefrencesWindow - - - - + + + + Prefrences @@ -1192,76 +1192,75 @@ - - - - - - - - - - + + + + + - - - + + + + + + + Enabled - + Dark UI Icons - + Language - + zh-CN - + en-US - + Log Level - + none - + debug - + info - + warning - + error - - + + Select @@ -1271,349 +1270,411 @@ - + Dark Tray Icon - + Auto Connect - + Transparent Proxy - + V2ray Core Path - + V2ray Assets Path - + Inbound Settings - + Listening Address - - Enable PAC - - - - - LISTEN_ADDR - - - - - /pac.txt - - - - - Choose File - - - - - SOCKS Inbound Settings - - - - - - + + + + Port - - SOCKS UDP - - - - - Local IP - - - - - - + + + Authentication - - - + + + Username - - - + + + Password - - HTTP Inbound Settings - - - - + Connection Settings - + General Connection Settings - + Enable Proxy - + Bypass Chinese Mainland - + Statistics - + API Port - + Use Local DNS - + Forward Proxy - + Status - + Type - + + HTTP - - Socks + + Features - - Host Address + + SOCKS - - Network Toolbar Settings + + PAC Support - - Items + + HTTP Settings + + + + + PAC Settings + + + + + GFWList Source + + + + + Github + + + + + Mirror: Pagure + + + + + Mirror: Repo.or.cz + + + + + Mirror: Bitbucket + + + + + Mirror: Gitlab + + + + + Mirror: TuxFamily + + + + + GFWList File + + + + + Go + + + + + Edit PAC + + + + + Open PAC Folder + + + + + Access URL + + + + + SOCKS Settings + + + + + UDP Support + + + + + Local IP (For UDP) - + Socks + + + + + Host Address + + + + + Network Toolbar Settings + + + + + Items + + + + + - - - + + + - + Page Y Offset - + Pages - + Lines - + Text Style - + Font - - + + Bold - - + + Italic - + Size - + Color - + A: - + R: - + G: - + B: - + ... - + Style - + Content - + Content Type - + Text/Tag - + You can config how the network speed toolbar looks like in this panel - + Apply Network Speed Bar UI Settings - + About - + Qv2ray - + Version: - + Built Time - + Official Repo - + Ignore Next Version - + <html><head/><body><p><a href="https://github.com/lhy0403/Qv2ray"><span style=" text-decoration: underline; color:#2980b9;">https://github.com/lhy0403/Qv2ray</span></a></p></body></html> - + Custom DNS List - + License: - + <html><head/><body><p><a href="https://www.gnu.org/licenses/gpl-3.0.txt"><span style=" text-decoration: underline; color:#2980b9;">GPLv3 (https://www.gnu.org/licenses/gpl-3.0.txt)</span></a></p></body></html> - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -1635,12 +1696,12 @@ p, li { white-space: pre-wrap; } - + Cancel - + About Qt @@ -1650,79 +1711,79 @@ p, li { white-space: pre-wrap; } - + Page - + Item(s) - + Port numbers cannot be the same - + Open v2ray assets folder - + Open v2ray core file - - + + Enable tProxy Support - + This will append capabilities to the v2ray executable. - + Qv2ray will copy your v2ray core to this path: - + If anything goes wrong after enabling this, please refer to issue #57 or the link below: - + Qv2ray cannot copy one or both v2ray files from: - + to this path: - - + + Failed to setcap onto v2ray executable. You may need to run `setcap` manually. - + tProxy is not supported on macOS and Windows - + Dark Mode - + Please restart Qv2ray to fully apply this feature. @@ -2163,13 +2224,13 @@ p, li { white-space: pre-wrap; } - + Any - + Items @@ -2206,46 +2267,46 @@ p, li { white-space: pre-wrap; } - - - - + + + + Changing route inbound/outbound - + You didn't select an outbound. - + Banlancer will be used. - - + + One or more inbound config(s) have no tag configured, do you still want to continue? - + Are you sure to change the inbound/outbound of currently selected route? - + Current inbound/outbound combinations: - + Inbounds: - + Outbound: @@ -2294,72 +2355,68 @@ p, li { white-space: pre-wrap; } - + #AddConnection - + A - + #RemoveConnection - + + R - - ... - - - - + Name - + URL - + Config List - + Update Subscription - + Config Detail - + Type - + Server - + Config - + Port