[fix] Several further fixes

Former-commit-id: 12fb3bcd29
This commit is contained in:
Leroy.H.Y 2019-11-27 10:39:04 +08:00
parent ce218f1ada
commit 22ecbe25a3
14 changed files with 759 additions and 504 deletions

View File

@ -1 +1 @@
887
917

View File

@ -34,7 +34,7 @@ namespace Qv2ray
bool RenameConnection(QString originalName, QString newName);
// VMess URI Protocol
QJsonObject ConvertConfigFromVMessString(QString vmess, QString *alias, QString *errMessage);
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool overrideInbounds);
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool keepInbounds);
QString ConvertConfigToVMessString(const StreamSettingsObject &transfer, const VMessServerObject &serverConfig, const QString &alias);
}

View File

@ -1,4 +1,4 @@
#include "QvCoreConfigOperations.hpp"
#include "QvCoreConfigOperations.hpp"
namespace Qv2ray
{
@ -224,7 +224,7 @@ namespace Qv2ray
RROOT
}
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool overrideInbounds)
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool keepInbounds)
{
QFile source(sourceFilePath);
@ -233,9 +233,9 @@ namespace Qv2ray
return QJsonObject();
}
auto root = JsonFromString(StringFromFile(new QFile(sourceFilePath)));
auto root = JsonFromString(StringFromFile(&source));
if (overrideInbounds) {
if (!keepInbounds) {
JSON_ROOT_TRY_REMOVE("inbounds")
}

View File

@ -24,6 +24,15 @@ ImportConfigWindow::ImportConfigWindow(QWidget *parent)
nameTxt->setText(QDateTime::currentDateTime().toString("MM-dd_hh-mm") + "_" + tr("Imported") + "_");
}
QMap<QString, QJsonObject> ImportConfigWindow::OpenImport(bool outboundsOnly)
{
// if Outbound Only, set keepImported to false and disable the checkbox
// keepImportedInboundCheckBox->setChecked(!outboundsOnly);
keepImportedInboundCheckBox->setEnabled(!outboundsOnly);
this->exec();
return this->result() == QDialog::Accepted ? connections : QMap<QString, QJsonObject>();
}
void ImportConfigWindow::on_importSourceCombo_currentIndexChanged(int index)
{
stackedWidget->setCurrentIndex(index);
@ -37,17 +46,7 @@ void ImportConfigWindow::on_selectFileBtn_clicked()
void ImportConfigWindow::on_qrFromScreenBtn_clicked()
{
// QRubberBand
QThread::msleep(static_cast<ulong>(doubleSpinBox->value() * 1000));
//bool hasVmessDetected = false;
//for (auto screen : qApp->screens()) {
// if (!screen) {
// LOG(MODULE_UI, "Cannot even find a screen. RARE")
// QvMessageBox(this, tr("Screenshot failed"), tr("Cannot find a valid screen, it's rare."));
// return;
// }
//auto pix = screen->grabWindow(0);
//
ScreenShotWindow w;
auto pix = w.DoScreenShot();
@ -57,32 +56,25 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked()
if (str.trimmed().isEmpty()) {
LOG(MODULE_UI, "Cannot decode QR Code from an image, size: h=" + to_string(pix.width()) + ", v=" + to_string(pix.height()))
QvMessageBox(this, tr("Capture QRCode"), tr("Cannot find a valid QRCode from this region."));
// continue;
} else {
vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE);
//hasVmessDetected = true;
}
}
//}
//if (!hasVmessDetected) {
//QvMessageBox(this, tr("QRCode scanning failed"), tr("Cannot find any QRCode from any screens."));
//}
}
void ImportConfigWindow::on_beginImportBtn_clicked()
{
QString aliasPrefix = nameTxt->text();
QJsonObject config;
auto conf = GetGlobalConfig();
//auto conf = GetGlobalConfig();
switch (importSourceCombo->currentIndex()) {
case 0: {
// From File...
bool overrideInBound = !keepImportedInboundCheckBox->isChecked();
bool keepInBound = keepImportedInboundCheckBox->isChecked();
QString path = fileLineTxt->text();
aliasPrefix = aliasPrefix.isEmpty() ? aliasPrefix : QFileInfo(path).fileName();
config = ConvertConfigFromFile(path, overrideInBound);
config = ConvertConfigFromFile(path, keepInBound);
if (config.isEmpty()) {
QvMessageBox(this, tr("Import config file"), tr("Import from file failed, for more information, please check the log file."));
@ -91,14 +83,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
QvMessageBox(this, tr("Import config file"), tr("Failed to check the validity of the config file."));
return;
} else {
// We save first, "alias" may change to prevent override existing file.
bool alwaysFalse = SaveConnectionConfig(config, &aliasPrefix, false);
if (alwaysFalse) {
QvMessageBox(this, tr("Assertion Failed"), tr("Assertion failed: ::SaveConnectionConfig should returns false."));
}
conf.configs.push_back(aliasPrefix.toStdString());
connections[aliasPrefix] = config;
break;
}
}
@ -125,13 +110,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
vmessErrors[vmess] = QString::number(vmessErrors.count() + 1) + ": " + errMessage;
continue;
} else {
bool alwaysFalse = SaveConnectionConfig(config, &aliasPrefix, false);
if (alwaysFalse) {
QvMessageBox(this, tr("Assertion Failed"), "Assertion failed: ::SaveConnectionConfig should returns false.");
}
conf.configs.push_back(aliasPrefix.toStdString());
connections[aliasPrefix] = config;
}
}
@ -141,24 +120,19 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
vmessConnectionStringTxt->appendPlainText(vmessErrors.key(item));
errorsList->addItem(item);
}
// Don't quit;
return;
}
break;
}
case 2: {
QvMessageBox(this, tr("TODO"), tr("TODO"));
// Subscription link.
break;
}
}
SetGlobalConfig(conf);
// Never restart current connection after import.
emit s_reload_config(false);
close();
accept();
}
void ImportConfigWindow::on_selectImageBtn_clicked()
{
@ -197,7 +171,7 @@ void ImportConfigWindow::on_errorsList_currentItemChanged(QListWidgetItem *curre
return;
}
//
// Select vmess string that is invalid.
QTextCursor c = vmessConnectionStringTxt->textCursor();
c.setPosition(startPos);
c.setPosition(endPos, QTextCursor::KeepAnchor);
@ -218,8 +192,7 @@ void ImportConfigWindow::on_editFileBtn_clicked()
if (!jsonCheckingError.isEmpty()) {
LOG(MODULE_FILE, "Currupted JSON file detected")
if (QvMessageBoxAsk(this, tr("Edit file as JSON"), tr("The file you selected has json syntax error. Continue editing may make you lose data. Would you like to continue?") +
NEWLINE + jsonCheckingError) != QMessageBox::Yes) {
if (QvMessageBoxAsk(this, tr("Edit file as JSON"), tr("The file you selected has json syntax error. Continue editing may make you lose data. Would you like to continue?") + NEWLINE + jsonCheckingError) != QMessageBox::Yes) {
return;
} else {
LOG(MODULE_FILE, "Continue editing curruped json file, data loss is expected.")
@ -257,13 +230,15 @@ void ImportConfigWindow::on_connectionEditBtn_clicked()
root.insert("outbounds", outboundsList);
//
// WARN This one will change the connection name, because of some duplicates.
SaveConnectionConfig(root, &alias, false);
connections[alias] = root;
//SaveConnectionConfig(root, &alias, false);
//
auto conf = GetGlobalConfig();
auto connectionList = conf.configs;
connectionList.push_back(alias.toStdString());
conf.configs = connectionList;
SetGlobalConfig(conf);
// WARN Add connection here
//auto conf = GetGlobalConfig();
//auto connectionList = conf.configs;
//connectionList.push_back(alias.toStdString());
//conf.configs = connectionList;
//SetGlobalConfig(conf);
close();
} else {
return;

View File

@ -2,6 +2,8 @@
#define IMPORTCONF_H
#include <QDialog>
#include <QString>
#include <QJsonObject>
#include "ui_w_ImportConfig.h"
class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
@ -11,8 +13,7 @@ class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
public:
explicit ImportConfigWindow(QWidget *parent = nullptr);
~ImportConfigWindow() { }
signals:
void s_reload_config(bool need_restart);
QMap<QString, QJsonObject> OpenImport(bool outboundsOnly = false);
private slots:
void on_importSourceCombo_currentIndexChanged(int index);
@ -30,6 +31,7 @@ class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
void on_cancelImportBtn_clicked();
private:
QMap<QString, QJsonObject> connections;
QMap<QString, QString> vmessErrors;
};

View File

@ -24,9 +24,13 @@ InboundEditor::InboundEditor(QJsonObject root, QWidget *parent) :
} else if (inboundType == "mtproto") {
mtSettings = root["settings"].toObject();
} else {
LOG(MODULE_UI, "Unsupported inbound type: " + inboundType.toStdString() + ", decisions should be made if to open JSONEDITOR")
if (!root["protocol"].toString().isEmpty()) {
LOG(MODULE_UI, "Unsupported inbound type: " + inboundType.toStdString())
QvMessageBox(this, tr("Inbound type not supported"), tr("The inbound type is not supported by Qv2ray (yet). Please use JsonEditor to change the settings") + "\r\n" +
tr("Inbound: ") + inboundType);
} else {
LOG(MODULE_UI, "Creating new inbound config")
}
}
LoadUIData();
@ -61,7 +65,10 @@ QJsonObject InboundEditor::GenerateNewRoot()
void InboundEditor::LoadUIData()
{
isLoading = true;
strategyCombo->setCurrentText(allocate["strategy"].toString());
auto x = allocate["strategy"].toString();
allocate["strategy"] = x.isEmpty() ? "always" : x;
strategyCombo->setCurrentText(x);
//
refreshNumberBox->setValue(allocate["refresh"].toInt());
concurrencyNumberBox->setValue(allocate["concurrency"].toInt());
enableSniffingCB->setChecked(sniffing["enabled"].toBool());

View File

@ -65,6 +65,7 @@ MainWindow::MainWindow(QWidget *parent)
//
QAction *action_RCM_RenameConnection = new QAction(tr("Rename"), this);
QAction *action_RCM_StartThis = new QAction(tr("Connect to this"), this);
QAction *action_RCM_ConvToComplex = new QAction(tr("Edit as Complex Config"), this);
QAction *action_RCM_EditJson = new QAction(QICON_R("json.png"), tr("Edit as Json"), this);
QAction *action_RCM_ShareQR = new QAction(QICON_R("share.png"), tr("Share as QRCode/VMess URL"), this);
//
@ -88,6 +89,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(action_RCM_RenameConnection, &QAction::triggered, this, &MainWindow::on_action_RenameConnection_triggered);
connect(action_RCM_StartThis, &QAction::triggered, this, &MainWindow::on_action_StartThis_triggered);
connect(action_RCM_EditJson, &QAction::triggered, this, &MainWindow::on_action_RCM_EditJson_triggered);
connect(action_RCM_ConvToComplex, &QAction::triggered, this, &MainWindow::on_action_RCM_ConvToComplex_triggered);
//
// Share optionss
connect(action_RCM_ShareQR, &QAction::triggered, this, &MainWindow::on_action_RCM_ShareQR_triggered);
@ -102,6 +104,7 @@ MainWindow::MainWindow(QWidget *parent)
listMenu = new QMenu(this);
listMenu->addAction(action_RCM_RenameConnection);
listMenu->addAction(action_RCM_StartThis);
listMenu->addAction(action_RCM_ConvToComplex);
listMenu->addAction(action_RCM_EditJson);
listMenu->addAction(action_RCM_ShareQR);
//
@ -308,8 +311,6 @@ void MainWindow::on_startButton_clicked()
bool httpEnabled = conf.inboundConfig.useHTTP;
bool socksEnabled = conf.inboundConfig.useSocks;
// TODO: Set PAC proxy string
if (usePAC) {
bool canStartPAC = true;
QString pacProxyString; // Something like this --> SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT; http://proxy:8080
@ -498,16 +499,26 @@ void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnect
// Check empty again...
if (guiConnectionName.isEmpty()) return;
// --------- BRGIN Show Connection
auto root = connections[guiConnectionName];
auto outBoundRoot = root["outbounds"].toArray().first().toObject();
//
auto outboundType = outBoundRoot["protocol"].toString();
_OutBoundTypeLabel->setText(outboundType);
removeConfigButton->setEnabled(true);
editConfigButton->setEnabled(true);
editJsonBtn->setEnabled(true);
duplicateBtn->setEnabled(true);
//
// --------- BRGIN Show Connection
auto root = connections[guiConnectionName];
//
auto isComplexConfig = root["routing"].toObject()["rules"].toArray().count() > 0;
routeCountLabel->setText(isComplexConfig > 0 ? tr("Complex") : tr("Simple"));
if (isComplexConfig) {
_OutBoundTypeLabel->setText(tr("N/A"));
_hostLabel->setText(tr("N/A"));
_portLabel->setText(tr("N/A"));
} else {
auto outBoundRoot = root["outbounds"].toArray().first().toObject();
auto outboundType = outBoundRoot["protocol"].toString();
_OutBoundTypeLabel->setText(outboundType);
if (outboundType == "vmess") {
auto Server = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
@ -524,8 +535,7 @@ void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnect
_hostLabel->setText(QSTRING(Server.address));
_portLabel->setText(QSTRING(to_string(Server.port)));
}
routeCountLabel->setText(QString::number(root["routing"].toObject()["rules"].toArray().count()));
}
// --------- END Show Connection
//
@ -660,8 +670,22 @@ void MainWindow::on_removeConfigButton_clicked()
}
void MainWindow::on_importConfigButton_clicked()
{
// BETA
ImportConfigWindow *w = new ImportConfigWindow(this);
w->exec();
auto configs = w->OpenImport();
auto gConf = GetGlobalConfig();
for (auto conf : configs) {
auto name = configs.key(conf, "");
if (name.isEmpty())
continue;
SaveConnectionConfig(conf, &name, false);
gConf.configs.push_back(name.toStdString());
}
SetGlobalConfig(gConf);
OnConfigListChanged(false);
}
void MainWindow::on_editConfigButton_clicked()
@ -677,7 +701,7 @@ void MainWindow::on_editConfigButton_clicked()
QJsonObject root;
bool isChanged = false;
if (outBoundRoot["outbounds"].toArray().count() > 1) {
if (CheckIsComplexConfig(outBoundRoot)) {
LOG(MODULE_UI, "INFO: Opening route editor.")
RouteEditor *routeWindow = new RouteEditor(outBoundRoot, this);
root = routeWindow->OpenEditor();
@ -705,6 +729,34 @@ void MainWindow::on_reconnectButton_clicked()
on_stopButton_clicked();
on_startButton_clicked();
}
void MainWindow::on_action_RCM_ConvToComplex_triggered()
{
// Check if we have a connection selected...
if (connectionListWidget->currentIndex().row() < 0) {
QvMessageBox(this, tr("No Config Selected"), tr("Please Select a Config"));
return;
}
auto alias = connectionListWidget->currentItem()->text();
auto outBoundRoot = connections[alias];
QJsonObject root;
bool isChanged = false;
//
LOG(MODULE_UI, "INFO: Opening route editor.")
RouteEditor *routeWindow = new RouteEditor(outBoundRoot, this);
root = routeWindow->OpenEditor();
isChanged = routeWindow->result() == QDialog::Accepted;
if (isChanged) {
connections[alias] = root;
// true indicates the alias will NOT change
SaveConnectionConfig(root, &alias, true);
OnConfigListChanged(alias == CurrentConnectionName);
ShowAndSetConnection(CurrentConnectionName, false, false);
}
}
void MainWindow::on_action_RCM_EditJson_triggered()
{
// Check if we have a connection selected...
@ -745,10 +797,9 @@ void MainWindow::on_shareBtn_clicked()
auto alias = connectionListWidget->currentItem()->text();
auto root = connections[alias];
auto outBoundRoot = root["outbounds"].toArray().first().toObject();
//
auto outboundType = outBoundRoot["protocol"].toString();
if (outboundType == "vmess") {
if (CheckIsComplexConfig(root) && outboundType == "vmess") {
auto vmessServer = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
auto transport = StructFromJsonString<StreamSettingsObject>(JsonToString(outBoundRoot["streamSettings"].toObject()));
auto vmess = ConvertConfigToVMessString(transport, vmessServer, alias);

View File

@ -90,6 +90,7 @@ class MainWindow : public QMainWindow, Ui::MainWindow
//
void on_action_StartThis_triggered();
void on_action_RCM_EditJson_triggered();
void on_action_RCM_ConvToComplex_triggered();
void on_action_RenameConnection_triggered();
//
QvHttpRequestHelper HTTPRequestHelper;

View File

@ -331,26 +331,12 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Mux</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="muxLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Actions</string>
<string>Operations</string>
</property>
</widget>
</item>
@ -387,6 +373,9 @@
</item>
<item>
<widget class="QPushButton" name="pingTestBtn">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Ping Test</string>
</property>

View File

@ -6,6 +6,7 @@
#include "w_OutboundEditor.hpp"
#include "w_MainWindow.hpp"
#include "w_JsonEditor.hpp"
#include "w_RoutesEditor.hpp"
OutboundEditor::OutboundEditor(QWidget *parent)
: QDialog(parent),

View File

@ -28,7 +28,7 @@
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_4" columnstretch="8,3">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
@ -327,7 +327,7 @@
<item row="3" column="5">
<widget class="QPushButton" name="tcpRespDefBtn">
<property name="text">
<string>Default Value</string>
<string>Default</string>
</property>
</widget>
</item>
@ -428,7 +428,7 @@
<item row="3" column="2">
<widget class="QPushButton" name="tcpRequestDefBtn">
<property name="text">
<string>Default Value</string>
<string>Default</string>
</property>
</widget>
</item>
@ -1045,7 +1045,9 @@
</layout>
</widget>
</item>
<item row="2" column="1">
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -1056,6 +1058,8 @@
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>

View File

@ -1,12 +1,12 @@
#include "w_RoutesEditor.hpp"
#include "w_RoutesEditor.hpp"
#include "QvCoreConfigOperations.hpp"
#include "w_OutboundEditor.hpp"
#include "w_JsonEditor.hpp"
#include "w_InboundEditor.hpp"
#include "w_ImportConfig.hpp"
static bool isLoading = false;
#define CurrentRule this->rules[this->currentRuleIndex]
#define STATUS(msg) statusLabel->setText(tr(msg));
#define LOADINGCHECK if(isLoading) return;
RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
@ -318,9 +318,9 @@ void RouteEditor::ShowRuleDetail(RuleObject rule)
inboundsList->item(_index)->setCheckState(Qt::Checked);
inboundsList->setCurrentRow(_index);
STATUS("OK")
statusLabel->setText(tr("OK"));
} else {
STATUS("Cannot find inbound by a tag, possible currupted files?")
statusLabel->setText(tr("Cannot find inbound by a tag, possible currupted files?"));
LOG(MODULE_UI, "An inbound could not be determined by tag.")
return;
}
@ -335,7 +335,7 @@ void RouteEditor::on_editOutboundBtn_clicked()
int row = outboundsList->currentRow();
if (row < 0) {
STATUS("No row selected.")
statusLabel->setText(tr("No row selected."));
LOG(MODULE_UI, "No outbound row selected.")
return;
}
@ -348,19 +348,19 @@ void RouteEditor::on_editOutboundBtn_clicked()
tr("This outbound entry is not supported by the GUI editor.") + "\r\n" +
tr("We will launch Json Editor instead."));
JsonEditor *w = new JsonEditor(currentOutbound, this);
STATUS("Opening JSON editor")
statusLabel->setText(tr("Opening JSON editor"));
result = w->OpenEditor();
delete w;
} else {
OutboundEditor *w = new OutboundEditor(currentOutbound, this);
STATUS("Opening default outbound editor.")
statusLabel->setText(tr("Opening default outbound editor."));
result = w->OpenEditor();
delete w;
}
outbounds[row] = result;
on_outboundsList_currentRowChanged(row);
STATUS("OK")
statusLabel->setText(tr("OK"));
}
void RouteEditor::on_insertDirectBtn_clicked()
@ -370,7 +370,7 @@ void RouteEditor::on_insertDirectBtn_clicked()
auto out = GenerateOutboundEntry("freedom", freedom, QJsonObject(), QJsonObject(), "0.0.0.0", tag);
this->outbounds.append(out);
outboundsList->addItem(tag);
STATUS("Added DIRECT outbound")
statusLabel->setText(tr("Added DIRECT outbound"));
}
void RouteEditor::on_editInboundBtn_clicked()
@ -386,20 +386,20 @@ void RouteEditor::on_editInboundBtn_clicked()
if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") {
QvMessageBox(this, tr("Cannot Edit"), tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" +
tr("We will launch Json Editor instead."));
STATUS("Opening JSON editor")
statusLabel->setText(tr("Opening JSON editor"));
JsonEditor *w = new JsonEditor(currentInbound, this);
result = w->OpenEditor();
delete w;
} else {
InboundEditor *w = new InboundEditor(currentInbound, this);
STATUS("Opening default inbound editor")
statusLabel->setText(tr("Opening default inbound editor"));
result = w->OpenEditor();
delete w;
}
inbounds[row] = result;
on_inboundsList_currentRowChanged(row);
STATUS("OK")
statusLabel->setText(tr("OK"));
}
void RouteEditor::on_routeProtocolHTTPCB_stateChanged(int arg1)
@ -414,7 +414,7 @@ void RouteEditor::on_routeProtocolHTTPCB_stateChanged(int arg1)
if (routeProtocolBTCB->isChecked()) protocols << "bittorrent";
CurrentRule.protocol = protocols.toStdList();
STATUS("Protocol list changed.")
statusLabel->setText(tr("Protocol list changed."));
}
void RouteEditor::on_routeProtocolTLSCB_stateChanged(int arg1)
@ -429,7 +429,7 @@ void RouteEditor::on_routeProtocolTLSCB_stateChanged(int arg1)
if (routeProtocolBTCB->isChecked()) protocols << "bittorrent";
CurrentRule.protocol = protocols.toStdList();
STATUS("Protocol list changed.")
statusLabel->setText(tr("Protocol list changed."));
}
void RouteEditor::on_routeProtocolBTCB_stateChanged(int arg1)
@ -444,7 +444,7 @@ void RouteEditor::on_routeProtocolBTCB_stateChanged(int arg1)
if (routeProtocolTLSCB->isChecked()) protocols << "tls";
CurrentRule.protocol = protocols.toStdList();
STATUS("Protocol list changed.")
statusLabel->setText(tr("Protocol list changed."));
}
void RouteEditor::on_balabcerAddBtn_clicked()
@ -460,9 +460,9 @@ void RouteEditor::on_balabcerAddBtn_clicked()
if (!balancerTx.isEmpty()) {
balancerList->addItem(balancerTx);
balancerSelectionCombo->setEditText("");
STATUS("OK")
statusLabel->setText(tr("OK"));
} else {
STATUS("Balacer is empty, not processing.")
statusLabel->setText(tr("Balacer is empty, not processing."));
}
}
@ -476,7 +476,7 @@ void RouteEditor::on_balancerDelBtn_clicked()
Balancers[QSTRING(CurrentRule.balancerTag)].removeAt(balancerList->currentRow());
balancerList->takeItem(balancerList->currentRow());
STATUS("Removed a balancer entry.")
statusLabel->setText(tr("Removed a balancer entry."));
}
void RouteEditor::on_hostList_textChanged()
@ -569,7 +569,7 @@ void RouteEditor::on_routesTable_cellChanged(int row, int column)
}
rules[row].QV2RAY_RULE_ENABLED = routesTable->item(row, column)->checkState() == Qt::Checked;
STATUS((rules[row].QV2RAY_RULE_ENABLED ? "Enabled a route" : "Disabled a route"))
statusLabel->setText(tr((rules[row].QV2RAY_RULE_ENABLED ? "Enabled a route" : "Disabled a route")));
}
void RouteEditor::on_netBothRB_clicked()
@ -647,7 +647,7 @@ void RouteEditor::on_inboundsList_itemChanged(QListWidgetItem *item)
}
CurrentRule.inboundTag = new_inbounds.toStdList();
STATUS("OK")
statusLabel->setText(tr("OK"));
}
void RouteEditor::on_delRouteBtn_clicked()
@ -730,3 +730,35 @@ void RouteEditor::on_delInboundBtn_clicked()
inbounds.removeAt(index);
inboundsList->takeItem(index);
}
void RouteEditor::on_addInboundBtn_clicked()
{
LOADINGCHECK
InboundEditor w(QJsonObject(), this);
auto _result = w.OpenEditor();
inbounds.append(_result);
inboundsList->addItem(tr("New Inbound"));
}
void RouteEditor::on_addOutboundBtn_clicked()
{
LOADINGCHECK
ImportConfigWindow *w = new ImportConfigWindow(this);
// True here for not keep the inbounds.
auto configs = w->OpenImport(true);
for (auto conf : configs) {
auto name = configs.key(conf, "");
if (name.isEmpty())
continue;
// conf is rootObject, needs to unwrap it.
auto confList = conf["outbounds"].toArray();
for (int i = 0; i < confList.count(); i++) {
outbounds.append(confList[i]);
outboundsList->addItem(name + "_" + QString::number(i));
}
}
}

View File

@ -1,4 +1,4 @@
#ifndef W_QVOUTBOUNDEDITOR_H
#ifndef W_QVOUTBOUNDEDITOR_H
#define W_QVOUTBOUNDEDITOR_H
#include <list>
@ -80,12 +80,16 @@ class RouteEditor : public QDialog, private Ui::RouteEditor
void on_delInboundBtn_clicked();
void on_addInboundBtn_clicked();
void on_addOutboundBtn_clicked();
private:
void ShowRuleDetail(RuleObject rule);
int currentRuleIndex;
QString DomainStrategy;
QMap<QString, QStringList> Balancers;
QList<RuleObject> rules;
QString DomainStrategy;
//
QJsonArray inbounds;
QJsonArray outbounds;

File diff suppressed because it is too large Load Diff