[add] Added UI for inbound editing.

Former-commit-id: 4a167dbab5
This commit is contained in:
Leroy.H.Y 2019-10-06 21:01:26 +08:00
parent 5bc2a6a8bb
commit 92f4d4fd55
19 changed files with 1709 additions and 569 deletions

View File

@ -11,7 +11,7 @@ TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS DEFINES += QT_DEPRECATED_WARNINGS
CONFIG += c++11 openssl openssl-linked lrelease embed_translations CONFIG += c++11 openssl openssl-linked lrelease embed_translations
VERSION = 1.999.999.999 VERSION = 1.99.99.2
DEFINES += QV_MAJOR_VERSION=\"\\\"$${VERSION}\\\"\" DEFINES += QV_MAJOR_VERSION=\"\\\"$${VERSION}\\\"\"
SOURCES += \ SOURCES += \
@ -22,15 +22,16 @@ SOURCES += \
src/QvCoreConfigOperations_Verification.cpp \ src/QvCoreConfigOperations_Verification.cpp \
src/QvCoreInteractions.cpp \ src/QvCoreInteractions.cpp \
src/QvUtils.cpp \ src/QvUtils.cpp \
src/ui/w_InboundEditor.cpp \
src/ui/w_OutboundEditor.cpp \
src/ui/w_RoutesEditor.cpp \
src/ui/w_SubscriptionEditor.cpp \
src/utils/QPingModel.cpp \ src/utils/QPingModel.cpp \
src/utils/QvHTTPRequestHelper.cpp \ src/utils/QvHTTPRequestHelper.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 \
src/ui/w_RouteEditor.cpp \
src/ui/w_SubscribeEditor.cpp \
src/ui/w_MainWindow.cpp \ src/ui/w_MainWindow.cpp \
src/ui/w_ConnectionEditWindow.cpp \
src/ui/w_ImportConfig.cpp \ src/ui/w_ImportConfig.cpp \
src/ui/w_PrefrencesWindow.cpp \ src/ui/w_PrefrencesWindow.cpp \
libs/gen/v2ray_api_commands.pb.cc \ libs/gen/v2ray_api_commands.pb.cc \
@ -50,6 +51,10 @@ HEADERS += \
src/QvCoreConfigOperations.h \ src/QvCoreConfigOperations.h \
src/QvCoreInteractions.h \ src/QvCoreInteractions.h \
src/QvUtils.h \ src/QvUtils.h \
src/ui/w_InboundEditor.h \
src/ui/w_OutboundEditor.h \
src/ui/w_RoutesEditor.h \
src/ui/w_SubscriptionEditor.h \
src/utils/QJsonObjectInsertMacros.h \ src/utils/QJsonObjectInsertMacros.h \
src/utils/QPingModel.h \ src/utils/QPingModel.h \
src/utils/QvHTTPRequestHelper.h \ src/utils/QvHTTPRequestHelper.h \
@ -57,41 +62,38 @@ HEADERS += \
src/utils/QvTinyLog.h \ src/utils/QvTinyLog.h \
src/utils/QJsonModel.h \ src/utils/QJsonModel.h \
src/ui/w_JsonEditor.h \ src/ui/w_JsonEditor.h \
src/ui/w_ConnectionEditWindow.h \
src/ui/w_ImportConfig.h \ src/ui/w_ImportConfig.h \
src/ui/w_MainWindow.h \ src/ui/w_MainWindow.h \
src/ui/w_PrefrencesWindow.h \ src/ui/w_PrefrencesWindow.h \
src/ui/w_RouteEditor.h \
src/ui/w_SubscribeEditor.h \
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
FORMS += \ FORMS += \
src/ui/w_ConnectionEditWindow.ui \
src/ui/w_ImportConfig.ui \ src/ui/w_ImportConfig.ui \
src/ui/w_InboundEditor.ui \
src/ui/w_JsonEditor.ui \ src/ui/w_JsonEditor.ui \
src/ui/w_MainWindow.ui \ src/ui/w_MainWindow.ui \
src/ui/w_OutboundEditor.ui \
src/ui/w_PrefrencesWindow.ui \ src/ui/w_PrefrencesWindow.ui \
src/ui/w_RouteEditor.ui \ src/ui/w_RoutesEditor.ui \
src/ui/w_SubscribeEditor.ui src/ui/w_SubscriptionEditor.ui
RESOURCES += \ RESOURCES += \
resources.qrc resources.qrc
# Fine...... # Fine......
message(" ") message(" ")
message("|------------------------------------------------|") message("Qv2ray Version: $${VERSION}")
message("| Qv2ray, Cross Platform v2ray GUI client |") message("|-------------------------------------------------|")
message("| Licenced under GPLv3 |") message("| Qv2ray, A Cross Platform v2ray Qt GUI Client. |")
message("| |") message("| Licenced under GPLv3 |")
message("| You may only use this program to the extent |") message("| |")
message("| permitted by local law. |") message("| You may only use this program to the extent |")
message("| |") message("| permitted by local law. |")
message("| See: https://www.gnu.org/licenses/gpl-3.0.html |") message("| |")
message("|------------------------------------------------|") message("| See: https://www.gnu.org/licenses/gpl-3.0.html |")
message("|-------------------------------------------------|")
message(" ") message(" ")
RC_ICONS += ./icons/Qv2ray.ico RC_ICONS += ./icons/Qv2ray.ico
ICON = ./icons/Qv2ray.icns ICON = ./icons/Qv2ray.icns
@ -100,10 +102,10 @@ ICON = ./icons/Qv2ray.icns
message(" ") message(" ")
message("-----------------------------------------------") message("-----------------------------------------------")
message("Cannot continue: ") message("Cannot continue: ")
message(" ---> Qv2ray is not properly configured yet: ") message(" --> Qv2ray is not properly configured yet: ")
message(" gRPC and protobuf headers for v2ray API is missing.") message(" gRPC and protobuf headers for v2ray API is missing.")
message(" ---> Please run gen_grpc.sh gen_grpc.bat or deps_macOS.sh located in tools/") message(" --> Please run gen_grpc.sh gen_grpc.bat or deps_macOS.sh located in tools/")
message(" ---> Or consider reading https://github.com/lhy0403/Qv2ray/blob/master/BUILDING.md") message(" --> Or consider reading https://github.com/lhy0403/Qv2ray/blob/master/BUILDING.md")
message("-----------------------------------------------") message("-----------------------------------------------")
message(" ") message(" ")
warning("IF YOU THINK IT'S A MISTAKE, PLEASE OPEN AN ISSUE") warning("IF YOU THINK IT'S A MISTAKE, PLEASE OPEN AN ISSUE")
@ -112,31 +114,31 @@ ICON = ./icons/Qv2ray.icns
} }
# ------------------------------------------ Begin to detect language files. # ------------------------------------------ Begin to detect language files.
message(" - Looking for language support.") message("Looking for language support.")
QM_FILES_RESOURCE_PREFIX = "translations" QM_FILES_RESOURCE_PREFIX = "translations"
for(var, $$list($$files("*.ts", true))) { for(var, $$list($$files("*.ts", true))) {
LOCALE_FILENAME = $$basename(var) LOCALE_FILENAME = $$basename(var)
message(" ---> Found:" $$LOCALE_FILENAME) message(" --> Found:" $$LOCALE_FILENAME)
!equals(LOCALE_FILENAME, "en-US.ts") { !equals(LOCALE_FILENAME, "en-US.ts") {
# ONLY USED IN LRELEASE CONTEXT - en-US is not EXTRA... # ONLY USED IN LRELEASE CONTEXTen-US is not EXTRA...
EXTRA_TRANSLATIONS += translations/$$LOCALE_FILENAME EXTRA_TRANSLATIONS += translations/$$LOCALE_FILENAME
} }
} }
message(" - Qv2ray will build with" $${replace(EXTRA_TRANSLATIONS, "translations/", "")}) message("Qv2ray will build with" $${replace(EXTRA_TRANSLATIONS, "translations/", "")})
TRANSLATIONS += translations/en-US.ts TRANSLATIONS += translations/en-US.ts
QMAKE_CXXFLAGS += "-Wno-missing-field-initializers" "-Wno-unused-parameter" QMAKE_CXXFLAGS += "-Wno-missing-field-initializers" "-Wno-unused-parameter"
win32 { win32 {
message(" - Configuring for win32 environment") message("Configuring for win32 environment")
message(" ---> Setting up target descriptions") message(" --> Setting up target descriptions")
QMAKE_TARGET_DESCRIPTION = "Qv2ray, a cross-platform v2ray GUI client." QMAKE_TARGET_DESCRIPTION = "Qv2ray, a cross-platform v2ray GUI client."
QMAKE_TARGET_PRODUCT = "Qv2ray" QMAKE_TARGET_PRODUCT = "Qv2ray"
# A hack for protobuf header. # A hack for protobuf header.
message(" ---> Applying a hack for protobuf header") message(" --> Applying a hack for protobuf header")
DEFINES += _WIN32_WINNT=0x600 DEFINES += _WIN32_WINNT=0x600
message(" ---> Linking against gRPC and protobuf library.") message(" --> Linking against gRPC and protobuf library.")
LIBS += -L$$PWD/libs/gRPC-win32/lib/ -llibgrpc++.dll -llibprotobuf.dll LIBS += -L$$PWD/libs/gRPC-win32/lib/ -llibgrpc++.dll -llibprotobuf.dll
INCLUDEPATH += $$PWD/libs/gRPC-win32/include INCLUDEPATH += $$PWD/libs/gRPC-win32/include
@ -144,12 +146,12 @@ win32 {
# Some files issue. # Some files issue.
CONFIG(release, debug|release) { CONFIG(release, debug|release) {
message(" ---> Appending scripts for copying gRPC and protobuf dll to RELEASE directory.") message(" --> Appending scripts for copying gRPC and protobuf dll to RELEASE directory.")
QMAKE_PRE_LINK += forfiles /s /p $${replace(PWD, /, \\)}\libs\ /m "*.dll" /c \"cmd.exe /c copy @file $${replace(OUT_PWD, /, \\)}\\release\\\" QMAKE_PRE_LINK += forfiles /s /p $${replace(PWD, /, \\)}\libs\ /m "*.dll" /c \"cmd.exe /c copy @file $${replace(OUT_PWD, /, \\)}\\release\\\"
} }
CONFIG(debug, debug|release) { CONFIG(debug, debug|release) {
message(" ---> Appending scripts for copying gRPC and protobuf dll to DEBUG directory.") message(" --> Appending scripts for copying gRPC and protobuf dll to DEBUG directory.")
QMAKE_PRE_LINK += forfiles /s /p $${replace(PWD, /, \\)}\libs\ /m "*.dll" /c \"cmd.exe /c copy @file $${replace(OUT_PWD, /, \\)}\\debug\\\" QMAKE_PRE_LINK += forfiles /s /p $${replace(PWD, /, \\)}\libs\ /m "*.dll" /c \"cmd.exe /c copy @file $${replace(OUT_PWD, /, \\)}\\debug\\\"
} }
PRE_TARGETDEPS += $$PWD/libs/gRPC-win32/lib/libgrpc++.dll.a $$PWD/libs/gRPC-win32/lib/libprotobuf.dll.a PRE_TARGETDEPS += $$PWD/libs/gRPC-win32/lib/libgrpc++.dll.a $$PWD/libs/gRPC-win32/lib/libprotobuf.dll.a
@ -157,16 +159,16 @@ win32 {
unix { unix {
# For Linux and macOS # For Linux and macOS
message(" - Configuring for unix (macOS and linux) environment") message("Configuring for unix (macOS and linux) environment")
# For gRPC and protobuf in linux and macOS # For gRPC and protobuf in linux and macOS
message(" ---> Linking against gRPC and protobuf library.") message(" --> Linking against gRPC and protobuf library.")
LIBS += -L/usr/local/lib -lgrpc++ -lprotobuf LIBS += -L/usr/local/lib -lgrpc++ -lprotobuf
message(" ---> Generating desktop dependency.") message(" --> Generating desktop dependency.")
desktop.files += ./icons/Qv2ray.desktop desktop.files += ./icons/Qv2ray.desktop
desktop.path = /opt/$${TARGET}/share/applications/ desktop.path = /opt/$${TARGET}/share/applications/
message(" ---> Generating icons dependency.") message(" --> Generating icons dependency.")
icon.files += ./icons/Qv2ray.png icon.files += ./icons/Qv2ray.png
icon.path = /opt/$${TARGET}/share/icons/hicolor/256x256/apps/ icon.path = /opt/$${TARGET}/share/icons/hicolor/256x256/apps/
@ -174,5 +176,5 @@ unix {
INSTALLS += target desktop icon INSTALLS += target desktop icon
} }
message(" - Done configuring Qv2ray project. Build output will be at:" $$OUT_PWD) message("Done configuring Qv2ray project. Build output will be at:" $$OUT_PWD)
message(" - Type `make` or `mingw32-make` to start building Qv2ray") message("Type `make` or `mingw32-make` to start building Qv2ray")

View File

@ -5,4 +5,4 @@ Categories=Network;Qt;
Icon=Qv2ray Icon=Qv2ray
Exec=/opt/Qv2ray/bin/Qv2ray Exec=/opt/Qv2ray/bin/Qv2ray
Name=Qv2ray Name=Qv2ray
Comment=Cross-platform v2ray GUI Client in Qt. Comment=Cross platform v2ray Qt GUI Client.

View File

@ -8,7 +8,7 @@
#include "QvUtils.h" #include "QvUtils.h"
#include "QvCoreInteractions.h" #include "QvCoreInteractions.h"
#include "QvCoreConfigOperations.h" #include "QvCoreConfigOperations.h"
#include "w_ConnectionEditWindow.h" #include "w_OutboundEditor.h"
#include "w_ImportConfig.h" #include "w_ImportConfig.h"

View File

@ -0,0 +1,14 @@
#include "w_InboundEditor.h"
#include "ui_w_InboundEditor.h"
InboundEditor::InboundEditor(QWidget *parent) :
QDialog(parent),
ui(new Ui::InboundEditor)
{
ui->setupUi(this);
}
InboundEditor::~InboundEditor()
{
delete ui;
}

22
src/ui/w_InboundEditor.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef W_INBOUNDEDITOR_H
#define W_INBOUNDEDITOR_H
#include <QDialog>
namespace Ui {
class InboundEditor;
}
class InboundEditor : public QDialog
{
Q_OBJECT
public:
explicit InboundEditor(QWidget *parent = nullptr);
~InboundEditor();
private:
Ui::InboundEditor *ui;
};
#endif // W_INBOUNDEDITOR_H

710
src/ui/w_InboundEditor.ui Normal file
View File

@ -0,0 +1,710 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InboundEditor</class>
<widget class="QDialog" name="InboundEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>874</width>
<height>497</height>
</rect>
</property>
<property name="windowTitle">
<string>Inbound Editor</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="7,3">
<item row="2" column="0">
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Tag</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="inboundTagTxt">
<property name="placeholderText">
<string>Tag of this inbound entry</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Listening</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0,1">
<item>
<widget class="QLineEdit" name="inboundHostTxt">
<property name="placeholderText">
<string>Hostname or IP Address</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="inboundPortTxt">
<property name="placeholderText">
<string>Port: 1080|env:PORT|80-85</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Protocol</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="inboundProtocolTxt">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>HTTP</string>
</property>
</item>
<item>
<property name="text">
<string>SOCKS</string>
</property>
</item>
<item>
<property name="text">
<string>Dokodemo</string>
</property>
</item>
<item>
<property name="text">
<string>MTProto</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Allocation Settings</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Strategy</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="strategyCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Always</string>
</property>
</item>
<item>
<property name="text">
<string>Random</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="refreshNumberBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>2</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Concurrency</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="concurrencyNumberBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="1">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Sniffing Settings</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Destination
Override</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QListWidget" name="destOverrideList">
<item>
<property name="text">
<string notr="true">http</string>
</property>
<property name="checkState">
<enum>Unchecked</enum>
</property>
</item>
<item>
<property name="text">
<string notr="true">tls</string>
</property>
<property name="checkState">
<enum>Unchecked</enum>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="enableSniffingCB">
<property name="text">
<string>Enabled</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Enabled</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="HTTPPage">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>HTTP Inbound Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="4,6">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Timeout</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="httpTimeoutSpinBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Allow Transparent</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="httpTransparentCB">
<property name="text">
<string>Enabled</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>User Level</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="httpUserLevelSB"/>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="3">
<widget class="QToolButton" name="httpRemoveUserBtn">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/remove_connection_btn.png</normaloff>:/icons/remove_connection_btn.png</iconset>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2" colspan="3">
<widget class="QListWidget" name="httpAccountListBox"/>
</item>
<item row="3" column="2">
<widget class="QLineEdit" name="httpAddPasswordTxt">
<property name="placeholderText">
<string>Password</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QToolButton" name="httpAddUserBtn">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/add_connection_btn.png</normaloff>:/icons/add_connection_btn.png</iconset>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="httpAddUserTxt">
<property name="placeholderText">
<string>Username</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="5">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Accounts</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="SOCKSPage">
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>SOCKS Inbound Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="4,6">
<item>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Auth</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="socksAuthCombo">
<item>
<property name="text">
<string>No Auth</string>
</property>
</item>
<item>
<property name="text">
<string>Password</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Enable UDP</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Local UDP IP</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>User Level</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="socksUDPCB">
<property name="text">
<string>Enabled</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="socksUDPIPAddrTxt">
<property name="placeholderText">
<string>127.0.0.1</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="socksUserLevelSB"/>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="3">
<widget class="QToolButton" name="socksRemoveUserBtn">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/remove_connection_btn.png</normaloff>:/icons/remove_connection_btn.png</iconset>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2" colspan="3">
<widget class="QListWidget" name="socksAccountListBox"/>
</item>
<item row="3" column="2">
<widget class="QLineEdit" name="socksAddPasswordTxt">
<property name="placeholderText">
<string>Password</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QToolButton" name="socksAddUserBtn">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/add_connection_btn.png</normaloff>:/icons/add_connection_btn.png</iconset>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="socksAddUserTxt">
<property name="placeholderText">
<string>Username</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="5">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Accounts</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="DokodemoPage">
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Dokodemo-Door Inbound Settings</string>
</property>
<layout class="QFormLayout" name="formLayout_6">
<item row="0" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>IP Address</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="dokoIPAddrTxt">
<property name="placeholderText">
<string>Not necessary when setting &quot;Follow Redirect&quot;</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="dokoPortSB">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>10086</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_23">
<property name="text">
<string>Network</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="dokoTCPCB">
<property name="text">
<string>TCP</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="dokoUDPCB">
<property name="text">
<string>UDP</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Timeout</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_25">
<property name="text">
<string>Follow Redirect</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>User Level</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="dokoTimeoutSB">
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>8192</number>
</property>
<property name="value">
<number>300</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="dokoFollowRedirectCB">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="dokoUserLevelSB"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="MTProtoPage">
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>MTProto Inbound Settings</string>
</property>
<layout class="QFormLayout" name="formLayout_7">
<item row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>EMail Address</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="mtEMailTxt">
<property name="placeholderText">
<string notr="true">your.name@domain.com</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Secret</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="mtSecretTxt">
<property name="placeholderText">
<string>SECRET</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_28">
<property name="text">
<string>User Level</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="mtUserLevelSB"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../resources.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>InboundEditor</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>InboundEditor</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -3,24 +3,24 @@
#include "QvUtils.h" #include "QvUtils.h"
JsonEditor::JsonEditor(QJsonObject document, QWidget *parent) : JsonEditor::JsonEditor(QJsonObject rootObject, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::JsonEditor) ui(new Ui::JsonEditor)
{ {
ui->setupUi(this); ui->setupUi(this);
original = document; original = rootObject;
result = document; result = rootObject;
QString jsonString = JsonToString(document); 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); ui->jsonTree->setModel(&model);
model.loadJson(QJsonDocument(document).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(document)); ui->jsonEditor->setText(JsonToString(rootObject));
ui->jsonTree->expandAll(); ui->jsonTree->expandAll();
ui->jsonTree->resizeColumnToContents(0); ui->jsonTree->resizeColumnToContents(0);
} }

View File

@ -15,7 +15,7 @@ class JsonEditor : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit JsonEditor(QJsonObject document, QWidget *parent = nullptr); explicit JsonEditor(QJsonObject rootObject, QWidget *parent = nullptr);
~JsonEditor(); ~JsonEditor();
QJsonObject OpenEditor(); QJsonObject OpenEditor();

View File

@ -16,12 +16,12 @@
#include <Windows.h> #include <Windows.h>
#endif #endif
#include "w_ConnectionEditWindow.h" #include "w_OutboundEditor.h"
#include "w_ImportConfig.h" #include "w_ImportConfig.h"
#include "w_MainWindow.h" #include "w_MainWindow.h"
#include "w_RouteEditor.h" #include "w_RoutesEditor.h"
#include "w_PrefrencesWindow.h" #include "w_PrefrencesWindow.h"
#include "w_SubscribeEditor.h" #include "w_SubscriptionEditor.h"
#include "w_JsonEditor.h" #include "w_JsonEditor.h"
#define TRAY_TOOLTIP_PREFIX "Qv2ray " QV2RAY_VERSION_STRING #define TRAY_TOOLTIP_PREFIX "Qv2ray " QV2RAY_VERSION_STRING
@ -533,8 +533,8 @@ void MainWindow::on_importConfigButton_clicked()
void MainWindow::on_addConfigButton_clicked() void MainWindow::on_addConfigButton_clicked()
{ {
ConnectionEditWindow *w = new ConnectionEditWindow(this); OutboundEditor *w = new OutboundEditor(this);
connect(w, &ConnectionEditWindow::s_reload_config, this, &MainWindow::OnConfigListChanged); connect(w, &OutboundEditor::s_reload_config, this, &MainWindow::OnConfigListChanged);
auto outboundEntry = w->OpenEditor(); auto outboundEntry = w->OpenEditor();
QJsonArray outboundsList; QJsonArray outboundsList;
outboundsList.push_back(outboundEntry); outboundsList.push_back(outboundEntry);
@ -570,7 +570,7 @@ void MainWindow::on_editConfigButton_clicked()
root = routeWindow->OpenEditor(); root = routeWindow->OpenEditor();
} else { } else {
LOG(MODULE_UI, "INFO: Opening single connection edit window.") LOG(MODULE_UI, "INFO: Opening single connection edit window.")
ConnectionEditWindow *w = new ConnectionEditWindow(outBoundRoot["outbounds"].toArray().first().toObject(), &alias, this); OutboundEditor *w = new OutboundEditor(outBoundRoot["outbounds"].toArray().first().toObject(), &alias, this);
auto outboundEntry = w->OpenEditor(); auto outboundEntry = w->OpenEditor();
QJsonArray outboundsList; QJsonArray outboundsList;
outboundsList.push_back(outboundEntry); outboundsList.push_back(outboundEntry);

View File

@ -3,15 +3,15 @@
#include <QIntValidator> #include <QIntValidator>
#include <iostream> #include <iostream>
#include "w_ConnectionEditWindow.h" #include "w_OutboundEditor.h"
#include "w_MainWindow.h" #include "w_MainWindow.h"
#include "w_JsonEditor.h" #include "w_JsonEditor.h"
ConnectionEditWindow::ConnectionEditWindow(QWidget *parent) OutboundEditor::OutboundEditor(QWidget *parent)
: QDialog(parent), : QDialog(parent),
Tag(OUTBOUND_TAG_PROXY), Tag(OUTBOUND_TAG_PROXY),
Alias(), Alias(),
ui(new Ui::ConnectionEditWindow), ui(new Ui::OutboundEditor),
stream(), stream(),
vmess(), vmess(),
shadowsocks() shadowsocks()
@ -31,8 +31,8 @@ ConnectionEditWindow::ConnectionEditWindow(QWidget *parent)
Result = GenerateConnectionJson(); Result = GenerateConnectionJson();
} }
ConnectionEditWindow::ConnectionEditWindow(QJsonObject outboundEntry, QString *alias, QWidget *parent) OutboundEditor::OutboundEditor(QJsonObject outboundEntry, QString *alias, QWidget *parent)
: ConnectionEditWindow(parent) : OutboundEditor(parent)
{ {
Original = outboundEntry; Original = outboundEntry;
Alias = alias == nullptr ? "" : *alias; Alias = alias == nullptr ? "" : *alias;
@ -65,18 +65,18 @@ ConnectionEditWindow::ConnectionEditWindow(QJsonObject outboundEntry, QString *a
} }
ConnectionEditWindow::~ConnectionEditWindow() OutboundEditor::~OutboundEditor()
{ {
delete ui; delete ui;
} }
QJsonObject ConnectionEditWindow::OpenEditor() QJsonObject OutboundEditor::OpenEditor()
{ {
int resultCode = this->exec(); int resultCode = this->exec();
return resultCode == QDialog::Accepted ? Result : Original; return resultCode == QDialog::Accepted ? Result : Original;
} }
void ConnectionEditWindow::ReLoad_GUI_JSON_ModelContent() void OutboundEditor::ReLoad_GUI_JSON_ModelContent()
{ {
if (OutboundType == "vmess") { if (OutboundType == "vmess") {
ui->outBoundTypeCombo->setCurrentIndex(0); ui->outBoundTypeCombo->setCurrentIndex(0);
@ -151,7 +151,7 @@ void ConnectionEditWindow::ReLoad_GUI_JSON_ModelContent()
} }
void ConnectionEditWindow::on_buttonBox_accepted() void OutboundEditor::on_buttonBox_accepted()
{ {
// TODO : NAMING THE CONNECTION // TODO : NAMING THE CONNECTION
auto alias = Alias == "" ? (ui->ipLineEdit->text() + "_" + ui->portLineEdit->text()) : Alias; auto alias = Alias == "" ? (ui->ipLineEdit->text() + "_" + ui->portLineEdit->text()) : Alias;
@ -179,7 +179,7 @@ void ConnectionEditWindow::on_buttonBox_accepted()
//emit s_reload_config(!is_new_config); //emit s_reload_config(!is_new_config);
} }
void ConnectionEditWindow::on_ipLineEdit_textEdited(const QString &arg1) void OutboundEditor::on_ipLineEdit_textEdited(const QString &arg1)
{ {
vmess.address = arg1.toStdString(); vmess.address = arg1.toStdString();
shadowsocks.address = arg1.toStdString(); shadowsocks.address = arg1.toStdString();
@ -197,7 +197,7 @@ void ConnectionEditWindow::on_ipLineEdit_textEdited(const QString &arg1)
//} //}
} }
void ConnectionEditWindow::on_portLineEdit_textEdited(const QString &arg1) void OutboundEditor::on_portLineEdit_textEdited(const QString &arg1)
{ {
if (arg1 != "") { if (arg1 != "") {
vmess.port = stoi(arg1.toStdString()); vmess.port = stoi(arg1.toStdString());
@ -206,38 +206,38 @@ void ConnectionEditWindow::on_portLineEdit_textEdited(const QString &arg1)
} }
} }
void ConnectionEditWindow::on_idLineEdit_textEdited(const QString &arg1) void OutboundEditor::on_idLineEdit_textEdited(const QString &arg1)
{ {
if (vmess.users.empty()) vmess.users.push_back(VMessServerObject::UserObject()); if (vmess.users.empty()) vmess.users.push_back(VMessServerObject::UserObject());
vmess.users.front().id = arg1.toStdString(); vmess.users.front().id = arg1.toStdString();
} }
void ConnectionEditWindow::on_alterLineEdit_textEdited(const QString &arg1) void OutboundEditor::on_alterLineEdit_textEdited(const QString &arg1)
{ {
if (vmess.users.empty()) vmess.users.push_back(VMessServerObject::UserObject()); if (vmess.users.empty()) vmess.users.push_back(VMessServerObject::UserObject());
vmess.users.front().alterId = stoi(arg1.toStdString()); vmess.users.front().alterId = stoi(arg1.toStdString());
} }
void ConnectionEditWindow::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());
vmess.users.front().security = arg1.toStdString(); vmess.users.front().security = arg1.toStdString();
} }
void ConnectionEditWindow::on_tranportCombo_currentIndexChanged(const QString &arg1) void OutboundEditor::on_tranportCombo_currentIndexChanged(const QString &arg1)
{ {
stream.network = arg1.toStdString(); stream.network = arg1.toStdString();
} }
void ConnectionEditWindow::on_httpPathTxt_textEdited(const QString &arg1) void OutboundEditor::on_httpPathTxt_textEdited(const QString &arg1)
{ {
stream.httpSettings.path = arg1.toStdString(); stream.httpSettings.path = arg1.toStdString();
} }
void ConnectionEditWindow::on_httpHostTxt_textChanged() void OutboundEditor::on_httpHostTxt_textChanged()
{ {
try { try {
QStringList hosts = ui->httpHostTxt->toPlainText().replace("\r", "").split("\n"); QStringList hosts = ui->httpHostTxt->toPlainText().replace("\r", "").split("\n");
@ -254,16 +254,18 @@ void ConnectionEditWindow::on_httpHostTxt_textChanged()
} }
} }
void ConnectionEditWindow::on_wsHeadersTxt_textChanged() void OutboundEditor::on_wsHeadersTxt_textChanged()
{ {
try { try {
QStringList headers = ui->wsHeadersTxt->toPlainText().replace("\r", "").split("\n"); QStringList headers = ui->wsHeadersTxt->toPlainText().replace("\r", "").split("\n");
stream.wsSettings.headers.clear(); stream.wsSettings.headers.clear();
foreach (auto header, headers) { foreach (auto header, headers) {
if (header.isEmpty()) continue;
auto content = header.split("|"); auto content = header.split("|");
if (content.length() < 2) throw "fast fail."; if (content.length() < 2) throw "fast fail to set RED color";
stream.wsSettings.headers.insert(make_pair(content[0].toStdString(), content[1].toStdString())); stream.wsSettings.headers.insert(make_pair(content[0].toStdString(), content[1].toStdString()));
} }
@ -275,7 +277,7 @@ void ConnectionEditWindow::on_wsHeadersTxt_textChanged()
} }
void ConnectionEditWindow::on_tcpRequestDefBtn_clicked() void OutboundEditor::on_tcpRequestDefBtn_clicked()
{ {
ui->tcpRequestTxt->clear(); ui->tcpRequestTxt->clear();
ui->tcpRequestTxt->insertPlainText("{\"version\":\"1.1\",\"method\":\"GET\",\"path\":[\"/\"],\"headers\":" ui->tcpRequestTxt->insertPlainText("{\"version\":\"1.1\",\"method\":\"GET\",\"path\":[\"/\"],\"headers\":"
@ -288,18 +290,18 @@ void ConnectionEditWindow::on_tcpRequestDefBtn_clicked()
"\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}"); "\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}");
} }
void ConnectionEditWindow::on_tcpRespDefBtn_clicked() void OutboundEditor::on_tcpRespDefBtn_clicked()
{ {
ui->tcpRespTxt->clear(); ui->tcpRespTxt->clear();
ui->tcpRespTxt->insertPlainText("{\"version\":\"1.1\",\"status\":\"200\",\"reason\":\"OK\",\"headers\":{\"Content-Type\":[\"application/octet-stream\",\"video/mpeg\"],\"Transfer-Encoding\":[\"chunked\"],\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}"); 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\"}}");
} }
void ConnectionEditWindow::on_genJsonBtn_clicked() void OutboundEditor::on_genJsonBtn_clicked()
{ {
auto json = GenerateConnectionJson(); auto json = GenerateConnectionJson();
} }
QJsonObject ConnectionEditWindow::GenerateConnectionJson() QJsonObject OutboundEditor::GenerateConnectionJson()
{ {
// VMess is only a ServerObject, and we need an array { "vnext": [] } // VMess is only a ServerObject, and we need an array { "vnext": [] }
QJsonObject settings; QJsonObject settings;
@ -326,124 +328,124 @@ QJsonObject ConnectionEditWindow::GenerateConnectionJson()
return root; return root;
} }
void ConnectionEditWindow::on_tlsCB_stateChanged(int arg1) void OutboundEditor::on_tlsCB_stateChanged(int arg1)
{ {
stream.security = arg1 == Qt::Checked ? "tls" : "none"; stream.security = arg1 == Qt::Checked ? "tls" : "none";
} }
void ConnectionEditWindow::on_soMarkSpinBox_valueChanged(int arg1) void OutboundEditor::on_soMarkSpinBox_valueChanged(int arg1)
{ {
stream.sockopt.mark = arg1; stream.sockopt.mark = arg1;
} }
void ConnectionEditWindow::on_tcpFastOpenCB_stateChanged(int arg1) void OutboundEditor::on_tcpFastOpenCB_stateChanged(int arg1)
{ {
stream.sockopt.tcpFastOpen = arg1 == Qt::Checked; stream.sockopt.tcpFastOpen = arg1 == Qt::Checked;
} }
void ConnectionEditWindow::on_tProxyCB_currentIndexChanged(const QString &arg1) void OutboundEditor::on_tProxyCB_currentIndexChanged(const QString &arg1)
{ {
stream.sockopt.tproxy = arg1.toStdString(); stream.sockopt.tproxy = arg1.toStdString();
} }
void ConnectionEditWindow::on_quicSecurityCB_currentTextChanged(const QString &arg1) void OutboundEditor::on_quicSecurityCB_currentTextChanged(const QString &arg1)
{ {
stream.quicSettings.security = arg1.toStdString(); stream.quicSettings.security = arg1.toStdString();
} }
void ConnectionEditWindow::on_quicKeyTxt_textEdited(const QString &arg1) void OutboundEditor::on_quicKeyTxt_textEdited(const QString &arg1)
{ {
stream.quicSettings.key = arg1.toStdString(); stream.quicSettings.key = arg1.toStdString();
} }
void ConnectionEditWindow::on_quicHeaderTypeCB_currentIndexChanged(const QString &arg1) void OutboundEditor::on_quicHeaderTypeCB_currentIndexChanged(const QString &arg1)
{ {
stream.quicSettings.header.type = arg1.toStdString(); stream.quicSettings.header.type = arg1.toStdString();
} }
void ConnectionEditWindow::on_tcpHeaderTypeCB_currentIndexChanged(const QString &arg1) void OutboundEditor::on_tcpHeaderTypeCB_currentIndexChanged(const QString &arg1)
{ {
stream.tcpSettings.header.type = arg1.toStdString(); stream.tcpSettings.header.type = arg1.toStdString();
} }
void ConnectionEditWindow::on_wsPathTxt_textEdited(const QString &arg1) void OutboundEditor::on_wsPathTxt_textEdited(const QString &arg1)
{ {
stream.wsSettings.path = arg1.toStdString(); stream.wsSettings.path = arg1.toStdString();
} }
void ConnectionEditWindow::on_kcpMTU_valueChanged(int arg1) void OutboundEditor::on_kcpMTU_valueChanged(int arg1)
{ {
stream.kcpSettings.mtu = arg1; stream.kcpSettings.mtu = arg1;
} }
void ConnectionEditWindow::on_kcpTTI_valueChanged(int arg1) void OutboundEditor::on_kcpTTI_valueChanged(int arg1)
{ {
stream.kcpSettings.tti = arg1; stream.kcpSettings.tti = arg1;
} }
void ConnectionEditWindow::on_kcpUploadCapacSB_valueChanged(int arg1) void OutboundEditor::on_kcpUploadCapacSB_valueChanged(int arg1)
{ {
stream.kcpSettings.uplinkCapacity = arg1; stream.kcpSettings.uplinkCapacity = arg1;
} }
void ConnectionEditWindow::on_kcpCongestionCB_stateChanged(int arg1) void OutboundEditor::on_kcpCongestionCB_stateChanged(int arg1)
{ {
stream.kcpSettings.congestion = arg1 == Qt::Checked; stream.kcpSettings.congestion = arg1 == Qt::Checked;
} }
void ConnectionEditWindow::on_kcpDownCapacitySB_valueChanged(int arg1) void OutboundEditor::on_kcpDownCapacitySB_valueChanged(int arg1)
{ {
stream.kcpSettings.downlinkCapacity = arg1; stream.kcpSettings.downlinkCapacity = arg1;
} }
void ConnectionEditWindow::on_kcpReadBufferSB_valueChanged(int arg1) void OutboundEditor::on_kcpReadBufferSB_valueChanged(int arg1)
{ {
stream.kcpSettings.readBufferSize = arg1; stream.kcpSettings.readBufferSize = arg1;
} }
void ConnectionEditWindow::on_kcpWriteBufferSB_valueChanged(int arg1) void OutboundEditor::on_kcpWriteBufferSB_valueChanged(int arg1)
{ {
stream.kcpSettings.writeBufferSize = arg1; stream.kcpSettings.writeBufferSize = arg1;
} }
void ConnectionEditWindow::on_kcpHeaderType_currentTextChanged(const QString &arg1) void OutboundEditor::on_kcpHeaderType_currentTextChanged(const QString &arg1)
{ {
stream.kcpSettings.header.type = arg1.toStdString(); stream.kcpSettings.header.type = arg1.toStdString();
} }
void ConnectionEditWindow::on_tranportCombo_currentIndexChanged(int index) void OutboundEditor::on_tranportCombo_currentIndexChanged(int index)
{ {
ui->v2rayStackView->setCurrentIndex(index); ui->v2rayStackView->setCurrentIndex(index);
} }
void ConnectionEditWindow::on_dsPathTxt_textEdited(const QString &arg1) void OutboundEditor::on_dsPathTxt_textEdited(const QString &arg1)
{ {
stream.dsSettings.path = arg1.toStdString(); stream.dsSettings.path = arg1.toStdString();
} }
void ConnectionEditWindow::on_outBoundTypeCombo_currentIndexChanged(int index) void OutboundEditor::on_outBoundTypeCombo_currentIndexChanged(int index)
{ {
ui->outboundTypeStackView->setCurrentIndex(index); ui->outboundTypeStackView->setCurrentIndex(index);
OutboundType = ui->outBoundTypeCombo->currentText().toLower(); OutboundType = ui->outBoundTypeCombo->currentText().toLower();
} }
void ConnectionEditWindow::on_ss_emailTxt_textEdited(const QString &arg1) void OutboundEditor::on_ss_emailTxt_textEdited(const QString &arg1)
{ {
shadowsocks.email = arg1.toStdString(); shadowsocks.email = arg1.toStdString();
} }
void ConnectionEditWindow::on_ss_passwordTxt_textEdited(const QString &arg1) void OutboundEditor::on_ss_passwordTxt_textEdited(const QString &arg1)
{ {
shadowsocks.password = arg1.toStdString(); shadowsocks.password = arg1.toStdString();
} }
void ConnectionEditWindow::on_ss_encryptionMethod_currentIndexChanged(const QString &arg1) void OutboundEditor::on_ss_encryptionMethod_currentIndexChanged(const QString &arg1)
{ {
shadowsocks.method = arg1.toStdString(); shadowsocks.method = arg1.toStdString();
} }
void ConnectionEditWindow::on_ss_levelSpin_valueChanged(int arg1) void OutboundEditor::on_ss_levelSpin_valueChanged(int arg1)
{ {
shadowsocks.level = arg1; shadowsocks.level = arg1;
} }
void ConnectionEditWindow::on_ss_otaCheckBox_stateChanged(int arg1) void OutboundEditor::on_ss_otaCheckBox_stateChanged(int arg1)
{ {
shadowsocks.ota = arg1 == Qt::Checked; shadowsocks.ota = arg1 == Qt::Checked;
} }
void ConnectionEditWindow::on_socks_UserNameTxt_textEdited(const QString &arg1) void OutboundEditor::on_socks_UserNameTxt_textEdited(const QString &arg1)
{ {
socks.users.front().user = arg1.toStdString(); socks.users.front().user = arg1.toStdString();
} }
void ConnectionEditWindow::on_socks_PasswordTxt_textEdited(const QString &arg1) void OutboundEditor::on_socks_PasswordTxt_textEdited(const QString &arg1)
{ {
socks.users.front().pass = arg1.toStdString(); socks.users.front().pass = arg1.toStdString();
} }
void ConnectionEditWindow::on_tcpRequestEditBtn_clicked() void OutboundEditor::on_tcpRequestEditBtn_clicked()
{ {
JsonEditor *w = new JsonEditor(JsonFromString(ui->tcpRequestTxt->toPlainText()), this); JsonEditor *w = new JsonEditor(JsonFromString(ui->tcpRequestTxt->toPlainText()), this);
auto rString = JsonToString(w->OpenEditor()); auto rString = JsonToString(w->OpenEditor());
@ -453,7 +455,7 @@ void ConnectionEditWindow::on_tcpRequestEditBtn_clicked()
delete w; delete w;
} }
void ConnectionEditWindow::on_tcpResponseEditBtn_clicked() void OutboundEditor::on_tcpResponseEditBtn_clicked()
{ {
JsonEditor *w = new JsonEditor(JsonFromString(ui->tcpRespTxt->toPlainText()), this); JsonEditor *w = new JsonEditor(JsonFromString(ui->tcpRespTxt->toPlainText()), this);
auto rString = JsonToString(w->OpenEditor()); auto rString = JsonToString(w->OpenEditor());

View File

@ -4,24 +4,24 @@
#include <QtCore> #include <QtCore>
#include <QDialog> #include <QDialog>
#include "QvCoreConfigObjects.h" #include "QvCoreConfigObjects.h"
#include "ui_w_ConnectionEditWindow.h" #include "ui_w_OutboundEditor.h"
namespace Ui namespace Ui
{ {
class ConnectionEditWindow; class OutboundEditor;
} }
class ConnectionEditWindow : public QDialog class OutboundEditor : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ConnectionEditWindow(QWidget *parent = nullptr); explicit OutboundEditor(QWidget *parent = nullptr);
QString Tag; QString Tag;
QString Alias; QString Alias;
QJsonObject OpenEditor(); QJsonObject OpenEditor();
explicit ConnectionEditWindow(QJsonObject outboundEntry, QString *alias, QWidget *parent = nullptr); explicit OutboundEditor(QJsonObject outboundEntry, QString *alias, QWidget *parent = nullptr);
~ConnectionEditWindow(); ~OutboundEditor();
signals: signals:
void s_reload_config(bool need_restart); void s_reload_config(bool need_restart);
private: private:
@ -115,7 +115,7 @@ class ConnectionEditWindow : public QDialog
QJsonObject Original; QJsonObject Original;
QJsonObject Result; QJsonObject Result;
QJsonObject GenerateConnectionJson(); QJsonObject GenerateConnectionJson();
Ui::ConnectionEditWindow *ui; Ui::OutboundEditor *ui;
// //
// Connection Configs // Connection Configs
QString OutboundType; QString OutboundType;

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>ConnectionEditWindow</class> <class>OutboundEditor</class>
<widget class="QDialog" name="ConnectionEditWindow"> <widget class="QDialog" name="OutboundEditor">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -39,7 +39,11 @@
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="QLineEdit" name="ipLineEdit"/> <widget class="QLineEdit" name="ipLineEdit">
<property name="placeholderText">
<string>Hostname or IP Address</string>
</property>
</widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="portLabel"> <widget class="QLabel" name="portLabel">
@ -53,6 +57,9 @@
<property name="maxLength"> <property name="maxLength">
<number>5</number> <number>5</number>
</property> </property>
<property name="placeholderText">
<string>Port</string>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
@ -192,6 +199,9 @@
<property name="maxLength"> <property name="maxLength">
<number>36</number> <number>36</number>
</property> </property>
<property name="placeholderText">
<string notr="true">xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</string>
</property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
@ -206,6 +216,9 @@
<property name="maxLength"> <property name="maxLength">
<number>5</number> <number>5</number>
</property> </property>
<property name="placeholderText">
<string>64</string>
</property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
@ -441,7 +454,11 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLineEdit" name="httpPathTxt"/> <widget class="QLineEdit" name="httpPathTxt">
<property name="placeholderText">
<string notr="true">/</string>
</property>
</widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
@ -451,7 +468,11 @@
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QPlainTextEdit" name="httpHostTxt"/> <widget class="QPlainTextEdit" name="httpHostTxt">
<property name="placeholderText">
<string notr="true">myhost.mydomain.com</string>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -471,10 +492,20 @@
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="placeholderText">
<string>/wsPath</string>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="0">
<widget class="QPlainTextEdit" name="wsHeadersTxt">
<property name="placeholderText">
<string notr="true">Key|Value</string>
</property>
</widget>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_26"> <widget class="QLabel" name="label_26">
<property name="text"> <property name="text">
@ -482,16 +513,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QLabel" name="label_23">
<property name="text">
<string>Format: Key|Value</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPlainTextEdit" name="wsHeadersTxt"/>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="mKCPStackPage"> <widget class="QWidget" name="mKCPStackPage">
@ -719,6 +740,9 @@
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="placeholderText">
<string notr="true">/dsPath</string>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -771,6 +795,9 @@
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="placeholderText">
<string>keys</string>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
@ -976,17 +1003,29 @@
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QLineEdit" name="ss_emailTxt"/> <widget class="QLineEdit" name="ss_emailTxt">
<property name="placeholderText">
<string notr="true">my.name@domain.com</string>
</property>
</widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="QLineEdit" name="ss_passwordTxt"/> <widget class="QLineEdit" name="ss_passwordTxt">
<property name="placeholderText">
<string notr="true">p@ssw0rd</string>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="page_3"> <widget class="QWidget" name="page_3">
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<item row="1" column="1"> <item row="1" column="1">
<widget class="QLineEdit" name="socks_UserNameTxt"/> <widget class="QLineEdit" name="socks_UserNameTxt">
<property name="placeholderText">
<string notr="true">Username</string>
</property>
</widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_31"> <widget class="QLabel" name="label_31">
@ -996,7 +1035,11 @@
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QLineEdit" name="socks_PasswordTxt"/> <widget class="QLineEdit" name="socks_PasswordTxt">
<property name="placeholderText">
<string notr="true">p@ssw0rd</string>
</property>
</widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_21"> <widget class="QLabel" name="label_21">
@ -1029,7 +1072,7 @@
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>accepted()</signal> <signal>accepted()</signal>
<receiver>ConnectionEditWindow</receiver> <receiver>OutboundEditor</receiver>
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
@ -1045,7 +1088,7 @@
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>rejected()</signal> <signal>rejected()</signal>
<receiver>ConnectionEditWindow</receiver> <receiver>OutboundEditor</receiver>
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">

View File

@ -1,7 +1,8 @@
#include "w_RouteEditor.h" #include "w_RoutesEditor.h"
#include "QvCoreConfigOperations.h" #include "QvCoreConfigOperations.h"
#include "ui_w_RouteEditor.h" #include "ui_w_RoutesEditor.h"
#include "w_ConnectionEditWindow.h" #include "w_OutboundEditor.h"
#include "w_JsonEditor.h"
RouteEditor::RouteEditor(QJsonObject connection, const QString alias, QWidget *parent) : RouteEditor::RouteEditor(QJsonObject connection, const QString alias, QWidget *parent) :
QDialog(parent), QDialog(parent),
@ -139,19 +140,23 @@ void RouteEditor::on_routesTable_cellClicked(int row, int column)
void RouteEditor::on_editOutboundBtn_clicked() void RouteEditor::on_editOutboundBtn_clicked()
{ {
QJsonObject result;
int row = ui->outboundsList->currentRow(); int row = ui->outboundsList->currentRow();
auto currentOutbound = outbounds[row].toObject(); auto currentOutbound = outbounds[row].toObject();
auto protocol = currentOutbound["protocol"].toString(); auto protocol = currentOutbound["protocol"].toString();
if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks") { if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks") {
QvMessageBox(this, tr("Cannot Edit"), tr("Currently, this type of outbound is not supported by the editor.")); QvMessageBox(this, tr("Cannot Edit"), tr("Currently, this type of outbound is not supported by the editor."));
return; QvMessageBox(this, tr("Cannot Edit"), tr("We will launch Json Editor instead."));
JsonEditor *w = new JsonEditor(currentOutbound, this);
result = w->OpenEditor();
delete w;
} else {
OutboundEditor *w = new OutboundEditor(currentOutbound, nullptr, this);
result = w->OpenEditor();
delete w;
} }
ConnectionEditWindow *w = new ConnectionEditWindow(currentOutbound, nullptr, this);
auto result = w->OpenEditor();
delete w;
//
outbounds[row] = result; outbounds[row] = result;
on_outboundsList_currentRowChanged(row); on_outboundsList_currentRowChanged(row);
} }
@ -160,3 +165,7 @@ void RouteEditor::on_insertDirectBtn_clicked()
{ {
auto freedom = GenerateFreedomOUT("as-is", "", 0); auto freedom = GenerateFreedomOUT("as-is", "", 0);
} }
void RouteEditor::on_editInboundBtn_clicked()
{
}

View File

@ -33,6 +33,8 @@ class RouteEditor : public QDialog
void on_insertDirectBtn_clicked(); void on_insertDirectBtn_clicked();
void on_editInboundBtn_clicked();
private: private:
QJsonArray inbounds; QJsonArray inbounds;
QJsonArray outbounds; QJsonArray outbounds;

View File

@ -186,62 +186,99 @@
<string>Inbound Information</string> <string>Inbound Information</string>
</property> </property>
<layout class="QFormLayout" name="formLayout_2"> <layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_8"> <widget class="QLabel" name="label_8">
<property name="text"> <property name="text">
<string>Tag</string> <string>Tag</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="1">
<widget class="QLabel" name="inboundTagLabel"> <widget class="QLabel" name="inboundTagLabel">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_9"> <widget class="QLabel" name="label_9">
<property name="text"> <property name="text">
<string>Type</string> <string>Type</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QLabel" name="inboundTypeLabel"> <widget class="QLabel" name="inboundTypeLabel">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_12"> <widget class="QLabel" name="label_12">
<property name="text"> <property name="text">
<string>Address</string> <string>Address</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_13"> <widget class="QLabel" name="label_13">
<property name="text"> <property name="text">
<string>Port</string> <string>Port</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QLabel" name="inboundAddressLabel"> <widget class="QLabel" name="inboundAddressLabel">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QLabel" name="inboundPortLabel"> <widget class="QLabel" name="inboundPortLabel">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>24</width>
<height>18</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="editInboundBtn">
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>24</width>
<height>18</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@ -1,5 +1,5 @@
#include "w_SubscribeEditor.h" #include "w_SubscriptionEditor.h"
#include "ui_w_SubscribeEditor.h" #include "ui_w_SubscriptionEditor.h"
#include "QvHTTPRequestHelper.h" #include "QvHTTPRequestHelper.h"
#include "QvUtils.h" #include "QvUtils.h"
#include "QvCoreConfigOperations.h" #include "QvCoreConfigOperations.h"

File diff suppressed because it is too large Load Diff