[add] Partly added routing edit 2

Former-commit-id: 736e3ac9cc
This commit is contained in:
Leroy.H.Y 2019-10-29 17:07:20 +08:00
parent d8d4f9dbf3
commit dbbd42b2f3
11 changed files with 778 additions and 465 deletions

View File

@ -1 +1 @@
106
146

View File

@ -61,8 +61,8 @@ namespace Qv2ray
//
//
struct RuleObject {
// Added due to @aliyuchang33
bool enabled;
// Added due to the request of @aliyuchang33
bool QV2RAY_RULE_ENABLED;
//
string type;
list<string> domain;
@ -76,8 +76,8 @@ namespace Qv2ray
string attrs;
string outboundTag;
string balancerTag;
RuleObject() : enabled(true), type("field"), domain(), ip(), port(), network(), source(), user(), inboundTag(), protocol(), attrs(), outboundTag(), balancerTag() {}
XTOSTRUCT(O(enabled, type, domain, ip, port, network, source, user, inboundTag, protocol, attrs, outboundTag, balancerTag))
RuleObject() : QV2RAY_RULE_ENABLED(true), type("field"), domain(), ip(), port(""), network(""), source(), user(), inboundTag(), protocol(), attrs(), outboundTag(""), balancerTag("") {}
XTOSTRUCT(O(QV2RAY_RULE_ENABLED, type, domain, ip, port, network, source, user, inboundTag, protocol, attrs, outboundTag, balancerTag))
};
//
//

View File

@ -43,6 +43,7 @@ namespace Qv2ray
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(json.toStdString()));
return doc.object();
}
template QJsonObject GetRootObject<RuleObject>(RuleObject t);
template QJsonObject GetRootObject<StreamSettingsObject>(StreamSettingsObject t);
template QJsonObject GetRootObject<VMessServerObject>(VMessServerObject t);
//

View File

@ -246,8 +246,24 @@ namespace Qv2ray
} else {
// For some config files that has routing entries already.
// We don't add extra routings.
// this part has been left blanking
LOG(MODULE_CONNECTION, "Skip adding 'freedom' entry.")
//
// HOWEVER, we need to verify the QV2RAY_RULE_ENABLED entry.
QJsonObject routing = root["routing"].toObject();
QJsonArray rules;
LOG(MODULE_CONNECTION, "Processing an existing routing table.")
for (auto _a : routing["rules"].toArray()) {
auto _b = _a.toObject();
if (_b.contains("QV2RAY_RULE_ENABLED") && _b["QV2RAY_RULE_ENABLED"].toBool() == true) {
rules.append(_b);
} else {
LOG(MODULE_CONFIG, "Discarded a rule as it's been set DISABLED")
}
}
routing["rules"] = rules;
root["routing"] = routing;
}
// Let's process some api features.

View File

@ -15,6 +15,20 @@ namespace Qv2ray
StringToFile(&str, &config);
}
const QString GenerateRandomString(int len)
{
const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
QString randomString;
for (int i = 0; i < len; ++i) {
int index = qrand() % possibleCharacters.length();
QChar nextChar = possibleCharacters.at(index);
randomString.append(nextChar);
}
return randomString;
}
Qv2rayConfig GetGlobalConfig()
{
return GlobalConfig;
@ -138,6 +152,21 @@ namespace Qv2ray
return QString(QByteArray::fromBase64(ba));
}
QStringList SplitLines(const QString &_string)
{
return _string.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
}
QList<string> SplitLinesStdString(const QString &_string)
{
QList<string> list;
for (auto line : _string.split(QRegExp("[\r\n]"), QString::SkipEmptyParts)) {
list.append(line.toStdString());
}
return list;
}
void LoadGlobalConfig()
{
QFile file(QV2RAY_CONFIG_FILE);

View File

@ -15,9 +15,13 @@ namespace Qv2ray
QString Base64Encode(QString string);
QString Base64Decode(QString string);
QStringList SplitLines(const QString &str);
QList<string> SplitLinesStdString(const QString &_string);
bool CheckFile(QDir dir, QString fileName);
const QString GenerateRandomString(int len = 12);
void SetConfigDirPath(const QString *path);
QString GetConfigDirPath();

View File

@ -8,9 +8,10 @@ static bool isLoading = false;
InboundEditor::InboundEditor(QJsonObject root, QWidget *parent) :
QDialog(parent),
ui(new Ui::InboundEditor)
ui(new Ui::InboundEditor),
original(root)
{
original = root;
ui->setupUi(this);
this->root = root;
auto inboundType = root["protocol"].toString();
allocate = root["allocate"].toObject();
@ -30,7 +31,6 @@ InboundEditor::InboundEditor(QJsonObject root, QWidget *parent) :
tr("Inbound: ") + inboundType);
}
ui->setupUi(this);
LoadUIData();
}
@ -67,8 +67,10 @@ void InboundEditor::LoadUIData()
ui->refreshNumberBox->setValue(allocate["refresh"].toInt());
ui->concurrencyNumberBox->setValue(allocate["concurrency"].toInt());
ui->enableSniffingCB->setChecked(sniffing["enabled"].toBool());
//
ui->destOverrideList->setEnabled(sniffing["enabled"].toBool());
foreach (auto item, sniffing["destOverride"].toArray()) {
for (auto item : sniffing["destOverride"].toArray()) {
if (item.toString().toLower() == "http") ui->destOverrideList->item(0)->setCheckState(Qt::Checked);
if (item.toString().toLower() == "tls") ui->destOverrideList->item(1)->setCheckState(Qt::Checked);
@ -281,6 +283,7 @@ void InboundEditor::on_enableSniffingCB_stateChanged(int arg1)
{
PREPARE_RETURN
sniffing["enabled"] = arg1 == Qt::Checked;
ui->destOverrideList->setEnabled(arg1 == Qt::Checked);
}
void InboundEditor::on_destOverrideList_itemChanged(QListWidgetItem *item)
@ -292,7 +295,7 @@ void InboundEditor::on_destOverrideList_itemChanged(QListWidgetItem *item)
for (int i = 0; i < ui->destOverrideList->count(); i++) {
auto _item = ui->destOverrideList->item(i);
if (item->checkState() == Qt::Checked) {
if (_item->checkState() == Qt::Checked) {
list.append(_item->text().toLower());
}
}

View File

@ -491,7 +491,6 @@ void PrefrencesWindow::on_nsBarLineAddBTN_clicked()
ui->nsBarLineDelBTN->setEnabled(true);
LOG(MODULE_UI, "Adding new line Id: " + to_string(CurrentBarLineId))
ui->nsBarLinesList->setCurrentRow(static_cast<int>(CurrentBarPage.Lines.size() - 1));
// TODO Some UI Works such as enabling ui.
}
void PrefrencesWindow::on_nsBarLineDelBTN_clicked()
@ -608,14 +607,12 @@ QString PrefrencesWindow::GetBarLineDescription(QvBarLine line)
QString result = "Empty";
result = NetSpeedPluginMessages[line.ContentType];
// BUG Content type is null, then set empty;
if (line.ContentType == 0) {
result += " (" + QSTRING(line.Message) + ")";
}
result = result.append(line.Bold ? ", " + tr("Bold") : "");
result = result.append(line.Italic ? ", " + tr("Italic") : "");
// TODO : Set more descriptions
return result;
}

View File

@ -11,6 +11,7 @@
RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
QDialog(parent),
root(connection),
original(connection),
ui(new Ui::RouteEditor)
{
ui->setupUi(this);
@ -19,6 +20,7 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
outbounds = root["outbounds"].toArray();
DomainStrategy = root["routing"].toObject()["domainStrategy"].toString();
// Applying Balancers.
for (auto _balancer : root["routing"].toObject()["balancers"].toArray()) {
auto __balancer = _balancer.toObject();
Balancers[__balancer["tag"].toString()] = QList<QString>();
@ -54,40 +56,83 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
ui->inboundsList->addItem(inItem);
}
for (auto route : rules) {
ui->routesTable->clearContents();
for (int i = 0; i < rules.size(); i++) {
#define rule rules[i]
// Set up balancers.
if (QSTRING(rule.balancerTag).isEmpty()) {
// Default balancer tag.
auto bTag = GenerateRandomString();
rule.balancerTag = bTag.toStdString();
Balancers[bTag] = QStringList();
}
//
ui->routesTable->insertRow(ui->routesTable->rowCount());
// There will be an additional check on the final configuration generation process.
//
// WARNING There should be an additional check on the final configuration generation process.
auto enabledItem = new QTableWidgetItem(tr("Enabled"));
enabledItem->setCheckState(route.enabled ? Qt::Checked : Qt::Unchecked);
enabledItem->setCheckState(rule.QV2RAY_RULE_ENABLED ? Qt::Checked : Qt::Unchecked);
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 0, enabledItem);
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 1, new QTableWidgetItem(route.inboundTag.size() > 0 ? Stringify(route.inboundTag) : tr("Any")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 2, new QTableWidgetItem(QString::number(route.domain.size() + route.ip.size()) + " " + tr("Items")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 3, new QTableWidgetItem(QSTRING(route.outboundTag)));
//
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 1, new QTableWidgetItem(rule.inboundTag.size() > 0 ? Stringify(rule.inboundTag) : tr("Any")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 2, new QTableWidgetItem(QString::number(rule.domain.size() + rule.ip.size()) + " " + tr("Items")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 3, new QTableWidgetItem(QSTRING(rule.outboundTag)));
#undef rule
}
if (rules.size() > 0) {
ui->routesTable->setCurrentItem(ui->routesTable->item(0, 0));
currentRuleIndex = 0;
ShowRuleDetail(CurrentRule);
} else {
ui->delRouteBtn->setEnabled(false);
if (ui->inboundsList->count() > 0) ui->inboundsList->setCurrentRow(0);
if (ui->outboundsList->count() > 0) ui->outboundsList->setCurrentRow(0);
}
}
QJsonObject RouteEditor::OpenEditor()
{
this->exec();
QJsonArray balancers;
auto result = this->exec();
for (auto item : Balancers) {
QJsonObject balancerEntry;
balancerEntry["tag"] = Balancers.key(item);
balancerEntry["selector"] = QJsonArray::fromStringList(item);
balancers.append(balancerEntry);
if (result == QDialog::Accepted) {
QJsonArray balancers;
for (auto item : Balancers) {
QJsonObject balancerEntry;
auto key = Balancers.key(item);
if (!key.isEmpty()) {
balancerEntry["tag"] = key;
balancerEntry["selector"] = QJsonArray::fromStringList(item);
balancers.append(balancerEntry);
}
}
//
QJsonArray rulesArray;
for (auto _rule : rules) {
rulesArray.append(GetRootObject(_rule));
}
QJsonObject routing;
routing["domainStrategy"] = DomainStrategy;
routing["rules"] = rulesArray;
routing["balancers"] = balancers;
//
root["inbounds"] = inbounds;
root["outbounds"] = outbounds;
root["routing"] = routing;
return root;
} else {
return original;
}
//
QJsonObject routing;
routing["domainStrategy"] = DomainStrategy;
routing["rules"] = GetRootObject(rules.toStdList());
routing["balancers"] = balancers;
//
root["inbounds"] = inbounds;
root["outbounds"] = outbounds;
root["routing"] = routing;
return root;
}
RouteEditor::~RouteEditor()
@ -149,38 +194,48 @@ void RouteEditor::ShowRuleDetail(RuleObject rule)
int index = FindIndexByTag(outbounds, &outboundTag);
ui->outboundsList->setCurrentRow(index);
//
auto protocols = QList<string>::fromStdList(CurrentRule.protocol);
auto network = QSTRING(rule.network).toLower();
ui->netUDPRB->setChecked(network.contains("udp"));
ui->netTCPRB->setChecked(network.contains("tcp"));
ui->netBothRB->setChecked(network.contains("tcp") && network.contains("udp"));
//
// Set protocol checkboxes.
ui->routeProtocolHTTPCB->setChecked(false);
ui->routeProtocolBTCB->setChecked(false);
ui->routeProtocolTLSCB->setChecked(false);
if (protocols.contains("http")) {
ui->routeProtocolHTTPCB->setChecked(true);
}
if (protocols.contains("tls")) {
ui->routeProtocolTLSCB->setChecked(true);
}
if (protocols.contains("bittorrent")) {
ui->routeProtocolBTCB->setChecked(true);
}
auto protocols = QList<string>::fromStdList(CurrentRule.protocol);
ui->routeProtocolHTTPCB->setChecked(protocols.contains("http"));
ui->routeProtocolTLSCB->setChecked(protocols.contains("tls"));
ui->routeProtocolBTCB->setChecked(protocols.contains("bittorrent"));
//
// Port
ui->routePortTxt->setText(QSTRING(CurrentRule.port));
//
QString users = std::accumulate(CurrentRule.user.begin(), CurrentRule.user.end(), QString(), [](QString result, const string & str) {
result.append(QSTRING(str) + NEWLINE);
return result;
});
// Users
QString users = Stringify(CurrentRule.user, NEWLINE);
ui->routeUserTxt->setPlainText(users);
//
// Incoming Sources
QString sources = Stringify(CurrentRule.source, NEWLINE);
ui->sourceIPList->setPlainText(sources);
//
// Domains
QString domains = Stringify(CurrentRule.domain, NEWLINE);
ui->hostList->setPlainText(domains);
//
// Outcoming IPs
QString ips = Stringify(CurrentRule.ip, NEWLINE);
ui->ipList->setPlainText(ips);
//
// Set Balancer
ui->balancerSelectionCombo->clear();
ui->balancerSelectionCombo->addItems(Balancers[QSTRING(CurrentRule.balancerTag)]);
ui->balancerList->clear();
ui->balancerList->addItems(Balancers[QSTRING(CurrentRule.balancerTag)]);
if (rule.inboundTag.size() == 0) {
for (int i = 0; i < ui->inboundsList->count(); i++) {
ui->inboundsList->item(i)->setCheckState(Qt::Checked);
}
ui->inboundsList->setCurrentRow(0);
} else {
for (auto inboundTag : rule.inboundTag) {
auto inTag = QSTRING(inboundTag);
@ -195,6 +250,7 @@ void RouteEditor::ShowRuleDetail(RuleObject rule)
}
ui->inboundsList->item(_index)->setCheckState(Qt::Checked);
ui->inboundsList->setCurrentRow(_index);
STATUS("OK")
} else {
STATUS("Cannot find inbound by a tag, possible currupted files?")
@ -205,18 +261,6 @@ void RouteEditor::ShowRuleDetail(RuleObject rule)
}
}
void RouteEditor::on_routesTable_cellClicked(int row, int column)
{
Q_UNUSED(column)
if (row < 0) {
return;
}
currentRuleIndex = row;
ShowRuleDetail(CurrentRule);
}
void RouteEditor::on_editOutboundBtn_clicked()
{
QJsonObject result;
@ -265,6 +309,9 @@ void RouteEditor::on_editInboundBtn_clicked()
{
QJsonObject result;
int row = ui->inboundsList->currentRow();
if (row < 0) return;
auto currentInbound = inbounds[row].toObject();
auto protocol = currentInbound["protocol"].toString();
@ -328,27 +375,190 @@ void RouteEditor::on_routeProtocolBTCB_stateChanged(int arg1)
CurrentRule.protocol = protocols.toStdList();
STATUS("Protocol list changed.")
}
void RouteEditor::on_balabcerAddBtn_clicked()
{
if (!ui->balancerSelectionCombo->currentText().isEmpty()) {
this->Balancers[QSTRING(CurrentRule.balancerTag)].append(ui->balancerSelectionCombo->currentText());
}
ui->balancerList->addItem(ui->balancerSelectionCombo->currentText());
ui->balancerSelectionCombo->setEditText("");
STATUS("OK")
}
void RouteEditor::on_balancerDelBtn_clicked()
{
if (ui->balancerList->currentRow() < 0) {
return;
}
Balancers[QSTRING(CurrentRule.balancerTag)].removeAt(ui->balancerList->currentRow());
ui->balancerList->takeItem(ui->balancerList->currentRow());
STATUS("Removed a balancer entry.")
}
void RouteEditor::on_hostList_textChanged()
{
CurrentRule.domain = SplitLinesStdString(ui->hostList->toPlainText()).toStdList();
}
void RouteEditor::on_ipList_textChanged()
{
CurrentRule.ip = SplitLinesStdString(ui->ipList->toPlainText()).toStdList();
}
void RouteEditor::on_routePortTxt_textEdited(const QString &arg1)
{
CurrentRule.port = arg1.toStdString();
}
void RouteEditor::on_routeUserTxt_textEdited(const QString &arg1)
{
CurrentRule.user = SplitLinesStdString(arg1).toStdList();
}
void RouteEditor::on_routesTable_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
{
Q_UNUSED(currentColumn)
Q_UNUSED(previousColumn)
Q_UNUSED(previousRow)
if (currentRow < 0) {
return;
}
currentRuleIndex = currentRow;
ShowRuleDetail(CurrentRule);
}
void RouteEditor::on_addRouteBtn_clicked()
{
// Add Route
RuleObject rule;
//
if (QSTRING(rule.balancerTag).isEmpty()) {
// Default balancer tag.
auto bTag = GenerateRandomString();
rule.balancerTag = bTag.toStdString();
Balancers[bTag] = QStringList();
}
//
ui->routesTable->insertRow(ui->routesTable->rowCount());
// WARNING There will be an additional check on the final configuration generation process.
auto enabledItem = new QTableWidgetItem(tr("Enabled"));
enabledItem->setCheckState(rule.QV2RAY_RULE_ENABLED ? Qt::Checked : Qt::Unchecked);
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 0, enabledItem);
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 1, new QTableWidgetItem(rule.inboundTag.size() > 0 ? Stringify(rule.inboundTag) : tr("Any")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 2, new QTableWidgetItem(QString::number(rule.domain.size() + rule.ip.size()) + " " + tr("Items")));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 3, new QTableWidgetItem(QSTRING(rule.outboundTag)));
rules.append(rule);
currentRuleIndex = ui->routesTable->rowCount() - 1;
ui->routesTable->setCurrentCell(currentRuleIndex, 0);
ShowRuleDetail(CurrentRule);
ui->delRouteBtn->setEnabled(true);
}
void RouteEditor::on_changeIOBtn_clicked()
{
QString outbound = "";
if (ui->outboundsList->currentRow() < 0) {
// Don't return as someone may use the outboundTag
//
//QvMessageBox(this, tr("Changing route inbound/outbound"), tr("Please select an outbound from the list."));
//return;
QvMessageBox(this, tr("Changing route inbound/outbound"),
tr("You didn't select an outbound.") + NEWLINE +
tr("Banlancer will be used."));
} else {
outbound = outbounds[ui->outboundsList->currentRow()].toObject()["tag"].toString();
}
QList<string> new_inbounds;
QList<string> new_inbounds_name;
for (int i = 0; i < ui->inboundsList->count(); i++) {
auto _item = ui->inboundsList->item(i);
if (_item->checkState() == Qt::Checked) {
// WARN there are possiblilties that someone may forget to set the tag.
new_inbounds.append(inbounds[i].toObject()["tag"].toString().toStdString());
new_inbounds_name.append(_item->text().toStdString());
}
}
if (new_inbounds.size() == 0) {
// TODO what to do?
}
if (new_inbounds.contains("")) {
// Empty tag.
auto result1 = QvMessageBoxAsk(this, tr("Changing route inbound/outbound"), tr("One or more inbound config(s) have no tag configured, do you still want to continue?"));
if (result1 != QMessageBox::Yes) {
return;
}
}
auto result = QvMessageBoxAsk(this, tr("Changing route inbound/outbound"),
tr("Are you sure to change the inbound/outbound of currently selected route?") + NEWLINE +
tr("Current inbound/outbound combinations:") + NEWLINE + NEWLINE + tr("Inbounds: ") + NEWLINE +
Stringify(new_inbounds_name.toStdList(), NEWLINE) + NEWLINE + tr("Outbound: ") + outbound);
if (result != QMessageBox::Yes) {
STATUS("Canceled changing inbound/outbound combination.")
return;
}
CurrentRule.inboundTag = new_inbounds.toStdList();
CurrentRule.outboundTag = outbound.toStdString();
STATUS("OK")
}
void RouteEditor::on_routesTable_cellChanged(int row, int column)
{
if (column != 0) {
// Impossible
return;
}
if (row < 0) {
return;
}
if (rules.size() <= row) {
LOG(MODULE_UI, "INFO: This message is possibly caused by adding a new route.")
LOG(MODULE_UI, "INFO: ... But may indicate to other bugs if you didn't do that.")
return;
}
rules[row].QV2RAY_RULE_ENABLED = ui->routesTable->item(row, column)->checkState() == Qt::Checked;
STATUS((rules[row].QV2RAY_RULE_ENABLED ? "Enabled a route" : "Disabled a route"))
}
void RouteEditor::on_netBothRB_clicked()
{
CurrentRule.network = "tcp,udp";
}
void RouteEditor::on_netUDPRB_clicked()
{
CurrentRule.network = "udp";
}
void RouteEditor::on_netTCPRB_clicked()
{
CurrentRule.network = "tcp";
}
void RouteEditor::on_routeUserTxt_textChanged()
{
CurrentRule.user = SplitLinesStdString(ui->routeUserTxt->toPlainText()).toStdList();
}
void RouteEditor::on_sourceIPList_textChanged()
{
CurrentRule.source = SplitLinesStdString(ui->sourceIPList->toPlainText()).toStdList();
}

View File

@ -27,8 +27,6 @@ class RouteEditor : public QDialog
void on_inboundsList_currentRowChanged(int currentRow);
void on_routesTable_cellClicked(int row, int column);
void on_editOutboundBtn_clicked();
void on_insertDirectBtn_clicked();
@ -53,6 +51,24 @@ class RouteEditor : public QDialog
void on_routeUserTxt_textEdited(const QString &arg1);
void on_routesTable_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn);
void on_addRouteBtn_clicked();
void on_changeIOBtn_clicked();
void on_routesTable_cellChanged(int row, int column);
void on_netBothRB_clicked();
void on_netUDPRB_clicked();
void on_netTCPRB_clicked();
void on_routeUserTxt_textChanged();
void on_sourceIPList_textChanged();
private:
void ShowRuleDetail(RuleObject rule);
int currentRuleIndex;
@ -63,6 +79,7 @@ class RouteEditor : public QDialog
QJsonArray inbounds;
QJsonArray outbounds;
QJsonObject root;
QJsonObject original;
Ui::RouteEditor *ui;
};

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>1010</width>
<height>610</height>
<height>625</height>
</rect>
</property>
<property name="minimumSize">
@ -22,14 +22,181 @@
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_5" columnstretch="3,9">
<layout class="QGridLayout" name="gridLayout_5" rowstretch="1,1,0" columnstretch="1,2">
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Outbound List</string>
</property>
<layout class="QGridLayout" name="gridLayout_4" rowstretch="1,0">
<item row="0" column="0" rowspan="2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QToolButton" name="addOutboundBtn">
<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="delOutboundBtn">
<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="QToolButton" name="editOutboundBtn">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/edit_connection_btn.png</normaloff>:/icons/edit_connection_btn.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="insertDirectBtn">
<property name="text">
<string>D</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QListWidget" name="outboundsList">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="outboundDetailGroup">
<property name="title">
<string>Outbound Information</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QGridLayout" name="gridLayout_7" columnstretch="0,1,0,1">
<item row="0" column="3">
<widget class="QLabel" name="outboundTagLabel">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Tag</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="outboundTypeLabel">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Address</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="outboundAddressLabel">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="outboundPortLabel">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Routes</string>
</property>
<layout class="QGridLayout" name="gridLayout_6" columnstretch="6,4">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="4,0,2">
<item>
<widget class="QTableWidget" name="routesTable">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
@ -52,7 +219,7 @@
</column>
<column>
<property name="text">
<string>DomainOrIP</string>
<string>Domain/IP</string>
</property>
</column>
<column>
@ -62,104 +229,7 @@
</column>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Route Information</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="1" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Protocol</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="routeProtocolHTTPCB">
<property name="text">
<string>HTTP</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="routeProtocolTLSCB">
<property name="text">
<string>TLS</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="routeProtocolBTCB">
<property name="text">
<string>BitTorrent</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="routePortTxt">
<property name="placeholderText">
<string>e.g. 80, 443, 8000-8080</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Users</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QPlainTextEdit" name="routeUserTxt"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Network</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QRadioButton" name="netTCPRB">
<property name="text">
<string>TCP</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="netUDPRB">
<property name="text">
<string>UDP</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="netBothRB">
<property name="text">
<string>Both</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<item>
<layout class="QHBoxLayout" name="routesControlButtons">
<item>
<spacer name="horizontalSpacer_4">
@ -218,92 +288,190 @@
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>320</height>
</size>
</property>
<property name="title">
<string>Route Details</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Target Host List</string>
</property>
</widget>
</item>
<layout class="QGridLayout" name="gridLayout_6" columnstretch="1,1,1">
<item row="1" column="2">
<widget class="QPlainTextEdit" name="sourceIPList"/>
</item>
<item row="3" column="2">
<widget class="QPlainTextEdit" name="ipList"/>
</item>
<item row="0" column="2">
<item row="0" column="0" rowspan="4">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Network</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QRadioButton" name="netTCPRB">
<property name="text">
<string>TCP</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="netUDPRB">
<property name="text">
<string>UDP</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="netBothRB">
<property name="text">
<string>Both</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Protocol</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="routeProtocolHTTPCB">
<property name="text">
<string>HTTP</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="routeProtocolTLSCB">
<property name="text">
<string>TLS</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="routeProtocolBTCB">
<property name="text">
<string>BitTorrent</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="routePortTxt">
<property name="placeholderText">
<string>e.g. 80, 443, 8000-8080</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Balancers</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QComboBox" name="balancerSelectionCombo">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="balancerDelBtn">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/remove_connection_btn.png</normaloff>:/icons/remove_connection_btn.png</iconset>
</property>
</widget>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="balabcerAddBtn">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/add_connection_btn.png</normaloff>:/icons/add_connection_btn.png</iconset>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2">
<widget class="QListWidget" name="balancerList"/>
</item>
</layout>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QPlainTextEdit" name="routeUserTxt"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Target IP List</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPlainTextEdit" name="hostList"/>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_6">
<item row="0" column="1">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Balancer</string>
<string>Users</string>
</property>
</widget>
</item>
<item row="1" column="3">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QComboBox" name="balancerSelectionCombo">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="balancerDelBtn">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/remove_connection_btn.png</normaloff>:/icons/remove_connection_btn.png</iconset>
</property>
</widget>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="balabcerAddBtn">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/add_connection_btn.png</normaloff>:/icons/add_connection_btn.png</iconset>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2">
<widget class="QListWidget" name="balancerList"/>
</item>
</layout>
<item row="3" column="1">
<widget class="QPlainTextEdit" name="hostList"/>
</item>
<item row="1" column="0">
<widget class="QPlainTextEdit" name="sourceIPList"/>
<item row="2" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Target Host List</string>
</property>
</widget>
</item>
<item row="0" column="0">
<item row="0" column="2">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Source IP List</string>
@ -321,22 +489,9 @@
<property name="title">
<string>Inbound List</string>
</property>
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,1">
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<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 class="QGridLayout" name="gridLayout_3" rowstretch="1,0">
<item row="0" column="0" rowspan="2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QToolButton" name="addInboundBtn">
<property name="text">
@ -360,28 +515,32 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="addDefaultBtn">
<widget class="QToolButton" name="editInboundBtn">
<property name="text">
<string>Add Defaults</string>
<string/>
</property>
<property name="icon">
<iconset resource="../../resources.qrc">
<normaloff>:/icons/edit_connection_btn.png</normaloff>:/icons/edit_connection_btn.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="editInboundBtn">
<widget class="QToolButton" name="addDefaultBtn">
<property name="text">
<string>Edit</string>
<string>D</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
@ -389,213 +548,90 @@
</layout>
</item>
<item row="0" column="1">
<widget class="QListWidget" name="inboundsList"/>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="outboundDetailGroup_2">
<property name="title">
<string>Inbound Information</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Tag</string>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QGridLayout" name="gridLayout_8" columnstretch="0,1,0,1">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="inboundTypeLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Address</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Tag</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="inboundTagLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="inboundAddressLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="inboundPortLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QLabel" name="inboundTagLabel">
<property name="text">
<string/>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Type</string>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>31</height>
</size>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="inboundTypeLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Address</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="inboundAddressLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="inboundPortLabel">
<property name="text">
<string/>
</property>
</widget>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QListWidget" name="inboundsList"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Outbound List</string>
</property>
<layout class="QGridLayout" name="gridLayout_4" columnstretch="1,1">
<item row="0" column="0">
<widget class="QListWidget" name="outboundsList">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="outboundDetailGroup">
<property name="title">
<string>Outbound Information</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Tag</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="outboundTagLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="outboundTypeLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Address</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="outboundAddressLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="outboundPortLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer_8">
<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="addOutboundBtn">
<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="delOutboundBtn">
<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="editOutboundBtn">
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<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>
</layout>
</widget>
</item>