[add] Added new inbound editor [HALF]

This commit is contained in:
Leroy.H.Y 2019-10-10 22:59:50 +08:00
parent 8e5e8cdfb1
commit 1009022eab
No known key found for this signature in database
GPG Key ID: 6AC1673B587DC37D
12 changed files with 1147 additions and 405 deletions

View File

@ -166,13 +166,13 @@ unix {
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 = /usr/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 = /usr/share/icons/hicolor/256x256/apps/
target.path = /opt/$${TARGET}/bin target.path = /usr/local/bin
INSTALLS += target desktop icon INSTALLS += target desktop icon
} }

View File

@ -3,6 +3,6 @@ Type=Application
Keywords=Internet;VPN;Proxy;v2ray;Qt; Keywords=Internet;VPN;Proxy;v2ray;Qt;
Categories=Network;Qt; Categories=Network;Qt;
Icon=Qv2ray Icon=Qv2ray
Exec=/opt/Qv2ray/bin/Qv2ray Exec=Qv2ray
Name=Qv2ray Name=Qv2ray
Comment=Cross platform v2ray Qt GUI Client. Comment=Cross platform v2ray Qt GUI Client.

View File

@ -88,6 +88,7 @@ namespace Qv2ray
{ {
QJsonParseError error; QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(source->toUtf8(), &error); QJsonDocument doc = QJsonDocument::fromJson(source->toUtf8(), &error);
Q_UNUSED(doc)
if (error.error == QJsonParseError::NoError) { if (error.error == QJsonParseError::NoError) {
return ""; return "";
@ -179,5 +180,3 @@ namespace Qv2ray
} }
} }
} }

View File

@ -1,14 +1,419 @@
#include "w_InboundEditor.h" #include "w_InboundEditor.h"
#include "ui_w_InboundEditor.h" #include "ui_w_InboundEditor.h"
#include "QvUtils.h"
#include "QvCoreConfigOperations.h"
InboundEditor::InboundEditor(QWidget *parent) : static bool isLoading = false;
#define PREPARE_RETURN if(isLoading) return;
InboundEditor::InboundEditor(QJsonObject root, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::InboundEditor) ui(new Ui::InboundEditor)
{ {
original = root;
this->root = root;
auto inboundType = root["protocol"].toString();
allocate = root["allocate"].toObject();
sniffing = root["sniffing"].toObject();
if (inboundType == "http") {
httpSettings = root["settings"].toObject();
} else if (inboundType == "socks") {
socksSettings = root["settings"].toObject();
} else if (inboundType == "dokodemo-door") {
dokoSettings = root["settings"].toObject();
} 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")
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);
}
ui->setupUi(this); ui->setupUi(this);
LoadUIData();
}
QJsonObject InboundEditor::OpenEditor()
{
int resultCode = this->exec();
return resultCode == QDialog::Accepted ? GenerateNewRoot() : original;
}
QJsonObject InboundEditor::GenerateNewRoot()
{
QJsonObject _newRoot = root;
auto inboundType = root["protocol"].toString();
if (inboundType == "http") {
_newRoot["settings"] = httpSettings;
} else if (inboundType == "socks") {
_newRoot["settings"] = socksSettings;
} else if (inboundType == "dokodemo-door") {
_newRoot["settings"] = dokoSettings;
} else if (inboundType == "mtproto") {
_newRoot["settings"] = mtSettings;
}
_newRoot["sniffing"] = sniffing;
_newRoot["allocate"] = allocate;
return _newRoot;
}
void InboundEditor::LoadUIData()
{
isLoading = true;
ui->strategyCombo->setCurrentText(allocate["strategy"].toString());
ui->refreshNumberBox->setValue(allocate["refresh"].toInt());
ui->concurrencyNumberBox->setValue(allocate["concurrency"].toInt());
ui->enableSniffingCB->setChecked(sniffing["enabled"].toBool());
foreach (auto item, sniffing["destOverride"].toArray()) {
if (item.toString().toLower() == "http") ui->destOverrideList->item(0)->setCheckState(Qt::Checked);
if (item.toString().toLower() == "tls") ui->destOverrideList->item(1)->setCheckState(Qt::Checked);
}
//
ui->inboundTagTxt->setText(root["tag"].toString());
ui->inboundHostTxt->setText(root["listen"].toString());
ui->inboundPortTxt->setText(root["port"].toVariant().toString());
ui->inboundProtocolCombo->setCurrentText(root["protocol"].toString());
// HTTP
ui->httpTimeoutSpinBox->setValue(httpSettings["timeout"].toInt());
ui->httpTransparentCB->setChecked(httpSettings["allowTransparent"].toBool());
ui->httpUserLevelSB->setValue(httpSettings["userLevel"].toInt());
ui->httpAccountListBox->clear();
for (auto user : httpSettings["accounts"].toArray()) {
ui->httpAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString());
}
// SOCKS
ui->socksAuthCombo->setCurrentText(socksSettings["auth"].toString());
ui->socksUDPCB->setChecked(socksSettings["udp"].toBool());
ui->socksUDPIPAddrTxt->setText(socksSettings["ip"].toString());
ui->socksUserLevelSB->setValue(socksSettings["userLevel"].toInt());
for (auto user : socksSettings["accounts"].toArray()) {
ui->socksAccountListBox->addItem(user.toObject()["user"].toString() + ":" + user.toObject()["pass"].toString());
}
// Dokodemo-Door
ui->dokoFollowRedirectCB->setChecked(dokoSettings["followRedirect"].toBool());
ui->dokoIPAddrTxt->setText(dokoSettings["address"].toString());
ui->dokoPortSB->setValue(dokoSettings["port"].toInt());
ui->dokoTimeoutSB->setValue(dokoSettings["timeout"].toInt());
ui->dokoUserLevelSB->setValue(dokoSettings["userLevel"].toInt());
ui->dokoTCPCB->setChecked(dokoSettings["network"].toString().contains("tcp"));
ui->dokoUDPCB->setChecked(dokoSettings["network"].toString().contains("udp"));
// MTProto
ui->mtEMailTxt->setText(mtSettings["users"].toArray().first()["email"].toString());
ui->mtUserLevelSB->setValue(mtSettings["users"].toArray().first()["level"].toInt());
ui->mtSecretTxt->setText(mtSettings["users"].toArray().first()["secret"].toString());
isLoading = false;
} }
InboundEditor::~InboundEditor() InboundEditor::~InboundEditor()
{ {
delete ui; delete ui;
} }
void InboundEditor::on_inboundProtocolCombo_currentIndexChanged(const QString &arg1)
{
PREPARE_RETURN
root["protocol"] = arg1.toLower();
}
void InboundEditor::on_inboundProtocolCombo_currentIndexChanged(int index)
{
ui->stackedWidget->setCurrentIndex(index);
}
void InboundEditor::on_inboundTagTxt_textEdited(const QString &arg1)
{
PREPARE_RETURN
root["tag"] = arg1;
}
void InboundEditor::on_httpTimeoutSpinBox_valueChanged(int arg1)
{
PREPARE_RETURN
httpSettings["timtout"] = arg1;
}
void InboundEditor::on_httpTransparentCB_stateChanged(int arg1)
{
PREPARE_RETURN
httpSettings["allowTransparent"] = arg1 == Qt::Checked;
}
void InboundEditor::on_httpUserLevelSB_valueChanged(int arg1)
{
PREPARE_RETURN
httpSettings["userLevel"] = arg1;
}
void InboundEditor::on_httpRemoveUserBtn_clicked()
{
PREPARE_RETURN
if (ui->httpAccountListBox->currentRow() != -1) {
auto userpass = ui->httpAccountListBox->currentItem();
auto list = httpSettings["accounts"].toArray();
for (int i = 0 ; i < list.count(); i++) {
auto user = list[i].toObject();
if (user["user"].toString() + ":" + user["pass"].toString() == userpass->text()) {
list.removeAt(i);
ui->httpAccountListBox->removeItemWidget(userpass);
return;
}
}
} else {
QvMessageBox(this, tr("Removing a user"), tr("You haven't selected a user yet,"));
}
}
void InboundEditor::on_httpAddUserBtn_clicked()
{
PREPARE_RETURN
auto user = ui->httpAddUserTxt->text();
auto pass = ui->httpAddPasswordTxt->text();
//
auto list = httpSettings["accounts"].toArray();
for (int i = 0 ; i < list.count(); i++) {
auto _user = list[i].toObject();
if (_user["user"].toString() == user) {
QvMessageBox(this, tr("Add a user"), tr("This user exists already."));
return;
}
}
QJsonObject entry;
entry["user"] = user;
entry["pass"] = pass;
list.append(entry);
httpSettings["accounts"] = list;
}
void InboundEditor::on_strategyCombo_currentIndexChanged(const QString &arg1)
{
PREPARE_RETURN
allocate["strategy"] = arg1.toLower();
}
void InboundEditor::on_refreshNumberBox_valueChanged(int arg1)
{
PREPARE_RETURN
allocate["refresh"] = arg1;
}
void InboundEditor::on_concurrencyNumberBox_valueChanged(int arg1)
{
PREPARE_RETURN
allocate["concurrency"] = arg1;
}
void InboundEditor::on_enableSniffingCB_stateChanged(int arg1)
{
PREPARE_RETURN
sniffing["enabled"] = arg1 == Qt::Checked;
}
void InboundEditor::on_destOverrideList_itemChanged(QListWidgetItem *item)
{
PREPARE_RETURN
Q_UNUSED(item)
QJsonArray list;
for (int i = 0; i < ui->destOverrideList->count(); i++) {
auto _item = ui->destOverrideList->item(i);
if (item->checkState() == Qt::Checked) {
list.append(_item->text().toLower());
}
}
sniffing["destOverride"] = list;
}
void InboundEditor::on_socksUDPCB_stateChanged(int arg1)
{
PREPARE_RETURN
socksSettings["udp"] = arg1 == Qt::Checked;
}
void InboundEditor::on_socksUDPIPAddrTxt_textEdited(const QString &arg1)
{
PREPARE_RETURN
socksSettings["ip"] = arg1;
}
void InboundEditor::on_socksUserLevelSB_valueChanged(int arg1)
{
PREPARE_RETURN
socksSettings["userLevel"] = arg1;
}
void InboundEditor::on_socksRemoveUserBtn_clicked()
{
PREPARE_RETURN
if (ui->socksAccountListBox->currentRow() != -1) {
auto userpass = ui->socksAccountListBox->currentItem();
auto list = socksSettings["accounts"].toArray();
for (int i = 0 ; i < list.count(); i++) {
auto user = list[i].toObject();
if (user["user"].toString() + ":" + user["pass"].toString() == userpass->text()) {
list.removeAt(i);
ui->socksAccountListBox->removeItemWidget(userpass);
return;
}
}
} else {
QvMessageBox(this, tr("Removing a user"), tr("You haven't selected a user yet,"));
}
}
void InboundEditor::on_socksAddUserBtn_clicked()
{
PREPARE_RETURN
auto user = ui->socksAddUserTxt->text();
auto pass = ui->socksAddPasswordTxt->text();
//
auto list = socksSettings["accounts"].toArray();
for (int i = 0 ; i < list.count(); i++) {
auto _user = list[i].toObject();
if (_user["user"].toString() == user) {
QvMessageBox(this, tr("Add a user"), tr("This user exists already."));
return;
}
}
QJsonObject entry;
entry["user"] = user;
entry["pass"] = pass;
list.append(entry);
socksSettings["accounts"] = list;
}
void InboundEditor::on_dokoIPAddrTxt_textEdited(const QString &arg1)
{
PREPARE_RETURN
dokoSettings["address"] = arg1;
}
void InboundEditor::on_dokoPortSB_valueChanged(int arg1)
{
PREPARE_RETURN
dokoSettings["port"] = arg1;
}
void InboundEditor::on_dokoTCPCB_stateChanged(int arg1)
{
PREPARE_RETURN
Q_UNUSED(arg1)
bool hasTCP = ui->dokoTCPCB->checkState() == Qt::Checked;
bool hasUDP = ui->dokoUDPCB->checkState() == Qt::Checked;
QString str = "";
str += hasTCP ? "tcp" : "";
str += (hasTCP && hasUDP) ? "," : "";
str += hasUDP ? "udp" : "";
dokoSettings["network"] = str;
}
void InboundEditor::on_dokoUDPCB_stateChanged(int arg1)
{
PREPARE_RETURN
Q_UNUSED(arg1)
bool hasTCP = ui->dokoTCPCB->checkState() == Qt::Checked;
bool hasUDP = ui->dokoUDPCB->checkState() == Qt::Checked;
QString str = "";
str += hasTCP ? "tcp" : "";
str += (hasTCP && hasUDP) ? "," : "";
str += hasUDP ? "udp" : "";
dokoSettings["network"] = str;
}
void InboundEditor::on_dokoTimeoutSB_valueChanged(int arg1)
{
PREPARE_RETURN
dokoSettings["timeout"] = arg1;
}
void InboundEditor::on_dokoFollowRedirectCB_stateChanged(int arg1)
{
PREPARE_RETURN
dokoSettings["followRedirect"] = arg1 == Qt::Checked;
}
void InboundEditor::on_dokoUserLevelSB_valueChanged(int arg1)
{
PREPARE_RETURN
dokoSettings["userLevel"] = arg1;
}
void InboundEditor::on_mtEMailTxt_textEdited(const QString &arg1)
{
PREPARE_RETURN
if (!mtSettings.contains("users")) mtSettings["users"] = QJsonArray();
QJsonObject user = mtSettings["users"].toArray().empty() ? QJsonObject() : mtSettings["users"].toArray().first().toObject();
user["email"] = arg1;
QJsonArray list;
list.append(user);
mtSettings["users"] = list;
}
void InboundEditor::on_mtSecretTxt_textEdited(const QString &arg1)
{
PREPARE_RETURN
if (!mtSettings.contains("users")) mtSettings["users"] = QJsonArray();
QJsonObject user = mtSettings["users"].toArray().empty() ? QJsonObject() : mtSettings["users"].toArray().first().toObject();
user["secret"] = arg1;
QJsonArray list;
list.append(user);
mtSettings["users"] = list;
}
void InboundEditor::on_mtUserLevelSB_valueChanged(int arg1)
{
PREPARE_RETURN
if (!mtSettings.contains("users")) mtSettings["users"] = QJsonArray();
QJsonObject user = mtSettings["users"].toArray().empty() ? QJsonObject() : mtSettings["users"].toArray().first().toObject();
user["userLevel"] = arg1;
QJsonArray list;
list.append(user);
mtSettings["users"] = list;
}
void InboundEditor::on_inboundHostTxt_textEdited(const QString &arg1)
{
PREPARE_RETURN
root["listen"] = arg1;
}
void InboundEditor::on_inboundPortTxt_textEdited(const QString &arg1)
{
PREPARE_RETURN
root["port"] = arg1;
}
void InboundEditor::on_socksAuthCombo_currentIndexChanged(const QString &arg1)
{
PREPARE_RETURN
socksSettings["auth"] = arg1.toLower();
}

View File

@ -2,21 +2,100 @@
#define W_INBOUNDEDITOR_H #define W_INBOUNDEDITOR_H
#include <QDialog> #include <QDialog>
#include <QJsonObject>
#include <QListWidgetItem>
namespace Ui { namespace Ui
class InboundEditor; {
class InboundEditor;
} }
class InboundEditor : public QDialog class InboundEditor : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit InboundEditor(QWidget *parent = nullptr); explicit InboundEditor(QJsonObject root, QWidget *parent = nullptr);
~InboundEditor(); ~InboundEditor();
QJsonObject OpenEditor();
private: private slots:
Ui::InboundEditor *ui; void on_inboundProtocolCombo_currentIndexChanged(const QString &arg1);
void on_inboundProtocolCombo_currentIndexChanged(int index);
void on_inboundTagTxt_textEdited(const QString &arg1);
void on_httpTimeoutSpinBox_valueChanged(int arg1);
void on_httpTransparentCB_stateChanged(int arg1);
void on_httpUserLevelSB_valueChanged(int arg1);
void on_httpRemoveUserBtn_clicked();
void on_httpAddUserBtn_clicked();
void on_strategyCombo_currentIndexChanged(const QString &arg1);
void on_refreshNumberBox_valueChanged(int arg1);
void on_concurrencyNumberBox_valueChanged(int arg1);
void on_enableSniffingCB_stateChanged(int arg1);
void on_destOverrideList_itemChanged(QListWidgetItem *item);
void on_socksUDPCB_stateChanged(int arg1);
void on_socksUDPIPAddrTxt_textEdited(const QString &arg1);
void on_socksUserLevelSB_valueChanged(int arg1);
void on_socksRemoveUserBtn_clicked();
void on_socksAddUserBtn_clicked();
void on_dokoIPAddrTxt_textEdited(const QString &arg1);
void on_dokoPortSB_valueChanged(int arg1);
void on_dokoTCPCB_stateChanged(int arg1);
void on_dokoUDPCB_stateChanged(int arg1);
void on_dokoTimeoutSB_valueChanged(int arg1);
void on_dokoFollowRedirectCB_stateChanged(int arg1);
void on_dokoUserLevelSB_valueChanged(int arg1);
void on_mtEMailTxt_textEdited(const QString &arg1);
void on_mtSecretTxt_textEdited(const QString &arg1);
void on_mtUserLevelSB_valueChanged(int arg1);
void on_inboundHostTxt_textEdited(const QString &arg1);
void on_inboundPortTxt_textEdited(const QString &arg1);
void on_socksAuthCombo_currentIndexChanged(const QString &arg1);
private:
QJsonObject GenerateNewRoot();
void LoadUIData();
Ui::InboundEditor *ui;
QJsonObject original;
QJsonObject root;
//
QJsonObject httpSettings;
QJsonObject socksSettings;
QJsonObject mtSettings;
QJsonObject dokoSettings;
//
QJsonObject sniffing;
QJsonObject allocate;
}; };
#endif // W_INBOUNDEDITOR_H #endif // W_INBOUNDEDITOR_H

View File

@ -2,12 +2,15 @@
<ui version="4.0"> <ui version="4.0">
<class>InboundEditor</class> <class>InboundEditor</class>
<widget class="QDialog" name="InboundEditor"> <widget class="QDialog" name="InboundEditor">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>874</width> <width>815</width>
<height>497</height> <height>500</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -24,6 +27,9 @@
<property name="text"> <property name="text">
<string>Tag</string> <string>Tag</string>
</property> </property>
<property name="buddy">
<cstring>inboundTagTxt</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
@ -41,7 +47,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0,1"> <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="2,0,1">
<item> <item>
<widget class="QLineEdit" name="inboundHostTxt"> <widget class="QLineEdit" name="inboundHostTxt">
<property name="placeholderText"> <property name="placeholderText">
@ -59,7 +65,7 @@
<item> <item>
<widget class="QLineEdit" name="inboundPortTxt"> <widget class="QLineEdit" name="inboundPortTxt">
<property name="placeholderText"> <property name="placeholderText">
<string>Port: 1080|env:PORT|80-85</string> <string>Port: 1080|80-85</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -70,10 +76,13 @@
<property name="text"> <property name="text">
<string>Protocol</string> <string>Protocol</string>
</property> </property>
<property name="buddy">
<cstring>inboundProtocolCombo</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QComboBox" name="inboundProtocolTxt"> <widget class="QComboBox" name="inboundProtocolCombo">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -82,22 +91,22 @@
</property> </property>
<item> <item>
<property name="text"> <property name="text">
<string>HTTP</string> <string notr="true">http</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>SOCKS</string> <string notr="true">socks</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>Dokodemo</string> <string notr="true">dokodemo-door</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>MTProto</string> <string notr="true">mtproto</string>
</property> </property>
</item> </item>
</widget> </widget>
@ -115,6 +124,9 @@
<property name="text"> <property name="text">
<string>Strategy</string> <string>Strategy</string>
</property> </property>
<property name="buddy">
<cstring>strategyCombo</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
@ -127,12 +139,12 @@
</property> </property>
<item> <item>
<property name="text"> <property name="text">
<string>Always</string> <string>always</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>Random</string> <string>random</string>
</property> </property>
</item> </item>
</widget> </widget>
@ -142,6 +154,9 @@
<property name="text"> <property name="text">
<string>Refresh</string> <string>Refresh</string>
</property> </property>
<property name="buddy">
<cstring>refreshNumberBox</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
@ -165,6 +180,9 @@
<property name="text"> <property name="text">
<string>Concurrency</string> <string>Concurrency</string>
</property> </property>
<property name="buddy">
<cstring>concurrencyNumberBox</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
@ -194,9 +212,32 @@
<layout class="QFormLayout" name="formLayout_2"> <layout class="QFormLayout" name="formLayout_2">
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text"> <property name="text">
<string>Destination <string>Destination Override</string>
Override</string> </property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>destOverrideList</cstring>
</property> </property>
</widget> </widget>
</item> </item>
@ -204,7 +245,7 @@ Override</string>
<widget class="QListWidget" name="destOverrideList"> <widget class="QListWidget" name="destOverrideList">
<item> <item>
<property name="text"> <property name="text">
<string notr="true">http</string> <string notr="true">HTTP</string>
</property> </property>
<property name="checkState"> <property name="checkState">
<enum>Unchecked</enum> <enum>Unchecked</enum>
@ -212,7 +253,7 @@ Override</string>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string notr="true">tls</string> <string notr="true">TLS</string>
</property> </property>
<property name="checkState"> <property name="checkState">
<enum>Unchecked</enum> <enum>Unchecked</enum>
@ -232,6 +273,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Enabled</string> <string>Enabled</string>
</property> </property>
<property name="buddy">
<cstring>enableSniffingCB</cstring>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -250,7 +294,7 @@ Override</string>
<item row="4" column="0"> <item row="4" column="0">
<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="HTTPPage"> <widget class="QWidget" name="HTTPPage">
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
@ -267,6 +311,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Timeout</string> <string>Timeout</string>
</property> </property>
<property name="buddy">
<cstring>httpTimeoutSpinBox</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
@ -277,6 +324,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Allow Transparent</string> <string>Allow Transparent</string>
</property> </property>
<property name="buddy">
<cstring>httpTransparentCB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
@ -291,6 +341,9 @@ Override</string>
<property name="text"> <property name="text">
<string>User Level</string> <string>User Level</string>
</property> </property>
<property name="buddy">
<cstring>httpUserLevelSB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
@ -299,7 +352,7 @@ Override</string>
</layout> </layout>
</item> </item>
<item> <item>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3" rowstretch="0,1,1,0">
<item row="1" column="3"> <item row="1" column="3">
<widget class="QToolButton" name="httpRemoveUserBtn"> <widget class="QToolButton" name="httpRemoveUserBtn">
<property name="text"> <property name="text">
@ -337,6 +390,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Add</string> <string>Add</string>
</property> </property>
<property name="buddy">
<cstring>httpAddUserTxt</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
@ -375,18 +431,21 @@ Override</string>
<property name="text"> <property name="text">
<string>Auth</string> <string>Auth</string>
</property> </property>
<property name="buddy">
<cstring>socksAuthCombo</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QComboBox" name="socksAuthCombo"> <widget class="QComboBox" name="socksAuthCombo">
<item> <item>
<property name="text"> <property name="text">
<string>No Auth</string> <string notr="true">noauth</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>Password</string> <string notr="true">password</string>
</property> </property>
</item> </item>
</widget> </widget>
@ -396,6 +455,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Enable UDP</string> <string>Enable UDP</string>
</property> </property>
<property name="buddy">
<cstring>socksUDPCB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
@ -403,6 +465,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Local UDP IP</string> <string>Local UDP IP</string>
</property> </property>
<property name="buddy">
<cstring>socksUDPIPAddrTxt</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
@ -410,6 +475,9 @@ Override</string>
<property name="text"> <property name="text">
<string>User Level</string> <string>User Level</string>
</property> </property>
<property name="buddy">
<cstring>socksUserLevelSB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
@ -432,7 +500,7 @@ Override</string>
</layout> </layout>
</item> </item>
<item> <item>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="gridLayout_4" rowstretch="0,1,1,0">
<item row="1" column="3"> <item row="1" column="3">
<widget class="QToolButton" name="socksRemoveUserBtn"> <widget class="QToolButton" name="socksRemoveUserBtn">
<property name="text"> <property name="text">
@ -470,6 +538,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Add</string> <string>Add</string>
</property> </property>
<property name="buddy">
<cstring>socksAddUserTxt</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
@ -506,6 +577,9 @@ Override</string>
<property name="text"> <property name="text">
<string>IP Address</string> <string>IP Address</string>
</property> </property>
<property name="buddy">
<cstring>dokoIPAddrTxt</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
@ -520,6 +594,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Port</string> <string>Port</string>
</property> </property>
<property name="buddy">
<cstring>dokoPortSB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
@ -540,6 +617,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Network</string> <string>Network</string>
</property> </property>
<property name="buddy">
<cstring>dokoTCPCB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
@ -571,6 +651,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Timeout</string> <string>Timeout</string>
</property> </property>
<property name="buddy">
<cstring>dokoTimeoutSB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="5" column="0">
@ -578,6 +661,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Follow Redirect</string> <string>Follow Redirect</string>
</property> </property>
<property name="buddy">
<cstring>dokoFollowRedirectCB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="6" column="0">
@ -585,6 +671,9 @@ Override</string>
<property name="text"> <property name="text">
<string>User Level</string> <string>User Level</string>
</property> </property>
<property name="buddy">
<cstring>dokoUserLevelSB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="4" column="1">
@ -603,7 +692,7 @@ Override</string>
<item row="5" column="1"> <item row="5" column="1">
<widget class="QCheckBox" name="dokoFollowRedirectCB"> <widget class="QCheckBox" name="dokoFollowRedirectCB">
<property name="text"> <property name="text">
<string>CheckBox</string> <string>Enabled</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -628,6 +717,9 @@ Override</string>
<property name="text"> <property name="text">
<string>EMail Address</string> <string>EMail Address</string>
</property> </property>
<property name="buddy">
<cstring>mtEMailTxt</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
@ -642,6 +734,9 @@ Override</string>
<property name="text"> <property name="text">
<string>Secret</string> <string>Secret</string>
</property> </property>
<property name="buddy">
<cstring>mtSecretTxt</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
@ -656,6 +751,9 @@ Override</string>
<property name="text"> <property name="text">
<string>User Level</string> <string>User Level</string>
</property> </property>
<property name="buddy">
<cstring>mtUserLevelSB</cstring>
</property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
@ -670,6 +768,44 @@ Override</string>
</item> </item>
</layout> </layout>
</widget> </widget>
<tabstops>
<tabstop>inboundTagTxt</tabstop>
<tabstop>inboundHostTxt</tabstop>
<tabstop>inboundPortTxt</tabstop>
<tabstop>inboundProtocolCombo</tabstop>
<tabstop>httpTimeoutSpinBox</tabstop>
<tabstop>httpTransparentCB</tabstop>
<tabstop>httpUserLevelSB</tabstop>
<tabstop>httpAccountListBox</tabstop>
<tabstop>httpRemoveUserBtn</tabstop>
<tabstop>httpAddUserTxt</tabstop>
<tabstop>httpAddPasswordTxt</tabstop>
<tabstop>httpAddUserBtn</tabstop>
<tabstop>socksAuthCombo</tabstop>
<tabstop>socksUDPCB</tabstop>
<tabstop>socksUDPIPAddrTxt</tabstop>
<tabstop>socksUserLevelSB</tabstop>
<tabstop>socksAccountListBox</tabstop>
<tabstop>socksRemoveUserBtn</tabstop>
<tabstop>socksAddUserTxt</tabstop>
<tabstop>socksAddPasswordTxt</tabstop>
<tabstop>socksAddUserBtn</tabstop>
<tabstop>dokoIPAddrTxt</tabstop>
<tabstop>dokoPortSB</tabstop>
<tabstop>dokoTCPCB</tabstop>
<tabstop>dokoUDPCB</tabstop>
<tabstop>dokoTimeoutSB</tabstop>
<tabstop>dokoFollowRedirectCB</tabstop>
<tabstop>dokoUserLevelSB</tabstop>
<tabstop>mtEMailTxt</tabstop>
<tabstop>mtSecretTxt</tabstop>
<tabstop>mtUserLevelSB</tabstop>
<tabstop>strategyCombo</tabstop>
<tabstop>refreshNumberBox</tabstop>
<tabstop>concurrencyNumberBox</tabstop>
<tabstop>enableSniffingCB</tabstop>
<tabstop>destOverrideList</tabstop>
</tabstops>
<resources> <resources>
<include location="../../resources.qrc"/> <include location="../../resources.qrc"/>
</resources> </resources>
@ -681,8 +817,8 @@ Override</string>
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>248</x> <x>841</x>
<y>254</y> <y>493</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>157</x> <x>157</x>
@ -697,8 +833,8 @@ Override</string>
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>316</x> <x>841</x>
<y>260</y> <y>493</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>286</x> <x>286</x>

View File

@ -9,7 +9,7 @@ JsonEditor::JsonEditor(QJsonObject rootObject, QWidget *parent) :
{ {
ui->setupUi(this); ui->setupUi(this);
original = rootObject; original = rootObject;
result = rootObject; final = rootObject;
QString jsonString = JsonToString(rootObject); QString jsonString = JsonToString(rootObject);
if (VerifyJsonString(&jsonString).isEmpty()) { if (VerifyJsonString(&jsonString).isEmpty()) {
@ -36,7 +36,7 @@ QJsonObject JsonEditor::OpenEditor()
string = ui->jsonEditor->toPlainText(); string = ui->jsonEditor->toPlainText();
} }
return resultCode == QDialog::Accepted ? result : original; return resultCode == QDialog::Accepted ? final : original;
} }
JsonEditor::~JsonEditor() JsonEditor::~JsonEditor()
@ -52,8 +52,8 @@ void JsonEditor::on_jsonEditor_textChanged()
if (VerifyResult.isEmpty()) { if (VerifyResult.isEmpty()) {
BLACK(jsonEditor) BLACK(jsonEditor)
result = JsonFromString(string); final = JsonFromString(string);
model.loadJson(QJsonDocument(result).toJson()); model.loadJson(QJsonDocument(final).toJson());
ui->jsonTree->expandAll(); ui->jsonTree->expandAll();
ui->jsonTree->resizeColumnToContents(0); ui->jsonTree->resizeColumnToContents(0);
} else { } else {

View File

@ -27,7 +27,7 @@ class JsonEditor : public QDialog
private: private:
QJsonModel model; QJsonModel model;
QJsonObject original; QJsonObject original;
QJsonObject result; QJsonObject final;
Ui::JsonEditor *ui; Ui::JsonEditor *ui;
}; };

View File

@ -538,20 +538,25 @@ void MainWindow::on_addConfigButton_clicked()
OutboundEditor *w = new OutboundEditor(this); OutboundEditor *w = new OutboundEditor(this);
connect(w, &OutboundEditor::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; bool isChanged = w->result() == QDialog::Accepted;
outboundsList.push_back(outboundEntry);
QJsonObject root;
root.insert("outbounds", outboundsList);
auto alias = w->Alias; auto alias = w->Alias;
delete w; delete w;
auto conf = GetGlobalConfig();
auto connectionList = conf.configs; if (isChanged) {
connectionList.push_back(alias.toStdString()); QJsonArray outboundsList;
conf.configs = connectionList; outboundsList.push_back(outboundEntry);
SetGlobalConfig(conf); QJsonObject root;
OnConfigListChanged(false); root.insert("outbounds", outboundsList);
SaveConnectionConfig(root, &alias); //
ShowAndSetConnection(CurrentConnectionName, false, false); auto conf = GetGlobalConfig();
auto connectionList = conf.configs;
connectionList.push_back(alias.toStdString());
conf.configs = connectionList;
SetGlobalConfig(conf);
OnConfigListChanged(false);
SaveConnectionConfig(root, &alias);
ShowAndSetConnection(CurrentConnectionName, false, false);
}
} }
void MainWindow::on_editConfigButton_clicked() void MainWindow::on_editConfigButton_clicked()
@ -565,24 +570,29 @@ void MainWindow::on_editConfigButton_clicked()
auto alias = ui->connectionListWidget->currentItem()->text(); auto alias = ui->connectionListWidget->currentItem()->text();
auto outBoundRoot = connections[alias]; auto outBoundRoot = connections[alias];
QJsonObject root; QJsonObject root;
bool isChanged = false;
if (outBoundRoot["outbounds"].toArray().count() > 1) { if (outBoundRoot["outbounds"].toArray().count() > 1) {
LOG(MODULE_UI, "INFO: Opening route editor.") LOG(MODULE_UI, "INFO: Opening route editor.")
RouteEditor *routeWindow = new RouteEditor(outBoundRoot, alias, this); RouteEditor *routeWindow = new RouteEditor(outBoundRoot, alias, this);
root = routeWindow->OpenEditor(); root = routeWindow->OpenEditor();
isChanged = routeWindow->result() == QDialog::Accepted;
} else { } else {
LOG(MODULE_UI, "INFO: Opening single connection edit window.") LOG(MODULE_UI, "INFO: Opening single connection edit window.")
OutboundEditor *w = new OutboundEditor(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();
isChanged = w->result() == QDialog::Accepted;
QJsonArray outboundsList; QJsonArray outboundsList;
outboundsList.push_back(outboundEntry); outboundsList.push_back(outboundEntry);
root.insert("outbounds", outboundsList); root.insert("outbounds", outboundsList);
} }
connections[alias] = root; if (isChanged) {
SaveConnectionConfig(root, &alias); connections[alias] = root;
OnConfigListChanged(alias == CurrentConnectionName); SaveConnectionConfig(root, &alias);
ShowAndSetConnection(CurrentConnectionName, false, false); OnConfigListChanged(alias == CurrentConnectionName);
ShowAndSetConnection(CurrentConnectionName, false, false);
}
} }
void MainWindow::on_reconnectButton_clicked() void MainWindow::on_reconnectButton_clicked()
@ -602,14 +612,19 @@ void MainWindow::on_action_RCM_EditJson_triggered()
auto alias = ui->connectionListWidget->currentItem()->text(); auto alias = ui->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;
delete w; delete w;
connections[alias] = root;
SaveConnectionConfig(root, &alias); if (isChanged) {
ShowAndSetConnection(CurrentConnectionName, false, false); connections[alias] = root;
SaveConnectionConfig(root, &alias);
ShowAndSetConnection(CurrentConnectionName, false, false);
}
} }
void MainWindow::on_editJsonBtn_clicked() void MainWindow::on_editJsonBtn_clicked()
{ {
// See above.
on_action_RCM_EditJson_triggered(); on_action_RCM_EditJson_triggered();
} }
@ -635,6 +650,12 @@ void MainWindow::on_speedTimer_Ticked()
foreach (auto inbound, inbounds) { foreach (auto inbound, inbounds) {
auto tag = inbound.toObject()["tag"].toString(); auto tag = inbound.toObject()["tag"].toString();
// TODO: A proper scheme...
if (tag == API_TAG_INBOUND) {
continue;
}
totalSpeedUp += vinstance->getTagLastUplink(tag); totalSpeedUp += vinstance->getTagLastUplink(tag);
totalSpeedDown += vinstance->getTagLastDownlink(tag); totalSpeedDown += vinstance->getTagLastDownlink(tag);
totalDataUp += vinstance->getTagTotalUplink(tag); totalDataUp += vinstance->getTagTotalUplink(tag);
@ -650,7 +671,6 @@ void MainWindow::on_speedTimer_Ticked()
ui->netspeedLabel->setText(speedUp + "/s\r\n" + speedDown + "/s"); ui->netspeedLabel->setText(speedUp + "/s\r\n" + speedDown + "/s");
ui->dataamountLabel->setText(dataUp + "\r\n" + dataDown); ui->dataamountLabel->setText(dataUp + "\r\n" + dataDown);
// //
hTray->setToolTip(TRAY_TOOLTIP_PREFIX "\r\n" + tr("Connected To Server: ") + CurrentConnectionName + "\r\n" hTray->setToolTip(TRAY_TOOLTIP_PREFIX "\r\n" + tr("Connected To Server: ") + CurrentConnectionName + "\r\nUp: " + speedUp + "/s Down: " + speedDown + "/s");
"Up: " + speedUp + "/s Down: " + speedDown + "/s");
} }

View File

@ -3,6 +3,7 @@
#include "ui_w_RoutesEditor.h" #include "ui_w_RoutesEditor.h"
#include "w_OutboundEditor.h" #include "w_OutboundEditor.h"
#include "w_JsonEditor.h" #include "w_JsonEditor.h"
#include "w_InboundEditor.h"
RouteEditor::RouteEditor(QJsonObject connection, const QString alias, QWidget *parent) : RouteEditor::RouteEditor(QJsonObject connection, const QString alias, QWidget *parent) :
QDialog(parent), QDialog(parent),
@ -15,6 +16,7 @@ RouteEditor::RouteEditor(QJsonObject connection, const QString alias, QWidget *p
routes = StructFromJsonString<RoutingObject>(JsonToString(root["routing"].toObject())); routes = StructFromJsonString<RoutingObject>(JsonToString(root["routing"].toObject()));
ui->setupUi(this); ui->setupUi(this);
ui->outboundsList->clear(); ui->outboundsList->clear();
ui->inboundsList->clear();
foreach (auto out, outbounds) { foreach (auto out, outbounds) {
bool hasTag = out.toObject().contains("tag"); bool hasTag = out.toObject().contains("tag");
@ -28,7 +30,7 @@ RouteEditor::RouteEditor(QJsonObject connection, const QString alias, QWidget *p
foreach (auto in, inbounds) { foreach (auto in, inbounds) {
bool hasTag = in.toObject().contains("tag"); bool hasTag = in.toObject().contains("tag");
// //
auto tag = hasTag ? in.toObject()["tag"].toString() : tr("NoTag"); auto tag = hasTag ? in.toObject()["tag"].toString() : tr("NoTag");
auto protocol = in.toObject()["protocol"].toString(); auto protocol = in.toObject()["protocol"].toString();
auto port = in.toObject()["port"].toVariant().toString(); auto port = in.toObject()["port"].toVariant().toString();
// //
@ -55,6 +57,9 @@ RouteEditor::RouteEditor(QJsonObject connection, const QString alias, QWidget *p
QJsonObject RouteEditor::OpenEditor() QJsonObject RouteEditor::OpenEditor()
{ {
this->exec(); this->exec();
root["inbounds"] = inbounds;
root["outbounds"] = outbounds;
root["routing"] = GetRootObject(routes);
return root; return root;
} }
@ -146,8 +151,8 @@ void RouteEditor::on_editOutboundBtn_clicked()
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.") + "\r\n" +
QvMessageBox(this, tr("Cannot Edit"), tr("We will launch Json Editor instead.")); tr("We will launch Json Editor instead."));
JsonEditor *w = new JsonEditor(currentOutbound, this); JsonEditor *w = new JsonEditor(currentOutbound, this);
result = w->OpenEditor(); result = w->OpenEditor();
delete w; delete w;
@ -168,4 +173,23 @@ void RouteEditor::on_insertDirectBtn_clicked()
void RouteEditor::on_editInboundBtn_clicked() void RouteEditor::on_editInboundBtn_clicked()
{ {
QJsonObject result;
int row = ui->inboundsList->currentRow();
auto currentInbound = inbounds[row].toObject();
auto protocol = currentInbound["protocol"].toString();
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."));
JsonEditor *w = new JsonEditor(currentInbound, this);
result = w->OpenEditor();
delete w;
} else {
InboundEditor *w = new InboundEditor(currentInbound, this);
result = w->OpenEditor();
delete w;
}
inbounds[row] = result;
on_inboundsList_currentRowChanged(row);
} }

View File

@ -6,134 +6,29 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>889</width> <width>950</width>
<height>560</height> <height>560</height>
</rect> </rect>
</property> </property>
<property name="minimumSize">
<size>
<width>950</width>
<height>560</height>
</size>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Dialog</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0"> <layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0">
<item row="0" column="1"> <item row="2" column="2">
<layout class="QVBoxLayout" name="routesLayout" stretch="0,1,0,1"> <widget class="QDialogButtonBox" name="buttonBox">
<item> <property name="orientation">
<widget class="QLabel" name="label_4"> <enum>Qt::Horizontal</enum>
<property name="text"> </property>
<string>Routes List</string> <property name="standardButtons">
</property> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</widget> </property>
</item> </widget>
<item>
<widget class="QTableWidget" name="routesTable">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<column>
<property name="text">
<string>InBounds</string>
</property>
</column>
<column>
<property name="text">
<string>DomainOrIP</string>
</property>
</column>
<column>
<property name="text">
<string>Outbound</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="routesControlButtons">
<item>
<spacer name="horizontalSpacer_4">
<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="QToolButton" name="addRouteBtn">
<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>
<widget class="QToolButton" name="delRouteBtn">
<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>
<widget class="QPushButton" name="changeIOBtn">
<property name="text">
<string>Change IO</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Route Information</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Domains</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>IPs</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item> </item>
<item row="0" column="0"> <item row="0" column="0">
<layout class="QVBoxLayout" name="inboundLayout" stretch="0,1,0,1"> <layout class="QVBoxLayout" name="inboundLayout" stretch="0,1,0,1">
@ -437,15 +332,131 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="2"> <item row="0" column="1">
<widget class="QDialogButtonBox" name="buttonBox"> <layout class="QVBoxLayout" name="routesLayout" stretch="0,1,0,1">
<property name="orientation"> <item>
<enum>Qt::Horizontal</enum> <widget class="QLabel" name="label_4">
</property> <property name="text">
<property name="standardButtons"> <string>Routes List</string>
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> </property>
</property> </widget>
</widget> </item>
<item>
<widget class="QTableWidget" name="routesTable">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<column>
<property name="text">
<string>Enabled</string>
</property>
</column>
<column>
<property name="text">
<string>InBounds</string>
</property>
</column>
<column>
<property name="text">
<string>DomainOrIP</string>
</property>
</column>
<column>
<property name="text">
<string>Outbound</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="routesControlButtons">
<item>
<spacer name="horizontalSpacer_4">
<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="QToolButton" name="addRouteBtn">
<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>
<widget class="QToolButton" name="delRouteBtn">
<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>
<widget class="QPushButton" name="changeIOBtn">
<property name="text">
<string>Change IO</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Route Information</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Domains</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>IPs</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item> </item>
<item row="2" column="0" colspan="2"> <item row="2" column="0" colspan="2">
<widget class="QLabel" name="statusLabel"> <widget class="QLabel" name="statusLabel">

View File

@ -120,266 +120,274 @@
<context> <context>
<name>InboundEditor</name> <name>InboundEditor</name>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="14"/> <location filename="../src/ui/w_InboundEditor.ui" line="17"/>
<source>Inbound Editor</source> <source>Inbound Editor</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="25"/> <location filename="../src/ui/w_InboundEditor.ui" line="28"/>
<source>Tag</source> <source>Tag</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="32"/> <location filename="../src/ui/w_InboundEditor.ui" line="38"/>
<source>Tag of this inbound entry</source> <source>Tag of this inbound entry</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="39"/> <location filename="../src/ui/w_InboundEditor.ui" line="45"/>
<source>Listening</source> <source>Listening</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="48"/> <location filename="../src/ui/w_InboundEditor.ui" line="54"/>
<source>Hostname or IP Address</source> <source>Hostname or IP Address</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="55"/> <location filename="../src/ui/w_InboundEditor.ui" line="61"/>
<source>:</source> <source>:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="62"/> <location filename="../src/ui/w_InboundEditor.ui" line="77"/>
<source>Port: 1080|env:PORT|80-85</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="71"/>
<source>Protocol</source> <source>Protocol</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="85"/> <location filename="../src/ui/w_InboundEditor.ui" line="119"/>
<source>HTTP</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="90"/>
<source>SOCKS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="95"/>
<source>Dokodemo</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="100"/>
<source>MTProto</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="110"/>
<source>Allocation Settings</source> <source>Allocation Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="116"/> <location filename="../src/ui/w_InboundEditor.ui" line="125"/>
<source>Strategy</source> <source>Strategy</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="130"/> <location filename="../src/ui/w_InboundEditor.ui" line="155"/>
<source>Always</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="135"/>
<source>Random</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="143"/>
<source>Refresh</source> <source>Refresh</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="166"/> <location filename="../src/ui/w_InboundEditor.ui" line="181"/>
<source>Concurrency</source> <source>Concurrency</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="192"/> <location filename="../src/ui/w_InboundEditor.ui" line="210"/>
<source>Sniffing Settings</source> <source>Sniffing Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="198"/> <location filename="../src/ui/w_InboundEditor.ui" line="68"/>
<source>Destination <source>Port: 1080|80-85</source>
Override</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="226"/> <location filename="../src/ui/w_InboundEditor.ui" line="142"/>
<location filename="../src/ui/w_InboundEditor.ui" line="233"/> <source>always</source>
<location filename="../src/ui/w_InboundEditor.ui" line="285"/> <translation type="unfinished"></translation>
<location filename="../src/ui/w_InboundEditor.ui" line="418"/> </message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="147"/>
<source>random</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="228"/>
<source>Destination Override</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="267"/>
<location filename="../src/ui/w_InboundEditor.ui" line="274"/>
<location filename="../src/ui/w_InboundEditor.ui" line="335"/>
<location filename="../src/ui/w_InboundEditor.ui" line="486"/>
<location filename="../src/ui/w_InboundEditor.ui" line="695"/>
<source>Enabled</source> <source>Enabled</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="260"/> <location filename="../src/ui/w_InboundEditor.ui" line="304"/>
<source>HTTP Inbound Settings</source> <source>HTTP Inbound Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="268"/> <location filename="../src/ui/w_InboundEditor.ui" line="312"/>
<location filename="../src/ui/w_InboundEditor.ui" line="572"/> <location filename="../src/ui/w_InboundEditor.ui" line="652"/>
<source>Timeout</source> <source>Timeout</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="278"/> <location filename="../src/ui/w_InboundEditor.ui" line="325"/>
<source>Allow Transparent</source> <source>Allow Transparent</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="292"/> <location filename="../src/ui/w_InboundEditor.ui" line="342"/>
<location filename="../src/ui/w_InboundEditor.ui" line="411"/> <location filename="../src/ui/w_InboundEditor.ui" line="476"/>
<location filename="../src/ui/w_InboundEditor.ui" line="586"/> <location filename="../src/ui/w_InboundEditor.ui" line="672"/>
<location filename="../src/ui/w_InboundEditor.ui" line="657"/> <location filename="../src/ui/w_InboundEditor.ui" line="752"/>
<source>User Level</source> <source>User Level</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="306"/> <location filename="../src/ui/w_InboundEditor.ui" line="359"/>
<location filename="../src/ui/w_InboundEditor.ui" line="327"/> <location filename="../src/ui/w_InboundEditor.ui" line="380"/>
<location filename="../src/ui/w_InboundEditor.ui" line="439"/> <location filename="../src/ui/w_InboundEditor.ui" line="507"/>
<location filename="../src/ui/w_InboundEditor.ui" line="460"/> <location filename="../src/ui/w_InboundEditor.ui" line="528"/>
<source>...</source> <source>...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="320"/> <location filename="../src/ui/w_InboundEditor.ui" line="373"/>
<location filename="../src/ui/w_InboundEditor.ui" line="389"/> <location filename="../src/ui/w_InboundEditor.ui" line="521"/>
<location filename="../src/ui/w_InboundEditor.ui" line="453"/>
<source>Password</source> <source>Password</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="338"/> <location filename="../src/ui/w_InboundEditor.ui" line="391"/>
<location filename="../src/ui/w_InboundEditor.ui" line="471"/> <location filename="../src/ui/w_InboundEditor.ui" line="539"/>
<source>Add</source> <source>Add</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="345"/> <location filename="../src/ui/w_InboundEditor.ui" line="401"/>
<location filename="../src/ui/w_InboundEditor.ui" line="478"/> <location filename="../src/ui/w_InboundEditor.ui" line="549"/>
<source>Username</source> <source>Username</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="352"/> <location filename="../src/ui/w_InboundEditor.ui" line="408"/>
<location filename="../src/ui/w_InboundEditor.ui" line="485"/> <location filename="../src/ui/w_InboundEditor.ui" line="556"/>
<source>Accounts</source> <source>Accounts</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="368"/> <location filename="../src/ui/w_InboundEditor.ui" line="424"/>
<source>SOCKS Inbound Settings</source> <source>SOCKS Inbound Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="376"/> <location filename="../src/ui/w_InboundEditor.ui" line="432"/>
<source>Auth</source> <source>Auth</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="384"/> <location filename="../src/ui/w_InboundEditor.ui" line="456"/>
<source>No Auth</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="397"/>
<source>Enable UDP</source> <source>Enable UDP</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="404"/> <location filename="../src/ui/w_InboundEditor.ui" line="466"/>
<source>Local UDP IP</source> <source>Local UDP IP</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="425"/> <location filename="../src/ui/w_InboundEditor.ui" line="493"/>
<source>127.0.0.1</source> <source>127.0.0.1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="501"/> <location filename="../src/ui/w_InboundEditor.ui" line="572"/>
<source>Dokodemo-Door Inbound Settings</source> <source>Dokodemo-Door Inbound Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="507"/> <location filename="../src/ui/w_InboundEditor.ui" line="578"/>
<source>IP Address</source> <source>IP Address</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="514"/> <location filename="../src/ui/w_InboundEditor.ui" line="588"/>
<source>Not necessary when setting &quot;Follow Redirect&quot;</source> <source>Not necessary when setting &quot;Follow Redirect&quot;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="521"/> <location filename="../src/ui/w_InboundEditor.ui" line="595"/>
<source>Port</source> <source>Port</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="541"/> <location filename="../src/ui/w_InboundEditor.ui" line="618"/>
<source>Network</source> <source>Network</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="550"/> <location filename="../src/ui/w_InboundEditor.ui" line="630"/>
<source>TCP</source> <source>TCP</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="563"/> <location filename="../src/ui/w_InboundEditor.ui" line="643"/>
<source>UDP</source> <source>UDP</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="579"/> <location filename="../src/ui/w_InboundEditor.ui" line="662"/>
<source>Follow Redirect</source> <source>Follow Redirect</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="606"/> <location filename="../src/ui/w_InboundEditor.ui" line="712"/>
<source>CheckBox</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.ui" line="623"/>
<source>MTProto Inbound Settings</source> <source>MTProto Inbound Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="629"/> <location filename="../src/ui/w_InboundEditor.ui" line="718"/>
<source>EMail Address</source> <source>EMail Address</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="643"/> <location filename="../src/ui/w_InboundEditor.ui" line="735"/>
<source>Secret</source> <source>Secret</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_InboundEditor.ui" line="650"/> <location filename="../src/ui/w_InboundEditor.ui" line="745"/>
<source>SECRET</source> <source>SECRET</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../src/ui/w_InboundEditor.cpp" line="29"/>
<source>Inbound type not supported</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.cpp" line="29"/>
<source>The inbound type is not supported by Qv2ray (yet). Please use JsonEditor to change the settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.cpp" line="30"/>
<source>Inbound: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.cpp" line="175"/>
<location filename="../src/ui/w_InboundEditor.cpp" line="280"/>
<source>Removing a user</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.cpp" line="175"/>
<location filename="../src/ui/w_InboundEditor.cpp" line="280"/>
<source>You haven&apos;t selected a user yet,</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.cpp" line="191"/>
<location filename="../src/ui/w_InboundEditor.cpp" line="296"/>
<source>Add a user</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_InboundEditor.cpp" line="191"/>
<location filename="../src/ui/w_InboundEditor.cpp" line="296"/>
<source>This user exists already.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>JsonEditor</name> <name>JsonEditor</name>
@ -434,172 +442,204 @@ Override</source>
<context> <context>
<name>MainWindow</name> <name>MainWindow</name>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="23"/> <location filename="../src/ui/w_MainWindow.ui" line="29"/>
<source>Qv2ray</source> <source>Qv2ray</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="184"/> <location filename="../src/ui/w_MainWindow.ui" line="127"/>
<source>Share</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="136"/>
<source>QR Code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="143"/>
<source>VMess</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="179"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="217"/>
<source>Instant</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="254"/>
<source>0.00 KB/s
0.00 KB/s</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="291"/>
<source>Total</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="328"/>
<source>0.00 KB
0.00 KB</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="513"/>
<location filename="../src/ui/w_MainWindow.cpp" line="45"/> <location filename="../src/ui/w_MainWindow.cpp" line="45"/>
<source>Connect</source> <source>Connect</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="194"/> <location filename="../src/ui/w_MainWindow.ui" line="523"/>
<location filename="../src/ui/w_MainWindow.cpp" line="47"/> <location filename="../src/ui/w_MainWindow.cpp" line="47"/>
<source>Disconnect</source> <source>Disconnect</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="201"/> <location filename="../src/ui/w_MainWindow.ui" line="530"/>
<location filename="../src/ui/w_MainWindow.cpp" line="46"/> <location filename="../src/ui/w_MainWindow.cpp" line="46"/>
<source>Reconnect</source> <source>Reconnect</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="208"/> <location filename="../src/ui/w_MainWindow.ui" line="537"/>
<source>Clear Log</source> <source>Clear Log</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="215"/> <location filename="../src/ui/w_MainWindow.ui" line="544"/>
<source>Prefrences</source> <source>Prefrences</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="238"/> <location filename="../src/ui/w_MainWindow.ui" line="567"/>
<source>Stopped</source> <source>Stopped</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="384"/> <location filename="../src/ui/w_MainWindow.ui" line="355"/>
<source>Host List</source> <source>Host List</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="247"/> <location filename="../src/ui/w_MainWindow.ui" line="72"/>
<source>Config Details</source> <source>Config Details</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="253"/> <location filename="../src/ui/w_MainWindow.ui" line="78"/>
<source>Type</source> <source>Type</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="267"/> <location filename="../src/ui/w_MainWindow.ui" line="92"/>
<source>Host</source> <source>Host</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="281"/> <location filename="../src/ui/w_MainWindow.ui" line="106"/>
<source>Port</source> <source>Port</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="295"/> <location filename="../src/ui/w_MainWindow.ui" line="120"/>
<source>Detail</source> <source>Detail</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="338"/> <location filename="../src/ui/w_MainWindow.ui" line="188"/>
<source>Ping</source> <source>Ping</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="345"/> <location filename="../src/ui/w_MainWindow.ui" line="150"/>
<source>QR</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="352"/>
<source>://</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.ui" line="359"/>
<source>Json</source> <source>Json</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="110"/> <location filename="../src/ui/w_MainWindow.ui" line="423"/>
<source>#AddConnection</source> <source>#AddConnection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="113"/> <location filename="../src/ui/w_MainWindow.ui" line="426"/>
<source>A</source> <source>A</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="130"/> <location filename="../src/ui/w_MainWindow.ui" line="443"/>
<location filename="../src/ui/w_MainWindow.ui" line="442"/> <location filename="../src/ui/w_MainWindow.ui" line="582"/>
<source>#ImportConnection</source> <source>#ImportConnection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="133"/> <location filename="../src/ui/w_MainWindow.ui" line="446"/>
<source>I</source> <source>I</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="324"/> <location filename="../src/ui/w_MainWindow.ui" line="477"/>
<source>#EditConnection</source> <source>#EditConnection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="327"/> <location filename="../src/ui/w_MainWindow.ui" line="480"/>
<source>...</source> <source>...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="150"/> <location filename="../src/ui/w_MainWindow.ui" line="463"/>
<source>#RemoveConnection</source> <source>#RemoveConnection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="153"/> <location filename="../src/ui/w_MainWindow.ui" line="466"/>
<source>R</source> <source>R</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="42"/> <location filename="../src/ui/w_MainWindow.ui" line="50"/>
<source>Log</source> <source>Log</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="437"/> <location filename="../src/ui/w_MainWindow.ui" line="577"/>
<source>#ManuallyCreateConnection</source> <source>#ManuallyCreateConnection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="447"/> <location filename="../src/ui/w_MainWindow.ui" line="587"/>
<source>#Exit</source> <source>#Exit</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="452"/> <location filename="../src/ui/w_MainWindow.ui" line="592"/>
<source>#Preferences</source> <source>#Preferences</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="457"/> <location filename="../src/ui/w_MainWindow.ui" line="597"/>
<source>#Start</source> <source>#Start</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="462"/> <location filename="../src/ui/w_MainWindow.ui" line="602"/>
<source>#Stop</source> <source>#Stop</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.ui" line="467"/> <location filename="../src/ui/w_MainWindow.ui" line="607"/>
<source>#Restart</source> <source>#Restart</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="43"/> <location filename="../src/ui/w_MainWindow.cpp" line="43"/>
<location filename="../src/ui/w_MainWindow.cpp" line="320"/> <location filename="../src/ui/w_MainWindow.cpp" line="318"/>
<source>Hide</source> <source>Hide</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -625,8 +665,8 @@ Override</source>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="109"/> <location filename="../src/ui/w_MainWindow.cpp" line="109"/>
<location filename="../src/ui/w_MainWindow.cpp" line="275"/> <location filename="../src/ui/w_MainWindow.cpp" line="273"/>
<location filename="../src/ui/w_MainWindow.cpp" line="323"/> <location filename="../src/ui/w_MainWindow.cpp" line="321"/>
<source>Show</source> <source>Show</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -670,7 +710,7 @@ Override</source>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="231"/> <location filename="../src/ui/w_MainWindow.cpp" line="231"/>
<location filename="../src/ui/w_MainWindow.cpp" line="232"/> <location filename="../src/ui/w_MainWindow.cpp" line="232"/>
<location filename="../src/ui/w_MainWindow.cpp" line="653"/> <location filename="../src/ui/w_MainWindow.cpp" line="674"/>
<source>Connected To Server: </source> <source>Connected To Server: </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -685,65 +725,71 @@ Override</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="363"/> <location filename="../src/ui/w_MainWindow.cpp" line="361"/>
<source>UUID</source> <source>UUID</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="365"/> <location filename="../src/ui/w_MainWindow.cpp" line="363"/>
<source>AlterID</source> <source>AlterID</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="367"/> <location filename="../src/ui/w_MainWindow.cpp" line="365"/>
<source>Transport</source> <source>Transport</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="374"/> <location filename="../src/ui/w_MainWindow.cpp" line="372"/>
<source>Email</source> <source>Email</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="376"/> <location filename="../src/ui/w_MainWindow.cpp" line="374"/>
<source>Encryption</source> <source>Encryption</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="383"/> <location filename="../src/ui/w_MainWindow.cpp" line="381"/>
<source>Username</source> <source>Username</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="469"/> <location filename="../src/ui/w_MainWindow.cpp" line="467"/>
<location filename="../src/ui/w_MainWindow.cpp" line="478"/> <location filename="../src/ui/w_MainWindow.cpp" line="476"/>
<source>Rename a Connection</source> <source>Rename a Connection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="469"/> <location filename="../src/ui/w_MainWindow.cpp" line="467"/>
<source>The name cannot be empty</source> <source>The name cannot be empty</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="505"/> <location filename="../src/ui/w_MainWindow.cpp" line="505"/>
<location filename="../src/ui/w_MainWindow.cpp" line="519"/>
<source>Removing this Connection</source> <source>Removing this Connection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="559"/> <location filename="../src/ui/w_MainWindow.cpp" line="519"/>
<location filename="../src/ui/w_MainWindow.cpp" line="596"/> <source>Failed to delete connection file, please delete manually.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_MainWindow.cpp" line="566"/>
<location filename="../src/ui/w_MainWindow.cpp" line="608"/>
<source>No Config Selected</source> <source>No Config Selected</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="559"/> <location filename="../src/ui/w_MainWindow.cpp" line="566"/>
<location filename="../src/ui/w_MainWindow.cpp" line="596"/> <location filename="../src/ui/w_MainWindow.cpp" line="608"/>
<source>Please Select a Config</source> <source>Please Select a Config</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_MainWindow.cpp" line="478"/> <location filename="../src/ui/w_MainWindow.cpp" line="476"/>
<source>The name has been used already, Please choose another.</source> <source>The name has been used already, Please choose another.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1275,27 +1321,42 @@ Override</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/main.cpp" line="154"/> <location filename="../src/main.cpp" line="150"/>
<source>DependencyMissing</source> <source>DependencyMissing</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/main.cpp" line="155"/> <location filename="../src/main.cpp" line="151"/>
<source>Cannot find openssl libs</source> <source>Cannot find openssl libs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/main.cpp" line="156"/> <location filename="../src/main.cpp" line="152"/>
<source>This could be caused by a missing of `openssl` package in your system. Or an AppImage issue.</source> <source>This could be caused by a missing of `openssl` package in your system. Or an AppImage issue.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/main.cpp" line="157"/> <location filename="../src/main.cpp" line="153"/>
<source>If you are using AppImage, please report a bug.</source> <source>If you are using AppImage, please report a bug.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/main.cpp" line="163"/> <location filename="../src/main.cpp" line="154"/>
<source>Please refer to Github Issue #65 to check for solutions.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/main.cpp" line="155"/>
<source>Github Issue Link: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/main.cpp" line="156"/>
<source>Technical Details</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/main.cpp" line="164"/>
<source>Another instance of Qv2ray is already running.</source> <source>Another instance of Qv2ray is already running.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1318,150 +1379,157 @@ Override</source>
<context> <context>
<name>RouteEditor</name> <name>RouteEditor</name>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="14"/> <location filename="../src/ui/w_RoutesEditor.ui" line="20"/>
<source>Dialog</source> <source>Dialog</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="22"/> <location filename="../src/ui/w_RoutesEditor.ui" line="340"/>
<source>Routes List</source> <source>Routes List</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="39"/> <location filename="../src/ui/w_RoutesEditor.ui" line="357"/>
<source>Enabled</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/ui/w_RoutesEditor.ui" line="362"/>
<source>InBounds</source> <source>InBounds</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="44"/> <location filename="../src/ui/w_RoutesEditor.ui" line="367"/>
<source>DomainOrIP</source> <source>DomainOrIP</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="49"/> <location filename="../src/ui/w_RoutesEditor.ui" line="372"/>
<source>Outbound</source> <source>Outbound</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="72"/> <location filename="../src/ui/w_RoutesEditor.ui" line="50"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="83"/> <location filename="../src/ui/w_RoutesEditor.ui" line="61"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="155"/> <location filename="../src/ui/w_RoutesEditor.ui" line="203"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="166"/> <location filename="../src/ui/w_RoutesEditor.ui" line="214"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="308"/> <location filename="../src/ui/w_RoutesEditor.ui" line="395"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="319"/> <location filename="../src/ui/w_RoutesEditor.ui" line="406"/>
<source>...</source> <source>...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="94"/> <location filename="../src/ui/w_RoutesEditor.ui" line="417"/>
<source>Change IO</source> <source>Change IO</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="116"/> <location filename="../src/ui/w_RoutesEditor.ui" line="439"/>
<source>Route Information</source> <source>Route Information</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="122"/> <location filename="../src/ui/w_RoutesEditor.ui" line="445"/>
<source>Domains</source> <source>Domains</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="129"/> <location filename="../src/ui/w_RoutesEditor.ui" line="452"/>
<source>IPs</source> <source>IPs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="143"/> <location filename="../src/ui/w_RoutesEditor.ui" line="38"/>
<source>Inbound List</source> <source>Inbound List</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="177"/> <location filename="../src/ui/w_RoutesEditor.ui" line="72"/>
<source>Add Default</source> <source>Add Default</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="186"/> <location filename="../src/ui/w_RoutesEditor.ui" line="81"/>
<source>Inbound Information</source> <source>Inbound Information</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="192"/> <location filename="../src/ui/w_RoutesEditor.ui" line="87"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="382"/> <location filename="../src/ui/w_RoutesEditor.ui" line="277"/>
<source>Tag</source> <source>Tag</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="206"/> <location filename="../src/ui/w_RoutesEditor.ui" line="101"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="396"/> <location filename="../src/ui/w_RoutesEditor.ui" line="291"/>
<source>Type</source> <source>Type</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="220"/> <location filename="../src/ui/w_RoutesEditor.ui" line="115"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="410"/> <location filename="../src/ui/w_RoutesEditor.ui" line="305"/>
<source>Address</source> <source>Address</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="227"/> <location filename="../src/ui/w_RoutesEditor.ui" line="122"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="424"/> <location filename="../src/ui/w_RoutesEditor.ui" line="319"/>
<source>Port</source> <source>Port</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="292"/> <location filename="../src/ui/w_RoutesEditor.ui" line="187"/>
<source>Outbound List</source> <source>Outbound List</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="330"/> <location filename="../src/ui/w_RoutesEditor.ui" line="225"/>
<source>Add &quot;Direct&quot;</source> <source>Add &quot;Direct&quot;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="339"/> <location filename="../src/ui/w_RoutesEditor.ui" line="234"/>
<source>Outbound Information</source> <source>Outbound Information</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="263"/> <location filename="../src/ui/w_RoutesEditor.ui" line="158"/>
<location filename="../src/ui/w_RoutesEditor.ui" line="360"/> <location filename="../src/ui/w_RoutesEditor.ui" line="255"/>
<source>Edit</source> <source>Edit</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.ui" line="453"/> <location filename="../src/ui/w_RoutesEditor.ui" line="464"/>
<source>Status</source> <source>Status</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.cpp" line="23"/> <location filename="../src/ui/w_RoutesEditor.cpp" line="25"/>
<location filename="../src/ui/w_RoutesEditor.cpp" line="31"/> <location filename="../src/ui/w_RoutesEditor.cpp" line="33"/>
<location filename="../src/ui/w_RoutesEditor.cpp" line="76"/> <location filename="../src/ui/w_RoutesEditor.cpp" line="81"/>
<source>NoTag</source> <source>NoTag</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.cpp" line="106"/> <location filename="../src/ui/w_RoutesEditor.cpp" line="111"/>
<source>#NoTag</source> <source>#NoTag</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.cpp" line="149"/> <location filename="../src/ui/w_RoutesEditor.cpp" line="154"/>
<location filename="../src/ui/w_RoutesEditor.cpp" line="150"/> <location filename="../src/ui/w_RoutesEditor.cpp" line="182"/>
<source>Cannot Edit</source> <source>Cannot Edit</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.cpp" line="149"/> <location filename="../src/ui/w_RoutesEditor.cpp" line="154"/>
<location filename="../src/ui/w_RoutesEditor.cpp" line="182"/>
<source>Currently, this type of outbound is not supported by the editor.</source> <source>Currently, this type of outbound is not supported by the editor.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/ui/w_RoutesEditor.cpp" line="150"/> <location filename="../src/ui/w_RoutesEditor.cpp" line="155"/>
<location filename="../src/ui/w_RoutesEditor.cpp" line="183"/>
<source>We will launch Json Editor instead.</source> <source>We will launch Json Editor instead.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>