diff --git a/cmake/components/qv2ray-ui.cmake b/cmake/components/qv2ray-ui.cmake index a06dfa70..b03a916e 100644 --- a/cmake/components/qv2ray-ui.cmake +++ b/cmake/components/qv2ray-ui.cmake @@ -44,6 +44,16 @@ set(QV2RAY_UI_SOURCES ${CMAKE_SOURCE_DIR}/src/ui/models/OutboundNodeModel.cpp ${CMAKE_SOURCE_DIR}/src/ui/models/RuleNodeModel.hpp ${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 ${CMAKE_SOURCE_DIR}/src/ui/styles/StyleManager.cpp ${CMAKE_SOURCE_DIR}/src/ui/styles/StyleManager.hpp diff --git a/makespec/BUILDVERSION b/makespec/BUILDVERSION index 33f6a209..aad55b59 100644 --- a/makespec/BUILDVERSION +++ b/makespec/BUILDVERSION @@ -1 +1 @@ -5791 +5792 diff --git a/src/base/models/QvSafeType.hpp b/src/base/models/QvSafeType.hpp index b4e80230..96146ddf 100644 --- a/src/base/models/QvSafeType.hpp +++ b/src/base/models/QvSafeType.hpp @@ -6,23 +6,23 @@ #include #include -#define SAFE_TYPEDEF_EXTRA(Base, name, extra) \ - class name : public Base \ - { \ - public: \ - template \ - explicit name(Args... args) : Base(args...) \ - { \ - } \ - const Base &raw() const \ - { \ - return *this; \ - } \ - extra \ +template +class SAFETYPE_IMPL : public BASETYPE_T +{ + public: + template + explicit SAFETYPE_IMPL(Args... args) : BASETYPE_T(args...){}; + const BASETYPE_T &raw() const + { + return *this; } +}; + +#define SAFE_TYPEDEF(BASE, CLASS) \ + class __##CLASS##__; \ + typedef SAFETYPE_IMPL<__##CLASS##__, BASE> CLASS; #define nothing -#define SAFE_TYPEDEF(Base, name) SAFE_TYPEDEF_EXTRA(Base, name, nothing) namespace Qv2ray::base::safetype { // To prevent anonying QJsonObject misuse @@ -31,14 +31,11 @@ namespace Qv2ray::base::safetype SAFE_TYPEDEF(QJsonObject, INBOUND); SAFE_TYPEDEF(QJsonObject, OUTBOUND); SAFE_TYPEDEF(QJsonObject, CONFIGROOT); - SAFE_TYPEDEF(QJsonObject, PROXYSETTING); - // - SAFE_TYPEDEF(QJsonArray, ROUTERULELIST); - SAFE_TYPEDEF(QJsonArray, INOUTLIST); SAFE_TYPEDEF(QJsonObject, ROUTING); SAFE_TYPEDEF(QJsonObject, ROUTERULE); - SAFE_TYPEDEF(INOUTLIST, OUTBOUNDS); - SAFE_TYPEDEF(INOUTLIST, INBOUNDS); + // + SAFE_TYPEDEF(QJsonArray, OUTBOUNDS); + SAFE_TYPEDEF(QJsonArray, INBOUNDS); template struct QvPair diff --git a/src/core/CoreUtils.cpp b/src/core/CoreUtils.cpp index 6f76bf87..b4616b61 100644 --- a/src/core/CoreUtils.cpp +++ b/src/core/CoreUtils.cpp @@ -165,23 +165,30 @@ namespace Qv2ray::core return TruncateString(ConnectionManager->GetGroupMetaObject(id).displayName, limit); } - const QMap 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 GetInboundInfo(const CONFIGROOT &root) { QMap inboundPorts; for (const auto &inboundVal : root["inbounds"].toArray()) { - const auto &inbound = inboundVal.toObject(); - inboundPorts[inbound["tag"].toString()] = { - inbound["protocol"].toString(), // - inbound["listen"].toString(), // - inbound["port"].toVariant().toInt() // - }; + INBOUND in{ inboundVal.toObject() }; + QString host, protocol; + int port; + if (GetInboundInfo(in, &host, &port, &protocol)) + inboundPorts[getTag(in)] = { protocol, host, port }; } return inboundPorts; } - const QMap GetConfigInboundInfo(const ConnectionId &id) + const QMap GetInboundInfo(const ConnectionId &id) { - return GetConfigInboundInfo(ConnectionManager->GetConnectionRoot(id)); + return GetInboundInfo(ConnectionManager->GetConnectionRoot(id)); } } // namespace Qv2ray::core diff --git a/src/core/CoreUtils.hpp b/src/core/CoreUtils.hpp index 61c0bcdc..06e74eef 100644 --- a/src/core/CoreUtils.hpp +++ b/src/core/CoreUtils.hpp @@ -49,8 +49,9 @@ namespace Qv2ray::core // // const GroupId GetConnectionGroupId(const ConnectionId &id); // - const QMap GetConfigInboundInfo(const CONFIGROOT &root); - const QMap GetConfigInboundInfo(const ConnectionId &id); + bool GetInboundInfo(const INBOUND &in, QString *listen, int *port, QString *protocol); + const QMap GetInboundInfo(const CONFIGROOT &root); + const QMap GetInboundInfo(const ConnectionId &id); } // namespace Qv2ray::core using namespace Qv2ray::core; diff --git a/src/core/handler/KernelInstanceHandler.cpp b/src/core/handler/KernelInstanceHandler.cpp index 357dbb0c..4ed04ebe 100644 --- a/src/core/handler/KernelInstanceHandler.cpp +++ b/src/core/handler/KernelInstanceHandler.cpp @@ -79,7 +79,7 @@ namespace Qv2ray::core::handler std::optional KernelInstanceHandler::StartConnection(const ConnectionGroupPair &id, CONFIGROOT fullConfig) { StopConnection(); - inboundInfo = GetConfigInboundInfo(fullConfig); + inboundInfo = GetInboundInfo(fullConfig); // const auto inboundPorts = GetInboundPorts(); const auto inboundHosts = GetInboundHosts(); diff --git a/src/core/handler/KernelInstanceHandler.hpp b/src/core/handler/KernelInstanceHandler.hpp index 6dc0261f..bc0f8c02 100644 --- a/src/core/handler/KernelInstanceHandler.hpp +++ b/src/core/handler/KernelInstanceHandler.hpp @@ -25,7 +25,7 @@ namespace Qv2ray::core::handler { return activeKernels.size(); } - const QMap GetInboundInfo() const + const QMap GetCurrentConnectionInboundInfo() const { return inboundInfo; } diff --git a/src/core/handler/RouteHandler.cpp b/src/core/handler/RouteHandler.cpp index c20df772..87649111 100644 --- a/src/core/handler/RouteHandler.cpp +++ b/src/core/handler/RouteHandler.cpp @@ -50,7 +50,7 @@ namespace Qv2ray::core::handler root.insert("domainStrategy", routeConfig.domainStrategy); // // For Rules list - ROUTERULELIST rulesList; + QJsonArray rulesList; // Private IPs should always NOT TO PROXY! 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 // rule object. ROUTING routing(root["routing"].toObject()); - ROUTERULELIST rules; + QJsonArray rules; LOG(MODULE_CONNECTION, "Processing an existing routing table.") for (const auto &_rule : routing["rules"].toArray()) @@ -315,7 +315,7 @@ namespace Qv2ray::core::handler if (firstOutbound[QV2RAY_USE_FPROXY_KEY].toBool(false)) { LOG(MODULE_CONNECTION, "Applying forward proxy to current connection.") - PROXYSETTING proxy; + QJsonObject proxy; proxy["tag"] = OUTBOUND_TAG_FORWARD_PROXY; firstOutbound["proxySettings"] = proxy; diff --git a/src/ui/editors/w_RoutesEditor.cpp b/src/ui/editors/w_RoutesEditor.cpp index a91f6c51..49956985 100644 --- a/src/ui/editors/w_RoutesEditor.cpp +++ b/src/ui/editors/w_RoutesEditor.cpp @@ -22,7 +22,7 @@ using QtNodes::FlowView; using namespace Qv2ray::ui::nodemodels; -#define CurrentRule this->rules[this->currentRuleTag] +//#define CurrentRule this->rules[this->currentRuleTag] #define LOADINGCHECK \ if (isLoading) \ return; @@ -85,14 +85,7 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QvDialog(par // SetupNodeWidget(); // - // 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")); - balancerAddBtn->setIcon(QICON_R("add.png")); - balancerDelBtn->setIcon(QICON_R("delete.png")); + updateColorScheme(); // domainStrategy = root["routing"].toObject()["domainStrategy"].toString(); domainStrategyCombo->setCurrentText(domainStrategy); @@ -117,15 +110,15 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) : QvDialog(par defaultOutbound = getTag(OUTBOUND(root["outbounds"].toArray().first().toObject())); defaultOutboundCombo->setCurrentText(defaultOutbound); - // Find and add balancers. - for (auto _balancer : root["routing"].toObject()["balancers"].toArray()) - { - auto _balancerObject = _balancer.toObject(); - if (!_balancerObject["tag"].toString().isEmpty()) - { - balancers.insert(_balancerObject["tag"].toString(), _balancerObject["selector"].toVariant().toStringList()); - } - } + // // Find and add balancers. + // for (auto _balancer : root["routing"].toObject()["balancers"].toArray()) + // { + // auto _balancerObject = _balancer.toObject(); + // if (!_balancerObject["tag"].toString().isEmpty()) + // { + // balancers.insert(_balancerObject["tag"].toString(), _balancerObject["selector"].toVariant().toStringList()); + // } + // } for (const auto &group : ConnectionManager->AllGroups()) { @@ -157,43 +150,37 @@ void RouteEditor::onNodeClicked(Node &n) auto isIn = inboundNodes.values().contains(n.id()); auto isRule = ruleNodes.values().contains(n.id()); - if (isRule) - { - // It's a rule object - currentRuleTag = GetFirstNodeData(n.id(), RuleNode)->GetRuleTag(); - DEBUG(MODULE_GRAPH, "Selecting rule: " + currentRuleTag) - ShowCurrentRuleDetail(); - toolBox->setCurrentIndex(1); - } - else if (isOut || isIn) + /* if (isRule) + { + // It's a rule object + currentRuleTag = GetFirstNodeData(n.id(), RuleNode)->GetRuleTag(); + DEBUG(MODULE_GRAPH, "Selecting rule: " + currentRuleTag) + // ShowCurrentRuleDetail(); + toolBox->setCurrentIndex(1); + } + else*/ + if (isOut || isIn) { // It's an inbound or an outbound. - QString alias; + QString tag; QString host; - QString port; + int port; QString protocol; if (isOut) { - alias = GetFirstNodeData(n.id(), OutboundNode)->GetOutbound(); - QJsonObject _root = outbounds[alias].raw(); - int _port; - GetOutboundInfo(OUTBOUND(_root), &host, &_port, &protocol); - port = QString::number(_port); + const auto root = GetFirstNodeData(n.id(), OutboundNode)->GetOutbound(); + GetOutboundInfo(*root, &host, &port, &protocol); } else { - alias = GetFirstNodeData(n.id(), InboundNode)->GetInbound(); - QJsonObject _root = inbounds[alias].raw(); - host = _root["listen"].toString(); - protocol = _root["protocol"].toString(); - // Port could be a string, or an integer. - port = _root["port"].toVariant().toString(); + const auto root = GetFirstNodeData(n.id(), InboundNode)->GetInbound(); + GetInboundInfo(*root, &host, &port, &protocol); } - tagLabel->setText(alias); + tagLabel->setText(tag); protocolLabel->setText(protocol); - portLabel->setText(port); + portLabel->setText(QSTRN(port)); hostLabel->setText(host); } else @@ -213,58 +200,58 @@ void RouteEditor::onConnectionCreated(QtNodes::Connection const &c) auto const &sourceNode = c.getNode(PortType::Out); auto const &targetNode = c.getNode(PortType::In); - if (inboundNodes.values().contains(sourceNode->id()) && ruleNodes.values().contains(targetNode->id())) - { - // It's a inbound-rule connection - onNodeClicked(*sourceNode); - onNodeClicked(*targetNode); - LOG(MODULE_GRAPH, "Inbound-rule new connection.") - // Get all connected inbounds to this rule node. - // QStringList has an helper to let us remove duplicates, see below. - QSet _inbounds; - // - // Workaround for removing a connection within the loop. - QList> connectionsTobeRemoved; - for (auto &&[_, conn] : nodeScene->connections()) - { - const auto &inNode = conn->getNode(PortType::In); - const auto &outNode = conn->getNode(PortType::Out); - // If a connection is not current Id, but with same IN/OUT nodes. - // It is a "duplicated" connection. - if (inNode->id() == targetNode->id() && outNode->id() == sourceNode->id() && conn->id() != c.id()) - { - connectionsTobeRemoved << (conn); - } - // Append all inbounds - if (inNode->id() == targetNode->id()) - { - _inbounds.insert(GetFirstNodeData(outNode->id(), InboundNode)->GetInbound()); - } - } - for (const auto &connRemoved : connectionsTobeRemoved) - { - nodeScene->deleteConnection(*connRemoved); - } - - CurrentRule.inboundTag = _inbounds.values(); - } - else if (ruleNodes.values().contains(sourceNode->id()) && outboundNodes.values().contains(targetNode->id())) - { - // It's a rule-outbound connection - onNodeClicked(*sourceNode); - onNodeClicked(*targetNode); - CurrentRule.outboundTag = GetFirstNodeData(targetNode->id(), OutboundNode)->GetOutbound(); - // Connecting to an outbound will disable the balancer feature. - CurrentRule.QV2RAY_RULE_USE_BALANCER = false; - // Update balancer settings. - ShowCurrentRuleDetail(); - LOG(MODULE_GRAPH, "Updated outbound: " + CurrentRule.outboundTag) - } - else - { - // It's an impossible connection - LOG(MODULE_GRAPH, "Unrecognized connection, RARE.") - } + // if (inboundNodes.values().contains(sourceNode->id()) && ruleNodes.values().contains(targetNode->id())) + // { + // // It's a inbound-rule connection + // onNodeClicked(*sourceNode); + // onNodeClicked(*targetNode); + // LOG(MODULE_GRAPH, "Inbound-rule new connection.") + // // Get all connected inbounds to this rule node. + // // QStringList has an helper to let us remove duplicates, see below. + // QSet _inbounds; + // // + // // Workaround for removing a connection within the loop. + // QList> connectionsTobeRemoved; + // for (auto &&[_, conn] : nodeScene->connections()) + // { + // const auto &inNode = conn->getNode(PortType::In); + // const auto &outNode = conn->getNode(PortType::Out); + // // If a connection is not current Id, but with same IN/OUT nodes. + // // It is a "duplicated" connection. + // if (inNode->id() == targetNode->id() && outNode->id() == sourceNode->id() && conn->id() != c.id()) + // { + // connectionsTobeRemoved << (conn); + // } + // // Append all inbounds + // if (inNode->id() == targetNode->id()) + // { + // _inbounds.insert(GetFirstNodeData(outNode->id(), InboundNode)->GetInbound()); + // } + // } + // for (const auto &connRemoved : connectionsTobeRemoved) + // { + // nodeScene->deleteConnection(*connRemoved); + // } + // + // CurrentRule.inboundTag = _inbounds.values(); + // } + // else if (ruleNodes.values().contains(sourceNode->id()) && outboundNodes.values().contains(targetNode->id())) + // { + // // It's a rule-outbound connection + // onNodeClicked(*sourceNode); + // onNodeClicked(*targetNode); + // CurrentRule.outboundTag = GetFirstNodeData(targetNode->id(), OutboundNode)->GetOutbound(); + // // Connecting to an outbound will disable the balancer feature. + // CurrentRule.QV2RAY_RULE_USE_BALANCER = false; + // // Update balancer settings. + // // ShowCurrentRuleDetail(); + // LOG(MODULE_GRAPH, "Updated outbound: " + CurrentRule.outboundTag) + // } + // else + // { + // // It's an impossible connection + // LOG(MODULE_GRAPH, "Unrecognized connection, RARE.") + // } } 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 &target = c.getNode(PortType::In); - if (inboundNodes.values().contains(source->id()) && ruleNodes.values().contains(target->id())) - { - // It's a inbound-rule connection - onNodeClicked(*source); - onNodeClicked(*target); - currentRuleTag = GetFirstNodeData(target->id(), RuleNode)->GetRuleTag(); - auto _inboundTag = GetFirstNodeData(source->id(), InboundNode)->GetInbound(); - LOG(MODULE_UI, "Removing inbound: " + _inboundTag + " from rule: " + currentRuleTag) - CurrentRule.inboundTag.removeAll(_inboundTag); - } - else if (ruleNodes.values().contains(source->id()) && outboundNodes.values().contains(target->id())) - { - // It's a rule-outbound connection - onNodeClicked(*source); - onNodeClicked(*target); - currentRuleTag = GetFirstNodeData(source->id(), RuleNode)->GetRuleTag(); - auto _outboundTag = GetFirstNodeData(target->id(), OutboundNode)->GetOutbound(); - - if (!CurrentRule.QV2RAY_RULE_USE_BALANCER && CurrentRule.outboundTag == _outboundTag) - { - CurrentRule.outboundTag.clear(); - } - - LOG(MODULE_GRAPH, "Removing an outbound: " + _outboundTag) - } - else - { - // It's an impossible connection - LOG(MODULE_GRAPH, "Selected an unknown node, RARE.") - } + // if (inboundNodes.values().contains(source->id()) && ruleNodes.values().contains(target->id())) + //{ + // // It's a inbound-rule connection + // onNodeClicked(*source); + // onNodeClicked(*target); + // currentRuleTag = GetFirstNodeData(target->id(), RuleNode)->GetRuleTag(); + // auto _inboundTag = GetFirstNodeData(source->id(), InboundNode)->GetInbound(); + // LOG(MODULE_UI, "Removing inbound: " + _inboundTag + " from rule: " + currentRuleTag) + // CurrentRule.inboundTag.removeAll(_inboundTag); + //} + // else if (ruleNodes.values().contains(source->id()) && outboundNodes.values().contains(target->id())) + //{ + // // It's a rule-outbound connection + // onNodeClicked(*source); + // onNodeClicked(*target); + // currentRuleTag = GetFirstNodeData(source->id(), RuleNode)->GetRuleTag(); + // auto _outboundTag = GetFirstNodeData(target->id(), OutboundNode)->GetOutbound(); + // + // if (!CurrentRule.QV2RAY_RULE_USE_BALANCER && CurrentRule.outboundTag == _outboundTag) + // { + // CurrentRule.outboundTag.clear(); + // } + // + // LOG(MODULE_GRAPH, "Removing an outbound: " + _outboundTag) + //} + // else + //{ + // // It's an impossible connection + // LOG(MODULE_GRAPH, "Selected an unknown node, RARE.") + //} } CONFIGROOT RouteEditor::OpenEditor() @@ -330,7 +317,7 @@ CONFIGROOT RouteEditor::OpenEditor() // Append rules by order for (auto i = 0; i < ruleListWidget->count(); i++) { - auto _rule = rules[ruleListWidget->item(i)->text()]; + auto _rule = rules[i]; auto ruleJsonObject = _rule.toJson(); // Process balancer for a rule @@ -339,19 +326,19 @@ CONFIGROOT RouteEditor::OpenEditor() // Do not use outbound tag. ruleJsonObject.remove("outboundTag"); - // Find balancer list - if (!balancers.contains(_rule.balancerTag)) - { - LOG(MODULE_UI, "Cannot find a balancer for tag: " + _rule.balancerTag) - } - else - { - auto _balancerList = balancers[_rule.balancerTag]; - QJsonObject balancerEntry; - balancerEntry["tag"] = _rule.balancerTag; - balancerEntry["selector"] = QJsonArray::fromStringList(_balancerList); - _balancers.append(balancerEntry); - } + // // Find balancer list + // if (!balancers.contains(_rule.balancerTag)) + // { + // LOG(MODULE_UI, "Cannot find a balancer for tag: " + _rule.balancerTag) + // } + // else + // { + // auto _balancerList = balancers[_rule.balancerTag]; + // QJsonObject balancerEntry; + // balancerEntry["tag"] = _rule.balancerTag; + // balancerEntry["selector"] = QJsonArray::fromStringList(_balancerList); + // _balancers.append(balancerEntry); + // } } // 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() { auto freedom = GenerateFreedomOUT("AsIs", "", 0); @@ -514,172 +422,6 @@ void RouteEditor::on_insertDirectBtn_clicked() 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() { LOADINGCHECK @@ -809,13 +551,7 @@ void RouteEditor::on_addOutboundBtn_clicked() 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() { if (nodeScene->selectedNodes().empty()) @@ -834,57 +570,57 @@ void RouteEditor::on_delBtn_clicked() // the node container. if (isInbound) { - currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), InboundNode)->GetInbound(); - nodeScene->removeNode(*nodeScene->node(inboundNodes[currentInboundOutboundTag])); - inboundNodes.remove(currentInboundOutboundTag); - - // Remove corresponded inbound tags from the rules. - for (auto k : rules.keys()) - { - auto v = rules[k]; - v.inboundTag.removeAll(currentInboundOutboundTag); - rules[k] = v; - } - - inbounds.remove(currentInboundOutboundTag); + // currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), InboundNode)->GetInbound(); + // nodeScene->removeNode(*nodeScene->node(inboundNodes[currentInboundOutboundTag])); + // inboundNodes.remove(currentInboundOutboundTag); + // + // // Remove corresponded inbound tags from the rules. + // for (auto k : rules.keys()) + // { + // auto v = rules[k]; + // v.inboundTag.removeAll(currentInboundOutboundTag); + // rules[k] = v; + // } + // + // inbounds.remove(currentInboundOutboundTag); } else if (isOutbound) { - currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), OutboundNode)->GetOutbound(); - outbounds.remove(currentInboundOutboundTag); - ResolveDefaultOutboundTag(currentInboundOutboundTag, ""); - - // Remove corresponded outbound tags from the rules. - for (auto k : rules.keys()) - { - auto v = rules[k]; - - if (v.outboundTag == currentInboundOutboundTag) - v.outboundTag.clear(); - - rules[k] = v; - } - - nodeScene->removeNode(*nodeScene->node(outboundNodes[currentInboundOutboundTag])); - outboundNodes.remove(currentInboundOutboundTag); + // currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), OutboundNode)->GetOutbound(); + // outbounds.remove(currentInboundOutboundTag); + // ResolveDefaultOutboundTag(currentInboundOutboundTag, ""); + // + //// Remove corresponded outbound tags from the rules. + // for (auto k : rules.keys()) + //{ + // auto v = rules[k]; + // + // if (v.outboundTag == currentInboundOutboundTag) + // v.outboundTag.clear(); + // + // rules[k] = v; + //} + // + // nodeScene->removeNode(*nodeScene->node(outboundNodes[currentInboundOutboundTag])); + // outboundNodes.remove(currentInboundOutboundTag); } else if (isRule) { - ruleEnableCB->setEnabled(false); - ruleTagLineEdit->setEnabled(false); - ruleRenameBtn->setEnabled(false); - auto RuleTag = GetFirstNodeData(firstNode->id(), RuleNode)->GetRuleTag(); - currentRuleTag.clear(); - routeRuleGroupBox->setEnabled(false); - routeEditGroupBox->setEnabled(false); - rules.remove(RuleTag); - nodeScene->removeNode(*nodeScene->node(ruleNodes[RuleTag])); - ruleNodes.remove(RuleTag); - // - // Remove item from the rule order list widget. - ruleListWidget->takeItem(ruleListWidget->row(ruleListWidget->findItems(RuleTag, Qt::MatchExactly).first())); - CHECKEMPTYRULES - // currentRuleTag = rules.firstKey(); + // ruleEnableCB->setEnabled(false); + // ruleTagLineEdit->setEnabled(false); + // ruleRenameBtn->setEnabled(false); + // auto RuleTag = GetFirstNodeData(firstNode->id(), RuleNode)->GetRuleTag(); + // currentRuleTag.clear(); + // routeRuleGroupBox->setEnabled(false); + // routeEditGroupBox->setEnabled(false); + // rules.remove(RuleTag); + // nodeScene->removeNode(*nodeScene->node(ruleNodes[RuleTag])); + // ruleNodes.remove(RuleTag); + //// + //// Remove item from the rule order list widget. + // ruleListWidget->takeItem(ruleListWidget->row(ruleListWidget->findItems(RuleTag, Qt::MatchExactly).first())); + // CHECKEMPTYRULES + //// currentRuleTag = rules.firstKey(); // ShowCurrentRuleDetail(); } else @@ -893,6 +629,11 @@ void RouteEditor::on_delBtn_clicked() 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() { if (nodeScene->selectedNodes().empty()) @@ -907,117 +648,117 @@ void RouteEditor::on_editBtn_clicked() if (isInbound) { - currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), InboundNode)->GetInbound(); - - if (!inbounds.contains(currentInboundOutboundTag)) - { - QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag); - return; - } - - auto _in = inbounds[currentInboundOutboundTag]; - INBOUND _result; - auto protocol = _in["protocol"].toString(); - int _code; - - if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") - { - QvMessageBoxWarn(this, tr("Cannot Edit"), - tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" + - tr("We will launch Json Editor instead.")); - statusLabel->setText(tr("Opening JSON editor")); - JsonEditor w(_in, this); - _result = INBOUND(w.OpenEditor()); - _code = w.result(); - } - else - { - InboundEditor w(_in, this); - statusLabel->setText(tr("Opening default inbound editor")); - _result = w.OpenEditor(); - _code = w.result(); - } - - statusLabel->setText(tr("OK")); - - if (_code == QDialog::Accepted) - { - bool isTagChanged = getTag(_in) != getTag(_result); - - if (isTagChanged) - { - auto newTag = getTag(_result); - RenameItemTag(RENAME_INBOUND, getTag(_in), &newTag); - } - - DEBUG(MODULE_UI, "Removed old tag: " + getTag(_in)) - inbounds.remove(getTag(_in)); - DEBUG(MODULE_UI, "Adding new tag: " + getTag(_result)) - inbounds.insert(getTag(_result), _result); - } + // currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), InboundNode)->GetInbound(); + // + // if (!inbounds.contains(currentInboundOutboundTag)) + // { + // QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag); + // return; + // } + // + // auto _in = inbounds[currentInboundOutboundTag]; + // INBOUND _result; + // auto protocol = _in["protocol"].toString(); + // int _code; + // + // if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") + // { + // QvMessageBoxWarn(this, tr("Cannot Edit"), + // tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" + + // tr("We will launch Json Editor instead.")); + // statusLabel->setText(tr("Opening JSON editor")); + // JsonEditor w(_in, this); + // _result = INBOUND(w.OpenEditor()); + // _code = w.result(); + // } + // else + // { + // InboundEditor w(_in, this); + // statusLabel->setText(tr("Opening default inbound editor")); + // _result = w.OpenEditor(); + // _code = w.result(); + // } + // + // statusLabel->setText(tr("OK")); + // + // if (_code == QDialog::Accepted) + // { + // bool isTagChanged = getTag(_in) != getTag(_result); + // + // if (isTagChanged) + // { + // auto newTag = getTag(_result); + // RenameItemTag(RENAME_INBOUND, getTag(_in), &newTag); + // } + // + // DEBUG(MODULE_UI, "Removed old tag: " + getTag(_in)) + // inbounds.remove(getTag(_in)); + // DEBUG(MODULE_UI, "Adding new tag: " + getTag(_result)) + // inbounds.insert(getTag(_result), _result); + // } } else if (isOutbound) { - currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), OutboundNode)->GetOutbound(); - - if (!outbounds.contains(currentInboundOutboundTag)) - { - QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag); - return; - } - - OUTBOUND _result; - auto _out = outbounds.value(currentInboundOutboundTag); - auto protocol = _out["protocol"].toString().toLower(); - int _code; - - bool guisupport = true; - if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks" && protocol != "http") - { - guisupport = false; - auto pluginEditorWidgetsInfo = PluginHost->GetOutboundEditorWidgets(); - for (const auto &plugin : pluginEditorWidgetsInfo) - { - for (const auto &_d : plugin->OutboundCapabilities()) - { - guisupport = guisupport || protocol == _d.protocol; - } - } - } - - if (!guisupport) - { - QvMessageBoxWarn(this, tr("Unsupported Outbound Type"), - tr("This outbound entry is not supported by the GUI editor.") + NEWLINE + - tr("We will launch Json Editor instead.")); - JsonEditor w(_out, this); - statusLabel->setText(tr("Opening JSON editor")); - _result = OUTBOUND(w.OpenEditor()); - _code = w.result(); - } - else - { - OutboundEditor w(_out, this); - statusLabel->setText(tr("Opening default outbound editor.")); - _result = w.OpenEditor(); - _code = w.result(); - } - - if (_code == QDialog::Accepted) - { - bool isTagChanged = getTag(_out) != getTag(_result); - - if (isTagChanged) - { - auto newTag = getTag(_result); - DEBUG(MODULE_UI, "Outbound tag is changed: " + newTag) - RenameItemTag(RENAME_OUTBOUND, getTag(_out), &newTag); - } - - DEBUG(MODULE_UI, "Adding new tag: " + getTag(_result)) - outbounds.insert(getTag(_result), _result); - statusLabel->setText(tr("OK")); - } + // currentInboundOutboundTag = GetFirstNodeData(firstNode->id(), OutboundNode)->GetOutbound(); + // + // if (!outbounds.contains(currentInboundOutboundTag)) + //{ + // QvMessageBoxWarn(this, tr("Edit Inbound"), tr("No inbound tag found: ") + currentInboundOutboundTag); + // return; + //} + // + // OUTBOUND _result; + // auto _out = outbounds.value(currentInboundOutboundTag); + // auto protocol = _out["protocol"].toString().toLower(); + // int _code; + // + // bool guisupport = true; + // if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks" && protocol != "http") + //{ + // guisupport = false; + // auto pluginEditorWidgetsInfo = PluginHost->GetOutboundEditorWidgets(); + // for (const auto &plugin : pluginEditorWidgetsInfo) + // { + // for (const auto &_d : plugin->OutboundCapabilities()) + // { + // guisupport = guisupport || protocol == _d.protocol; + // } + // } + //} + // + // if (!guisupport) + //{ + // QvMessageBoxWarn(this, tr("Unsupported Outbound Type"), + // tr("This outbound entry is not supported by the GUI editor.") + NEWLINE + + // tr("We will launch Json Editor instead.")); + // JsonEditor w(_out, this); + // statusLabel->setText(tr("Opening JSON editor")); + // _result = OUTBOUND(w.OpenEditor()); + // _code = w.result(); + //} + // else + //{ + // OutboundEditor w(_out, this); + // statusLabel->setText(tr("Opening default outbound editor.")); + // _result = w.OpenEditor(); + // _code = w.result(); + //} + // + // if (_code == QDialog::Accepted) + //{ + // bool isTagChanged = getTag(_out) != getTag(_result); + // + // if (isTagChanged) + // { + // auto newTag = getTag(_result); + // DEBUG(MODULE_UI, "Outbound tag is changed: " + newTag) + // RenameItemTag(RENAME_OUTBOUND, getTag(_out), &newTag); + // } + // + // DEBUG(MODULE_UI, "Adding new tag: " + getTag(_result)) + // outbounds.insert(getTag(_result), _result); + // statusLabel->setText(tr("OK")); + //} } else { @@ -1031,31 +772,6 @@ void RouteEditor::on_domainStrategyCombo_currentIndexChanged(const QString &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) { LOADINGCHECK diff --git a/src/ui/editors/w_RoutesEditor.hpp b/src/ui/editors/w_RoutesEditor.hpp index c72ef517..4ecd1aab 100644 --- a/src/ui/editors/w_RoutesEditor.hpp +++ b/src/ui/editors/w_RoutesEditor.hpp @@ -36,68 +36,30 @@ class RouteEditor void processCommands(QString, QStringList, QMap) override{}; 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; private slots: void on_buttonBox_accepted(); - 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_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_insertBlackBtn_clicked(); - void on_addInboundBtn_clicked(); - void on_addOutboundBtn_clicked(); - - void on_ruleEnableCB_stateChanged(int arg1); - void on_delBtn_clicked(); - void on_editBtn_clicked(); - void on_domainStrategyCombo_currentIndexChanged(const QString &arg1); - - void on_ruleRenameBtn_clicked(); - void on_defaultOutboundCombo_currentTextChanged(const QString &arg1); - void on_importExistingBtn_clicked(); - void on_importGroupBtn_currentIndexChanged(int index); public slots: @@ -108,17 +70,16 @@ class RouteEditor private: bool isLoading = false; void RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, QString *newTag); - void ShowCurrentRuleDetail(); // - QString currentRuleTag; + // QString currentRuleTag; QString currentInboundOutboundTag; - QMap balancers; + // QMap balancers; QString domainStrategy; QString defaultOutbound; // - QMap inbounds; - QMap outbounds; - QMap rules; + QList inbounds; + QList outbounds; + QList rules; // CONFIGROOT root; CONFIGROOT original; diff --git a/src/ui/editors/w_RoutesEditor.ui b/src/ui/editors/w_RoutesEditor.ui index 513f8744..b0ddc665 100644 --- a/src/ui/editors/w_RoutesEditor.ui +++ b/src/ui/editors/w_RoutesEditor.ui @@ -297,7 +297,7 @@ - 1 + 0 @@ -305,7 +305,7 @@ 0 0 359 - 505 + 536 @@ -401,275 +401,6 @@ - - - - 0 - 0 - 347 - 704 - - - - Rule Settings - - - - - - - - true - - - Rule Status - - - - - - - false - - - Enabled - - - - - - - Rule Tag - - - - - - - - - false - - - - - - - false - - - Rename - - - - - - - - - - - false - - - Route Editor - - - false - - - - - - Network - - - - - - - - - TCP - - - - - - - UDP - - - - - - - Both - - - - - - - - - Protocol - - - - - - - - - HTTP - - - - - - - TLS - - - - - - - BitTorrent - - - - - - - - - Port - - - - - - - e.g. 80, 443, 8000-8080 - - - - - - - Balancers - - - - - - - Use Balancers - - - - - - - - - - true - - - - - - - - - - ... - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - ... - - - - - - - - - - - - - false - - - Route Detail Settings - - - - - - Users List - - - - - - - Source IP Matches - - - - - - - - - - - - - Target Domain List - - - - - - - Target IP List - - - - - - - - - - - - - - @@ -715,25 +446,6 @@ domainStrategyCombo defaultOutboundCombo ruleListWidget - ruleEnableCB - ruleTagLineEdit - ruleRenameBtn - netTCPRB - netUDPRB - netBothRB - routeProtocolHTTPCB - routeProtocolTLSCB - routeProtocolBTCB - routePortTxt - enableBalancerCB - balancerSelectionCombo - balancerAddBtn - balancerList - balancerDelBtn - routeUserTxt - sourceIPList - ipList - hostList diff --git a/src/ui/editors/w_RoutesEditor_extra.cpp b/src/ui/editors/w_RoutesEditor_extra.cpp index a180e0ee..0b49362d 100644 --- a/src/ui/editors/w_RoutesEditor_extra.cpp +++ b/src/ui/editors/w_RoutesEditor_extra.cpp @@ -1,10 +1,11 @@ -#include #include "core/CoreUtils.hpp" #include "ui/common/UIBase.hpp" #include "ui/models/InboundNodeModel.hpp" #include "ui/models/OutboundNodeModel.hpp" #include "ui/models/RuleNodeModel.hpp" #include "w_RoutesEditor.hpp" + +#include // Supplementary source file for Routes editor, basically providing // routes-related operations. @@ -12,40 +13,36 @@ void RouteEditor::AddInbound(INBOUND in) { QString tag = getTag(in); - if (inbounds.contains(tag)) - { - tag = tag + "_" + GenerateRandomString(5); - } + if (inboundNodes.contains(tag)) + tag.append("_" + GenerateRandomString(5)); in["tag"] = tag; - auto _nodeData = std::make_unique(std::make_shared(tag)); + inbounds << in; + auto _nodeData = std::make_unique(std::make_shared(std::make_shared(inbounds.last()))); auto &node = nodeScene->createNode(std::move(_nodeData)); QPointF pos; pos.setX(0 + GRAPH_GLOBAL_OFFSET_X); pos.setY(inboundNodes.count() * 130 + GRAPH_GLOBAL_OFFSET_Y); nodeScene->setNodePosition(node, pos); inboundNodes.insert(tag, node.id()); - inbounds.insert(getTag(in), in); } void RouteEditor::AddOutbound(OUTBOUND out) { QString tag = getTag(out); - if (outbounds.contains(tag)) - { - tag = tag + "_" + GenerateRandomString(5); - } + if (outboundNodes.contains(tag)) + tag.append("_" + GenerateRandomString(5)); out["tag"] = tag; - auto _nodeData = std::make_unique(std::make_shared(tag)); + outbounds << out; + auto _nodeData = std::make_unique(std::make_shared(std::make_shared(outbounds.last()))); auto pos = nodeGraphWidget->pos(); pos.setX(pos.x() + 850 + GRAPH_GLOBAL_OFFSET_X); pos.setY(pos.y() + outboundNodes.count() * 120 + GRAPH_GLOBAL_OFFSET_Y); auto &node = nodeScene->createNode(std::move(_nodeData)); nodeScene->setNodePosition(node, pos); outboundNodes.insert(tag, node.id()); - outbounds.insert(tag, out); defaultOutboundCombo->addItem(tag); } @@ -60,7 +57,7 @@ QString RouteEditor::AddNewRule() auto bTag = GenerateRandomString(); rule.QV2RAY_RULE_TAG = rules.isEmpty() ? tr("Default rule") : (tr("rule") + "-" + GenerateRandomString(6)); rule.balancerTag = bTag; - balancers[bTag] = QStringList(); + // balancers[bTag] = QStringList(); AddRule(rule); return rule.QV2RAY_RULE_TAG; } @@ -73,11 +70,11 @@ void RouteEditor::AddRule(RuleObject rule) rule.QV2RAY_RULE_TAG += "-" + GenerateRandomString(5); } - rules.insert(rule.QV2RAY_RULE_TAG, rule); + rules << rule; auto pos = nodeGraphWidget->pos(); pos.setX(pos.x() + 350 + GRAPH_GLOBAL_OFFSET_X); pos.setY(pos.y() + ruleNodes.count() * 120 + GRAPH_GLOBAL_OFFSET_Y); - auto _nodeData = std::make_unique(std::make_shared(rule.QV2RAY_RULE_TAG)); + auto _nodeData = std::make_unique(std::make_shared(std::make_shared(rules.last()))); auto &node = nodeScene->createNode(std::move(_nodeData)); 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. void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, QString *newTag) { + /* switch (mode) { case RENAME_RULE: @@ -158,11 +156,11 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, { items.first()->setText(*newTag); } - - if (currentRuleTag == originalTag) - { - currentRuleTag = *newTag; - } + abort(); + // if (currentRuleTag == originalTag) + // { + // currentRuleTag = *newTag; + // } } else { @@ -261,7 +259,7 @@ void RouteEditor::RenameItemTag(ROUTE_EDIT_MODE mode, const QString originalTag, } break; - } + }*/ } // Do not use const reference here. @@ -272,7 +270,9 @@ void RouteEditor::ResolveDefaultOutboundTag(const QString original, const QStrin // isLoading = true; defaultOutboundCombo->clear(); - defaultOutboundCombo->addItems(outbounds.keys()); + // + for (const auto &out : outbounds) defaultOutboundCombo->addItem(getTag(out)); + // isLoading = false; // if (!isDefaultChanged) @@ -293,7 +293,7 @@ void RouteEditor::ResolveDefaultOutboundTag(const QString original, const QStrin else { defaultOutbound = getTag(outbounds.first()); - defaultOutboundCombo->addItem(outbounds.firstKey()); + defaultOutboundCombo->addItem(getTag(outbounds.first())); } } else diff --git a/src/ui/models/InboundNodeModel.cpp b/src/ui/models/InboundNodeModel.cpp index 970ef688..1adc6047 100644 --- a/src/ui/models/InboundNodeModel.cpp +++ b/src/ui/models/InboundNodeModel.cpp @@ -3,13 +3,7 @@ QvInboundNodeModel::QvInboundNodeModel(std::shared_ptr data) : NodeDataModel() { _in = data; - _label = new QLabel(); - // - QFont font = _label->font(); - 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); + widget = new InboundOutboundWidget(); + widget->setWindowFlags(Qt::FramelessWindowHint); + widget->setAttribute(Qt::WA_TranslucentBackground); } diff --git a/src/ui/models/InboundNodeModel.hpp b/src/ui/models/InboundNodeModel.hpp index 103ca655..f4812697 100644 --- a/src/ui/models/InboundNodeModel.hpp +++ b/src/ui/models/InboundNodeModel.hpp @@ -1,6 +1,7 @@ #pragma once #include "NodeModelsBase.hpp" +#include "ui/widgets/node/InboundOutboundWidget.hpp" #include @@ -9,12 +10,7 @@ class QvInboundNodeModel : public NodeDataModel Q_OBJECT public: explicit QvInboundNodeModel(std::shared_ptr data); - ~QvInboundNodeModel() - { - // if (_label) { - // delete _label; - //} - } + ~QvInboundNodeModel(){}; QString caption() const override { @@ -40,7 +36,7 @@ class QvInboundNodeModel : public NodeDataModel { Q_UNUSED(portType) Q_UNUSED(portIndex) - return inboundType; + return NODE_TYPE_INBOUND; } std::shared_ptr outData(PortIndex) override @@ -48,19 +44,17 @@ class QvInboundNodeModel : public NodeDataModel return _in; } - void setInData(std::shared_ptr, int) override - { - } - void setData(const QString &data) + void setInData(std::shared_ptr, int) override{}; + + void setData(std::shared_ptr data) { _in = std::make_shared(data); - _label->setText(data); - _label->adjustSize(); + widget->adjustSize(); } QWidget *embeddedWidget() override { - return _label; + return widget; } std::unique_ptr clone() const override { @@ -72,5 +66,5 @@ class QvInboundNodeModel : public NodeDataModel QString modelValidationError = tr("Missing or incorrect inputs"); // std::shared_ptr _in; - QLabel *_label; + InboundOutboundWidget *widget; }; diff --git a/src/ui/models/NodeModelsBase.hpp b/src/ui/models/NodeModelsBase.hpp index 7d49e3be..d756777e 100644 --- a/src/ui/models/NodeModelsBase.hpp +++ b/src/ui/models/NodeModelsBase.hpp @@ -1,11 +1,12 @@ #pragma once -#include -#include +#include "base/Qv2rayBase.hpp" #include "common/QvHelpers.hpp" #include #include +#include +#include using QtNodes::NodeData; using QtNodes::NodeDataModel; @@ -17,79 +18,69 @@ using QtNodes::PortType; using QtNodes::NodeData; using QtNodes::NodeDataType; -const int GRAPH_NODE_LABEL_FONTSIZE_INCREMENT = 3; +constexpr auto GRAPH_NODE_LABEL_FONTSIZE_INCREMENT = 3; namespace Qv2ray::ui::nodemodels { - const std::shared_ptr outboundType = std::make_shared("outbound", QObject::tr("Outbound")); - const std::shared_ptr inboundType = std::make_shared("inbound", QObject::tr("Inbound")); - /// The class can potentially incapsulate any user data - /// need to be transferred within the Node Editor graph + const std::shared_ptr NODE_TYPE_OUTBOUND = std::make_shared("outbound", QObject::tr("Outbound")); + const std::shared_ptr NODE_TYPE_INBOUND = std::make_shared("inbound", QObject::tr("Inbound")); + class InboundNodeData : public NodeData { public: - explicit InboundNodeData(QString in) : _inboundTag(in) - { - } + explicit InboundNodeData(std::shared_ptr data) : inboundData(data){}; std::shared_ptr type() const override { - return inboundType; + return NODE_TYPE_INBOUND; } - QString GetInbound() + std::shared_ptr GetInbound() { - return _inboundTag; + return inboundData; } private: - QString _inboundTag; + std::shared_ptr inboundData; }; - /// The class can potentially incapsulate any user data - /// need to be transferred within the Node Editor graph class OutboundNodeData : public NodeData { public: - explicit OutboundNodeData(QString out) : _outboundTag(out) - { - } + explicit OutboundNodeData(std::shared_ptr data) : outboundData(data){}; std::shared_ptr type() const override { - return outboundType; + return NODE_TYPE_INBOUND; } - QString GetOutbound() + std::shared_ptr GetOutbound() { - return _outboundTag; + return outboundData; } private: - QString _outboundTag; + std::shared_ptr outboundData; }; - /// The class can potentially incapsulate any user data - /// need to be transferred within the Node Editor graph class RuleNodeData : public NodeData { + public: - explicit RuleNodeData(QString out) : _ruleTag(out) - { - } + explicit RuleNodeData(std::shared_ptr rule) : _rule(rule){}; std::shared_ptr type() const override { - return outboundType; + return NODE_TYPE_INBOUND; } - QString GetRuleTag() + std::shared_ptr GetRule() { - return _ruleTag; + return _rule; } private: - QString _ruleTag; + std::shared_ptr _rule; }; } // namespace Qv2ray::ui::nodemodels diff --git a/src/ui/models/OutboundNodeModel.cpp b/src/ui/models/OutboundNodeModel.cpp index 37f6ee80..0387ca0c 100644 --- a/src/ui/models/OutboundNodeModel.cpp +++ b/src/ui/models/OutboundNodeModel.cpp @@ -3,13 +3,7 @@ QvOutboundNodeModel::QvOutboundNodeModel(std::shared_ptr data) : NodeDataModel() { _out = data; - _label = new QLabel(); - // - QFont font = _label->font(); - 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); + widget = new InboundOutboundWidget(); + widget->setWindowFlags(Qt::FramelessWindowHint); + widget->setAttribute(Qt::WA_TranslucentBackground); } diff --git a/src/ui/models/OutboundNodeModel.hpp b/src/ui/models/OutboundNodeModel.hpp index 74032afe..4c425d27 100644 --- a/src/ui/models/OutboundNodeModel.hpp +++ b/src/ui/models/OutboundNodeModel.hpp @@ -1,5 +1,6 @@ #pragma once #include "ui/models/NodeModelsBase.hpp" +#include "ui/widgets/node/InboundOutboundWidget.hpp" #include @@ -8,12 +9,9 @@ class QvOutboundNodeModel : public NodeDataModel Q_OBJECT public: explicit QvOutboundNodeModel(std::shared_ptr data); - ~QvOutboundNodeModel() - { - // if (_label) { - // delete _label; - //} - } + ~QvOutboundNodeModel(){}; + void setInData(std::shared_ptr, int) override{}; + void setInData(std::vector>, int) override{}; QString caption() const override { @@ -39,7 +37,7 @@ class QvOutboundNodeModel : public NodeDataModel { Q_UNUSED(portType) Q_UNUSED(portIndex) - return outboundType; + return NODE_TYPE_OUTBOUND; } std::shared_ptr outData(PortIndex) override @@ -47,23 +45,15 @@ class QvOutboundNodeModel : public NodeDataModel return _out; } - void setInData(std::shared_ptr, int) override - { - } - - void setInData(std::vector>, int) override - { - } - void setData(const QString &data) + void setData(std::shared_ptr data) { _out = std::make_shared(data); - _label->setText(_out->GetOutbound()); - _label->adjustSize(); + widget->adjustSize(); } QWidget *embeddedWidget() override { - return _label; + return nullptr; } ConnectionPolicy portInConnectionPolicy(PortIndex) const override @@ -80,5 +70,5 @@ class QvOutboundNodeModel : public NodeDataModel QString modelValidationError = tr("Missing or incorrect inputs"); // std::shared_ptr _out; - QLabel *_label; + InboundOutboundWidget *widget; }; diff --git a/src/ui/models/RuleNodeModel.cpp b/src/ui/models/RuleNodeModel.cpp index 10b68faf..7396a7ea 100644 --- a/src/ui/models/RuleNodeModel.cpp +++ b/src/ui/models/RuleNodeModel.cpp @@ -3,14 +3,7 @@ QvRuleNodeModel::QvRuleNodeModel(std::shared_ptr data) : NodeDataModel() { _ruleTag = data; - _label = new QLabel(); - // - QFont font = _label->font(); - 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); + ruleWidget = new QvNodeRuleWidget(); + ruleWidget->setWindowFlags(Qt::FramelessWindowHint); + ruleWidget->setAttribute(Qt::WA_TranslucentBackground); } diff --git a/src/ui/models/RuleNodeModel.hpp b/src/ui/models/RuleNodeModel.hpp index 2a97340b..fb3873e4 100644 --- a/src/ui/models/RuleNodeModel.hpp +++ b/src/ui/models/RuleNodeModel.hpp @@ -1,6 +1,7 @@ #pragma once #include "ui/models/NodeModelsBase.hpp" +#include "ui/widgets/node/RuleWidget.hpp" #include @@ -9,12 +10,7 @@ class QvRuleNodeModel : public NodeDataModel Q_OBJECT public: QvRuleNodeModel(std::shared_ptr data); - ~QvRuleNodeModel() - { - // if (_label) { - // delete _label; - //} - } + ~QvRuleNodeModel(){}; QString caption() const override { @@ -28,18 +24,9 @@ class QvRuleNodeModel : public NodeDataModel unsigned int nPorts(PortType portType) const override { - if (portType == PortType::In) - { + if (portType == PortType::In || portType == PortType::Out) return 1; - } - else if (portType == PortType::Out) - { - return 1; - } - else - { - return 0; - } + return 0; } QString name() const override @@ -47,42 +34,32 @@ class QvRuleNodeModel : public NodeDataModel return "RuleNode"; } - std::shared_ptr dataType(PortType portType, PortIndex portIndex) const override + std::shared_ptr dataType(PortType portType, PortIndex) const override { - Q_UNUSED(portIndex) - switch (portType) { - case PortType::In: return inboundType; - - case PortType::Out: return outboundType; - + case PortType::In: return NODE_TYPE_INBOUND; + case PortType::Out: return NODE_TYPE_OUTBOUND; default: return {}; } } - std::shared_ptr outData(PortIndex port) override + std::shared_ptr outData(PortIndex) override { - Q_UNUSED(port) return _ruleTag; } - void setInData(std::shared_ptr, int) override - { - } - void setInData(std::vector>, int) override - { - } - void setData(const QString &data) + void setInData(std::shared_ptr, int) override{}; + void setInData(std::vector>, int) override{}; + void setData(std::shared_ptr data) { _ruleTag = std::make_shared(data); - _label->setText(_ruleTag->GetRuleTag()); - _label->adjustSize(); + ruleWidget->adjustSize(); } QWidget *embeddedWidget() override { - return _label; + return ruleWidget; } ConnectionPolicy portInConnectionPolicy(PortIndex) const override @@ -104,5 +81,5 @@ class QvRuleNodeModel : public NodeDataModel QString modelValidationError = tr("Missing or incorrect inputs"); // std::shared_ptr _ruleTag; - QLabel *_label; + QvNodeRuleWidget *ruleWidget; }; diff --git a/src/ui/widgets/node/OutboundBalancerWidget.cpp b/src/ui/widgets/node/OutboundBalancerWidget.cpp index c3600ae2..1360558b 100644 --- a/src/ui/widgets/node/OutboundBalancerWidget.cpp +++ b/src/ui/widgets/node/OutboundBalancerWidget.cpp @@ -1,8 +1,12 @@ #include "OutboundBalancerWidget.hpp" +#include "base/Qv2rayBase.hpp" + OutboundBalancerWidget::OutboundBalancerWidget(QWidget *parent) : QWidget(parent) { setupUi(this); + balancerAddBtn->setIcon(QICON_R("add.png")); + balancerDelBtn->setIcon(QICON_R("delete.png")); } void OutboundBalancerWidget::changeEvent(QEvent *e) @@ -14,3 +18,31 @@ void OutboundBalancerWidget::changeEvent(QEvent *e) 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.")); +} diff --git a/src/ui/widgets/node/OutboundBalancerWidget.hpp b/src/ui/widgets/node/OutboundBalancerWidget.hpp index 3aa72987..4c8e9891 100644 --- a/src/ui/widgets/node/OutboundBalancerWidget.hpp +++ b/src/ui/widgets/node/OutboundBalancerWidget.hpp @@ -10,7 +10,11 @@ class OutboundBalancerWidget public: explicit OutboundBalancerWidget(QWidget *parent = nullptr); + void on_balancerAddBtn_clicked(); + + void on_balancerDelBtn_clicked(); protected: void changeEvent(QEvent *e); + QStringList targetList; }; diff --git a/src/ui/widgets/node/OutboundBalancerWidget.ui b/src/ui/widgets/node/OutboundBalancerWidget.ui index 51608047..4e196a64 100644 --- a/src/ui/widgets/node/OutboundBalancerWidget.ui +++ b/src/ui/widgets/node/OutboundBalancerWidget.ui @@ -1,9 +1,7 @@ + - - - OutboundBalancerWidget - + 0 @@ -15,7 +13,56 @@ Form + + + + 130 + 100 + 197 + 150 + + + + + + + true + + + + + + + + + + ... + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + ... + + + + + - + diff --git a/src/ui/widgets/node/RuleWidget.cpp b/src/ui/widgets/node/RuleWidget.cpp index ba1114c1..f8b49b50 100644 --- a/src/ui/widgets/node/RuleWidget.cpp +++ b/src/ui/widgets/node/RuleWidget.cpp @@ -1,5 +1,15 @@ #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) { setupUi(this); @@ -14,3 +24,235 @@ void QvNodeRuleWidget::changeEvent(QEvent *e) default: break; } } + +void QvNodeRuleWidget::ShowCurrentRuleDetail(std::shared_ptr _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(); +} diff --git a/src/ui/widgets/node/RuleWidget.hpp b/src/ui/widgets/node/RuleWidget.hpp index 79af15a6..a5e3937e 100644 --- a/src/ui/widgets/node/RuleWidget.hpp +++ b/src/ui/widgets/node/RuleWidget.hpp @@ -1,5 +1,6 @@ #pragma once +#include "base/Qv2rayBase.hpp" #include "ui_RuleWidget.h" class QvNodeRuleWidget @@ -10,7 +11,27 @@ class QvNodeRuleWidget public: explicit QvNodeRuleWidget(QWidget *parent = nullptr); + void ShowCurrentRuleDetail(std::shared_ptr 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: void changeEvent(QEvent *e); + std::shared_ptr ruleptr; + bool isLoading; }; diff --git a/src/ui/widgets/node/RuleWidget.ui b/src/ui/widgets/node/RuleWidget.ui index ba2d03db..ca1e5e9d 100644 --- a/src/ui/widgets/node/RuleWidget.ui +++ b/src/ui/widgets/node/RuleWidget.ui @@ -6,264 +6,179 @@ 0 0 - 296 - 704 + 298 + 500 Form - + - - - - - true - - - Rule Status - - + + + - - + + false - Enabled + Rename - - - - Rule Tag - - - - - - - - - false - - - - - - - false - - - Rename - - - - - - - - false + + + Rule Enabled - - Route Editor + + + + + + Show / Hide - - false + + + + + + QFrame::StyledPanel - - - - - Network - - - - - - - - - TCP - - - - - - - UDP - - - - - - - Both - - - - - - - - - Protocol - - - - - + + QFrame::Raised + + + + - + - HTTP + Network - + + + + + TCP + + + + + + + UDP + + + + + + + Both + + + + + + + - TLS + Protocol - - + + + + + + HTTP + + + + + + + TLS + + + + + + + BitTorrent + + + + + + + - BitTorrent + Port + + + + + + + e.g. 80, 443, 8000-8080 - - - - Port - - - - - - - e.g. 80, 443, 8000-8080 - - - - - - - Balancers - - - - - - - Use Balancers - - - - - - - - - - true - - - - - - - - - - ... - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - ... - - - - - - - - - - - - - false - - - Route Detail Settings - - - - - - Users List - - - - - - - Source IP Matches - - - - - - - - - - - - - Target Domain List - - - - - - - Target IP List - - - - - - - - + + + + + + Users List + + + + + + + Source IP Matches + + + + + + + + + + + + + Target Domain List + + + + + + + Target IP List + + + + + + + + + + diff --git a/src/ui/windows/w_MainWindow_extra.cpp b/src/ui/windows/w_MainWindow_extra.cpp index c4391d8e..8dbfcfc8 100644 --- a/src/ui/windows/w_MainWindow_extra.cpp +++ b/src/ui/windows/w_MainWindow_extra.cpp @@ -5,7 +5,7 @@ void MainWindow::MWSetSystemProxy() { - const auto inboundInfo = KernelInstance->GetInboundInfo(); + const auto inboundInfo = KernelInstance->GetCurrentConnectionInboundInfo(); InboundInfoObject httpInboundInfo; InboundInfoObject socksInboundInfo;