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

View File

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

View File

@ -1,4 +1,4 @@
#include <QThread> #include <QThread>
#include "QvNetSpeedPlugin.hpp" #include "QvNetSpeedPlugin.hpp"
#include "QvUtils.hpp" #include "QvUtils.hpp"
@ -64,13 +64,13 @@ namespace Qv2ray
case 101: { case 101: {
// Current Time // Current Time
CL.Message = QTime().toString("hh:mm:ss").toStdString(); CL.Message = QTime().currentTime().toString("hh:mm:ss").toStdString();
break; break;
} }
case 102: { case 102: {
// Current Date // Current Date
CL.Message = QDate().toString("yyyy-MM-dd").toStdString(); CL.Message = QDate().currentDate().toString("yyyy-MM-dd").toStdString();
break; 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 "QvUtils.hpp"
#include "QvCoreInteractions.hpp" #include "QvCoreInteractions.hpp"
#include "QvCoreConfigOperations.hpp" #include "QvCoreConfigOperations.hpp"
#include "w_OutboundEditor.hpp" #include "w_OutboundEditor.hpp"
#include "w_ImportConfig.hpp" #include "w_ImportConfig.hpp"
@ -15,46 +16,49 @@
ImportConfigWindow::ImportConfigWindow(QWidget *parent) ImportConfigWindow::ImportConfigWindow(QWidget *parent)
: QDialog(parent) : QDialog(parent)
, ui(new Ui::ImportConfigWindow)
{ {
ui->setupUi(this); setupUi(this);
ui->nameTxt->setText(QUuid::createUuid().toString()); nameTxt->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-MM-ss.imported"));
} }
ImportConfigWindow::~ImportConfigWindow() ImportConfigWindow::~ImportConfigWindow()
{ {
delete ui; }
void ImportConfigWindow::OpenImporter()
{
this->exec();
} }
void ImportConfigWindow::on_importSourceCombo_currentIndexChanged(int index) void ImportConfigWindow::on_importSourceCombo_currentIndexChanged(int index)
{ {
ui->stackedWidget->setCurrentIndex(index); stackedWidget->setCurrentIndex(index);
} }
void ImportConfigWindow::on_selectFileBtn_clicked() void ImportConfigWindow::on_selectFileBtn_clicked()
{ {
QString dir = QFileDialog::getOpenFileName(this, tr("Select file to import"), QDir::currentPath()); QString dir = QFileDialog::getOpenFileName(this, tr("Select file to import"), QDir::currentPath());
ui->fileLineTxt->setText(dir); fileLineTxt->setText(dir);
} }
void ImportConfigWindow::on_buttonBox_accepted() void ImportConfigWindow::on_buttonBox_accepted()
{ {
QString alias = ui->nameTxt->text(); QString alias = nameTxt->text();
QJsonObject config; QJsonObject config;
auto conf = GetGlobalConfig(); auto conf = GetGlobalConfig();
auto needReload = false; auto needReload = false;
if (ui->importSourceCombo->currentIndex() == 0) { if (importSourceCombo->currentIndex() == 0) {
// From File... // From File...
bool overrideInBound = !ui->keepImportedInboundCheckBox->isChecked(); bool overrideInBound = !keepImportedInboundCheckBox->isChecked();
auto fileName = ui->fileLineTxt->text(); auto fileName = fileLineTxt->text();
if (!Qv2Instance::ValidateConfig(&fileName)) { if (!Qv2Instance::ValidateConfig(&fileName)) {
QvMessageBox(this, tr("Import config file"), tr("Failed to check the validity of the config file.")); QvMessageBox(this, tr("Import config file"), tr("Failed to check the validity of the config file."));
return; return;
} }
QString path = ui->fileLineTxt->text(); QString path = fileLineTxt->text();
alias = alias != "" ? alias : QFileInfo(path).fileName(); alias = alias != "" ? alias : QFileInfo(path).fileName();
config = ConvertConfigFromFile(path, overrideInBound); config = ConvertConfigFromFile(path, overrideInBound);
// //
@ -64,7 +68,7 @@ void ImportConfigWindow::on_buttonBox_accepted()
// //
SetGlobalConfig(conf); SetGlobalConfig(conf);
} else { } else {
QString vmess = ui->vmessConnectionStringTxt->toPlainText(); QString vmess = vmessConnectionStringTxt->toPlainText();
// //
// We saperate the string into lines. // We saperate the string into lines.
QStringList vmessList = vmess.split(NEWLINE, QString::SplitBehavior::SkipEmptyParts); QStringList vmessList = vmess.split(NEWLINE, QString::SplitBehavior::SkipEmptyParts);
@ -76,7 +80,7 @@ void ImportConfigWindow::on_buttonBox_accepted()
switch (result) { switch (result) {
case 0: case 0:
// This result code passes the validation check. // This result code passes the validation check.
config = ConvertConfigFromVMessString(ui->vmessConnectionStringTxt->toPlainText()); config = ConvertConfigFromVMessString(vmessConnectionStringTxt->toPlainText());
// //
alias = alias.isEmpty() ? alias : config["QV2RAY_ALIAS"].toString(); alias = alias.isEmpty() ? alias : config["QV2RAY_ALIAS"].toString();
config.remove("QV2RAY_ALIAS"); config.remove("QV2RAY_ALIAS");
@ -101,3 +105,29 @@ void ImportConfigWindow::on_buttonBox_accepted()
SetGlobalConfig(conf); SetGlobalConfig(conf);
emit s_reload_config(needReload); 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 #define IMPORTCONF_H
#include <QDialog> #include <QDialog>
#include "ui_w_ImportConfig.h" #include "ui_w_ImportConfig.h"
namespace Ui class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
{
class ImportConfigWindow;
}
class ImportConfigWindow : public QDialog
{ {
Q_OBJECT Q_OBJECT
@ -26,9 +21,7 @@ class ImportConfigWindow : public QDialog
void on_buttonBox_accepted(); void on_buttonBox_accepted();
private: void on_qrFromScreenBtn_clicked();
Ui::ImportConfigWindow *ui;
}; };
#endif // IMPORTCONF_H #endif // IMPORTCONF_H

View File

@ -55,12 +55,12 @@
</property> </property>
<item> <item>
<property name="text"> <property name="text">
<string>File</string> <string>Existing File</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>VMess String</string> <string>VMess and QRCode</string>
</property> </property>
</item> </item>
<item> <item>
@ -68,11 +68,6 @@
<string>Subscription Link</string> <string>Subscription Link</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>Scan Image</string>
</property>
</item>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -86,7 +81,7 @@
<item> <item>
<widget class="QStackedWidget" name="stackedWidget"> <widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="filePage"> <widget class="QWidget" name="filePage">
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
@ -146,63 +141,179 @@
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="vmessPage"> <widget class="QWidget" name="vmessPage">
<layout class="QVBoxLayout" name="verticalLayout_2"> <widget class="QLabel" name="label_3">
<item> <property name="geometry">
<widget class="QLabel" name="label_3"> <rect>
<property name="text"> <x>6</x>
<string>VMess Connection String</string> <y>6</y>
</property> <width>153</width>
</widget> <height>18</height>
</item> </rect>
<item> </property>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,1"> <property name="text">
<item> <string>VMess Connection String</string>
<widget class="QTextEdit" name="vmessConnectionStringTxt"> </property>
<property name="placeholderText"> </widget>
<string>Put your vmess:// here</string> <widget class="QWidget" name="layoutWidget">
</property> <property name="geometry">
</widget> <rect>
</item> <x>0</x>
<item> <y>30</y>
<widget class="QGroupBox" name="groupBox_2"> <width>227</width>
<property name="title"> <height>36</height>
<string>VMess Check Status</string> </rect>
</property> </property>
<layout class="QFormLayout" name="formLayout_4"> <layout class="QHBoxLayout" name="horizontalLayout">
<item row="0" column="0"> <item>
<widget class="QLabel" name="label_6"> <widget class="QLineEdit" name="lineEdit">
<property name="text"> <property name="text">
<string>Processing</string> <string>---TODO---</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item>
<widget class="QLabel" name="label_9"> <widget class="QPushButton" name="pushButton">
<property name="text"> <property name="text">
<string>0/0</string> <string>Select</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> </layout>
<widget class="QLabel" name="label_7"> </widget>
<property name="text"> <widget class="QLabel" name="label_12">
<string>Line Failed</string> <property name="geometry">
</property> <rect>
</widget> <x>504</x>
</item> <y>80</y>
<item row="1" column="1"> <width>40</width>
<widget class="QLabel" name="label_8"> <height>18</height>
<property name="text"> </rect>
<string>0</string> </property>
</property> <property name="text">
</widget> <string>Image</string>
</item> </property>
</layout> </widget>
</widget> <widget class="QLabel" name="qRContentLabel">
</item> <property name="geometry">
</layout> <rect>
</item> <x>550</x>
</layout> <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>
<widget class="QWidget" name="page"> <widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
@ -236,49 +347,6 @@
</item> </item>
</layout> </layout>
</widget> </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> </widget>
</item> </item>
</layout> </layout>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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