You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

186 lines
6.5 KiB

// networksettingspage.cpp — Network configuration form
#include "networksettingspage.h"
#include "../transport/config_updater.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QNetworkInterface>
#include <QFile>
#include <QTextStream>
static const char* SECTION = "server:lan";
NetworkSettingsPage::NetworkSettingsPage(QWidget* parent)
: QWidget(parent)
{
auto* layout = new QVBoxLayout(this);
layout->setSpacing(12);
layout->setContentsMargins(0, 0, 0, 0);
auto* title = new QLabel("Listen Address", this);
title->setStyleSheet("font-weight: bold; font-size: 13px;");
layout->addWidget(title);
// Interface
auto* ifRow = new QHBoxLayout();
ifRow->addWidget(new QLabel("Interface:", this));
m_interfaceCombo = new QComboBox(this);
m_interfaceCombo->setMinimumWidth(180);
ifRow->addWidget(m_interfaceCombo, 1);
layout->addLayout(ifRow);
// IP
auto* ipRow = new QHBoxLayout();
ipRow->addWidget(new QLabel("IP Address:", this));
m_ipCombo = new QComboBox(this);
m_ipCombo->setEditable(true);
m_ipCombo->setMinimumWidth(180);
ipRow->addWidget(m_ipCombo, 1);
layout->addLayout(ipRow);
// Port
auto* portRow = new QHBoxLayout();
portRow->addWidget(new QLabel("Port:", this));
m_portSpin = new QSpinBox(this);
m_portSpin->setRange(1, 65535);
m_portSpin->setValue(1333);
m_portSpin->setMinimumWidth(100);
portRow->addWidget(m_portSpin);
portRow->addStretch();
layout->addLayout(portRow);
// Protocol
auto* protoRow = new QHBoxLayout();
protoRow->addWidget(new QLabel("Protocol:", this));
m_protoCombo = new QComboBox(this);
m_protoCombo->addItems({"UDP", "TCP"});
m_protoCombo->setMinimumWidth(100);
protoRow->addWidget(m_protoCombo);
protoRow->addStretch();
layout->addLayout(protoRow);
auto* note = new QLabel("Changes take effect after restart.", this);
note->setStyleSheet("color: gray; font-size: 11px;");
layout->addWidget(note);
layout->addStretch();
populateInterfaces();
connect(m_interfaceCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &NetworkSettingsPage::onInterfaceChanged);
}
void NetworkSettingsPage::loadFromConfig(const QString& configPath) {
// Read [server:lan] section from INI file
QString addr, netif, transport;
QFile f(configPath);
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
bool inSection = false;
QTextStream in(&f);
while (!in.atEnd()) {
QString line = in.readLine();
if (line.startsWith('[') && line.endsWith(']')) {
inSection = (line.mid(1, line.length() - 2) == SECTION);
continue;
}
if (!inSection || !line.contains('=')) continue;
QString key = line.section('=', 0, 0).trimmed();
QString val = line.section('=', 1).trimmed();
if (key == "addr") addr = val;
else if (key == "netif") netif = val;
else if (key == "transport") transport = val;
}
f.close();
}
// Parse addr: IP:port
QString ip;
if (!addr.isEmpty()) {
int lastColon = addr.lastIndexOf(':');
if (lastColon > 0) {
ip = addr.left(lastColon);
int port = addr.mid(lastColon + 1).toInt();
if (port > 0 && port <= 65535) m_portSpin->setValue(port);
}
}
// Set protocol
int protoIdx = (transport == "tcp") ? 1 : 0;
m_protoCombo->setCurrentIndex(protoIdx);
// Set interface
int ifIdx = m_interfaceCombo->findText(netif);
if (ifIdx >= 0) m_interfaceCombo->setCurrentIndex(ifIdx);
// Set IP — populate addresses first, then select
populateAddresses(netif.isEmpty() ? QString() : netif);
if (ip.isEmpty() || ip == "0.0.0.0") ip = "Auto (0.0.0.0)";
int ipIdx = m_ipCombo->findText(ip);
if (ipIdx >= 0)
m_ipCombo->setCurrentIndex(ipIdx);
else
m_ipCombo->setCurrentText(ip);
}
void NetworkSettingsPage::saveToConfig(const QString& configPath) const {
// addr
QString ip = m_ipCombo->currentText().trimmed();
if (ip.isEmpty() || ip == "Auto (0.0.0.0)") ip = "0.0.0.0";
config_update_option(configPath, SECTION, "addr",
QString("%1:%2").arg(ip).arg(m_portSpin->value()),
CONFIG_UPDATE_REPLACE);
// netif: set or remove (empty value means no netif binding)
QString iface = m_interfaceCombo->currentText();
if (iface.startsWith("Auto"))
iface.clear();
config_update_option(configPath, SECTION, "netif", iface, CONFIG_UPDATE_REPLACE);
// transport
config_update_option(configPath, SECTION, "transport",
m_protoCombo->currentText().toLower(),
CONFIG_UPDATE_REPLACE);
}
void NetworkSettingsPage::onInterfaceChanged(int index) {
Q_UNUSED(index);
QString iface = m_interfaceCombo->currentText();
populateAddresses(iface.startsWith("Auto") ? QString() : iface);
}
void NetworkSettingsPage::populateInterfaces() {
m_interfaceCombo->addItem("Auto (any)");
for (const QNetworkInterface& iface : QNetworkInterface::allInterfaces()) {
if (iface.flags() & QNetworkInterface::IsLoopBack) continue;
if (!(iface.flags() & QNetworkInterface::IsUp)) continue;
m_interfaceCombo->addItem(iface.name());
}
}
void NetworkSettingsPage::populateAddresses(const QString& ifaceName) {
QString current = m_ipCombo->currentText();
m_ipCombo->clear();
m_ipCombo->addItem("Auto (0.0.0.0)");
if (ifaceName.isEmpty()) {
for (const QNetworkInterface& iface : QNetworkInterface::allInterfaces()) {
if (iface.flags() & QNetworkInterface::IsLoopBack) continue;
if (!(iface.flags() & QNetworkInterface::IsUp)) continue;
for (const QNetworkAddressEntry& entry : iface.addressEntries()) {
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
m_ipCombo->addItem(entry.ip().toString());
}
}
} else {
QNetworkInterface iface = QNetworkInterface::interfaceFromName(ifaceName);
if (iface.isValid()) {
for (const QNetworkAddressEntry& entry : iface.addressEntries()) {
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
m_ipCombo->addItem(entry.ip().toString());
}
}
}
int idx = m_ipCombo->findText(current);
if (idx >= 0) m_ipCombo->setCurrentIndex(idx);
}