Qv2ray/src/ui/w_PrefrencesWindow.cpp
2019-12-02 09:50:05 +08:00

855 lines
29 KiB
C++

#include <QFileDialog>
#include <QColorDialog>
#include <QStyleFactory>
#include <QStyle>
#include <QDesktopServices>
#include "QvUtils.hpp"
#include "QvCoreInteractions.hpp"
#include "QvNetSpeedPlugin.hpp"
#include "w_PrefrencesWindow.hpp"
#include "QvHTTPRequestHelper.hpp"
#define LOADINGCHECK if(!finishedLoading) return;
#define NEEDRESTART if(finishedLoading) IsConnectionPropertyChanged = true;
PrefrencesWindow::PrefrencesWindow(QWidget *parent) : QDialog(parent),
CurrentConfig(),
ui(new Ui::PrefrencesWindow)
{
setupUi(this);
// We add locales
languageComboBox->clear();
QDirIterator it(":/translations");
while (it.hasNext()) {
languageComboBox->addItem(it.next().split("/").last().split(".").first());
}
//
nsBarContentCombo->addItems(NetSpeedPluginMessages.values());
themeCombo->addItems(QStyleFactory::keys());
//
qvVersion->setText(QV2RAY_VERSION_STRING);
qvBuildTime->setText(__DATE__ " " __TIME__);
CurrentConfig = GetGlobalConfig();
//
themeCombo->setCurrentText(QSTRING(CurrentConfig.uiConfig.theme));
darkThemeCB->setChecked(CurrentConfig.uiConfig.useDarkTheme);
darkTrayCB->setChecked(CurrentConfig.uiConfig.useDarkTrayIcon);
#if QV2RAY_USE_BUILTIN_DARKTHEME
// If we use built in theme, it should always be fusion.
themeCombo->setEnabled(!CurrentConfig.uiConfig.useDarkTheme);
darkThemeLabel->setText(tr("Use Dark Theme"));
#endif
languageComboBox->setCurrentText(QSTRING(CurrentConfig.uiConfig.language));
logLevelComboBox->setCurrentIndex(CurrentConfig.logLevel);
tProxyCheckBox->setChecked(CurrentConfig.tProxySupport);
//
//
listenIPTxt->setText(QSTRING(CurrentConfig.inboundConfig.listenip));
bool pacEnabled = CurrentConfig.inboundConfig.pacConfig.enablePAC;
enablePACCB->setChecked(pacEnabled);
setSysProxyCB->setChecked(CurrentConfig.inboundConfig.setSystemProxy);
//
// PAC
pacGroupBox->setEnabled(pacEnabled);
pacPortSB->setValue(CurrentConfig.inboundConfig.pacConfig.port);
pacProxyTxt->setText(QSTRING(CurrentConfig.inboundConfig.pacConfig.proxyIP));
pacProxyCB->setCurrentIndex(CurrentConfig.inboundConfig.pacConfig.useSocksProxy ? 1 : 0);
//
bool have_http = CurrentConfig.inboundConfig.useHTTP;
httpCB->setChecked(have_http);
httpPortLE->setValue(CurrentConfig.inboundConfig.http_port);
httpAuthCB->setChecked(CurrentConfig.inboundConfig.http_useAuth);
//
httpAuthCB->setChecked(CurrentConfig.inboundConfig.http_useAuth);
httpAuthUsernameTxt->setEnabled(CurrentConfig.inboundConfig.http_useAuth);
httpAuthPasswordTxt->setEnabled(CurrentConfig.inboundConfig.http_useAuth);
httpAuthUsernameTxt->setText(QSTRING(CurrentConfig.inboundConfig.httpAccount.user));
httpAuthPasswordTxt->setText(QSTRING(CurrentConfig.inboundConfig.httpAccount.pass));
httpGroupBox->setEnabled(have_http);
//
//
bool have_socks = CurrentConfig.inboundConfig.useSocks;
socksCB->setChecked(have_socks);
socksPortLE->setValue(CurrentConfig.inboundConfig.socks_port);
//
socksAuthCB->setChecked(CurrentConfig.inboundConfig.socks_useAuth);
socksAuthUsernameTxt->setEnabled(CurrentConfig.inboundConfig.socks_useAuth);
socksAuthPasswordTxt->setEnabled(CurrentConfig.inboundConfig.socks_useAuth);
socksAuthUsernameTxt->setText(QSTRING(CurrentConfig.inboundConfig.socksAccount.user));
socksAuthPasswordTxt->setText(QSTRING(CurrentConfig.inboundConfig.socksAccount.pass));
// Socks UDP Options
socksUDPCB->setChecked(CurrentConfig.inboundConfig.socksUDP);
socksUDPIP->setEnabled(CurrentConfig.inboundConfig.socksUDP);
socksUDPIP->setText(QSTRING(CurrentConfig.inboundConfig.socksLocalIP));
socksGroupBox->setEnabled(have_socks);
//
//
vCorePathTxt->setText(QSTRING(CurrentConfig.v2CorePath));
vCoreAssetsPathTxt->setText(QSTRING(CurrentConfig.v2AssetsPath));
statsCheckbox->setChecked(CurrentConfig.connectionConfig.enableStats);
statsPortBox->setValue(CurrentConfig.connectionConfig.statsPort);
//
//
bypassCNCb->setChecked(CurrentConfig.connectionConfig.bypassCN);
proxyDefaultCb->setChecked(CurrentConfig.connectionConfig.enableProxy);
//
localDNSCb->setChecked(CurrentConfig.connectionConfig.withLocalDNS);
//
DNSListTxt->clear();
foreach (auto dnsStr, CurrentConfig.connectionConfig.dnsList) {
auto str = QString::fromStdString(dnsStr).trimmed();
if (!str.isEmpty()) {
DNSListTxt->appendPlainText(str);
}
}
foreach (auto connection, CurrentConfig.configs) {
autoStartCombo->addItem(QSTRING(connection));
}
autoStartCombo->setCurrentText(QSTRING(CurrentConfig.autoStartConfig));
cancelIgnoreVersionBtn->setEnabled(CurrentConfig.ignoredVersion != "");
ignoredNextVersion->setText(QSTRING(CurrentConfig.ignoredVersion));
//
for (size_t i = 0; i < CurrentConfig.toolBarConfig.Pages.size(); i++) {
nsBarPagesList->addItem(tr("Page") + QString::number(i + 1) + ": " + QString::number(CurrentConfig.toolBarConfig.Pages[i].Lines.size()) + " " + tr("Item(s)"));
}
if (CurrentConfig.toolBarConfig.Pages.size() > 0) {
nsBarPagesList->setCurrentRow(0);
on_nsBarPagesList_currentRowChanged(0);
} else {
nsBarVerticalLayout->setEnabled(false);
nsBarLinesList->setEnabled(false);
nsBarLineDelBTN->setEnabled(false);
nsBarLineAddBTN->setEnabled(false);
nsBarPageYOffset->setEnabled(false);
}
CurrentBarPageId = 0;
finishedLoading = true;
}
PrefrencesWindow::~PrefrencesWindow()
{
delete ui;
}
void PrefrencesWindow::on_buttonBox_accepted()
{
int sp = socksPortLE->text().toInt();
int hp = httpPortLE->text().toInt() ;
if (!(sp == 0 || hp == 0) && sp == hp) {
QvMessageBox(this, tr("Prefrences"), tr("Port numbers cannot be the same"));
return;
}
SetGlobalConfig(CurrentConfig);
emit s_reload_config(IsConnectionPropertyChanged);
}
void PrefrencesWindow::on_httpCB_stateChanged(int checked)
{
NEEDRESTART
bool enabled = checked == Qt::Checked;
httpGroupBox->setEnabled(enabled);
CurrentConfig.inboundConfig.useHTTP = enabled;
}
void PrefrencesWindow::on_socksCB_stateChanged(int checked)
{
NEEDRESTART
bool enabled = checked == Qt::Checked;
socksGroupBox->setEnabled(enabled);
CurrentConfig.inboundConfig.useSocks = enabled;
}
void PrefrencesWindow::on_httpAuthCB_stateChanged(int checked)
{
NEEDRESTART
bool enabled = checked == Qt::Checked;
httpAuthUsernameTxt->setEnabled(enabled);
httpAuthPasswordTxt->setEnabled(enabled);
CurrentConfig.inboundConfig.http_useAuth = enabled;
}
void PrefrencesWindow::on_socksAuthCB_stateChanged(int checked)
{
NEEDRESTART
bool enabled = checked == Qt::Checked;
socksAuthUsernameTxt->setEnabled(enabled);
socksAuthPasswordTxt->setEnabled(enabled);
CurrentConfig.inboundConfig.socks_useAuth = enabled;
}
void PrefrencesWindow::on_languageComboBox_currentTextChanged(const QString &arg1)
{
LOADINGCHECK
//
// A strange bug prevents us to change the UI language online
// https://github.com/lhy0403/Qv2ray/issues/34
//
CurrentConfig.uiConfig.language = arg1.toStdString();
//
//
//if (QApplication::installTranslator(getTranslator(arg1))) {
// LOG(MODULE_UI, "Loaded translations " + arg1.toStdString())
// retranslateUi(this);
//} else {
// QvMessageBox(this, tr("#Prefrences"), tr("#SwitchTranslationError"));
//}
//
//emit retranslateUi(this);
}
void PrefrencesWindow::on_logLevelComboBox_currentIndexChanged(int index)
{
NEEDRESTART
CurrentConfig.logLevel = index;
}
void PrefrencesWindow::on_vCoreAssetsPathTxt_textEdited(const QString &arg1)
{
NEEDRESTART
CurrentConfig.v2AssetsPath = arg1.toStdString();
}
void PrefrencesWindow::on_listenIPTxt_textEdited(const QString &arg1)
{
NEEDRESTART
CurrentConfig.inboundConfig.listenip = arg1.toStdString();
//pacAccessPathTxt->setText("http://" + arg1 + ":" + QString::number(pacPortSB->value()) + "/pac");
}
void PrefrencesWindow::on_httpAuthUsernameTxt_textEdited(const QString &arg1)
{
NEEDRESTART
CurrentConfig.inboundConfig.httpAccount.user = arg1.toStdString();
}
void PrefrencesWindow::on_httpAuthPasswordTxt_textEdited(const QString &arg1)
{
NEEDRESTART
CurrentConfig.inboundConfig.httpAccount.pass = arg1.toStdString();
}
void PrefrencesWindow::on_socksAuthUsernameTxt_textEdited(const QString &arg1)
{
NEEDRESTART
CurrentConfig.inboundConfig.socksAccount.user = arg1.toStdString();
}
void PrefrencesWindow::on_socksAuthPasswordTxt_textEdited(const QString &arg1)
{
NEEDRESTART
CurrentConfig.inboundConfig.socksAccount.pass = arg1.toStdString();
}
void PrefrencesWindow::on_proxyDefaultCb_stateChanged(int arg1)
{
NEEDRESTART
CurrentConfig.connectionConfig.enableProxy = arg1 == Qt::Checked;
}
void PrefrencesWindow::on_localDNSCb_stateChanged(int arg1)
{
NEEDRESTART
CurrentConfig.connectionConfig.withLocalDNS = arg1 == Qt::Checked;
}
void PrefrencesWindow::on_selectVAssetBtn_clicked()
{
NEEDRESTART
QString dir = QFileDialog::getExistingDirectory(this, tr("Open v2ray assets folder"), QDir::currentPath());
if (!dir.isEmpty()) {
vCoreAssetsPathTxt->setText(dir);
on_vCoreAssetsPathTxt_textEdited(dir);
}
}
void PrefrencesWindow::on_selectVCoreBtn_clicked()
{
QString core = QFileDialog::getOpenFileName(this, tr("Open v2ray core file"), QDir::currentPath());
if (!core.isEmpty()) {
vCorePathTxt->setText(core);
on_vCorePathTxt_textEdited(core);
}
}
void PrefrencesWindow::on_vCorePathTxt_textEdited(const QString &arg1)
{
NEEDRESTART
CurrentConfig.v2CorePath = arg1.toStdString();
}
void PrefrencesWindow::on_DNSListTxt_textChanged()
{
if (finishedLoading) {
try {
QStringList hosts = DNSListTxt->toPlainText().replace("\r", "").split("\n");
CurrentConfig.connectionConfig.dnsList.clear();
foreach (auto host, hosts) {
if (host != "" && host != "\r") {
// Not empty, so we save.
CurrentConfig.connectionConfig.dnsList.push_back(host.toStdString());
NEEDRESTART
}
}
BLACK(DNSListTxt)
} catch (...) {
RED(DNSListTxt)
}
}
}
void PrefrencesWindow::on_autoStartCombo_currentTextChanged(const QString &arg1)
{
CurrentConfig.autoStartConfig = arg1.toStdString();
}
void PrefrencesWindow::on_aboutQt_clicked()
{
QApplication::aboutQt();
}
void PrefrencesWindow::on_cancelIgnoreVersionBtn_clicked()
{
CurrentConfig.ignoredVersion.clear();
cancelIgnoreVersionBtn->setEnabled(false);
}
void PrefrencesWindow::on_tProxyCheckBox_stateChanged(int arg1)
{
#ifdef __linux
if (finishedLoading) {
// Set UID and GID for linux
// Steps:
// --> 1. Copy v2ray core files to the #CONFIG_DIR#/vcore/ dir.
// --> 2. Change GlobalConfig.v2CorePath.
// --> 3. Call `pkexec setcap CAP_NET_ADMIN,CAP_NET_RAW,CAP_NET_BIND_SERVICE=eip` on the v2ray core.
if (arg1 == Qt::Checked) {
// We enable it!
if (QvMessageBoxAsk(this, tr("Enable tProxy Support"),
tr("This will append capabilities to the v2ray executable.") + NEWLINE + NEWLINE +
tr("Qv2ray will copy your v2ray core to this path: ") + NEWLINE + QV2RAY_DEFAULT_VCORE_PATH + NEWLINE + NEWLINE +
tr("If anything goes wrong after enabling this, please refer to issue #57 or the link below:") + NEWLINE +
" https://lhy0403.github.io/Qv2ray/zh-CN/FAQ.html ") != QMessageBox::Yes) {
tProxyCheckBox->setChecked(false);
LOG(MODULE_UI, "Canceled enabling tProxy feature.")
} else {
LOG(MODULE_VCORE, "ENABLING tProxy Support")
LOG(MODULE_FILE, " --> Origin v2ray core file is at: " + CurrentConfig.v2CorePath)
auto v2ctlPath = QFileInfo(QSTRING(CurrentConfig.v2CorePath)).path() + "/v2ctl";
auto newPath = QFileInfo(QV2RAY_DEFAULT_VCORE_PATH).path();
//
LOG(MODULE_FILE, " --> Origin v2ctl file is at: " + v2ctlPath.toStdString())
LOG(MODULE_FILE, " --> New v2ray files will be placed in: " + newPath.toStdString())
//
LOG(MODULE_FILE, " --> Copying files....")
if (QFileInfo(QSTRING(CurrentConfig.v2CorePath)).absoluteFilePath() != QFileInfo(QV2RAY_DEFAULT_VCORE_PATH).absoluteFilePath()) {
// Only trying to remove file when they are not in the default dir.
// (In other words...) Keep using the current files. <Because we don't know where else we can copy the file from...>
if (QFile(QV2RAY_DEFAULT_VCORE_PATH).exists()) {
LOG(MODULE_FILE, QV2RAY_DEFAULT_VCORE_PATH.toStdString() + ": File already exists.")
LOG(MODULE_FILE, QV2RAY_DEFAULT_VCORE_PATH.toStdString() + ": Deleting file.")
QFile(QV2RAY_DEFAULT_VCORE_PATH).remove();
}
if (QFile(newPath + "/v2ctl").exists()) {
LOG(MODULE_FILE, newPath.toStdString() + "/v2ctl : File already exists.")
LOG(MODULE_FILE, newPath.toStdString() + "/v2ctl : Deleting file.")
QFile(newPath + "/v2ctl").remove();
}
string vCoreresult = QFile(QSTRING(CurrentConfig.v2CorePath)).copy(QV2RAY_DEFAULT_VCORE_PATH) ? "OK" : "FAILED";
LOG(MODULE_FILE, " --> v2ray Core: " + vCoreresult)
//
string vCtlresult = QFile(v2ctlPath).copy(newPath + "/v2ctl") ? "OK" : "FAILED";
LOG(MODULE_FILE, " --> v2ray Ctl: " + vCtlresult)
//
if (vCoreresult == "OK" && vCtlresult == "OK") {
LOG(MODULE_VCORE, " --> Done copying files.")
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 +
QSTRING(CurrentConfig.v2CorePath) + NEWLINE + v2ctlPath + NEWLINE + NEWLINE +
tr("to this path: ") + NEWLINE + newPath);
return;
}
} else {
LOG(MODULE_VCORE, "Skipped removing files since the current v2ray core is in the default path.")
LOG(MODULE_VCORE, " --> Actually because we don't know where else to obtain the files.")
}
LOG(MODULE_UI, "Calling pkexec and setcap...")
int ret = QProcess::execute("pkexec setcap CAP_NET_ADMIN,CAP_NET_RAW,CAP_NET_BIND_SERVICE=eip " + QSTRING(CurrentConfig.v2CorePath));
if (ret != 0) {
LOG(MODULE_UI, "WARN: setcap exits with code: " + to_string(ret))
QvMessageBox(this, tr("Prefrences"), tr("Failed to setcap onto v2ray executable. You may need to run `setcap` manually."));
}
CurrentConfig.tProxySupport = true;
NEEDRESTART
}
} else {
int ret = QProcess::execute("pkexec setcap -r " + QSTRING(CurrentConfig.v2CorePath));
if (ret != 0) {
LOG(MODULE_UI, "WARN: setcap exits with code: " + to_string(ret))
QvMessageBox(this, tr("Prefrences"), tr("Failed to setcap onto v2ray executable. You may need to run `setcap` manually."));
}
CurrentConfig.tProxySupport = false;
NEEDRESTART
}
}
#else
Q_UNUSED(arg1)
// No such tProxy thing on Windows and macOS
QvMessageBox(this, tr("Prefrences"), tr("tProxy is not supported on macOS and Windows"));
CurrentConfig.tProxySupport = false;
tProxyCheckBox->setChecked(false);
#endif
}
void PrefrencesWindow::on_bypassCNCb_stateChanged(int arg1)
{
NEEDRESTART
CurrentConfig.connectionConfig.bypassCN = arg1 == Qt::Checked;
}
void PrefrencesWindow::on_statsCheckbox_stateChanged(int arg1)
{
NEEDRESTART
CurrentConfig.connectionConfig.enableStats = arg1 == Qt::Checked;
}
void PrefrencesWindow::on_statsPortBox_valueChanged(int arg1)
{
NEEDRESTART
CurrentConfig.connectionConfig.statsPort = arg1;
}
void PrefrencesWindow::on_socksPortLE_valueChanged(int arg1)
{
NEEDRESTART
CurrentConfig.inboundConfig.socks_port = arg1;
}
void PrefrencesWindow::on_httpPortLE_valueChanged(int arg1)
{
NEEDRESTART
CurrentConfig.inboundConfig.http_port = arg1;
}
void PrefrencesWindow::on_socksUDPCB_stateChanged(int arg1)
{
NEEDRESTART
CurrentConfig.inboundConfig.socksUDP = arg1 == Qt::Checked;
socksUDPIP->setEnabled(arg1 == Qt::Checked);
}
void PrefrencesWindow::on_socksUDPIP_textEdited(const QString &arg1)
{
NEEDRESTART
CurrentConfig.inboundConfig.socksLocalIP = arg1.toStdString();
}
// ------------------- NET SPEED PLUGIN OPERATIONS -----------------------------------------------------------------
#define CurrentBarPage CurrentConfig.toolBarConfig.Pages[this->CurrentBarPageId]
#define CurrentBarLine CurrentBarPage.Lines[this->CurrentBarLineId]
#define SET_LINE_LIST_TEXT nsBarLinesList->currentItem()->setText(GetBarLineDescription(CurrentBarLine));
void PrefrencesWindow::on_nsBarPageAddBTN_clicked()
{
QvBarPage page;
CurrentConfig.toolBarConfig.Pages.push_back(page);
CurrentBarPageId = CurrentConfig.toolBarConfig.Pages.size() - 1 ;
// Add default line.
QvBarLine line;
CurrentBarPage.Lines.push_back(line);
CurrentBarLineId = 0;
nsBarPagesList->addItem(QString::number(CurrentBarPageId));
ShowLineParameters(CurrentBarLine);
LOG(MODULE_UI, "Adding new page Id: " + to_string(CurrentBarPageId))
nsBarPageDelBTN->setEnabled(true);
nsBarLineAddBTN->setEnabled(true);
nsBarLineDelBTN->setEnabled(true);
nsBarLinesList->setEnabled(true);
nsBarPageYOffset->setEnabled(true);
on_nsBarPagesList_currentRowChanged(static_cast<int>(CurrentBarPageId));
nsBarPagesList->setCurrentRow(static_cast<int>(CurrentBarPageId));
}
void PrefrencesWindow::on_nsBarPageDelBTN_clicked()
{
if (nsBarPagesList->currentRow() >= 0) {
RemoveItem(CurrentConfig.toolBarConfig.Pages, static_cast<size_t>(nsBarPagesList->currentRow()));
nsBarPagesList->takeItem(nsBarPagesList->currentRow());
if (nsBarPagesList->count() <= 0) {
nsBarPageDelBTN->setEnabled(false);
nsBarLineAddBTN->setEnabled(false);
nsBarLineDelBTN->setEnabled(false);
nsBarLinesList->setEnabled(false);
nsBarVerticalLayout->setEnabled(false);
nsBarPageYOffset->setEnabled(false);
nsBarLinesList->clear();
}
}
}
void PrefrencesWindow::on_nsBarPageYOffset_valueChanged(int arg1)
{
LOADINGCHECK
CurrentBarPage.OffsetYpx = arg1;
}
void PrefrencesWindow::on_nsBarLineAddBTN_clicked()
{
// WARNING Is it really just this simple?
QvBarLine line;
CurrentBarPage.Lines.push_back(line);
CurrentBarLineId = CurrentBarPage.Lines.size() - 1;
nsBarLinesList->addItem(QString::number(CurrentBarLineId));
ShowLineParameters(CurrentBarLine);
nsBarLineDelBTN->setEnabled(true);
LOG(MODULE_UI, "Adding new line Id: " + to_string(CurrentBarLineId))
nsBarLinesList->setCurrentRow(static_cast<int>(CurrentBarPage.Lines.size() - 1));
}
void PrefrencesWindow::on_nsBarLineDelBTN_clicked()
{
if (nsBarLinesList->currentRow() >= 0) {
RemoveItem(CurrentBarPage.Lines, static_cast<size_t>(nsBarLinesList->currentRow()));
nsBarLinesList->takeItem(nsBarLinesList->currentRow());
CurrentBarLineId = 0;
if (nsBarLinesList->count() <= 0) {
nsBarVerticalLayout->setEnabled(false);
nsBarLineDelBTN->setEnabled(false);
}
// TODO Disabling some UI;
}
}
void PrefrencesWindow::on_nsBarPagesList_currentRowChanged(int currentRow)
{
if (currentRow < 0) return;
// Change page.
// We reload the lines
// Set all parameters item to the property of the first line.
CurrentBarPageId = static_cast<size_t>(currentRow);
CurrentBarLineId = 0;
nsBarPageYOffset->setValue(CurrentBarPage.OffsetYpx);
nsBarLinesList->clear();
if (!CurrentBarPage.Lines.empty()) {
for (auto line : CurrentBarPage.Lines) {
auto description = GetBarLineDescription(line);
nsBarLinesList->addItem(description);
}
nsBarLinesList->setCurrentRow(0);
ShowLineParameters(CurrentBarLine);
} else {
nsBarVerticalLayout->setEnabled(false);
}
}
void PrefrencesWindow::on_nsBarLinesList_currentRowChanged(int currentRow)
{
if (currentRow < 0) return;
CurrentBarLineId = static_cast<size_t>(currentRow);
ShowLineParameters(CurrentBarLine);
}
void PrefrencesWindow::on_fontComboBox_currentFontChanged(const QFont &f)
{
LOADINGCHECK
CurrentBarLine.Family = f.family().toStdString();
SET_LINE_LIST_TEXT
}
void PrefrencesWindow::on_nsBarFontBoldCB_stateChanged(int arg1)
{
LOADINGCHECK
CurrentBarLine.Bold = arg1 == Qt::Checked;
SET_LINE_LIST_TEXT
}
void PrefrencesWindow::on_nsBarFontItalicCB_stateChanged(int arg1)
{
LOADINGCHECK
CurrentBarLine.Italic = arg1 == Qt::Checked;
SET_LINE_LIST_TEXT
}
void PrefrencesWindow::on_nsBarFontASB_valueChanged(int arg1)
{
LOADINGCHECK
CurrentBarLine.ColorA = arg1;
ShowLineParameters(CurrentBarLine);
SET_LINE_LIST_TEXT
}
void PrefrencesWindow::on_nsBarFontRSB_valueChanged(int arg1)
{
LOADINGCHECK
CurrentBarLine.ColorR = arg1;
ShowLineParameters(CurrentBarLine);
SET_LINE_LIST_TEXT
}
void PrefrencesWindow::on_nsBarFontGSB_valueChanged(int arg1)
{
LOADINGCHECK
CurrentBarLine.ColorG = arg1;
ShowLineParameters(CurrentBarLine);
SET_LINE_LIST_TEXT
}
void PrefrencesWindow::on_nsBarFontBSB_valueChanged(int arg1)
{
LOADINGCHECK
CurrentBarLine.ColorB = arg1;
ShowLineParameters(CurrentBarLine);
SET_LINE_LIST_TEXT
}
void PrefrencesWindow::on_nsBarFontSizeSB_valueChanged(double arg1)
{
LOADINGCHECK
CurrentBarLine.Size = arg1;
SET_LINE_LIST_TEXT
}
QString PrefrencesWindow::GetBarLineDescription(QvBarLine barLine)
{
QString result = "Empty";
result = NetSpeedPluginMessages[barLine.ContentType];
if (barLine.ContentType == 0) {
result += " (" + QSTRING(barLine.Message) + ")";
}
result = result.append(barLine.Bold ? ", " + tr("Bold") : "");
result = result.append(barLine.Italic ? ", " + tr("Italic") : "");
return result;
}
void PrefrencesWindow::ShowLineParameters(QvBarLine &barLine)
{
finishedLoading = false;
if (!barLine.Family.empty()) {
fontComboBox->setCurrentFont(QFont(QSTRING(barLine.Family)));
}
// Colors
nsBarFontASB->setValue(barLine.ColorA);
nsBarFontBSB->setValue(barLine.ColorB);
nsBarFontGSB->setValue(barLine.ColorG);
nsBarFontRSB->setValue(barLine.ColorR);
//
QColor color = QColor::fromRgb(barLine.ColorR, barLine.ColorG, barLine.ColorB, barLine.ColorA);
QString s("background: #"
+ QString(color.red() < 16 ? "0" : "") + QString::number(color.red(), 16)
+ QString(color.green() < 16 ? "0" : "") + QString::number(color.green(), 16)
+ QString(color.blue() < 16 ? "0" : "") + QString::number(color.blue(), 16) + ";");
chooseColorBtn->setStyleSheet(s);
nsBarFontSizeSB->setValue(barLine.Size);
nsBarFontBoldCB->setChecked(barLine.Bold);
nsBarFontItalicCB->setChecked(barLine.Italic);
nsBarContentCombo->setCurrentText(NetSpeedPluginMessages[barLine.ContentType]);
nsBarTagTxt->setText(QSTRING(barLine.Message));
finishedLoading = true;
nsBarVerticalLayout->setEnabled(true);
}
void PrefrencesWindow::on_chooseColorBtn_clicked()
{
LOADINGCHECK
QColorDialog d(QColor::fromRgb(CurrentBarLine.ColorR, CurrentBarLine.ColorG, CurrentBarLine.ColorB, CurrentBarLine.ColorA), this);
d.exec();
if (d.result() == QDialog::DialogCode::Accepted) {
d.selectedColor().getRgb(&CurrentBarLine.ColorR, &CurrentBarLine.ColorG, &CurrentBarLine.ColorB, &CurrentBarLine.ColorA);
ShowLineParameters(CurrentBarLine);
SET_LINE_LIST_TEXT
}
}
void PrefrencesWindow::on_nsBarTagTxt_textEdited(const QString &arg1)
{
LOADINGCHECK
CurrentBarLine.Message = arg1.toStdString();
SET_LINE_LIST_TEXT
}
void PrefrencesWindow::on_nsBarContentCombo_currentIndexChanged(const QString &arg1)
{
LOADINGCHECK
CurrentBarLine.ContentType = NetSpeedPluginMessages.key(arg1);
SET_LINE_LIST_TEXT
}
void PrefrencesWindow::on_applyNSBarSettingsBtn_clicked()
{
auto conf = GetGlobalConfig();
conf.toolBarConfig = CurrentConfig.toolBarConfig;
SetGlobalConfig(conf);
}
void PrefrencesWindow::on_themeCombo_currentTextChanged(const QString &arg1)
{
LOADINGCHECK
CurrentConfig.uiConfig.theme = arg1.toStdString();
}
void PrefrencesWindow::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."));
#if QV2RAY_USE_BUILTIN_DARKTHEME
themeCombo->setEnabled(arg1 != Qt::Checked);
if (arg1 == Qt::Checked) {
themeCombo->setCurrentIndex(QStyleFactory::keys().indexOf("Fusion"));
CurrentConfig.uiConfig.theme = "Fusion";
}
#endif
}
void PrefrencesWindow::on_darkTrayCB_stateChanged(int arg1)
{
LOADINGCHECK
CurrentConfig.uiConfig.useDarkTrayIcon = arg1 == Qt::Checked;
}
void PrefrencesWindow::on_enablePACCB_stateChanged(int arg1)
{
LOADINGCHECK
NEEDRESTART
bool enabled = arg1 == Qt::Checked;
CurrentConfig.inboundConfig.pacConfig.enablePAC = enabled;
pacGroupBox->setEnabled(enabled);
}
void PrefrencesWindow::on_pacGoBtn_clicked()
{
LOADINGCHECK
QString gfwLocation;
QString fileContent;
auto request = new QvHttpRequestHelper();
switch (gfwListCB->currentIndex()) {
case 0:
gfwLocation = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt";
fileContent = QString::fromUtf8(request->syncget(gfwLocation));
break;
case 1:
gfwLocation = "https://pagure.io/gfwlist/raw/master/f/gfwlist.txt";
fileContent = QString::fromUtf8(request->syncget(gfwLocation));
break;
case 2:
gfwLocation = "http://repo.or.cz/gfwlist.git/blob_plain/HEAD:/gfwlist.txt";
fileContent = QString::fromUtf8(request->syncget(gfwLocation));
break;
case 3:
gfwLocation = "https://bitbucket.org/gfwlist/gfwlist/raw/HEAD/gfwlist.txt";
fileContent = QString::fromUtf8(request->syncget(gfwLocation));
break;
case 4:
gfwLocation = "https://gitlab.com/gfwlist/gfwlist/raw/master/gfwlist.txt";
fileContent = QString::fromUtf8(request->syncget(gfwLocation));
break;
case 5:
gfwLocation = "https://git.tuxfamily.org/gfwlist/gfwlist.git/plain/gfwlist.txt";
fileContent = QString::fromUtf8(request->syncget(gfwLocation));
break;
case 6:
QFileDialog d;
d.exec();
auto file = d.getOpenFileUrl(this, tr("Select GFWList in base64")).toString();
//
fileContent = StringFromFile(new QFile(file));
break;
}
//
if (!QDir(QV2RAY_RULES_DIR).exists()) {
QDir(QV2RAY_RULES_DIR).mkpath(QV2RAY_RULES_DIR);
}
QFile privateGFWListFile(QV2RAY_RULES_GFWLIST_PATH);
StringToFile(&fileContent, &privateGFWListFile);
}
void PrefrencesWindow::on_pacPortSB_valueChanged(int arg1)
{
LOADINGCHECK
NEEDRESTART
CurrentConfig.inboundConfig.pacConfig.port = arg1;
//pacAccessPathTxt->setText("http://" + listenIPTxt->text() + ":" + QString::number(arg1) + "/pac");
}
void PrefrencesWindow::on_setSysProxyCB_stateChanged(int arg1)
{
LOADINGCHECK
NEEDRESTART
CurrentConfig.inboundConfig.setSystemProxy = arg1 == Qt::Checked;
}
void PrefrencesWindow::on_pacProxyCB_currentIndexChanged(int index)
{
LOADINGCHECK
NEEDRESTART
// 0 -> http
// 1 -> socks
CurrentConfig.inboundConfig.pacConfig.useSocksProxy = index == 1;
}
void PrefrencesWindow::on_pushButton_clicked()
{
LOADINGCHECK
QDesktopServices::openUrl(QUrl::fromUserInput(QV2RAY_RULES_DIR));
}
void PrefrencesWindow::on_pacProxyTxt_textEdited(const QString &arg1)
{
LOADINGCHECK
NEEDRESTART
CurrentConfig.inboundConfig.pacConfig.proxyIP = arg1.toStdString();
}