[change] now using c++ private inheritance and added QRCode libs.

Former-commit-id: 4f49dad042
This commit is contained in:
Leroy.H.Y 2019-11-10 13:29:09 +08:00
parent b804e98c9c
commit b5042aec4c
28 changed files with 981 additions and 729 deletions

View File

@ -1 +1 @@
385
444

View File

@ -6,11 +6,14 @@
QT += core gui widgets network charts
include(3rdparty/qzxing_noTests/QZXing.pri)
TARGET = qv2ray
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
# Don't merge those configs with below.
CONFIG += enable_decoder_qr_code enable_encoder_qr_code
include(3rdparty/qzxing_noTests/QZXing-components.pri)
# Main config
CONFIG += c++11 openssl-linked lrelease embed_translations
# Now read build number file.
@ -19,7 +22,7 @@ VERSION = 1.99.1.$$_BUILD_NUMBER
_BUILD_NUMBER = $$num_add($$_BUILD_NUMBER, 1)
write_file("Build.Counter", _BUILD_NUMBER)
DEFINES += QV2RAY_VERSION_STRING=\"\\\"v$${VERSION}\\\"\"
DEFINES += QT_DEPRECATED_WARNINGS QV2RAY_VERSION_STRING=\"\\\"v$${VERSION}\\\"\"
SOURCES += \
src/main.cpp \
@ -30,13 +33,14 @@ SOURCES += \
src/QvCoreInteractions.cpp \
src/QvUtils.cpp \
src/ui/NetSpeedBar/QvNetSpeedBar.cpp \
src/ui/w_ExportConfig.cpp \
src/ui/w_InboundEditor.cpp \
src/ui/w_OutboundEditor.cpp \
src/ui/w_RoutesEditor.cpp \
src/ui/w_SubscriptionEditor.cpp \
src/utils/QObjectMessageProxy.cpp \
src/utils/QPingModel.cpp \
src/utils/QvHTTPRequestHelper.cpp \
src/utils/QvPingModel.cpp \
src/utils/QvRunguard.cpp \
src/utils/QJsonModel.cpp \
src/ui/w_JsonEditor.cpp \
@ -59,6 +63,7 @@ HEADERS += \
src/QvCoreConfigOperations.hpp \
src/QvCoreInteractions.hpp \
src/QvUtils.hpp \
src/ui/w_ExportConfig.hpp \
src/ui/w_ImportConfig.hpp \
src/ui/w_InboundEditor.hpp \
src/ui/w_JsonEditor.hpp \
@ -70,15 +75,16 @@ HEADERS += \
src/utils/QJsonModel.hpp \
src/utils/QJsonObjectInsertMacros.h \
src/utils/QObjectMessageProxy.hpp \
src/utils/QPingModel.hpp \
src/utils/QvHTTPRequestHelper.hpp \
src/utils/QvNetSpeedPlugin.hpp \
src/utils/QvPingModel.hpp \
src/utils/QvRunguard.hpp \
libs/gen/v2ray_api_commands.pb.h \
libs/gen/v2ray_api_commands.grpc.pb.h \
src/utils/QvTinyLog.hpp
FORMS += \
src/ui/w_ExportConfig.ui \
src/ui/w_ImportConfig.ui \
src/ui/w_InboundEditor.ui \
src/ui/w_JsonEditor.ui \

View File

@ -18,6 +18,7 @@
// Get Configured Config Dir Path
#define QV2RAY_CONFIG_DIR (Qv2ray::Utils::GetConfigDirPath())
#define QV2RAY_CONFIG_FILE (QV2RAY_CONFIG_DIR + "Qv2ray.conf")
#define QV2RAY_QRCODE_DIR (QV2RAY_CONFIG_DIR + "qr_images/")
#define QV2RAY_CONFIG_FILE_EXTENSION ".qv2ray.json"
#define QV2RAY_GENERATED_DIR (QV2RAY_CONFIG_DIR + "generated/")
@ -37,14 +38,14 @@
// GUI TOOLS
#define RED(obj) \
auto _temp = ui->obj->palette(); \
auto _temp = obj->palette(); \
_temp.setColor(QPalette::Text, Qt::red); \
ui->obj->setPalette(_temp);
obj->setPalette(_temp);
#define BLACK(obj) \
auto _temp = ui->obj->palette(); \
auto _temp = obj->palette(); \
_temp.setColor(QPalette::Text, Qt::blue); \
ui->obj->setPalette(_temp);
obj->setPalette(_temp);
#define QSTRING(std_string) QString::fromStdString(std_string)

View File

@ -1,4 +1,4 @@
#include <QThread>
#include <QThread>
#include "QvNetSpeedPlugin.hpp"
#include "QvUtils.hpp"
@ -64,13 +64,13 @@ namespace Qv2ray
case 101: {
// Current Time
CL.Message = QTime().toString("hh:mm:ss").toStdString();
CL.Message = QTime().currentTime().toString("hh:mm:ss").toStdString();
break;
}
case 102: {
// Current Date
CL.Message = QDate().toString("yyyy-MM-dd").toStdString();
CL.Message = QDate().currentDate().toString("yyyy-MM-dd").toStdString();
break;
}

67
src/ui/w_ExportConfig.cpp Normal file
View File

@ -0,0 +1,67 @@
#include "w_ExportConfig.hpp"
#include "QvUtils.hpp"
// Private initialiser
ConfigExporter::ConfigExporter(QWidget *parent) :
QDialog(parent),
qzxing(this)
{
setupUi(this);
}
ConfigExporter::ConfigExporter(const QImage &img, QWidget *parent): ConfigExporter(parent)
{
image = img;
message = tr("Empty");
}
ConfigExporter::ConfigExporter(const QString &data, QWidget *parent): ConfigExporter(parent)
{
QZXingEncoderConfig conf;
conf.border = true;
conf.errorCorrectionLevel = QZXing::EncodeErrorCorrectionLevel_Q;
auto img = qzxing.encodeData(data, conf);
image = img.copy();
message = data;
}
void ConfigExporter::OpenExport()
{
imageLabel->setPixmap(QPixmap::fromImage(image));
messageTxt->setPlainText(message);
this->exec();
}
void ConfigExporter::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
retranslateUi(this);
break;
default:
break;
}
}
void ConfigExporter::on_closeBtn_clicked()
{
// OK
close();
}
void ConfigExporter::on_saveBtn_clicked()
{
// Save
if (!QDir(QV2RAY_QRCODE_DIR).exists()) {
QDir().mkpath(QV2RAY_QRCODE_DIR);
}
auto filePath = QV2RAY_QRCODE_DIR + QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss-z.png");
auto result = image.save(filePath);
QDesktopServices::openUrl(QUrl(QV2RAY_QRCODE_DIR));
LOG(MODULE_FILE, "Saving an image to: " + filePath.toStdString() + " result: " + (result ? "OK" : "Failed"))
// If succeed, we disable future save.
saveBtn->setEnabled(result);
}

29
src/ui/w_ExportConfig.hpp Normal file
View File

@ -0,0 +1,29 @@
#ifndef QVIMAGEVIEWER_H
#define QVIMAGEVIEWER_H
#include "ui_w_ExportConfig.h"
#include "QZXing"
class ConfigExporter : public QDialog, private Ui::ExportConfigWindow
{
Q_OBJECT
public:
explicit ConfigExporter(const QImage &img, QWidget *parent = nullptr);
explicit ConfigExporter(const QString &data, QWidget *parent = nullptr);
void OpenExport();
protected:
void changeEvent(QEvent *e);
private slots:
void on_closeBtn_clicked();
void on_saveBtn_clicked();
private:
explicit ConfigExporter(QWidget *parent);
QZXing qzxing;
QImage image;
QString message;
};
#endif // QVIMAGEVIEWER_H

87
src/ui/w_ExportConfig.ui Normal file
View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ExportConfigWindow</class>
<widget class="QDialog" name="ExportConfigWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>549</width>
<height>493</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="10,0,3,0">
<item>
<widget class="QLabel" name="imageLabel">
<property name="text">
<string>Image</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="indent">
<number>-1</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
<property name="buddy">
<cstring>Buddy</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Text Message</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="messageTxt"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<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="QPushButton" name="saveBtn">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closeBtn">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -8,6 +8,7 @@
#include "QvUtils.hpp"
#include "QvCoreInteractions.hpp"
#include "QvCoreConfigOperations.hpp"
#include "w_OutboundEditor.hpp"
#include "w_ImportConfig.hpp"
@ -15,46 +16,49 @@
ImportConfigWindow::ImportConfigWindow(QWidget *parent)
: QDialog(parent)
, ui(new Ui::ImportConfigWindow)
{
ui->setupUi(this);
ui->nameTxt->setText(QUuid::createUuid().toString());
setupUi(this);
nameTxt->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-MM-ss.imported"));
}
ImportConfigWindow::~ImportConfigWindow()
{
delete ui;
}
void ImportConfigWindow::OpenImporter()
{
this->exec();
}
void ImportConfigWindow::on_importSourceCombo_currentIndexChanged(int index)
{
ui->stackedWidget->setCurrentIndex(index);
stackedWidget->setCurrentIndex(index);
}
void ImportConfigWindow::on_selectFileBtn_clicked()
{
QString dir = QFileDialog::getOpenFileName(this, tr("Select file to import"), QDir::currentPath());
ui->fileLineTxt->setText(dir);
fileLineTxt->setText(dir);
}
void ImportConfigWindow::on_buttonBox_accepted()
{
QString alias = ui->nameTxt->text();
QString alias = nameTxt->text();
QJsonObject config;
auto conf = GetGlobalConfig();
auto needReload = false;
if (ui->importSourceCombo->currentIndex() == 0) {
if (importSourceCombo->currentIndex() == 0) {
// From File...
bool overrideInBound = !ui->keepImportedInboundCheckBox->isChecked();
auto fileName = ui->fileLineTxt->text();
bool overrideInBound = !keepImportedInboundCheckBox->isChecked();
auto fileName = fileLineTxt->text();
if (!Qv2Instance::ValidateConfig(&fileName)) {
QvMessageBox(this, tr("Import config file"), tr("Failed to check the validity of the config file."));
return;
}
QString path = ui->fileLineTxt->text();
QString path = fileLineTxt->text();
alias = alias != "" ? alias : QFileInfo(path).fileName();
config = ConvertConfigFromFile(path, overrideInBound);
//
@ -64,7 +68,7 @@ void ImportConfigWindow::on_buttonBox_accepted()
//
SetGlobalConfig(conf);
} else {
QString vmess = ui->vmessConnectionStringTxt->toPlainText();
QString vmess = vmessConnectionStringTxt->toPlainText();
//
// We saperate the string into lines.
QStringList vmessList = vmess.split(NEWLINE, QString::SplitBehavior::SkipEmptyParts);
@ -76,7 +80,7 @@ void ImportConfigWindow::on_buttonBox_accepted()
switch (result) {
case 0:
// This result code passes the validation check.
config = ConvertConfigFromVMessString(ui->vmessConnectionStringTxt->toPlainText());
config = ConvertConfigFromVMessString(vmessConnectionStringTxt->toPlainText());
//
alias = alias.isEmpty() ? alias : config["QV2RAY_ALIAS"].toString();
config.remove("QV2RAY_ALIAS");
@ -101,3 +105,29 @@ void ImportConfigWindow::on_buttonBox_accepted()
SetGlobalConfig(conf);
emit s_reload_config(needReload);
}
void ImportConfigWindow::on_qrFromScreenBtn_clicked()
{
QScreen *screen = qApp->primaryScreen();
if (const QWindow *window = windowHandle())
screen = window->screen();
if (!screen) {
LOG(MODULE_UI, "Cannot even find a screen.")
return;
}
auto pix = screen->grabWindow(0);
imageLabel->setPixmap(pix.scaled(QSize(250, 200), Qt::KeepAspectRatio, Qt::SmoothTransformation));
{
QZXing x;
auto str = x.decodeImage(pix.toImage());
qRContentLabel->setText(str);
if (str.isEmpty()) {
QvMessageBox(this, tr("QRCode Scanning failed"), tr("Cannot find a qrcode from current primary screen"));
return;
}
}
}

View File

@ -1,15 +1,10 @@
#ifndef IMPORTCONF_H
#ifndef IMPORTCONF_H
#define IMPORTCONF_H
#include <QDialog>
#include "ui_w_ImportConfig.h"
namespace Ui
{
class ImportConfigWindow;
}
class ImportConfigWindow : public QDialog
class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
{
Q_OBJECT
@ -26,9 +21,7 @@ class ImportConfigWindow : public QDialog
void on_buttonBox_accepted();
private:
Ui::ImportConfigWindow *ui;
void on_qrFromScreenBtn_clicked();
};
#endif // IMPORTCONF_H

View File

@ -55,12 +55,12 @@
</property>
<item>
<property name="text">
<string>File</string>
<string>Existing File</string>
</property>
</item>
<item>
<property name="text">
<string>VMess String</string>
<string>VMess and QRCode</string>
</property>
</item>
<item>
@ -68,11 +68,6 @@
<string>Subscription Link</string>
</property>
</item>
<item>
<property name="text">
<string>Scan Image</string>
</property>
</item>
</widget>
</item>
</layout>
@ -86,7 +81,7 @@
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="filePage">
<layout class="QFormLayout" name="formLayout">
@ -146,63 +141,179 @@
</layout>
</widget>
<widget class="QWidget" name="vmessPage">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>VMess Connection String</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,1">
<item>
<widget class="QTextEdit" name="vmessConnectionStringTxt">
<property name="placeholderText">
<string>Put your vmess:// here</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>VMess Check Status</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Processing</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_9">
<property name="text">
<string>0/0</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Line Failed</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>6</x>
<y>6</y>
<width>153</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>VMess Connection String</string>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>30</y>
<width>227</width>
<height>36</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="text">
<string>---TODO---</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QLabel" name="label_12">
<property name="geometry">
<rect>
<x>504</x>
<y>80</y>
<width>40</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Image</string>
</property>
</widget>
<widget class="QLabel" name="qRContentLabel">
<property name="geometry">
<rect>
<x>550</x>
<y>104</y>
<width>16</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>C</string>
</property>
</widget>
<widget class="QLabel" name="label_13">
<property name="geometry">
<rect>
<x>434</x>
<y>104</y>
<width>110</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Connection String</string>
</property>
</widget>
<widget class="QPushButton" name="qrFromScreenBtn">
<property name="geometry">
<rect>
<x>550</x>
<y>40</y>
<width>84</width>
<height>34</height>
</rect>
</property>
<property name="text">
<string>Go</string>
</property>
</widget>
<widget class="QLabel" name="label_11">
<property name="geometry">
<rect>
<x>437</x>
<y>40</y>
<width>107</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Scan from Screen</string>
</property>
</widget>
<widget class="QLabel" name="imageLabel">
<property name="geometry">
<rect>
<x>550</x>
<y>80</y>
<width>16</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>I</string>
</property>
</widget>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>60</x>
<y>80</y>
<width>404</width>
<height>194</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,1">
<item>
<widget class="QTextEdit" name="vmessConnectionStringTxt">
<property name="placeholderText">
<string>Put your vmess:// here</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>VMess Check Status</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Processing</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_9">
<property name="text">
<string>0/0</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Line Failed</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout">
@ -236,49 +347,6 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="text">
<string>---TODO---</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Select Image File</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Scan from Screen</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Go</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@ -1,5 +1,4 @@
#include "w_InboundEditor.hpp"
#include "ui_w_InboundEditor.h"
#include "w_InboundEditor.hpp"
#include "QvUtils.hpp"
#include "QvCoreConfigOperations.hpp"
@ -8,10 +7,9 @@ static bool isLoading = false;
InboundEditor::InboundEditor(QJsonObject root, QWidget *parent) :
QDialog(parent),
ui(new Ui::InboundEditor),
original(root)
{
ui->setupUi(this);
setupUi(this);
this->root = root;
auto inboundType = root["protocol"].toString();
allocate = root["allocate"].toObject();
@ -63,62 +61,61 @@ QJsonObject InboundEditor::GenerateNewRoot()
void InboundEditor::LoadUIData()
{
isLoading = true;
ui->strategyCombo->setCurrentText(allocate["strategy"].toString());
ui->refreshNumberBox->setValue(allocate["refresh"].toInt());
ui->concurrencyNumberBox->setValue(allocate["concurrency"].toInt());
ui->enableSniffingCB->setChecked(sniffing["enabled"].toBool());
strategyCombo->setCurrentText(allocate["strategy"].toString());
refreshNumberBox->setValue(allocate["refresh"].toInt());
concurrencyNumberBox->setValue(allocate["concurrency"].toInt());
enableSniffingCB->setChecked(sniffing["enabled"].toBool());
//
ui->destOverrideList->setEnabled(sniffing["enabled"].toBool());
destOverrideList->setEnabled(sniffing["enabled"].toBool());
for (auto item : sniffing["destOverride"].toArray()) {
if (item.toString().toLower() == "http") ui->destOverrideList->item(0)->setCheckState(Qt::Checked);
if (item.toString().toLower() == "http") destOverrideList->item(0)->setCheckState(Qt::Checked);
if (item.toString().toLower() == "tls") ui->destOverrideList->item(1)->setCheckState(Qt::Checked);
if (item.toString().toLower() == "tls") destOverrideList->item(1)->setCheckState(Qt::Checked);
}
//
ui->inboundTagTxt->setText(root["tag"].toString());
ui->inboundHostTxt->setText(root["listen"].toString());
ui->inboundPortTxt->setText(root["port"].toVariant().toString());
ui->inboundProtocolCombo->setCurrentText(root["protocol"].toString());
inboundTagTxt->setText(root["tag"].toString());
inboundHostTxt->setText(root["listen"].toString());
inboundPortTxt->setText(root["port"].toVariant().toString());
inboundProtocolCombo->setCurrentText(root["protocol"].toString());
// HTTP
ui->httpTimeoutSpinBox->setValue(httpSettings["timeout"].toInt());
ui->httpTransparentCB->setChecked(httpSettings["allowTransparent"].toBool());
ui->httpUserLevelSB->setValue(httpSettings["userLevel"].toInt());
ui->httpAccountListBox->clear();
httpTimeoutSpinBox->setValue(httpSettings["timeout"].toInt());
httpTransparentCB->setChecked(httpSettings["allowTransparent"].toBool());
httpUserLevelSB->setValue(httpSettings["userLevel"].toInt());
httpAccountListBox->clear();
for (auto user : httpSettings["accounts"].toArray()) {
ui->httpAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString());
httpAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString());
}
// SOCKS
ui->socksAuthCombo->setCurrentText(socksSettings["auth"].toString());
ui->socksUDPCB->setChecked(socksSettings["udp"].toBool());
ui->socksUDPIPAddrTxt->setText(socksSettings["ip"].toString());
ui->socksUserLevelSB->setValue(socksSettings["userLevel"].toInt());
socksAuthCombo->setCurrentText(socksSettings["auth"].toString());
socksUDPCB->setChecked(socksSettings["udp"].toBool());
socksUDPIPAddrTxt->setText(socksSettings["ip"].toString());
socksUserLevelSB->setValue(socksSettings["userLevel"].toInt());
for (auto user : socksSettings["accounts"].toArray()) {
ui->socksAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString());
socksAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString());
}
// Dokodemo-Door
ui->dokoFollowRedirectCB->setChecked(dokoSettings["followRedirect"].toBool());
ui->dokoIPAddrTxt->setText(dokoSettings["address"].toString());
ui->dokoPortSB->setValue(dokoSettings["port"].toInt());
ui->dokoTimeoutSB->setValue(dokoSettings["timeout"].toInt());
ui->dokoUserLevelSB->setValue(dokoSettings["userLevel"].toInt());
ui->dokoTCPCB->setChecked(dokoSettings["network"].toString().contains("tcp"));
ui->dokoUDPCB->setChecked(dokoSettings["network"].toString().contains("udp"));
dokoFollowRedirectCB->setChecked(dokoSettings["followRedirect"].toBool());
dokoIPAddrTxt->setText(dokoSettings["address"].toString());
dokoPortSB->setValue(dokoSettings["port"].toInt());
dokoTimeoutSB->setValue(dokoSettings["timeout"].toInt());
dokoUserLevelSB->setValue(dokoSettings["userLevel"].toInt());
dokoTCPCB->setChecked(dokoSettings["network"].toString().contains("tcp"));
dokoUDPCB->setChecked(dokoSettings["network"].toString().contains("udp"));
// MTProto
ui->mtEMailTxt->setText(mtSettings["users"].toArray().first().toObject()["email"].toString());
ui->mtUserLevelSB->setValue(mtSettings["users"].toArray().first().toObject()["level"].toInt());
ui->mtSecretTxt->setText(mtSettings["users"].toArray().first().toObject()["secret"].toString());
mtEMailTxt->setText(mtSettings["users"].toArray().first().toObject()["email"].toString());
mtUserLevelSB->setValue(mtSettings["users"].toArray().first().toObject()["level"].toInt());
mtSecretTxt->setText(mtSettings["users"].toArray().first().toObject()["secret"].toString());
isLoading = false;
}
InboundEditor::~InboundEditor()
{
delete ui;
}
void InboundEditor::on_inboundProtocolCombo_currentIndexChanged(const QString &arg1)
@ -129,7 +126,7 @@ void InboundEditor::on_inboundProtocolCombo_currentIndexChanged(const QString &a
void InboundEditor::on_inboundProtocolCombo_currentIndexChanged(int index)
{
ui->stackedWidget->setCurrentIndex(index);
stackedWidget->setCurrentIndex(index);
}
void InboundEditor::on_inboundTagTxt_textEdited(const QString &arg1)
@ -160,8 +157,8 @@ void InboundEditor::on_httpRemoveUserBtn_clicked()
{
PREPARE_RETURN
if (ui->httpAccountListBox->currentRow() != -1) {
auto item = ui->httpAccountListBox->currentItem();
if (httpAccountListBox->currentRow() != -1) {
auto item = httpAccountListBox->currentItem();
auto list = httpSettings["accounts"].toArray();
for (int i = 0 ; i < list.count(); i++) {
@ -172,7 +169,7 @@ void InboundEditor::on_httpRemoveUserBtn_clicked()
list.removeAt(i);
httpSettings["accounts"] = list;
LOG(MODULE_UI, "Removed http inbound user " + entry.toStdString())
ui->httpAccountListBox->takeItem(ui->httpAccountListBox->currentRow());
httpAccountListBox->takeItem(httpAccountListBox->currentRow());
}
}
@ -185,8 +182,8 @@ void InboundEditor::on_httpRemoveUserBtn_clicked()
void InboundEditor::on_httpAddUserBtn_clicked()
{
PREPARE_RETURN
auto user = ui->httpAddUserTxt->text();
auto pass = ui->httpAddPasswordTxt->text();
auto user = httpAddUserTxt->text();
auto pass = httpAddPasswordTxt->text();
//
auto list = httpSettings["accounts"].toArray();
@ -199,13 +196,13 @@ void InboundEditor::on_httpAddUserBtn_clicked()
}
}
ui->httpAddUserTxt->clear();
ui->httpAddPasswordTxt->clear();
httpAddUserTxt->clear();
httpAddPasswordTxt->clear();
QJsonObject entry;
entry["user"] = user;
entry["pass"] = pass;
list.append(entry);
ui->httpAccountListBox->addItem(user + ":" + pass);
httpAccountListBox->addItem(user + ":" + pass);
httpSettings["accounts"] = list;
}
@ -213,8 +210,8 @@ void InboundEditor::on_socksRemoveUserBtn_clicked()
{
PREPARE_RETURN
if (ui->socksAccountListBox->currentRow() != -1) {
auto item = ui->socksAccountListBox->currentItem();
if (socksAccountListBox->currentRow() != -1) {
auto item = socksAccountListBox->currentItem();
auto list = socksSettings["accounts"].toArray();
for (int i = 0 ; i < list.count(); i++) {
@ -225,7 +222,7 @@ void InboundEditor::on_socksRemoveUserBtn_clicked()
list.removeAt(i);
socksSettings["accounts"] = list;
LOG(MODULE_UI, "Removed http inbound user " + entry.toStdString())
ui->socksAccountListBox->takeItem(ui->socksAccountListBox->currentRow());
socksAccountListBox->takeItem(socksAccountListBox->currentRow());
return;
}
}
@ -237,8 +234,8 @@ void InboundEditor::on_socksRemoveUserBtn_clicked()
void InboundEditor::on_socksAddUserBtn_clicked()
{
PREPARE_RETURN
auto user = ui->socksAddUserTxt->text();
auto pass = ui->socksAddPasswordTxt->text();
auto user = socksAddUserTxt->text();
auto pass = socksAddPasswordTxt->text();
//
auto list = socksSettings["accounts"].toArray();
@ -251,13 +248,13 @@ void InboundEditor::on_socksAddUserBtn_clicked()
}
}
ui->socksAddUserTxt->clear();
ui->socksAddPasswordTxt->clear();
socksAddUserTxt->clear();
socksAddPasswordTxt->clear();
QJsonObject entry;
entry["user"] = user;
entry["pass"] = pass;
list.append(entry);
ui->socksAccountListBox->addItem(user + ":" + pass);
socksAccountListBox->addItem(user + ":" + pass);
socksSettings["accounts"] = list;
}
@ -283,7 +280,7 @@ void InboundEditor::on_enableSniffingCB_stateChanged(int arg1)
{
PREPARE_RETURN
sniffing["enabled"] = arg1 == Qt::Checked;
ui->destOverrideList->setEnabled(arg1 == Qt::Checked);
destOverrideList->setEnabled(arg1 == Qt::Checked);
}
void InboundEditor::on_destOverrideList_itemChanged(QListWidgetItem *item)
@ -292,8 +289,8 @@ void InboundEditor::on_destOverrideList_itemChanged(QListWidgetItem *item)
Q_UNUSED(item)
QJsonArray list;
for (int i = 0; i < ui->destOverrideList->count(); i++) {
auto _item = ui->destOverrideList->item(i);
for (int i = 0; i < destOverrideList->count(); i++) {
auto _item = destOverrideList->item(i);
if (_item->checkState() == Qt::Checked) {
list.append(_item->text().toLower());
@ -337,8 +334,8 @@ void InboundEditor::on_dokoTCPCB_stateChanged(int arg1)
{
PREPARE_RETURN
Q_UNUSED(arg1)
bool hasTCP = ui->dokoTCPCB->checkState() == Qt::Checked;
bool hasUDP = ui->dokoUDPCB->checkState() == Qt::Checked;
bool hasTCP = dokoTCPCB->checkState() == Qt::Checked;
bool hasUDP = dokoUDPCB->checkState() == Qt::Checked;
QString str = "";
str += hasTCP ? "tcp" : "";
str += (hasTCP && hasUDP) ? "," : "";
@ -350,8 +347,8 @@ void InboundEditor::on_dokoUDPCB_stateChanged(int arg1)
{
PREPARE_RETURN
Q_UNUSED(arg1)
bool hasTCP = ui->dokoTCPCB->checkState() == Qt::Checked;
bool hasUDP = ui->dokoUDPCB->checkState() == Qt::Checked;
bool hasTCP = dokoTCPCB->checkState() == Qt::Checked;
bool hasUDP = dokoUDPCB->checkState() == Qt::Checked;
QString str = "";
str += hasTCP ? "tcp" : "";
str += (hasTCP && hasUDP) ? "," : "";

View File

@ -1,16 +1,12 @@
#ifndef W_INBOUNDEDITOR_H
#ifndef W_INBOUNDEDITOR_H
#define W_INBOUNDEDITOR_H
#include <QDialog>
#include <QJsonObject>
#include <QListWidgetItem>
#include "ui_w_InboundEditor.h"
namespace Ui
{
class InboundEditor;
}
class InboundEditor : public QDialog
class InboundEditor : public QDialog, private Ui::InboundEditor
{
Q_OBJECT
@ -85,7 +81,6 @@ class InboundEditor : public QDialog
private:
QJsonObject GenerateNewRoot();
void LoadUIData();
Ui::InboundEditor *ui;
QJsonObject original;
QJsonObject root;
//

View File

@ -1,39 +1,37 @@
#include "w_JsonEditor.hpp"
#include "ui_w_JsonEditor.h"
#include "w_JsonEditor.hpp"
#include "QvUtils.hpp"
JsonEditor::JsonEditor(QJsonObject rootObject, QWidget *parent) :
QDialog(parent),
ui(new Ui::JsonEditor)
QDialog(parent)
{
ui->setupUi(this);
setupUi(this);
original = rootObject;
final = rootObject;
QString jsonString = JsonToString(rootObject);
if (VerifyJsonString(&jsonString).isEmpty()) {
LOG(MODULE_UI, "Begin loading Json Model")
ui->jsonTree->setModel(&model);
jsonTree->setModel(&model);
model.loadJson(QJsonDocument(rootObject).toJson());
} else {
QvMessageBox(this, tr("Json Contains Syntax Errors"), tr("Original Json may contain syntax errors. Json tree is disabled."));
}
ui->jsonEditor->setText(JsonToString(rootObject));
ui->jsonTree->expandAll();
ui->jsonTree->resizeColumnToContents(0);
jsonEditor->setText(JsonToString(rootObject));
jsonTree->expandAll();
jsonTree->resizeColumnToContents(0);
}
QJsonObject JsonEditor::OpenEditor()
{
int resultCode = this->exec();
auto string = ui->jsonEditor->toPlainText();
auto string = jsonEditor->toPlainText();
while (resultCode == QDialog::Accepted && !VerifyJsonString(&string).isEmpty()) {
QvMessageBox(this, tr("Json Contains Syntax Errors"), tr("You must correct these errors before continue."));
resultCode = this->exec();
string = ui->jsonEditor->toPlainText();
string = jsonEditor->toPlainText();
}
return resultCode == QDialog::Accepted ? final : original;
@ -41,21 +39,20 @@ QJsonObject JsonEditor::OpenEditor()
JsonEditor::~JsonEditor()
{
delete ui;
}
void JsonEditor::on_jsonEditor_textChanged()
{
auto string = ui->jsonEditor->toPlainText();
auto string = jsonEditor->toPlainText();
auto VerifyResult = VerifyJsonString(&string);
ui->jsonValidateStatus->setText(VerifyResult);
jsonValidateStatus->setText(VerifyResult);
if (VerifyResult.isEmpty()) {
BLACK(jsonEditor)
final = JsonFromString(string);
model.loadJson(QJsonDocument(final).toJson());
ui->jsonTree->expandAll();
ui->jsonTree->resizeColumnToContents(0);
jsonTree->expandAll();
jsonTree->resizeColumnToContents(0);
} else {
RED(jsonEditor)
}
@ -63,13 +60,13 @@ void JsonEditor::on_jsonEditor_textChanged()
void JsonEditor::on_formatJsonBtn_clicked()
{
auto string = ui->jsonEditor->toPlainText();
auto string = jsonEditor->toPlainText();
auto VerifyResult = VerifyJsonString(&string);
ui->jsonValidateStatus->setText(VerifyResult);
jsonValidateStatus->setText(VerifyResult);
if (VerifyResult.isEmpty()) {
BLACK(jsonEditor)
ui->jsonEditor->setPlainText(JsonToString(JsonFromString(string)));
jsonEditor->setPlainText(JsonToString(JsonFromString(string)));
} else {
RED(jsonEditor)
QvMessageBox(this, tr("Json Contains Syntax Errors"), tr("Please fix it and retry later."));

View File

@ -4,13 +4,9 @@
#include <QDialog>
#include <QtCore>
#include "QJsonModel.hpp"
#include "ui_w_JsonEditor.h"
namespace Ui
{
class JsonEditor;
}
class JsonEditor : public QDialog
class JsonEditor : public QDialog, private Ui::JsonEditor
{
Q_OBJECT
@ -28,7 +24,6 @@ class JsonEditor : public QDialog
QJsonModel model;
QJsonObject original;
QJsonObject final;
Ui::JsonEditor *ui;
};
#endif // W_JSONEDITOR_H

View File

@ -19,7 +19,9 @@
#include "w_PrefrencesWindow.hpp"
#include "w_SubscriptionEditor.hpp"
#include "w_JsonEditor.hpp"
#include "w_ExportConfig.hpp"
#include "QvPingModel.hpp"
#include "QvNetSpeedPlugin.hpp"
#define TRAY_TOOLTIP_PREFIX "Qv2ray " QV2RAY_VERSION_STRING
@ -27,7 +29,6 @@
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
vinstance(),
ui(new Ui::MainWindow),
uploadList(),
downloadList(),
HTTPRequestHelper(),
@ -35,7 +36,7 @@ MainWindow::MainWindow(QWidget *parent)
{
auto conf = GetGlobalConfig();
vinstance = new Qv2Instance(this);
ui->setupUi(this);
setupUi(this);
this->setWindowIcon(QIcon(":/icons/qv2ray.ico"));
hTray->setIcon(this->windowIcon());
hTray->setToolTip(TRAY_TOOLTIP_PREFIX);
@ -49,8 +50,7 @@ MainWindow::MainWindow(QWidget *parent)
QAction *action_RCM_RenameConnection = new QAction(tr("Rename"), this);
QAction *action_RCM_StartThis = new QAction(tr("Connect to this"), this);
QAction *action_RCM_EditJson = new QAction(tr("Edit as Json"), this);
QAction *action_RCM_ShareLink = new QAction(tr("Share as vmess://"), this);
QAction *action_RCM_ShareQR = new QAction(tr("Share as QRCore"), this);
QAction *action_RCM_ShareQR = new QAction(tr("Share as QRCode/vmess Uri"), this);
//
action_Tray_Start->setEnabled(true);
action_Tray_Stop->setEnabled(false);
@ -68,14 +68,13 @@ MainWindow::MainWindow(QWidget *parent)
connect(action_Tray_Reconnect, &QAction::triggered, this, &MainWindow::on_reconnectButton_clicked);
connect(action_Tray_Quit, &QAction::triggered, this, &MainWindow::quit);
connect(hTray, &QSystemTrayIcon::activated, this, &MainWindow::on_activatedTray);
connect(ui->logText, &QTextBrowser::textChanged, this, &MainWindow::QTextScrollToBottom);
connect(logText, &QTextBrowser::textChanged, this, &MainWindow::QTextScrollToBottom);
connect(action_RCM_RenameConnection, &QAction::triggered, this, &MainWindow::on_action_RenameConnection_triggered);
connect(action_RCM_StartThis, &QAction::triggered, this, &MainWindow::on_action_StartThis_triggered);
connect(action_RCM_EditJson, &QAction::triggered, this, &MainWindow::on_action_RCM_EditJson_triggered);
// TODO: UNCOMMENT THIS....
LOG(MODULE_UI, "SHARE OPTION TODO...")
//connect(action_RCM_ShareLink, &QAction::triggered, this, &MainWindow::on_action_RCM_ShareLink_triggered);
//connect(action_RCM_ShareQR, &QAction::triggered, this, &MainWindow::on_action_RCM_ShareQR_triggered);
//
// Share optionss
connect(action_RCM_ShareQR, &QAction::triggered, this, &MainWindow::on_action_RCM_ShareQR_triggered);
//
connect(this, &MainWindow::Connect, this, &MainWindow::on_startButton_clicked);
connect(this, &MainWindow::DisConnect, this, &MainWindow::on_stopButton_clicked);
@ -87,7 +86,6 @@ MainWindow::MainWindow(QWidget *parent)
listMenu.addAction(action_RCM_RenameConnection);
listMenu.addAction(action_RCM_StartThis);
listMenu.addAction(action_RCM_EditJson);
listMenu.addAction(action_RCM_ShareLink);
listMenu.addAction(action_RCM_ShareQR);
//
LoadConnections();
@ -108,40 +106,40 @@ MainWindow::MainWindow(QWidget *parent)
downloadSerie->append(i, 0);
}
speedChart = new QChart();
speedChart->setTheme(conf.UISettings.useDarkChartStyle ? QChart::ChartThemeDark : QChart::ChartThemeLight);
speedChart->setTitle("Qv2ray Speed Chart");
speedChart->legend()->hide();
speedChart->createDefaultAxes();
speedChart->addSeries(uploadSerie);
speedChart->addSeries(downloadSerie);
speedChart->createDefaultAxes();
speedChart->axes(Qt::Vertical).first()->setRange(0, 512);
static_cast<QValueAxis>(speedChart->axes(Qt::Horizontal).first()).setLabelFormat("dd.dd");
speedChart->axes(Qt::Horizontal).first()->setRange(0, 30);
speedChart->setContentsMargins(-20, -45, -20, -25);
speedChartView = new QChartView(speedChart, this);
speedChartObj = new QChart();
speedChartObj->setTheme(conf.UISettings.useDarkChartStyle ? QChart::ChartThemeDark : QChart::ChartThemeLight);
speedChartObj->setTitle("Qv2ray Speed Chart");
speedChartObj->legend()->hide();
speedChartObj->createDefaultAxes();
speedChartObj->addSeries(uploadSerie);
speedChartObj->addSeries(downloadSerie);
speedChartObj->createDefaultAxes();
speedChartObj->axes(Qt::Vertical).first()->setRange(0, 512);
static_cast<QValueAxis>(speedChartObj->axes(Qt::Horizontal).first()).setLabelFormat("dd.dd");
speedChartObj->axes(Qt::Horizontal).first()->setRange(0, 30);
speedChartObj->setContentsMargins(-20, -45, -20, -25);
speedChartView = new QChartView(speedChartObj, this);
speedChartView->setRenderHint(QPainter::RenderHint::HighQualityAntialiasing, true);
auto layout = new QHBoxLayout(ui->speedChart);
auto layout = new QHBoxLayout(speedChart);
layout->addWidget(speedChartView);
ui->speedChart->setLayout(layout);
speedChart->setLayout(layout);
//
if (vinstance->ValidateKernal()) {
if (conf.autoStartConfig != "" && QList<string>::fromStdList(conf.configs).contains(conf.autoStartConfig)) {
CurrentConnectionName = QSTRING(conf.autoStartConfig);
auto item = ui->connectionListWidget->findItems(QSTRING(conf.autoStartConfig), Qt::MatchExactly).front();
auto item = connectionListWidget->findItems(QSTRING(conf.autoStartConfig), Qt::MatchExactly).front();
item->setSelected(true);
ui->connectionListWidget->setCurrentItem(item);
connectionListWidget->setCurrentItem(item);
on_connectionListWidget_itemClicked(item);
on_startButton_clicked();
hasAutoStart = true;
trayMenu->actions()[0]->setText(tr("Show"));
} else {
if (ui->connectionListWidget->count() != 0) {
if (connectionListWidget->count() != 0) {
// The first one is default.
ui->connectionListWidget->setCurrentRow(0);
ShowAndSetConnection(ui->connectionListWidget->item(0)->text(), true, false);
connectionListWidget->setCurrentRow(0);
ShowAndSetConnection(connectionListWidget->item(0)->text(), true, false);
}
}
}
@ -157,14 +155,15 @@ MainWindow::MainWindow(QWidget *parent)
void MainWindow::on_action_StartThis_triggered()
{
if (ui->connectionListWidget->selectedItems().empty()) {
if (connectionListWidget->selectedItems().empty()) {
QvMessageBox(this, tr("No connection selected!"), tr("Please select a config from the list."));
return;
}
CurrentConnectionName = ui->connectionListWidget->currentItem()->text();
CurrentConnectionName = connectionListWidget->currentItem()->text();
on_reconnectButton_clicked();
}
void MainWindow::VersionUpdate(QByteArray &data)
{
auto conf = GetGlobalConfig();
@ -199,42 +198,44 @@ void MainWindow::VersionUpdate(QByteArray &data)
}
}
}
void MainWindow::LoadConnections()
{
auto conf = GetGlobalConfig();
connections = GetConnections(conf.configs);
ui->connectionListWidget->clear();
connectionListWidget->clear();
for (int i = 0; i < connections.count(); i++) {
ui->connectionListWidget->addItem(connections.keys()[i]);
connectionListWidget->addItem(connections.keys()[i]);
}
ui->connectionListWidget->sortItems();
ui->removeConfigButton->setEnabled(false);
ui->editConfigButton->setEnabled(false);
ui->editJsonBtn->setEnabled(false);
ui->duplicateBtn->setEnabled(false);
connectionListWidget->sortItems();
removeConfigButton->setEnabled(false);
editConfigButton->setEnabled(false);
editJsonBtn->setEnabled(false);
duplicateBtn->setEnabled(false);
// We set the current item back...
if (vinstance->VCoreStatus == STARTED && !CurrentConnectionName.isEmpty()) {
auto items = ui->connectionListWidget->findItems(CurrentConnectionName, Qt::MatchFlag::MatchExactly);
auto items = connectionListWidget->findItems(CurrentConnectionName, Qt::MatchFlag::MatchExactly);
if (items.count() > 0) {
ui->connectionListWidget->setCurrentItem(items.first());
connectionListWidget->setCurrentItem(items.first());
}
ShowAndSetConnection(CurrentConnectionName, false, false);
}
}
void MainWindow::OnConfigListChanged(bool need_restart)
{
auto statusText = ui->statusLabel->text();
auto statusText = statusLabel->text();
//
// A strange bug prevents us to change the UI language `live`ly
// https://github.com/lhy0403/Qv2ray/issues/34
//
//ui->retranslateUi(this);
ui->statusLabel->setText(statusText);
//retranslateUi(this);
statusLabel->setText(statusText);
bool isRunning = vinstance->VCoreStatus == STARTED;
if (isRunning && need_restart) on_stopButton_clicked();
@ -243,17 +244,19 @@ void MainWindow::OnConfigListChanged(bool need_restart)
if (isRunning && need_restart) on_startButton_clicked();
}
MainWindow::~MainWindow()
{
hTray->hide();
delete this->hTray;
delete this->vinstance;
delete ui;
}
void MainWindow::UpdateLog()
{
ui->logText->append(vinstance->ReadProcessOutput().trimmed());
logText->append(vinstance->ReadProcessOutput().trimmed());
}
void MainWindow::on_startButton_clicked()
{
if (vinstance->VCoreStatus != STARTED) {
@ -271,7 +274,7 @@ void MainWindow::on_startButton_clicked()
}
LOG(MODULE_VCORE, ("Connecting to: " + CurrentConnectionName).toStdString())
ui->logText->clear();
logText->clear();
CurrentFullConfig = GenerateRuntimeConfig(connections[CurrentConnectionName]);
StartPreparation(CurrentFullConfig);
bool startFlag = this->vinstance->StartVCore();
@ -279,7 +282,7 @@ void MainWindow::on_startButton_clicked()
if (startFlag) {
this->hTray->showMessage("Qv2ray", tr("Connected To Server: ") + CurrentConnectionName);
hTray->setToolTip(TRAY_TOOLTIP_PREFIX "\r\n" + tr("Connected To Server: ") + CurrentConnectionName);
ui->statusLabel->setText(tr("Connected") + ": " + CurrentConnectionName);
statusLabel->setText(tr("Connected") + ": " + CurrentConnectionName);
if (GetGlobalConfig().enableStats) {
vinstance->SetAPIPort(GetGlobalConfig().statsPort);
@ -291,10 +294,11 @@ void MainWindow::on_startButton_clicked()
trayMenu->actions()[3]->setEnabled(startFlag);
trayMenu->actions()[4]->setEnabled(startFlag);
//
ui->startButton->setEnabled(!startFlag);
ui->stopButton->setEnabled(startFlag);
startButton->setEnabled(!startFlag);
stopButton->setEnabled(startFlag);
}
}
void MainWindow::on_stopButton_clicked()
{
if (vinstance->VCoreStatus != STOPPED) {
@ -302,25 +306,27 @@ void MainWindow::on_stopButton_clicked()
killTimer(speedTimerId);
hTray->setToolTip(TRAY_TOOLTIP_PREFIX);
QFile(QV2RAY_GENERATED_FILE_PATH).remove();
ui->statusLabel->setText(tr("Disconnected"));
ui->logText->setText("");
statusLabel->setText(tr("Disconnected"));
logText->setText("");
trayMenu->actions()[2]->setEnabled(true);
trayMenu->actions()[3]->setEnabled(false);
trayMenu->actions()[4]->setEnabled(false);
//
ui->startButton->setEnabled(true);
ui->stopButton->setEnabled(false);
startButton->setEnabled(true);
stopButton->setEnabled(false);
//
ui->netspeedLabel->setText("0.00 B/s\r\n0.00 B/s");
ui->dataamountLabel->setText("0.00 B\r\n0.00 B");
netspeedLabel->setText("0.00 B/s\r\n0.00 B/s");
dataamountLabel->setText("0.00 B\r\n0.00 B");
}
}
void MainWindow::closeEvent(QCloseEvent *event)
{
this->hide();
trayMenu->actions()[0]->setText(tr("Show"));
event->ignore();
}
void MainWindow::on_activatedTray(QSystemTrayIcon::ActivationReason reason)
{
switch (reason) {
@ -352,6 +358,7 @@ void MainWindow::on_activatedTray(QSystemTrayIcon::ActivationReason reason)
break;
}
}
void MainWindow::ToggleVisibility()
{
if (this->isHidden()) {
@ -367,22 +374,26 @@ void MainWindow::ToggleVisibility()
trayMenu->actions()[0]->setText(tr("Show"));
}
}
void MainWindow::quit()
{
Utils::NetSpeedPlugin::StopProcessingPlugins();
on_stopButton_clicked();
QApplication::quit();
}
void MainWindow::on_actionExit_triggered()
{
quit();
}
void MainWindow::QTextScrollToBottom()
{
auto bar = ui->logText->verticalScrollBar();
auto bar = logText->verticalScrollBar();
if (bar->value() >= bar->maximum() - 10) bar->setValue(bar->maximum());
}
void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnection, bool ApplyConnection)
{
// Check empty again...
@ -392,29 +403,29 @@ void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnect
auto outBoundRoot = (connections[guiConnectionName])["outbounds"].toArray().first().toObject();
//
auto outboundType = outBoundRoot["protocol"].toString();
ui->_OutBoundTypeLabel->setText(outboundType);
ui->removeConfigButton->setEnabled(true);
ui->editConfigButton->setEnabled(true);
ui->editJsonBtn->setEnabled(true);
ui->duplicateBtn->setEnabled(true);
_OutBoundTypeLabel->setText(outboundType);
removeConfigButton->setEnabled(true);
editConfigButton->setEnabled(true);
editJsonBtn->setEnabled(true);
duplicateBtn->setEnabled(true);
if (outboundType == "vmess") {
auto Server = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
ui->_hostLabel->setText(QSTRING(Server.address));
ui->_portLabel->setText(QSTRING(to_string(Server.port)));
_hostLabel->setText(QSTRING(Server.address));
_portLabel->setText(QSTRING(to_string(Server.port)));
} else if (outboundType == "shadowsocks") {
auto x = JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
auto Server = StructFromJsonString<ShadowSocksServerObject>(x);
ui->_hostLabel->setText(QSTRING(Server.address));
ui->_portLabel->setText(QSTRING(to_string(Server.port)));
_hostLabel->setText(QSTRING(Server.address));
_portLabel->setText(QSTRING(to_string(Server.port)));
} else if (outboundType == "socks") {
auto x = JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
auto Server = StructFromJsonString<SocksServerObject>(x);
ui->_hostLabel->setText(QSTRING(Server.address));
ui->_portLabel->setText(QSTRING(to_string(Server.port)));
_hostLabel->setText(QSTRING(Server.address));
_portLabel->setText(QSTRING(to_string(Server.port)));
}
ui->routeCountLabel->setText(QString::number((connections[guiConnectionName])["routing"].toArray().count()));
routeCountLabel->setText(QString::number((connections[guiConnectionName])["routing"].toArray().count()));
// --------- END Show Connection
//
@ -428,56 +439,64 @@ void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnect
on_reconnectButton_clicked();
}
}
void MainWindow::on_connectionListWidget_itemClicked(QListWidgetItem *item)
{
Q_UNUSED(item)
int currentRow = ui->connectionListWidget->currentRow();
int currentRow = connectionListWidget->currentRow();
if (currentRow < 0) return;
QString currentText = ui->connectionListWidget->currentItem()->text();
QString currentText = connectionListWidget->currentItem()->text();
bool canSetConnection = !isRenamingInProgress && vinstance->VCoreStatus != STARTED;
ShowAndSetConnection(currentText, canSetConnection, false);
}
void MainWindow::on_prefrencesBtn_clicked()
{
PrefrencesWindow *w = new PrefrencesWindow(this);
connect(w, &PrefrencesWindow::s_reload_config, this, &MainWindow::OnConfigListChanged);
w->show();
}
void MainWindow::on_connectionListWidget_doubleClicked(const QModelIndex &index)
{
Q_UNUSED(index)
int currentRow = ui->connectionListWidget->currentRow();
int currentRow = connectionListWidget->currentRow();
if (currentRow < 0) return;
QString currentText = ui->connectionListWidget->currentItem()->text();
QString currentText = connectionListWidget->currentItem()->text();
ShowAndSetConnection(currentText, true, true);
}
void MainWindow::on_clearlogButton_clicked()
{
ui->logText->clear();
logText->clear();
}
void MainWindow::on_connectionListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
Q_UNUSED(previous)
isRenamingInProgress = false;
on_connectionListWidget_itemClicked(current);
}
void MainWindow::on_connectionListWidget_customContextMenuRequested(const QPoint &pos)
{
Q_UNUSED(pos)
listMenu.popup(QCursor::pos());
}
void MainWindow::on_action_RenameConnection_triggered()
{
auto item = ui->connectionListWidget->currentItem();
auto item = connectionListWidget->currentItem();
item->setFlags(item->flags() | Qt::ItemIsEditable);
ui->connectionListWidget->editItem(item);
connectionListWidget->editItem(item);
originalName = item->text();
isRenamingInProgress = true;
}
void MainWindow::on_connectionListWidget_itemChanged(QListWidgetItem *item)
{
DEBUG(MODULE_UI, "A connection ListViewItem is changed.")
@ -516,17 +535,18 @@ void MainWindow::on_connectionListWidget_itemChanged(QListWidgetItem *item)
if (running) CurrentConnectionName = newName;
OnConfigListChanged(running);
auto newItem = ui->connectionListWidget->findItems(newName, Qt::MatchExactly).front();
ui->connectionListWidget->setCurrentItem(newItem);
auto newItem = connectionListWidget->findItems(newName, Qt::MatchExactly).front();
connectionListWidget->setCurrentItem(newItem);
}
}
}
void MainWindow::on_removeConfigButton_clicked()
{
if (ui->connectionListWidget->currentIndex().row() < 0) return;
if (connectionListWidget->currentIndex().row() < 0) return;
if (QvMessageBoxAsk(this, tr("Removing this Connection"), tr("Are you sure to remove this connection?")) == QMessageBox::Yes) {
auto connectionName = ui->connectionListWidget->currentItem()->text();
auto connectionName = connectionListWidget->currentItem()->text();
if (connectionName == CurrentConnectionName) {
on_stopButton_clicked();
@ -547,13 +567,15 @@ void MainWindow::on_removeConfigButton_clicked()
ShowAndSetConnection(CurrentConnectionName, false, false);
}
}
void MainWindow::on_importConfigButton_clicked()
{
// TODO
ImportConfigWindow *w = new ImportConfigWindow(this);
//w->OpenImporter();
w->OpenImporter();
OnConfigListChanged(false);
}
void MainWindow::on_addConfigButton_clicked()
{
OutboundEditor *w = new OutboundEditor(this);
@ -581,15 +603,16 @@ void MainWindow::on_addConfigButton_clicked()
ShowAndSetConnection(CurrentConnectionName, false, false);
}
}
void MainWindow::on_editConfigButton_clicked()
{
// Check if we have a connection selected...
if (ui->connectionListWidget->currentIndex().row() < 0) {
if (connectionListWidget->currentIndex().row() < 0) {
QvMessageBox(this, tr("No Config Selected"), tr("Please Select a Config"));
return;
}
auto alias = ui->connectionListWidget->currentItem()->text();
auto alias = connectionListWidget->currentItem()->text();
auto outBoundRoot = connections[alias];
QJsonObject root;
bool isChanged = false;
@ -617,20 +640,22 @@ void MainWindow::on_editConfigButton_clicked()
ShowAndSetConnection(CurrentConnectionName, false, false);
}
}
void MainWindow::on_reconnectButton_clicked()
{
on_stopButton_clicked();
on_startButton_clicked();
}
void MainWindow::on_action_RCM_EditJson_triggered()
{
// Check if we have a connection selected...
if (ui->connectionListWidget->currentIndex().row() < 0) {
if (connectionListWidget->currentIndex().row() < 0) {
QvMessageBox(this, tr("No Config Selected"), tr("Please Select a Config"));
return;
}
auto alias = ui->connectionListWidget->currentItem()->text();
auto alias = connectionListWidget->currentItem()->text();
JsonEditor *w = new JsonEditor(connections[alias], this);
auto root = w->OpenEditor();
bool isChanged = w->result() == QDialog::Accepted;
@ -643,23 +668,30 @@ void MainWindow::on_action_RCM_EditJson_triggered()
ShowAndSetConnection(CurrentConnectionName, false, false);
}
}
void MainWindow::on_editJsonBtn_clicked()
{
// See above.
on_action_RCM_EditJson_triggered();
}
void MainWindow::on_pingTestBtn_clicked()
{
// Ping
}
void MainWindow::on_shareQRButton_clicked()
void MainWindow::on_shareBtn_clicked()
{
// Share QR
ConfigExporter v("FUTURE VMESS:// GOES HERE!", this);
v.OpenExport();
}
void MainWindow::on_shareVMessButton_clicked()
void MainWindow::on_action_RCM_ShareQR_triggered()
{
// Share vmess://
on_shareBtn_clicked();
}
void MainWindow::timerEvent(QTimerEvent *event)
{
Q_UNUSED(event)
@ -699,7 +731,7 @@ void MainWindow::timerEvent(QTimerEvent *event)
downloadSerie->replace(29, 29, graphVDown);
//
max = MAX(MAX(graphVUp, graphVDown), historyMax);
speedChart->axes(Qt::Vertical).first()->setRange(0, max * 1.2);
speedChartObj->axes(Qt::Vertical).first()->setRange(0, max * 1.2);
//
//
totalSpeedUp = FormatBytes(_totalSpeedUp);
@ -707,18 +739,18 @@ void MainWindow::timerEvent(QTimerEvent *event)
totalDataUp = FormatBytes(_totalDataUp);
totalDataDown = FormatBytes(_totalDataDown);
//
ui->netspeedLabel->setText(totalSpeedUp + "/s\r\n" + totalSpeedDown + "/s");
ui->dataamountLabel->setText(totalDataUp + "\r\n" + totalDataDown);
netspeedLabel->setText(totalSpeedUp + "/s\r\n" + totalSpeedDown + "/s");
dataamountLabel->setText(totalDataUp + "\r\n" + totalDataDown);
//
hTray->setToolTip(TRAY_TOOLTIP_PREFIX "\r\n" + tr("Connected To Server: ") + CurrentConnectionName + "\r\nUp: " + totalSpeedUp + "/s Down: " + totalSpeedDown + "/s");
}
void MainWindow::on_duplicateBtn_clicked()
{
if (ui->connectionListWidget->currentRow() < 0) {
if (connectionListWidget->currentRow() < 0) {
return;
}
auto alias = ui->connectionListWidget->currentItem()->text();
auto alias = connectionListWidget->currentItem()->text();
auto conf = ConvertConfigFromFile(QV2RAY_CONFIG_DIR + alias + QV2RAY_CONFIG_FILE_EXTENSION, false);
// Alias may change.
SaveConnectionConfig(conf, &alias, false);

View File

@ -13,12 +13,7 @@
#include "ui_w_MainWindow.h"
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
class MainWindow : public QMainWindow, Ui::MainWindow
{
Q_OBJECT
public:
@ -32,6 +27,7 @@ class MainWindow : public QMainWindow
void UpdateLog();
void OnConfigListChanged(bool need_restart);
private slots:
void on_action_RCM_ShareQR_triggered();
void on_startButton_clicked();
void on_stopButton_clicked();
void on_reconnectButton_clicked();
@ -68,9 +64,8 @@ class MainWindow : public QMainWindow
void on_pingTestBtn_clicked();
void on_shareQRButton_clicked();
void on_shareBtn_clicked();
void on_shareVMessButton_clicked();
void on_duplicateBtn_clicked();
public:
@ -86,10 +81,8 @@ class MainWindow : public QMainWindow
void timerEvent(QTimerEvent *event);
private:
Ui::MainWindow *ui;
//
QChartView *speedChartView;
QChart *speedChart;
QChart *speedChartObj;
QSplineSeries *uploadSerie;
QSplineSeries *downloadSerie;
QList<double> uploadList;

View File

@ -388,16 +388,9 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="shareQRButton">
<widget class="QToolButton" name="shareBtn">
<property name="text">
<string>QR Code</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="shareVMessButton">
<property name="text">
<string>VMess</string>
<string>Share</string>
</property>
</widget>
</item>

View File

@ -1,4 +1,4 @@
#include <QDebug>
#include <QDebug>
#include <QFile>
#include <QIntValidator>
#include <iostream>
@ -11,14 +11,11 @@ OutboundEditor::OutboundEditor(QWidget *parent)
: QDialog(parent),
Tag(""),
Mux(),
ui(new Ui::OutboundEditor),
stream(),
vmess(),
shadowsocks()
{
ui->setupUi(this);
ui->portLineEdit->setValidator(new QIntValidator());
ui->alterLineEdit->setValidator(new QIntValidator());
setupUi(this);
shadowsocks = ShadowSocksServerObject();
socks = SocksServerObject();
socks.users.push_back(SocksServerObject::UserObject());
@ -36,7 +33,7 @@ OutboundEditor::OutboundEditor(QJsonObject outboundEntry, QWidget *parent)
{
Original = outboundEntry;
Tag = outboundEntry["tag"].toString();
ui->tagTxt->setText(Tag);
tagTxt->setText(Tag);
OutboundType = outboundEntry["protocol"].toString();
Mux = outboundEntry["mux"].toObject();
@ -68,7 +65,6 @@ OutboundEditor::OutboundEditor(QJsonObject outboundEntry, QWidget *parent)
OutboundEditor::~OutboundEditor()
{
delete ui;
}
QJsonObject OutboundEditor::OpenEditor()
@ -79,8 +75,8 @@ QJsonObject OutboundEditor::OpenEditor()
QString OutboundEditor::GetFriendlyName()
{
auto host = ui->ipLineEdit->text().replace(":", "-").replace("/", "_").replace("\\", "_");
auto port = ui->portLineEdit->text().replace(":", "-").replace("/", "_").replace("\\", "_");
auto host = ipLineEdit->text().replace(":", "-").replace("/", "_").replace("\\", "_");
auto port = portLineEdit->text().replace(":", "-").replace("/", "_").replace("\\", "_");
auto type = OutboundType;
QString name = Tag.isEmpty() ? host + "-[" + port + "]-" + type : Tag;
return name;
@ -89,18 +85,18 @@ QString OutboundEditor::GetFriendlyName()
void OutboundEditor::ReLoad_GUI_JSON_ModelContent()
{
if (OutboundType == "vmess") {
ui->outBoundTypeCombo->setCurrentIndex(0);
ui->ipLineEdit->setText(QSTRING(vmess.address));
ui->portLineEdit->setText(QString::number(vmess.port));
ui->idLineEdit->setText(QSTRING(vmess.users.front().id));
ui->alterLineEdit->setText(QString::number(vmess.users.front().alterId));
ui->securityCombo->setCurrentText(QSTRING(vmess.users.front().security));
ui->tranportCombo->setCurrentText(QSTRING(stream.network));
ui->tlsCB->setChecked(stream.security == "tls");
outBoundTypeCombo->setCurrentIndex(0);
ipLineEdit->setText(QSTRING(vmess.address));
portLineEdit->setText(QString::number(vmess.port));
idLineEdit->setText(QSTRING(vmess.users.front().id));
alterLineEdit->setValue(vmess.users.front().alterId);
securityCombo->setCurrentText(QSTRING(vmess.users.front().security));
tranportCombo->setCurrentText(QSTRING(stream.network));
tlsCB->setChecked(stream.security == "tls");
// TCP
ui->tcpHeaderTypeCB->setCurrentText(QSTRING(stream.tcpSettings.header.type));
ui->tcpRequestTxt->setPlainText(StructToJsonString(stream.tcpSettings.header.request));
ui->tcpRespTxt->setPlainText(StructToJsonString(stream.tcpSettings.header.response));
tcpHeaderTypeCB->setCurrentText(QSTRING(stream.tcpSettings.header.type));
tcpRequestTxt->setPlainText(StructToJsonString(stream.tcpSettings.header.request));
tcpRespTxt->setPlainText(StructToJsonString(stream.tcpSettings.header.response));
// HTTP
QString allHosts;
@ -108,57 +104,57 @@ void OutboundEditor::ReLoad_GUI_JSON_ModelContent()
allHosts = allHosts + QSTRING(host) + "\r\n";
}
ui->httpHostTxt->setPlainText(allHosts);
ui->httpPathTxt->setText(QSTRING(stream.httpSettings.path));
httpHostTxt->setPlainText(allHosts);
httpPathTxt->setText(QSTRING(stream.httpSettings.path));
// WS
ui->wsPathTxt->setText(QSTRING(stream.wsSettings.path));
wsPathTxt->setText(QSTRING(stream.wsSettings.path));
QString wsHeaders = std::accumulate(stream.wsSettings.headers.begin(), stream.wsSettings.headers.end(), QString(), [](QString in1, const pair<string, string> &in2) {
in1 += QSTRING(in2.first + "|" + in2.second) + "\r\n";
return in1;
});
ui->wsHeadersTxt->setPlainText(wsHeaders);
wsHeadersTxt->setPlainText(wsHeaders);
// mKCP
ui->kcpMTU->setValue(stream.kcpSettings.mtu);
ui->kcpTTI->setValue(stream.kcpSettings.tti);
ui->kcpHeaderType->setCurrentText(QSTRING(stream.kcpSettings.header.type));
ui->kcpCongestionCB->setChecked(stream.kcpSettings.congestion);
ui->kcpReadBufferSB->setValue(stream.kcpSettings.readBufferSize);
ui->kcpUploadCapacSB->setValue(stream.kcpSettings.uplinkCapacity);
ui->kcpDownCapacitySB->setValue(stream.kcpSettings.downlinkCapacity);
ui->kcpWriteBufferSB->setValue(stream.kcpSettings.writeBufferSize);
kcpMTU->setValue(stream.kcpSettings.mtu);
kcpTTI->setValue(stream.kcpSettings.tti);
kcpHeaderType->setCurrentText(QSTRING(stream.kcpSettings.header.type));
kcpCongestionCB->setChecked(stream.kcpSettings.congestion);
kcpReadBufferSB->setValue(stream.kcpSettings.readBufferSize);
kcpUploadCapacSB->setValue(stream.kcpSettings.uplinkCapacity);
kcpDownCapacitySB->setValue(stream.kcpSettings.downlinkCapacity);
kcpWriteBufferSB->setValue(stream.kcpSettings.writeBufferSize);
// DS
ui->dsPathTxt->setText(QSTRING(stream.dsSettings.path));
dsPathTxt->setText(QSTRING(stream.dsSettings.path));
// QUIC
ui->quicKeyTxt->setText(QSTRING(stream.quicSettings.key));
ui->quicSecurityCB->setCurrentText(QSTRING(stream.quicSettings.security));
ui->quicHeaderTypeCB->setCurrentText(QSTRING(stream.quicSettings.header.type));
quicKeyTxt->setText(QSTRING(stream.quicSettings.key));
quicSecurityCB->setCurrentText(QSTRING(stream.quicSettings.security));
quicHeaderTypeCB->setCurrentText(QSTRING(stream.quicSettings.header.type));
// SOCKOPT
ui->tProxyCB->setCurrentText(QSTRING(stream.sockopt.tproxy));
ui->tcpFastOpenCB->setChecked(stream.sockopt.tcpFastOpen);
ui->soMarkSpinBox->setValue(stream.sockopt.mark);
tProxyCB->setCurrentText(QSTRING(stream.sockopt.tproxy));
tcpFastOpenCB->setChecked(stream.sockopt.tcpFastOpen);
soMarkSpinBox->setValue(stream.sockopt.mark);
} else if (OutboundType == "shadowsocks") {
ui->outBoundTypeCombo->setCurrentIndex(1);
outBoundTypeCombo->setCurrentIndex(1);
// ShadowSocks Configs
ui->ipLineEdit->setText(QSTRING(shadowsocks.address));
ui->portLineEdit->setText(QString::number(shadowsocks.port));
ui->ss_emailTxt->setText(QSTRING(shadowsocks.email));
ui->ss_levelSpin->setValue(shadowsocks.level);
ui->ss_otaCheckBox->setChecked(shadowsocks.ota);
ui->ss_passwordTxt->setText(QSTRING(shadowsocks.password));
ui->ss_encryptionMethod->setCurrentText(QSTRING(shadowsocks.method));
ipLineEdit->setText(QSTRING(shadowsocks.address));
portLineEdit->setText(QString::number(shadowsocks.port));
ss_emailTxt->setText(QSTRING(shadowsocks.email));
ss_levelSpin->setValue(shadowsocks.level);
ss_otaCheckBox->setChecked(shadowsocks.ota);
ss_passwordTxt->setText(QSTRING(shadowsocks.password));
ss_encryptionMethod->setCurrentText(QSTRING(shadowsocks.method));
} else if (OutboundType == "socks") {
ui->outBoundTypeCombo->setCurrentIndex(2);
ui->ipLineEdit->setText(QSTRING(socks.address));
ui->portLineEdit->setText(QString::number(socks.port));
outBoundTypeCombo->setCurrentIndex(2);
ipLineEdit->setText(QSTRING(socks.address));
portLineEdit->setText(QString::number(socks.port));
if (socks.users.empty()) socks.users.push_back(SocksServerObject::UserObject());
ui->socks_PasswordTxt->setText(QSTRING(socks.users.front().pass));
ui->socks_UserNameTxt->setText(QSTRING(socks.users.front().user));
socks_PasswordTxt->setText(QSTRING(socks.users.front().pass));
socks_UserNameTxt->setText(QSTRING(socks.users.front().user));
}
ui->muxEnabledCB->setChecked(Mux["enabled"].toBool());
ui->muxConcurrencyTxt->setValue(Mux["concurrency"].toInt());
muxEnabledCB->setChecked(Mux["enabled"].toBool());
muxConcurrencyTxt->setValue(Mux["concurrency"].toInt());
}
@ -190,13 +186,6 @@ void OutboundEditor::on_idLineEdit_textEdited(const QString &arg1)
vmess.users.front().id = arg1.toStdString();
}
void OutboundEditor::on_alterLineEdit_textEdited(const QString &arg1)
{
if (vmess.users.empty()) vmess.users.push_back(VMessServerObject::UserObject());
vmess.users.front().alterId = stoi(arg1.toStdString());
}
void OutboundEditor::on_securityCombo_currentIndexChanged(const QString &arg1)
{
if (vmess.users.empty()) vmess.users.push_back(VMessServerObject::UserObject());
@ -217,7 +206,7 @@ void OutboundEditor::on_httpPathTxt_textEdited(const QString &arg1)
void OutboundEditor::on_httpHostTxt_textChanged()
{
try {
QStringList hosts = ui->httpHostTxt->toPlainText().replace("\r", "").split("\n");
QStringList hosts = httpHostTxt->toPlainText().replace("\r", "").split("\n");
stream.httpSettings.host.clear();
foreach (auto host, hosts) {
@ -234,7 +223,7 @@ void OutboundEditor::on_httpHostTxt_textChanged()
void OutboundEditor::on_wsHeadersTxt_textChanged()
{
try {
QStringList headers = ui->wsHeadersTxt->toPlainText().replace("\r", "").split("\n");
QStringList headers = wsHeadersTxt->toPlainText().replace("\r", "").split("\n");
stream.wsSettings.headers.clear();
foreach (auto header, headers) {
@ -256,21 +245,21 @@ void OutboundEditor::on_wsHeadersTxt_textChanged()
void OutboundEditor::on_tcpRequestDefBtn_clicked()
{
ui->tcpRequestTxt->clear();
ui->tcpRequestTxt->insertPlainText("{\"version\":\"1.1\",\"method\":\"GET\",\"path\":[\"/\"],\"headers\":"
"{\"Host\":[\"www.baidu.com\",\"www.bing.com\"],\"User-Agent\":"
"[\"Mozilla/5.0 (Windows NT 10.0; WOW64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\","
"\"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) "
"AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 "
"Safari/601.1.46\"],\"Accept-Encoding\":[\"gzip, deflate\"],"
"\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}");
tcpRequestTxt->clear();
tcpRequestTxt->insertPlainText("{\"version\":\"1.1\",\"method\":\"GET\",\"path\":[\"/\"],\"headers\":"
"{\"Host\":[\"www.baidu.com\",\"www.bing.com\"],\"User-Agent\":"
"[\"Mozilla/5.0 (Windows NT 10.0; WOW64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\","
"\"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) "
"AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 "
"Safari/601.1.46\"],\"Accept-Encoding\":[\"gzip, deflate\"],"
"\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}");
}
void OutboundEditor::on_tcpRespDefBtn_clicked()
{
ui->tcpRespTxt->clear();
ui->tcpRespTxt->insertPlainText("{\"version\":\"1.1\",\"status\":\"200\",\"reason\":\"OK\",\"headers\":{\"Content-Type\":[\"application/octet-stream\",\"video/mpeg\"],\"Transfer-Encoding\":[\"chunked\"],\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}");
tcpRespTxt->clear();
tcpRespTxt->insertPlainText("{\"version\":\"1.1\",\"status\":\"200\",\"reason\":\"OK\",\"headers\":{\"Content-Type\":[\"application/octet-stream\",\"video/mpeg\"],\"Transfer-Encoding\":[\"chunked\"],\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}");
}
QJsonObject OutboundEditor::GenerateConnectionJson()
@ -369,7 +358,7 @@ void OutboundEditor::on_kcpHeaderType_currentTextChanged(const QString &arg1)
}
void OutboundEditor::on_tranportCombo_currentIndexChanged(int index)
{
ui->v2rayStackView->setCurrentIndex(index);
v2rayStackView->setCurrentIndex(index);
}
void OutboundEditor::on_dsPathTxt_textEdited(const QString &arg1)
{
@ -377,8 +366,8 @@ void OutboundEditor::on_dsPathTxt_textEdited(const QString &arg1)
}
void OutboundEditor::on_outBoundTypeCombo_currentIndexChanged(int index)
{
ui->outboundTypeStackView->setCurrentIndex(index);
OutboundType = ui->outBoundTypeCombo->currentText().toLower();
outboundTypeStackView->setCurrentIndex(index);
OutboundType = outBoundTypeCombo->currentText().toLower();
}
void OutboundEditor::on_ss_emailTxt_textEdited(const QString &arg1)
@ -418,9 +407,9 @@ void OutboundEditor::on_socks_PasswordTxt_textEdited(const QString &arg1)
void OutboundEditor::on_tcpRequestEditBtn_clicked()
{
JsonEditor *w = new JsonEditor(JsonFromString(ui->tcpRequestTxt->toPlainText()), this);
JsonEditor *w = new JsonEditor(JsonFromString(tcpRequestTxt->toPlainText()), this);
auto rString = JsonToString(w->OpenEditor());
ui->tcpRequestTxt->setPlainText(rString);
tcpRequestTxt->setPlainText(rString);
auto tcpReqObject = StructFromJsonString<TSObjects::HTTPRequestObject>(rString);
stream.tcpSettings.header.request = tcpReqObject;
delete w;
@ -428,9 +417,9 @@ void OutboundEditor::on_tcpRequestEditBtn_clicked()
void OutboundEditor::on_tcpResponseEditBtn_clicked()
{
JsonEditor *w = new JsonEditor(JsonFromString(ui->tcpRespTxt->toPlainText()), this);
JsonEditor *w = new JsonEditor(JsonFromString(tcpRespTxt->toPlainText()), this);
auto rString = JsonToString(w->OpenEditor());
ui->tcpRespTxt->setPlainText(rString);
tcpRespTxt->setPlainText(rString);
auto tcpRspObject = StructFromJsonString<TSObjects::HTTPResponseObject>(rString);
stream.tcpSettings.header.response = tcpRspObject;
delete w;
@ -450,3 +439,10 @@ void OutboundEditor::on_muxConcurrencyTxt_valueChanged(int arg1)
{
Mux["concurrency"] = arg1;
}
void OutboundEditor::on_alterLineEdit_valueChanged(int arg1)
{
if (vmess.users.empty()) vmess.users.push_back(VMessServerObject::UserObject());
vmess.users.front().alterId = arg1;
}

View File

@ -6,12 +6,7 @@
#include "QvCoreConfigObjects.hpp"
#include "ui_w_OutboundEditor.h"
namespace Ui
{
class OutboundEditor;
}
class OutboundEditor : public QDialog
class OutboundEditor : public QDialog, private Ui::OutboundEditor
{
Q_OBJECT
public:
@ -31,8 +26,6 @@ class OutboundEditor : public QDialog
void on_idLineEdit_textEdited(const QString &arg1);
void on_alterLineEdit_textEdited(const QString &arg1);
void on_securityCombo_currentIndexChanged(const QString &arg1);
void on_tranportCombo_currentIndexChanged(const QString &arg1);
@ -111,6 +104,8 @@ class OutboundEditor : public QDialog
void on_muxConcurrencyTxt_valueChanged(int arg1);
void on_alterLineEdit_valueChanged(int arg1);
private:
QString Tag;
void ReLoad_GUI_JSON_ModelContent();
@ -118,7 +113,6 @@ class OutboundEditor : public QDialog
QJsonObject Original;
QJsonObject Result;
QJsonObject Mux;
Ui::OutboundEditor *ui;
//
// Connection Configs
QString OutboundType;

View File

@ -202,12 +202,12 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="alterLineEdit">
<property name="maxLength">
<number>5</number>
<widget class="QSpinBox" name="alterLineEdit">
<property name="maximum">
<number>1024</number>
</property>
<property name="placeholderText">
<string>64</string>
<property name="value">
<number>16</number>
</property>
</widget>
</item>

View File

@ -15,104 +15,104 @@ PrefrencesWindow::PrefrencesWindow(QWidget *parent) : QDialog(parent),
CurrentConfig(),
ui(new Ui::PrefrencesWindow)
{
ui->setupUi(this);
setupUi(this);
// We add locales
ui->languageComboBox->clear();
languageComboBox->clear();
QDirIterator it(":/translations");
while (it.hasNext()) {
ui->languageComboBox->addItem(it.next().split("/").last().split(".").first());
languageComboBox->addItem(it.next().split("/").last().split(".").first());
}
//
ui->nsBarContentCombo->addItems(NetSpeedPluginMessages.values());
ui->themeCombo->addItems(QStyleFactory::keys());
nsBarContentCombo->addItems(NetSpeedPluginMessages.values());
themeCombo->addItems(QStyleFactory::keys());
//
ui->qvVersion->setText(QV2RAY_VERSION_STRING);
qvVersion->setText(QV2RAY_VERSION_STRING);
CurrentConfig = GetGlobalConfig();
//
ui->themeCombo->setCurrentText(QSTRING(CurrentConfig.UISettings.theme));
ui->darkChartThemeCB->setChecked(CurrentConfig.UISettings.useDarkChartStyle);
ui->languageComboBox->setCurrentText(QSTRING(CurrentConfig.UISettings.language));
ui->logLevelComboBox->setCurrentIndex(CurrentConfig.logLevel);
ui->tProxyCheckBox->setChecked(CurrentConfig.tProxySupport);
themeCombo->setCurrentText(QSTRING(CurrentConfig.UISettings.theme));
darkChartThemeCB->setChecked(CurrentConfig.UISettings.useDarkChartStyle);
languageComboBox->setCurrentText(QSTRING(CurrentConfig.UISettings.language));
logLevelComboBox->setCurrentIndex(CurrentConfig.logLevel);
tProxyCheckBox->setChecked(CurrentConfig.tProxySupport);
//
//
ui->listenIPTxt->setText(QSTRING(CurrentConfig.inBoundSettings.listenip));
listenIPTxt->setText(QSTRING(CurrentConfig.inBoundSettings.listenip));
//
bool have_http = CurrentConfig.inBoundSettings.http_port != 0;
ui->httpCB->setChecked(have_http);
ui->httpPortLE->setValue(CurrentConfig.inBoundSettings.http_port);
ui->httpAuthCB->setChecked(CurrentConfig.inBoundSettings.http_useAuth);
httpCB->setChecked(have_http);
httpPortLE->setValue(CurrentConfig.inBoundSettings.http_port);
httpAuthCB->setChecked(CurrentConfig.inBoundSettings.http_useAuth);
//
ui->httpAuthCB->setEnabled(have_http);
ui->httpAuthCB->setChecked(CurrentConfig.inBoundSettings.http_useAuth);
ui->httpAuthUsernameTxt->setEnabled(have_http && CurrentConfig.inBoundSettings.http_useAuth);
ui->httpAuthPasswordTxt->setEnabled(have_http && CurrentConfig.inBoundSettings.http_useAuth);
ui->httpAuthUsernameTxt->setText(QSTRING(CurrentConfig.inBoundSettings.httpAccount.user));
ui->httpAuthPasswordTxt->setText(QSTRING(CurrentConfig.inBoundSettings.httpAccount.pass));
httpAuthCB->setEnabled(have_http);
httpAuthCB->setChecked(CurrentConfig.inBoundSettings.http_useAuth);
httpAuthUsernameTxt->setEnabled(have_http && CurrentConfig.inBoundSettings.http_useAuth);
httpAuthPasswordTxt->setEnabled(have_http && CurrentConfig.inBoundSettings.http_useAuth);
httpAuthUsernameTxt->setText(QSTRING(CurrentConfig.inBoundSettings.httpAccount.user));
httpAuthPasswordTxt->setText(QSTRING(CurrentConfig.inBoundSettings.httpAccount.pass));
//
//
bool have_socks = CurrentConfig.inBoundSettings.socks_port != 0;
ui->socksCB->setChecked(have_socks);
ui->socksPortLE->setValue(CurrentConfig.inBoundSettings.socks_port);
ui->socksAuthCB->setChecked(CurrentConfig.inBoundSettings.socks_useAuth);
socksCB->setChecked(have_socks);
socksPortLE->setValue(CurrentConfig.inBoundSettings.socks_port);
socksAuthCB->setChecked(CurrentConfig.inBoundSettings.socks_useAuth);
//
ui->socksAuthCB->setEnabled(have_socks);
ui->socksAuthCB->setChecked(CurrentConfig.inBoundSettings.socks_useAuth);
ui->socksAuthUsernameTxt->setEnabled(have_socks && CurrentConfig.inBoundSettings.socks_useAuth);
ui->socksAuthPasswordTxt->setEnabled(have_socks && CurrentConfig.inBoundSettings.socks_useAuth);
ui->socksAuthUsernameTxt->setText(QSTRING(CurrentConfig.inBoundSettings.socksAccount.user));
ui->socksAuthPasswordTxt->setText(QSTRING(CurrentConfig.inBoundSettings.socksAccount.pass));
socksAuthCB->setEnabled(have_socks);
socksAuthCB->setChecked(CurrentConfig.inBoundSettings.socks_useAuth);
socksAuthUsernameTxt->setEnabled(have_socks && CurrentConfig.inBoundSettings.socks_useAuth);
socksAuthPasswordTxt->setEnabled(have_socks && CurrentConfig.inBoundSettings.socks_useAuth);
socksAuthUsernameTxt->setText(QSTRING(CurrentConfig.inBoundSettings.socksAccount.user));
socksAuthPasswordTxt->setText(QSTRING(CurrentConfig.inBoundSettings.socksAccount.pass));
// Socks UDP Options
ui->socksUDPCB->setChecked(CurrentConfig.inBoundSettings.socksUDP);
ui->socksUDPIP->setEnabled(CurrentConfig.inBoundSettings.socksUDP);
ui->socksUDPIP->setText(QSTRING(CurrentConfig.inBoundSettings.socksLocalIP));
socksUDPCB->setChecked(CurrentConfig.inBoundSettings.socksUDP);
socksUDPIP->setEnabled(CurrentConfig.inBoundSettings.socksUDP);
socksUDPIP->setText(QSTRING(CurrentConfig.inBoundSettings.socksLocalIP));
//
//
ui->vCorePathTxt->setText(QSTRING(CurrentConfig.v2CorePath));
ui->vCoreAssetsPathTxt->setText(QSTRING(CurrentConfig.v2AssetsPath));
ui->statsCheckbox->setChecked(CurrentConfig.enableStats);
ui->statsPortBox->setValue(CurrentConfig.statsPort);
vCorePathTxt->setText(QSTRING(CurrentConfig.v2CorePath));
vCoreAssetsPathTxt->setText(QSTRING(CurrentConfig.v2AssetsPath));
statsCheckbox->setChecked(CurrentConfig.enableStats);
statsPortBox->setValue(CurrentConfig.statsPort);
//
//
ui->bypassCNCb->setChecked(CurrentConfig.bypassCN);
ui->proxyDefaultCb->setChecked(CurrentConfig.enableProxy);
bypassCNCb->setChecked(CurrentConfig.bypassCN);
proxyDefaultCb->setChecked(CurrentConfig.enableProxy);
//
ui->localDNSCb->setChecked(CurrentConfig.withLocalDNS);
localDNSCb->setChecked(CurrentConfig.withLocalDNS);
//
ui->DNSListTxt->clear();
DNSListTxt->clear();
foreach (auto dnsStr, CurrentConfig.dnsList) {
auto str = QString::fromStdString(dnsStr).trimmed();
if (!str.isEmpty()) {
ui->DNSListTxt->appendPlainText(str);
DNSListTxt->appendPlainText(str);
}
}
foreach (auto connection, CurrentConfig.configs) {
ui->autoStartCombo->addItem(QSTRING(connection));
autoStartCombo->addItem(QSTRING(connection));
}
ui->autoStartCombo->setCurrentText(QSTRING(CurrentConfig.autoStartConfig));
ui->cancelIgnoreVersionBtn->setEnabled(CurrentConfig.ignoredVersion != "");
ui->ignoredNextVersion->setText(QSTRING(CurrentConfig.ignoredVersion));
autoStartCombo->setCurrentText(QSTRING(CurrentConfig.autoStartConfig));
cancelIgnoreVersionBtn->setEnabled(CurrentConfig.ignoredVersion != "");
ignoredNextVersion->setText(QSTRING(CurrentConfig.ignoredVersion));
//
for (size_t i = 0; i < CurrentConfig.speedBarConfig.Pages.size(); i++) {
ui->nsBarPagesList->addItem(tr("Page") + QString::number(i + 1) + ": " + QString::number(CurrentConfig.speedBarConfig.Pages[i].Lines.size()) + " " + tr("Item(s)"));
nsBarPagesList->addItem(tr("Page") + QString::number(i + 1) + ": " + QString::number(CurrentConfig.speedBarConfig.Pages[i].Lines.size()) + " " + tr("Item(s)"));
}
if (CurrentConfig.speedBarConfig.Pages.size() > 0) {
ui->nsBarPagesList->setCurrentRow(0);
nsBarPagesList->setCurrentRow(0);
on_nsBarPagesList_currentRowChanged(0);
} else {
ui->nsBarVerticalLayout->setEnabled(false);
ui->nsBarLinesList->setEnabled(false);
ui->nsBarLineDelBTN->setEnabled(false);
ui->nsBarLineAddBTN->setEnabled(false);
ui->nsBarPageYOffset->setEnabled(false);
nsBarVerticalLayout->setEnabled(false);
nsBarLinesList->setEnabled(false);
nsBarLineDelBTN->setEnabled(false);
nsBarLineAddBTN->setEnabled(false);
nsBarPageYOffset->setEnabled(false);
}
CurrentBarPageId = 0;
@ -126,8 +126,8 @@ PrefrencesWindow::~PrefrencesWindow()
void PrefrencesWindow::on_buttonBox_accepted()
{
int sp = ui->socksPortLE->text().toInt();
int hp = ui->httpPortLE->text().toInt() ;
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"));
@ -141,44 +141,44 @@ void PrefrencesWindow::on_buttonBox_accepted()
void PrefrencesWindow::on_httpCB_stateChanged(int checked)
{
NEEDRESTART
ui->httpPortLE->setEnabled(checked == Qt::Checked);
ui->httpAuthCB->setEnabled(checked == Qt::Checked);
ui->httpAuthUsernameTxt->setEnabled(checked == Qt::Checked && ui->httpAuthCB->isChecked());
ui->httpAuthPasswordTxt->setEnabled(checked == Qt::Checked && ui->httpAuthCB->isChecked());
httpPortLE->setEnabled(checked == Qt::Checked);
httpAuthCB->setEnabled(checked == Qt::Checked);
httpAuthUsernameTxt->setEnabled(checked == Qt::Checked && httpAuthCB->isChecked());
httpAuthPasswordTxt->setEnabled(checked == Qt::Checked && httpAuthCB->isChecked());
CurrentConfig.inBoundSettings.http_port = checked == Qt::Checked ? CurrentConfig.inBoundSettings.http_port : 0;
if (checked != Qt::Checked) {
ui->httpPortLE->setValue(0);
httpPortLE->setValue(0);
}
}
void PrefrencesWindow::on_socksCB_stateChanged(int checked)
{
NEEDRESTART
ui->socksPortLE->setEnabled(checked == Qt::Checked);
ui->socksAuthCB->setEnabled(checked == Qt::Checked);
ui->socksAuthUsernameTxt->setEnabled(checked == Qt::Checked && ui->socksAuthCB->isChecked());
ui->socksAuthPasswordTxt->setEnabled(checked == Qt::Checked && ui->socksAuthCB->isChecked());
socksPortLE->setEnabled(checked == Qt::Checked);
socksAuthCB->setEnabled(checked == Qt::Checked);
socksAuthUsernameTxt->setEnabled(checked == Qt::Checked && socksAuthCB->isChecked());
socksAuthPasswordTxt->setEnabled(checked == Qt::Checked && socksAuthCB->isChecked());
CurrentConfig.inBoundSettings.socks_port = checked == Qt::Checked ? CurrentConfig.inBoundSettings.socks_port : 0;
if (checked != Qt::Checked) {
ui->socksPortLE->setValue(0);
socksPortLE->setValue(0);
}
}
void PrefrencesWindow::on_httpAuthCB_stateChanged(int checked)
{
NEEDRESTART
ui->httpAuthUsernameTxt->setEnabled(checked == Qt::Checked);
ui->httpAuthPasswordTxt->setEnabled(checked == Qt::Checked);
httpAuthUsernameTxt->setEnabled(checked == Qt::Checked);
httpAuthPasswordTxt->setEnabled(checked == Qt::Checked);
CurrentConfig.inBoundSettings.http_useAuth = checked == Qt::Checked;
}
void PrefrencesWindow::on_socksAuthCB_stateChanged(int checked)
{
NEEDRESTART
ui->socksAuthUsernameTxt->setEnabled(checked == Qt::Checked);
ui->socksAuthPasswordTxt->setEnabled(checked == Qt::Checked);
socksAuthUsernameTxt->setEnabled(checked == Qt::Checked);
socksAuthPasswordTxt->setEnabled(checked == Qt::Checked);
CurrentConfig.inBoundSettings.socks_useAuth = checked == Qt::Checked;
}
@ -191,7 +191,7 @@ void PrefrencesWindow::on_languageComboBox_currentTextChanged(const QString &arg
//
//if (QApplication::installTranslator(getTranslator(&arg1))) {
// LOG(MODULE_UI, "Loaded translations " + arg1.toStdString())
// ui->retranslateUi(this);
// retranslateUi(this);
//} else {
// QvMessageBox(this, tr("#Prefrences"), tr("#SwitchTranslationError"));
//}
@ -255,14 +255,14 @@ void PrefrencesWindow::on_selectVAssetBtn_clicked()
{
NEEDRESTART
QString dir = QFileDialog::getExistingDirectory(this, tr("Open v2ray assets folder"), QDir::currentPath());
ui->vCoreAssetsPathTxt->setText(dir);
vCoreAssetsPathTxt->setText(dir);
on_vCoreAssetsPathTxt_textEdited(dir);
}
void PrefrencesWindow::on_selectVCoreBtn_clicked()
{
QString core = QFileDialog::getOpenFileName(this, tr("Open v2ray core file"), QDir::currentPath());
ui->vCorePathTxt->setText(core);
vCorePathTxt->setText(core);
on_vCorePathTxt_textEdited(core);
}
@ -276,7 +276,7 @@ void PrefrencesWindow::on_DNSListTxt_textChanged()
{
if (finishedLoading) {
try {
QStringList hosts = ui->DNSListTxt->toPlainText().replace("\r", "").split("\n");
QStringList hosts = DNSListTxt->toPlainText().replace("\r", "").split("\n");
CurrentConfig.dnsList.clear();
foreach (auto host, hosts) {
@ -307,7 +307,7 @@ void PrefrencesWindow::on_aboutQt_clicked()
void PrefrencesWindow::on_cancelIgnoreVersionBtn_clicked()
{
CurrentConfig.ignoredVersion.clear();
ui->cancelIgnoreVersionBtn->setEnabled(false);
cancelIgnoreVersionBtn->setEnabled(false);
}
void PrefrencesWindow::on_tProxyCheckBox_stateChanged(int arg1)
@ -327,7 +327,7 @@ void PrefrencesWindow::on_tProxyCheckBox_stateChanged(int arg1)
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) {
ui->tProxyCheckBox->setChecked(false);
tProxyCheckBox->setChecked(false);
LOG(MODULE_UI, "Canceled enabling tProxy feature.")
} else {
LOG(MODULE_VCORE, "ENABLING tProxy Support")
@ -404,7 +404,7 @@ void PrefrencesWindow::on_tProxyCheckBox_stateChanged(int arg1)
#else
Q_UNUSED(arg1)
ui->tProxyCheckBox->setChecked(false);
tProxyCheckBox->setChecked(false);
// No such uid gid thing on Windows and macOS
QvMessageBox(this, tr("Prefrences"), tr("tProxy is not supported on macOS and Windows"));
#endif
@ -443,7 +443,7 @@ void PrefrencesWindow::on_socksUDPCB_stateChanged(int arg1)
{
NEEDRESTART
CurrentConfig.inBoundSettings.socksUDP = arg1 == Qt::Checked;
ui->socksUDPIP->setEnabled(arg1 == Qt::Checked);
socksUDPIP->setEnabled(arg1 == Qt::Checked);
}
void PrefrencesWindow::on_socksUDPIP_textEdited(const QString &arg1)
@ -456,7 +456,7 @@ void PrefrencesWindow::on_socksUDPIP_textEdited(const QString &arg1)
#define CurrentBarPage CurrentConfig.speedBarConfig.Pages[this->CurrentBarPageId]
#define CurrentBarLine CurrentBarPage.Lines[this->CurrentBarLineId]
#define SET_LINE_LIST_TEXT ui->nsBarLinesList->currentItem()->setText(GetBarLineDescription(CurrentBarLine));
#define SET_LINE_LIST_TEXT nsBarLinesList->currentItem()->setText(GetBarLineDescription(CurrentBarLine));
void PrefrencesWindow::on_nsBarPageAddBTN_clicked()
{
@ -467,32 +467,32 @@ void PrefrencesWindow::on_nsBarPageAddBTN_clicked()
QvBarLine line;
CurrentBarPage.Lines.push_back(line);
CurrentBarLineId = 0;
ui->nsBarPagesList->addItem(QString::number(CurrentBarPageId));
nsBarPagesList->addItem(QString::number(CurrentBarPageId));
ShowLineParameters(CurrentBarLine);
LOG(MODULE_UI, "Adding new page Id: " + to_string(CurrentBarPageId))
ui->nsBarPageDelBTN->setEnabled(true);
ui->nsBarLineAddBTN->setEnabled(true);
ui->nsBarLineDelBTN->setEnabled(true);
ui->nsBarLinesList->setEnabled(true);
ui->nsBarPageYOffset->setEnabled(true);
nsBarPageDelBTN->setEnabled(true);
nsBarLineAddBTN->setEnabled(true);
nsBarLineDelBTN->setEnabled(true);
nsBarLinesList->setEnabled(true);
nsBarPageYOffset->setEnabled(true);
on_nsBarPagesList_currentRowChanged(static_cast<int>(CurrentBarPageId));
ui->nsBarPagesList->setCurrentRow(static_cast<int>(CurrentBarPageId));
nsBarPagesList->setCurrentRow(static_cast<int>(CurrentBarPageId));
}
void PrefrencesWindow::on_nsBarPageDelBTN_clicked()
{
if (ui->nsBarPagesList->currentRow() >= 0) {
RemoveItem(CurrentConfig.speedBarConfig.Pages, static_cast<size_t>(ui->nsBarPagesList->currentRow()));
ui->nsBarPagesList->takeItem(ui->nsBarPagesList->currentRow());
if (nsBarPagesList->currentRow() >= 0) {
RemoveItem(CurrentConfig.speedBarConfig.Pages, static_cast<size_t>(nsBarPagesList->currentRow()));
nsBarPagesList->takeItem(nsBarPagesList->currentRow());
if (ui->nsBarPagesList->count() <= 0) {
ui->nsBarPageDelBTN->setEnabled(false);
ui->nsBarLineAddBTN->setEnabled(false);
ui->nsBarLineDelBTN->setEnabled(false);
ui->nsBarLinesList->setEnabled(false);
ui->nsBarVerticalLayout->setEnabled(false);
ui->nsBarPageYOffset->setEnabled(false);
ui->nsBarLinesList->clear();
if (nsBarPagesList->count() <= 0) {
nsBarPageDelBTN->setEnabled(false);
nsBarLineAddBTN->setEnabled(false);
nsBarLineDelBTN->setEnabled(false);
nsBarLinesList->setEnabled(false);
nsBarVerticalLayout->setEnabled(false);
nsBarPageYOffset->setEnabled(false);
nsBarLinesList->clear();
}
}
}
@ -509,23 +509,23 @@ void PrefrencesWindow::on_nsBarLineAddBTN_clicked()
QvBarLine line;
CurrentBarPage.Lines.push_back(line);
CurrentBarLineId = CurrentBarPage.Lines.size() - 1;
ui->nsBarLinesList->addItem(QString::number(CurrentBarLineId));
nsBarLinesList->addItem(QString::number(CurrentBarLineId));
ShowLineParameters(CurrentBarLine);
ui->nsBarLineDelBTN->setEnabled(true);
nsBarLineDelBTN->setEnabled(true);
LOG(MODULE_UI, "Adding new line Id: " + to_string(CurrentBarLineId))
ui->nsBarLinesList->setCurrentRow(static_cast<int>(CurrentBarPage.Lines.size() - 1));
nsBarLinesList->setCurrentRow(static_cast<int>(CurrentBarPage.Lines.size() - 1));
}
void PrefrencesWindow::on_nsBarLineDelBTN_clicked()
{
if (ui->nsBarLinesList->currentRow() >= 0) {
RemoveItem(CurrentBarPage.Lines, static_cast<size_t>(ui->nsBarLinesList->currentRow()));
ui->nsBarLinesList->takeItem(ui->nsBarLinesList->currentRow());
if (nsBarLinesList->currentRow() >= 0) {
RemoveItem(CurrentBarPage.Lines, static_cast<size_t>(nsBarLinesList->currentRow()));
nsBarLinesList->takeItem(nsBarLinesList->currentRow());
CurrentBarLineId = 0;
if (ui->nsBarLinesList->count() <= 0) {
ui->nsBarVerticalLayout->setEnabled(false);
ui->nsBarLineDelBTN->setEnabled(false);
if (nsBarLinesList->count() <= 0) {
nsBarVerticalLayout->setEnabled(false);
nsBarLineDelBTN->setEnabled(false);
}
// TODO Disabling some UI;
@ -541,19 +541,19 @@ void PrefrencesWindow::on_nsBarPagesList_currentRowChanged(int currentRow)
// Set all parameters item to the property of the first line.
CurrentBarPageId = static_cast<size_t>(currentRow);
CurrentBarLineId = 0;
ui->nsBarPageYOffset->setValue(CurrentBarPage.OffsetYpx);
ui->nsBarLinesList->clear();
nsBarPageYOffset->setValue(CurrentBarPage.OffsetYpx);
nsBarLinesList->clear();
if (!CurrentBarPage.Lines.empty()) {
for (auto line : CurrentBarPage.Lines) {
auto description = GetBarLineDescription(line);
ui->nsBarLinesList->addItem(description);
nsBarLinesList->addItem(description);
}
ui->nsBarLinesList->setCurrentRow(0);
nsBarLinesList->setCurrentRow(0);
ShowLineParameters(CurrentBarLine);
} else {
ui->nsBarVerticalLayout->setEnabled(false);
nsBarVerticalLayout->setEnabled(false);
}
}
@ -644,28 +644,28 @@ void PrefrencesWindow::ShowLineParameters(QvBarLine &line)
finishedLoading = false;
if (!line.Family.empty()) {
ui->fontComboBox->setCurrentFont(QFont(QSTRING(line.Family)));
fontComboBox->setCurrentFont(QFont(QSTRING(line.Family)));
}
// Colors
ui->nsBarFontASB->setValue(line.ColorA);
ui->nsBarFontBSB->setValue(line.ColorB);
ui->nsBarFontGSB->setValue(line.ColorG);
ui->nsBarFontRSB->setValue(line.ColorR);
nsBarFontASB->setValue(line.ColorA);
nsBarFontBSB->setValue(line.ColorB);
nsBarFontGSB->setValue(line.ColorG);
nsBarFontRSB->setValue(line.ColorR);
//
QColor color = QColor::fromRgb(line.ColorR, line.ColorG, line.ColorB, line.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) + ";");
ui->chooseColorBtn->setStyleSheet(s);
ui->nsBarFontSizeSB->setValue(line.Size);
ui->nsBarFontBoldCB->setChecked(line.Bold);
ui->nsBarFontItalicCB->setChecked(line.Italic);
ui->nsBarContentCombo->setCurrentText(NetSpeedPluginMessages[line.ContentType]);
ui->nsBarTagTxt->setText(QSTRING(line.Message));
chooseColorBtn->setStyleSheet(s);
nsBarFontSizeSB->setValue(line.Size);
nsBarFontBoldCB->setChecked(line.Bold);
nsBarFontItalicCB->setChecked(line.Italic);
nsBarContentCombo->setCurrentText(NetSpeedPluginMessages[line.ContentType]);
nsBarTagTxt->setText(QSTRING(line.Message));
finishedLoading = true;
ui->nsBarVerticalLayout->setEnabled(true);
nsBarVerticalLayout->setEnabled(true);
}
void PrefrencesWindow::on_chooseColorBtn_clicked()

View File

@ -5,12 +5,7 @@
#include <ui_w_PrefrencesWindow.h>
#include "Qv2rayBase.hpp"
namespace Ui
{
class PrefrencesWindow;
}
class PrefrencesWindow : public QDialog
class PrefrencesWindow : public QDialog, private Ui::PrefrencesWindow
{
Q_OBJECT

View File

@ -1,21 +1,19 @@
#include "w_RoutesEditor.hpp"
#include "w_RoutesEditor.hpp"
#include "QvCoreConfigOperations.hpp"
#include "ui_w_RoutesEditor.h"
#include "w_OutboundEditor.hpp"
#include "w_JsonEditor.hpp"
#include "w_InboundEditor.hpp"
#define CurrentRule this->rules[this->currentRuleIndex]
#define STATUS(msg) ui->statusLabel->setText(tr(msg));
#define STATUS(msg) statusLabel->setText(tr(msg));
RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
QDialog(parent),
root(connection),
original(connection),
ui(new Ui::RouteEditor)
original(connection)
{
// TODO Balancer will not be removed if an rule has been removed.
ui->setupUi(this);
setupUi(this);
//
inbounds = root["inbounds"].toArray();
outbounds = root["outbounds"].toArray();
@ -33,8 +31,8 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
rules = QList<RuleObject>::fromStdList(StructFromJsonString<list<RuleObject>>(JsonToString(root["routing"].toObject()["rules"].toArray())));
//
ui->outboundsList->clear();
ui->inboundsList->clear();
outboundsList->clear();
inboundsList->clear();
for (auto out : outbounds) {
bool hasTag = out.toObject().contains("tag");
@ -42,7 +40,7 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
auto protocol = out.toObject()["protocol"].toString();
auto tag = hasTag ? out.toObject()["tag"].toString() : tr("No Tag");
//
ui->outboundsList->addItem(tag + " (" + protocol + ")");
outboundsList->addItem(tag + " (" + protocol + ")");
}
for (auto in : inbounds) {
@ -54,10 +52,10 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
//
auto inItem = new QListWidgetItem(tag + " (" + protocol + ": " + port + ")");
inItem->setCheckState(Qt::Unchecked);
ui->inboundsList->addItem(inItem);
inboundsList->addItem(inItem);
}
ui->routesTable->clearContents();
routesTable->clearContents();
for (int i = 0; i < rules.size(); i++) {
#define rule rules[i]
@ -71,29 +69,29 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
}
//
ui->routesTable->insertRow(ui->routesTable->rowCount());
routesTable->insertRow(routesTable->rowCount());
//
// WARNING There should be an additional check on the final configuration generation process.
auto enabledItem = new QTableWidgetItem(tr("Enabled"));
enabledItem->setCheckState(rule.QV2RAY_RULE_ENABLED ? Qt::Checked : Qt::Unchecked);
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 0, enabledItem);
routesTable->setItem(routesTable->rowCount() - 1, 0, enabledItem);
//
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 1, new QTableWidgetItem(rule.inboundTag.size() > 0 ? Stringify(rule.inboundTag) : tr("Any")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 2, new QTableWidgetItem(QString::number(rule.domain.size() + rule.ip.size()) + " " + tr("Items")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 3, new QTableWidgetItem(QSTRING(rule.outboundTag)));
routesTable->setItem(routesTable->rowCount() - 1, 1, new QTableWidgetItem(rule.inboundTag.size() > 0 ? Stringify(rule.inboundTag) : tr("Any")));
routesTable->setItem(routesTable->rowCount() - 1, 2, new QTableWidgetItem(QString::number(rule.domain.size() + rule.ip.size()) + " " + tr("Items")));
routesTable->setItem(routesTable->rowCount() - 1, 3, new QTableWidgetItem(QSTRING(rule.outboundTag)));
#undef rule
}
if (rules.size() > 0) {
ui->routesTable->setCurrentItem(ui->routesTable->item(0, 0));
routesTable->setCurrentItem(routesTable->item(0, 0));
currentRuleIndex = 0;
ShowRuleDetail(CurrentRule);
} else {
ui->delRouteBtn->setEnabled(false);
delRouteBtn->setEnabled(false);
if (ui->inboundsList->count() > 0) ui->inboundsList->setCurrentRow(0);
if (inboundsList->count() > 0) inboundsList->setCurrentRow(0);
if (ui->outboundsList->count() > 0) ui->outboundsList->setCurrentRow(0);
if (outboundsList->count() > 0) outboundsList->setCurrentRow(0);
}
}
@ -147,7 +145,6 @@ QJsonObject RouteEditor::OpenEditor()
RouteEditor::~RouteEditor()
{
delete ui;
}
void RouteEditor::on_buttonBox_accepted()
@ -158,9 +155,9 @@ void RouteEditor::on_outboundsList_currentRowChanged(int currentRow)
{
auto outBoundRoot = outbounds[currentRow].toObject();
auto outboundType = outBoundRoot["protocol"].toString();
ui->outboundTagLabel->setText(outBoundRoot.contains("tag") ? outBoundRoot["tag"].toString() : tr("No Tag"));
outboundTagLabel->setText(outBoundRoot.contains("tag") ? outBoundRoot["tag"].toString() : tr("No Tag"));
//
ui->outboundTypeLabel->setText(outboundType);
outboundTypeLabel->setText(outboundType);
string serverAddress = "N/A";
string serverPort = "N/A";
@ -180,45 +177,45 @@ void RouteEditor::on_outboundsList_currentRowChanged(int currentRow)
serverPort = to_string(Server.port);
}
ui->outboundAddressLabel->setText(QSTRING(serverAddress));
ui->outboundPortLabel->setText(QSTRING(serverPort));
outboundAddressLabel->setText(QSTRING(serverAddress));
outboundPortLabel->setText(QSTRING(serverPort));
}
void RouteEditor::on_inboundsList_currentRowChanged(int currentRow)
{
auto inBoundRoot = inbounds[currentRow].toObject();
//
ui->inboundTagLabel->setText(inBoundRoot.contains("tag") ? inBoundRoot["tag"].toString() : tr("No Tag"));
ui->inboundTypeLabel->setText(inBoundRoot["protocol"].toString());
ui->inboundAddressLabel->setText(inBoundRoot["listen"].toString());
ui->inboundPortLabel->setText(inBoundRoot["port"].toVariant().toString());
inboundTagLabel->setText(inBoundRoot.contains("tag") ? inBoundRoot["tag"].toString() : tr("No Tag"));
inboundTypeLabel->setText(inBoundRoot["protocol"].toString());
inboundAddressLabel->setText(inBoundRoot["listen"].toString());
inboundPortLabel->setText(inBoundRoot["port"].toVariant().toString());
}
void RouteEditor::ShowRuleDetail(RuleObject rule)
{
// BUG added the wrong items, should be outbound list.
ui->balancerSelectionCombo->clear();
ui->routeOutboundSelector->clear();
balancerSelectionCombo->clear();
routeOutboundSelector->clear();
for (auto out : outbounds) {
ui->routeOutboundSelector->addItem(out.toObject()["tag"].toString());
ui->balancerSelectionCombo->addItem(out.toObject()["tag"].toString());
routeOutboundSelector->addItem(out.toObject()["tag"].toString());
balancerSelectionCombo->addItem(out.toObject()["tag"].toString());
}
//
// Balancers combo and balancer list.
ui->enableBalancerCB->setChecked(rule.QV2RAY_RULE_USE_BALANCER);
enableBalancerCB->setChecked(rule.QV2RAY_RULE_USE_BALANCER);
if (!QSTRING(rule.balancerTag).isEmpty()) {
ui->balancerList->clear();
ui->balancerList->addItems(Balancers[QSTRING(CurrentRule.balancerTag)]);
balancerList->clear();
balancerList->addItems(Balancers[QSTRING(CurrentRule.balancerTag)]);
}
if (!QSTRING(rule.outboundTag).isEmpty()) {
// Find outbound index by tag.
auto tag = QSTRING(rule.outboundTag);
auto index = FindIndexByTag(outbounds, &tag);
ui->routeOutboundSelector->setCurrentIndex(index);
routeOutboundSelector->setCurrentIndex(index);
//
// Default balancer tag.
// Don't add anything, we just show the configuration.
@ -229,53 +226,53 @@ void RouteEditor::ShowRuleDetail(RuleObject rule)
}
//
for (int i = 0; i < ui->inboundsList->count(); ++i) {
ui->inboundsList->item(i)->setCheckState(Qt::Unchecked);
for (int i = 0; i < inboundsList->count(); ++i) {
inboundsList->item(i)->setCheckState(Qt::Unchecked);
}
auto outboundTag = QSTRING(rule.outboundTag);
int index = FindIndexByTag(outbounds, &outboundTag);
ui->outboundsList->setCurrentRow(index);
outboundsList->setCurrentRow(index);
//
// Networks
auto network = QSTRING(rule.network).toLower();
ui->netUDPRB->setChecked(network.contains("udp"));
ui->netTCPRB->setChecked(network.contains("tcp"));
ui->netBothRB->setChecked(network.contains("tcp") && network.contains("udp"));
netUDPRB->setChecked(network.contains("udp"));
netTCPRB->setChecked(network.contains("tcp"));
netBothRB->setChecked(network.contains("tcp") && network.contains("udp"));
//
// Set protocol checkboxes.
auto protocols = QList<string>::fromStdList(CurrentRule.protocol);
ui->routeProtocolHTTPCB->setChecked(protocols.contains("http"));
ui->routeProtocolTLSCB->setChecked(protocols.contains("tls"));
ui->routeProtocolBTCB->setChecked(protocols.contains("bittorrent"));
routeProtocolHTTPCB->setChecked(protocols.contains("http"));
routeProtocolTLSCB->setChecked(protocols.contains("tls"));
routeProtocolBTCB->setChecked(protocols.contains("bittorrent"));
//
// Port
ui->routePortTxt->setText(QSTRING(CurrentRule.port));
routePortTxt->setText(QSTRING(CurrentRule.port));
//
// Users
QString users = Stringify(CurrentRule.user, NEWLINE);
ui->routeUserTxt->setPlainText(users);
routeUserTxt->setPlainText(users);
//
// Incoming Sources
QString sources = Stringify(CurrentRule.source, NEWLINE);
ui->sourceIPList->setPlainText(sources);
sourceIPList->setPlainText(sources);
//
// Domains
QString domains = Stringify(CurrentRule.domain, NEWLINE);
ui->hostList->setPlainText(domains);
hostList->setPlainText(domains);
//
// Outcoming IPs
QString ips = Stringify(CurrentRule.ip, NEWLINE);
ui->ipList->setPlainText(ips);
ipList->setPlainText(ips);
//
// Inbound Tags
if (rule.inboundTag.size() == 0) {
for (int i = 0; i < ui->inboundsList->count(); i++) {
ui->inboundsList->item(i)->setCheckState(Qt::Checked);
for (int i = 0; i < inboundsList->count(); i++) {
inboundsList->item(i)->setCheckState(Qt::Checked);
}
ui->inboundsList->setCurrentRow(0);
inboundsList->setCurrentRow(0);
} else {
for (auto inboundTag : rule.inboundTag) {
auto inTag = QSTRING(inboundTag);
@ -283,14 +280,14 @@ void RouteEditor::ShowRuleDetail(RuleObject rule)
// FIXED if an inbound is missing (index out of range)
if (_index >= 0) {
if (ui->inboundsList->count() <= _index) {
if (inboundsList->count() <= _index) {
QvMessageBox(this, tr("Route Editor"), tr("Cannot find an inbound by tag: ") + tr("Index Out Of Range"));
LOG(MODULE_UI, "FATAL: An inbound could not be found.")
return;
}
ui->inboundsList->item(_index)->setCheckState(Qt::Checked);
ui->inboundsList->setCurrentRow(_index);
inboundsList->item(_index)->setCheckState(Qt::Checked);
inboundsList->setCurrentRow(_index);
STATUS("OK")
} else {
STATUS("Cannot find inbound by a tag, possible currupted files?")
@ -304,7 +301,7 @@ void RouteEditor::ShowRuleDetail(RuleObject rule)
void RouteEditor::on_editOutboundBtn_clicked()
{
QJsonObject result;
int row = ui->outboundsList->currentRow();
int row = outboundsList->currentRow();
if (row < 0) {
STATUS("No row selected.")
@ -341,14 +338,14 @@ void RouteEditor::on_insertDirectBtn_clicked()
auto tag = "Freedom_" + QString::number(QTime::currentTime().msecsSinceStartOfDay());
auto out = GenerateOutboundEntry("freedom", freedom, QJsonObject(), QJsonObject(), "0.0.0.0", tag);
this->outbounds.append(out);
ui->outboundsList->addItem(tag);
outboundsList->addItem(tag);
STATUS("Added DIRECT outbound")
}
void RouteEditor::on_editInboundBtn_clicked()
{
QJsonObject result;
int row = ui->inboundsList->currentRow();
int row = inboundsList->currentRow();
if (row < 0) return;
@ -380,9 +377,9 @@ void RouteEditor::on_routeProtocolHTTPCB_stateChanged(int arg1)
if (arg1 == Qt::Checked) protocols << "http";
if (ui->routeProtocolTLSCB->isChecked()) protocols << "tls";
if (routeProtocolTLSCB->isChecked()) protocols << "tls";
if (ui->routeProtocolBTCB->isChecked()) protocols << "bittorrent";
if (routeProtocolBTCB->isChecked()) protocols << "bittorrent";
CurrentRule.protocol = protocols.toStdList();
STATUS("Protocol list changed.")
@ -394,9 +391,9 @@ void RouteEditor::on_routeProtocolTLSCB_stateChanged(int arg1)
if (arg1 == Qt::Checked) protocols << "tls";
if (ui->routeProtocolHTTPCB->isChecked()) protocols << "http";
if (routeProtocolHTTPCB->isChecked()) protocols << "http";
if (ui->routeProtocolBTCB->isChecked()) protocols << "bittorrent";
if (routeProtocolBTCB->isChecked()) protocols << "bittorrent";
CurrentRule.protocol = protocols.toStdList();
STATUS("Protocol list changed.")
@ -408,9 +405,9 @@ void RouteEditor::on_routeProtocolBTCB_stateChanged(int arg1)
if (arg1 == Qt::Checked) protocols << "bittorrent";
if (ui->routeProtocolHTTPCB->isChecked()) protocols << "http";
if (routeProtocolHTTPCB->isChecked()) protocols << "http";
if (ui->routeProtocolTLSCB->isChecked()) protocols << "tls";
if (routeProtocolTLSCB->isChecked()) protocols << "tls";
CurrentRule.protocol = protocols.toStdList();
STATUS("Protocol list changed.")
@ -418,34 +415,34 @@ void RouteEditor::on_routeProtocolBTCB_stateChanged(int arg1)
void RouteEditor::on_balabcerAddBtn_clicked()
{
if (!ui->balancerSelectionCombo->currentText().isEmpty()) {
this->Balancers[QSTRING(CurrentRule.balancerTag)].append(ui->balancerSelectionCombo->currentText());
if (!balancerSelectionCombo->currentText().isEmpty()) {
this->Balancers[QSTRING(CurrentRule.balancerTag)].append(balancerSelectionCombo->currentText());
}
ui->balancerList->addItem(ui->balancerSelectionCombo->currentText());
ui->balancerSelectionCombo->setEditText("");
balancerList->addItem(balancerSelectionCombo->currentText());
balancerSelectionCombo->setEditText("");
STATUS("OK")
}
void RouteEditor::on_balancerDelBtn_clicked()
{
if (ui->balancerList->currentRow() < 0) {
if (balancerList->currentRow() < 0) {
return;
}
Balancers[QSTRING(CurrentRule.balancerTag)].removeAt(ui->balancerList->currentRow());
ui->balancerList->takeItem(ui->balancerList->currentRow());
Balancers[QSTRING(CurrentRule.balancerTag)].removeAt(balancerList->currentRow());
balancerList->takeItem(balancerList->currentRow());
STATUS("Removed a balancer entry.")
}
void RouteEditor::on_hostList_textChanged()
{
CurrentRule.domain = SplitLinesStdString(ui->hostList->toPlainText()).toStdList();
CurrentRule.domain = SplitLinesStdString(hostList->toPlainText()).toStdList();
}
void RouteEditor::on_ipList_textChanged()
{
CurrentRule.ip = SplitLinesStdString(ui->ipList->toPlainText()).toStdList();
CurrentRule.ip = SplitLinesStdString(ipList->toPlainText()).toStdList();
}
void RouteEditor::on_routePortTxt_textEdited(const QString &arg1)
@ -485,26 +482,26 @@ void RouteEditor::on_addRouteBtn_clicked()
rule.balancerTag = bTag.toStdString();
Balancers[bTag] = QStringList();
//
ui->routesTable->insertRow(ui->routesTable->rowCount());
routesTable->insertRow(routesTable->rowCount());
// WARNING There will be an additional check on the final configuration generation process.
auto enabledItem = new QTableWidgetItem(tr("Enabled"));
enabledItem->setCheckState(rule.QV2RAY_RULE_ENABLED ? Qt::Checked : Qt::Unchecked);
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 0, enabledItem);
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 1, new QTableWidgetItem(rule.inboundTag.size() > 0 ? Stringify(rule.inboundTag) : tr("Any")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 2, new QTableWidgetItem(QString::number(rule.domain.size() + rule.ip.size()) + " " + tr("Items")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 3, new QTableWidgetItem(QSTRING(rule.outboundTag)));
routesTable->setItem(routesTable->rowCount() - 1, 0, enabledItem);
routesTable->setItem(routesTable->rowCount() - 1, 1, new QTableWidgetItem(rule.inboundTag.size() > 0 ? Stringify(rule.inboundTag) : tr("Any")));
routesTable->setItem(routesTable->rowCount() - 1, 2, new QTableWidgetItem(QString::number(rule.domain.size() + rule.ip.size()) + " " + tr("Items")));
routesTable->setItem(routesTable->rowCount() - 1, 3, new QTableWidgetItem(QSTRING(rule.outboundTag)));
rules.append(rule);
currentRuleIndex = ui->routesTable->rowCount() - 1;
ui->routesTable->setCurrentCell(currentRuleIndex, 0);
currentRuleIndex = routesTable->rowCount() - 1;
routesTable->setCurrentCell(currentRuleIndex, 0);
ShowRuleDetail(CurrentRule);
ui->delRouteBtn->setEnabled(true);
delRouteBtn->setEnabled(true);
}
void RouteEditor::on_changeIOBtn_clicked()
{
QString outbound = "";
if (ui->outboundsList->currentRow() < 0) {
if (outboundsList->currentRow() < 0) {
// Don't return as someone may use the outboundTag
//
//QvMessageBox(this, tr("Changing route inbound/outbound"), tr("Please select an outbound from the list."));
@ -513,14 +510,14 @@ void RouteEditor::on_changeIOBtn_clicked()
tr("You didn't select an outbound.") + NEWLINE +
tr("Banlancer will be used."));
} else {
outbound = outbounds[ui->outboundsList->currentRow()].toObject()["tag"].toString();
outbound = outbounds[outboundsList->currentRow()].toObject()["tag"].toString();
}
QList<string> new_inbounds;
QList<string> new_inbounds_name;
for (int i = 0; i < ui->inboundsList->count(); i++) {
auto _item = ui->inboundsList->item(i);
for (int i = 0; i < inboundsList->count(); i++) {
auto _item = inboundsList->item(i);
if (_item->checkState() == Qt::Checked) {
// WARN there are possiblilties that someone may forget to set the tag.
@ -574,7 +571,7 @@ void RouteEditor::on_routesTable_cellChanged(int row, int column)
return;
}
rules[row].QV2RAY_RULE_ENABLED = ui->routesTable->item(row, column)->checkState() == Qt::Checked;
rules[row].QV2RAY_RULE_ENABLED = routesTable->item(row, column)->checkState() == Qt::Checked;
STATUS((rules[row].QV2RAY_RULE_ENABLED ? "Enabled a route" : "Disabled a route"))
}
@ -595,18 +592,18 @@ void RouteEditor::on_netTCPRB_clicked()
void RouteEditor::on_routeUserTxt_textChanged()
{
CurrentRule.user = SplitLinesStdString(ui->routeUserTxt->toPlainText()).toStdList();
CurrentRule.user = SplitLinesStdString(routeUserTxt->toPlainText()).toStdList();
}
void RouteEditor::on_sourceIPList_textChanged()
{
CurrentRule.source = SplitLinesStdString(ui->sourceIPList->toPlainText()).toStdList();
CurrentRule.source = SplitLinesStdString(sourceIPList->toPlainText()).toStdList();
}
void RouteEditor::on_enableBalancerCB_stateChanged(int arg1)
{
CurrentRule.QV2RAY_RULE_USE_BALANCER = arg1 == Qt::Checked;
ui->stackedWidget->setCurrentIndex(arg1 == Qt::Checked ? 1 : 0);
stackedWidget->setCurrentIndex(arg1 == Qt::Checked ? 1 : 0);
}
@ -620,8 +617,8 @@ void RouteEditor::on_inboundsList_itemChanged(QListWidgetItem *item)
Q_UNUSED(item)
QList<string> new_inbounds;
for (int i = 0; i < ui->inboundsList->count(); i++) {
auto _item = ui->inboundsList->item(i);
for (int i = 0; i < inboundsList->count(); i++) {
auto _item = inboundsList->item(i);
if (_item->checkState() == Qt::Checked) {
// WARN there are possiblilties that someone may forget to set the tag.
@ -648,17 +645,17 @@ void RouteEditor::on_inboundsList_itemChanged(QListWidgetItem *item)
void RouteEditor::on_delRouteBtn_clicked()
{
if (ui->routesTable->currentRow() >= 0) {
auto index = ui->routesTable->currentRow();
if (routesTable->currentRow() >= 0) {
auto index = routesTable->currentRow();
auto rule = rules[index];
rules.removeAt(index);
Q_UNUSED(rule)
ui->routesTable->removeRow(index);
routesTable->removeRow(index);
// Show current row.;
if (ui->routesTable->rowCount() > 0) {
if (routesTable->rowCount() > 0) {
currentRuleIndex = 0;
ui->routesTable->setCurrentCell(currentRuleIndex, 0);
routesTable->setCurrentCell(currentRuleIndex, 0);
ShowRuleDetail(CurrentRule);
}
}
@ -680,12 +677,12 @@ void RouteEditor::on_addDefaultBtn_clicked()
auto _in_SOCKS = GenerateInboundEntry(QSTRING(_in.listenip), _in.socks_port, "socks", _in_socksConf, "SOCKS_gConf");
//
inbounds.append(_in_HTTP);
ui->inboundsList->addItem("HTTP Global Config");
ui->inboundsList->item(ui->inboundsList->count() - 1)->setCheckState(Qt::Unchecked);
inboundsList->addItem("HTTP Global Config");
inboundsList->item(inboundsList->count() - 1)->setCheckState(Qt::Unchecked);
//
inbounds.append(_in_SOCKS);
ui->inboundsList->addItem("SOCKS Global Config");
ui->inboundsList->item(ui->inboundsList->count() - 1)->setCheckState(Qt::Unchecked);
inboundsList->addItem("SOCKS Global Config");
inboundsList->item(inboundsList->count() - 1)->setCheckState(Qt::Unchecked);
}
void RouteEditor::on_insertBlackBtn_clicked()
@ -694,27 +691,27 @@ void RouteEditor::on_insertBlackBtn_clicked()
auto tag = "blackhole_" + QString::number(QTime::currentTime().msecsSinceStartOfDay());
auto _blackHoleOutbound = GenerateOutboundEntry("blackhole", blackHole, QJsonObject(), QJsonObject(), "0.0.0.0", tag);
outbounds.append(_blackHoleOutbound);
ui->outboundsList->addItem(tag);
outboundsList->addItem(tag);
}
void RouteEditor::on_delOutboundBtn_clicked()
{
if (ui->outboundsList->currentRow() < 0) {
if (outboundsList->currentRow() < 0) {
return;
}
auto index = ui->outboundsList->currentRow();
auto index = outboundsList->currentRow();
outbounds.removeAt(index);
ui->outboundsList->takeItem(index);
outboundsList->takeItem(index);
}
void RouteEditor::on_delInboundBtn_clicked()
{
if (ui->inboundsList->currentRow() < 0) {
if (inboundsList->currentRow() < 0) {
return;
}
auto index = ui->inboundsList->currentRow();
auto index = inboundsList->currentRow();
inbounds.removeAt(index);
ui->inboundsList->takeItem(index);
inboundsList->takeItem(index);
}

View File

@ -8,12 +8,8 @@
#include <QListWidgetItem>
#include "QvUtils.hpp"
namespace Ui
{
class RouteEditor;
}
class RouteEditor : public QDialog
#include "ui_w_RoutesEditor.h"
class RouteEditor : public QDialog, private Ui::RouteEditor
{
Q_OBJECT
@ -97,7 +93,6 @@ class RouteEditor : public QDialog
QJsonArray outbounds;
QJsonObject root;
QJsonObject original;
Ui::RouteEditor *ui;
};
#endif // W_QVOUTBOUNDEDITOR_H

View File

@ -1,37 +1,34 @@
#include "w_SubscriptionEditor.hpp"
#include "ui_w_SubscriptionEditor.h"
#include "w_SubscriptionEditor.hpp"
#include "QvHTTPRequestHelper.hpp"
#include "QvUtils.hpp"
#include "QvCoreConfigOperations.hpp"
SubscribeEditor::SubscribeEditor(QWidget *parent) :
QDialog(parent),
ui(new Ui::w_SubscribeEditor)
QDialog(parent)
{
ui->setupUi(this);
setupUi(this);
auto conf = GetGlobalConfig();
foreach (auto value, conf.subscribes) {
ui->subsribeTable->insertRow(ui->subsribeTable->rowCount());
ui->subsribeTable->setItem(ui->subsribeTable->rowCount() - 1, 0, new QTableWidgetItem(QString::fromStdString(value.first)));
ui->subsribeTable->setItem(ui->subsribeTable->rowCount() - 1, 1, new QTableWidgetItem(QString::fromStdString(value.second)));
subsribeTable->insertRow(subsribeTable->rowCount());
subsribeTable->setItem(subsribeTable->rowCount() - 1, 0, new QTableWidgetItem(QString::fromStdString(value.first)));
subsribeTable->setItem(subsribeTable->rowCount() - 1, 1, new QTableWidgetItem(QString::fromStdString(value.second)));
}
}
SubscribeEditor::~SubscribeEditor()
{
delete ui;
}
void SubscribeEditor::on_buttonBox_accepted()
{
map<string, string> subscribes;
for (int i = 0; i < ui->subsribeTable->rowCount(); i++) {
for (int i = 0; i < subsribeTable->rowCount(); i++) {
pair<string, string> kvp;
kvp.first = ui->subsribeTable->item(i, 0)->text().toStdString();
kvp.second = ui->subsribeTable->item(i, 1)->text().toStdString();
kvp.first = subsribeTable->item(i, 0)->text().toStdString();
kvp.second = subsribeTable->item(i, 1)->text().toStdString();
subscribes.insert(kvp);
}
@ -43,7 +40,7 @@ void SubscribeEditor::on_buttonBox_accepted()
void SubscribeEditor::on_addSubsButton_clicked()
{
ui->subsribeTable->insertRow(ui->subsribeTable->rowCount());
subsribeTable->insertRow(subsribeTable->rowCount());
}
void SubscribeEditor::on_updateButton_clicked()
@ -54,9 +51,9 @@ void SubscribeEditor::on_updateButton_clicked()
}
isUpdateInProgress = true;
int index = ui->subsribeTable->currentRow();
auto name = ui->subsribeTable->item(index, 0)->text();
auto url = ui->subsribeTable->item(index, 1)->text();
int index = subsribeTable->currentRow();
auto name = subsribeTable->item(index, 0)->text();
auto url = subsribeTable->item(index, 1)->text();
auto data = helper.syncget(url);
ProcessSubscriptionEntry(data, name);
}
@ -81,8 +78,8 @@ void SubscribeEditor::ProcessSubscriptionEntry(QByteArray result, QString subsci
void SubscribeEditor::on_updateAllButton_clicked()
{
for (auto rowIndex = 0; ui->subscribeList->count(); rowIndex++) {
auto url = ui->subsribeTable->item(rowIndex, 1)->text();
for (auto rowIndex = 0; subscribeList->count(); rowIndex++) {
auto url = subsribeTable->item(rowIndex, 1)->text();
helper.get(url);
}
}

View File

@ -5,12 +5,8 @@
#include "QvUtils.hpp"
#include "QvHTTPRequestHelper.hpp"
namespace Ui
{
class w_SubscribeEditor;
}
class SubscribeEditor : public QDialog
#include "ui_w_SubscriptionEditor.h"
class SubscribeEditor : public QDialog, private Ui::w_SubscribeEditor
{
Q_OBJECT
@ -34,7 +30,6 @@ class SubscribeEditor : public QDialog
void ProcessSubscriptionEntry(QByteArray result, QString subsciptionName);
bool isUpdateInProgress = false;
Ui::w_SubscribeEditor *ui;
QvHttpRequestHelper helper;
QMap<QString, QList<QJsonObject>> subscriptions;
};

View File

@ -1,12 +1,12 @@
#include <QString>
#include <QDebug>
#include "QPingModel.hpp"
#include "QvPingModel.hpp"
namespace Qv2ray
{
namespace Utils
{
PingModel::PingModel(QObject *parent) :
QvPingModel::QvPingModel(QObject *parent) :
QObject(parent),
running(false)
{
@ -15,11 +15,11 @@ namespace Qv2ray
connect(pingworker, SIGNAL(finished(int)), this, SLOT(readResult()));
}
PingModel::~PingModel()
QvPingModel::~QvPingModel()
{
}
void PingModel::verifyStatus()
void QvPingModel::verifyStatus()
{
if (pingworker->isReadable()) {
qDebug() << "read on ...";
@ -33,14 +33,14 @@ namespace Qv2ray
}
}
void PingModel::readResult()
void QvPingModel::readResult()
{
qDebug() << "Acabou!!!";
running = false;
qDebug() << "LENDO: " << pingworker->readLine();
}
void PingModel::start_command()
void QvPingModel::start_command()
{
if (pingworker) {
QString command = "ping";
@ -53,12 +53,12 @@ namespace Qv2ray
}
}
bool PingModel::is_running()
bool QvPingModel::is_running()
{
return running;
}
bool PingModel::finished()
bool QvPingModel::finished()
{
return pingworker->atEnd();
}

View File

@ -1,4 +1,4 @@
#ifndef PINGMODEL_H
#ifndef PINGMODEL_H
#define PINGMODEL_H
#include <QObject>
@ -8,12 +8,12 @@ namespace Qv2ray
{
namespace Utils
{
class PingModel : public QObject
class QvPingModel : public QObject
{
Q_OBJECT
public:
explicit PingModel(QObject *parent = nullptr);
~PingModel();
explicit QvPingModel(QObject *parent = nullptr);
~QvPingModel();
void start_command();
bool is_running();