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
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); |
|
}
|
|
|