fix: some fixes and refactors, fixed #253 and fixed #254

This commit is contained in:
Qv2ray Bot 2020-01-17 21:29:29 +08:00
parent ba8858dc77
commit 712059f503
20 changed files with 1382 additions and 1327 deletions

View File

@ -1 +1 @@
2830 2862

View File

@ -11,17 +11,20 @@ namespace Qv2ray
QvStartupOptions StartupOption = QvStartupOptions{}; QvStartupOptions StartupOption = QvStartupOptions{};
QvCommandArgParser::QvCommandArgParser() : QObject(), 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.setApplicationDescription(QObject::tr("Qv2ray - A cross-platform Qt frontend for V2ray."));
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); 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(noAPIOption);
parser.addOption(runAsRootOption); parser.addOption(runAsRootOption);
parser.addOption(debugOption); parser.addOption(debugOption);
parser.addOption(withToolbarOption);
helpOption = parser.addHelpOption(); helpOption = parser.addHelpOption();
versionOption = parser.addVersionOption(); versionOption = parser.addVersionOption();
} }
@ -51,6 +54,10 @@ namespace Qv2ray
StartupOption.debugLog = true; StartupOption.debugLog = true;
} }
if (parser.isSet(withToolbarOption)) {
StartupOption.enableToolbarPlguin = true;
}
return CommandLineOk; return CommandLineOk;
} }
} }

View File

@ -14,6 +14,8 @@ namespace Qv2ray
bool forceRunAsRootUser; bool forceRunAsRootUser;
/// Enable Debug Log. /// Enable Debug Log.
bool debugLog; bool debugLog;
/// Enable Network toolbar plugin.
bool enableToolbarPlguin;
}; };
enum CommandLineParseResult { enum CommandLineParseResult {
CommandLineOk, CommandLineOk,
@ -40,6 +42,7 @@ namespace Qv2ray
QCommandLineOption noAPIOption; QCommandLineOption noAPIOption;
QCommandLineOption runAsRootOption; QCommandLineOption runAsRootOption;
QCommandLineOption debugOption; QCommandLineOption debugOption;
QCommandLineOption withToolbarOption;
QCommandLineOption helpOption; QCommandLineOption helpOption;
QCommandLineOption versionOption; QCommandLineOption versionOption;
}; };

View File

@ -100,18 +100,18 @@ namespace Qv2ray
if (!process.waitForFinished(1000) && process.exitCode() != 0) { if (!process.waitForFinished(1000) && process.exitCode() != 0) {
LOG(MODULE_VCORE, "V2ray core failed with an exit code: " + QSTRN(process.exitCode())) 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; return false;
} else if (process.exitCode() != 0) { } else if (process.exitCode() != 0) {
QString output = QString(process.readAllStandardOutput()); 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; return false;
} else { } else {
DEBUG(MODULE_VCORE, "Config file check passed.") DEBUG(MODULE_VCORE, "Config file check passed.")
return true; return true;
} }
} else { } else {
QvMessageBox(nullptr, tr("Cannot start v2ray"), QvMessageBoxWarn(nullptr, tr("Cannot start v2ray"),
tr("V2ray core settings is incorrect.") + NEWLINE + NEWLINE + tr("V2ray core settings is incorrect.") + NEWLINE + NEWLINE +
tr("The error is: ") + NEWLINE + v2rayCheckResult); tr("The error is: ") + NEWLINE + v2rayCheckResult);
return false; return false;
@ -235,7 +235,7 @@ namespace Qv2ray
if (apiFailedCounter == QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD) { if (apiFailedCounter == QV2RAY_API_CALL_FAILEDCHECK_THRESHOLD) {
LOG(MODULE_VCORE, "API call failure threshold reached, cancelling further API aclls.") 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(); transferData.clear();
transferSpeed.clear(); transferSpeed.clear();
apiFailedCounter++; apiFailedCounter++;

View File

@ -40,7 +40,7 @@ namespace Qv2ray
LOG(MODULE_PROXY, "Started PAC listener") LOG(MODULE_PROXY, "Started PAC listener")
} else { } else {
LOG(MODULE_PROXY, "Failed to listen on port " + QSTRN(port) + ", please verify the permission.") 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"));
} }
} }

View File

@ -80,7 +80,7 @@ bool verifyConfigAvaliability(QString path, bool checkExistingConfig)
} catch (...) { } catch (...) {
LOG(MODULE_CONFIG, "Exception raised when checking config: " + configFile.fileName()) LOG(MODULE_CONFIG, "Exception raised when checking config: " + configFile.fileName())
//LOG(MODULE_INIT, e->what()) //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; return false;
} }
} else return true; } else return true;
@ -144,7 +144,7 @@ bool initialiseQv2ray()
// Otherwise Qv2ray would have loaded this config already instead of notifying to // Otherwise Qv2ray would have loaded this config already instead of notifying to
// create a new config in this folder. // create a new config in this folder.
LOG(MODULE_INIT, "This should not occur: Qv2ray config exists but failed to load.") LOG(MODULE_INIT, "This should not occur: Qv2ray config exists but failed to load.")
QvMessageBox(nullptr, QObject::tr("Failed to initialise Qv2ray"), QvMessageBoxWarn(nullptr, QObject::tr("Failed to initialise Qv2ray"),
QObject::tr("Failed to determine the location of config file.") + NEWLINE + QObject::tr("Failed to determine the location of config file.") + NEWLINE +
QObject::tr("Qv2ray will now exit.") + NEWLINE + QObject::tr("Qv2ray will now exit.") + NEWLINE +
QObject::tr("Please report if you think it's a bug.")); QObject::tr("Please report if you think it's a bug."));
@ -165,7 +165,7 @@ bool initialiseQv2ray()
LOG(MODULE_INIT, "FATAL") LOG(MODULE_INIT, "FATAL")
LOG(MODULE_INIT, " ---> CANNOT find a proper place to store Qv2ray config files.") LOG(MODULE_INIT, " ---> CANNOT find a proper place to store Qv2ray config files.")
QString searchPath = Stringify(configFilePaths, NEWLINE); QString searchPath = Stringify(configFilePaths, NEWLINE);
QvMessageBox(nullptr, QObject::tr("Cannot Start Qv2ray"), QvMessageBoxWarn(nullptr, QObject::tr("Cannot Start Qv2ray"),
QObject::tr("Cannot find a place to store config files.") + NEWLINE + QObject::tr("Cannot find a place to store config files.") + NEWLINE +
QObject::tr("Qv2ray has searched these paths below:") + QObject::tr("Qv2ray has searched these paths below:") +
NEWLINE + NEWLINE + searchPath + NEWLINE + NEWLINE + NEWLINE + searchPath + NEWLINE +
@ -186,6 +186,17 @@ bool initialiseQv2ray()
int main(int argc, char *argv[]) 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 // parse the command line before starting as a Qt application
{ {
std::unique_ptr<QCoreApplication> consoleApp(new QCoreApplication(argc, argv)); std::unique_ptr<QCoreApplication> 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); SingleApplication _qApp(argc, argv, false, SingleApplication::Mode::User | SingleApplication::Mode::ExcludeAppPath | SingleApplication::Mode::ExcludeAppVersion);
// Early initialisation // 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 LOG("LICENCE", NEWLINE "This program comes with ABSOLUTELY NO WARRANTY." NEWLINE
"This is free software, and you are welcome to redistribute it" NEWLINE "This is free software, and you are welcome to redistribute it" NEWLINE
"under certain conditions." NEWLINE NEWLINE "under certain conditions." NEWLINE NEWLINE
@ -287,7 +287,7 @@ int main(int argc, char *argv[])
if (langs.empty()) { if (langs.empty()) {
LOG(MODULE_INIT, "FAILED to find any translations. THIS IS A BUILD ERROR.") 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 { } else {
for (auto lang : langs) { for (auto lang : langs) {
LOG(MODULE_INIT, "Found Translator: " + lang) LOG(MODULE_INIT, "Found Translator: " + lang)
@ -306,7 +306,7 @@ int main(int argc, char *argv[])
if (confVersion > QV2RAY_CONFIG_VERSION) { if (confVersion > QV2RAY_CONFIG_VERSION) {
// Config version is larger than the current version... // Config version is larger than the current version...
// This is rare but it may happen.... // This is rare but it may happen....
QvMessageBox(nullptr, QObject::tr("Qv2ray Cannot Continue"), 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("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("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("Or submit a new issue if you think this is an error.") + NEWLINE + NEWLINE +
@ -336,11 +336,10 @@ int main(int argc, char *argv[])
} else { } else {
// Do not translate these..... // Do not translate these.....
// If a translator fails to load, pop up a message. // If a translator fails to load, pop up a message.
QvMessageBox( QvMessageBoxWarn(
nullptr, "Translation Failed", nullptr, "Translation Failed",
"Cannot load translation for " + confObject.uiConfig.language + ", English is now used.\r\n\r\n" "Cannot load translation for " + confObject.uiConfig.language + ", English is now used." + NEWLINE + NEWLINE +
"Please go to Preferences Window to change or Report a Bug at: \r\n" "Please go to Preferences Window to change language or open an Issue");
"https://github.com/lhy0403/Qv2ray/issues/new");
} }
// Let's save the config. // Let's save the config.
@ -354,14 +353,12 @@ int main(int argc, char *argv[])
if (!QSslSocket::supportsSsl()) { if (!QSslSocket::supportsSsl()) {
LOG(MODULE_NETWORK, "Required OpenSSL version: " + osslReqVersion) LOG(MODULE_NETWORK, "Required OpenSSL version: " + osslReqVersion)
LOG(MODULE_NETWORK, "OpenSSL library MISSING, Quitting.") LOG(MODULE_NETWORK, "OpenSSL library MISSING, Quitting.")
QvMessageBox(nullptr, QObject::tr("DependencyMissing"), QvMessageBoxWarn(nullptr, QObject::tr("Dependency Missing"),
QObject::tr("Cannot find openssl libs") + "\r\n" + QObject::tr("Cannot find openssl libs") + NEWLINE +
QObject::tr("This could be caused by a missing of `openssl` package in your system. Or an AppImage issue.") + "\r\n" + QObject::tr("This could be caused by a missing of `openssl` package in your system.") + NEWLINE +
QObject::tr("If you are using AppImage, please report a bug.") + "\r\n\r\n" + QObject::tr("If you are using an AppImage from Github Action, please report a bug.") + NEWLINE + NEWLINE +
QObject::tr("Please refer to Github Issue #65 to check for solutions.") + "\r\n" + QObject::tr("Technical Details") + NEWLINE +
QObject::tr("Github Issue Link: ") + "https://github.com/lhy0403/Qv2ray/issues/65" + "\r\n\r\n" + "OSsl.Rq.V=" + osslReqVersion + NEWLINE +
QObject::tr("Technical Details") + "\r\n" +
"OSsl.Rq.V=" + osslReqVersion + "\r\n" +
"OSsl.Cr.V=" + osslCurVersion); "OSsl.Cr.V=" + osslCurVersion);
return -3; return -3;
} }

View File

@ -68,11 +68,11 @@ void ConfigExporter::on_saveBtn_clicked()
void ConfigExporter::on_copyImageBtn_clicked() void ConfigExporter::on_copyImageBtn_clicked()
{ {
QGuiApplication::clipboard()->setImage(image); 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() void ConfigExporter::on_copyVMessBtn_clicked()
{ {
QGuiApplication::clipboard()->setText(message); 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."));
} }

View File

@ -52,7 +52,7 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked()
if (str.trimmed().isEmpty()) { if (str.trimmed().isEmpty()) {
LOG(MODULE_UI, "Cannot decode QR Code from an image, size: h=" + QSTRN(pix.width()) + ", v=" + QSTRN(pix.height())) 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 { } else {
vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE); vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE);
} }
@ -71,7 +71,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
QString path = fileLineTxt->text(); QString path = fileLineTxt->text();
if (!V2rayKernelInstance::ValidateConfig(path)) { 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; return;
} }
@ -120,12 +120,6 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
break; break;
} }
case 2: {
QvMessageBox(this, tr("TODO"), tr("TODO"));
// Subscription link.
break;
}
} }
accept(); accept();
@ -143,7 +137,7 @@ void ImportConfigWindow::on_selectImageBtn_clicked()
auto str = QZXing().decodeImage(QImage::fromData(buf)); auto str = QZXing().decodeImage(QImage::fromData(buf));
if (str.isEmpty()) { 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; return;
} else { } else {
vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE); vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE);
@ -178,7 +172,7 @@ void ImportConfigWindow::on_editFileBtn_clicked()
QFile file(fileLineTxt->text()); QFile file(fileLineTxt->text());
if (!file.exists()) { 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; return;
} }
@ -204,7 +198,7 @@ void ImportConfigWindow::on_editFileBtn_clicked()
bool result = StringToFile(&str, &file); bool result = StringToFile(&str, &file);
if (!result) { 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 { } else {
LOG(MODULE_FILE, "Canceled saving a file.") LOG(MODULE_FILE, "Canceled saving a file.")

View File

@ -24,7 +24,7 @@ InboundEditor::InboundEditor(INBOUND root, QWidget *parent) :
} else { } else {
if (!root["protocol"].toString().isEmpty()) { if (!root["protocol"].toString().isEmpty()) {
LOG(MODULE_UI, "Unsupported inbound type: " + inboundType) 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); tr("Inbound: ") + inboundType);
} else { } else {
LOG(MODULE_UI, "Creating new inbound config") 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?")); //QvMessageBox(this, tr("Removing a user"), tr("No user has been removed. Why?"));
} else { } 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(); auto _user = list[i].toObject();
if (_user["user"].toString() == user) { 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; return;
} }
} }
@ -247,7 +247,7 @@ void InboundEditor::on_socksRemoveUserBtn_clicked()
} }
} }
} else { } 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(); auto _user = list[i].toObject();
if (_user["user"].toString() == user) { 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; return;
} }
} }

View File

@ -15,7 +15,7 @@ JsonEditor::JsonEditor(QJsonObject rootObject, QWidget *parent) :
jsonTree->setModel(&model); jsonTree->setModel(&model);
model.loadJson(QJsonDocument(rootObject).toJson()); model.loadJson(QJsonDocument(rootObject).toJson());
} else { } 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)); jsonEditor->setText(JsonToString(rootObject));
@ -29,7 +29,7 @@ QJsonObject JsonEditor::OpenEditor()
auto string = jsonEditor->toPlainText(); auto string = jsonEditor->toPlainText();
while (resultCode == QDialog::Accepted && !VerifyJsonString(string).isEmpty()) { 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(); resultCode = this->exec();
string = jsonEditor->toPlainText(); string = jsonEditor->toPlainText();
} }
@ -69,6 +69,6 @@ void JsonEditor::on_formatJsonBtn_clicked()
jsonEditor->setPlainText(JsonToString(JsonFromString(string))); jsonEditor->setPlainText(JsonToString(JsonFromString(string)));
} else { } else {
RED(jsonEditor) 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"));
} }
} }

View File

@ -50,7 +50,7 @@
#define SUBSCRIPTION_CONFIG_MODIFY_DENY(_item_) \ #define SUBSCRIPTION_CONFIG_MODIFY_DENY(_item_) \
if (!CheckConfigType(_item_, REGULAR)) { \ 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; \ return; \
} \ } \
@ -230,7 +230,12 @@ MainWindow::MainWindow(QWidget *parent):
connect(requestHelper, &QvHttpRequestHelper::httpRequestFinished, this, &MainWindow::VersionUpdate); connect(requestHelper, &QvHttpRequestHelper::httpRequestFinished, this, &MainWindow::VersionUpdate);
requestHelper->get("https://api.github.com/repos/lhy0403/Qv2ray/releases/latest"); requestHelper->get("https://api.github.com/repos/lhy0403/Qv2ray/releases/latest");
if (StartupOption.enableToolbarPlguin) {
LOG(MODULE_UI, "Plugin daemon is enabled.")
StartProcessingPlugins(); StartProcessingPlugins();
}
CheckSubscriptionsUpdate(); CheckSubscriptionsUpdate();
} }
@ -281,7 +286,7 @@ void MainWindow::keyPressEvent(QKeyEvent *e)
void MainWindow::on_action_StartThis_triggered() void MainWindow::on_action_StartThis_triggered()
{ {
if (!IsSelectionConnectable) { 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; return;
} }
@ -435,7 +440,7 @@ void MainWindow::on_startButton_clicked()
// Check Selection // Check Selection
if (CurrentConnectionIdentifier.isEmpty()) { 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; return;
} }
@ -666,17 +671,17 @@ void MainWindow::on_connectionListWidget_itemChanged(QTreeWidgetItem *item, int)
bool canContinueRename = true; bool canContinueRename = true;
if (newIdentifier.connectionName.trimmed().isEmpty()) { 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; canContinueRename = false;
} }
if (currentConfig.configs.contains(newIdentifier.connectionName)) { 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; canContinueRename = false;
} }
if (!IsValidFileName(newIdentifier.connectionName + QV2RAY_CONFIG_FILE_EXTENSION)) { 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; canContinueRename = false;
} }
@ -767,7 +772,7 @@ void MainWindow::on_removeConfigButton_clicked()
currentConfig.configs.removeOne(conn.connectionName); currentConfig.configs.removeOne(conn.connectionName);
if (!RemoveConnection(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) { } else if (connData.configType == CONNECTION_SUBSCRIPTION) {
if (subscriptionRemovalCheckStatus == -1) { if (subscriptionRemovalCheckStatus == -1) {
@ -778,7 +783,7 @@ void MainWindow::on_removeConfigButton_clicked()
if (subscriptionRemovalCheckStatus == 1) { if (subscriptionRemovalCheckStatus == 1) {
if (!RemoveSubscriptionConnection(connData.subscriptionName, connData.connectionName)) { 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 { } else {
@ -816,7 +821,7 @@ void MainWindow::on_editConfigButton_clicked()
{ {
// Check if we have a connection selected... // Check if we have a connection selected...
if (!IsSelectionConnectable) { 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; return;
} }
@ -867,7 +872,7 @@ void MainWindow::on_action_RCM_ConvToComplex_triggered()
{ {
// Check if we have a connection selected... // Check if we have a connection selected...
if (!IsSelectionConnectable) { 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; return;
} }
@ -898,7 +903,7 @@ void MainWindow::on_action_RCM_EditJson_triggered()
{ {
// Check if we have a connection selected... // Check if we have a connection selected...
if (!IsSelectionConnectable) { 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; return;
} }
@ -976,7 +981,7 @@ void MainWindow::on_shareBtn_clicked()
ConfigExporter v(vmess, this); ConfigExporter v(vmess, this);
v.OpenExport(); v.OpenExport();
} else { } 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() void MainWindow::on_action_RCM_ShareQR_triggered()

View File

@ -48,7 +48,7 @@ void MainWindow::MWFindAndStartAutoConfig()
tray_RootMenu->actions()[0]->setText(tr("Show")); tray_RootMenu->actions()[0]->setText(tr("Show"));
on_startButton_clicked(); on_startButton_clicked();
} else { } 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 + name + NEWLINE + NEWLINE +
tr("Please reset the settings in Preference Window")); 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, "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 configured to use socks but socks is not enabled.")
LOG(MODULE_PROXY, " --> PAC is configuted to use http but http 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.")); NEWLINE + tr("Qv2ray will continue, but will not set system proxy."));
canSetSystemProxy = false; canSetSystemProxy = false;
} }
@ -109,7 +109,7 @@ void MainWindow::MWSetSystemProxy()
proxyAddress = "http://localhost"; proxyAddress = "http://localhost";
} else { } else {
LOG(MODULE_PROXY, "HTTP is not enabled, cannot set system proxy.") 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; canSetSystemProxy = false;
} }
} }
@ -153,7 +153,7 @@ bool MainWindow::MWtryStartConnection()
pacProxyString = "SOCKS5 " + pacIP + ":" + QSTRN(currentConfig.inboundConfig.socks_port); pacProxyString = "SOCKS5 " + pacIP + ":" + QSTRN(currentConfig.inboundConfig.socks_port);
} else { } else {
LOG(MODULE_UI, "PAC is using SOCKS, but it is not enabled") 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; canStartPAC = false;
} }
} else { } else {
@ -161,7 +161,7 @@ bool MainWindow::MWtryStartConnection()
pacProxyString = "PROXY " + pacIP + ":" + QSTRN(currentConfig.inboundConfig.http_port); pacProxyString = "PROXY " + pacIP + ":" + QSTRN(currentConfig.inboundConfig.http_port);
} else { } else {
LOG(MODULE_UI, "PAC is using HTTP, but it is not enabled") 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; canStartPAC = false;
} }
} }
@ -205,7 +205,7 @@ void MainWindow::MWTryPingConnection(const QvConfigIdentifier &alias)
int port = get<1>(info); int port = get<1>(info);
tcpingModel->StartPing(alias, host, port); tcpingModel->StartPing(alias, host, port);
} catch (...) { } 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()) { 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("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)); tr("These subscriptions are out-of-date: ") + NEWLINE + Stringify(updateList));
on_subsButton_clicked(); on_subsButton_clicked();

View File

@ -22,6 +22,15 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent),
setupUi(this); setupUi(this);
textBrowser->setHtml(StringFromFile(new QFile(":/assets/credit.html"))); textBrowser->setHtml(StringFromFile(new QFile(":/assets/credit.html")));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); 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 // We add locales
languageComboBox->clear(); languageComboBox->clear();
QDirIterator it(":/translations"); QDirIterator it(":/translations");
@ -55,17 +64,16 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent),
// //
listenIPTxt->setText(CurrentConfig.inboundConfig.listenip); listenIPTxt->setText(CurrentConfig.inboundConfig.listenip);
bool pacEnabled = CurrentConfig.inboundConfig.pacConfig.enablePAC; bool pacEnabled = CurrentConfig.inboundConfig.pacConfig.enablePAC;
enablePACCB->setChecked(pacEnabled); pacGroupBox->setChecked(pacEnabled);
setSysProxyCB->setChecked(CurrentConfig.inboundConfig.setSystemProxy); setSysProxyCB->setChecked(CurrentConfig.inboundConfig.setSystemProxy);
// //
// PAC // PAC
pacGroupBox->setEnabled(pacEnabled);
pacPortSB->setValue(CurrentConfig.inboundConfig.pacConfig.port); pacPortSB->setValue(CurrentConfig.inboundConfig.pacConfig.port);
pacProxyTxt->setText(CurrentConfig.inboundConfig.pacConfig.localIP); pacProxyTxt->setText(CurrentConfig.inboundConfig.pacConfig.localIP);
pacProxyCB->setCurrentIndex(CurrentConfig.inboundConfig.pacConfig.useSocksProxy ? 1 : 0); pacProxyCB->setCurrentIndex(CurrentConfig.inboundConfig.pacConfig.useSocksProxy ? 1 : 0);
// //
bool have_http = CurrentConfig.inboundConfig.useHTTP; bool have_http = CurrentConfig.inboundConfig.useHTTP;
httpCB->setChecked(have_http); httpGroupBox->setChecked(have_http);
httpPortLE->setValue(CurrentConfig.inboundConfig.http_port); httpPortLE->setValue(CurrentConfig.inboundConfig.http_port);
httpAuthCB->setChecked(CurrentConfig.inboundConfig.http_useAuth); httpAuthCB->setChecked(CurrentConfig.inboundConfig.http_useAuth);
// //
@ -74,11 +82,10 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent),
httpAuthPasswordTxt->setEnabled(CurrentConfig.inboundConfig.http_useAuth); httpAuthPasswordTxt->setEnabled(CurrentConfig.inboundConfig.http_useAuth);
httpAuthUsernameTxt->setText(CurrentConfig.inboundConfig.httpAccount.user); httpAuthUsernameTxt->setText(CurrentConfig.inboundConfig.httpAccount.user);
httpAuthPasswordTxt->setText(CurrentConfig.inboundConfig.httpAccount.pass); httpAuthPasswordTxt->setText(CurrentConfig.inboundConfig.httpAccount.pass);
httpGroupBox->setEnabled(have_http);
// //
// //
bool have_socks = CurrentConfig.inboundConfig.useSocks; bool have_socks = CurrentConfig.inboundConfig.useSocks;
socksCB->setChecked(have_socks); socksGroupBox->setChecked(have_socks);
socksPortLE->setValue(CurrentConfig.inboundConfig.socks_port); socksPortLE->setValue(CurrentConfig.inboundConfig.socks_port);
// //
socksAuthCB->setChecked(CurrentConfig.inboundConfig.socks_useAuth); socksAuthCB->setChecked(CurrentConfig.inboundConfig.socks_useAuth);
@ -125,7 +132,7 @@ PreferencesWindow::PreferencesWindow(QWidget *parent) : QDialog(parent),
nsBarPagesList->setCurrentRow(0); nsBarPagesList->setCurrentRow(0);
on_nsBarPagesList_currentRowChanged(0); on_nsBarPagesList_currentRowChanged(0);
} else { } else {
nsBarVerticalLayout->setEnabled(false); networkToolbarSettingsFrame->setEnabled(false);
nsBarLinesList->setEnabled(false); nsBarLinesList->setEnabled(false);
nsBarLineDelBTN->setEnabled(false); nsBarLineDelBTN->setEnabled(false);
nsBarLineAddBTN->setEnabled(false); nsBarLineAddBTN->setEnabled(false);
@ -181,7 +188,7 @@ void PreferencesWindow::on_buttonBox_accepted()
int hp = httpPortLE->text().toInt() ; int hp = httpPortLE->text().toInt() ;
if (!(sp == 0 || hp == 0) && sp == hp) { 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; return;
} }
@ -189,22 +196,6 @@ void PreferencesWindow::on_buttonBox_accepted()
emit s_reload_config(IsConnectionPropertyChanged); 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) void PreferencesWindow::on_httpAuthCB_stateChanged(int checked)
{ {
NEEDRESTART NEEDRESTART
@ -415,7 +406,7 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1)
on_vCorePathTxt_textEdited(QV2RAY_DEFAULT_VCORE_PATH); on_vCorePathTxt_textEdited(QV2RAY_DEFAULT_VCORE_PATH);
} else { } else {
LOG(MODULE_VCORE, "FAILED to copy v2ray files. Aborting.") LOG(MODULE_VCORE, "FAILED to copy v2ray files. Aborting.")
QvMessageBox(this, tr("Enable tProxy Support"), QvMessageBoxWarn(this, tr("Enable tProxy Support"),
tr("Qv2ray cannot copy one or both v2ray files from: ") + NEWLINE + NEWLINE + tr("Qv2ray cannot copy one or both v2ray files from: ") + NEWLINE + NEWLINE +
CurrentConfig.v2CorePath + NEWLINE + v2ctlPath + NEWLINE + NEWLINE + CurrentConfig.v2CorePath + NEWLINE + v2ctlPath + NEWLINE + NEWLINE +
tr("to this path: ") + NEWLINE + newPath); tr("to this path: ") + NEWLINE + newPath);
@ -431,7 +422,7 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1)
if (ret != 0) { if (ret != 0) {
LOG(MODULE_UI, "WARN: setcap exits with code: " + QSTRN(ret)) 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; CurrentConfig.tProxySupport = true;
@ -442,7 +433,7 @@ void PreferencesWindow::on_tProxyCheckBox_stateChanged(int arg1)
if (ret != 0) { if (ret != 0) {
LOG(MODULE_UI, "WARN: setcap exits with code: " + QSTRN(ret)) 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; CurrentConfig.tProxySupport = false;
@ -534,7 +525,7 @@ void PreferencesWindow::on_nsBarPageDelBTN_clicked()
nsBarLineAddBTN->setEnabled(false); nsBarLineAddBTN->setEnabled(false);
nsBarLineDelBTN->setEnabled(false); nsBarLineDelBTN->setEnabled(false);
nsBarLinesList->setEnabled(false); nsBarLinesList->setEnabled(false);
nsBarVerticalLayout->setEnabled(false); networkToolbarSettingsFrame->setEnabled(false);
nsBarPageYOffset->setEnabled(false); nsBarPageYOffset->setEnabled(false);
nsBarLinesList->clear(); nsBarLinesList->clear();
} }
@ -568,7 +559,7 @@ void PreferencesWindow::on_nsBarLineDelBTN_clicked()
CurrentBarLineId = 0; CurrentBarLineId = 0;
if (nsBarLinesList->count() <= 0) { if (nsBarLinesList->count() <= 0) {
nsBarVerticalLayout->setEnabled(false); networkToolbarSettingsFrame->setEnabled(false);
nsBarLineDelBTN->setEnabled(false); nsBarLineDelBTN->setEnabled(false);
} }
@ -597,7 +588,7 @@ void PreferencesWindow::on_nsBarPagesList_currentRowChanged(int currentRow)
nsBarLinesList->setCurrentRow(0); nsBarLinesList->setCurrentRow(0);
ShowLineParameters(CurrentBarLine); ShowLineParameters(CurrentBarLine);
} else { } else {
nsBarVerticalLayout->setEnabled(false); networkToolbarSettingsFrame->setEnabled(false);
} }
} }
@ -709,7 +700,7 @@ void PreferencesWindow::ShowLineParameters(QvBarLine &barLine)
nsBarContentCombo->setCurrentText(NetSpeedPluginMessages[barLine.ContentType]); nsBarContentCombo->setCurrentText(NetSpeedPluginMessages[barLine.ContentType]);
nsBarTagTxt->setText(barLine.Message); nsBarTagTxt->setText(barLine.Message);
finishedLoading = true; finishedLoading = true;
nsBarVerticalLayout->setEnabled(true); networkToolbarSettingsFrame->setEnabled(true);
} }
void PreferencesWindow::on_chooseColorBtn_clicked() void PreferencesWindow::on_chooseColorBtn_clicked()
@ -756,7 +747,7 @@ void PreferencesWindow::on_darkThemeCB_stateChanged(int arg1)
{ {
LOADINGCHECK LOADINGCHECK
CurrentConfig.uiConfig.useDarkTheme = arg1 == Qt::Checked; 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 #ifdef QV2RAY_USE_BUILTIN_DARKTHEME
themeCombo->setEnabled(arg1 != Qt::Checked); themeCombo->setEnabled(arg1 != Qt::Checked);
@ -774,15 +765,6 @@ void PreferencesWindow::on_darkTrayCB_stateChanged(int arg1)
CurrentConfig.uiConfig.useDarkTrayIcon = arg1 == Qt::Checked; 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() void PreferencesWindow::on_pacGoBtn_clicked()
{ {
LOADINGCHECK LOADINGCHECK
@ -833,7 +815,7 @@ void PreferencesWindow::on_pacGoBtn_clicked()
} }
LOG(MODULE_NETWORK, "Fetched: " + gfwLocation) 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); pacGoBtn->setEnabled(true);
gfwListCB->setEnabled(true); gfwListCB->setEnabled(true);
@ -909,7 +891,7 @@ void PreferencesWindow::on_installBootStart_clicked()
// If failed to set the status. // If failed to set the status.
if (!GetLaunchAtLoginStatus()) { 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()); SetAutoStartButtonsState(GetLaunchAtLoginStatus());
@ -921,7 +903,7 @@ void PreferencesWindow::on_removeBootStart_clicked()
// If that setting still present. // If that setting still present.
if (GetLaunchAtLoginStatus()) { 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()); SetAutoStartButtonsState(GetLaunchAtLoginStatus());
@ -998,9 +980,31 @@ void PreferencesWindow::on_checkVCoreSettings_clicked()
QString result; QString result;
if (!V2rayKernelInstance::ValidateKernel(vcorePath, vAssetsPath, &result)) { if (!V2rayKernelInstance::ValidateKernel(vcorePath, vAssetsPath, &result)) {
QvMessageBox(this, tr("V2ray Core Settings"), result); QvMessageBoxWarn(this, tr("V2ray Core Settings"), result);
} else { } else {
QvMessageBox(this, tr("V2ray Core Settings"), tr("V2ray path configuration check passed.") + NEWLINE + NEWLINE + QvMessageBoxInfo(this, tr("V2ray Core Settings"), tr("V2ray path configuration check passed.") + NEWLINE + NEWLINE +
tr("Current version of V2ray is: ") + NEWLINE + result); 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);
}

View File

@ -18,10 +18,6 @@ class PreferencesWindow : public QDialog, private Ui::PreferencesWindow
private slots: private slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
void on_httpCB_stateChanged(int arg1);
void on_socksCB_stateChanged(int arg1);
void on_httpAuthCB_stateChanged(int arg1); void on_httpAuthCB_stateChanged(int arg1);
void on_socksAuthCB_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_darkTrayCB_stateChanged(int arg1);
void on_enablePACCB_stateChanged(int arg1);
void on_pacGoBtn_clicked(); void on_pacGoBtn_clicked();
void on_pacPortSB_valueChanged(int arg1); void on_pacPortSB_valueChanged(int arg1);
@ -158,6 +152,12 @@ class PreferencesWindow : public QDialog, private Ui::PreferencesWindow
void on_checkVCoreSettings_clicked(); void on_checkVCoreSettings_clicked();
void on_httpGroupBox_clicked(bool checked);
void on_socksGroupBox_clicked(bool checked);
void on_pacGroupBox_clicked(bool checked);
private: private:
void SetAutoStartButtonsState(bool isAutoStart); void SetAutoStartButtonsState(bool isAutoStart);
// Set ui parameters for a line; // Set ui parameters for a line;

View File

@ -9,47 +9,44 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>780</width> <width>701</width>
<height>578</height> <height>486</height>
</rect> </rect>
</property> </property>
<property name="minimumSize">
<size>
<width>780</width>
<height>578</height>
</size>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>Preferences</string> <string>Preferences</string>
</property> </property>
<property name="modal"> <property name="modal">
<bool>true</bool> <bool>true</bool>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout_10">
<item row="2" column="0"> <item row="0" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tabWidgetPage1" native="true">
<attribute name="title"> <attribute name="title">
<string>General</string> <string>General Settings</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_7"> <layout class="QGridLayout" name="gridLayout_3">
<item> <item row="0" column="0">
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>649</width>
<height>442</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout_5"> <layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_35"> <widget class="QLabel" name="label_35">
@ -481,28 +478,48 @@
</item> </item>
</layout> </layout>
</item> </item>
</layout> <item row="8" column="1">
</item> <spacer name="verticalSpacer_11">
<item>
<spacer name="verticalSpacer_9">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>183</height> <height>40</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_3"> </widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabWidgetPage2" native="true">
<attribute name="title"> <attribute name="title">
<string>Inbound Settings</string> <string>Inbound Settings</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QScrollArea" name="scrollArea_2">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>649</width>
<height>607</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<layout class="QFormLayout" name="formLayout_4"> <layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0"> <item row="0" column="0">
@ -522,50 +539,11 @@
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_59"> <widget class="QLabel" name="label_59">
<property name="text"> <property name="text">
<string>Features</string> <string>Set System Proxy</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="httpCB">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>HTTP</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="socksCB">
<property name="text">
<string>SOCKS</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="enablePACCB">
<property name="text">
<string>Use PAC</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="setSysProxyCB"> <widget class="QCheckBox" name="setSysProxyCB">
<property name="text"> <property name="text">
<string>Set System Proxy</string> <string>Set System Proxy</string>
@ -574,15 +552,19 @@
</item> </item>
</layout> </layout>
</item> </item>
</layout>
</item>
<item> <item>
<layout class="QGridLayout" name="gridLayout_7"> <layout class="QHBoxLayout" name="horizontalLayout">
<item row="0" column="0"> <item>
<widget class="QGroupBox" name="socksGroupBox"> <widget class="QGroupBox" name="socksGroupBox">
<property name="title"> <property name="title">
<string>SOCKS Settings</string> <string>SOCKS Settings</string>
</property> </property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_2"> <layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
@ -612,79 +594,62 @@
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QCheckBox" name="socksUDPCB"> <widget class="QCheckBox" name="socksUDPCB">
<property name="text"> <property name="text">
<string>Enabled</string> <string>Enabled</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="2" column="0">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_25"> <widget class="QLabel" name="label_25">
<property name="text"> <property name="text">
<string>IP:</string> <string>UDP Local IP</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="2" column="1">
<widget class="QLineEdit" name="socksUDPIP"> <widget class="QLineEdit" name="socksUDPIP">
<property name="placeholderText"> <property name="placeholderText">
<string notr="true">127.0.0.1</string> <string notr="true">127.0.0.1</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item row="3" column="0">
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10"> <widget class="QLabel" name="label_10">
<property name="text"> <property name="text">
<string>Authentication</string> <string>Authentication</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QCheckBox" name="socksAuthCB"> <widget class="QCheckBox" name="socksAuthCB">
<property name="text"> <property name="text">
<string>Enabled</string> <string>Enabled</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_11"> <widget class="QLabel" name="label_11">
<property name="text"> <property name="text">
<string>Username</string> <string>Username</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QLineEdit" name="socksAuthUsernameTxt"> <widget class="QLineEdit" name="socksAuthUsernameTxt">
<property name="placeholderText"> <property name="placeholderText">
<string notr="true">user</string> <string notr="true">user</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_12"> <widget class="QLabel" name="label_12">
<property name="text"> <property name="text">
<string>Password</string> <string>Password</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="5" column="1">
<widget class="QLineEdit" name="socksAuthPasswordTxt"> <widget class="QLineEdit" name="socksAuthPasswordTxt">
<property name="placeholderText"> <property name="placeholderText">
<string notr="true">pass</string> <string notr="true">pass</string>
@ -694,11 +659,17 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item>
<widget class="QGroupBox" name="httpGroupBox"> <widget class="QGroupBox" name="httpGroupBox">
<property name="title"> <property name="title">
<string>HTTP Settings</string> <string>HTTP Settings</string>
</property> </property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_7"> <layout class="QFormLayout" name="formLayout_7">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
@ -765,20 +736,40 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="1" rowspan="2"> </layout>
</item>
<item>
<widget class="QGroupBox" name="pacGroupBox"> <widget class="QGroupBox" name="pacGroupBox">
<property name="title"> <property name="title">
<string>PAC Settings</string> <string>PAC Settings</string>
</property> </property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_11"> <layout class="QFormLayout" name="formLayout_11">
<item row="0" column="0"> <item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_74">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>The system proxy will be configured to use the PAC instead of HTTP and SOCKS.</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_57"> <widget class="QLabel" name="label_57">
<property name="text"> <property name="text">
<string>Port</string> <string>Port</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="1">
<widget class="QSpinBox" name="pacPortSB"> <widget class="QSpinBox" name="pacPortSB">
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
@ -791,28 +782,28 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_56"> <widget class="QLabel" name="label_56">
<property name="text"> <property name="text">
<string>Local IP for PAC</string> <string>Local IP for PAC</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QLineEdit" name="pacProxyTxt"> <widget class="QLineEdit" name="pacProxyTxt">
<property name="placeholderText"> <property name="placeholderText">
<string>127.0.0.1</string> <string>127.0.0.1</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_63"> <widget class="QLabel" name="label_63">
<property name="text"> <property name="text">
<string>Use Proxy</string> <string>Use Proxy</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QComboBox" name="pacProxyCB"> <widget class="QComboBox" name="pacProxyCB">
<item> <item>
<property name="text"> <property name="text">
@ -826,14 +817,14 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_58"> <widget class="QLabel" name="label_58">
<property name="text"> <property name="text">
<string>Import GFWList</string> <string>Import GFWList</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QComboBox" name="gfwListCB"> <widget class="QComboBox" name="gfwListCB">
@ -883,14 +874,14 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="4" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_62"> <widget class="QLabel" name="label_62">
<property name="text"> <property name="text">
<string>Edit PAC</string> <string>Edit PAC</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="5" column="1">
<widget class="QPushButton" name="pushButton"> <widget class="QPushButton" name="pushButton">
<property name="text"> <property name="text">
<string>Open PAC Folder</string> <string>Open PAC Folder</string>
@ -905,30 +896,21 @@
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="6" column="1">
<widget class="QLineEdit" name="pacListenAddrLabel"> <widget class="QLabel" name="pacListenAddrLabel">
<property name="readOnly"> <property name="cursor">
<bool>true</bool> <cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string/>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0">
<spacer name="verticalSpacer_11">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
</layout>
</item>
<item> <item>
<spacer name="verticalSpacer_10"> <spacer name="verticalSpacer_10">
<property name="orientation"> <property name="orientation">
@ -944,12 +926,18 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_4"> </widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabWidgetPage3" native="true">
<attribute name="title"> <attribute name="title">
<string>Connection Settings</string> <string>Connection Settings</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_4" rowstretch="0,0" columnstretch="6,4" rowminimumheight="0,1"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item row="0" column="0" rowspan="2"> <item>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
<string>General Connection Settings</string> <string>General Connection Settings</string>
@ -1036,7 +1024,24 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QGroupBox" name="formGroupBox"> <widget class="QGroupBox" name="formGroupBox">
<property name="title"> <property name="title">
<string>Forward Proxy</string> <string>Forward Proxy</string>
@ -1161,8 +1166,8 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer_14">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -1175,20 +1180,25 @@
</spacer> </spacer>
</item> </item>
</layout> </layout>
</item>
</layout>
</widget> </widget>
<widget class="QWidget" name="tab_2"> <widget class="QWidget" name="networkToolbarPage" native="true">
<property name="enabled">
<bool>true</bool>
</property>
<attribute name="title"> <attribute name="title">
<string>Network Toolbar Settings</string> <string>Network Toolbar Settings</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout">
<item row="4" column="1"> <item row="1" column="0" colspan="2">
<widget class="QPushButton" name="applyNSBarSettingsBtn"> <widget class="QLabel" name="label_33">
<property name="text"> <property name="text">
<string>Apply Network Speed Bar UI Settings</string> <string>You can config how the network speed toolbar looks like in this panel</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" rowspan="3"> <item row="3" column="0">
<widget class="QGroupBox" name="groupBox_6"> <widget class="QGroupBox" name="groupBox_6">
<property name="title"> <property name="title">
<string>Items</string> <string>Items</string>
@ -1333,9 +1343,58 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="networkToolbarInfoLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color: red</string>
</property>
<property name="text">
<string>This feature is not stable and no documentation is provided, please use it at your own risk!</string>
</property>
</widget>
</item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QFrame" name="nsBarVerticalLayout"> <widget class="QFrame" name="networkToolbarSettingsFrame">
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Content</string>
</property>
<layout class="QFormLayout" name="formLayout_9">
<item row="0" column="0">
<widget class="QLabel" name="label_44">
<property name="text">
<string>Content Type</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="nsBarContentCombo"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_31">
<property name="text">
<string>Text/Tag</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="nsBarTagTxt"/>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy"> <property name="sizePolicy">
@ -1471,68 +1530,35 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBox_5"> <widget class="QPushButton" name="applyNSBarSettingsBtn">
<property name="title">
<string>Content</string>
</property>
<layout class="QFormLayout" name="formLayout_9">
<item row="0" column="0">
<widget class="QLabel" name="label_44">
<property name="text"> <property name="text">
<string>Content Type</string> <string>Apply Network Speed Bar UI Settings</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item>
<widget class="QComboBox" name="nsBarContentCombo"/> <spacer name="verticalSpacer_9">
</item> <property name="orientation">
<item row="1" column="0"> <enum>Qt::Vertical</enum>
<widget class="QLabel" name="label_31">
<property name="text">
<string>Text/Tag</string>
</property> </property>
</widget> <property name="sizeHint" stdset="0">
</item> <size>
<item row="1" column="1"> <width>20</width>
<widget class="QLineEdit" name="nsBarTagTxt"/> <height>40</height>
</size>
</property>
</spacer>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> <widget class="QWidget" name="tabWidgetPage5" native="true">
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_33">
<property name="text">
<string>You can config how the network speed toolbar looks like in this panel</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_64">
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color: red</string>
</property>
<property name="text">
<string>This feature is not stable enough and no documentation is provided, please use it as your own risk!</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_5">
<attribute name="title"> <attribute name="title">
<string>About</string> <string>About</string>
</attribute> </attribute>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout_5">
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_5"> <layout class="QVBoxLayout" name="verticalLayout_5">
<item> <item>
@ -1793,6 +1819,16 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>

View File

@ -551,7 +551,7 @@ void RouteEditor::on_enableBalancerCB_stateChanged(int arg1)
} }
} }
} else { } 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() void RouteEditor::on_addDefaultBtn_clicked()
@ -628,7 +628,7 @@ void RouteEditor::on_ruleEnableCB_stateChanged(int arg1)
void RouteEditor::on_delBtn_clicked() void RouteEditor::on_delBtn_clicked()
{ {
if (nodeScene->selectedNodes().empty()) { 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]; auto firstNode = nodeScene->selectedNodes()[0];
@ -677,7 +677,7 @@ void RouteEditor::on_delBtn_clicked()
void RouteEditor::on_editBtn_clicked() void RouteEditor::on_editBtn_clicked()
{ {
if (nodeScene->selectedNodes().empty()) { 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]; auto firstNode = nodeScene->selectedNodes()[0];
@ -692,7 +692,7 @@ void RouteEditor::on_editBtn_clicked()
int _code; int _code;
if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") { 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.")); tr("We will launch Json Editor instead."));
statusLabel->setText(tr("Opening JSON editor")); statusLabel->setText(tr("Opening JSON editor"));
JsonEditor *w = new JsonEditor(_in, this); JsonEditor *w = new JsonEditor(_in, this);
@ -726,7 +726,7 @@ void RouteEditor::on_editBtn_clicked()
int _code; int _code;
if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks") { 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("This outbound entry is not supported by the GUI editor.") + NEWLINE +
tr("We will launch Json Editor instead.")); tr("We will launch Json Editor instead."));
JsonEditor w(_out, this); JsonEditor w(_out, this);

View File

@ -68,7 +68,7 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString &originalTag
case RENAME_RULE: case RENAME_RULE:
if (rules.contains(originalTag) && ruleNodes.contains(originalTag)) { if (rules.contains(originalTag) && ruleNodes.contains(originalTag)) {
if (rules.contains(newTag) && rules.contains(newTag)) { 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; return;
} }
@ -103,7 +103,7 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString &originalTag
case RENAME_OUTBOUND: case RENAME_OUTBOUND:
if (outbounds.contains(originalTag) && outboundNodes.contains(originalTag)) { if (outbounds.contains(originalTag) && outboundNodes.contains(originalTag)) {
if (outbounds.contains(newTag) && outboundNodes.contains(newTag)) { 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; return;
} }
@ -131,7 +131,7 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString &originalTag
case RENAME_INBOUND: case RENAME_INBOUND:
if (inbounds.contains(originalTag) && inboundNodes.contains(originalTag)) { if (inbounds.contains(originalTag) && inboundNodes.contains(originalTag)) {
if (inbounds.contains(newTag) && inboundNodes.contains(newTag)) { 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; return;
} }

View File

@ -56,12 +56,12 @@ void SubscribeEditor::on_updateButton_clicked()
bool canGo = true; bool canGo = true;
if (newName.isEmpty() || !IsValidFileName(newName)) { 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; canGo = false;
} }
if (subscriptionList->findItems(newName, Qt::MatchExactly).count() > 0) { 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; canGo = false;
} }
@ -73,7 +73,7 @@ void SubscribeEditor::on_updateButton_clicked()
bool result = RenameSubscription(currentSubName, newName); bool result = RenameSubscription(currentSubName, newName);
if (!result) { 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; return;
} }
@ -92,7 +92,7 @@ void SubscribeEditor::on_updateButton_clicked()
SetGlobalConfig(conf); SetGlobalConfig(conf);
// This will set the name to the new name. // This will set the name to the new name.
LoadSubscriptionList(subscriptions); 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; 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()); subscriptions[subscriptionName].lastUpdated = system_clock::to_time_t(system_clock::now());
lastUpdatedLabel->setText(timeToString(subscriptions[subscriptionName].lastUpdated));
isUpdateInProgress = false; isUpdateInProgress = false;
} else { } else {
LOG(MODULE_NETWORK, "We have received an empty string from the URL.") 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); this->setEnabled(true);
@ -161,8 +162,7 @@ void SubscribeEditor::on_removeSubsButton_clicked()
auto conf = GetGlobalConfig(); auto conf = GetGlobalConfig();
if (conf.autoStartConfig.subscriptionName == name) { if (conf.autoStartConfig.subscriptionName == name) {
conf.autoStartConfig.subscriptionName.clear(); conf.autoStartConfig = QvConfigIdentifier();
conf.autoStartConfig.connectionName.clear();
SetGlobalConfig(conf); SetGlobalConfig(conf);
} }
@ -186,7 +186,7 @@ void SubscribeEditor::on_subscriptionList_currentRowChanged(int currentRow)
subNameTxt->setText(currentSubName); subNameTxt->setText(currentSubName);
subAddrTxt->setText(subscriptions[currentSubName].address); subAddrTxt->setText(subscriptions[currentSubName].address);
updateIntervalSB->setValue(subscriptions[currentSubName].updateInterval); updateIntervalSB->setValue(subscriptions[currentSubName].updateInterval);
lastUpdatedLabel->setText(QString::fromStdString(timeToString(subscriptions[currentSubName].lastUpdated))); lastUpdatedLabel->setText(timeToString(subscriptions[currentSubName].lastUpdated));
// //
connectionsList->clear(); connectionsList->clear();
auto _list = GetSubscriptionConnection(currentSubName); auto _list = GetSubscriptionConnection(currentSubName);

View File

@ -175,14 +175,20 @@ namespace Qv2ray
return GetFileList(dir).contains(fileName); 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); 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) 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) QString FormatBytes(long long bytes)

View File

@ -19,8 +19,11 @@ namespace Qv2ray
list<string> SplitLines_std(const QString &_string); list<string> SplitLines_std(const QString &_string);
bool FileExistsIn(QDir dir, QString fileName); bool FileExistsIn(QDir dir, QString fileName);
const QString GenerateRandomString(int len = 12); 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); int QvMessageBoxAsk(QWidget *parent, QString title, QString text, QMessageBox::StandardButton extraButtons = QMessageBox::NoButton);
//
QString StringFromFile(QFile *source); QString StringFromFile(QFile *source);
bool StringToFile(const QString *text, QFile *target); bool StringToFile(const QString *text, QFile *target);
QJsonObject JsonFromString(QString string); QJsonObject JsonFromString(QString string);
@ -149,13 +152,13 @@ namespace Qv2ray
return it != listOfElements.end(); return it != listOfElements.end();
} }
inline std::string timeToString(const time_t &t) inline QString timeToString(const time_t &t)
{ {
auto _tm = std::localtime(&t); auto _tm = std::localtime(&t);
char MY_TIME[128]; char MY_TIME[128];
// using strftime to display time // using strftime to display time
strftime(MY_TIME, sizeof(MY_TIME), "%x - %I:%M%p", _tm); strftime(MY_TIME, sizeof(MY_TIME), "%x - %I:%M%p", _tm);
return MY_TIME; return QString(MY_TIME);
} }
} }