refactor: huge refactor of basic SafeType system

This commit is contained in:
QwQ 2020-07-15 17:02:00 +08:00
parent 3059fc9d88
commit cd017adb2a
No known key found for this signature in database
GPG Key ID: E7FAEFAFCD031D4B
26 changed files with 929 additions and 1331 deletions

View File

@ -44,6 +44,16 @@ set(QV2RAY_UI_SOURCES
${CMAKE_SOURCE_DIR}/src/ui/models/OutboundNodeModel.cpp ${CMAKE_SOURCE_DIR}/src/ui/models/OutboundNodeModel.cpp
${CMAKE_SOURCE_DIR}/src/ui/models/RuleNodeModel.hpp ${CMAKE_SOURCE_DIR}/src/ui/models/RuleNodeModel.hpp
${CMAKE_SOURCE_DIR}/src/ui/models/RuleNodeModel.cpp ${CMAKE_SOURCE_DIR}/src/ui/models/RuleNodeModel.cpp
# NodeEditor Widgets
${CMAKE_SOURCE_DIR}/src/ui/widgets/node/RuleWidget.cpp
${CMAKE_SOURCE_DIR}/src/ui/widgets/node/RuleWidget.hpp
${CMAKE_SOURCE_DIR}/src/ui/widgets/node/RuleWidget.ui
${CMAKE_SOURCE_DIR}/src/ui/widgets/node/InboundOutboundWidget.cpp
${CMAKE_SOURCE_DIR}/src/ui/widgets/node/InboundOutboundWidget.hpp
${CMAKE_SOURCE_DIR}/src/ui/widgets/node/InboundOutboundWidget.ui
${CMAKE_SOURCE_DIR}/src/ui/widgets/node/OutboundBalancerWidget.cpp
${CMAKE_SOURCE_DIR}/src/ui/widgets/node/OutboundBalancerWidget.hpp
${CMAKE_SOURCE_DIR}/src/ui/widgets/node/OutboundBalancerWidget.ui
# Style Manager # Style Manager
${CMAKE_SOURCE_DIR}/src/ui/styles/StyleManager.cpp ${CMAKE_SOURCE_DIR}/src/ui/styles/StyleManager.cpp
${CMAKE_SOURCE_DIR}/src/ui/styles/StyleManager.hpp ${CMAKE_SOURCE_DIR}/src/ui/styles/StyleManager.hpp

View File

@ -1 +1 @@
5791 5792

View File

@ -6,23 +6,23 @@
#include <QJsonObject> #include <QJsonObject>
#include <QMap> #include <QMap>
#define SAFE_TYPEDEF_EXTRA(Base, name, extra) \ template<typename placeholder, typename BASETYPE_T>
class name : public Base \ class SAFETYPE_IMPL : public BASETYPE_T
{ \ {
public: \ public:
template<class... Args> \ template<class... Args>
explicit name(Args... args) : Base(args...) \ explicit SAFETYPE_IMPL(Args... args) : BASETYPE_T(args...){};
{ \ const BASETYPE_T &raw() const
} \ {
const Base &raw() const \ return *this;
{ \
return *this; \
} \
extra \
} }
};
#define SAFE_TYPEDEF(BASE, CLASS) \
class __##CLASS##__; \
typedef SAFETYPE_IMPL<__##CLASS##__, BASE> CLASS;
#define nothing #define nothing
#define SAFE_TYPEDEF(Base, name) SAFE_TYPEDEF_EXTRA(Base, name, nothing)
namespace Qv2ray::base::safetype namespace Qv2ray::base::safetype
{ {
// To prevent anonying QJsonObject misuse // To prevent anonying QJsonObject misuse
@ -31,14 +31,11 @@ namespace Qv2ray::base::safetype
SAFE_TYPEDEF(QJsonObject, INBOUND); SAFE_TYPEDEF(QJsonObject, INBOUND);
SAFE_TYPEDEF(QJsonObject, OUTBOUND); SAFE_TYPEDEF(QJsonObject, OUTBOUND);
SAFE_TYPEDEF(QJsonObject, CONFIGROOT); SAFE_TYPEDEF(QJsonObject, CONFIGROOT);
SAFE_TYPEDEF(QJsonObject, PROXYSETTING);
//
SAFE_TYPEDEF(QJsonArray, ROUTERULELIST);
SAFE_TYPEDEF(QJsonArray, INOUTLIST);
SAFE_TYPEDEF(QJsonObject, ROUTING); SAFE_TYPEDEF(QJsonObject, ROUTING);
SAFE_TYPEDEF(QJsonObject, ROUTERULE); SAFE_TYPEDEF(QJsonObject, ROUTERULE);
SAFE_TYPEDEF(INOUTLIST, OUTBOUNDS); //
SAFE_TYPEDEF(INOUTLIST, INBOUNDS); SAFE_TYPEDEF(QJsonArray, OUTBOUNDS);
SAFE_TYPEDEF(QJsonArray, INBOUNDS);
template<typename T> template<typename T>
struct QvPair struct QvPair

View File

@ -165,23 +165,30 @@ namespace Qv2ray::core
return TruncateString(ConnectionManager->GetGroupMetaObject(id).displayName, limit); return TruncateString(ConnectionManager->GetGroupMetaObject(id).displayName, limit);
} }
const QMap<QString, InboundInfoObject> GetConfigInboundInfo(const CONFIGROOT &root) bool GetInboundInfo(const INBOUND &in, QString *listen, int *port, QString *protocol)
{
*protocol = in["protocol"].toString();
*listen = in["listen"].toString();
*port = in["port"].toVariant().toInt();
return true;
}
const QMap<QString, InboundInfoObject> GetInboundInfo(const CONFIGROOT &root)
{ {
QMap<QString, InboundInfoObject> inboundPorts; QMap<QString, InboundInfoObject> inboundPorts;
for (const auto &inboundVal : root["inbounds"].toArray()) for (const auto &inboundVal : root["inbounds"].toArray())
{ {
const auto &inbound = inboundVal.toObject(); INBOUND in{ inboundVal.toObject() };
inboundPorts[inbound["tag"].toString()] = { QString host, protocol;
inbound["protocol"].toString(), // int port;
inbound["listen"].toString(), // if (GetInboundInfo(in, &host, &port, &protocol))
inbound["port"].toVariant().toInt() // inboundPorts[getTag(in)] = { protocol, host, port };
};
} }
return inboundPorts; return inboundPorts;
} }
const QMap<QString, InboundInfoObject> GetConfigInboundInfo(const ConnectionId &id) const QMap<QString, InboundInfoObject> GetInboundInfo(const ConnectionId &id)
{ {
return GetConfigInboundInfo(ConnectionManager->GetConnectionRoot(id)); return GetInboundInfo(ConnectionManager->GetConnectionRoot(id));
} }
} // namespace Qv2ray::core } // namespace Qv2ray::core

View File

@ -49,8 +49,9 @@ namespace Qv2ray::core
// //
// const GroupId GetConnectionGroupId(const ConnectionId &id); // const GroupId GetConnectionGroupId(const ConnectionId &id);
// //
const QMap<QString, InboundInfoObject> GetConfigInboundInfo(const CONFIGROOT &root); bool GetInboundInfo(const INBOUND &in, QString *listen, int *port, QString *protocol);
const QMap<QString, InboundInfoObject> GetConfigInboundInfo(const ConnectionId &id); const QMap<QString, InboundInfoObject> GetInboundInfo(const CONFIGROOT &root);
const QMap<QString, InboundInfoObject> GetInboundInfo(const ConnectionId &id);
} // namespace Qv2ray::core } // namespace Qv2ray::core
using namespace Qv2ray::core; using namespace Qv2ray::core;

View File

@ -79,7 +79,7 @@ namespace Qv2ray::core::handler
std::optional<QString> KernelInstanceHandler::StartConnection(const ConnectionGroupPair &id, CONFIGROOT fullConfig) std::optional<QString> KernelInstanceHandler::StartConnection(const ConnectionGroupPair &id, CONFIGROOT fullConfig)
{ {
StopConnection(); StopConnection();
inboundInfo = GetConfigInboundInfo(fullConfig); inboundInfo = GetInboundInfo(fullConfig);
// //
const auto inboundPorts = GetInboundPorts(); const auto inboundPorts = GetInboundPorts();
const auto inboundHosts = GetInboundHosts(); const auto inboundHosts = GetInboundHosts();

View File

@ -25,7 +25,7 @@ namespace Qv2ray::core::handler
{ {
return activeKernels.size(); return activeKernels.size();
} }
const QMap<QString, InboundInfoObject> GetInboundInfo() const const QMap<QString, InboundInfoObject> GetCurrentConnectionInboundInfo() const
{ {
return inboundInfo; return inboundInfo;
} }

View File

@ -50,7 +50,7 @@ namespace Qv2ray::core::handler
root.insert("domainStrategy", routeConfig.domainStrategy); root.insert("domainStrategy", routeConfig.domainStrategy);
// //
// For Rules list // For Rules list
ROUTERULELIST rulesList; QJsonArray rulesList;
// Private IPs should always NOT TO PROXY! // Private IPs should always NOT TO PROXY!
rulesList.append(GenerateSingleRouteRule("geoip:private", false, OUTBOUND_TAG_DIRECT)); rulesList.append(GenerateSingleRouteRule("geoip:private", false, OUTBOUND_TAG_DIRECT));
@ -256,7 +256,7 @@ namespace Qv2ray::core::handler
// And what's more, process (by removing unused items) from a // And what's more, process (by removing unused items) from a
// rule object. // rule object.
ROUTING routing(root["routing"].toObject()); ROUTING routing(root["routing"].toObject());
ROUTERULELIST rules; QJsonArray rules;
LOG(MODULE_CONNECTION, "Processing an existing routing table.") LOG(MODULE_CONNECTION, "Processing an existing routing table.")
for (const auto &_rule : routing["rules"].toArray()) for (const auto &_rule : routing["rules"].toArray())
@ -315,7 +315,7 @@ namespace Qv2ray::core::handler
if (firstOutbound[QV2RAY_USE_FPROXY_KEY].toBool(false)) if (firstOutbound[QV2RAY_USE_FPROXY_KEY].toBool(false))
{ {
LOG(MODULE_CONNECTION, "Applying forward proxy to current connection.") LOG(MODULE_CONNECTION, "Applying forward proxy to current connection.")
PROXYSETTING proxy; QJsonObject proxy;
proxy["tag"] = OUTBOUND_TAG_FORWARD_PROXY; proxy["tag"] = OUTBOUND_TAG_FORWARD_PROXY;
firstOutbound["proxySettings"] = proxy; firstOutbound["proxySettings"] = proxy;

View File

@ -22,7 +22,7 @@
using QtNodes::FlowView; using QtNodes::FlowView;
using namespace Qv2ray::ui::nodemodels; using namespace Qv2ray::ui::nodemodels;
#define CurrentRule this->rules[this->currentRuleTag] //#define CurrentRule this->rules[this->currentRuleTag]
#define LOADINGCHECK \ #define LOADINGCHECK \
if (isLoading) \ if (isLoading) \
return; return;
@ -85,14 +85,7 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QvDialog(par
// //
SetupNodeWidget(); SetupNodeWidget();
// //
// Setup icons according to the theme settings. updateColorScheme();
addInboundBtn->setIcon(QICON_R("add.png"));
addOutboundBtn->setIcon(QICON_R("add.png"));
editBtn->setIcon(QICON_R("edit.png"));
addRouteBtn->setIcon(QICON_R("add.png"));
delBtn->setIcon(QICON_R("delete.png"));
balancerAddBtn->setIcon(QICON_R("add.png"));
balancerDelBtn->setIcon(QICON_R("delete.png"));
// //
domainStrategy = root["routing"].toObject()["domainStrategy"].toString(); domainStrategy = root["routing"].toObject()["domainStrategy"].toString();
domainStrategyCombo->setCurrentText(domainStrategy); domainStrategyCombo->setCurrentText(domainStrategy);
@ -117,15 +110,15 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QvDialog(par
defaultOutbound = getTag(OUTBOUND(root["outbounds"].toArray().first().toObject())); defaultOutbound = getTag(OUTBOUND(root["outbounds"].toArray().first().toObject()));
defaultOutboundCombo->setCurrentText(defaultOutbound); defaultOutboundCombo->setCurrentText(defaultOutbound);
// Find and add balancers. // // Find and add balancers.
for (auto _balancer : root["routing"].toObject()["balancers"].toArray()) // for (auto _balancer : root["routing"].toObject()["balancers"].toArray())
{ // {
auto _balancerObject = _balancer.toObject(); // auto _balancerObject = _balancer.toObject();
if (!_balancerObject["tag"].toString().isEmpty()) // if (!_balancerObject["tag"].toString().isEmpty())
{ // {
balancers.insert(_balancerObject["tag"].toString(), _balancerObject["selector"].toVariant().toStringList()); // balancers.insert(_balancerObject["tag"].toString(), _balancerObject["selector"].toVariant().toStringList());
} // }
} // }
for (const auto &group : ConnectionManager->AllGroups()) for (const auto &group : ConnectionManager->AllGroups())
{ {
@ -157,43 +150,37 @@ void RouteEditor::onNodeClicked(Node &n)
auto isIn = inboundNodes.values().contains(n.id()); auto isIn = inboundNodes.values().contains(n.id());
auto isRule = ruleNodes.values().contains(n.id()); auto isRule = ruleNodes.values().contains(n.id());
if (isRule) /* if (isRule)
{ {
// It's a rule object // It's a rule object
currentRuleTag = GetFirstNodeData(n.id(), RuleNode)->GetRuleTag(); currentRuleTag = GetFirstNodeData(n.id(), RuleNode)->GetRuleTag();
DEBUG(MODULE_GRAPH, "Selecting rule: " + currentRuleTag) DEBUG(MODULE_GRAPH, "Selecting rule: " + currentRuleTag)
ShowCurrentRuleDetail(); // ShowCurrentRuleDetail();
toolBox->setCurrentIndex(1); toolBox->setCurrentIndex(1);
} }
else if (isOut || isIn) else*/
if (isOut || isIn)
{ {
// It's an inbound or an outbound. // It's an inbound or an outbound.
QString alias; QString tag;
QString host; QString host;
QString port; int port;
QString protocol; QString protocol;
if (isOut) if (isOut)
{ {
alias = GetFirstNodeData(n.id(), OutboundNode)->GetOutbound(); const auto root = GetFirstNodeData(n.id(), OutboundNode)->GetOutbound();
QJsonObject _root = outbounds[alias].raw(); GetOutboundInfo(*root, &host, &port, &protocol);
int _port;
GetOutboundInfo(OUTBOUND(_root), &host, &_port, &protocol);
port = QString::number(_port);
} }
else else
{ {
alias = GetFirstNodeData(n.id(), InboundNode)->GetInbound(); const auto root = GetFirstNodeData(n.id(), InboundNode)->GetInbound();
QJsonObject _root = inbounds[alias].raw(); GetInboundInfo(*root, &host, &port, &protocol);
host = _root["listen"].toString();
protocol = _root["protocol"].toString();
// Port could be a string, or an integer.
port = _root["port"].toVariant().toString();
} }
tagLabel->setText(alias); tagLabel->setText(tag);
protocolLabel->setText(protocol); protocolLabel->setText(protocol);
portLabel->setText(port); portLabel->setText(QSTRN(port));
hostLabel->setText(host); hostLabel->setText(host);
} }
else else
@ -213,58 +200,58 @@ void RouteEditor::onConnectionCreated(QtNodes::Connection const &c)
auto const &sourceNode = c.getNode(PortType::Out); auto const &sourceNode = c.getNode(PortType::Out);
auto const &targetNode = c.getNode(PortType::In); auto const &targetNode = c.getNode(PortType::In);
if (inboundNodes.values().contains(sourceNode->id()) && ruleNodes.values().contains(targetNode->id())) // if (inboundNodes.values().contains(sourceNode->id()) && ruleNodes.values().contains(targetNode->id()))
{ // {
// It's a inbound-rule connection // // It's a inbound-rule connection
onNodeClicked(*sourceNode); // onNodeClicked(*sourceNode);
onNodeClicked(*targetNode); // onNodeClicked(*targetNode);
LOG(MODULE_GRAPH, "Inbound-rule new connection.") // LOG(MODULE_GRAPH, "Inbound-rule new connection.")
// Get all connected inbounds to this rule node. // // Get all connected inbounds to this rule node.
// QStringList has an helper to let us remove duplicates, see below. // // QStringList has an helper to let us remove duplicates, see below.
QSet<QString> _inbounds; // QSet<QString> _inbounds;
// // //
// Workaround for removing a connection within the loop. // // Workaround for removing a connection within the loop.
QList<std::shared_ptr<QtNodes::Connection>> connectionsTobeRemoved; // QList<std::shared_ptr<QtNodes::Connection>> connectionsTobeRemoved;
for (auto &&[_, conn] : nodeScene->connections()) // for (auto &&[_, conn] : nodeScene->connections())
{ // {
const auto &inNode = conn->getNode(PortType::In); // const auto &inNode = conn->getNode(PortType::In);
const auto &outNode = conn->getNode(PortType::Out); // const auto &outNode = conn->getNode(PortType::Out);
// If a connection is not current Id, but with same IN/OUT nodes. // // If a connection is not current Id, but with same IN/OUT nodes.
// It is a "duplicated" connection. // // It is a "duplicated" connection.
if (inNode->id() == targetNode->id() && outNode->id() == sourceNode->id() && conn->id() != c.id()) // if (inNode->id() == targetNode->id() && outNode->id() == sourceNode->id() && conn->id() != c.id())
{ // {
connectionsTobeRemoved << (conn); // connectionsTobeRemoved << (conn);
} // }
// Append all inbounds // // Append all inbounds
if (inNode->id() == targetNode->id()) // if (inNode->id() == targetNode->id())
{ // {
_inbounds.insert(GetFirstNodeData(outNode->id(), InboundNode)->GetInbound()); // _inbounds.insert(GetFirstNodeData(outNode->id(), InboundNode)->GetInbound());
} // }
} // }
for (const auto &connRemoved : connectionsTobeRemoved) // for (const auto &connRemoved : connectionsTobeRemoved)
{ // {
nodeScene->deleteConnection(*connRemoved); // nodeScene->deleteConnection(*connRemoved);
} // }
//
CurrentRule.inboundTag = _inbounds.values(); // CurrentRule.inboundTag = _inbounds.values();
} // }
else if (ruleNodes.values().contains(sourceNode->id()) && outboundNodes.values().contains(targetNode->id())) // else if (ruleNodes.values().contains(sourceNode->id()) && outboundNodes.values().contains(targetNode->id()))
{ // {
// It's a rule-outbound connection // // It's a rule-outbound connection
onNodeClicked(*sourceNode); // onNodeClicked(*sourceNode);
onNodeClicked(*targetNode); // onNodeClicked(*targetNode);
CurrentRule.outboundTag = GetFirstNodeData(targetNode->id(), OutboundNode)->GetOutbound(); // CurrentRule.outboundTag = GetFirstNodeData(targetNode->id(), OutboundNode)->GetOutbound();
// Connecting to an outbound will disable the balancer feature. // // Connecting to an outbound will disable the balancer feature.
CurrentRule.QV2RAY_RULE_USE_BALANCER = false; // CurrentRule.QV2RAY_RULE_USE_BALANCER = false;
// Update balancer settings. // // Update balancer settings.
ShowCurrentRuleDetail(); // // ShowCurrentRuleDetail();
LOG(MODULE_GRAPH, "Updated outbound: " + CurrentRule.outboundTag) // LOG(MODULE_GRAPH, "Updated outbound: " + CurrentRule.outboundTag)
} // }
else // else
{ // {
// It's an impossible connection // // It's an impossible connection
LOG(MODULE_GRAPH, "Unrecognized connection, RARE.") // LOG(MODULE_GRAPH, "Unrecognized connection, RARE.")
} // }
} }
void RouteEditor::onConnectionDeleted(QtNodes::Connection const &c) void RouteEditor::onConnectionDeleted(QtNodes::Connection const &c)
@ -278,36 +265,36 @@ void RouteEditor::onConnectionDeleted(QtNodes::Connection const &c)
const auto &source = c.getNode(PortType::Out); const auto &source = c.getNode(PortType::Out);
const auto &target = c.getNode(PortType::In); const auto &target = c.getNode(PortType::In);
if (inboundNodes.values().contains(source->id()) && ruleNodes.values().contains(target->id())) // if (inboundNodes.values().contains(source->id()) && ruleNodes.values().contains(target->id()))
{ //{
// It's a inbound-rule connection // // It's a inbound-rule connection
onNodeClicked(*source); // onNodeClicked(*source);
onNodeClicked(*target); // onNodeClicked(*target);
currentRuleTag = GetFirstNodeData(target->id(), RuleNode)->GetRuleTag(); // currentRuleTag = GetFirstNodeData(target->id(), RuleNode)->GetRuleTag();
auto _inboundTag = GetFirstNodeData(source->id(), InboundNode)->GetInbound(); // auto _inboundTag = GetFirstNodeData(source->id(), InboundNode)->GetInbound();
LOG(MODULE_UI, "Removing inbound: " + _inboundTag + " from rule: " + currentRuleTag) // LOG(MODULE_UI, "Removing inbound: " + _inboundTag + " from rule: " + currentRuleTag)
CurrentRule.inboundTag.removeAll(_inboundTag); // CurrentRule.inboundTag.removeAll(_inboundTag);
} //}
else if (ruleNodes.values().contains(source->id()) && outboundNodes.values().contains(target->id())) // else if (ruleNodes.values().contains(source->id()) && outboundNodes.values().contains(target->id()))
{ //{
// It's a rule-outbound connection // // It's a rule-outbound connection
onNodeClicked(*source); // onNodeClicked(*source);
onNodeClicked(*target); // onNodeClicked(*target);
currentRuleTag = GetFirstNodeData(source->id(), RuleNode)->GetRuleTag(); // currentRuleTag = GetFirstNodeData(source->id(), RuleNode)->GetRuleTag();
auto _outboundTag = GetFirstNodeData(target->id(), OutboundNode)->GetOutbound(); // auto _outboundTag = GetFirstNodeData(target->id(), OutboundNode)->GetOutbound();
//
if (!CurrentRule.QV2RAY_RULE_USE_BALANCER && CurrentRule.outboundTag == _outboundTag) // if (!CurrentRule.QV2RAY_RULE_USE_BALANCER && CurrentRule.outboundTag == _outboundTag)
{ // {
CurrentRule.outboundTag.clear(); // CurrentRule.outboundTag.clear();
} // }
//
LOG(MODULE_GRAPH, "Removing an outbound: " + _outboundTag) // LOG(MODULE_GRAPH, "Removing an outbound: " + _outboundTag)
} //}
else // else
{ //{
// It's an impossible connection // // It's an impossible connection
LOG(MODULE_GRAPH, "Selected an unknown node, RARE.") // LOG(MODULE_GRAPH, "Selected an unknown node, RARE.")
} //}
} }
CONFIGROOT RouteEditor::OpenEditor() CONFIGROOT RouteEditor::OpenEditor()
@ -330,7 +317,7 @@ CONFIGROOT RouteEditor::OpenEditor()
// Append rules by order // Append rules by order
for (auto i = 0; i < ruleListWidget->count(); i++) for (auto i = 0; i < ruleListWidget->count(); i++)
{ {
auto _rule = rules[ruleListWidget->item(i)->text()]; auto _rule = rules[i];
auto ruleJsonObject = _rule.toJson(); auto ruleJsonObject = _rule.toJson();
// Process balancer for a rule // Process balancer for a rule
@ -339,19 +326,19 @@ CONFIGROOT RouteEditor::OpenEditor()
// Do not use outbound tag. // Do not use outbound tag.
ruleJsonObject.remove("outboundTag"); ruleJsonObject.remove("outboundTag");
// Find balancer list // // Find balancer list
if (!balancers.contains(_rule.balancerTag)) // if (!balancers.contains(_rule.balancerTag))
{ // {
LOG(MODULE_UI, "Cannot find a balancer for tag: " + _rule.balancerTag) // LOG(MODULE_UI, "Cannot find a balancer for tag: " + _rule.balancerTag)
} // }
else // else
{ // {
auto _balancerList = balancers[_rule.balancerTag]; // auto _balancerList = balancers[_rule.balancerTag];
QJsonObject balancerEntry; // QJsonObject balancerEntry;
balancerEntry["tag"] = _rule.balancerTag; // balancerEntry["tag"] = _rule.balancerTag;
balancerEntry["selector"] = QJsonArray::fromStringList(_balancerList); // balancerEntry["selector"] = QJsonArray::fromStringList(_balancerList);
_balancers.append(balancerEntry); // _balancers.append(balancerEntry);
} // }
} }
// Remove some empty fields. // Remove some empty fields.
@ -425,85 +412,6 @@ void RouteEditor::on_buttonBox_accepted()
{ {
} }
void RouteEditor::ShowCurrentRuleDetail()
{
LOADINGCHECK
if (currentRuleTag.isEmpty())
{
LOG(MODULE_UI, "WARNING, trying to access a non-exist rule entry. return.")
return;
}
if (!rules.contains(currentRuleTag))
{
QvMessageBoxWarn(this, tr("Show rule details"), tr("A rule cannot be found: ") + currentRuleTag);
LOG(MODULE_UI, "WARNING, trying to access a non-exist rule entry. return.")
return;
}
// Switch to the detailed page.
ruleEnableCB->setEnabled(true);
ruleEnableCB->setChecked(CurrentRule.QV2RAY_RULE_ENABLED);
routeEditGroupBox->setEnabled(true);
ruleTagLineEdit->setEnabled(true);
ruleRenameBtn->setEnabled(true);
routeRuleGroupBox->setEnabled(true);
LOAD_FLAG_BEGIN
ruleTagLineEdit->setText(CurrentRule.QV2RAY_RULE_TAG);
balancerSelectionCombo->clear();
for (auto out : outbounds)
{
balancerSelectionCombo->addItem(getTag(OUTBOUND(out)));
}
//
// Balancers combo and balancer list.
enableBalancerCB->setChecked(CurrentRule.QV2RAY_RULE_USE_BALANCER);
balancersWidget->setEnabled(CurrentRule.QV2RAY_RULE_USE_BALANCER);
if (!CurrentRule.balancerTag.isEmpty())
{
balancerList->clear();
balancerList->addItems(balancers[CurrentRule.balancerTag]);
}
isLoading = false;
// Networks
auto network = CurrentRule.network.toLower();
bool isBoth = (network.contains("tcp") && network.contains("udp")) || network.isEmpty();
netUDPRB->setChecked(network.contains("udp"));
netTCPRB->setChecked(network.contains("tcp"));
netBothRB->setChecked(isBoth);
//
// Set protocol checkboxes.
auto protocol = CurrentRule.protocol;
routeProtocolHTTPCB->setChecked(protocol.contains("http"));
routeProtocolTLSCB->setChecked(protocol.contains("tls"));
routeProtocolBTCB->setChecked(protocol.contains("bittorrent"));
//
// Port
routePortTxt->setText(CurrentRule.port);
//
// Users
QString users = CurrentRule.user.join(NEWLINE);
routeUserTxt->setPlainText(users);
//
// Incoming Sources
QString sources = CurrentRule.source.join(NEWLINE);
sourceIPList->setPlainText(sources);
//
// Domains
QString domains = CurrentRule.domain.join(NEWLINE);
hostList->setPlainText(domains);
//
// Outcoming IPs
QString ips = CurrentRule.ip.join(NEWLINE);
ipList->setPlainText(ips);
LOAD_FLAG_END
}
void RouteEditor::on_insertDirectBtn_clicked() void RouteEditor::on_insertDirectBtn_clicked()
{ {
auto freedom = GenerateFreedomOUT("AsIs", "", 0); auto freedom = GenerateFreedomOUT("AsIs", "", 0);
@ -514,172 +422,6 @@ void RouteEditor::on_insertDirectBtn_clicked()
statusLabel->setText(tr("Added DIRECT outbound")); statusLabel->setText(tr("Added DIRECT outbound"));
} }
void RouteEditor::on_routeProtocolHTTPCB_stateChanged(int arg1)
{
LOADINGCHECK
QStringList protocols;
if (arg1 == Qt::Checked)
protocols.push_back("http");
if (routeProtocolTLSCB->isChecked())
protocols.push_back("tls");
if (routeProtocolBTCB->isChecked())
protocols.push_back("bittorrent");
CurrentRule.protocol = protocols;
statusLabel->setText(tr("Protocol list changed: ") + protocols.join(";"));
}
void RouteEditor::on_routeProtocolTLSCB_stateChanged(int arg1)
{
LOADINGCHECK
QStringList protocols;
if (arg1 == Qt::Checked)
protocols.push_back("tls");
if (routeProtocolHTTPCB->isChecked())
protocols.push_back("http");
if (routeProtocolBTCB->isChecked())
protocols.push_back("bittorrent");
CurrentRule.protocol = protocols;
statusLabel->setText(tr("Protocol list changed: ") + protocols.join(";"));
}
void RouteEditor::on_routeProtocolBTCB_stateChanged(int arg1)
{
LOADINGCHECK
QStringList protocols;
if (arg1 == Qt::Checked)
protocols.push_back("bittorrent");
if (routeProtocolHTTPCB->isChecked())
protocols.push_back("http");
if (routeProtocolTLSCB->isChecked())
protocols.push_back("tls");
CurrentRule.protocol = protocols;
statusLabel->setText(tr("Protocol list changed: ") + protocols.join(";"));
}
void RouteEditor::on_balancerAddBtn_clicked()
{
LOADINGCHECK
auto balancerTx = balancerSelectionCombo->currentText();
if (!balancerTx.isEmpty())
{
this->balancers[CurrentRule.balancerTag].append(balancerSelectionCombo->currentText());
balancerList->addItem(balancerTx);
balancerSelectionCombo->setEditText("");
statusLabel->setText(tr("OK"));
}
else
{
statusLabel->setText(tr("Balancer is empty, not processing."));
}
}
void RouteEditor::on_balancerDelBtn_clicked()
{
LOADINGCHECK
if (balancerList->currentRow() < 0)
{
return;
}
balancers[CurrentRule.balancerTag].removeAt(balancerList->currentRow());
balancerList->takeItem(balancerList->currentRow());
statusLabel->setText(tr("Removed a balancer entry."));
}
void RouteEditor::on_hostList_textChanged()
{
LOADINGCHECK
CurrentRule.domain = SplitLines(hostList->toPlainText());
}
void RouteEditor::on_ipList_textChanged()
{
LOADINGCHECK
CurrentRule.ip = SplitLines(ipList->toPlainText());
}
void RouteEditor::on_routePortTxt_textEdited(const QString &arg1)
{
LOADINGCHECK
CurrentRule.port = arg1;
}
void RouteEditor::on_routeUserTxt_textEdited(const QString &arg1)
{
LOADINGCHECK
CurrentRule.user = SplitLines(arg1);
}
void RouteEditor::on_addRouteBtn_clicked()
{
auto ruleName = AddNewRule();
Q_UNUSED(ruleName)
}
void RouteEditor::on_netBothRB_clicked()
{
LOADINGCHECK
CurrentRule.network = "tcp,udp";
}
void RouteEditor::on_netUDPRB_clicked()
{
LOADINGCHECK
CurrentRule.network = "udp";
}
void RouteEditor::on_netTCPRB_clicked()
{
LOADINGCHECK
CurrentRule.network = "tcp";
}
void RouteEditor::on_routeUserTxt_textChanged()
{
LOADINGCHECK
CurrentRule.user = SplitLines(routeUserTxt->toPlainText());
}
void RouteEditor::on_sourceIPList_textChanged()
{
LOADINGCHECK
CurrentRule.source = SplitLines(sourceIPList->toPlainText());
}
void RouteEditor::on_enableBalancerCB_stateChanged(int arg1)
{
LOADINGCHECK
auto useBalancer = arg1 == Qt::Checked;
CurrentRule.QV2RAY_RULE_USE_BALANCER = useBalancer;
balancersWidget->setEnabled(useBalancer);
if (CurrentRule.balancerTag.isEmpty())
{
LOG(MODULE_UI, "Creating a new balancer tag.")
CurrentRule.balancerTag = GenerateRandomString(6);
balancers[CurrentRule.balancerTag] = QStringList();
}
DEBUG(MODULE_UI, "Balancer: " + CurrentRule.balancerTag)
if (useBalancer)
{
LOG(MODULE_UI, "A rule has been set to use balancer, disconnect it to any outbound.")
auto ruleNode = ruleNodes[currentRuleTag];
for (auto &&[_, conn] : nodeScene->connections())
{
if (conn->getNode(PortType::Out)->id() == ruleNode)
{
nodeScene->deleteConnection(*conn);
// Since there should be only one connection from this rule node.
break;
}
}
}
else
{
QvMessageBoxWarn(this, tr("Route Editor"), tr("To make this rule ready to use, you need to connect it to an outbound node."));
}
}
void RouteEditor::on_addDefaultBtn_clicked() void RouteEditor::on_addDefaultBtn_clicked()
{ {
LOADINGCHECK LOADINGCHECK
@ -809,13 +551,7 @@ void RouteEditor::on_addOutboundBtn_clicked()
CHECKEMPTYRULES CHECKEMPTYRULES
} }
void RouteEditor::on_ruleEnableCB_stateChanged(int arg1)
{
bool _isEnabled = arg1 == Qt::Checked;
CurrentRule.QV2RAY_RULE_ENABLED = _isEnabled;
routeEditGroupBox->setEnabled(_isEnabled);
routeRuleGroupBox->setEnabled(_isEnabled);
}
void RouteEditor::on_delBtn_clicked() void RouteEditor::on_delBtn_clicked()
{ {
if (nodeScene->selectedNodes().empty()) if (nodeScene->selectedNodes().empty())
@ -834,57 +570,57 @@ void RouteEditor::on_delBtn_clicked()
// the node container. // the node container.
if (isInbound) if (isInbound)
{ {
currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), InboundNode)->GetInbound(); // currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), InboundNode)->GetInbound();
nodeScene->removeNode(*nodeScene->node(inboundNodes[currentInboundOutboundTag])); // nodeScene->removeNode(*nodeScene->node(inboundNodes[currentInboundOutboundTag]));
inboundNodes.remove(currentInboundOutboundTag); // inboundNodes.remove(currentInboundOutboundTag);
//
// Remove corresponded inbound tags from the rules. // // Remove corresponded inbound tags from the rules.
for (auto k : rules.keys()) // for (auto k : rules.keys())
{ // {
auto v = rules[k]; // auto v = rules[k];
v.inboundTag.removeAll(currentInboundOutboundTag); // v.inboundTag.removeAll(currentInboundOutboundTag);
rules[k] = v; // rules[k] = v;
} // }
//
inbounds.remove(currentInboundOutboundTag); // inbounds.remove(currentInboundOutboundTag);
} }
else if (isOutbound) else if (isOutbound)
{ {
currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), OutboundNode)->GetOutbound(); // currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), OutboundNode)->GetOutbound();
outbounds.remove(currentInboundOutboundTag); // outbounds.remove(currentInboundOutboundTag);
ResolveDefaultOutboundTag(currentInboundOutboundTag, ""); // ResolveDefaultOutboundTag(currentInboundOutboundTag, "");
//
// Remove corresponded outbound tags from the rules. //// Remove corresponded outbound tags from the rules.
for (auto k : rules.keys()) // for (auto k : rules.keys())
{ //{
auto v = rules[k]; // auto v = rules[k];
//
if (v.outboundTag == currentInboundOutboundTag) // if (v.outboundTag == currentInboundOutboundTag)
v.outboundTag.clear(); // v.outboundTag.clear();
//
rules[k] = v; // rules[k] = v;
} //}
//
nodeScene->removeNode(*nodeScene->node(outboundNodes[currentInboundOutboundTag])); // nodeScene->removeNode(*nodeScene->node(outboundNodes[currentInboundOutboundTag]));
outboundNodes.remove(currentInboundOutboundTag); // outboundNodes.remove(currentInboundOutboundTag);
} }
else if (isRule) else if (isRule)
{ {
ruleEnableCB->setEnabled(false); // ruleEnableCB->setEnabled(false);
ruleTagLineEdit->setEnabled(false); // ruleTagLineEdit->setEnabled(false);
ruleRenameBtn->setEnabled(false); // ruleRenameBtn->setEnabled(false);
auto RuleTag = GetFirstNodeData(firstNode->id(), RuleNode)->GetRuleTag(); // auto RuleTag = GetFirstNodeData(firstNode->id(), RuleNode)->GetRuleTag();
currentRuleTag.clear(); // currentRuleTag.clear();
routeRuleGroupBox->setEnabled(false); // routeRuleGroupBox->setEnabled(false);
routeEditGroupBox->setEnabled(false); // routeEditGroupBox->setEnabled(false);
rules.remove(RuleTag); // rules.remove(RuleTag);
nodeScene->removeNode(*nodeScene->node(ruleNodes[RuleTag])); // nodeScene->removeNode(*nodeScene->node(ruleNodes[RuleTag]));
ruleNodes.remove(RuleTag); // ruleNodes.remove(RuleTag);
// ////
// Remove item from the rule order list widget. //// Remove item from the rule order list widget.
ruleListWidget->takeItem(ruleListWidget->row(ruleListWidget->findItems(RuleTag, Qt::MatchExactly).first())); // ruleListWidget->takeItem(ruleListWidget->row(ruleListWidget->findItems(RuleTag, Qt::MatchExactly).first()));
CHECKEMPTYRULES // CHECKEMPTYRULES
// currentRuleTag = rules.firstKey(); //// currentRuleTag = rules.firstKey();
// ShowCurrentRuleDetail(); // ShowCurrentRuleDetail();
} }
else else
@ -893,6 +629,11 @@ void RouteEditor::on_delBtn_clicked()
QvMessageBoxWarn(this, tr("Error"), tr("Qv2ray entered an unknown state.")); QvMessageBoxWarn(this, tr("Error"), tr("Qv2ray entered an unknown state."));
} }
} }
void RouteEditor::on_addRouteBtn_clicked()
{
auto ruleName = AddNewRule();
Q_UNUSED(ruleName)
}
void RouteEditor::on_editBtn_clicked() void RouteEditor::on_editBtn_clicked()
{ {
if (nodeScene->selectedNodes().empty()) if (nodeScene->selectedNodes().empty())
@ -907,117 +648,117 @@ void RouteEditor::on_editBtn_clicked()
if (isInbound) if (isInbound)
{ {
currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), InboundNode)->GetInbound(); // currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), InboundNode)->GetInbound();
//
if (!inbounds.contains(currentInboundOutboundTag)) // if (!inbounds.contains(currentInboundOutboundTag))
{ // {
QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag); // QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag);
return; // return;
} // }
//
auto _in = inbounds[currentInboundOutboundTag]; // auto _in = inbounds[currentInboundOutboundTag];
INBOUND _result; // INBOUND _result;
auto protocol = _in["protocol"].toString(); // auto protocol = _in["protocol"].toString();
int _code; // int _code;
//
if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") // if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door")
{ // {
QvMessageBoxWarn(this, tr("Cannot Edit"), // QvMessageBoxWarn(this, tr("Cannot Edit"),
tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" + // tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" +
tr("We will launch Json Editor instead.")); // tr("We will launch Json Editor instead."));
statusLabel->setText(tr("Opening JSON editor")); // statusLabel->setText(tr("Opening JSON editor"));
JsonEditor w(_in, this); // JsonEditor w(_in, this);
_result = INBOUND(w.OpenEditor()); // _result = INBOUND(w.OpenEditor());
_code = w.result(); // _code = w.result();
} // }
else // else
{ // {
InboundEditor w(_in, this); // InboundEditor w(_in, this);
statusLabel->setText(tr("Opening default inbound editor")); // statusLabel->setText(tr("Opening default inbound editor"));
_result = w.OpenEditor(); // _result = w.OpenEditor();
_code = w.result(); // _code = w.result();
} // }
//
statusLabel->setText(tr("OK")); // statusLabel->setText(tr("OK"));
//
if (_code == QDialog::Accepted) // if (_code == QDialog::Accepted)
{ // {
bool isTagChanged = getTag(_in) != getTag(_result); // bool isTagChanged = getTag(_in) != getTag(_result);
//
if (isTagChanged) // if (isTagChanged)
{ // {
auto newTag = getTag(_result); // auto newTag = getTag(_result);
RenameItemTag(RENAME_INBOUND, getTag(_in), &newTag); // RenameItemTag(RENAME_INBOUND, getTag(_in), &newTag);
} // }
//
DEBUG(MODULE_UI, "Removed old tag: " + getTag(_in)) // DEBUG(MODULE_UI, "Removed old tag: " + getTag(_in))
inbounds.remove(getTag(_in)); // inbounds.remove(getTag(_in));
DEBUG(MODULE_UI, "Adding new tag: " + getTag(_result)) // DEBUG(MODULE_UI, "Adding new tag: " + getTag(_result))
inbounds.insert(getTag(_result), _result); // inbounds.insert(getTag(_result), _result);
} // }
} }
else if (isOutbound) else if (isOutbound)
{ {
currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), OutboundNode)->GetOutbound(); // currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), OutboundNode)->GetOutbound();
//
if (!outbounds.contains(currentInboundOutboundTag)) // if (!outbounds.contains(currentInboundOutboundTag))
{ //{
QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag); // QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag);
return; // return;
} //}
//
OUTBOUND _result; // OUTBOUND _result;
auto _out = outbounds.value(currentInboundOutboundTag); // auto _out = outbounds.value(currentInboundOutboundTag);
auto protocol = _out["protocol"].toString().toLower(); // auto protocol = _out["protocol"].toString().toLower();
int _code; // int _code;
//
bool guisupport = true; // bool guisupport = true;
if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks" && protocol != "http") // if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks" && protocol != "http")
{ //{
guisupport = false; // guisupport = false;
auto pluginEditorWidgetsInfo = PluginHost->GetOutboundEditorWidgets(); // auto pluginEditorWidgetsInfo = PluginHost->GetOutboundEditorWidgets();
for (const auto &plugin : pluginEditorWidgetsInfo) // for (const auto &plugin : pluginEditorWidgetsInfo)
{ // {
for (const auto &_d : plugin->OutboundCapabilities()) // for (const auto &_d : plugin->OutboundCapabilities())
{ // {
guisupport = guisupport || protocol == _d.protocol; // guisupport = guisupport || protocol == _d.protocol;
} // }
} // }
} //}
//
if (!guisupport) // if (!guisupport)
{ //{
QvMessageBoxWarn(this, tr("Unsupported Outbound Type"), // QvMessageBoxWarn(this, tr("Unsupported Outbound Type"),
tr("This outbound entry is not supported by the GUI editor.") + NEWLINE + // tr("This outbound entry is not supported by the GUI editor.") + NEWLINE +
tr("We will launch Json Editor instead.")); // tr("We will launch Json Editor instead."));
JsonEditor w(_out, this); // JsonEditor w(_out, this);
statusLabel->setText(tr("Opening JSON editor")); // statusLabel->setText(tr("Opening JSON editor"));
_result = OUTBOUND(w.OpenEditor()); // _result = OUTBOUND(w.OpenEditor());
_code = w.result(); // _code = w.result();
} //}
else // else
{ //{
OutboundEditor w(_out, this); // OutboundEditor w(_out, this);
statusLabel->setText(tr("Opening default outbound editor.")); // statusLabel->setText(tr("Opening default outbound editor."));
_result = w.OpenEditor(); // _result = w.OpenEditor();
_code = w.result(); // _code = w.result();
} //}
//
if (_code == QDialog::Accepted) // if (_code == QDialog::Accepted)
{ //{
bool isTagChanged = getTag(_out) != getTag(_result); // bool isTagChanged = getTag(_out) != getTag(_result);
//
if (isTagChanged) // if (isTagChanged)
{ // {
auto newTag = getTag(_result); // auto newTag = getTag(_result);
DEBUG(MODULE_UI, "Outbound tag is changed: " + newTag) // DEBUG(MODULE_UI, "Outbound tag is changed: " + newTag)
RenameItemTag(RENAME_OUTBOUND, getTag(_out), &newTag); // RenameItemTag(RENAME_OUTBOUND, getTag(_out), &newTag);
} // }
//
DEBUG(MODULE_UI, "Adding new tag: " + getTag(_result)) // DEBUG(MODULE_UI, "Adding new tag: " + getTag(_result))
outbounds.insert(getTag(_result), _result); // outbounds.insert(getTag(_result), _result);
statusLabel->setText(tr("OK")); // statusLabel->setText(tr("OK"));
} //}
} }
else else
{ {
@ -1031,31 +772,6 @@ void RouteEditor::on_domainStrategyCombo_currentIndexChanged(const QString &arg1
domainStrategy = arg1; domainStrategy = arg1;
} }
void RouteEditor::on_ruleRenameBtn_clicked()
{
auto newTag = ruleTagLineEdit->text();
if (newTag.isEmpty())
{
LOG(MODULE_UI, "Tag is empty, this is ILLEGAL!")
QvMessageBoxWarn(this, tr("Renaming a tag"), tr("New tag is empty, please try another."));
}
else if (newTag == CurrentRule.QV2RAY_RULE_TAG)
{
LOG(MODULE_UI, "No tag changed, returning.")
QvMessageBoxInfo(this, tr("Renaming a tag"), tr("New tag is the same as the original one."));
}
else if (rules.contains(newTag))
{
LOG(MODULE_UI, "Tag duplicate detected.")
QvMessageBoxWarn(this, tr("Renaming a tag"), tr("Duplicate rule tag detected, please try another."));
}
else
{
RenameItemTag(RENAME_RULE, CurrentRule.QV2RAY_RULE_TAG, &newTag);
}
}
void RouteEditor::on_defaultOutboundCombo_currentTextChanged(const QString &arg1) void RouteEditor::on_defaultOutboundCombo_currentTextChanged(const QString &arg1)
{ {
LOADINGCHECK LOADINGCHECK

View File

@ -36,68 +36,30 @@ class RouteEditor
void processCommands(QString, QStringList, QMap<QString, QString>) override{}; void processCommands(QString, QStringList, QMap<QString, QString>) override{};
private: private:
void updateColorScheme() override{}; void updateColorScheme() override
{
// Setup icons according to the theme settings.
addInboundBtn->setIcon(QICON_R("add.png"));
addOutboundBtn->setIcon(QICON_R("add.png"));
editBtn->setIcon(QICON_R("edit.png"));
addRouteBtn->setIcon(QICON_R("add.png"));
delBtn->setIcon(QICON_R("delete.png"));
};
QvMessageBusSlotDecl; QvMessageBusSlotDecl;
private slots: private slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
void on_insertDirectBtn_clicked(); void on_insertDirectBtn_clicked();
void on_routeProtocolHTTPCB_stateChanged(int arg1);
void on_routeProtocolTLSCB_stateChanged(int arg1);
void on_routeProtocolBTCB_stateChanged(int arg1);
void on_balancerAddBtn_clicked();
void on_balancerDelBtn_clicked();
void on_hostList_textChanged();
void on_ipList_textChanged();
void on_routePortTxt_textEdited(const QString &arg1);
void on_routeUserTxt_textEdited(const QString &arg1);
void on_addRouteBtn_clicked(); void on_addRouteBtn_clicked();
void on_netBothRB_clicked();
void on_netUDPRB_clicked();
void on_netTCPRB_clicked();
void on_routeUserTxt_textChanged();
void on_sourceIPList_textChanged();
void on_enableBalancerCB_stateChanged(int arg1);
void on_addDefaultBtn_clicked(); void on_addDefaultBtn_clicked();
void on_insertBlackBtn_clicked(); void on_insertBlackBtn_clicked();
void on_addInboundBtn_clicked(); void on_addInboundBtn_clicked();
void on_addOutboundBtn_clicked(); void on_addOutboundBtn_clicked();
void on_ruleEnableCB_stateChanged(int arg1);
void on_delBtn_clicked(); void on_delBtn_clicked();
void on_editBtn_clicked(); void on_editBtn_clicked();
void on_domainStrategyCombo_currentIndexChanged(const QString &arg1); void on_domainStrategyCombo_currentIndexChanged(const QString &arg1);
void on_ruleRenameBtn_clicked();
void on_defaultOutboundCombo_currentTextChanged(const QString &arg1); void on_defaultOutboundCombo_currentTextChanged(const QString &arg1);
void on_importExistingBtn_clicked(); void on_importExistingBtn_clicked();
void on_importGroupBtn_currentIndexChanged(int index); void on_importGroupBtn_currentIndexChanged(int index);
public slots: public slots:
@ -108,17 +70,16 @@ class RouteEditor
private: private:
bool isLoading = false; bool isLoading = false;
void RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, QString *newTag); void RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, QString *newTag);
void ShowCurrentRuleDetail();
// //
QString currentRuleTag; // QString currentRuleTag;
QString currentInboundOutboundTag; QString currentInboundOutboundTag;
QMap<QString, QStringList> balancers; // QMap<QString, QStringList> balancers;
QString domainStrategy; QString domainStrategy;
QString defaultOutbound; QString defaultOutbound;
// //
QMap<QString, INBOUND> inbounds; QList<INBOUND> inbounds;
QMap<QString, OUTBOUND> outbounds; QList<OUTBOUND> outbounds;
QMap<QString, RuleObject> rules; QList<RuleObject> rules;
// //
CONFIGROOT root; CONFIGROOT root;
CONFIGROOT original; CONFIGROOT original;

View File

@ -297,7 +297,7 @@
<item row="1" column="1"> <item row="1" column="1">
<widget class="QToolBox" name="toolBox"> <widget class="QToolBox" name="toolBox">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="page_2"> <widget class="QWidget" name="page_2">
<property name="geometry"> <property name="geometry">
@ -305,7 +305,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>359</width> <width>359</width>
<height>505</height> <height>536</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
@ -401,275 +401,6 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="page">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>347</width>
<height>704</height>
</rect>
</property>
<attribute name="label">
<string>Rule Settings</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Rule Status</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="ruleEnableCB">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Enabled</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Rule Tag</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLineEdit" name="ruleTagLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ruleRenameBtn">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Rename</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="routeEditGroupBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Route Editor</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<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">
<widget class="QCheckBox" name="enableBalancerCB">
<property name="text">
<string>Use Balancers</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QWidget" name="balancersWidget" native="true">
<layout class="QGridLayout" name="balancerLayout">
<item row="0" column="0">
<widget class="QComboBox" name="balancerSelectionCombo">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2">
<widget class="QListWidget" name="balancerList"/>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="balancerDelBtn">
<property name="text">
<string>...</string>
</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="balancerAddBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="routeRuleGroupBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Route Detail Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Users List</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Source IP Matches</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPlainTextEdit" name="routeUserTxt"/>
</item>
<item row="1" column="1">
<widget class="QPlainTextEdit" name="sourceIPList"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Target Domain List</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Target IP List</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPlainTextEdit" name="hostList"/>
</item>
<item row="3" column="1">
<widget class="QPlainTextEdit" name="ipList"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
<item row="2" column="0" colspan="2"> <item row="2" column="0" colspan="2">
@ -715,25 +446,6 @@
<tabstop>domainStrategyCombo</tabstop> <tabstop>domainStrategyCombo</tabstop>
<tabstop>defaultOutboundCombo</tabstop> <tabstop>defaultOutboundCombo</tabstop>
<tabstop>ruleListWidget</tabstop> <tabstop>ruleListWidget</tabstop>
<tabstop>ruleEnableCB</tabstop>
<tabstop>ruleTagLineEdit</tabstop>
<tabstop>ruleRenameBtn</tabstop>
<tabstop>netTCPRB</tabstop>
<tabstop>netUDPRB</tabstop>
<tabstop>netBothRB</tabstop>
<tabstop>routeProtocolHTTPCB</tabstop>
<tabstop>routeProtocolTLSCB</tabstop>
<tabstop>routeProtocolBTCB</tabstop>
<tabstop>routePortTxt</tabstop>
<tabstop>enableBalancerCB</tabstop>
<tabstop>balancerSelectionCombo</tabstop>
<tabstop>balancerAddBtn</tabstop>
<tabstop>balancerList</tabstop>
<tabstop>balancerDelBtn</tabstop>
<tabstop>routeUserTxt</tabstop>
<tabstop>sourceIPList</tabstop>
<tabstop>ipList</tabstop>
<tabstop>hostList</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections> <connections>

View File

@ -1,10 +1,11 @@
#include <nodes/internal/FlowScene.hpp>
#include "core/CoreUtils.hpp" #include "core/CoreUtils.hpp"
#include "ui/common/UIBase.hpp" #include "ui/common/UIBase.hpp"
#include "ui/models/InboundNodeModel.hpp" #include "ui/models/InboundNodeModel.hpp"
#include "ui/models/OutboundNodeModel.hpp" #include "ui/models/OutboundNodeModel.hpp"
#include "ui/models/RuleNodeModel.hpp" #include "ui/models/RuleNodeModel.hpp"
#include "w_RoutesEditor.hpp" #include "w_RoutesEditor.hpp"
#include <nodes/internal/FlowScene.hpp>
// Supplementary source file for Routes editor, basically providing // Supplementary source file for Routes editor, basically providing
// routes-related operations. // routes-related operations.
@ -12,40 +13,36 @@ void RouteEditor::AddInbound(INBOUND in)
{ {
QString tag = getTag(in); QString tag = getTag(in);
if (inbounds.contains(tag)) if (inboundNodes.contains(tag))
{ tag.append("_" + GenerateRandomString(5));
tag = tag + "_" + GenerateRandomString(5);
}
in["tag"] = tag; in["tag"] = tag;
auto _nodeData = std::make_unique<QvInboundNodeModel>(std::make_shared<InboundNodeData>(tag)); inbounds << in;
auto _nodeData = std::make_unique<QvInboundNodeModel>(std::make_shared<InboundNodeData>(std::make_shared<INBOUND>(inbounds.last())));
auto &node = nodeScene->createNode(std::move(_nodeData)); auto &node = nodeScene->createNode(std::move(_nodeData));
QPointF pos; QPointF pos;
pos.setX(0 + GRAPH_GLOBAL_OFFSET_X); pos.setX(0 + GRAPH_GLOBAL_OFFSET_X);
pos.setY(inboundNodes.count() * 130 + GRAPH_GLOBAL_OFFSET_Y); pos.setY(inboundNodes.count() * 130 + GRAPH_GLOBAL_OFFSET_Y);
nodeScene->setNodePosition(node, pos); nodeScene->setNodePosition(node, pos);
inboundNodes.insert(tag, node.id()); inboundNodes.insert(tag, node.id());
inbounds.insert(getTag(in), in);
} }
void RouteEditor::AddOutbound(OUTBOUND out) void RouteEditor::AddOutbound(OUTBOUND out)
{ {
QString tag = getTag(out); QString tag = getTag(out);
if (outbounds.contains(tag)) if (outboundNodes.contains(tag))
{ tag.append("_" + GenerateRandomString(5));
tag = tag + "_" + GenerateRandomString(5);
}
out["tag"] = tag; out["tag"] = tag;
auto _nodeData = std::make_unique<QvOutboundNodeModel>(std::make_shared<OutboundNodeData>(tag)); outbounds << out;
auto _nodeData = std::make_unique<QvOutboundNodeModel>(std::make_shared<OutboundNodeData>(std::make_shared<OUTBOUND>(outbounds.last())));
auto pos = nodeGraphWidget->pos(); auto pos = nodeGraphWidget->pos();
pos.setX(pos.x() + 850 + GRAPH_GLOBAL_OFFSET_X); pos.setX(pos.x() + 850 + GRAPH_GLOBAL_OFFSET_X);
pos.setY(pos.y() + outboundNodes.count() * 120 + GRAPH_GLOBAL_OFFSET_Y); pos.setY(pos.y() + outboundNodes.count() * 120 + GRAPH_GLOBAL_OFFSET_Y);
auto &node = nodeScene->createNode(std::move(_nodeData)); auto &node = nodeScene->createNode(std::move(_nodeData));
nodeScene->setNodePosition(node, pos); nodeScene->setNodePosition(node, pos);
outboundNodes.insert(tag, node.id()); outboundNodes.insert(tag, node.id());
outbounds.insert(tag, out);
defaultOutboundCombo->addItem(tag); defaultOutboundCombo->addItem(tag);
} }
@ -60,7 +57,7 @@ QString RouteEditor::AddNewRule()
auto bTag = GenerateRandomString(); auto bTag = GenerateRandomString();
rule.QV2RAY_RULE_TAG = rules.isEmpty() ? tr("Default rule") : (tr("rule") + "-" + GenerateRandomString(6)); rule.QV2RAY_RULE_TAG = rules.isEmpty() ? tr("Default rule") : (tr("rule") + "-" + GenerateRandomString(6));
rule.balancerTag = bTag; rule.balancerTag = bTag;
balancers[bTag] = QStringList(); // balancers[bTag] = QStringList();
AddRule(rule); AddRule(rule);
return rule.QV2RAY_RULE_TAG; return rule.QV2RAY_RULE_TAG;
} }
@ -73,11 +70,11 @@ void RouteEditor::AddRule(RuleObject rule)
rule.QV2RAY_RULE_TAG += "-" + GenerateRandomString(5); rule.QV2RAY_RULE_TAG += "-" + GenerateRandomString(5);
} }
rules.insert(rule.QV2RAY_RULE_TAG, rule); rules << rule;
auto pos = nodeGraphWidget->pos(); auto pos = nodeGraphWidget->pos();
pos.setX(pos.x() + 350 + GRAPH_GLOBAL_OFFSET_X); pos.setX(pos.x() + 350 + GRAPH_GLOBAL_OFFSET_X);
pos.setY(pos.y() + ruleNodes.count() * 120 + GRAPH_GLOBAL_OFFSET_Y); pos.setY(pos.y() + ruleNodes.count() * 120 + GRAPH_GLOBAL_OFFSET_Y);
auto _nodeData = std::make_unique<QvRuleNodeModel>(std::make_shared<RuleNodeData>(rule.QV2RAY_RULE_TAG)); auto _nodeData = std::make_unique<QvRuleNodeModel>(std::make_shared<RuleNodeData>(std::make_shared<RuleObject>(rules.last())));
auto &node = nodeScene->createNode(std::move(_nodeData)); auto &node = nodeScene->createNode(std::move(_nodeData));
nodeScene->setNodePosition(node, pos); nodeScene->setNodePosition(node, pos);
@ -121,6 +118,7 @@ void RouteEditor::AddRule(RuleObject rule)
// Do not use reference here, we need deep copy of EVERY QString. // Do not use reference here, we need deep copy of EVERY QString.
void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, QString *newTag) void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, QString *newTag)
{ {
/*
switch (mode) switch (mode)
{ {
case RENAME_RULE: case RENAME_RULE:
@ -158,11 +156,11 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag,
{ {
items.first()->setText(*newTag); items.first()->setText(*newTag);
} }
abort();
if (currentRuleTag == originalTag) // if (currentRuleTag == originalTag)
{ // {
currentRuleTag = *newTag; // currentRuleTag = *newTag;
} // }
} }
else else
{ {
@ -261,7 +259,7 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag,
} }
break; break;
} }*/
} }
// Do not use const reference here. // Do not use const reference here.
@ -272,7 +270,9 @@ void RouteEditor::ResolveDefaultOutboundTag(const QString original, const QStrin
// //
isLoading = true; isLoading = true;
defaultOutboundCombo->clear(); defaultOutboundCombo->clear();
defaultOutboundCombo->addItems(outbounds.keys()); //
for (const auto &out : outbounds) defaultOutboundCombo->addItem(getTag(out));
//
isLoading = false; isLoading = false;
// //
if (!isDefaultChanged) if (!isDefaultChanged)
@ -293,7 +293,7 @@ void RouteEditor::ResolveDefaultOutboundTag(const QString original, const QStrin
else else
{ {
defaultOutbound = getTag(outbounds.first()); defaultOutbound = getTag(outbounds.first());
defaultOutboundCombo->addItem(outbounds.firstKey()); defaultOutboundCombo->addItem(getTag(outbounds.first()));
} }
} }
else else

View File

@ -3,13 +3,7 @@
QvInboundNodeModel::QvInboundNodeModel(std::shared_ptr<InboundNodeData> data) : NodeDataModel() QvInboundNodeModel::QvInboundNodeModel(std::shared_ptr<InboundNodeData> data) : NodeDataModel()
{ {
_in = data; _in = data;
_label = new QLabel(); widget = new InboundOutboundWidget();
// widget->setWindowFlags(Qt::FramelessWindowHint);
QFont font = _label->font(); widget->setAttribute(Qt::WA_TranslucentBackground);
font.setPointSize(font.pointSize() + GRAPH_NODE_LABEL_FONTSIZE_INCREMENT);
_label->setFont(font);
//
_label->setText(data->GetInbound());
_label->setWindowFlags(Qt::FramelessWindowHint);
_label->setAttribute(Qt::WA_TranslucentBackground);
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "NodeModelsBase.hpp" #include "NodeModelsBase.hpp"
#include "ui/widgets/node/InboundOutboundWidget.hpp"
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
@ -9,12 +10,7 @@ class QvInboundNodeModel : public NodeDataModel
Q_OBJECT Q_OBJECT
public: public:
explicit QvInboundNodeModel(std::shared_ptr<InboundNodeData> data); explicit QvInboundNodeModel(std::shared_ptr<InboundNodeData> data);
~QvInboundNodeModel() ~QvInboundNodeModel(){};
{
// if (_label) {
// delete _label;
//}
}
QString caption() const override QString caption() const override
{ {
@ -40,7 +36,7 @@ class QvInboundNodeModel : public NodeDataModel
{ {
Q_UNUSED(portType) Q_UNUSED(portType)
Q_UNUSED(portIndex) Q_UNUSED(portIndex)
return inboundType; return NODE_TYPE_INBOUND;
} }
std::shared_ptr<NodeData> outData(PortIndex) override std::shared_ptr<NodeData> outData(PortIndex) override
@ -48,19 +44,17 @@ class QvInboundNodeModel : public NodeDataModel
return _in; return _in;
} }
void setInData(std::shared_ptr<NodeData>, int) override void setInData(std::shared_ptr<NodeData>, int) override{};
{
} void setData(std::shared_ptr<INBOUND> data)
void setData(const QString &data)
{ {
_in = std::make_shared<InboundNodeData>(data); _in = std::make_shared<InboundNodeData>(data);
_label->setText(data); widget->adjustSize();
_label->adjustSize();
} }
QWidget *embeddedWidget() override QWidget *embeddedWidget() override
{ {
return _label; return widget;
} }
std::unique_ptr<NodeDataModel> clone() const override std::unique_ptr<NodeDataModel> clone() const override
{ {
@ -72,5 +66,5 @@ class QvInboundNodeModel : public NodeDataModel
QString modelValidationError = tr("Missing or incorrect inputs"); QString modelValidationError = tr("Missing or incorrect inputs");
// //
std::shared_ptr<InboundNodeData> _in; std::shared_ptr<InboundNodeData> _in;
QLabel *_label; InboundOutboundWidget *widget;
}; };

View File

@ -1,11 +1,12 @@
#pragma once #pragma once
#include <nodes/internal/NodeDataModel.hpp> #include "base/Qv2rayBase.hpp"
#include <nodes/internal/PortType.hpp>
#include "common/QvHelpers.hpp" #include "common/QvHelpers.hpp"
#include <QLabel> #include <QLabel>
#include <memory> #include <memory>
#include <nodes/internal/NodeDataModel.hpp>
#include <nodes/internal/PortType.hpp>
using QtNodes::NodeData; using QtNodes::NodeData;
using QtNodes::NodeDataModel; using QtNodes::NodeDataModel;
@ -17,79 +18,69 @@ using QtNodes::PortType;
using QtNodes::NodeData; using QtNodes::NodeData;
using QtNodes::NodeDataType; using QtNodes::NodeDataType;
const int GRAPH_NODE_LABEL_FONTSIZE_INCREMENT = 3; constexpr auto GRAPH_NODE_LABEL_FONTSIZE_INCREMENT = 3;
namespace Qv2ray::ui::nodemodels namespace Qv2ray::ui::nodemodels
{ {
const std::shared_ptr<NodeDataType> outboundType = std::make_shared<NodeDataType>("outbound", QObject::tr("Outbound")); const std::shared_ptr<NodeDataType> NODE_TYPE_OUTBOUND = std::make_shared<NodeDataType>("outbound", QObject::tr("Outbound"));
const std::shared_ptr<NodeDataType> inboundType = std::make_shared<NodeDataType>("inbound", QObject::tr("Inbound")); const std::shared_ptr<NodeDataType> NODE_TYPE_INBOUND = std::make_shared<NodeDataType>("inbound", QObject::tr("Inbound"));
/// The class can potentially incapsulate any user data
/// need to be transferred within the Node Editor graph
class InboundNodeData : public NodeData class InboundNodeData : public NodeData
{ {
public: public:
explicit InboundNodeData(QString in) : _inboundTag(in) explicit InboundNodeData(std::shared_ptr<INBOUND> data) : inboundData(data){};
{
}
std::shared_ptr<NodeDataType> type() const override std::shared_ptr<NodeDataType> type() const override
{ {
return inboundType; return NODE_TYPE_INBOUND;
} }
QString GetInbound() std::shared_ptr<INBOUND> GetInbound()
{ {
return _inboundTag; return inboundData;
} }
private: private:
QString _inboundTag; std::shared_ptr<INBOUND> inboundData;
}; };
/// The class can potentially incapsulate any user data
/// need to be transferred within the Node Editor graph
class OutboundNodeData : public NodeData class OutboundNodeData : public NodeData
{ {
public: public:
explicit OutboundNodeData(QString out) : _outboundTag(out) explicit OutboundNodeData(std::shared_ptr<OUTBOUND> data) : outboundData(data){};
{
}
std::shared_ptr<NodeDataType> type() const override std::shared_ptr<NodeDataType> type() const override
{ {
return outboundType; return NODE_TYPE_INBOUND;
} }
QString GetOutbound() std::shared_ptr<OUTBOUND> GetOutbound()
{ {
return _outboundTag; return outboundData;
} }
private: private:
QString _outboundTag; std::shared_ptr<OUTBOUND> outboundData;
}; };
/// The class can potentially incapsulate any user data
/// need to be transferred within the Node Editor graph
class RuleNodeData : public NodeData class RuleNodeData : public NodeData
{ {
public: public:
explicit RuleNodeData(QString out) : _ruleTag(out) explicit RuleNodeData(std::shared_ptr<RuleObject> rule) : _rule(rule){};
{
}
std::shared_ptr<NodeDataType> type() const override std::shared_ptr<NodeDataType> type() const override
{ {
return outboundType; return NODE_TYPE_INBOUND;
} }
QString GetRuleTag() std::shared_ptr<RuleObject> GetRule()
{ {
return _ruleTag; return _rule;
} }
private: private:
QString _ruleTag; std::shared_ptr<RuleObject> _rule;
}; };
} // namespace Qv2ray::ui::nodemodels } // namespace Qv2ray::ui::nodemodels

View File

@ -3,13 +3,7 @@
QvOutboundNodeModel::QvOutboundNodeModel(std::shared_ptr<OutboundNodeData> data) : NodeDataModel() QvOutboundNodeModel::QvOutboundNodeModel(std::shared_ptr<OutboundNodeData> data) : NodeDataModel()
{ {
_out = data; _out = data;
_label = new QLabel(); widget = new InboundOutboundWidget();
// widget->setWindowFlags(Qt::FramelessWindowHint);
QFont font = _label->font(); widget->setAttribute(Qt::WA_TranslucentBackground);
font.setPointSize(font.pointSize() + GRAPH_NODE_LABEL_FONTSIZE_INCREMENT);
_label->setFont(font);
//
_label->setText(data->GetOutbound());
_label->setWindowFlags(Qt::FramelessWindowHint);
_label->setAttribute(Qt::WA_TranslucentBackground);
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ui/models/NodeModelsBase.hpp" #include "ui/models/NodeModelsBase.hpp"
#include "ui/widgets/node/InboundOutboundWidget.hpp"
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
@ -8,12 +9,9 @@ class QvOutboundNodeModel : public NodeDataModel
Q_OBJECT Q_OBJECT
public: public:
explicit QvOutboundNodeModel(std::shared_ptr<OutboundNodeData> data); explicit QvOutboundNodeModel(std::shared_ptr<OutboundNodeData> data);
~QvOutboundNodeModel() ~QvOutboundNodeModel(){};
{ void setInData(std::shared_ptr<NodeData>, int) override{};
// if (_label) { void setInData(std::vector<std::shared_ptr<NodeData>>, int) override{};
// delete _label;
//}
}
QString caption() const override QString caption() const override
{ {
@ -39,7 +37,7 @@ class QvOutboundNodeModel : public NodeDataModel
{ {
Q_UNUSED(portType) Q_UNUSED(portType)
Q_UNUSED(portIndex) Q_UNUSED(portIndex)
return outboundType; return NODE_TYPE_OUTBOUND;
} }
std::shared_ptr<NodeData> outData(PortIndex) override std::shared_ptr<NodeData> outData(PortIndex) override
@ -47,23 +45,15 @@ class QvOutboundNodeModel : public NodeDataModel
return _out; return _out;
} }
void setInData(std::shared_ptr<NodeData>, int) override void setData(std::shared_ptr<OUTBOUND> data)
{
}
void setInData(std::vector<std::shared_ptr<NodeData>>, int) override
{
}
void setData(const QString &data)
{ {
_out = std::make_shared<OutboundNodeData>(data); _out = std::make_shared<OutboundNodeData>(data);
_label->setText(_out->GetOutbound()); widget->adjustSize();
_label->adjustSize();
} }
QWidget *embeddedWidget() override QWidget *embeddedWidget() override
{ {
return _label; return nullptr;
} }
ConnectionPolicy portInConnectionPolicy(PortIndex) const override ConnectionPolicy portInConnectionPolicy(PortIndex) const override
@ -80,5 +70,5 @@ class QvOutboundNodeModel : public NodeDataModel
QString modelValidationError = tr("Missing or incorrect inputs"); QString modelValidationError = tr("Missing or incorrect inputs");
// //
std::shared_ptr<OutboundNodeData> _out; std::shared_ptr<OutboundNodeData> _out;
QLabel *_label; InboundOutboundWidget *widget;
}; };

View File

@ -3,14 +3,7 @@
QvRuleNodeModel::QvRuleNodeModel(std::shared_ptr<RuleNodeData> data) : NodeDataModel() QvRuleNodeModel::QvRuleNodeModel(std::shared_ptr<RuleNodeData> data) : NodeDataModel()
{ {
_ruleTag = data; _ruleTag = data;
_label = new QLabel(); ruleWidget = new QvNodeRuleWidget();
// ruleWidget->setWindowFlags(Qt::FramelessWindowHint);
QFont font = _label->font(); ruleWidget->setAttribute(Qt::WA_TranslucentBackground);
font.setPointSize(font.pointSize() + GRAPH_NODE_LABEL_FONTSIZE_INCREMENT);
font.setBold(true);
_label->setFont(font);
//
_label->setText(data->GetRuleTag());
_label->setWindowFlags(Qt::FramelessWindowHint);
_label->setAttribute(Qt::WA_TranslucentBackground);
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "ui/models/NodeModelsBase.hpp" #include "ui/models/NodeModelsBase.hpp"
#include "ui/widgets/node/RuleWidget.hpp"
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
@ -9,12 +10,7 @@ class QvRuleNodeModel : public NodeDataModel
Q_OBJECT Q_OBJECT
public: public:
QvRuleNodeModel(std::shared_ptr<RuleNodeData> data); QvRuleNodeModel(std::shared_ptr<RuleNodeData> data);
~QvRuleNodeModel() ~QvRuleNodeModel(){};
{
// if (_label) {
// delete _label;
//}
}
QString caption() const override QString caption() const override
{ {
@ -28,18 +24,9 @@ class QvRuleNodeModel : public NodeDataModel
unsigned int nPorts(PortType portType) const override unsigned int nPorts(PortType portType) const override
{ {
if (portType == PortType::In) if (portType == PortType::In || portType == PortType::Out)
{
return 1; return 1;
} return 0;
else if (portType == PortType::Out)
{
return 1;
}
else
{
return 0;
}
} }
QString name() const override QString name() const override
@ -47,42 +34,32 @@ class QvRuleNodeModel : public NodeDataModel
return "RuleNode"; return "RuleNode";
} }
std::shared_ptr<NodeDataType> dataType(PortType portType, PortIndex portIndex) const override std::shared_ptr<NodeDataType> dataType(PortType portType, PortIndex) const override
{ {
Q_UNUSED(portIndex)
switch (portType) switch (portType)
{ {
case PortType::In: return inboundType; case PortType::In: return NODE_TYPE_INBOUND;
case PortType::Out: return NODE_TYPE_OUTBOUND;
case PortType::Out: return outboundType;
default: return {}; default: return {};
} }
} }
std::shared_ptr<NodeData> outData(PortIndex port) override std::shared_ptr<NodeData> outData(PortIndex) override
{ {
Q_UNUSED(port)
return _ruleTag; return _ruleTag;
} }
void setInData(std::shared_ptr<NodeData>, int) override void setInData(std::shared_ptr<NodeData>, int) override{};
{ void setInData(std::vector<std::shared_ptr<NodeData>>, int) override{};
} void setData(std::shared_ptr<RuleObject> data)
void setInData(std::vector<std::shared_ptr<NodeData>>, int) override
{
}
void setData(const QString &data)
{ {
_ruleTag = std::make_shared<RuleNodeData>(data); _ruleTag = std::make_shared<RuleNodeData>(data);
_label->setText(_ruleTag->GetRuleTag()); ruleWidget->adjustSize();
_label->adjustSize();
} }
QWidget *embeddedWidget() override QWidget *embeddedWidget() override
{ {
return _label; return ruleWidget;
} }
ConnectionPolicy portInConnectionPolicy(PortIndex) const override ConnectionPolicy portInConnectionPolicy(PortIndex) const override
@ -104,5 +81,5 @@ class QvRuleNodeModel : public NodeDataModel
QString modelValidationError = tr("Missing or incorrect inputs"); QString modelValidationError = tr("Missing or incorrect inputs");
// //
std::shared_ptr<RuleNodeData> _ruleTag; std::shared_ptr<RuleNodeData> _ruleTag;
QLabel *_label; QvNodeRuleWidget *ruleWidget;
}; };

View File

@ -1,8 +1,12 @@
#include "OutboundBalancerWidget.hpp" #include "OutboundBalancerWidget.hpp"
#include "base/Qv2rayBase.hpp"
OutboundBalancerWidget::OutboundBalancerWidget(QWidget *parent) : QWidget(parent) OutboundBalancerWidget::OutboundBalancerWidget(QWidget *parent) : QWidget(parent)
{ {
setupUi(this); setupUi(this);
balancerAddBtn->setIcon(QICON_R("add.png"));
balancerDelBtn->setIcon(QICON_R("delete.png"));
} }
void OutboundBalancerWidget::changeEvent(QEvent *e) void OutboundBalancerWidget::changeEvent(QEvent *e)
@ -14,3 +18,31 @@ void OutboundBalancerWidget::changeEvent(QEvent *e)
default: break; default: break;
} }
} }
void OutboundBalancerWidget::on_balancerAddBtn_clicked()
{
auto balancerTx = balancerSelectionCombo->currentText();
if (!balancerTx.isEmpty())
{
targetList.append(balancerSelectionCombo->currentText());
balancerList->addItem(balancerTx);
balancerSelectionCombo->setEditText("");
// statusLabel->setText(tr("OK"));
}
else
{
// statusLabel->setText(tr("Balancer is empty, not processing."));
}
}
void OutboundBalancerWidget::on_balancerDelBtn_clicked()
{
if (balancerList->currentRow() < 0)
{
return;
}
targetList.removeAt(balancerList->currentRow());
balancerList->takeItem(balancerList->currentRow());
// statusLabel->setText(tr("Removed a balancer entry."));
}

View File

@ -10,7 +10,11 @@ class OutboundBalancerWidget
public: public:
explicit OutboundBalancerWidget(QWidget *parent = nullptr); explicit OutboundBalancerWidget(QWidget *parent = nullptr);
void on_balancerAddBtn_clicked();
void on_balancerDelBtn_clicked();
protected: protected:
void changeEvent(QEvent *e); void changeEvent(QEvent *e);
QStringList targetList;
}; };

View File

@ -1,9 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<author/>
<comment/>
<exportmacro/>
<class>OutboundBalancerWidget</class> <class>OutboundBalancerWidget</class>
<widget name="OutboundBalancerWidget" class="QWidget"> <widget class="QWidget" name="OutboundBalancerWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -15,7 +13,56 @@
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<widget class="QWidget" name="balancersWidget" native="true">
<property name="geometry">
<rect>
<x>130</x>
<y>100</y>
<width>197</width>
<height>150</height>
</rect>
</property>
<layout class="QGridLayout" name="balancerLayout">
<item row="0" column="0">
<widget class="QComboBox" name="balancerSelectionCombo">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2">
<widget class="QListWidget" name="balancerList"/>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="balancerDelBtn">
<property name="text">
<string>...</string>
</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="balancerAddBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
<pixmapfunction/> <resources/>
<connections/> <connections/>
</ui> </ui>

View File

@ -1,5 +1,15 @@
#include "RuleWidget.hpp" #include "RuleWidget.hpp"
#include "base/Qv2rayBase.hpp"
#include "common/QvHelpers.hpp"
#define LOAD_FLAG_END isLoading = false;
#define LOAD_FLAG_BEGIN isLoading = true;
#define LOADINGCHECK \
if (isLoading) \
return;
#define rule (*ruleptr)
QvNodeRuleWidget::QvNodeRuleWidget(QWidget *parent) : QWidget(parent) QvNodeRuleWidget::QvNodeRuleWidget(QWidget *parent) : QWidget(parent)
{ {
setupUi(this); setupUi(this);
@ -14,3 +24,235 @@ void QvNodeRuleWidget::changeEvent(QEvent *e)
default: break; default: break;
} }
} }
void QvNodeRuleWidget::ShowCurrentRuleDetail(std::shared_ptr<RuleObject> _ruleptr)
{
LOADINGCHECK
this->ruleptr = _ruleptr;
// Switch to the detailed page.
ruleEnableCB->setEnabled(true);
ruleEnableCB->setChecked(rule.QV2RAY_RULE_ENABLED);
ruleTagLineEdit->setEnabled(true);
ruleRenameBtn->setEnabled(true);
LOAD_FLAG_BEGIN
ruleTagLineEdit->setText(rule.QV2RAY_RULE_TAG);
// balancerSelectionCombo->clear();
// for (auto out : outbounds)
// {
// balancerSelectionCombo->addItem(getTag(OUTBOUND(out)));
// }
// //
// // Balancers combo and balancer list.
// enableBalancerCB->setChecked(CurrentRule.QV2RAY_RULE_USE_BALANCER);
// balancersWidget->setEnabled(CurrentRule.QV2RAY_RULE_USE_BALANCER);
// if (!CurrentRule.balancerTag.isEmpty())
// {
// balancerList->clear();
// balancerList->addItems(balancers[CurrentRule.balancerTag]);
// }
isLoading = false;
// Networks
auto network = rule.network.toLower();
bool isBoth = (network.contains("tcp") && network.contains("udp")) || network.isEmpty();
netUDPRB->setChecked(network.contains("udp"));
netTCPRB->setChecked(network.contains("tcp"));
netBothRB->setChecked(isBoth);
//
// Set protocol checkboxes.
auto protocol = rule.protocol;
routeProtocolHTTPCB->setChecked(protocol.contains("http"));
routeProtocolTLSCB->setChecked(protocol.contains("tls"));
routeProtocolBTCB->setChecked(protocol.contains("bittorrent"));
//
// Port
routePortTxt->setText(rule.port);
//
// Users
QString users = rule.user.join(NEWLINE);
routeUserTxt->setPlainText(users);
//
// Incoming Sources
QString sources = rule.source.join(NEWLINE);
sourceIPList->setPlainText(sources);
//
// Domains
QString domains = rule.domain.join(NEWLINE);
hostList->setPlainText(domains);
//
// Outcoming IPs
QString ips = rule.ip.join(NEWLINE);
ipList->setPlainText(ips);
LOAD_FLAG_END
}
void QvNodeRuleWidget::on_routeProtocolHTTPCB_stateChanged(int arg1)
{
LOADINGCHECK
QStringList protocols;
if (arg1 == Qt::Checked)
protocols.push_back("http");
if (routeProtocolTLSCB->isChecked())
protocols.push_back("tls");
if (routeProtocolBTCB->isChecked())
protocols.push_back("bittorrent");
rule.protocol = protocols;
}
void QvNodeRuleWidget::on_routeProtocolTLSCB_stateChanged(int arg1)
{
LOADINGCHECK
QStringList protocols;
if (arg1 == Qt::Checked)
protocols.push_back("tls");
if (routeProtocolHTTPCB->isChecked())
protocols.push_back("http");
if (routeProtocolBTCB->isChecked())
protocols.push_back("bittorrent");
rule.protocol = protocols;
}
void QvNodeRuleWidget::on_routeProtocolBTCB_stateChanged(int arg1)
{
LOADINGCHECK
QStringList protocols;
if (arg1 == Qt::Checked)
protocols.push_back("bittorrent");
if (routeProtocolHTTPCB->isChecked())
protocols.push_back("http");
if (routeProtocolTLSCB->isChecked())
protocols.push_back("tls");
rule.protocol = protocols;
}
void QvNodeRuleWidget::on_hostList_textChanged()
{
LOADINGCHECK
rule.domain = SplitLines(hostList->toPlainText());
}
void QvNodeRuleWidget::on_ipList_textChanged()
{
LOADINGCHECK
rule.ip = SplitLines(ipList->toPlainText());
}
void QvNodeRuleWidget::on_routePortTxt_textEdited(const QString &arg1)
{
LOADINGCHECK
rule.port = arg1;
}
void QvNodeRuleWidget::on_routeUserTxt_textEdited(const QString &arg1)
{
LOADINGCHECK
rule.user = SplitLines(arg1);
}
void QvNodeRuleWidget::on_netBothRB_clicked()
{
LOADINGCHECK
rule.network = "tcp,udp";
}
void QvNodeRuleWidget::on_netUDPRB_clicked()
{
LOADINGCHECK
rule.network = "udp";
}
void QvNodeRuleWidget::on_netTCPRB_clicked()
{
LOADINGCHECK
rule.network = "tcp";
}
void QvNodeRuleWidget::on_routeUserTxt_textChanged()
{
LOADINGCHECK
rule.user = SplitLines(routeUserTxt->toPlainText());
}
void QvNodeRuleWidget::on_sourceIPList_textChanged()
{
LOADINGCHECK
rule.source = SplitLines(sourceIPList->toPlainText());
}
void QvNodeRuleWidget::on_enableBalancerCB_stateChanged(int arg1)
{
// LOADINGCHECK
// auto useBalancer = arg1 == Qt::Checked;
// CurrentRule.QV2RAY_RULE_USE_BALANCER = useBalancer;
// // balancersWidget->setEnabled(useBalancer);
// // if (CurrentRule.balancerTag.isEmpty())
// // {
// // LOG(MODULE_UI, "Creating a new balancer tag.")
// // CurrentRule.balancerTag = GenerateRandomString(6);
// // balancers[CurrentRule.balancerTag] = QStringList();
// // }
// DEBUG(MODULE_UI, "Balancer: " + CurrentRule.balancerTag)
// if (useBalancer)
// {
// LOG(MODULE_UI, "A rule has been set to use balancer, disconnect it to any outbound.")
// auto ruleNode = ruleNodes[currentRuleTag];
// for (auto &&[_, conn] : nodeScene->connections())
// {
// if (conn->getNode(PortType::Out)->id() == ruleNode)
// {
// nodeScene->deleteConnection(*conn);
// // Since there should be only one connection from this rule node.
// break;
// }
// }
// }
// else
// {
// QvMessageBoxWarn(this, tr("Route Editor"), tr("To make this rule ready to use, you need to connect it to an outbound node."));
// }
}
void QvNodeRuleWidget::on_ruleRenameBtn_clicked()
{
abort();
// auto newTag = ruleTagLineEdit->text();
//
// if (newTag.isEmpty())
//{
// LOG(MODULE_UI, "Tag is empty, this is ILLEGAL!")
// QvMessageBoxWarn(this, tr("Renaming a tag"), tr("New tag is empty, please try another."));
//}
// else if (newTag == rule.QV2RAY_RULE_TAG)
//{
// LOG(MODULE_UI, "No tag changed, returning.")
// QvMessageBoxInfo(this, tr("Renaming a tag"), tr("New tag is the same as the original one."));
//}
// else if (rules.contains(newTag))
//{
// LOG(MODULE_UI, "Tag duplicate detected.")
// QvMessageBoxWarn(this, tr("Renaming a tag"), tr("Duplicate rule tag detected, please try another."));
//}
// else
//{
// RenameItemTag(RENAME_RULE, rule.QV2RAY_RULE_TAG, &newTag);
//}
}
void QvNodeRuleWidget::on_ruleEnableCB_stateChanged(int arg1)
{
bool _isEnabled = arg1 == Qt::Checked;
rule.QV2RAY_RULE_ENABLED = _isEnabled;
settingsFrame->setEnabled(isEnabled());
}
void QvNodeRuleWidget::on_toolButton_clicked()
{
settingsFrame->setVisible(!settingsFrame->isVisible());
adjustSize();
}

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "base/Qv2rayBase.hpp"
#include "ui_RuleWidget.h" #include "ui_RuleWidget.h"
class QvNodeRuleWidget class QvNodeRuleWidget
@ -10,7 +11,27 @@ class QvNodeRuleWidget
public: public:
explicit QvNodeRuleWidget(QWidget *parent = nullptr); explicit QvNodeRuleWidget(QWidget *parent = nullptr);
void ShowCurrentRuleDetail(std::shared_ptr<RuleObject> rule);
private slots:
void on_toolButton_clicked();
void on_routeProtocolHTTPCB_stateChanged(int arg1);
void on_routeProtocolTLSCB_stateChanged(int arg1);
void on_routeProtocolBTCB_stateChanged(int arg1);
void on_hostList_textChanged();
void on_ipList_textChanged();
void on_routePortTxt_textEdited(const QString &arg1);
void on_routeUserTxt_textEdited(const QString &arg1);
void on_netBothRB_clicked();
void on_netUDPRB_clicked();
void on_netTCPRB_clicked();
void on_routeUserTxt_textChanged();
void on_sourceIPList_textChanged();
void on_enableBalancerCB_stateChanged(int arg1);
void on_ruleRenameBtn_clicked();
void on_ruleEnableCB_stateChanged(int arg1);
protected: protected:
void changeEvent(QEvent *e); void changeEvent(QEvent *e);
std::shared_ptr<RuleObject> ruleptr;
bool isLoading;
}; };

View File

@ -6,264 +6,179 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>296</width> <width>298</width>
<height>704</height> <height>500</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<layout class="QFormLayout" name="formLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout">
<item row="0" column="0"> <item>
<widget class="QLabel" name="label"> <widget class="QLineEdit" name="ruleTagLineEdit"/>
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Rule Status</string>
</property>
</widget>
</item> </item>
<item row="0" column="1"> <item>
<widget class="QCheckBox" name="ruleEnableCB"> <widget class="QToolButton" name="ruleRenameBtn">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Enabled</string> <string>Rename</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Rule Tag</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLineEdit" name="ruleTagLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ruleRenameBtn">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Rename</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="routeEditGroupBox"> <widget class="QCheckBox" name="ruleEnableCB">
<property name="enabled"> <property name="text">
<bool>false</bool> <string>Rule Enabled</string>
</property> </property>
<property name="title"> </widget>
<string>Route Editor</string> </item>
<item>
<widget class="QToolButton" name="toolButton">
<property name="text">
<string>Show / Hide</string>
</property> </property>
<property name="flat"> </widget>
<bool>false</bool> </item>
<item>
<widget class="QFrame" name="settingsFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <property name="frameShadow">
<item row="0" column="0"> <enum>QFrame::Raised</enum>
<widget class="QLabel" name="label_17"> </property>
<property name="text"> <layout class="QVBoxLayout" name="verticalLayout">
<string>Network</string> <item>
</property> <layout class="QFormLayout" name="formLayout">
</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"> <item row="0" column="0">
<widget class="QCheckBox" name="routeProtocolHTTPCB"> <widget class="QLabel" name="label_17">
<property name="text"> <property name="text">
<string>HTTP</string> <string>Network</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QCheckBox" name="routeProtocolTLSCB"> <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"> <property name="text">
<string>TLS</string> <string>Protocol</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2"> <item row="1" column="1">
<widget class="QCheckBox" name="routeProtocolBTCB"> <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"> <property name="text">
<string>BitTorrent</string> <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> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="0"> <item>
<widget class="QLabel" name="label_14"> <layout class="QGridLayout" name="gridLayout_2">
<property name="text"> <item row="0" column="0">
<string>Port</string> <widget class="QLabel" name="label_15">
</property> <property name="text">
</widget> <string>Users List</string>
</item> </property>
<item row="2" column="1"> </widget>
<widget class="QLineEdit" name="routePortTxt"> </item>
<property name="placeholderText"> <item row="0" column="1">
<string>e.g. 80, 443, 8000-8080</string> <widget class="QLabel" name="label_10">
</property> <property name="text">
</widget> <string>Source IP Matches</string>
</item> </property>
<item row="3" column="0"> </widget>
<widget class="QLabel" name="label_6"> </item>
<property name="text"> <item row="1" column="0">
<string>Balancers</string> <widget class="QPlainTextEdit" name="routeUserTxt"/>
</property> </item>
</widget> <item row="1" column="1">
</item> <widget class="QPlainTextEdit" name="sourceIPList"/>
<item row="3" column="1"> </item>
<widget class="QCheckBox" name="enableBalancerCB"> <item row="2" column="0">
<property name="text"> <widget class="QLabel" name="label_2">
<string>Use Balancers</string> <property name="text">
</property> <string>Target Domain List</string>
</widget> </property>
</item> </widget>
<item row="4" column="1"> </item>
<widget class="QWidget" name="balancersWidget" native="true"> <item row="2" column="1">
<layout class="QGridLayout" name="balancerLayout"> <widget class="QLabel" name="label_4">
<item row="0" column="0"> <property name="text">
<widget class="QComboBox" name="balancerSelectionCombo"> <string>Target IP List</string>
<property name="editable"> </property>
<bool>true</bool> </widget>
</property> </item>
</widget> <item row="3" column="0">
</item> <widget class="QPlainTextEdit" name="hostList"/>
<item row="1" column="0" rowspan="2"> </item>
<widget class="QListWidget" name="balancerList"/> <item row="3" column="1">
</item> <widget class="QPlainTextEdit" name="ipList"/>
<item row="1" column="1"> </item>
<widget class="QToolButton" name="balancerDelBtn"> </layout>
<property name="text">
<string>...</string>
</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="balancerAddBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="routeRuleGroupBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Route Detail Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Users List</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Source IP Matches</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPlainTextEdit" name="routeUserTxt"/>
</item>
<item row="1" column="1">
<widget class="QPlainTextEdit" name="sourceIPList"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Target Domain List</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Target IP List</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPlainTextEdit" name="hostList"/>
</item>
<item row="3" column="1">
<widget class="QPlainTextEdit" name="ipList"/>
</item> </item>
</layout> </layout>
</widget> </widget>

View File

@ -5,7 +5,7 @@
void MainWindow::MWSetSystemProxy() void MainWindow::MWSetSystemProxy()
{ {
const auto inboundInfo = KernelInstance->GetInboundInfo(); const auto inboundInfo = KernelInstance->GetCurrentConnectionInboundInfo();
InboundInfoObject httpInboundInfo; InboundInfoObject httpInboundInfo;
InboundInfoObject socksInboundInfo; InboundInfoObject socksInboundInfo;