From aa39c7aae55607bd997a8f2419b565f547049a99 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sat, 14 May 2022 18:13:42 +0800 Subject: [PATCH] Fix wrong GUI behavior in "Optional IP address to bind to" setting Previously the address field got erroneously reset to "All addresses" when the network interface is down. --- src/gui/advancedsettings.cpp | 114 +++++++++++++++++------------------ 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index 80016d33e..cba5e8330 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -262,23 +262,14 @@ void AdvancedSettings::saveAdvancedSettings() pref->resolvePeerCountries(m_checkBoxResolveCountries.isChecked()); pref->resolvePeerHostNames(m_checkBoxResolveHosts.isChecked()); // Network interface - if (m_comboBoxInterface.currentIndex() == 0) - { - // All interfaces (default) - session->setNetworkInterface(QString()); - session->setNetworkInterfaceName(QString()); - } - else - { - session->setNetworkInterface(m_comboBoxInterface.itemData(m_comboBoxInterface.currentIndex()).toString()); - session->setNetworkInterfaceName(m_comboBoxInterface.currentText()); - } - + session->setNetworkInterface(m_comboBoxInterface.currentData().toString()); + session->setNetworkInterfaceName((m_comboBoxInterface.currentIndex() == 0) + ? QString() + : m_comboBoxInterface.currentText()); // Interface address // Construct a QHostAddress to filter malformed strings - const QHostAddress ifaceAddr(m_comboBoxInterfaceAddress.currentData().toString().trimmed()); + const QHostAddress ifaceAddr {m_comboBoxInterfaceAddress.currentData().toString()}; session->setNetworkInterfaceAddress(ifaceAddr.toString()); - // Announce IP // Construct a QHostAddress to filter malformed strings const QHostAddress addr(m_lineEditAnnounceIP.text().trimmed()); @@ -346,45 +337,57 @@ void AdvancedSettings::updateSaveResumeDataIntervalSuffix(const int value) void AdvancedSettings::updateInterfaceAddressCombo() { - // Try to get the currently selected interface name - const QString ifaceName = m_comboBoxInterface.itemData(m_comboBoxInterface.currentIndex()).toString(); // Empty string for the first element - const QString currentAddress = BitTorrent::Session::instance()->networkInterfaceAddress(); - - // Clear all items and reinsert them, default to all - m_comboBoxInterfaceAddress.clear(); - m_comboBoxInterfaceAddress.addItem(tr("All addresses"), {}); - m_comboBoxInterfaceAddress.addItem(tr("All IPv4 addresses"), QLatin1String("0.0.0.0")); - m_comboBoxInterfaceAddress.addItem(tr("All IPv6 addresses"), QLatin1String("::")); - - const auto populateCombo = [this](const QHostAddress &addr) + const auto toString = [](const QHostAddress &address) -> QString { - if (addr.protocol() == QAbstractSocket::IPv4Protocol) - { - const QString str = addr.toString(); - m_comboBoxInterfaceAddress.addItem(str, str); - } - else if (addr.protocol() == QAbstractSocket::IPv6Protocol) - { - const QString str = Utils::Net::canonicalIPv6Addr(addr).toString(); - m_comboBoxInterfaceAddress.addItem(str, str); + switch (address.protocol()) { + case QAbstractSocket::IPv4Protocol: + return address.toString(); + case QAbstractSocket::IPv6Protocol: + return Utils::Net::canonicalIPv6Addr(address).toString(); + default: + Q_ASSERT(false); + break; } + return {}; }; - if (ifaceName.isEmpty()) + // Clear all items and reinsert them + m_comboBoxInterfaceAddress.clear(); + m_comboBoxInterfaceAddress.addItem(tr("All addresses"), QString()); + m_comboBoxInterfaceAddress.addItem(tr("All IPv4 addresses"), QHostAddress(QHostAddress::AnyIPv4).toString()); + m_comboBoxInterfaceAddress.addItem(tr("All IPv6 addresses"), QHostAddress(QHostAddress::AnyIPv6).toString()); + + const QString currentIface = m_comboBoxInterface.currentData().toString(); + if (currentIface.isEmpty()) // `any` interface { - for (const QHostAddress &addr : asConst(QNetworkInterface::allAddresses())) - populateCombo(addr); + for (const QHostAddress &address : asConst(QNetworkInterface::allAddresses())) + { + const QString addressString = toString(address); + m_comboBoxInterfaceAddress.addItem(addressString, addressString); + } } else { - const QNetworkInterface iface = QNetworkInterface::interfaceFromName(ifaceName); - const QList addresses = iface.addressEntries(); + const QList addresses = QNetworkInterface::interfaceFromName(currentIface).addressEntries(); for (const QNetworkAddressEntry &entry : addresses) - populateCombo(entry.ip()); + { + const QString addressString = toString(entry.ip()); + m_comboBoxInterfaceAddress.addItem(addressString, addressString); + } } + const QString currentAddress = BitTorrent::Session::instance()->networkInterfaceAddress(); const int index = m_comboBoxInterfaceAddress.findData(currentAddress); - m_comboBoxInterfaceAddress.setCurrentIndex(std::max(index, 0)); + if (index > -1) + { + m_comboBoxInterfaceAddress.setCurrentIndex(index); + } + else + { + // not found, for the sake of UI consistency, add such entry + m_comboBoxInterfaceAddress.addItem(currentAddress, currentAddress); + m_comboBoxInterfaceAddress.setCurrentIndex(m_comboBoxInterfaceAddress.count() - 1); + } } void AdvancedSettings::loadAdvancedSettings() @@ -638,26 +641,23 @@ void AdvancedSettings::loadAdvancedSettings() m_checkBoxResolveHosts.setChecked(pref->resolvePeerHostNames()); addRow(RESOLVE_HOSTS, tr("Resolve peer host names"), &m_checkBoxResolveHosts); // Network interface - m_comboBoxInterface.addItem(tr("Any interface", "i.e. Any network interface")); - const QString currentInterface = session->networkInterface(); - bool interfaceExists = currentInterface.isEmpty(); - int i = 1; + m_comboBoxInterface.addItem(tr("Any interface", "i.e. Any network interface"), QString()); for (const QNetworkInterface &iface : asConst(QNetworkInterface::allInterfaces())) - { m_comboBoxInterface.addItem(iface.humanReadableName(), iface.name()); - if (!currentInterface.isEmpty() && (iface.name() == currentInterface)) - { - m_comboBoxInterface.setCurrentIndex(i); - interfaceExists = true; - } - ++i; - } - // Saved interface does not exist, show it anyway - if (!interfaceExists) + + const QString currentInterface = session->networkInterface(); + const int ifaceIndex = m_comboBoxInterface.findData(currentInterface); + if (ifaceIndex > -1) { - m_comboBoxInterface.addItem(session->networkInterfaceName(), currentInterface); - m_comboBoxInterface.setCurrentIndex(i); + m_comboBoxInterface.setCurrentIndex(ifaceIndex); } + else + { + // Saved interface does not exist, show it + m_comboBoxInterface.addItem(session->networkInterfaceName(), currentInterface); + m_comboBoxInterface.setCurrentIndex(m_comboBoxInterface.count() - 1); + } + connect(&m_comboBoxInterface, qOverload(&QComboBox::currentIndexChanged) , this, &AdvancedSettings::updateInterfaceAddressCombo); addRow(NETWORK_IFACE, tr("Network interface"), &m_comboBoxInterface);