From 712059f5035ca93e507ac792113c7788209b3c68 Mon Sep 17 00:00:00 2001 From: Qv2ray Bot <59914293+Qv2ray-Bot@users.noreply.github.com> Date: Fri, 17 Jan 2020 21:29:29 +0800 Subject: [PATCH] fix: some fixes and refactors, fixed #253 and fixed #254 --- Build.Counter | 2 +- src/components/QvCore/QvCommandLineArgs.cpp | 15 +- src/components/QvCore/QvCommandLineArgs.hpp | 3 + src/components/QvKernelInteractions.cpp | 8 +- src/components/QvPACHandler.cpp | 2 +- src/main.cpp | 77 +- src/ui/w_ExportConfig.cpp | 4 +- src/ui/w_ImportConfig.cpp | 16 +- src/ui/w_InboundEditor.cpp | 10 +- src/ui/w_JsonEditor.cpp | 6 +- src/ui/w_MainWindow.cpp | 31 +- src/ui/w_MainWindow_extra.cpp | 14 +- src/ui/w_PreferencesWindow.cpp | 102 +- src/ui/w_PreferencesWindow.hpp | 12 +- src/ui/w_PreferencesWindow.ui | 2356 ++++++++++--------- src/ui/w_RoutesEditor.cpp | 10 +- src/ui/w_RoutesEditor_extra.cpp | 6 +- src/ui/w_SubscriptionEditor.cpp | 16 +- src/utils/QvHelpers.cpp | 10 +- src/utils/QvHelpers.hpp | 9 +- 20 files changed, 1382 insertions(+), 1327 deletions(-) diff --git a/Build.Counter b/Build.Counter index e069f017..e6c53ce6 100644 --- a/Build.Counter +++ b/Build.Counter @@ -1 +1 @@ -2830 +2862 diff --git a/src/components/QvCore/QvCommandLineArgs.cpp b/src/components/QvCore/QvCommandLineArgs.cpp index bade8eee..747c5fa7 100644 --- a/src/components/QvCore/QvCommandLineArgs.cpp +++ b/src/components/QvCore/QvCommandLineArgs.cpp @@ -11,17 +11,20 @@ namespace Qv2ray QvStartupOptions StartupOption = QvStartupOptions{}; QvCommandArgParser::QvCommandArgParser() : QObject(), - noAPIOption("FAKE"), runAsRootOption("FAKE"), debugOption("FAKE"), helpOption("FAKE"), versionOption("FAKE") + noAPIOption("noAPI", QObject::tr("Disable gRPC API subsystems.")), + runAsRootOption("I-just-wanna-run-with-root", QObject::tr("Explicitly run Qv2ray as root.")), + debugOption("debug", QObject::tr("Enable Debug Output")), + withToolbarOption("withToolbarPlugin", QObject::tr("Enable Qv2ray network toolbar plugin")), + // + helpOption("FAKE"), versionOption("FAKE") { parser.setApplicationDescription(QObject::tr("Qv2ray - A cross-platform Qt frontend for V2ray.")); parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); // - noAPIOption = QCommandLineOption("noAPI", QObject::tr("Disable gRPC API subsystems.")); - runAsRootOption = QCommandLineOption("I-just-wanna-run-with-root", QObject::tr("Explicitly run Qv2ray as root.")); - debugOption = QCommandLineOption("debug", QObject::tr("Enable Debug Output")); parser.addOption(noAPIOption); parser.addOption(runAsRootOption); parser.addOption(debugOption); + parser.addOption(withToolbarOption); helpOption = parser.addHelpOption(); versionOption = parser.addVersionOption(); } @@ -51,6 +54,10 @@ namespace Qv2ray StartupOption.debugLog = true; } + if (parser.isSet(withToolbarOption)) { + StartupOption.enableToolbarPlguin = true; + } + return CommandLineOk; } } diff --git a/src/components/QvCore/QvCommandLineArgs.hpp b/src/components/QvCore/QvCommandLineArgs.hpp index 90ce8587..f20c4496 100644 --- a/src/components/QvCore/QvCommandLineArgs.hpp +++ b/src/components/QvCore/QvCommandLineArgs.hpp @@ -14,6 +14,8 @@ namespace Qv2ray bool forceRunAsRootUser; /// Enable Debug Log. bool debugLog; + /// Enable Network toolbar plugin. + bool enableToolbarPlguin; }; enum CommandLineParseResult { CommandLineOk, @@ -40,6 +42,7 @@ namespace Qv2ray QCommandLineOption noAPIOption; QCommandLineOption runAsRootOption; QCommandLineOption debugOption; + QCommandLineOption withToolbarOption; QCommandLineOption helpOption; QCommandLineOption versionOption; }; diff --git a/src/components/QvKernelInteractions.cpp b/src/components/QvKernelInteractions.cpp index 463ddc99..5aef0ee4 100644 --- a/src/components/QvKernelInteractions.cpp +++ b/src/components/QvKernelInteractions.cpp @@ -100,18 +100,18 @@ namespace Qv2ray if (!process.waitForFinished(1000) && process.exitCode() != 0) { LOG(MODULE_VCORE, "V2ray core failed with an exit code: " + QSTRN(process.exitCode())) - QvMessageBox(nullptr, tr("Cannot start v2ray"), tr("V2ray core failed with an exit code: ") + QSTRN(process.exitCode())); + QvMessageBoxWarn(nullptr, tr("Cannot start v2ray"), tr("V2ray core failed with an exit code: ") + QSTRN(process.exitCode())); return false; } else if (process.exitCode() != 0) { QString output = QString(process.readAllStandardOutput()); - QvMessageBox(nullptr, tr("Configuration Error"), output.mid(output.indexOf("anti-censorship.") + 17)); + QvMessageBoxWarn(nullptr, tr("Configuration Error"), output.mid(output.indexOf("anti-censorship.") + 17)); return false; } else { DEBUG(MODULE_VCORE, "Config file check passed.") return true; } } else { - QvMessageBox(nullptr, tr("Cannot start v2ray"), + QvMessageBoxWarn(nullptr, tr("Cannot start v2ray"), tr("V2ray core settings is incorrect.") + NEWLINE + NEWLINE + tr("The error is: ") + NEWLINE + v2rayCheckResult); return false; @@ -235,7 +235,7 @@ namespace Qv2ray if (apiFailedCounter == QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD) { LOG(MODULE_VCORE, "API call failure threshold reached, cancelling further API aclls.") - QvMessageBox(nullptr, tr("API Call Failed"), tr("Failed to get statistics data, please check if v2ray is running properly")); + QvMessageBoxWarn(nullptr, tr("API Call Failed"), tr("Failed to get statistics data, please check if v2ray is running properly")); transferData.clear(); transferSpeed.clear(); apiFailedCounter++; diff --git a/src/components/QvPACHandler.cpp b/src/components/QvPACHandler.cpp index bb697a6b..adb9ca5c 100644 --- a/src/components/QvPACHandler.cpp +++ b/src/components/QvPACHandler.cpp @@ -40,7 +40,7 @@ namespace Qv2ray LOG(MODULE_PROXY, "Started PAC listener") } else { LOG(MODULE_PROXY, "Failed to listen on port " + QSTRN(port) + ", please verify the permission.") - QvMessageBox(nullptr, tr("PAC Handler"), tr("Failed to listen PAC request on this port, please verify the permissions")); + QvMessageBoxWarn(nullptr, tr("PAC Handler"), tr("Failed to listen PAC request on this port, please verify the permissions")); } } diff --git a/src/main.cpp b/src/main.cpp index 14970c24..2d78a702 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -80,7 +80,7 @@ bool verifyConfigAvaliability(QString path, bool checkExistingConfig) } catch (...) { LOG(MODULE_CONFIG, "Exception raised when checking config: " + configFile.fileName()) //LOG(MODULE_INIT, e->what()) - QvMessageBox(nullptr, QObject::tr("Warning"), QObject::tr("Qv2ray cannot load the config file from here:") + NEWLINE + configFile.fileName()); + QvMessageBoxWarn(nullptr, QObject::tr("Warning"), QObject::tr("Qv2ray cannot load the config file from here:") + NEWLINE + configFile.fileName()); return false; } } else return true; @@ -144,10 +144,10 @@ bool initialiseQv2ray() // Otherwise Qv2ray would have loaded this config already instead of notifying to // create a new config in this folder. LOG(MODULE_INIT, "This should not occur: Qv2ray config exists but failed to load.") - QvMessageBox(nullptr, QObject::tr("Failed to initialise Qv2ray"), - QObject::tr("Failed to determine the location of config file.") + NEWLINE + - QObject::tr("Qv2ray will now exit.") + NEWLINE + - QObject::tr("Please report if you think it's a bug.")); + QvMessageBoxWarn(nullptr, QObject::tr("Failed to initialise Qv2ray"), + QObject::tr("Failed to determine the location of config file.") + NEWLINE + + QObject::tr("Qv2ray will now exit.") + NEWLINE + + QObject::tr("Please report if you think it's a bug.")); return false; } @@ -165,11 +165,11 @@ bool initialiseQv2ray() LOG(MODULE_INIT, "FATAL") LOG(MODULE_INIT, " ---> CANNOT find a proper place to store Qv2ray config files.") QString searchPath = Stringify(configFilePaths, NEWLINE); - QvMessageBox(nullptr, QObject::tr("Cannot Start Qv2ray"), - QObject::tr("Cannot find a place to store config files.") + NEWLINE + - QObject::tr("Qv2ray has searched these paths below:") + - NEWLINE + NEWLINE + searchPath + NEWLINE + - QObject::tr("Qv2ray will now exit.")); + QvMessageBoxWarn(nullptr, QObject::tr("Cannot Start Qv2ray"), + QObject::tr("Cannot find a place to store config files.") + NEWLINE + + QObject::tr("Qv2ray has searched these paths below:") + + NEWLINE + NEWLINE + searchPath + NEWLINE + + QObject::tr("Qv2ray will now exit.")); return false; } } @@ -186,6 +186,17 @@ bool initialiseQv2ray() int main(int argc, char *argv[]) { + // + // Install a default translater. From the OS/DE + auto _lang = QLocale::system().name().replace("_", "-"); + auto _sysTranslator = getTranslator(_lang); + + if (_lang != "en-US") { + // Do not install en-US as it's the default language. + bool _result_ = QApplication::installTranslator(_sysTranslator); + LOG(MODULE_UI, "Installing a tranlator from OS: " + _lang + " -- " + (_result_ ? "OK" : "Failed")) + } + // parse the command line before starting as a Qt application { std::unique_ptr consoleApp(new QCoreApplication(argc, argv)); @@ -247,17 +258,6 @@ int main(int argc, char *argv[]) SingleApplication _qApp(argc, argv, false, SingleApplication::Mode::User | SingleApplication::Mode::ExcludeAppPath | SingleApplication::Mode::ExcludeAppVersion); // Early initialisation // - // - // Install a default translater. From the OS/DE - auto _lang = QLocale::system().name().replace("_", "-"); - auto _sysTranslator = getTranslator(_lang); - - if (_lang != "en-US") { - // Do not install en-US as it's the default language. - bool _result_ = qApp->installTranslator(_sysTranslator); - LOG(MODULE_UI, "Installing a tranlator from OS: " + _lang + " -- " + (_result_ ? "OK" : "Failed")) - } - LOG("LICENCE", NEWLINE "This program comes with ABSOLUTELY NO WARRANTY." NEWLINE "This is free software, and you are welcome to redistribute it" NEWLINE "under certain conditions." NEWLINE NEWLINE @@ -287,7 +287,7 @@ int main(int argc, char *argv[]) if (langs.empty()) { LOG(MODULE_INIT, "FAILED to find any translations. THIS IS A BUILD ERROR.") - QvMessageBox(nullptr, QObject::tr("Cannot load languages"), QObject::tr("Qv2ray will continue running, but you cannot change the UI language.")); + QvMessageBoxWarn(nullptr, QObject::tr("Cannot load languages"), QObject::tr("Qv2ray will continue running, but you cannot change the UI language.")); } else { for (auto lang : langs) { LOG(MODULE_INIT, "Found Translator: " + lang) @@ -306,11 +306,11 @@ int main(int argc, char *argv[]) if (confVersion > QV2RAY_CONFIG_VERSION) { // Config version is larger than the current version... // This is rare but it may happen.... - QvMessageBox(nullptr, QObject::tr("Qv2ray Cannot Continue"), - QObject::tr("You are running a lower version of Qv2ray compared to the current config file.") + NEWLINE + - QObject::tr("Please check if there's an issue explaining about it.") + NEWLINE + - QObject::tr("Or submit a new issue if you think this is an error.") + NEWLINE + NEWLINE + - QObject::tr("Qv2ray will now exit.")); + QvMessageBoxWarn(nullptr, QObject::tr("Qv2ray Cannot Continue"), + QObject::tr("You are running a lower version of Qv2ray compared to the current config file.") + NEWLINE + + QObject::tr("Please check if there's an issue explaining about it.") + NEWLINE + + QObject::tr("Or submit a new issue if you think this is an error.") + NEWLINE + NEWLINE + + QObject::tr("Qv2ray will now exit.")); return -2; } @@ -336,11 +336,10 @@ int main(int argc, char *argv[]) } else { // Do not translate these..... // If a translator fails to load, pop up a message. - QvMessageBox( + QvMessageBoxWarn( nullptr, "Translation Failed", - "Cannot load translation for " + confObject.uiConfig.language + ", English is now used.\r\n\r\n" - "Please go to Preferences Window to change or Report a Bug at: \r\n" - "https://github.com/lhy0403/Qv2ray/issues/new"); + "Cannot load translation for " + confObject.uiConfig.language + ", English is now used." + NEWLINE + NEWLINE + + "Please go to Preferences Window to change language or open an Issue"); } // Let's save the config. @@ -354,15 +353,13 @@ int main(int argc, char *argv[]) if (!QSslSocket::supportsSsl()) { LOG(MODULE_NETWORK, "Required OpenSSL version: " + osslReqVersion) LOG(MODULE_NETWORK, "OpenSSL library MISSING, Quitting.") - QvMessageBox(nullptr, QObject::tr("DependencyMissing"), - QObject::tr("Cannot find openssl libs") + "\r\n" + - QObject::tr("This could be caused by a missing of `openssl` package in your system. Or an AppImage issue.") + "\r\n" + - QObject::tr("If you are using AppImage, please report a bug.") + "\r\n\r\n" + - QObject::tr("Please refer to Github Issue #65 to check for solutions.") + "\r\n" + - QObject::tr("Github Issue Link: ") + "https://github.com/lhy0403/Qv2ray/issues/65" + "\r\n\r\n" + - QObject::tr("Technical Details") + "\r\n" + - "OSsl.Rq.V=" + osslReqVersion + "\r\n" + - "OSsl.Cr.V=" + osslCurVersion); + QvMessageBoxWarn(nullptr, QObject::tr("Dependency Missing"), + QObject::tr("Cannot find openssl libs") + NEWLINE + + QObject::tr("This could be caused by a missing of `openssl` package in your system.") + NEWLINE + + QObject::tr("If you are using an AppImage from Github Action, please report a bug.") + NEWLINE + NEWLINE + + QObject::tr("Technical Details") + NEWLINE + + "OSsl.Rq.V=" + osslReqVersion + NEWLINE + + "OSsl.Cr.V=" + osslCurVersion); return -3; } diff --git a/src/ui/w_ExportConfig.cpp b/src/ui/w_ExportConfig.cpp index 6667078f..e589eb4c 100644 --- a/src/ui/w_ExportConfig.cpp +++ b/src/ui/w_ExportConfig.cpp @@ -68,11 +68,11 @@ void ConfigExporter::on_saveBtn_clicked() void ConfigExporter::on_copyImageBtn_clicked() { QGuiApplication::clipboard()->setImage(image); - QvMessageBox(this, tr("Share Connection"), tr("Image has been copied to the clipboard.")); + QvMessageBoxInfo(this, tr("Share Connection"), tr("Image has been copied to the clipboard.")); } void ConfigExporter::on_copyVMessBtn_clicked() { QGuiApplication::clipboard()->setText(message); - QvMessageBox(this, tr("Share Connection"), tr("VMess string has been copied to the clipboard.")); + QvMessageBoxInfo(this, tr("Share Connection"), tr("VMess string has been copied to the clipboard.")); } diff --git a/src/ui/w_ImportConfig.cpp b/src/ui/w_ImportConfig.cpp index a135c55c..d91662c0 100644 --- a/src/ui/w_ImportConfig.cpp +++ b/src/ui/w_ImportConfig.cpp @@ -52,7 +52,7 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked() if (str.trimmed().isEmpty()) { LOG(MODULE_UI, "Cannot decode QR Code from an image, size: h=" + QSTRN(pix.width()) + ", v=" + QSTRN(pix.height())) - QvMessageBox(this, tr("Capture QRCode"), tr("Cannot find a valid QRCode from this region.")); + QvMessageBoxWarn(this, tr("Capture QRCode"), tr("Cannot find a valid QRCode from this region.")); } else { vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE); } @@ -71,7 +71,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked() QString path = fileLineTxt->text(); if (!V2rayKernelInstance::ValidateConfig(path)) { - QvMessageBox(this, tr("Import config file"), tr("Failed to check the validity of the config file.")); + QvMessageBoxWarn(this, tr("Import config file"), tr("Failed to check the validity of the config file.")); return; } @@ -120,12 +120,6 @@ void ImportConfigWindow::on_beginImportBtn_clicked() break; } - - case 2: { - QvMessageBox(this, tr("TODO"), tr("TODO")); - // Subscription link. - break; - } } accept(); @@ -143,7 +137,7 @@ void ImportConfigWindow::on_selectImageBtn_clicked() auto str = QZXing().decodeImage(QImage::fromData(buf)); if (str.isEmpty()) { - QvMessageBox(this, tr("QRCode scanning failed"), tr("Cannot find any QRCode from the image.")); + QvMessageBoxWarn(this, tr("QRCode scanning failed"), tr("Cannot find any QRCode from the image.")); return; } else { vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE); @@ -178,7 +172,7 @@ void ImportConfigWindow::on_editFileBtn_clicked() QFile file(fileLineTxt->text()); if (!file.exists()) { - QvMessageBox(this, tr("Edit file as JSON"), tr("Provided file not found: ") + fileLineTxt->text()); + QvMessageBoxWarn(this, tr("Edit file as JSON"), tr("Provided file not found: ") + fileLineTxt->text()); return; } @@ -204,7 +198,7 @@ void ImportConfigWindow::on_editFileBtn_clicked() bool result = StringToFile(&str, &file); if (!result) { - QvMessageBox(this, tr("Edit file as JSON"), tr("Failed to save file, please check if you have proper permissions")); + QvMessageBoxWarn(this, tr("Edit file as JSON"), tr("Failed to save file, please check if you have proper permissions")); } } else { LOG(MODULE_FILE, "Canceled saving a file.") diff --git a/src/ui/w_InboundEditor.cpp b/src/ui/w_InboundEditor.cpp index 74d90e59..7b995f5a 100644 --- a/src/ui/w_InboundEditor.cpp +++ b/src/ui/w_InboundEditor.cpp @@ -24,7 +24,7 @@ InboundEditor::InboundEditor(INBOUND root, QWidget *parent) : } else { if (!root["protocol"].toString().isEmpty()) { LOG(MODULE_UI, "Unsupported inbound type: " + inboundType) - QvMessageBox(this, tr("Inbound type not supported"), tr("The inbound type is not supported by Qv2ray (yet). Please use JsonEditor to change the settings") + "\r\n" + + QvMessageBoxWarn(this, tr("Inbound type not supported"), tr("The inbound type is not supported by Qv2ray (yet). Please use JsonEditor to change the settings") + "\r\n" + tr("Inbound: ") + inboundType); } else { LOG(MODULE_UI, "Creating new inbound config") @@ -195,7 +195,7 @@ void InboundEditor::on_httpRemoveUserBtn_clicked() //QvMessageBox(this, tr("Removing a user"), tr("No user has been removed. Why?")); } else { - QvMessageBox(this, tr("Removing a user"), tr("You haven't selected a user yet.")); + QvMessageBoxWarn(this, tr("Removing a user"), tr("You haven't selected a user yet.")); } } @@ -211,7 +211,7 @@ void InboundEditor::on_httpAddUserBtn_clicked() auto _user = list[i].toObject(); if (_user["user"].toString() == user) { - QvMessageBox(this, tr("Add a user"), tr("This user exists already.")); + QvMessageBoxWarn(this, tr("Add a user"), tr("This user exists already.")); return; } } @@ -247,7 +247,7 @@ void InboundEditor::on_socksRemoveUserBtn_clicked() } } } else { - QvMessageBox(this, tr("Removing a user"), tr("You haven't selected a user yet.")); + QvMessageBoxWarn(this, tr("Removing a user"), tr("You haven't selected a user yet.")); } } @@ -263,7 +263,7 @@ void InboundEditor::on_socksAddUserBtn_clicked() auto _user = list[i].toObject(); if (_user["user"].toString() == user) { - QvMessageBox(this, tr("Add a user"), tr("This user exists already.")); + QvMessageBoxWarn(this, tr("Add a user"), tr("This user exists already.")); return; } } diff --git a/src/ui/w_JsonEditor.cpp b/src/ui/w_JsonEditor.cpp index 0ba29e9c..7ad276f3 100644 --- a/src/ui/w_JsonEditor.cpp +++ b/src/ui/w_JsonEditor.cpp @@ -15,7 +15,7 @@ JsonEditor::JsonEditor(QJsonObject rootObject, QWidget *parent) : jsonTree->setModel(&model); model.loadJson(QJsonDocument(rootObject).toJson()); } else { - QvMessageBox(this, tr("Json Contains Syntax Errors"), tr("Original Json may contain syntax errors. Json tree is disabled.")); + QvMessageBoxWarn(this, tr("Json Contains Syntax Errors"), tr("Original Json may contain syntax errors. Json tree is disabled.")); } jsonEditor->setText(JsonToString(rootObject)); @@ -29,7 +29,7 @@ QJsonObject JsonEditor::OpenEditor() auto string = jsonEditor->toPlainText(); while (resultCode == QDialog::Accepted && !VerifyJsonString(string).isEmpty()) { - QvMessageBox(this, tr("Json Contains Syntax Errors"), tr("You must correct these errors before continue.")); + QvMessageBoxWarn(this, tr("Json Contains Syntax Errors"), tr("You must correct these errors before continue.")); resultCode = this->exec(); string = jsonEditor->toPlainText(); } @@ -69,6 +69,6 @@ void JsonEditor::on_formatJsonBtn_clicked() jsonEditor->setPlainText(JsonToString(JsonFromString(string))); } else { RED(jsonEditor) - QvMessageBox(this, tr("Syntax Errors"), tr("Please fix the JSON errors before continue")); + QvMessageBoxWarn(this, tr("Syntax Errors"), tr("Please fix the JSON errors before continue")); } } diff --git a/src/ui/w_MainWindow.cpp b/src/ui/w_MainWindow.cpp index 86297d91..bcccb5c3 100644 --- a/src/ui/w_MainWindow.cpp +++ b/src/ui/w_MainWindow.cpp @@ -50,7 +50,7 @@ #define SUBSCRIPTION_CONFIG_MODIFY_DENY(_item_) \ if (!CheckConfigType(_item_, REGULAR)) { \ - QvMessageBox(this, QObject::tr("Editing a subscription config"), QObject::tr("You should not modity this property of a config from a subscription")); \ + QvMessageBoxWarn(this, QObject::tr("Editing a subscription config"), QObject::tr("You should not modity this property of a config from a subscription")); \ return; \ } \ @@ -230,7 +230,12 @@ MainWindow::MainWindow(QWidget *parent): connect(requestHelper, &QvHttpRequestHelper::httpRequestFinished, this, &MainWindow::VersionUpdate); requestHelper->get("https://api.github.com/repos/lhy0403/Qv2ray/releases/latest"); - StartProcessingPlugins(); + + if (StartupOption.enableToolbarPlguin) { + LOG(MODULE_UI, "Plugin daemon is enabled.") + StartProcessingPlugins(); + } + CheckSubscriptionsUpdate(); } @@ -281,7 +286,7 @@ void MainWindow::keyPressEvent(QKeyEvent *e) void MainWindow::on_action_StartThis_triggered() { if (!IsSelectionConnectable) { - QvMessageBox(this, tr("No connection selected!"), tr("Please select a config from the list.")); + QvMessageBoxWarn(this, tr("No connection selected!"), tr("Please select a config from the list.")); return; } @@ -435,7 +440,7 @@ void MainWindow::on_startButton_clicked() // Check Selection if (CurrentConnectionIdentifier.isEmpty()) { - QvMessageBox(this, tr("No connection selected!"), tr("Please select a config from the list.")); + QvMessageBoxWarn(this, tr("No connection selected!"), tr("Please select a config from the list.")); return; } @@ -666,17 +671,17 @@ void MainWindow::on_connectionListWidget_itemChanged(QTreeWidgetItem *item, int) bool canContinueRename = true; if (newIdentifier.connectionName.trimmed().isEmpty()) { - QvMessageBox(this, tr("Rename a Connection"), tr("The name cannot be empty")); + QvMessageBoxWarn(this, tr("Rename a Connection"), tr("The name cannot be empty")); canContinueRename = false; } if (currentConfig.configs.contains(newIdentifier.connectionName)) { - QvMessageBox(this, tr("Rename a Connection"), tr("The name has been used already, Please choose another.")); + QvMessageBoxWarn(this, tr("Rename a Connection"), tr("The name has been used already, Please choose another.")); canContinueRename = false; } if (!IsValidFileName(newIdentifier.connectionName + QV2RAY_CONFIG_FILE_EXTENSION)) { - QvMessageBox(this, tr("Rename a Connection"), tr("The name you suggested is not valid, please try another.")); + QvMessageBoxWarn(this, tr("Rename a Connection"), tr("The name you suggested is not valid, please try another.")); canContinueRename = false; } @@ -767,7 +772,7 @@ void MainWindow::on_removeConfigButton_clicked() currentConfig.configs.removeOne(conn.connectionName); if (!RemoveConnection(conn.connectionName)) { - QvMessageBox(this, tr("Removing this Connection"), tr("Failed to delete connection file, please delete manually.")); + QvMessageBoxWarn(this, tr("Removing this Connection"), tr("Failed to delete connection file, please delete manually.")); } } else if (connData.configType == CONNECTION_SUBSCRIPTION) { if (subscriptionRemovalCheckStatus == -1) { @@ -778,7 +783,7 @@ void MainWindow::on_removeConfigButton_clicked() if (subscriptionRemovalCheckStatus == 1) { if (!RemoveSubscriptionConnection(connData.subscriptionName, connData.connectionName)) { - QvMessageBox(this, tr("Removing this Connection"), tr("Failed to delete connection file, please delete manually.")); + QvMessageBoxWarn(this, tr("Removing this Connection"), tr("Failed to delete connection file, please delete manually.")); } } } else { @@ -816,7 +821,7 @@ void MainWindow::on_editConfigButton_clicked() { // Check if we have a connection selected... if (!IsSelectionConnectable) { - QvMessageBox(this, tr("No Config Selected"), tr("Please Select a Config")); + QvMessageBoxWarn(this, tr("No Config Selected"), tr("Please Select a Config")); return; } @@ -867,7 +872,7 @@ void MainWindow::on_action_RCM_ConvToComplex_triggered() { // Check if we have a connection selected... if (!IsSelectionConnectable) { - QvMessageBox(this, tr("No Config Selected"), tr("Please Select a Config")); + QvMessageBoxWarn(this, tr("No Config Selected"), tr("Please Select a Config")); return; } @@ -898,7 +903,7 @@ void MainWindow::on_action_RCM_EditJson_triggered() { // Check if we have a connection selected... if (!IsSelectionConnectable) { - QvMessageBox(this, tr("No Config Selected"), tr("Please Select a Config")); + QvMessageBoxWarn(this, tr("No Config Selected"), tr("Please Select a Config")); return; } @@ -976,7 +981,7 @@ void MainWindow::on_shareBtn_clicked() ConfigExporter v(vmess, this); v.OpenExport(); } else { - QvMessageBox(this, tr("Share Connection"), tr("There're no support of sharing configs other than vmess")); + QvMessageBoxWarn(this, tr("Share Connection"), tr("There're no support of sharing configs other than vmess")); } } void MainWindow::on_action_RCM_ShareQR_triggered() diff --git a/src/ui/w_MainWindow_extra.cpp b/src/ui/w_MainWindow_extra.cpp index 0c88c4e9..e9d41a85 100644 --- a/src/ui/w_MainWindow_extra.cpp +++ b/src/ui/w_MainWindow_extra.cpp @@ -48,7 +48,7 @@ void MainWindow::MWFindAndStartAutoConfig() tray_RootMenu->actions()[0]->setText(tr("Show")); on_startButton_clicked(); } else { - QvMessageBox(this, tr("Autostarting a config"), tr("Could not find a specified config named: ") + NEWLINE + + QvMessageBoxWarn(this, tr("Autostarting a config"), tr("Could not find a specified config named: ") + NEWLINE + name + NEWLINE + NEWLINE + tr("Please reset the settings in Preference Window")); } @@ -97,7 +97,7 @@ void MainWindow::MWSetSystemProxy() LOG(MODULE_PROXY, "Failed to process pac due to following reasons:") LOG(MODULE_PROXY, " --> PAC is configured to use socks but socks is not enabled.") LOG(MODULE_PROXY, " --> PAC is configuted to use http but http is not enabled.") - QvMessageBox(this, tr("PAC Processing Failed"), tr("HTTP or SOCKS inbound is not properly configured for PAC") + + QvMessageBoxWarn(this, tr("PAC Processing Failed"), tr("HTTP or SOCKS inbound is not properly configured for PAC") + NEWLINE + tr("Qv2ray will continue, but will not set system proxy.")); canSetSystemProxy = false; } @@ -109,7 +109,7 @@ void MainWindow::MWSetSystemProxy() proxyAddress = "http://localhost"; } else { LOG(MODULE_PROXY, "HTTP is not enabled, cannot set system proxy.") - QvMessageBox(this, tr("Cannot set system proxy"), tr("HTTP inbound is not enabled")); + QvMessageBoxWarn(this, tr("Cannot set system proxy"), tr("HTTP inbound is not enabled")); canSetSystemProxy = false; } } @@ -153,7 +153,7 @@ bool MainWindow::MWtryStartConnection() pacProxyString = "SOCKS5 " + pacIP + ":" + QSTRN(currentConfig.inboundConfig.socks_port); } else { LOG(MODULE_UI, "PAC is using SOCKS, but it is not enabled") - QvMessageBox(this, tr("Configuring PAC"), tr("Could not start PAC server as it is configured to use SOCKS, but it is not enabled")); + QvMessageBoxWarn(this, tr("Configuring PAC"), tr("Could not start PAC server as it is configured to use SOCKS, but it is not enabled")); canStartPAC = false; } } else { @@ -161,7 +161,7 @@ bool MainWindow::MWtryStartConnection() pacProxyString = "PROXY " + pacIP + ":" + QSTRN(currentConfig.inboundConfig.http_port); } else { LOG(MODULE_UI, "PAC is using HTTP, but it is not enabled") - QvMessageBox(this, tr("Configuring PAC"), tr("Could not start PAC server as it is configured to use HTTP, but it is not enabled")); + QvMessageBoxWarn(this, tr("Configuring PAC"), tr("Could not start PAC server as it is configured to use HTTP, but it is not enabled")); canStartPAC = false; } } @@ -205,7 +205,7 @@ void MainWindow::MWTryPingConnection(const QvConfigIdentifier &alias) int port = get<1>(info); tcpingModel->StartPing(alias, host, port); } catch (...) { - QvMessageBox(this, tr("Latency Test"), tr("Failed to test latency for this connection.")); + QvMessageBoxWarn(this, tr("Latency Test"), tr("Failed to test latency for this connection.")); } } @@ -239,7 +239,7 @@ void MainWindow::CheckSubscriptionsUpdate() } if (!updateList.isEmpty()) { - QvMessageBox(this, tr("Update Subscriptions"), + QvMessageBoxWarn(this, tr("Update Subscriptions"), tr("There are subscriptions need to be updated, please go to subscriptions window to update them.") + NEWLINE + NEWLINE + tr("These subscriptions are out-of-date: ") + NEWLINE + Stringify(updateList)); on_subsButton_clicked(); diff --git a/src/ui/w_PreferencesWindow.cpp b/src/ui/w_PreferencesWindow.cpp index e983cd03..e38e19a2 100644 --- a/src/ui/w_PreferencesWindow.cpp +++ b/src/ui/w_PreferencesWindow.cpp @@ -22,6 +22,15 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), setupUi(this); textBrowser->setHtml(StringFromFile(new QFile(":/assets/credit.html"))); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + // + // Set network Toolbar page state. + networkToolbarPage->setEnabled(StartupOption.enableToolbarPlguin); + + if (!StartupOption.enableToolbarPlguin) { + networkToolbarInfoLabel->setText(tr("Qv2ray Network Toolbar is disabled and still under test. Add --withNetworkToolbar to enable.")); + } + + // // We add locales languageComboBox->clear(); QDirIterator it(":/translations"); @@ -55,17 +64,16 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), // listenIPTxt->setText(CurrentConfig.inboundConfig.listenip); bool pacEnabled = CurrentConfig.inboundConfig.pacConfig.enablePAC; - enablePACCB->setChecked(pacEnabled); + pacGroupBox->setChecked(pacEnabled); setSysProxyCB->setChecked(CurrentConfig.inboundConfig.setSystemProxy); // // PAC - pacGroupBox->setEnabled(pacEnabled); pacPortSB->setValue(CurrentConfig.inboundConfig.pacConfig.port); pacProxyTxt->setText(CurrentConfig.inboundConfig.pacConfig.localIP); pacProxyCB->setCurrentIndex(CurrentConfig.inboundConfig.pacConfig.useSocksProxy ? 1 : 0); // bool have_http = CurrentConfig.inboundConfig.useHTTP; - httpCB->setChecked(have_http); + httpGroupBox->setChecked(have_http); httpPortLE->setValue(CurrentConfig.inboundConfig.http_port); httpAuthCB->setChecked(CurrentConfig.inboundConfig.http_useAuth); // @@ -74,11 +82,10 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), httpAuthPasswordTxt->setEnabled(CurrentConfig.inboundConfig.http_useAuth); httpAuthUsernameTxt->setText(CurrentConfig.inboundConfig.httpAccount.user); httpAuthPasswordTxt->setText(CurrentConfig.inboundConfig.httpAccount.pass); - httpGroupBox->setEnabled(have_http); // // bool have_socks = CurrentConfig.inboundConfig.useSocks; - socksCB->setChecked(have_socks); + socksGroupBox->setChecked(have_socks); socksPortLE->setValue(CurrentConfig.inboundConfig.socks_port); // socksAuthCB->setChecked(CurrentConfig.inboundConfig.socks_useAuth); @@ -125,7 +132,7 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent), nsBarPagesList->setCurrentRow(0); on_nsBarPagesList_currentRowChanged(0); } else { - nsBarVerticalLayout->setEnabled(false); + networkToolbarSettingsFrame->setEnabled(false); nsBarLinesList->setEnabled(false); nsBarLineDelBTN->setEnabled(false); nsBarLineAddBTN->setEnabled(false); @@ -181,7 +188,7 @@ void PreferencesWindow::on_buttonBox_accepted() int hp = httpPortLE->text().toInt() ; if (!(sp == 0 || hp == 0) && sp == hp) { - QvMessageBox(this, tr("Preferences"), tr("Port numbers cannot be the same")); + QvMessageBoxWarn(this, tr("Preferences"), tr("Port numbers cannot be the same")); return; } @@ -189,22 +196,6 @@ void PreferencesWindow::on_buttonBox_accepted() emit s_reload_config(IsConnectionPropertyChanged); } -void PreferencesWindow::on_httpCB_stateChanged(int checked) -{ - NEEDRESTART - bool enabled = checked == Qt::Checked; - httpGroupBox->setEnabled(enabled); - CurrentConfig.inboundConfig.useHTTP = enabled; -} - -void PreferencesWindow::on_socksCB_stateChanged(int checked) -{ - NEEDRESTART - bool enabled = checked == Qt::Checked; - socksGroupBox->setEnabled(enabled); - CurrentConfig.inboundConfig.useSocks = enabled; -} - void PreferencesWindow::on_httpAuthCB_stateChanged(int checked) { NEEDRESTART @@ -415,10 +406,10 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1) on_vCorePathTxt_textEdited(QV2RAY_DEFAULT_VCORE_PATH); } else { LOG(MODULE_VCORE, "FAILED to copy v2ray files. Aborting.") - QvMessageBox(this, tr("Enable tProxy Support"), - tr("Qv2ray cannot copy one or both v2ray files from: ") + NEWLINE + NEWLINE + - CurrentConfig.v2CorePath + NEWLINE + v2ctlPath + NEWLINE + NEWLINE + - tr("to this path: ") + NEWLINE + newPath); + QvMessageBoxWarn(this, tr("Enable tProxy Support"), + tr("Qv2ray cannot copy one or both v2ray files from: ") + NEWLINE + NEWLINE + + CurrentConfig.v2CorePath + NEWLINE + v2ctlPath + NEWLINE + NEWLINE + + tr("to this path: ") + NEWLINE + newPath); return; } } else { @@ -431,7 +422,7 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1) if (ret != 0) { LOG(MODULE_UI, "WARN: setcap exits with code: " + QSTRN(ret)) - QvMessageBox(this, tr("Preferences"), tr("Failed to setcap onto v2ray executable. You may need to run `setcap` manually.")); + QvMessageBoxWarn(this, tr("Preferences"), tr("Failed to setcap onto v2ray executable. You may need to run `setcap` manually.")); } CurrentConfig.tProxySupport = true; @@ -442,7 +433,7 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1) if (ret != 0) { LOG(MODULE_UI, "WARN: setcap exits with code: " + QSTRN(ret)) - QvMessageBox(this, tr("Preferences"), tr("Failed to setcap onto v2ray executable. You may need to run `setcap` manually.")); + QvMessageBoxWarn(this, tr("Preferences"), tr("Failed to setcap onto v2ray executable. You may need to run `setcap` manually.")); } CurrentConfig.tProxySupport = false; @@ -534,7 +525,7 @@ void PreferencesWindow::on_nsBarPageDelBTN_clicked() nsBarLineAddBTN->setEnabled(false); nsBarLineDelBTN->setEnabled(false); nsBarLinesList->setEnabled(false); - nsBarVerticalLayout->setEnabled(false); + networkToolbarSettingsFrame->setEnabled(false); nsBarPageYOffset->setEnabled(false); nsBarLinesList->clear(); } @@ -568,7 +559,7 @@ void PreferencesWindow::on_nsBarLineDelBTN_clicked() CurrentBarLineId = 0; if (nsBarLinesList->count() <= 0) { - nsBarVerticalLayout->setEnabled(false); + networkToolbarSettingsFrame->setEnabled(false); nsBarLineDelBTN->setEnabled(false); } @@ -597,7 +588,7 @@ void PreferencesWindow::on_nsBarPagesList_currentRowChanged(int currentRow) nsBarLinesList->setCurrentRow(0); ShowLineParameters(CurrentBarLine); } else { - nsBarVerticalLayout->setEnabled(false); + networkToolbarSettingsFrame->setEnabled(false); } } @@ -709,7 +700,7 @@ void PreferencesWindow::ShowLineParameters(QvBarLine &barLine) nsBarContentCombo->setCurrentText(NetSpeedPluginMessages[barLine.ContentType]); nsBarTagTxt->setText(barLine.Message); finishedLoading = true; - nsBarVerticalLayout->setEnabled(true); + networkToolbarSettingsFrame->setEnabled(true); } void PreferencesWindow::on_chooseColorBtn_clicked() @@ -756,7 +747,7 @@ void PreferencesWindow::on_darkThemeCB_stateChanged(int arg1) { LOADINGCHECK CurrentConfig.uiConfig.useDarkTheme = arg1 == Qt::Checked; - QvMessageBox(this, tr("Dark Mode"), tr("Please restart Qv2ray to fully apply this feature.")); + QvMessageBoxWarn(this, tr("Dark Mode"), tr("Please restart Qv2ray to fully apply this feature.")); #ifdef QV2RAY_USE_BUILTIN_DARKTHEME themeCombo->setEnabled(arg1 != Qt::Checked); @@ -774,15 +765,6 @@ void PreferencesWindow::on_darkTrayCB_stateChanged(int arg1) CurrentConfig.uiConfig.useDarkTrayIcon = arg1 == Qt::Checked; } -void PreferencesWindow::on_enablePACCB_stateChanged(int arg1) -{ - LOADINGCHECK - NEEDRESTART - bool enabled = arg1 == Qt::Checked; - CurrentConfig.inboundConfig.pacConfig.enablePAC = enabled; - pacGroupBox->setEnabled(enabled); -} - void PreferencesWindow::on_pacGoBtn_clicked() { LOADINGCHECK @@ -833,7 +815,7 @@ void PreferencesWindow::on_pacGoBtn_clicked() } LOG(MODULE_NETWORK, "Fetched: " + gfwLocation) - QvMessageBox(this, tr("Download GFWList"), tr("Successfully downloaded GFWList.")); + QvMessageBoxWarn(this, tr("Download GFWList"), tr("Successfully downloaded GFWList.")); pacGoBtn->setEnabled(true); gfwListCB->setEnabled(true); @@ -909,7 +891,7 @@ void PreferencesWindow::on_installBootStart_clicked() // If failed to set the status. if (!GetLaunchAtLoginStatus()) { - QvMessageBox(this, tr("Start with boot"), tr("Failed to set auto start option.")); + QvMessageBoxWarn(this, tr("Start with boot"), tr("Failed to set auto start option.")); } SetAutoStartButtonsState(GetLaunchAtLoginStatus()); @@ -921,7 +903,7 @@ void PreferencesWindow::on_removeBootStart_clicked() // If that setting still present. if (GetLaunchAtLoginStatus()) { - QvMessageBox(this, tr("Start with boot"), tr("Failed to set auto start option.")); + QvMessageBoxWarn(this, tr("Start with boot"), tr("Failed to set auto start option.")); } SetAutoStartButtonsState(GetLaunchAtLoginStatus()); @@ -998,9 +980,31 @@ void PreferencesWindow::on_checkVCoreSettings_clicked() QString result; if (!V2rayKernelInstance::ValidateKernel(vcorePath, vAssetsPath, &result)) { - QvMessageBox(this, tr("V2ray Core Settings"), result); + QvMessageBoxWarn(this, tr("V2ray Core Settings"), result); } else { - QvMessageBox(this, tr("V2ray Core Settings"), tr("V2ray path configuration check passed.") + NEWLINE + NEWLINE + - tr("Current version of V2ray is: ") + NEWLINE + result); + QvMessageBoxInfo(this, tr("V2ray Core Settings"), tr("V2ray path configuration check passed.") + NEWLINE + NEWLINE + + tr("Current version of V2ray is: ") + NEWLINE + result); } } + +void PreferencesWindow::on_httpGroupBox_clicked(bool checked) +{ + NEEDRESTART + httpGroupBox->setEnabled(checked); + CurrentConfig.inboundConfig.useHTTP = checked; +} + +void PreferencesWindow::on_socksGroupBox_clicked(bool checked) +{ + NEEDRESTART + socksGroupBox->setEnabled(checked); + CurrentConfig.inboundConfig.useSocks = checked; +} + +void PreferencesWindow::on_pacGroupBox_clicked(bool checked) +{ + LOADINGCHECK + NEEDRESTART + CurrentConfig.inboundConfig.pacConfig.enablePAC = checked; + pacGroupBox->setEnabled(checked); +} diff --git a/src/ui/w_PreferencesWindow.hpp b/src/ui/w_PreferencesWindow.hpp index 696a86c4..9685f1d9 100644 --- a/src/ui/w_PreferencesWindow.hpp +++ b/src/ui/w_PreferencesWindow.hpp @@ -18,10 +18,6 @@ class PreferencesWindow : public QDialog, private Ui::PreferencesWindow private slots: void on_buttonBox_accepted(); - void on_httpCB_stateChanged(int arg1); - - void on_socksCB_stateChanged(int arg1); - void on_httpAuthCB_stateChanged(int arg1); void on_socksAuthCB_stateChanged(int arg1); @@ -116,8 +112,6 @@ class PreferencesWindow : public QDialog, private Ui::PreferencesWindow void on_darkTrayCB_stateChanged(int arg1); - void on_enablePACCB_stateChanged(int arg1); - void on_pacGoBtn_clicked(); void on_pacPortSB_valueChanged(int arg1); @@ -158,6 +152,12 @@ class PreferencesWindow : public QDialog, private Ui::PreferencesWindow void on_checkVCoreSettings_clicked(); + void on_httpGroupBox_clicked(bool checked); + + void on_socksGroupBox_clicked(bool checked); + + void on_pacGroupBox_clicked(bool checked); + private: void SetAutoStartButtonsState(bool isAutoStart); // Set ui parameters for a line; diff --git a/src/ui/w_PreferencesWindow.ui b/src/ui/w_PreferencesWindow.ui index 2487a16c..cb5c594f 100644 --- a/src/ui/w_PreferencesWindow.ui +++ b/src/ui/w_PreferencesWindow.ui @@ -9,1186 +9,1196 @@ 0 0 - 780 - 578 + 701 + 486 - - - 780 - 578 - - Preferences true - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - + + - - QTabWidget::Rounded - 0 - + - General + General Settings - - - - - - - UI Theme - - - - - - - - 200 - 0 - - - - - - - - Launch at Login - - - - - - - + + + + + QFrame::NoFrame + + + true + + + + + 0 + 0 + 649 + 442 + + + + + - Install - - - - - - - Remove - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - Theme Settings - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - - Enabled - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Enabled + UI Theme - - - Darkmode UI Icons - - - - - - - Darkmode Tray Icon - - - - - - - QFrame::Plain - - - 2 - - - Qt::Vertical - - - - - - - - - Language - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - zh-CN - - - - - en-US - - - - - - - - Log Level - - - - - - - - 0 - 0 - - - - - 150 - 0 - - - - - none - - - - - debug - - - - - info - - - - - warning - - - - - error - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - Auto Connect - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - - Config - - - - - - - Subscription - - - - - - - - + - 180 + 200 0 - - - - - - - - - QFrame::Plain - - - 2 - - - Qt::Vertical - - - - - - - - - Transparent Proxy - - - - - - - Enabled - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + - V2ray Settings - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - QFrame::Plain - - - 2 - - - Qt::Vertical - - - - - - - Core Executable Path - - - - - - - - - - Select - - - - - - - Select - - - - - - - + Launch at Login - - - Assets Directory Path - - - - - - - Check V2ray Core Settings - - - - - - - - - - - Qt::Vertical - - - - 20 - 183 - - - - - - - - - Inbound Settings - - - - - - - - Listening Address - - - - - - - 0.0.0.0 - - - - - - - Features - - - - - - - - - Qt::LeftToRight - - - HTTP - - - - - - - SOCKS - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Use PAC - - - - - - - Set System Proxy - - - - - - - - - - - - - SOCKS Settings - - - - - - Port - - - - - - - 1 - - - 65535 - - - 1081 - - - - - - - UDP Support - - - - - - - - - Enabled - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - IP: - - - - - - - 127.0.0.1 - - - - - - - - - Authentication - - - - - - - Enabled - - - - - - - Username - - - - - - - user - - - - - - - Password - - - - - - - pass - - - - - - - - - - HTTP Settings - - - - - - Port - - - - - - - 1 - - - 65535 - - - 18001 - - - - - - - Authentication - - - - - - - Enabled - - - - - - - Username - - - - - - - user - - - - - - - Password - - - - - - - pass - - - - - - - - - - PAC Settings - - - - - - Port - - - - - - - 1 - - - 65535 - - - 8088 - - - - - - - Local IP for PAC - - - - - - - 127.0.0.1 - - - - - - - Use Proxy - - - - - - + + + - HTTP - - - - - SOCKS - - - - - - - - Import GFWList - - - - - - - - - - Mirror: Gitlab - - - - - Github - - - - - Mirror: Pagure - - - - - Mirror: Repo.or.cz - - - - - Mirror: Bitbucket - - - - - Mirror: TuxFamily - - - - - GFWList File - - - - - - - - Go - - - - - - - - - Edit PAC - - - - - - - Open PAC Folder - - - - - - - PAC Access Path - - - - - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Connection Settings - - - - - - General Connection Settings - - - - - - Enable Proxy - - - - - - - Enabled - - - - - - - Bypass Chinese Mainland - - - - - - - Enabled - - - - - - - API Port - - - - - - - - 100 - 0 - - - - 1024 - - - 65535 - - - 15934 - - - - - - - Use Local DNS - - - - - - - Enabled - - - - - - - Custom DNS List - - - - - - - - - - - - - Forward Proxy - - - - - - Only simple config is supported. - - - - - - - - - Status - - - - - - - Enabled - - - - - - - - - - - - Type + Install - - - - - HTTP - - - - - Socks - - - - - - + + - Host Address + Remove - - + + + + Qt::Horizontal + + + + 40 + 20 + + + - - + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + - Port + Theme Settings - - - - 1 + + + + Qt::Vertical - - 65535 + + + 0 + 0 + - - 8000 - - + - - - - Authentication - - - - - + + + + + + Enabled - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - Username + Enabled - - - - - + + - Password + Darkmode UI Icons - - + + + + Darkmode Tray Icon + + + + + + + QFrame::Plain + + + 2 + + + Qt::Vertical + + - - - + + + + + Language + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + zh-CN + + + + + en-US + + + + + + + + Log Level + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + + none + + + + + debug + + + + + info + + + + + warning + + + + + error + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + Auto Connect + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + Config + + + + + + + Subscription + + + + + + + + + + + 180 + 0 + + + + + + + + + + + + + QFrame::Plain + + + 2 + + + Qt::Vertical + + + + + + + + + Transparent Proxy + + + + + + + Enabled + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + V2ray Settings + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + QFrame::Plain + + + 2 + + + Qt::Vertical + + + + + + + Core Executable Path + + + + + + + + + + Select + + + + + + + Select + + + + + + + + + + + + + + Assets Directory Path + + + + + + + Check V2ray Core Settings + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - - - - Qt::Vertical - - - - 20 - 40 - - - - - + + + Inbound Settings + + + + + + QFrame::NoFrame + + + true + + + + + 0 + 0 + 649 + 607 + + + + + + + + + Listening Address + + + + + + + 0.0.0.0 + + + + + + + Set System Proxy + + + + + + + Set System Proxy + + + + + + + + + + + SOCKS Settings + + + true + + + false + + + + + + Port + + + + + + + 1 + + + 65535 + + + 1081 + + + + + + + UDP Support + + + + + + + Enabled + + + + + + + UDP Local IP + + + + + + + 127.0.0.1 + + + + + + + Authentication + + + + + + + Enabled + + + + + + + Username + + + + + + + user + + + + + + + Password + + + + + + + pass + + + + + + + + + + HTTP Settings + + + true + + + false + + + + + + Port + + + + + + + 1 + + + 65535 + + + 18001 + + + + + + + Authentication + + + + + + + Enabled + + + + + + + Username + + + + + + + user + + + + + + + Password + + + + + + + pass + + + + + + + + + + + + PAC Settings + + + true + + + true + + + + + + + true + + + + The system proxy will be configured to use the PAC instead of HTTP and SOCKS. + + + + + + + Port + + + + + + + 1 + + + 65535 + + + 8088 + + + + + + + Local IP for PAC + + + + + + + 127.0.0.1 + + + + + + + Use Proxy + + + + + + + + HTTP + + + + + SOCKS + + + + + + + + Import GFWList + + + + + + + + + + Mirror: Gitlab + + + + + Github + + + + + Mirror: Pagure + + + + + Mirror: Repo.or.cz + + + + + Mirror: Bitbucket + + + + + Mirror: TuxFamily + + + + + GFWList File + + + + + + + + Go + + + + + + + + + Edit PAC + + + + + + + Open PAC Folder + + + + + + + PAC Access Path + + + + + + + IBeamCursor + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Connection Settings + + + + + + + + General Connection Settings + + + + + + Enable Proxy + + + + + + + Enabled + + + + + + + Bypass Chinese Mainland + + + + + + + Enabled + + + + + + + API Port + + + + + + + + 100 + 0 + + + + 1024 + + + 65535 + + + 15934 + + + + + + + Use Local DNS + + + + + + + Enabled + + + + + + + Custom DNS List + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Forward Proxy + + + + + + Only simple config is supported. + + + + + + + + + Status + + + + + + + Enabled + + + + + + + + + + + + Type + + + + + + + + HTTP + + + + + Socks + + + + + + + + Host Address + + + + + + + + + + Port + + + + + + + 1 + + + 65535 + + + 8000 + + + + + + + Authentication + + + + + + + Enabled + + + + + + + Username + + + + + + + + + + Password + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + true + Network Toolbar Settings - - - + + + - Apply Network Speed Bar UI Settings + You can config how the network speed toolbar looks like in this panel - + Items @@ -1333,9 +1343,58 @@ + + + + true + + + + 75 + true + true + + + + color: red + + + This feature is not stable and no documentation is provided, please use it at your own risk! + + + - - + + + + + + Content + + + + + + Content Type + + + + + + + + + + Text/Tag + + + + + + + + + @@ -1471,68 +1530,35 @@ - - - Content + + + Apply Network Speed Bar UI Settings - - - - - Content Type - - - - - - - - - - Text/Tag - - - - - - - + + + + Qt::Vertical + + + + 20 + 40 + + + + - - - - You can config how the network speed toolbar looks like in this panel - - - - - - - - 75 - true - true - - - - color: red - - - This feature is not stable enough and no documentation is provided, please use it as your own risk! - - - - + About - + @@ -1793,6 +1819,16 @@ p, li { white-space: pre-wrap; } + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + diff --git a/src/ui/w_RoutesEditor.cpp b/src/ui/w_RoutesEditor.cpp index d0c20e90..73b5d407 100644 --- a/src/ui/w_RoutesEditor.cpp +++ b/src/ui/w_RoutesEditor.cpp @@ -551,7 +551,7 @@ void RouteEditor::on_enableBalancerCB_stateChanged(int arg1) } } } else { - QvMessageBox(this, tr("Route Editor"), tr("To make this rule ready to use, you need to connect it to an outbound node.")); + QvMessageBoxWarn(this, tr("Route Editor"), tr("To make this rule ready to use, you need to connect it to an outbound node.")); } } void RouteEditor::on_addDefaultBtn_clicked() @@ -628,7 +628,7 @@ void RouteEditor::on_ruleEnableCB_stateChanged(int arg1) void RouteEditor::on_delBtn_clicked() { if (nodeScene->selectedNodes().empty()) { - QvMessageBox(this, tr("Remove Items"), tr("Please select a node from the graph to continue.")); + QvMessageBoxWarn(this, tr("Remove Items"), tr("Please select a node from the graph to continue.")); } auto firstNode = nodeScene->selectedNodes()[0]; @@ -677,7 +677,7 @@ void RouteEditor::on_delBtn_clicked() void RouteEditor::on_editBtn_clicked() { if (nodeScene->selectedNodes().empty()) { - QvMessageBox(this, tr("Edit Inbound/Outbound"), tr("Please select a node from the graph to continue.")); + QvMessageBoxWarn(this, tr("Edit Inbound/Outbound"), tr("Please select a node from the graph to continue.")); } auto firstNode = nodeScene->selectedNodes()[0]; @@ -692,7 +692,7 @@ void RouteEditor::on_editBtn_clicked() int _code; if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") { - QvMessageBox(this, tr("Cannot Edit"), tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" + + QvMessageBoxWarn(this, tr("Cannot Edit"), tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" + tr("We will launch Json Editor instead.")); statusLabel->setText(tr("Opening JSON editor")); JsonEditor *w = new JsonEditor(_in, this); @@ -726,7 +726,7 @@ void RouteEditor::on_editBtn_clicked() int _code; if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks") { - QvMessageBox(this, tr("Unsupported Outbound Type"), + QvMessageBoxWarn(this, tr("Unsupported Outbound Type"), tr("This outbound entry is not supported by the GUI editor.") + NEWLINE + tr("We will launch Json Editor instead.")); JsonEditor w(_out, this); diff --git a/src/ui/w_RoutesEditor_extra.cpp b/src/ui/w_RoutesEditor_extra.cpp index 7243056c..c72f44a2 100644 --- a/src/ui/w_RoutesEditor_extra.cpp +++ b/src/ui/w_RoutesEditor_extra.cpp @@ -68,7 +68,7 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString &originalTag case RENAME_RULE: if (rules.contains(originalTag) && ruleNodes.contains(originalTag)) { if (rules.contains(newTag) && rules.contains(newTag)) { - QvMessageBox(this, tr("Rename tags"), tr("The new tag has been used, please suggest another.")); + QvMessageBoxWarn(this, tr("Rename tags"), tr("The new tag has been used, please suggest another.")); return; } @@ -103,7 +103,7 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString &originalTag case RENAME_OUTBOUND: if (outbounds.contains(originalTag) && outboundNodes.contains(originalTag)) { if (outbounds.contains(newTag) && outboundNodes.contains(newTag)) { - QvMessageBox(this, tr("Rename tags"), tr("The new tag has been used, please suggest another.")); + QvMessageBoxWarn(this, tr("Rename tags"), tr("The new tag has been used, please suggest another.")); return; } @@ -131,7 +131,7 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString &originalTag case RENAME_INBOUND: if (inbounds.contains(originalTag) && inboundNodes.contains(originalTag)) { if (inbounds.contains(newTag) && inboundNodes.contains(newTag)) { - QvMessageBox(this, tr("Rename tags"), tr("The new tag has been used, please suggest another.")); + QvMessageBoxWarn(this, tr("Rename tags"), tr("The new tag has been used, please suggest another.")); return; } diff --git a/src/ui/w_SubscriptionEditor.cpp b/src/ui/w_SubscriptionEditor.cpp index ea392cf4..e455b480 100644 --- a/src/ui/w_SubscriptionEditor.cpp +++ b/src/ui/w_SubscriptionEditor.cpp @@ -56,12 +56,12 @@ void SubscribeEditor::on_updateButton_clicked() bool canGo = true; if (newName.isEmpty() || !IsValidFileName(newName)) { - QvMessageBox(this, tr("Renaming a subscription"), tr("The subscription name is invalid, please try another.")); + QvMessageBoxWarn(this, tr("Renaming a subscription"), tr("The subscription name is invalid, please try another.")); canGo = false; } if (subscriptionList->findItems(newName, Qt::MatchExactly).count() > 0) { - QvMessageBox(this, tr("Renaming a subscription"), tr("New name of this subscription has been used already, please suggest another one")); + QvMessageBoxWarn(this, tr("Renaming a subscription"), tr("New name of this subscription has been used already, please suggest another one")); canGo = false; } @@ -73,7 +73,7 @@ void SubscribeEditor::on_updateButton_clicked() bool result = RenameSubscription(currentSubName, newName); if (!result) { - QvMessageBox(this, tr("Renaming a subscription"), tr("Failed to rename a subscription, this is an unknown error.")); + QvMessageBoxWarn(this, tr("Renaming a subscription"), tr("Failed to rename a subscription, this is an unknown error.")); return; } @@ -92,7 +92,7 @@ void SubscribeEditor::on_updateButton_clicked() SetGlobalConfig(conf); // This will set the name to the new name. LoadSubscriptionList(subscriptions); - QvMessageBox(this, tr("Renaming a subscription"), tr("Successfully renamed a subscription")); + QvMessageBoxInfo(this, tr("Renaming a subscription"), tr("Successfully renamed a subscription")); } subscriptions[currentSubName].updateInterval = newUpdateInterval; @@ -135,10 +135,11 @@ void SubscribeEditor::StartUpdateSubscription(const QString &subscriptionName) } subscriptions[subscriptionName].lastUpdated = system_clock::to_time_t(system_clock::now()); + lastUpdatedLabel->setText(timeToString(subscriptions[subscriptionName].lastUpdated)); isUpdateInProgress = false; } else { LOG(MODULE_NETWORK, "We have received an empty string from the URL.") - QvMessageBox(this, tr("Updating subscriptions"), tr("Failed to process the result from the upstream, please check your Url")); + QvMessageBoxWarn(this, tr("Updating subscriptions"), tr("Failed to process the result from the upstream, please check your Url.")); } this->setEnabled(true); @@ -161,8 +162,7 @@ void SubscribeEditor::on_removeSubsButton_clicked() auto conf = GetGlobalConfig(); if (conf.autoStartConfig.subscriptionName == name) { - conf.autoStartConfig.subscriptionName.clear(); - conf.autoStartConfig.connectionName.clear(); + conf.autoStartConfig = QvConfigIdentifier(); SetGlobalConfig(conf); } @@ -186,7 +186,7 @@ void SubscribeEditor::on_subscriptionList_currentRowChanged(int currentRow) subNameTxt->setText(currentSubName); subAddrTxt->setText(subscriptions[currentSubName].address); updateIntervalSB->setValue(subscriptions[currentSubName].updateInterval); - lastUpdatedLabel->setText(QString::fromStdString(timeToString(subscriptions[currentSubName].lastUpdated))); + lastUpdatedLabel->setText(timeToString(subscriptions[currentSubName].lastUpdated)); // connectionsList->clear(); auto _list = GetSubscriptionConnection(currentSubName); diff --git a/src/utils/QvHelpers.cpp b/src/utils/QvHelpers.cpp index eb387402..92f3ed45 100644 --- a/src/utils/QvHelpers.cpp +++ b/src/utils/QvHelpers.cpp @@ -175,14 +175,20 @@ namespace Qv2ray return GetFileList(dir).contains(fileName); } - void QvMessageBox(QWidget *parent, QString title, QString text) + void QvMessageBoxWarn(QWidget *parent, QString title, QString text) { QMessageBox::warning(parent, title, text, QMessageBox::Ok | QMessageBox::Default, 0); } + void QvMessageBoxInfo(QWidget *parent, QString title, QString text) + { + QMessageBox::information(parent, title, text, QMessageBox::Ok | QMessageBox::Default, 0); + } + + int QvMessageBoxAsk(QWidget *parent, QString title, QString text, QMessageBox::StandardButton extraButtons) { - return QMessageBox::information(parent, title, text, QMessageBox::Yes | QMessageBox::No | extraButtons); + return QMessageBox::question(parent, title, text, QMessageBox::Yes | QMessageBox::No | extraButtons); } QString FormatBytes(long long bytes) diff --git a/src/utils/QvHelpers.hpp b/src/utils/QvHelpers.hpp index 64a4ea33..ca1108e1 100644 --- a/src/utils/QvHelpers.hpp +++ b/src/utils/QvHelpers.hpp @@ -19,8 +19,11 @@ namespace Qv2ray list SplitLines_std(const QString &_string); bool FileExistsIn(QDir dir, QString fileName); const QString GenerateRandomString(int len = 12); - void QvMessageBox(QWidget *parent, QString title, QString text); + // + void QvMessageBoxWarn(QWidget *parent, QString title, QString text); + void QvMessageBoxInfo(QWidget *parent, QString title, QString text); int QvMessageBoxAsk(QWidget *parent, QString title, QString text, QMessageBox::StandardButton extraButtons = QMessageBox::NoButton); + // QString StringFromFile(QFile *source); bool StringToFile(const QString *text, QFile *target); QJsonObject JsonFromString(QString string); @@ -149,13 +152,13 @@ namespace Qv2ray return it != listOfElements.end(); } - inline std::string timeToString(const time_t &t) + inline QString timeToString(const time_t &t) { auto _tm = std::localtime(&t); char MY_TIME[128]; // using strftime to display time strftime(MY_TIME, sizeof(MY_TIME), "%x - %I:%M%p", _tm); - return MY_TIME; + return QString(MY_TIME); } }